@graphty/graph-io 0.3.18 → 0.3.19

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.
Files changed (118) hide show
  1. package/README.md +37 -2
  2. package/dist/chunks/{escape-D-gZWO26.js → escape-CWExcecC.js} +3 -3
  3. package/dist/chunks/{escape-D-gZWO26.js.map → escape-CWExcecC.js.map} +1 -1
  4. package/dist/chunks/exporter-CbMZyVt-.js +735 -0
  5. package/dist/chunks/exporter-CbMZyVt-.js.map +1 -0
  6. package/dist/chunks/importer-BAP4PrxR.js +2194 -0
  7. package/dist/chunks/importer-BAP4PrxR.js.map +1 -0
  8. package/dist/chunks/{importer-Br_QeAeE.js → importer-BNFuV1-K.js} +5 -4
  9. package/dist/chunks/{importer-Br_QeAeE.js.map → importer-BNFuV1-K.js.map} +1 -1
  10. package/dist/chunks/{importer-d0uQxFp6.js → importer-BVGtU1NA.js} +5 -4
  11. package/dist/chunks/{importer-d0uQxFp6.js.map → importer-BVGtU1NA.js.map} +1 -1
  12. package/dist/chunks/{importer-DHagxvDD.js → importer-BW-Ft2ps.js} +5 -4
  13. package/dist/chunks/{importer-DHagxvDD.js.map → importer-BW-Ft2ps.js.map} +1 -1
  14. package/dist/chunks/{importer-Du5crN9l.js → importer-Bm1_5vPS.js} +275 -82
  15. package/dist/chunks/importer-Bm1_5vPS.js.map +1 -0
  16. package/dist/chunks/{importer-aNJfe0qu.js → importer-ByPGO-09.js} +2 -2
  17. package/dist/chunks/{importer-aNJfe0qu.js.map → importer-ByPGO-09.js.map} +1 -1
  18. package/dist/chunks/importer-DOepkgnG.js +1713 -0
  19. package/dist/chunks/importer-DOepkgnG.js.map +1 -0
  20. package/dist/chunks/json-elements-CZY1wiZh.js +779 -0
  21. package/dist/chunks/json-elements-CZY1wiZh.js.map +1 -0
  22. package/dist/chunks/{records-Bk9jgodz.js → records-BzNicMsf.js} +2 -2
  23. package/dist/chunks/{records-Bk9jgodz.js.map → records-BzNicMsf.js.map} +1 -1
  24. package/dist/chunks/{report-BOk0p5y8.js → report-BcWboivV.js} +95 -95
  25. package/dist/chunks/{report-BOk0p5y8.js.map → report-BcWboivV.js.map} +1 -1
  26. package/dist/chunks/weights-CwISIpCP.js +176 -0
  27. package/dist/chunks/weights-CwISIpCP.js.map +1 -0
  28. package/dist/chunks/{writer-GAdltGmC.js → writer-DQiKgQJc.js} +8 -179
  29. package/dist/chunks/writer-DQiKgQJc.js.map +1 -0
  30. package/dist/csv.js +5 -4
  31. package/dist/csv.js.map +1 -1
  32. package/dist/cx.d.ts +1 -0
  33. package/dist/cx.js +6 -0
  34. package/dist/cx.js.map +1 -0
  35. package/dist/cx2.d.ts +1 -0
  36. package/dist/cx2.js +10 -0
  37. package/dist/cx2.js.map +1 -0
  38. package/dist/dot.js +1 -1
  39. package/dist/gexf.js +15 -4
  40. package/dist/gexf.js.map +1 -1
  41. package/dist/gml.js +5 -4
  42. package/dist/gml.js.map +1 -1
  43. package/dist/graph-io.js +145 -389
  44. package/dist/graph-io.js.map +1 -1
  45. package/dist/graphml.js +1 -1
  46. package/dist/json.js +1 -1
  47. package/dist/neo4j.js +5 -4
  48. package/dist/neo4j.js.map +1 -1
  49. package/dist/obo.js +1 -1
  50. package/dist/pajek.js +1 -1
  51. package/dist/src/common/json-elements.d.ts +286 -0
  52. package/dist/src/common/json-elements.d.ts.map +1 -0
  53. package/dist/src/common/json-elements.js +926 -0
  54. package/dist/src/common/json-elements.js.map +1 -0
  55. package/dist/src/formats/cx/importer.d.ts +133 -0
  56. package/dist/src/formats/cx/importer.d.ts.map +1 -0
  57. package/dist/src/formats/cx/importer.js +2220 -0
  58. package/dist/src/formats/cx/importer.js.map +1 -0
  59. package/dist/src/formats/cx/index.d.ts +7 -0
  60. package/dist/src/formats/cx/index.d.ts.map +1 -0
  61. package/dist/src/formats/cx/index.js +7 -0
  62. package/dist/src/formats/cx/index.js.map +1 -0
  63. package/dist/src/formats/cx2/exporter.d.ts +59 -0
  64. package/dist/src/formats/cx2/exporter.d.ts.map +1 -0
  65. package/dist/src/formats/cx2/exporter.js +864 -0
  66. package/dist/src/formats/cx2/exporter.js.map +1 -0
  67. package/dist/src/formats/cx2/importer.d.ts +169 -0
  68. package/dist/src/formats/cx2/importer.d.ts.map +1 -0
  69. package/dist/src/formats/cx2/importer.js +1652 -0
  70. package/dist/src/formats/cx2/importer.js.map +1 -0
  71. package/dist/src/formats/cx2/index.d.ts +7 -0
  72. package/dist/src/formats/cx2/index.d.ts.map +1 -0
  73. package/dist/src/formats/cx2/index.js +7 -0
  74. package/dist/src/formats/cx2/index.js.map +1 -0
  75. package/dist/src/formats/gexf/exporter.d.ts +2 -0
  76. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  77. package/dist/src/formats/gexf/exporter.js +6 -0
  78. package/dist/src/formats/gexf/exporter.js.map +1 -1
  79. package/dist/src/formats/gexf/importer.d.ts +2 -4
  80. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  81. package/dist/src/formats/gexf/importer.js +2 -4
  82. package/dist/src/formats/gexf/importer.js.map +1 -1
  83. package/dist/src/formats/gexf/index.d.ts +1 -1
  84. package/dist/src/formats/gexf/index.js +2 -2
  85. package/dist/src/formats/gexf/index.js.map +1 -1
  86. package/dist/src/formats/gml/exporter.js +1 -1
  87. package/dist/src/formats/gml/exporter.js.map +1 -1
  88. package/dist/src/formats/json/importer.d.ts.map +1 -1
  89. package/dist/src/formats/json/importer.js +6 -104
  90. package/dist/src/formats/json/importer.js.map +1 -1
  91. package/dist/src/index.d.ts +2 -0
  92. package/dist/src/index.d.ts.map +1 -1
  93. package/dist/src/index.js +2 -0
  94. package/dist/src/index.js.map +1 -1
  95. package/dist/src/registry.d.ts.map +1 -1
  96. package/dist/src/registry.js +5 -0
  97. package/dist/src/registry.js.map +1 -1
  98. package/dist/src/sniff.d.ts +1 -1
  99. package/dist/src/sniff.d.ts.map +1 -1
  100. package/dist/src/sniff.js +2 -0
  101. package/dist/src/sniff.js.map +1 -1
  102. package/package.json +11 -1
  103. package/src/common/json-elements.ts +1147 -0
  104. package/src/formats/cx/importer.ts +2733 -0
  105. package/src/formats/cx/index.ts +7 -0
  106. package/src/formats/cx2/exporter.ts +1036 -0
  107. package/src/formats/cx2/importer.ts +2187 -0
  108. package/src/formats/cx2/index.ts +7 -0
  109. package/src/formats/gexf/exporter.ts +11 -0
  110. package/src/formats/gexf/importer.ts +2 -2
  111. package/src/formats/gexf/index.ts +1 -1
  112. package/src/formats/gml/exporter.ts +1 -1
  113. package/src/formats/json/importer.ts +6 -105
  114. package/src/index.ts +10 -0
  115. package/src/registry.ts +5 -0
  116. package/src/sniff.ts +14 -1
  117. package/dist/chunks/importer-Du5crN9l.js.map +0 -1
  118. package/dist/chunks/writer-GAdltGmC.js.map +0 -1
package/dist/gexf.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"gexf.js","sources":["../src/formats/gexf/schema.ts","../src/formats/gexf/importer.ts","../src/formats/gexf/exporter.ts","../src/formats/gexf/index.ts"],"sourcesContent":["/**\n * What the GEXF importer and exporter share (research note 07 section 2.1, design sections 5.1,\n * 5.5, 5.6 and 5.10): the namespaces of the two supported versions, the fixed names and\n * declarations of the columns derived from XML attributes and viz elements (design section 5.6:\n * XML-attribute-derived columns have fixed names and roles, and a declared attribute that would\n * take one of them is renamed `<name>#<id>`), the shape of a temporal extension table, and the\n * declared-type table of each version for the exporter.\n */\n\nimport { type ColumnDecl, type Dtype } from \"@graphty/graph-format\";\n\nimport { TIME_TEXT_ROLE, TIME_TEXT_SUFFIX } from \"../../common/temporal.js\";\n\n/** The GEXF versions the exporter writes. */\nexport type GexfVersion = \"1.2\" | \"1.3\";\n\n/** The format name. */\nexport const GEXF_FORMAT = \"gexf\";\n\n/** The namespace URIs of each version. */\nexport const GEXF_NAMESPACES: Readonly<Record<GexfVersion, { readonly gexf: string; readonly viz: string }>> = {\n \"1.2\": { gexf: \"http://www.gexf.net/1.2draft\", viz: \"http://www.gexf.net/1.2draft/viz\" },\n \"1.3\": { gexf: \"http://gexf.net/1.3\", viz: \"http://gexf.net/1.3/viz\" },\n};\n\n/** The default edge type values of `<graph defaultedgetype>` and `<edge type>`. */\nexport type GexfEdgeType = \"directed\" | \"undirected\" | \"mutual\";\n\n/** The GEXF `timeformat` values. */\nexport const TIME_FORMATS: ReadonlySet<string> = new Set([\"integer\", \"double\", \"date\", \"dateTime\"]);\n\n/** The GEXF graph `mode` values. */\nexport const GRAPH_MODES: ReadonlySet<string> = new Set([\"static\", \"dynamic\", \"slice\"]);\n\n/** The GEXF 1.3 `timerepresentation` values. */\nexport const TIME_REPRESENTATIONS: ReadonlySet<string> = new Set([\"interval\", \"timestamp\"]);\n\n/** The `origin.namespace` of viz-derived columns. */\nexport const VIZ_NAMESPACE = \"viz\";\n\n/** The origin every XML-derived column declares. */\nconst XML_ORIGIN = { format: GEXF_FORMAT };\n\n/** The origin of every viz-derived column. */\nconst VIZ_ORIGIN = { format: GEXF_FORMAT, namespace: VIZ_NAMESPACE };\n\n/**\n * The fixed node column names the importer owns (design section 5.6): a declared attribute with\n * one of these titles is renamed `<title>#<id>` so the XML-derived column keeps its name and role.\n */\nexport const NODE_COLUMNS = Object.freeze({\n label: \"label\",\n parent: \"parent\",\n parents: \"parents\",\n start: \"start\",\n end: \"end\",\n timestamp: \"timestamp\",\n spells: \"spells\",\n spellsOpen: \"spells.open\",\n timestamps: \"timestamps\",\n open: \"open\",\n position: \"position\",\n color: \"color\",\n size: \"size\",\n shape: \"shape\",\n shapeUri: \"shape.uri\",\n});\n\n/** The fixed edge column names the importer owns. */\nconst EDGE_COLUMNS = Object.freeze({\n id: \"id\",\n label: \"label\",\n kind: \"kind\",\n start: \"start\",\n end: \"end\",\n timestamp: \"timestamp\",\n spells: \"spells\",\n spellsOpen: \"spells.open\",\n timestamps: \"timestamps\",\n open: \"open\",\n color: \"color\",\n thickness: \"thickness\",\n shape: \"shape\",\n});\n\n/** Every reserved node column name, including the temporal companions. */\nexport const RESERVED_NODE_NAMES: ReadonlySet<string> = new Set([\n ...Object.values(NODE_COLUMNS),\n NODE_COLUMNS.start + TIME_TEXT_SUFFIX,\n NODE_COLUMNS.end + TIME_TEXT_SUFFIX,\n NODE_COLUMNS.timestamp + TIME_TEXT_SUFFIX,\n]);\n\n/** Every reserved edge column name, including the temporal companions. */\nexport const RESERVED_EDGE_NAMES: ReadonlySet<string> = new Set([\n ...Object.values(EDGE_COLUMNS),\n EDGE_COLUMNS.start + TIME_TEXT_SUFFIX,\n EDGE_COLUMNS.end + TIME_TEXT_SUFFIX,\n EDGE_COLUMNS.timestamp + TIME_TEXT_SUFFIX,\n]);\n\n/** The declarations of the XML-derived node columns, keyed as NODE_COLUMNS. */\nexport const NODE_DECLS: Readonly<Record<keyof typeof NODE_COLUMNS, ColumnDecl>> = {\n label: { name: NODE_COLUMNS.label, dtype: \"string\", role: \"label\", nullable: true, origin: XML_ORIGIN },\n parent: {\n name: NODE_COLUMNS.parent,\n dtype: \"u32\",\n role: \"parent\",\n refersTo: \"node\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n parents: {\n name: NODE_COLUMNS.parents,\n dtype: \"list\",\n itemDtype: \"u32\",\n role: \"parents\",\n refersTo: \"node\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n start: { name: NODE_COLUMNS.start, dtype: \"f64\", role: \"start\", nullable: true, origin: XML_ORIGIN },\n end: { name: NODE_COLUMNS.end, dtype: \"f64\", role: \"end\", nullable: true, origin: XML_ORIGIN },\n timestamp: { name: NODE_COLUMNS.timestamp, dtype: \"f64\", role: \"timestamp\", nullable: true, origin: XML_ORIGIN },\n spells: {\n name: NODE_COLUMNS.spells,\n dtype: \"list\",\n itemDtype: \"f64\",\n itemComponents: 2,\n role: \"spells\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n timestamps: {\n name: NODE_COLUMNS.timestamps,\n dtype: \"list\",\n itemDtype: \"f64\",\n role: \"timestamps\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n open: { name: NODE_COLUMNS.open, dtype: \"u8\", role: \"open\", nullable: true, origin: XML_ORIGIN },\n spellsOpen: {\n name: NODE_COLUMNS.spellsOpen,\n dtype: \"list\",\n itemDtype: \"u8\",\n role: \"spellsOpen\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n position: {\n name: NODE_COLUMNS.position,\n dtype: \"f32\",\n components: 3,\n role: \"position\",\n mutable: true,\n nullable: true,\n origin: VIZ_ORIGIN,\n extra: { units: \"file\" },\n },\n color: {\n name: NODE_COLUMNS.color,\n dtype: \"f32\",\n components: 4,\n role: \"color\",\n nullable: true,\n origin: VIZ_ORIGIN,\n },\n size: { name: NODE_COLUMNS.size, dtype: \"f32\", role: \"size\", nullable: true, origin: VIZ_ORIGIN },\n shape: { name: NODE_COLUMNS.shape, dtype: \"dict\", role: \"shape\", nullable: true, origin: VIZ_ORIGIN },\n shapeUri: { name: NODE_COLUMNS.shapeUri, dtype: \"string\", nullable: true, origin: VIZ_ORIGIN },\n};\n\n/** The declarations of the XML-derived edge columns, keyed as EDGE_COLUMNS. */\nexport const EDGE_DECLS: Readonly<Record<keyof typeof EDGE_COLUMNS, ColumnDecl>> = {\n id: { name: EDGE_COLUMNS.id, dtype: \"string\", role: \"id\", unique: true, nullable: true, origin: XML_ORIGIN },\n label: { name: EDGE_COLUMNS.label, dtype: \"string\", role: \"label\", nullable: true, origin: XML_ORIGIN },\n kind: { name: EDGE_COLUMNS.kind, dtype: \"dict\", role: \"kind\", nullable: true, origin: XML_ORIGIN },\n start: { name: EDGE_COLUMNS.start, dtype: \"f64\", role: \"start\", nullable: true, origin: XML_ORIGIN },\n end: { name: EDGE_COLUMNS.end, dtype: \"f64\", role: \"end\", nullable: true, origin: XML_ORIGIN },\n timestamp: { name: EDGE_COLUMNS.timestamp, dtype: \"f64\", role: \"timestamp\", nullable: true, origin: XML_ORIGIN },\n spells: {\n name: EDGE_COLUMNS.spells,\n dtype: \"list\",\n itemDtype: \"f64\",\n itemComponents: 2,\n role: \"spells\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n timestamps: {\n name: EDGE_COLUMNS.timestamps,\n dtype: \"list\",\n itemDtype: \"f64\",\n role: \"timestamps\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n open: { name: EDGE_COLUMNS.open, dtype: \"u8\", role: \"open\", nullable: true, origin: XML_ORIGIN },\n spellsOpen: {\n name: EDGE_COLUMNS.spellsOpen,\n dtype: \"list\",\n itemDtype: \"u8\",\n role: \"spellsOpen\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n color: {\n name: EDGE_COLUMNS.color,\n dtype: \"f32\",\n components: 4,\n role: \"color\",\n nullable: true,\n origin: VIZ_ORIGIN,\n },\n thickness: { name: EDGE_COLUMNS.thickness, dtype: \"f32\", role: \"thickness\", nullable: true, origin: VIZ_ORIGIN },\n shape: { name: EDGE_COLUMNS.shape, dtype: \"dict\", role: \"shape\", nullable: true, origin: VIZ_ORIGIN },\n};\n\n/** The bit of the `open` column marking an open start (design section 5.1). */\nexport const OPEN_START = 1;\n\n/** The bit of the `open` column marking an open end. */\nexport const OPEN_END = 2;\n\n/** The prefix of a temporal extension table's name (design section 5.10). */\nconst TEMPORAL_TABLE_PREFIX = \"temporal:\";\n\n/** The column names of a temporal extension table (design section 5.10). */\nexport const TEMPORAL_COLUMNS = Object.freeze({\n element: \"element\",\n start: \"start\",\n end: \"end\",\n value: \"value\",\n open: \"open\",\n startText: `start${TIME_TEXT_SUFFIX}`,\n endText: `end${TIME_TEXT_SUFFIX}`,\n valueText: `value${TIME_TEXT_SUFFIX}`,\n});\n\n/**\n * The name of the temporal extension table of a dynamic attribute.\n * @param domain - node or edge\n * @param column - the static column's name\n * @returns `temporal:<domain>:<column>`\n */\nexport function temporalTableName(domain: \"node\" | \"edge\", column: string): string {\n return `${TEMPORAL_TABLE_PREFIX}${domain}:${column}`;\n}\n\n/**\n * Split a temporal table name into its domain and column.\n * @param name - the table name\n * @returns the parts, or null when the name is not a temporal table's\n */\nexport function parseTemporalTableName(name: string): { domain: \"node\" | \"edge\"; column: string } | null {\n if (!name.startsWith(TEMPORAL_TABLE_PREFIX)) {\n return null;\n }\n const rest = name.slice(TEMPORAL_TABLE_PREFIX.length);\n const colon = rest.indexOf(\":\");\n if (colon < 0) {\n return null;\n }\n const domain = rest.slice(0, colon);\n if (domain !== \"node\" && domain !== \"edge\") {\n return null;\n }\n return { domain, column: rest.slice(colon + 1) };\n}\n\n/**\n * The column declarations of a temporal extension table (design section 5.10): the element index,\n * the interval, the value in the attribute's dtype, the interval's text companions, an open-bounds\n * byte and, for a temporal-typed attribute, the value's text companion.\n * @param domain - the domain the element column refers to\n * @param value - the value column's declaration fields (dtype, itemDtype, options...)\n * @param temporalValue - whether the value is itself a temporal type needing a text companion\n * @returns the declarations in table order\n */\nexport function temporalTableDecls(\n domain: \"node\" | \"edge\",\n value: Pick<ColumnDecl, \"dtype\" | \"itemDtype\" | \"options\" | \"origin\">,\n temporalValue: boolean,\n): ColumnDecl[] {\n const decls: ColumnDecl[] = [\n { name: TEMPORAL_COLUMNS.element, dtype: \"u32\", refersTo: domain, nullable: false },\n { name: TEMPORAL_COLUMNS.start, dtype: \"f64\", role: \"start\", nullable: true },\n { name: TEMPORAL_COLUMNS.end, dtype: \"f64\", role: \"end\", nullable: true },\n { name: TEMPORAL_COLUMNS.value, ...value, nullable: true },\n {\n name: TEMPORAL_COLUMNS.startText,\n dtype: \"string\",\n role: TIME_TEXT_ROLE,\n nullable: true,\n extra: { for: TEMPORAL_COLUMNS.start },\n },\n { name: TEMPORAL_COLUMNS.endText, dtype: \"string\", nullable: true, extra: { for: TEMPORAL_COLUMNS.end } },\n { name: TEMPORAL_COLUMNS.open, dtype: \"u8\", role: \"open\", nullable: true },\n ];\n if (temporalValue) {\n decls.push({\n name: TEMPORAL_COLUMNS.valueText,\n dtype: \"string\",\n nullable: true,\n extra: { for: TEMPORAL_COLUMNS.value },\n });\n }\n return decls;\n}\n\n/** The scalar type names GEXF 1.2 declares. */\nconst TYPES_1_2: ReadonlySet<string> = new Set([\"integer\", \"long\", \"double\", \"float\", \"boolean\", \"string\", \"anyURI\"]);\n\n/** The scalar type names GEXF 1.3 declares (the list variants are derived). */\nconst TYPES_1_3: ReadonlySet<string> = new Set([\n ...TYPES_1_2,\n \"bigdecimal\",\n \"biginteger\",\n \"byte\",\n \"char\",\n \"short\",\n \"date\",\n \"dateTime\",\n]);\n\n/**\n * Whether a declared type text is a scalar type of a version (case-sensitive, as the schema spells\n * them).\n * @param type - the type text\n * @param version - the target version\n * @returns true when the version declares it\n */\nexport function isScalarType(type: string, version: GexfVersion): boolean {\n return (version === \"1.2\" ? TYPES_1_2 : TYPES_1_3).has(type);\n}\n\n/**\n * Whether a declared type text is a list type of a version: `liststring` in 1.2, `list<scalar>` in 1.3.\n * @param type - the type text\n * @param version - the target version\n * @returns true when the version declares it\n */\nexport function isListType(type: string, version: GexfVersion): boolean {\n if (version === \"1.2\") {\n return type === \"liststring\";\n }\n return type.startsWith(\"list\") && type.length > 4 && isScalarType(type.slice(4), \"1.3\");\n}\n\n/**\n * The canonical GEXF scalar type of a column dtype (design section 5.1 reversed).\n * @param dtype - a scalar dtype\n * @returns the type text; u32 becomes `long` (its range exceeds `integer`), u8 `integer`, json `string`\n */\nexport function canonicalScalarType(dtype: Dtype): string {\n switch (dtype) {\n case \"bool\":\n return \"boolean\";\n case \"i32\":\n case \"u8\":\n return \"integer\";\n case \"u32\":\n return \"long\";\n case \"f32\":\n return \"float\";\n case \"f64\":\n return \"double\";\n case \"dict\":\n case \"string\":\n case \"json\":\n case \"list\":\n return \"string\";\n default: {\n const name: string = dtype;\n return name;\n }\n }\n}\n","/**\n * The GEXF importer (design sections 8.4, 8.6, 5.1, 5.6, 5.10; research note 07 section 2.1):\n * GEXF 1.1, 1.2 and 1.3 documents read in one SAX-style pass over the shared streaming XML\n * tokenizer (src/common/xml.ts) and pushed into the sink one scalar at a time, so a document of\n * any size is never held in memory. Declared attributes become typed columns as they are read\n * (defaults, options, list types, temporal types with their text companions declared on the first\n * value whose text is not canonical); the viz namespace becomes the position / color / size /\n * shape / thickness role columns with origin.namespace \"viz\"; `pid`, nested `<nodes>` and\n * `<parents>` become the parent / parents columns, resolved once every node is declared so a\n * forward reference is legal; element lifetimes (`start` / `end` / `timestamp`, `<spells>`, 1.3\n * `timestamps` / `intervals`, 1.2 `startopen` / `endopen` holding the open bound's time) become\n * the temporal role columns; dynamic attribute values go into the temporal extension tables of\n * design section 5.10, and a spell's open bounds go to the spells.open column; the graph header's\n * `mode`, `timeformat`, `timerepresentation` and `idtype` land in the graph meta, and its\n * `defaultedgetype`, `start`, `end` and `timestamp` as written in `meta.extra.gexf` (`idtype` is\n * informational: Gephi writes `idtype=\"string\"` for every file, so ids follow the `ids` rule,\n * canonical by default).\n *\n * Direction follows design section 8.4: `defaultedgetype` (undirected when absent, per the spec and\n * the `defaultDirected` option) sets the sink's direction once, and every per-edge `type` override,\n * `mutual` included, goes through the common DirectionResolver and the `onMixedDirection` policy.\n * The weight is the `weight` XML attribute, overridden by a static value of the edge attribute\n * titled `weightFrom` (\"weight\" by default), applied with `setEdgeWeight` when that value arrives;\n * timed values of that attribute form the `temporal:edge:weight` table (design section 5.10). Ids\n * are coerced with the \"canonical\" rule of design section 4.1 by default. Edges may not reference\n * undeclared nodes unless `addMissingNodes` is set (the GEXF default is false, design section 8.4).\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n type ExtensionHandle,\n GraphFormatError,\n type GraphMetaPatch,\n type GraphSink,\n INVALID_INDEX,\n MAX_COUNT,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport {\n type AttributeDeclarationInput,\n declareAttribute,\n declareCompanion,\n type DeclaredAttribute,\n declareResolved,\n losesPrecision,\n parseDeclaredTemporal,\n parseDeclaredValue,\n PRECISION_CODE,\n} from \"../../common/attributes.js\";\nimport {\n COUNT_HINT_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_NODE_CODE,\n ID_MERGED_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n NO_GRAPH_CODE,\n STRAY_TEXT_CODE,\n UNKNOWN_ELEMENT_CODE,\n UNKNOWN_PARENT_CODE,\n XML_SYNTAX_CODE,\n} from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec, parseDecimalText } from \"../../common/declared-types.js\";\nimport { DirectionResolver, type EdgeKind } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { textChunks, throwIfAborted } from \"../../common/input.js\";\nimport { type ListSyntax, splitListText } from \"../../common/lists.js\";\nimport {\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder, type IssueLocation } from \"../../common/report.js\";\nimport { parseTimeText, type TemporalValue, type TimeFormat, timeTextCompanion } from \"../../common/temporal.js\";\nimport { isWeightField, parseWeightText } from \"../../common/weights.js\";\nimport {\n isWhitespace,\n localName,\n tokenizeXml,\n xmlDeclaredEncoding,\n type XmlHandler,\n XmlSyntaxError,\n} from \"../../common/xml.js\";\nimport { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from \"../../types.js\";\nimport {\n EDGE_DECLS,\n GEXF_FORMAT,\n type GexfEdgeType,\n GRAPH_MODES,\n NODE_DECLS,\n OPEN_END,\n OPEN_START,\n RESERVED_EDGE_NAMES,\n RESERVED_NODE_NAMES,\n temporalTableDecls,\n temporalTableName,\n TIME_FORMATS,\n TIME_REPRESENTATIONS,\n} from \"./schema.js\";\n\n/** The format-specific options of the GEXF importer. */\nexport interface GexfImportOptions {\n /**\n * Whether the viz namespace elements (color, position, size, shape, thickness) are imported as\n * role columns (default true); false ignores them and records one `unsupported` warning.\n */\n viz?: boolean | undefined;\n}\n\n/** Issue code: the document is not a GEXF document (no `<gexf>` root). */\nexport const NOT_GEXF_CODE = \"E_NOT_GEXF\";\n/** Issue code: the graph declares edges but no `<nodes>` section. */\nexport const MISSING_NODES_CODE = \"E_GEXF_MISSING_NODES\";\n/** Issue code: an edge `type` outside directed / undirected / mutual. */\nexport const EDGE_TYPE_CODE = \"E_GEXF_EDGE_TYPE\";\n/** Issue code: an `<attributes>` group without a class, or with an unknown one. */\nexport const ATTRIBUTES_CLASS_CODE = \"E_GEXF_ATTRIBUTES_CLASS\";\n/** Issue code: an `<attribute>` without an id. */\nexport const ATTRIBUTE_ID_CODE = \"E_GEXF_ATTRIBUTE_ID\";\n/** Issue code: a graph header value (`defaultedgetype`, `mode`, `timeformat`, ...) outside its set. */\nexport const HEADER_VALUE_CODE = \"W_GEXF_HEADER_VALUE\";\n/** Issue code: a second `<attribute>` with the same id in the same class (the first is kept). */\nexport const DUPLICATE_ATTRIBUTE_CODE = \"W_GEXF_DUPLICATE_ATTRIBUTE\";\n/** Issue code: an `<attribute>` without a type (read as string). */\nexport const ATTRIBUTE_TYPE_CODE = \"W_GEXF_ATTRIBUTE_TYPE\";\n/** Issue code: an `<attvalue>` naming an attribute the document never declares (once per id). */\nexport const UNKNOWN_ATTRIBUTE_CODE = \"W_GEXF_UNKNOWN_ATTRIBUTE\";\n/** Issue code: an `<attvalue>` without a `for` or a `value`. */\nexport const ATTVALUE_SHAPE_CODE = \"W_GEXF_ATTVALUE_SHAPE\";\n/** Issue code: a timed value on an attribute declared in a static group (stored as dynamic anyway). */\nexport const TIMED_STATIC_CODE = \"W_GEXF_TIMED_VALUE_ON_STATIC\";\n/** Issue code: the `weight` XML attribute is present but `weightFrom` is null. */\nexport const WEIGHT_IGNORED_CODE = \"W_GEXF_WEIGHT_IGNORED\";\n/** Issue code: viz elements skipped under `viz: false`. */\nexport const VIZ_SKIPPED_CODE = \"W_GEXF_VIZ_SKIPPED\";\n/** Issue code: a 1.2 dynamic viz element (its bounds are dropped, the value kept). */\nexport const VIZ_DYNAMIC_CODE = \"W_GEXF_VIZ_DYNAMIC_DROPPED\";\n/**\n * Issue code: `startopen` / `endopen` on a `<spell>` stored closed. No longer recorded: the open\n * bits of each spell are kept in the spells.open column. Kept so the exported code table is stable.\n */\nexport const SPELL_OPEN_CODE = \"W_GEXF_SPELL_OPEN_DROPPED\";\n/** Issue code: a viz element with a value that does not parse (the element is skipped). */\nexport const VIZ_VALUE_CODE = \"W_GEXF_VIZ_VALUE\";\n/** Issue code: both `start` and `startopen` (or `end` and `endopen`) on one element; the closed bound wins. */\nexport const OPEN_BOUND_CONFLICT_CODE = \"W_GEXF_OPEN_BOUND_CONFLICT\";\n\nexport {\n DUPLICATE_NODE_CODE,\n ID_MERGED_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n NO_GRAPH_CODE,\n UNKNOWN_PARENT_CODE,\n};\n\nconst EDGE_TYPES: ReadonlySet<string> = new Set([\"directed\", \"undirected\", \"mutual\"]);\n\n/**\n * An edge type as a keyword of {@link EDGE_TYPES}: the schema spells them in lower case, but files\n * in the wild write `Directed`, and the keyword is read whatever its case or surrounding space.\n * @param text - a `defaultedgetype` or edge `type` value\n * @returns the text trimmed and in lower case\n */\nfunction edgeTypeKeyword(text: string): string {\n return text.trim().toLowerCase();\n}\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The XML attributes the importer reads on `<node>`; any other one is reported once. */\nconst NODE_ATTRIBUTES: ReadonlySet<string> = new Set([\n \"id\",\n \"label\",\n \"pid\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"startopen\",\n \"endopen\",\n \"timestamps\",\n \"intervals\",\n]);\n\n/** The XML attributes the importer reads on `<edge>`; any other one is reported once. */\nconst EDGE_ATTRIBUTES: ReadonlySet<string> = new Set([\n \"id\",\n \"source\",\n \"target\",\n \"type\",\n \"label\",\n \"weight\",\n \"kind\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"startopen\",\n \"endopen\",\n \"timestamps\",\n \"intervals\",\n]);\n\n/** The common options the GEXF importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** A GraphMetaPatch under construction (its fields are readonly once handed to the sink). */\ntype MetaPatchDraft = { -readonly [K in keyof GraphMetaPatch]: GraphMetaPatch[K] };\n\n/** A declared attribute as the importer tracks it: its column and how values are parsed and stored. */\ninterface TrackedAttribute {\n /** The attribute id as written. */\n readonly id: string;\n /** The column name. */\n readonly name: string;\n /** How values are parsed. */\n readonly spec: DeclaredTypeSpec;\n /** The list syntax of values. */\n readonly listSyntax: ListSyntax;\n /** The column handle. */\n readonly handle: ColumnHandle;\n /** The companion text column's declaration of a temporal attribute, or null. */\n readonly companionDecl: ColumnDecl | null;\n /** The companion's handle once a value needed it, or INVALID_INDEX. */\n companion: ColumnHandle;\n /** Whether the attribute was declared in a dynamic group. */\n readonly dynamic: boolean;\n /** The value column fields of the temporal table. */\n readonly valueDecl: Pick<ColumnDecl, \"dtype\" | \"itemDtype\" | \"options\" | \"origin\">;\n /** The temporal table, created on the first timed value. */\n table: ExtensionHandle;\n}\n\n/** A pending containment reference resolved after every node is declared. */\ninterface ParentRef {\n /** The child's node index. */\n readonly child: number;\n /** The parent's id (from `pid` / `<parent for>`), or null when the index is known. */\n readonly parentId: NodeId | null;\n /** The parent's index (nested `<nodes>`), or INVALID_INDEX. */\n readonly parentIndex: number;\n /** Where the reference was read. */\n readonly where: IssueLocation;\n}\n\n/** A column declared on first use, through the design section 5.6 rule. */\nclass LazyColumn {\n private handle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private readonly domain: \"node\" | \"edge\";\n\n private readonly decl: ColumnDecl;\n\n /**\n * Create a lazily declared column.\n * @param domain - node or edge\n * @param decl - the declaration\n */\n constructor(domain: \"node\" | \"edge\", decl: ColumnDecl) {\n this.domain = domain;\n this.decl = decl;\n }\n\n /**\n * The handle, declaring the column on the first call (renamed or without its role when the\n * sink already holds the name or the role, reported).\n * @param sink - the sink\n * @param report - the report\n * @param where - the location of the first use\n * @returns the handle\n */\n get(sink: GraphSink, report: ImportReportBuilder, where?: IssueLocation): ColumnHandle {\n if (this.handle === INVALID_INDEX) {\n this.handle = declareResolved(sink, this.domain, this.decl, report, where).handle;\n }\n return this.handle;\n }\n\n /**\n * Write one cell, declaring the column first when needed.\n * @param sink - the sink\n * @param report - the report\n * @param index - the row\n * @param value - the value\n * @param where - the location, for a declaration issue\n */\n set(sink: GraphSink, report: ImportReportBuilder, index: number, value: unknown, where?: IssueLocation): void {\n const handle = this.get(sink, report, where);\n if (this.domain === \"node\") {\n sink.setNodeValue(handle, index, value);\n } else {\n sink.setEdgeValue(handle, index, value);\n }\n }\n}\n\n/** A temporal role column with its lazily declared text companion. */\nclass TemporalColumn {\n private readonly column: LazyColumn;\n\n private companion: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private readonly domain: \"node\" | \"edge\";\n\n private readonly name: string;\n\n /**\n * Create the pair.\n * @param domain - node or edge\n * @param decl - the numeric column's declaration\n */\n constructor(domain: \"node\" | \"edge\", decl: ColumnDecl) {\n this.domain = domain;\n this.name = decl.name;\n this.column = new LazyColumn(domain, decl);\n }\n\n /**\n * Write a parsed time value and, when its text must be kept, the companion cell.\n * @param sink - the sink\n * @param report - the report\n * @param index - the row\n * @param value - the parsed value\n * @param where - the location, for a declaration issue\n */\n set(\n sink: GraphSink,\n report: ImportReportBuilder,\n index: number,\n value: TemporalValue,\n where?: IssueLocation,\n ): void {\n this.column.set(sink, report, index, value.value, where);\n if (value.text === null) {\n return;\n }\n if (this.companion === INVALID_INDEX) {\n this.companion = declareCompanion(sink, this.domain, timeTextCompanion(this.name), report);\n }\n if (this.domain === \"node\") {\n sink.setNodeValue(this.companion, index, value.text);\n } else {\n sink.setEdgeValue(this.companion, index, value.text);\n }\n }\n}\n\n/** The lazily declared columns of one domain. */\ninterface DomainColumns {\n readonly label: LazyColumn;\n readonly start: TemporalColumn;\n readonly end: TemporalColumn;\n readonly timestamp: TemporalColumn;\n readonly spells: LazyColumn;\n readonly spellsOpen: LazyColumn;\n readonly timestamps: LazyColumn;\n readonly open: LazyColumn;\n readonly color: LazyColumn;\n readonly shape: LazyColumn;\n}\n\n/** Where the reader is in the document. */\nconst enum Ctx {\n Gexf,\n Meta,\n MetaText,\n Graph,\n Attributes,\n Attribute,\n AttributeText,\n Nodes,\n Node,\n Attvalues,\n Parents,\n Spells,\n Edges,\n Edge,\n Skip,\n}\n\n/** An open `<node>`: its index (INVALID_INDEX when the node was skipped) and location. */\ninterface NodeFrame {\n readonly index: number;\n readonly where: IssueLocation;\n}\n\n/**\n * The open `<edge>`: its primary index, the mirror of an expanded pair (or INVALID_INDEX) and\n * location. One frame is reused for every edge (the hot loop allocates nothing per edge but the\n * tokenizer's attribute map): the report copies a location's fields into each issue, and nothing\n * keeps a reference to an edge's frame or location past the edge's end tag.\n */\ninterface EdgeFrame {\n index: number;\n mirror: number;\n readonly where: MutableLocation;\n}\n\n/** A location whose fields are overwritten per element (see EdgeFrame). */\ninterface MutableLocation {\n line: number;\n element: string | null;\n}\n\n/** An `<attribute>` being read: its start-tag fields and the texts of `<default>` / `<options>`. */\ninterface PendingAttribute {\n readonly domain: \"node\" | \"edge\";\n readonly dynamic: boolean;\n readonly attrs: ReadonlyMap<string, string>;\n readonly line: number;\n defaultText: string | null;\n optionsText: string | null;\n}\n\n/**\n * The event handler that turns the tokenizer's events into sink calls: one import call.\n */\nclass GexfReader implements XmlHandler {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly viz: boolean;\n\n private readonly coercer: IdCoercer;\n\n private readonly resolver: DirectionResolver;\n\n private readonly ctx: Ctx[] = [];\n\n private timeFormat: TimeFormat | null = null;\n\n private defaultKind: GexfEdgeType = \"undirected\";\n\n private readonly meta: MetaPatchDraft = { sourceFormat: GEXF_FORMAT };\n\n private metaText = \"\";\n\n private metaField: \"creator\" | \"description\" | \"keywords\" | null = null;\n\n private readonly nodeAttrs = new Map<string, TrackedAttribute>();\n\n private readonly edgeAttrs = new Map<string, TrackedAttribute>();\n\n private readonly declaredNodeNames = new Set<string>();\n\n private readonly declaredEdgeNames = new Set<string>();\n\n /** The edge attribute that is THE weight (its title equals weightFrom), or null. */\n private weightAttr: { readonly id: string; readonly spec: DeclaredTypeSpec; table: ExtensionHandle } | null = null;\n\n private readonly nodeColumns: DomainColumns;\n\n private readonly edgeColumns: DomainColumns;\n\n private readonly parentColumn = new LazyColumn(\"node\", NODE_DECLS.parent);\n\n private readonly parentsColumn = new LazyColumn(\"node\", NODE_DECLS.parents);\n\n private positionColumn: LazyColumn | null = null;\n\n private readonly sizeColumn = new LazyColumn(\"node\", NODE_DECLS.size);\n\n private readonly shapeUriColumn = new LazyColumn(\"node\", NODE_DECLS.shapeUri);\n\n private readonly thicknessColumn = new LazyColumn(\"edge\", EDGE_DECLS.thickness);\n\n private readonly edgeIdColumn = new LazyColumn(\"edge\", EDGE_DECLS.id);\n\n private readonly edgeKindColumn = new LazyColumn(\"edge\", EDGE_DECLS.kind);\n\n private readonly edgeIds = new Set<string>();\n\n private parentRefs: ParentRef[] = [];\n\n private parentsRefs: { readonly child: number; readonly ids: readonly NodeId[]; readonly where: IssueLocation }[] =\n [];\n\n private readonly unknownAttributes = new Set<string>();\n\n private readonly nodeStack: NodeFrame[] = [];\n\n private edge: EdgeFrame | null = null;\n\n /** The one edge frame, reused for every `<edge>` (see EdgeFrame). */\n private readonly edgeFrame: EdgeFrame = {\n index: INVALID_INDEX,\n mirror: INVALID_INDEX,\n where: { line: 0, element: null },\n };\n\n /** The one `<attvalue>` location, reused per value (its fields are copied into every issue). */\n private readonly valueWhere: MutableLocation = { line: 0, element: null };\n\n private attributeGroup: { readonly domain: \"node\" | \"edge\" | null; readonly dynamic: boolean } | null = null;\n\n private pendingAttribute: PendingAttribute | null = null;\n\n private attributeText: \"default\" | \"options\" | null = null;\n\n private attributeTextValue = \"\";\n\n private spellPairs: number[][] | null = null;\n\n /** The open bits of each spell in spellPairs, in the same order. */\n private spellOpen: number[] = [];\n\n private spellsWhere: IssueLocation | null = null;\n\n private parentIds: NodeId[] | null = null;\n\n private nodesSeen = false;\n\n private graphSeen = false;\n\n private elementsSinceCheck = 0;\n\n /**\n * Set up one import.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param viz - whether viz elements are imported\n */\n constructor(sink: GraphSink, report: ImportReportBuilder, options: ResolvedImportOptions, viz: boolean) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.viz = viz;\n this.coercer = new IdCoercer(options.ids);\n this.resolver = new DirectionResolver(sink, report, options.onMixedDirection);\n this.nodeColumns = {\n label: new LazyColumn(\"node\", NODE_DECLS.label),\n start: new TemporalColumn(\"node\", NODE_DECLS.start),\n end: new TemporalColumn(\"node\", NODE_DECLS.end),\n timestamp: new TemporalColumn(\"node\", NODE_DECLS.timestamp),\n spells: new LazyColumn(\"node\", NODE_DECLS.spells),\n spellsOpen: new LazyColumn(\"node\", NODE_DECLS.spellsOpen),\n timestamps: new LazyColumn(\"node\", NODE_DECLS.timestamps),\n open: new LazyColumn(\"node\", NODE_DECLS.open),\n color: new LazyColumn(\"node\", NODE_DECLS.color),\n shape: new LazyColumn(\"node\", NODE_DECLS.shape),\n };\n this.edgeColumns = {\n label: new LazyColumn(\"edge\", EDGE_DECLS.label),\n start: new TemporalColumn(\"edge\", EDGE_DECLS.start),\n end: new TemporalColumn(\"edge\", EDGE_DECLS.end),\n timestamp: new TemporalColumn(\"edge\", EDGE_DECLS.timestamp),\n spells: new LazyColumn(\"edge\", EDGE_DECLS.spells),\n spellsOpen: new LazyColumn(\"edge\", EDGE_DECLS.spellsOpen),\n timestamps: new LazyColumn(\"edge\", EDGE_DECLS.timestamps),\n open: new LazyColumn(\"edge\", EDGE_DECLS.open),\n color: new LazyColumn(\"edge\", EDGE_DECLS.color),\n shape: new LazyColumn(\"edge\", EDGE_DECLS.shape),\n };\n }\n\n // ---------------------------------------------------------------- events\n\n start(name: string, attrs: ReadonlyMap<string, string>, line: number): void {\n const parent = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];\n const local = localName(name);\n switch (parent) {\n case null:\n if (local !== \"gexf\") {\n this.report.fail(NOT_GEXF_CODE, `the root element is <${name}>, not <gexf>`, { line });\n }\n this.readRoot(attrs);\n this.ctx.push(Ctx.Gexf);\n return;\n case Ctx.Gexf:\n this.startInGexf(name, local, attrs, line);\n return;\n case Ctx.Meta:\n this.startInMeta(name, local, line);\n return;\n case Ctx.Graph:\n this.startInGraph(name, local, attrs, line);\n return;\n case Ctx.Attributes:\n this.startInAttributes(name, local, attrs, line);\n return;\n case Ctx.Attribute:\n this.startInAttribute(name, local, line);\n return;\n case Ctx.Nodes:\n this.startInNodes(name, local, attrs, line);\n return;\n case Ctx.Node:\n this.startInNode(name, local, attrs, line);\n return;\n case Ctx.Attvalues:\n this.startInAttvalues(name, local, attrs, line);\n return;\n case Ctx.Parents:\n this.startInParents(name, local, attrs, line);\n return;\n case Ctx.Spells:\n this.startInSpells(name, local, attrs, line);\n return;\n case Ctx.Edges:\n this.startInEdges(name, local, attrs, line);\n return;\n case Ctx.Edge:\n this.startInEdge(name, local, attrs, line);\n return;\n case Ctx.MetaText:\n case Ctx.AttributeText:\n case Ctx.Skip:\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * An element ends.\n * @param _name - the element name\n * @param _line - the line (unused: issues of an element cite its start line)\n */\n end(_name: string, _line: number): void {\n const ctx = this.ctx.pop();\n switch (ctx) {\n case Ctx.Meta:\n this.finishMeta();\n return;\n case Ctx.MetaText:\n this.finishMetaText();\n return;\n case Ctx.Graph:\n this.resolveParents();\n return;\n case Ctx.Attributes:\n this.attributeGroup = null;\n return;\n case Ctx.Attribute:\n this.finishAttribute();\n return;\n case Ctx.AttributeText:\n this.finishAttributeText();\n return;\n case Ctx.Node:\n this.nodeStack.pop();\n return;\n case Ctx.Edge:\n this.edge = null;\n return;\n case Ctx.Parents:\n this.finishParents();\n return;\n case Ctx.Spells:\n this.finishSpells();\n return;\n case Ctx.Gexf:\n case Ctx.Nodes:\n case Ctx.Edges:\n case Ctx.Attvalues:\n case Ctx.Skip:\n case undefined:\n return;\n default: {\n const value: never = ctx;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown reader state ${String(value)}`, {});\n }\n }\n }\n\n /**\n * Character data: kept inside `<creator>` / `<description>` / `<keywords>` and `<default>` /\n * `<options>`, ignored elsewhere (reported once when it is not whitespace).\n * @param text - the text\n * @param line - the line\n */\n text(text: string, line: number): void {\n const ctx = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];\n switch (ctx) {\n case Ctx.MetaText:\n this.metaText += text;\n return;\n case Ctx.AttributeText:\n this.attributeTextValue += text;\n return;\n case Ctx.Skip:\n return;\n default:\n if (!isWhitespace(text)) {\n this.report.warnOnce(\n \"validation-error\",\n STRAY_TEXT_CODE,\n \"text where GEXF allows only elements was ignored\",\n { line },\n );\n }\n }\n }\n\n /**\n * Apply what the root and `<meta>` gave to the sink; called once the graph's header is read.\n */\n finish(): void {\n if (!this.graphSeen) {\n this.report.fail(NO_GRAPH_CODE, \"the document has no <graph> element\");\n }\n }\n\n // ---------------------------------------------------------------- root, meta, graph\n\n /**\n * Record the root's version.\n * @param attrs - the `<gexf>` attributes\n */\n private readRoot(attrs: ReadonlyMap<string, string>): void {\n const version = attrs.get(\"version\");\n if (version !== undefined && version.length > 0) {\n this.meta.sourceVersion = version;\n }\n }\n\n /**\n * A child of `<gexf>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGexf(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"meta\": {\n const modified = attrs.get(\"lastmodifieddate\");\n if (modified !== undefined && modified.length > 0) {\n this.meta.modified = modified;\n }\n this.ctx.push(Ctx.Meta);\n return;\n }\n case \"graph\":\n if (this.graphSeen) {\n this.report.fail(NO_GRAPH_CODE, \"a second <graph> element; a GEXF document has one graph\", {\n line,\n });\n }\n this.graphSeen = true;\n this.readHeader(attrs, line);\n this.ctx.push(Ctx.Graph);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<meta>`.\n * @param name - the element name\n * @param local - its local name\n * @param line - the line\n */\n private startInMeta(name: string, local: string, line: number): void {\n if (local === \"creator\" || local === \"description\" || local === \"keywords\") {\n this.metaField = local;\n this.metaText = \"\";\n this.ctx.push(Ctx.MetaText);\n return;\n }\n this.unknownElement(name, line);\n }\n\n /** Close a `<creator>` / `<description>` / `<keywords>`. */\n private finishMetaText(): void {\n const text = this.metaText;\n switch (this.metaField) {\n case \"creator\":\n this.meta.creator = text;\n break;\n case \"description\":\n this.meta.description = text;\n break;\n case \"keywords\":\n this.meta.keywords = text\n .split(\",\")\n .map((k) => k.trim())\n .filter((k) => k.length > 0);\n break;\n default:\n break;\n }\n this.metaField = null;\n this.metaText = \"\";\n }\n\n /** Close `<meta>`: nothing more to do (the patch is applied at `<graph>`). */\n private finishMeta(): void {\n // the meta patch is applied when the graph header is read\n }\n\n /**\n * Read `<graph defaultedgetype mode timeformat timerepresentation idtype start end timestamp>`\n * into the meta and the importer's own state, apply the meta patch and set the sink's\n * direction; an unknown value is a warning and the default applies.\n * @param attrs - the `<graph>` attributes\n * @param line - the line\n */\n private readHeader(attrs: ReadonlyMap<string, string>, line: number): void {\n const where = { line };\n const patch = this.meta;\n const edgeType = attrs.get(\"defaultedgetype\");\n if (edgeType === undefined) {\n this.defaultKind = this.options.defaultDirected ? \"directed\" : \"undirected\";\n } else if (EDGE_TYPES.has(edgeTypeKeyword(edgeType))) {\n this.defaultKind = edgeTypeKeyword(edgeType) as GexfEdgeType;\n } else {\n this.defaultKind = this.options.defaultDirected ? \"directed\" : \"undirected\";\n this.warnHeader(\"defaultedgetype\", edgeType, where);\n }\n const mode = attrs.get(\"mode\") ?? attrs.get(\"type\");\n if (mode !== undefined) {\n if (GRAPH_MODES.has(mode)) {\n patch.mode = mode as \"static\" | \"dynamic\" | \"slice\";\n } else {\n this.warnHeader(\"mode\", mode, where);\n }\n }\n const timeFormat = attrs.get(\"timeformat\");\n if (timeFormat !== undefined) {\n if (TIME_FORMATS.has(timeFormat)) {\n this.timeFormat = timeFormat as TimeFormat;\n patch.timeFormat = this.timeFormat;\n } else {\n this.warnHeader(\"timeformat\", timeFormat, where);\n }\n }\n const representation = attrs.get(\"timerepresentation\");\n if (representation !== undefined) {\n if (TIME_REPRESENTATIONS.has(representation)) {\n patch.timeRepresentation = representation as \"interval\" | \"timestamp\";\n } else {\n this.warnHeader(\"timerepresentation\", representation, where);\n }\n }\n const idType = attrs.get(\"idtype\");\n if (idType !== undefined) {\n if (idType === \"string\") {\n // informational only: Gephi writes idtype=\"string\" unconditionally, so honouring it\n // would turn every Gephi export's integer ids into text; the canonical rule of\n // design section 4.1 applies and the exporter's check() reports W_ID_TEXT_TYPE\n patch.idType = \"string\";\n } else if (idType === \"integer\" || idType === \"long\") {\n patch.idType = \"integer\";\n } else {\n this.warnHeader(\"idtype\", idType, where);\n }\n }\n const extra: Record<string, unknown> = {};\n for (const key of [\"defaultedgetype\", \"start\", \"end\", \"timestamp\"]) {\n const value = attrs.get(key);\n if (value !== undefined) {\n extra[key] = value;\n }\n }\n if (Object.keys(extra).length > 0) {\n patch.extra = { gexf: extra };\n }\n this.sink.setMeta(patch);\n this.resolver.setHeader(this.defaultKind !== \"undirected\", where);\n }\n\n /**\n * Record a header value outside its set.\n * @param name - the attribute name\n * @param value - the value found\n * @param where - the header line\n */\n private warnHeader(name: string, value: string, where: IssueLocation): void {\n this.report.warning(\n \"validation-error\",\n HEADER_VALUE_CODE,\n `<graph ${name}=\"${value}\"> is not a known value; the default applies`,\n { ...where, element: name },\n );\n }\n\n /**\n * A child of `<graph>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGraph(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"attributes\":\n this.beginAttributes(attrs, line);\n return;\n case \"nodes\":\n this.nodesSeen = true;\n this.reserve(attrs, \"node\", line);\n this.ctx.push(Ctx.Nodes);\n return;\n case \"edges\":\n if (!this.nodesSeen) {\n this.report.error(\n \"validation-error\",\n MISSING_NODES_CODE,\n \"the graph declares <edges> but no <nodes>\",\n { line },\n );\n }\n this.resolveParents();\n this.reserve(attrs, \"edge\", line);\n this.ctx.push(Ctx.Edges);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * Pass a section's `count` hint to the sink; a hint the sink cannot reserve is a warning.\n * @param attrs - the `<nodes>` or `<edges>` attributes\n * @param domain - which count it is\n * @param line - the line\n */\n private reserve(attrs: ReadonlyMap<string, string>, domain: \"node\" | \"edge\", line: number): void {\n const text = attrs.get(\"count\");\n if (text === undefined) {\n return;\n }\n const count = Number(text);\n if (!Number.isInteger(count) || count < 0 || count > MAX_COUNT) {\n this.report.warning(\n \"validation-error\",\n COUNT_HINT_CODE,\n `<${domain}s count=\"${text}\"> is not a count the sink can reserve; ignored`,\n { line, element: \"count\" },\n );\n return;\n }\n if (count === 0) {\n return;\n }\n try {\n if (domain === \"node\") {\n this.sink.reserve(count, undefined);\n } else {\n this.sink.reserve(undefined, count);\n }\n } catch (err) {\n if (!(err instanceof GraphFormatError)) {\n throw err;\n }\n this.report.warning(\"validation-error\", COUNT_HINT_CODE, `count hint ${text} refused: ${err.message}`, {\n line,\n element: \"count\",\n });\n }\n }\n\n // ---------------------------------------------------------------- attribute declarations\n\n /**\n * Open an `<attributes class mode>` group.\n * @param attrs - the group's attributes\n * @param line - the line\n */\n private beginAttributes(attrs: ReadonlyMap<string, string>, line: number): void {\n const cls = attrs.get(\"class\");\n const where = { line };\n let domain: \"node\" | \"edge\" | null = null;\n if (cls === \"node\" || cls === \"edge\") {\n domain = cls;\n } else {\n this.report.error(\n \"validation-error\",\n ATTRIBUTES_CLASS_CODE,\n cls === undefined\n ? \"<attributes> without a class\"\n : `<attributes class=\"${cls}\"> is neither node nor edge`,\n where,\n );\n }\n const mode = attrs.get(\"mode\");\n if (mode !== undefined && mode !== \"static\" && mode !== \"dynamic\") {\n this.warnHeader(\"mode\", mode, where);\n }\n this.attributeGroup = { domain, dynamic: mode === \"dynamic\" };\n this.ctx.push(Ctx.Attributes);\n }\n\n /**\n * A child of `<attributes>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInAttributes(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"attribute\") {\n this.unknownElement(name, line);\n return;\n }\n const group = this.attributeGroup;\n if (group === null || group.domain === null) {\n // the group's class was refused; its attributes are dropped with it\n this.ctx.push(Ctx.Skip);\n return;\n }\n this.pendingAttribute = {\n domain: group.domain,\n dynamic: group.dynamic,\n attrs,\n line,\n defaultText: null,\n optionsText: null,\n };\n this.ctx.push(Ctx.Attribute);\n }\n\n /**\n * A child of `<attribute>`: `<default>` or `<options>`.\n * @param name - the element name\n * @param local - its local name\n * @param line - the line\n */\n private startInAttribute(name: string, local: string, line: number): void {\n if (local === \"default\" || local === \"options\") {\n this.attributeText = local;\n this.attributeTextValue = \"\";\n this.ctx.push(Ctx.AttributeText);\n return;\n }\n this.unknownElement(name, line);\n }\n\n /** Close a `<default>` / `<options>`. */\n private finishAttributeText(): void {\n const pending = this.pendingAttribute;\n if (pending !== null) {\n if (this.attributeText === \"default\") {\n pending.defaultText = this.attributeTextValue;\n } else if (this.attributeText === \"options\") {\n pending.optionsText = this.attributeTextValue;\n }\n }\n this.attributeText = null;\n this.attributeTextValue = \"\";\n }\n\n /** Close an `<attribute>`: declare it. */\n private finishAttribute(): void {\n const pending = this.pendingAttribute;\n this.pendingAttribute = null;\n if (pending === null) {\n return;\n }\n try {\n this.declareOne(pending);\n } catch (err) {\n this.report.recordError(err, { line: pending.line, element: pending.attrs.get(\"id\") ?? null });\n }\n }\n\n /**\n * Declare one `<attribute id title type>` with its `<default>` and `<options>` (design\n * sections 5.1, 5.5, 5.6). The edge attribute titled `weightFrom` is the weight and gets no\n * column; its declaration is recorded in meta.weightOrigin.\n * @param pending - the attribute as read\n */\n private declareOne(pending: PendingAttribute): void {\n const { report, sink, options } = this;\n const { domain, dynamic, attrs } = pending;\n const id = attrs.get(\"id\");\n const where = { line: pending.line, element: id ?? null };\n if (id === undefined) {\n report.error(\"validation-error\", ATTRIBUTE_ID_CODE, \"<attribute> without an id\", where);\n return;\n }\n const tracked = domain === \"node\" ? this.nodeAttrs : this.edgeAttrs;\n if (tracked.has(id) || (domain === \"edge\" && this.weightAttr !== null && this.weightAttr.id === id)) {\n report.warning(\n \"validation-error\",\n DUPLICATE_ATTRIBUTE_CODE,\n `${domain} attribute \"${id}\" is declared twice; the first declaration is kept`,\n where,\n );\n return;\n }\n const title = attrs.get(\"title\") ?? null;\n const type = attrs.get(\"type\") ?? null;\n if (type === null) {\n report.warning(\n \"validation-error\",\n ATTRIBUTE_TYPE_CODE,\n `attribute \"${id}\" declares no type; read as string`,\n where,\n );\n }\n const name = title !== null && title.length > 0 ? title : id;\n if (domain === \"edge\" && isWeightField(name, options.weightFrom)) {\n const declared = declareAttribute({ format: GEXF_FORMAT, id, title, type, long: options.long });\n for (const issue of declared.issues) {\n report.warning(issue.category, issue.code, issue.message, where);\n }\n this.weightAttr = { id, spec: declared.spec, table: INVALID_INDEX as ExtensionHandle };\n sink.setMeta({ weightOrigin: { format: GEXF_FORMAT, id, title, type, namespace: null } });\n return;\n }\n const declaredNames = domain === \"node\" ? this.declaredNodeNames : this.declaredEdgeNames;\n const reserved = domain === \"node\" ? RESERVED_NODE_NAMES : RESERVED_EDGE_NAMES;\n const taken = (candidate: string): boolean => reserved.has(candidate) || declaredNames.has(candidate);\n const input: AttributeDeclarationInput = {\n format: GEXF_FORMAT,\n id,\n title,\n type,\n defaultText: pending.defaultText,\n optionsText: pending.optionsText,\n listSyntax: \"gexf\",\n dynamic,\n long: options.long,\n taken,\n };\n const declared: DeclaredAttribute = declareAttribute(input);\n for (const issue of declared.issues) {\n report.warning(issue.category, issue.code, issue.message, where);\n }\n const resolved = declareResolved(sink, domain, declared.decl, report, where);\n declaredNames.add(resolved.decl.name);\n let companionDecl: ColumnDecl | null = null;\n if (declared.companion !== null) {\n companionDecl = {\n ...declared.companion,\n name: `${resolved.decl.name}.text`,\n extra: { for: resolved.decl.name },\n };\n declaredNames.add(companionDecl.name);\n }\n const valueDecl: Pick<ColumnDecl, \"dtype\" | \"itemDtype\" | \"options\" | \"origin\"> = {\n dtype: resolved.decl.dtype,\n itemDtype: resolved.decl.itemDtype,\n options: resolved.decl.options,\n origin: resolved.decl.origin,\n };\n tracked.set(id, {\n id,\n name: resolved.decl.name,\n spec: declared.spec,\n listSyntax: declared.listSyntax,\n handle: resolved.handle,\n companionDecl,\n companion: INVALID_INDEX as ColumnHandle,\n dynamic,\n valueDecl,\n table: INVALID_INDEX as ExtensionHandle,\n });\n }\n\n // ---------------------------------------------------------------- nodes\n\n /**\n * A child of `<nodes>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInNodes(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"node\") {\n this.unknownElement(name, line);\n return;\n }\n this.beginNode(attrs, line);\n }\n\n /**\n * Push one `<node>`.\n * @param attrs - its attributes\n * @param line - the line\n */\n private beginNode(attrs: ReadonlyMap<string, string>, line: number): void {\n const { report, sink } = this;\n this.checkAbort();\n const enclosing = this.nodeStack.length === 0 ? INVALID_INDEX : this.nodeStack[this.nodeStack.length - 1].index;\n const idText = attrs.get(\"id\");\n const where: IssueLocation = { line, element: idText ?? attrs.get(\"label\") ?? null };\n this.checkAttributeNames(attrs, NODE_ATTRIBUTES, \"node\", where);\n if (idText === undefined) {\n report.error(\"missing-value\", MISSING_ID_CODE, \"<node> without an id\", where);\n report.counts.skippedNodes++;\n this.nodeStack.push({ index: INVALID_INDEX, where });\n this.ctx.push(Ctx.Node);\n return;\n }\n let index: number;\n try {\n const id = this.coerceId(idText, where);\n const existing = sink.indexOf(id);\n if (existing !== INVALID_INDEX) {\n report.warning(\n \"validation-error\",\n DUPLICATE_NODE_CODE,\n `node \"${idText}\" is declared more than once; later attributes overwrite`,\n where,\n );\n index = existing;\n } else {\n index = sink.addNode(id);\n report.counts.nodes++;\n }\n } catch (err) {\n report.recordError(err, where);\n report.counts.skippedNodes++;\n this.nodeStack.push({ index: INVALID_INDEX, where });\n this.ctx.push(Ctx.Node);\n return;\n }\n this.nodeStack.push({ index, where });\n this.ctx.push(Ctx.Node);\n try {\n const label = attrs.get(\"label\");\n if (label !== undefined) {\n this.nodeColumns.label.set(sink, report, index, label, where);\n }\n const pid = attrs.get(\"pid\");\n if (pid !== undefined) {\n this.parentRefs.push({\n child: index,\n parentId: this.coerceId(pid, where),\n parentIndex: INVALID_INDEX,\n where,\n });\n } else if (enclosing !== INVALID_INDEX) {\n this.parentRefs.push({ child: index, parentId: null, parentIndex: enclosing, where });\n }\n this.writeLifetime(attrs, index, this.nodeColumns, where);\n } catch (err) {\n report.recordError(err, where);\n }\n }\n\n /**\n * A child of `<node>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInNode(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n const frame = this.nodeStack[this.nodeStack.length - 1];\n if (frame.index === INVALID_INDEX && local !== \"nodes\") {\n // the node was skipped; its children are too\n this.ctx.push(Ctx.Skip);\n return;\n }\n switch (local) {\n case \"attvalues\":\n this.ctx.push(Ctx.Attvalues);\n return;\n case \"parents\":\n this.parentIds = [];\n this.ctx.push(Ctx.Parents);\n return;\n case \"spells\":\n this.spellPairs = [];\n this.spellOpen = [];\n this.spellsWhere = frame.where;\n this.ctx.push(Ctx.Spells);\n return;\n case \"nodes\":\n this.reserve(attrs, \"node\", line);\n this.ctx.push(Ctx.Nodes);\n return;\n case \"color\":\n case \"position\":\n case \"size\":\n case \"shape\":\n this.writeViz(name, local, attrs, \"node\", frame.index, frame.where);\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A `<parent for>` inside `<parents>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInParents(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"parent\") {\n this.unknownElement(name, line);\n return;\n }\n this.ctx.push(Ctx.Skip);\n const frame = this.nodeStack[this.nodeStack.length - 1];\n const text = attrs.get(\"for\");\n if (text === undefined) {\n this.report.warning(\"missing-value\", ATTVALUE_SHAPE_CODE, \"<parent> without a for attribute\", frame.where);\n return;\n }\n try {\n this.parentIds?.push(this.coerceId(text, frame.where));\n } catch (err) {\n this.report.recordError(err, frame.where);\n }\n }\n\n /** Close `<parents>`: queue the list for resolution. */\n private finishParents(): void {\n const frame = this.nodeStack[this.nodeStack.length - 1];\n if (this.parentIds !== null && frame.index !== INVALID_INDEX) {\n this.parentsRefs.push({ child: frame.index, ids: this.parentIds, where: frame.where });\n }\n this.parentIds = null;\n }\n\n /**\n * Resolve every `pid`, nested and `<parents>` reference read so far now that every node is\n * declared (design section 8.4); an unknown parent is a missing-value error.\n */\n private resolveParents(): void {\n const { sink, report } = this;\n const refs = this.parentRefs;\n const lists = this.parentsRefs;\n this.parentRefs = [];\n this.parentsRefs = [];\n for (const ref of refs) {\n let parent = ref.parentIndex;\n if (ref.parentId !== null) {\n parent = sink.indexOf(ref.parentId);\n if (parent === INVALID_INDEX) {\n report.error(\n \"missing-value\",\n UNKNOWN_PARENT_CODE,\n `pid \"${String(ref.parentId)}\" names a node the document does not declare`,\n ref.where,\n );\n continue;\n }\n }\n try {\n this.parentColumn.set(sink, report, ref.child, parent, ref.where);\n } catch (err) {\n report.recordError(err, ref.where);\n }\n }\n for (const ref of lists) {\n const indices: number[] = [];\n for (const id of ref.ids) {\n const parent = sink.indexOf(id);\n if (parent === INVALID_INDEX) {\n report.error(\n \"missing-value\",\n UNKNOWN_PARENT_CODE,\n `<parent for=\"${String(id)}\"> names a node the document does not declare`,\n ref.where,\n );\n continue;\n }\n indices.push(parent);\n }\n try {\n this.parentsColumn.set(sink, report, ref.child, indices, ref.where);\n } catch (err) {\n report.recordError(err, ref.where);\n }\n }\n }\n\n // ---------------------------------------------------------------- edges\n\n /**\n * A child of `<edges>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInEdges(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"edge\") {\n this.unknownElement(name, line);\n return;\n }\n this.beginEdge(attrs, line);\n }\n\n /**\n * Push one `<edge>`.\n * @param attrs - its attributes\n * @param line - the line\n */\n private beginEdge(attrs: ReadonlyMap<string, string>, line: number): void {\n const { report, sink, options } = this;\n this.checkAbort();\n this.ctx.push(Ctx.Edge);\n this.edge = null;\n const sourceText = attrs.get(\"source\");\n const targetText = attrs.get(\"target\");\n const idText = attrs.get(\"id\");\n const { where } = this.edgeFrame;\n where.line = line;\n where.element = idText ?? edgeElement(sourceText, targetText);\n this.checkAttributeNames(attrs, EDGE_ATTRIBUTES, \"edge\", where);\n if (sourceText === undefined || targetText === undefined) {\n report.error(\n \"missing-value\",\n MISSING_ENDPOINT_CODE,\n `<edge> without a ${sourceText === undefined ? \"source\" : \"target\"}`,\n where,\n );\n report.counts.skippedEdges++;\n return;\n }\n let kind: EdgeKind = this.defaultKind;\n const typeText = attrs.get(\"type\");\n if (typeText !== undefined) {\n const type = edgeTypeKeyword(typeText);\n if (!EDGE_TYPES.has(type)) {\n report.error(\n \"validation-error\",\n EDGE_TYPE_CODE,\n `edge type \"${typeText}\" is not directed, undirected or mutual`,\n where,\n );\n report.counts.skippedEdges++;\n return;\n }\n kind = type as EdgeKind;\n }\n if (idText !== undefined) {\n if (this.edgeIds.has(idText)) {\n report.error(\n \"validation-error\",\n DUPLICATE_EDGE_ID_CODE,\n `edge id \"${idText}\" is declared more than once; the edge is skipped`,\n where,\n );\n report.counts.skippedEdges++;\n return;\n }\n this.edgeIds.add(idText);\n }\n let index: number;\n try {\n const source = this.coerceId(sourceText, where);\n const target = this.coerceId(targetText, where);\n if (!options.addMissingNodes) {\n if (sink.indexOf(source) === INVALID_INDEX) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge references undeclared node \"${sourceText}\"`, {\n id: source,\n });\n }\n if (sink.indexOf(target) === INVALID_INDEX) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge references undeclared node \"${targetText}\"`, {\n id: target,\n });\n }\n }\n const weight = this.xmlWeight(attrs, where);\n const before = sink.edgeCount;\n index = this.resolver.addEdge(source, target, kind, weight, where);\n report.counts.edges += sink.edgeCount - before;\n } catch (err) {\n report.recordError(err, where);\n report.counts.skippedEdges++;\n return;\n }\n const frame = this.edgeFrame;\n frame.index = index;\n frame.mirror = this.resolver.lastMirror;\n this.edge = frame;\n try {\n if (idText !== undefined) {\n this.edgeIdColumn.set(sink, report, index, idText, where);\n }\n const label = attrs.get(\"label\");\n if (label !== undefined) {\n this.edgeColumns.label.set(sink, report, index, label, where);\n }\n const edgeKind = attrs.get(\"kind\");\n if (edgeKind !== undefined) {\n this.edgeKindColumn.set(sink, report, index, edgeKind, where);\n }\n this.writeLifetime(attrs, index, this.edgeColumns, where);\n } catch (err) {\n report.recordError(err, where);\n }\n }\n\n /**\n * The weight argument of one edge from its `weight` XML attribute; undefined when absent (the\n * sink records a defaulted weight, design section 3.7).\n * @param attrs - the edge's attributes\n * @param where - the edge's location\n * @returns the weight, or undefined\n */\n private xmlWeight(attrs: ReadonlyMap<string, string>, where: IssueLocation): number | undefined {\n const text = attrs.get(\"weight\");\n if (text === undefined) {\n return undefined;\n }\n if (this.options.weightFrom === null) {\n this.report.warnOnce(\n \"coercion\",\n WEIGHT_IGNORED_CODE,\n \"the weight attribute is ignored because weightFrom is null; edges are unweighted\",\n where,\n );\n return undefined;\n }\n return parseWeightText(text);\n }\n\n /**\n * A child of `<edge>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInEdge(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n const { edge } = this;\n if (edge === null) {\n this.ctx.push(Ctx.Skip);\n return;\n }\n switch (local) {\n case \"attvalues\":\n this.ctx.push(Ctx.Attvalues);\n return;\n case \"spells\":\n this.spellPairs = [];\n this.spellOpen = [];\n this.spellsWhere = edge.where;\n this.ctx.push(Ctx.Spells);\n return;\n case \"color\":\n case \"thickness\":\n case \"shape\":\n this.writeViz(name, local, attrs, \"edge\", edge.index, edge.where);\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n // ---------------------------------------------------------------- attribute values\n\n /**\n * An `<attvalue>` of the open node or edge; a value that does not parse is recorded and skipped\n * without losing the element or its other values.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInAttvalues(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"attvalue\") {\n this.unknownElement(name, line);\n return;\n }\n this.ctx.push(Ctx.Skip);\n const { report, edge } = this;\n const domain: \"node\" | \"edge\" = edge === null ? \"node\" : \"edge\";\n let index: number;\n let element: string | null;\n if (edge !== null) {\n ({ index } = edge);\n element = edge.where.element ?? null;\n } else {\n const frame = this.nodeStack[this.nodeStack.length - 1];\n ({ index } = frame);\n element = frame.where.element ?? null;\n }\n if (index === INVALID_INDEX) {\n return;\n }\n const forId = attrs.get(\"for\");\n const { valueWhere } = this;\n valueWhere.line = line;\n valueWhere.element = element;\n if (forId === undefined) {\n report.warning(\"missing-value\", ATTVALUE_SHAPE_CODE, \"<attvalue> without a for attribute\", valueWhere);\n return;\n }\n const value = attrs.get(\"value\");\n if (value === undefined) {\n report.warning(\n \"missing-value\",\n ATTVALUE_SHAPE_CODE,\n `<attvalue for=\"${forId}\"> without a value attribute`,\n valueWhere,\n );\n return;\n }\n try {\n if (domain === \"edge\" && this.weightAttr !== null && this.weightAttr.id === forId) {\n if (isTimed(attrs)) {\n this.writeTimedWeight(attrs, value, index, valueWhere);\n } else {\n this.applyStaticWeight(value, valueWhere);\n }\n return;\n }\n const tracked = domain === \"node\" ? this.nodeAttrs : this.edgeAttrs;\n const attribute = tracked.get(forId);\n if (attribute === undefined) {\n const key = `${domain}:${forId}`;\n if (!this.unknownAttributes.has(key)) {\n this.unknownAttributes.add(key);\n report.warning(\n \"missing-value\",\n UNKNOWN_ATTRIBUTE_CODE,\n `<attvalue for=\"${forId}\"> names an undeclared ${domain} attribute; its values are dropped`,\n { ...valueWhere, element: forId },\n );\n }\n return;\n }\n if (isTimed(attrs)) {\n this.writeTimedValue(attribute, domain, attrs, value, index, valueWhere);\n } else {\n this.writeStaticValue(attribute, domain, value, index, valueWhere);\n }\n } catch (err) {\n report.recordError(err, { ...valueWhere, element: `${element ?? \"?\"}[${forId}]` });\n }\n }\n\n /**\n * A static value of the attribute titled `weightFrom` overrides the XML weight of the open\n * edge (and of its mirror half, design section 3.6).\n * @param text - the value text\n * @param where - the value's location\n */\n private applyStaticWeight(text: string, where: IssueLocation): void {\n const { edge, sink } = this;\n if (edge === null) {\n return;\n }\n const weight = parseWeightText(text);\n if (weight === undefined) {\n throw new GraphFormatError(\"E_INVALID_WEIGHT\", \"an edge weight cannot be blank\", {\n value: text,\n line: where.line ?? null,\n });\n }\n sink.setEdgeWeight(edge.index, weight);\n if (edge.mirror !== INVALID_INDEX) {\n sink.setEdgeWeight(edge.mirror, weight);\n }\n }\n\n /**\n * Parse a value by its declaration and write the cell (and the temporal companion, declared\n * on the first value whose text is not canonical, design section 5.1).\n * @param attribute - the declaration\n * @param domain - node or edge\n * @param text - the value text\n * @param index - the element's index\n * @param where - the value's location\n */\n private writeStaticValue(\n attribute: TrackedAttribute,\n domain: \"node\" | \"edge\",\n text: string,\n index: number,\n where: IssueLocation,\n ): void {\n const { spec } = attribute;\n if (spec.temporal !== null && !spec.list) {\n const parsed = parseDeclaredTemporal(text, spec);\n this.setCell(domain, attribute.handle, index, parsed.value);\n if (parsed.text !== null && attribute.companionDecl !== null) {\n if (attribute.companion === INVALID_INDEX) {\n attribute.companion = declareCompanion(this.sink, domain, attribute.companionDecl, this.report);\n }\n this.setCell(domain, attribute.companion, index, parsed.text);\n }\n return;\n }\n const value = parseDeclaredValue(text, spec, attribute.listSyntax);\n if (losesPrecision(spec, text)) {\n this.report.warning(\n \"precision\",\n PRECISION_CODE,\n `long value ${text.trim()} of \"${attribute.name}\" exceeds 2^53 and was rounded`,\n where,\n );\n }\n this.setCell(domain, attribute.handle, index, value);\n }\n\n /**\n * Append a timed value to the attribute's temporal table (design section 5.10), creating the\n * table on first use.\n * @param attribute - the declaration\n * @param domain - node or edge\n * @param attrs - the `<attvalue>` attributes carrying the bounds\n * @param text - the value text\n * @param index - the element's index\n * @param where - the value's location\n */\n private writeTimedValue(\n attribute: TrackedAttribute,\n domain: \"node\" | \"edge\",\n attrs: ReadonlyMap<string, string>,\n text: string,\n index: number,\n where: IssueLocation,\n ): void {\n const { sink, report } = this;\n if (!attribute.dynamic) {\n report.warnOnce(\n \"validation-error\",\n TIMED_STATIC_CODE,\n `attribute \"${attribute.name}\" is declared static but has timed values; they are stored as dynamic`,\n where,\n );\n }\n const { spec } = attribute;\n const temporalValue = spec.temporal !== null && !spec.list;\n if (attribute.table === INVALID_INDEX) {\n attribute.table = sink.addExtensionTable(\n temporalTableName(domain, attribute.name),\n temporalTableDecls(domain, attribute.valueDecl, temporalValue),\n );\n }\n let value: unknown;\n let valueText: string | null = null;\n if (temporalValue) {\n const parsed = parseDeclaredTemporal(text, spec);\n ({ value } = parsed);\n valueText = parsed.text;\n } else {\n value = parseDeclaredValue(text, spec, attribute.listSyntax);\n if (losesPrecision(spec, text)) {\n report.warning(\n \"precision\",\n PRECISION_CODE,\n `long value ${text.trim()} of \"${attribute.name}\" exceeds 2^53 and was rounded`,\n where,\n );\n }\n }\n const row = this.temporalRow(attrs, index, value, where);\n if (temporalValue) {\n row.push(valueText ?? undefined);\n }\n sink.addExtensionRow(attribute.table, row);\n }\n\n /**\n * Append a timed weight to the `temporal:edge:weight` table (design section 5.10).\n * @param attrs - the `<attvalue>` attributes carrying the bounds\n * @param text - the value text\n * @param index - the edge index\n * @param where - the value's location\n */\n private writeTimedWeight(\n attrs: ReadonlyMap<string, string>,\n text: string,\n index: number,\n where: IssueLocation,\n ): void {\n const { weightAttr } = this;\n if (weightAttr === null) {\n return;\n }\n const { sink } = this;\n if (weightAttr.table === INVALID_INDEX) {\n weightAttr.table = sink.addExtensionTable(\n temporalTableName(\"edge\", this.options.weightFrom ?? \"weight\"),\n temporalTableDecls(\n \"edge\",\n {\n dtype: \"f64\",\n origin: { format: GEXF_FORMAT, id: weightAttr.id, type: weightAttr.spec.declared },\n },\n false,\n ),\n );\n }\n const value = parseWeightText(text);\n if (value === undefined) {\n throw new GraphFormatError(\"E_INVALID_WEIGHT\", \"a timed edge weight cannot be blank\", {\n value: text,\n line: where.line ?? null,\n });\n }\n sink.addExtensionRow(weightAttr.table, this.temporalRow(attrs, index, value, where));\n }\n\n /**\n * The row of a temporal table for one timed value: element, bounds, value, bound texts, open bits.\n * @param attrs - the attributes carrying `start` / `end` / `timestamp` / `startopen` / `endopen`\n * @param index - the element's index\n * @param value - the parsed value\n * @param where - the value's location\n * @returns the row, without the optional value text\n */\n private temporalRow(\n attrs: ReadonlyMap<string, string>,\n index: number,\n value: unknown,\n where: IssueLocation,\n ): unknown[] {\n const bounds = this.readBounds(attrs, where);\n return [\n index,\n bounds.start.value,\n bounds.end.value,\n value,\n bounds.start.text ?? undefined,\n bounds.end.text ?? undefined,\n bounds.open === 0 ? undefined : bounds.open,\n ];\n }\n\n /**\n * The interval of an element or timed value: `timestamp`, or `start` / `startopen` and `end` /\n * `endopen` (GEXF 1.2: the open form carries the bound's time and marks the bound open, design\n * section 5.1); missing bounds are unbounded.\n * @param attrs - the attributes\n * @param where - the location, for the conflict warning\n * @returns the bounds and the open bits\n */\n private readBounds(\n attrs: ReadonlyMap<string, string>,\n where: IssueLocation,\n ): { start: TemporalValue; end: TemporalValue; open: number } {\n let start: TemporalValue = { value: -Infinity, text: null };\n let end: TemporalValue = { value: Infinity, text: null };\n let open = 0;\n const timestamp = attrs.get(\"timestamp\");\n if (timestamp !== undefined) {\n start = parseTimeText(timestamp, this.timeFormat);\n end = start;\n }\n const startText = attrs.get(\"start\");\n const startOpen = attrs.get(\"startopen\");\n if (startText !== undefined) {\n start = parseTimeText(startText, this.timeFormat);\n if (startOpen !== undefined) {\n this.warnOpenConflict(\"start\", where);\n }\n } else if (startOpen !== undefined) {\n start = parseTimeText(startOpen, this.timeFormat);\n open |= OPEN_START;\n }\n const endText = attrs.get(\"end\");\n const endOpen = attrs.get(\"endopen\");\n if (endText !== undefined) {\n end = parseTimeText(endText, this.timeFormat);\n if (endOpen !== undefined) {\n this.warnOpenConflict(\"end\", where);\n }\n } else if (endOpen !== undefined) {\n end = parseTimeText(endOpen, this.timeFormat);\n open |= OPEN_END;\n }\n return { start, end, open };\n }\n\n /**\n * Record a `start` next to a `startopen` (or `end` next to `endopen`), which the 1.2 primer forbids.\n * @param bound - which bound\n * @param where - the location\n */\n private warnOpenConflict(bound: \"start\" | \"end\", where: IssueLocation): void {\n this.report.warnOnce(\n \"validation-error\",\n OPEN_BOUND_CONFLICT_CODE,\n `both ${bound} and ${bound}open are given; the closed bound is kept`,\n where,\n );\n }\n\n // ---------------------------------------------------------------- lifetimes\n\n /**\n * Write an element's lifetime: `start` / `end` / `timestamp` (with text companions), the 1.2\n * `startopen` / `endopen` bounds and bits, and the 1.3 `timestamps` / `intervals` attributes.\n * @param attrs - the node or edge attributes\n * @param index - its index\n * @param columns - the domain's columns\n * @param where - the element's location\n */\n private writeLifetime(\n attrs: ReadonlyMap<string, string>,\n index: number,\n columns: DomainColumns,\n where: IssueLocation,\n ): void {\n const { sink, report } = this;\n if (\n attrs.has(\"start\") ||\n attrs.has(\"end\") ||\n attrs.has(\"timestamp\") ||\n attrs.has(\"startopen\") ||\n attrs.has(\"endopen\")\n ) {\n const bounds = this.readBounds(attrs, where);\n const timestamp = attrs.get(\"timestamp\");\n if (timestamp !== undefined) {\n columns.timestamp.set(sink, report, index, bounds.start, where);\n }\n if (attrs.has(\"start\") || attrs.has(\"startopen\")) {\n columns.start.set(sink, report, index, bounds.start, where);\n }\n if (attrs.has(\"end\") || attrs.has(\"endopen\")) {\n columns.end.set(sink, report, index, bounds.end, where);\n }\n if (bounds.open !== 0) {\n columns.open.set(sink, report, index, bounds.open, where);\n }\n }\n const timestamps = attrs.get(\"timestamps\");\n if (timestamps !== undefined) {\n const items = splitListText(stripAngles(timestamps), \"brackets\");\n columns.timestamps.set(\n sink,\n report,\n index,\n items.map((item) => parseTimeText(item, this.timeFormat).value),\n where,\n );\n }\n const intervals = attrs.get(\"intervals\");\n if (intervals !== undefined) {\n columns.spells.set(sink, report, index, this.parseIntervals(intervals, where), where);\n }\n }\n\n /**\n * Parse a 1.3 `intervals=\"<[s, e]; [s, e]>\"` attribute into spell pairs.\n * @param text - the attribute text\n * @param where - the element's location, for the error\n * @returns the pairs\n */\n private parseIntervals(text: string, where: IssueLocation): number[][] {\n const pairs: number[][] = [];\n for (const part of stripAngles(text).split(\";\")) {\n if (part.trim().length === 0) {\n continue;\n }\n const items = splitListText(part, \"brackets\");\n if (items.length !== 2) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `interval \"${part.trim()}\" is not a [start, end] pair`, {\n value: part,\n line: where.line ?? null,\n });\n }\n pairs.push([\n parseTimeText(items[0], this.timeFormat).value,\n parseTimeText(items[1], this.timeFormat).value,\n ]);\n }\n return pairs;\n }\n\n /**\n * A `<spell>` inside `<spells>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInSpells(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"spell\") {\n this.unknownElement(name, line);\n return;\n }\n this.ctx.push(Ctx.Skip);\n const where = this.spellsWhere ?? { line };\n try {\n const bounds = this.readBounds(attrs, where);\n this.spellPairs?.push([bounds.start.value, bounds.end.value]);\n this.spellOpen.push(bounds.open);\n } catch (err) {\n this.report.recordError(err, where);\n }\n }\n\n /**\n * Close `<spells>`: write the pairs into the open element's spells column, and their open bits\n * into the spells.open column when any spell has an open bound.\n */\n private finishSpells(): void {\n const pairs = this.spellPairs;\n const open = this.spellOpen;\n const where = this.spellsWhere ?? undefined;\n this.spellPairs = null;\n this.spellOpen = [];\n this.spellsWhere = null;\n if (pairs === null) {\n return;\n }\n try {\n const columns = this.edge === null ? this.nodeColumns : this.edgeColumns;\n const { index } = this.edge ?? this.nodeStack[this.nodeStack.length - 1];\n if (index !== INVALID_INDEX) {\n columns.spells.set(this.sink, this.report, index, pairs, where);\n if (open.some((bits) => bits !== 0)) {\n columns.spellsOpen.set(this.sink, this.report, index, open, where);\n }\n }\n } catch (err) {\n this.report.recordError(err, where);\n }\n }\n\n // ---------------------------------------------------------------- viz\n\n /**\n * Write one viz element into its role column; a value that does not parse is a recorded\n * warning and the element is skipped.\n * @param name - the element name as written\n * @param local - its local name\n * @param attrs - its attributes\n * @param domain - node or edge\n * @param index - the element's index\n * @param where - the element's location\n */\n private writeViz(\n name: string,\n local: string,\n attrs: ReadonlyMap<string, string>,\n domain: \"node\" | \"edge\",\n index: number,\n where: IssueLocation,\n ): void {\n const { sink, report } = this;\n if (!this.viz) {\n report.warnOnce(\"unsupported\", VIZ_SKIPPED_CODE, \"viz elements are skipped (option viz: false)\", where);\n return;\n }\n if (isTimed(attrs)) {\n report.warnOnce(\n \"unsupported\",\n VIZ_DYNAMIC_CODE,\n \"dynamic viz elements are not supported; the bounds are dropped and the last value kept\",\n where,\n );\n }\n const columns = domain === \"node\" ? this.nodeColumns : this.edgeColumns;\n try {\n switch (local) {\n case \"color\":\n columns.color.set(sink, report, index, parseColor(attrs), where);\n break;\n case \"position\": {\n const x = vizNumber(attrs, \"x\");\n const y = vizNumber(attrs, \"y\");\n const z = attrs.has(\"z\") ? vizNumber(attrs, \"z\") : 0;\n this.positionColumn ??= new LazyColumn(\"node\", {\n ...NODE_DECLS.position,\n extra: { ...NODE_DECLS.position.extra, sourceDims: attrs.has(\"z\") ? 3 : 2 },\n });\n this.positionColumn.set(sink, report, index, [x, y, z], where);\n break;\n }\n case \"size\":\n this.sizeColumn.set(sink, report, index, vizNumber(attrs, \"value\"), where);\n break;\n case \"thickness\":\n this.thicknessColumn.set(sink, report, index, vizNumber(attrs, \"value\"), where);\n break;\n case \"shape\": {\n const value = attrs.get(\"value\");\n if (value === undefined) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", \"<viz:shape> without a value\", { element: name });\n }\n columns.shape.set(sink, report, index, value, where);\n const uri = attrs.get(\"uri\");\n if (domain === \"node\" && uri !== undefined) {\n this.shapeUriColumn.set(sink, report, index, uri, where);\n }\n break;\n }\n default:\n break;\n }\n } catch (err) {\n if (!(err instanceof GraphFormatError) || err.code !== \"E_COLUMN_TYPE\") {\n throw err;\n }\n report.warning(\"validation-error\", VIZ_VALUE_CODE, `<${name}> skipped: ${err.message}`, where);\n }\n }\n\n // ---------------------------------------------------------------- helpers\n\n /**\n * Report an element the schema does not define at this place and skip its subtree.\n * @param name - the element name\n * @param line - the line\n */\n private unknownElement(name: string, line: number): void {\n this.report.warnOnce(\"unsupported\", UNKNOWN_ELEMENT_CODE, `element <${name}> is not GEXF and was skipped`, {\n line,\n element: name,\n });\n this.ctx.push(Ctx.Skip);\n }\n\n /**\n * Report XML attributes the importer does not read (once per attribute name and domain).\n * @param attrs - the element's attributes\n * @param known - the attribute names read\n * @param domain - node or edge\n * @param where - the element's location\n */\n private checkAttributeNames(\n attrs: ReadonlyMap<string, string>,\n known: ReadonlySet<string>,\n domain: \"node\" | \"edge\",\n where: IssueLocation,\n ): void {\n for (const key of attrs.keys()) {\n if (!known.has(key)) {\n const seen = `${domain}@${key}`;\n if (!this.unknownAttributes.has(seen)) {\n this.unknownAttributes.add(seen);\n this.report.warning(\n \"unsupported\",\n UNKNOWN_ELEMENT_CODE,\n `attribute ${key} of <${domain}> is not GEXF and was ignored`,\n { ...where, element: key },\n );\n }\n }\n }\n }\n\n /**\n * Write one cell of a domain.\n * @param domain - node or edge\n * @param handle - the column\n * @param index - the row\n * @param value - the value\n */\n private setCell(domain: \"node\" | \"edge\", handle: ColumnHandle, index: number, value: unknown): void {\n if (domain === \"node\") {\n this.sink.setNodeValue(handle, index, value);\n } else {\n this.sink.setEdgeValue(handle, index, value);\n }\n }\n\n /**\n * Coerce an id text, recording a merge under ids \"number\".\n * @param text - the id text\n * @param where - the location, for the merge warning\n * @returns the id\n */\n private coerceId(text: string, where: IssueLocation): NodeId {\n const id = this.coercer.text(text);\n const merge = this.coercer.lastMerge;\n if (merge !== null) {\n this.report.warning(\n \"coercion\",\n ID_MERGED_CODE,\n `id text \"${merge.text}\" merged with \"${merge.previousText}\" as ${merge.id} under ids \"number\"`,\n where,\n );\n }\n return id;\n }\n\n /** Check the cancellation signal every ABORT_CHECK_INTERVAL elements. */\n private checkAbort(): void {\n if (++this.elementsSinceCheck >= ABORT_CHECK_INTERVAL) {\n this.elementsSinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n}\n\n/**\n * The element text of an edge without an id, for issues.\n * @param source - the source text, or undefined\n * @param target - the target text, or undefined\n * @returns `source->target`\n */\nfunction edgeElement(source: string | undefined, target: string | undefined): string {\n return `${source ?? \"?\"}->${target ?? \"?\"}`;\n}\n\n/**\n * Whether an element carries time bounds.\n * @param attrs - the element's attributes\n * @returns true when start, end, timestamp or an open bound is present\n */\nfunction isTimed(attrs: ReadonlyMap<string, string>): boolean {\n return (\n attrs.has(\"start\") ||\n attrs.has(\"end\") ||\n attrs.has(\"timestamp\") ||\n attrs.has(\"startopen\") ||\n attrs.has(\"endopen\")\n );\n}\n\n/**\n * Remove the `<` `>` wrapper of a 1.3 `timestamps` / `intervals` attribute value.\n * @param text - the attribute text\n * @returns the inner text\n */\nfunction stripAngles(text: string): string {\n let inner = text.trim();\n if (inner.startsWith(\"<\")) {\n inner = inner.slice(1);\n }\n if (inner.endsWith(\">\")) {\n inner = inner.slice(0, -1);\n }\n return inner;\n}\n\n/**\n * A numeric viz attribute.\n * @param attrs - the element's attributes\n * @param name - the attribute name\n * @returns the number; E_COLUMN_TYPE when absent or not a number\n */\nfunction vizNumber(attrs: ReadonlyMap<string, string>, name: string): number {\n const text = attrs.get(name);\n if (text === undefined) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `viz element without a ${name} attribute`, { attribute: name });\n }\n const value = parseDecimalText(text);\n if (Number.isNaN(value)) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `viz ${name}=\"${text}\" is not a number`, { attribute: name });\n }\n return value;\n}\n\n/**\n * Parse `<viz:color r g b a hex>` into rgba in 0..1 (design section 5.5: role color, f32 x4).\n * @param attrs - the element's attributes\n * @returns [r, g, b, a]\n */\nfunction parseColor(attrs: ReadonlyMap<string, string>): number[] {\n let r: number;\n let g: number;\n let b: number;\n const hex = attrs.get(\"hex\");\n if (hex !== undefined && !attrs.has(\"r\")) {\n const digits = hex.startsWith(\"#\") ? hex.slice(1) : hex;\n if (!/^[0-9a-fA-F]{6}$/.test(digits)) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `viz hex=\"${hex}\" is not a #RRGGBB colour`, {\n attribute: \"hex\",\n });\n }\n r = Number.parseInt(digits.slice(0, 2), 16);\n g = Number.parseInt(digits.slice(2, 4), 16);\n b = Number.parseInt(digits.slice(4, 6), 16);\n } else {\n r = vizNumber(attrs, \"r\");\n g = vizNumber(attrs, \"g\");\n b = vizNumber(attrs, \"b\");\n }\n const a = attrs.has(\"a\") ? vizNumber(attrs, \"a\") : 1;\n return [r / 255, g / 255, b / 255, a];\n}\n\n/** A head that starts with markup, after an optional byte-order mark and whitespace. */\nconst XML_START = /^\\uFEFF?\\s*</;\n\n/**\n * Confidence that a document head is GEXF.\n * @param head - the first bytes\n * @returns 1 for a `<gexf` tag, 0.8 for a gexf.net namespace, 0 otherwise or when the head does\n * not start with markup\n */\nfunction sniffGexf(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\", { fatal: false }).decode(head);\n // Only a document that starts as markup: a JSON or CSV value may mention a `<gexf>` tag.\n if (!XML_START.test(text)) {\n return 0;\n }\n if (/<(\\w+:)?gexf[\\s>]/.test(text)) {\n return 1;\n }\n return text.includes(\"gexf.net\") ? 0.8 : 0;\n}\n\n/**\n * Validate the format-specific options.\n * @param options - the caller's options\n * @returns whether viz elements are imported\n */\nfunction resolveGexfOptions(options: (GexfImportOptions & CommonImportOptions) | undefined): boolean {\n const viz = options?.viz;\n if (viz === undefined) {\n return true;\n }\n if (typeof viz !== \"boolean\") {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option viz: ${typeof viz} is not a boolean`, {\n option: \"viz\",\n found: viz,\n });\n }\n return viz;\n}\n\n/** The GEXF importer (design section 8.4). */\nexport const gexfImporter: GraphImporter<GexfImportOptions> = Object.freeze({\n format: GEXF_FORMAT,\n extensions: Object.freeze([\".gexf\"]),\n mimeTypes: Object.freeze([\"application/gexf+xml\", \"application/xml\", \"text/xml\"]),\n sniff: sniffGexf,\n /**\n * Read a GEXF document into the sink in one streaming pass.\n * @param input - the document as text, bytes, a stream or chunks\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: GexfImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const resolved = resolveImportOptions(options, {\n ids: \"canonical\",\n defaultDirected: false,\n weightFrom: \"weight\",\n addMissingNodes: false,\n });\n const viz = resolveGexfOptions(options);\n const report = new ImportReportBuilder(GEXF_FORMAT, resolved.errorLimit);\n reportSinkOptions(sink, options, report, true);\n // nodeIdFrom is among the options reportUnusedOptions() reports: GEXF ids are mandatory\n reportUnusedOptions(options, report, USED_OPTIONS);\n const reader = new GexfReader(sink, report, resolved, viz);\n try {\n await tokenizeXml(\n textChunks(input, report, { ...resolved, declaredEncoding: xmlDeclaredEncoding }),\n reader,\n );\n } catch (err) {\n if (err instanceof XmlSyntaxError) {\n report.fail(XML_SYNTAX_CODE, err.message, { line: err.line });\n }\n throw err;\n }\n reader.finish();\n // an abort raised during the last few elements (after the last periodic check) still rejects\n throwIfAborted(resolved.signal);\n return report.finish();\n },\n});\n","/**\n * The GEXF exporter (design sections 8.5, 3.6, 3.7, 5.1, 5.10; research note 07 section 9): writes\n * GEXF 1.3 by default (1.2 on request), restoring declared attributes from `origin` (id, title,\n * type, defaults, options), the viz namespace from the position / color / size / shape /\n * thickness role columns, containment from the parent / parents columns, element lifetimes from\n * the temporal role columns (with the text companions of design section 5.1), and dynamic\n * attribute values from the temporal extension tables of design section 5.10. Expanded\n * mixed-direction pairs are folded back through the `pair` / `directed` / `mutual` roles into one\n * undirected or mutual edge; weights are written for explicit rows only (the role-weight column's\n * validity, design section 3.7). check() lists every loss before anything is written: the generic\n * capability gaps (W_OPEN_INTERVAL in 1.3, u32 / u8 dtypes, strides, nested json, graph\n * attributes, foreign extension tables) and the GEXF-specific ones (1.2 has no `kind`, no\n * timestamps and no typed lists; role columns of an unexpected shape; roles the format cannot\n * carry; attribute titles the importer would rename).\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot, INVALID_INDEX } from \"@graphty/graph-format\";\n\nimport { mapDeclaredType } from \"../../common/declared-types.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { escapeXmlAttribute, escapeXmlText } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, LOSS, sanitizeIds } from \"../../common/export.js\";\nimport { formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { isCanonicalIntegerText } from \"../../common/ids.js\";\nimport { joinListText } from \"../../common/lists.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { formatTemporal, formatTimeValue, type TimeFormat } from \"../../common/temporal.js\";\nimport { explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { xmlIllegalTextNotes } from \"../../common/xml.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport {\n canonicalScalarType,\n GEXF_FORMAT,\n GEXF_NAMESPACES,\n type GexfEdgeType,\n type GexfVersion,\n isListType,\n isScalarType,\n NODE_COLUMNS,\n OPEN_END,\n OPEN_START,\n parseTemporalTableName,\n RESERVED_EDGE_NAMES,\n RESERVED_NODE_NAMES,\n TEMPORAL_COLUMNS,\n VIZ_NAMESPACE,\n} from \"./schema.js\";\n\n/** The format-specific options of the GEXF exporter. */\nexport interface GexfExportOptions {\n /** The GEXF version to write: \"1.3\" (default) or \"1.2\". */\n version?: GexfVersion | undefined;\n}\n\n/** LossNote codes specific to the GEXF exporter, next to the shared LOSS codes. */\nexport const GEXF_LOSS = Object.freeze({\n /** GEXF 1.2 has no parallel-edge `kind`; the kind column is dropped. */\n KIND_DROPPED: \"W_GEXF_KIND_DROPPED\",\n /** GEXF 1.2 has no timestamps; a timestamp becomes a closed interval [t, t]. */\n TIMESTAMP_AS_INTERVAL: \"W_TIMESTAMP_AS_INTERVAL\",\n /** GEXF 1.2 liststring items are separated by `|`; an item containing one cannot be split back. */\n LIST_SEPARATOR: \"W_LIST_SEPARATOR\",\n /** A role column of a shape GEXF cannot map (a string `start`, a 2-component color); written as a plain attribute. */\n ROLE_SHAPE: \"W_ROLE_SHAPE\",\n /** A temporal extension table without the element / start / end / value columns of design section 5.10. */\n TEMPORAL_TABLE_SHAPE: \"W_TEMPORAL_TABLE_SHAPE\",\n /** An attribute whose title the importer would rename on re-import (a reserved name). */\n ATTRIBUTE_RENAMED: \"W_ATTRIBUTE_RENAMED\",\n /** A cell, default or option the declared type cannot express (skipped). */\n VALUE_UNWRITABLE: \"W_VALUE_UNWRITABLE\",\n /** A declared type the target version lacks (1.2: date, dateTime, typed lists...); the canonical type is written. */\n DECLARED_TYPE: \"W_DECLARED_TYPE\",\n /** A node id whose text reads back as the other type under the canonical rule (design section 4.1): a non-integer number, a string of integer text. */\n ID_TEXT_TYPE: LOSS.ID_TEXT_TYPE,\n /** A viz role column (position, color, size, thickness) that is not f32; the importer reads viz values as f32. */\n VIZ_DTYPE: \"W_GEXF_VIZ_DTYPE\",\n /** A plain `weight` edge column reads back as THE weight (the importer's weightFrom default). */\n WEIGHT_KEY_CLASH: LOSS.WEIGHT_KEY_CLASH,\n /** A dict column without declared options gains one from its dictionary on re-import. */\n OPTIONS_GAINED: LOSS.OPTIONS_GAINED,\n /** A string cell holding a character XML 1.0 forbids; export() throws E_COLUMN_TYPE. */\n XML_ILLEGAL_CHAR: LOSS.XML_ILLEGAL_CHAR,\n});\n\nconst DTYPES_KEPT = [\"f32\", \"f64\", \"i32\", \"bool\", \"dict\", \"string\"] as const;\n\n/** GEXF 1.3: everything the model has but nested json, strides, graph attributes and open intervals. */\nconst CAPABILITIES_1_3: ExportCapabilities = capabilities({\n mixedDirection: true,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"optional\",\n idCharset: \"any\",\n dtypes: DTYPES_KEPT,\n lists: true,\n defaults: true,\n options: true,\n hierarchy: true,\n temporal: \"dynamic-values\",\n positions: true,\n viz: true,\n});\n\n/** GEXF 1.2: no parallel edges, required edge ids, `liststring` only. */\nconst CAPABILITIES_1_2: ExportCapabilities = capabilities({\n ...CAPABILITIES_1_3,\n multiEdges: false,\n edgeIds: \"required\",\n});\n\nconst STRUCTURAL_ROLES: ReadonlySet<string> = new Set([\"directed\", \"pair\", \"mutual\", \"weight\", \"timeText\"]);\n\n/** The attribute title the importer reads THE weight from by default (its weightFrom default). */\nconst DEFAULT_WEIGHT_TITLE = \"weight\";\nconst NUMERIC_DTYPES: ReadonlySet<string> = new Set([\"f32\", \"f64\", \"i32\", \"u32\", \"u8\"]);\nconst TEXT_DTYPES: ReadonlySet<string> = new Set([\"string\", \"dict\"]);\n\n/** Formats one cell value as GEXF text; null when the value cannot be expressed. */\ntype ValueFormatter = (value: unknown) => string | null;\n\n/** The GEXF type of a column and how its values are written. */\ninterface TypedAttribute {\n /** The type text written in the declaration. */\n readonly type: string;\n /** Whether it is a list type. */\n readonly list: boolean;\n /** The item type of a list, the type itself otherwise. */\n readonly itemType: string;\n /** The value formatter. */\n readonly format: ValueFormatter;\n /** A declared type the target version cannot express (written as `type` instead), or null. */\n readonly dropped: string | null;\n}\n\n/** A temporal extension table resolved to its columns (design section 5.10). */\ninterface TemporalTable {\n readonly element: Column;\n readonly start: Column;\n readonly end: Column;\n readonly value: Column;\n readonly startText: Column | null;\n readonly endText: Column | null;\n readonly valueText: Column | null;\n readonly open: Column | null;\n /** Row indices per element index. */\n readonly rows: ReadonlyMap<number, readonly number[]>;\n readonly format: ValueFormatter;\n}\n\n/** One `<attribute>` declaration and how its values are written. */\ninterface AttributeSpec {\n readonly id: string;\n readonly title: string;\n readonly type: string;\n readonly column: Column | null;\n /** The text companion of a temporal-typed column, used only when the written type is temporal. */\n readonly companion: Column | null;\n readonly format: ValueFormatter;\n readonly defaultText: string | null;\n readonly optionsText: string | null;\n readonly dynamic: boolean;\n readonly table: TemporalTable | null;\n}\n\n/** The role columns of one domain, each null when absent or of an unusable shape. */\ninterface RoleColumns {\n label: Column | null;\n id: Column | null;\n kind: Column | null;\n start: Column | null;\n end: Column | null;\n timestamp: Column | null;\n spells: Column | null;\n spellsOpen: Column | null;\n timestamps: Column | null;\n open: Column | null;\n position: Column | null;\n color: Column | null;\n size: Column | null;\n shape: Column | null;\n shapeUri: Column | null;\n thickness: Column | null;\n parent: Column | null;\n parents: Column | null;\n /** Text companions keyed by the column they accompany. */\n readonly companions: ReadonlyMap<string, Column>;\n}\n\n/** Everything check() decides and export() writes from. */\ninterface ExportPlan {\n readonly version: GexfVersion;\n readonly options: ResolvedExportOptions;\n readonly notes: LossNote[];\n readonly nodeRoles: RoleColumns;\n readonly edgeRoles: RoleColumns;\n readonly nodeAttrs: readonly AttributeSpec[];\n readonly edgeAttrs: readonly AttributeSpec[];\n readonly timeFormat: TimeFormat | null;\n readonly temporal: boolean;\n readonly timeRepresentation: \"interval\" | \"timestamp\" | null;\n}\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the version to write\n */\nfunction resolveVersion(options: (GexfExportOptions & CommonExportOptions) | undefined): GexfVersion {\n const version = options?.version;\n if (version === undefined) {\n return \"1.3\";\n }\n if (version !== \"1.2\" && version !== \"1.3\") {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option version: ${JSON.stringify(version)} is not \"1.2\" or \"1.3\"`,\n {\n option: \"version\",\n found: version,\n supported: [\"1.2\", \"1.3\"],\n },\n );\n }\n return version;\n}\n\n/**\n * Decide everything about an export: the capability notes, the role columns of each domain, the\n * attribute declarations and their formatters, the temporal tables and the graph header values.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction planExport(\n snapshot: GraphSnapshot,\n options: (GexfExportOptions & CommonExportOptions) | undefined,\n): ExportPlan {\n const version = resolveVersion(options);\n const resolved = resolveExportOptions(options);\n const caps = version === \"1.2\" ? CAPABILITIES_1_2 : CAPABILITIES_1_3;\n const notes = [\n ...checkCapabilities(snapshot, caps, resolved, {\n openIntervals: version === \"1.2\",\n temporalText: true,\n positionDtype: \"f32\",\n roles: MAPPED_ROLES,\n roleNames: ROLE_NAMES,\n }),\n ];\n const note = (code: string, message: string, column: string | null = null, count: number | null = null): void => {\n notes.push(Object.freeze({ code, message, column, count }));\n };\n notes.push(...xmlIllegalTextNotes(snapshot));\n let typeChanges = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id = snapshot.ids.idOf(i);\n if (typeof id === \"number\" ? !Number.isSafeInteger(id) : isCanonicalIntegerText(id)) {\n typeChanges++;\n }\n }\n if (typeChanges > 0) {\n note(\n GEXF_LOSS.ID_TEXT_TYPE,\n `${typeChanges} node id(s) change type when read back under ids: \"canonical\" (string ids that are integer text, non-integer numbers); the file's idtype is not honoured by the importer`,\n null,\n typeChanges,\n );\n }\n const tables = collectTemporalTables(snapshot, version, note);\n const nodeRoles = collectRoles(snapshot.nodes, \"node\", note);\n const edgeRoles = collectRoles(snapshot.edges, \"edge\", note);\n const nodeAttrs = collectAttributes(snapshot, \"node\", nodeRoles, tables.get(\"node\") ?? new Map(), version, note);\n const edgeAttrs = collectAttributes(snapshot, \"edge\", edgeRoles, tables.get(\"edge\") ?? new Map(), version, note);\n const temporal =\n hasLifetime(nodeRoles) ||\n hasLifetime(edgeRoles) ||\n nodeAttrs.some((a) => a.dynamic) ||\n edgeAttrs.some((a) => a.dynamic);\n if (version === \"1.2\") {\n for (const [domain, roles] of [\n [\"node\", nodeRoles],\n [\"edge\", edgeRoles],\n ] as const) {\n if (roles.timestamp !== null || roles.timestamps !== null) {\n note(\n GEXF_LOSS.TIMESTAMP_AS_INTERVAL,\n `${domain} timestamps are written as closed intervals; GEXF 1.2 has no timestamp representation`,\n (roles.timestamp ?? roles.timestamps)?.meta.name ?? null,\n null,\n );\n }\n }\n if (graphExtraText(snapshot, \"timestamp\") !== null) {\n note(\n GEXF_LOSS.TIMESTAMP_AS_INTERVAL,\n \"the graph timestamp is written as a closed interval (start = end); GEXF 1.2 has no timestamp representation\",\n null,\n null,\n );\n }\n if (edgeRoles.kind !== null) {\n note(\n GEXF_LOSS.KIND_DROPPED,\n `edge column \"${edgeRoles.kind.meta.name}\" (kind) cannot be written; GEXF 1.2 has no edge kind`,\n edgeRoles.kind.meta.name,\n edgeRoles.kind.length - edgeRoles.kind.nullCount,\n );\n }\n }\n const { meta } = snapshot;\n let { timeRepresentation } = meta;\n if (timeRepresentation === null && temporal) {\n const timestampOnly =\n (nodeRoles.timestamp !== null || edgeRoles.timestamp !== null) &&\n nodeRoles.start === null &&\n nodeRoles.end === null &&\n edgeRoles.start === null &&\n edgeRoles.end === null;\n timeRepresentation = timestampOnly ? \"timestamp\" : null;\n }\n return {\n version,\n options: resolved,\n notes,\n nodeRoles,\n edgeRoles,\n nodeAttrs,\n edgeAttrs,\n timeFormat: meta.timeFormat,\n temporal,\n timeRepresentation,\n };\n}\n\n/**\n * Whether a domain carries element lifetimes.\n * @param roles - the domain's role columns\n * @returns true when any temporal role column exists\n */\nfunction hasLifetime(roles: RoleColumns): boolean {\n return (\n roles.start !== null ||\n roles.end !== null ||\n roles.timestamp !== null ||\n roles.spells !== null ||\n roles.timestamps !== null\n );\n}\n\n/**\n * Whether a column is a scalar numeric column.\n * @param column - the column\n * @returns true for f32 / f64 / i32 / u32 / u8 with one component\n */\nfunction isNumericScalar(column: Column): boolean {\n return NUMERIC_DTYPES.has(column.dtype) && column.meta.components === 1;\n}\n\n/**\n * Whether a column is a numeric column with a given stride.\n * @param column - the column\n * @param components - the accepted strides\n * @returns true when numeric with one of the strides\n */\nfunction isNumericVector(column: Column, components: readonly number[]): boolean {\n return NUMERIC_DTYPES.has(column.dtype) && components.includes(column.meta.components);\n}\n\n/**\n * Whether a column holds text (string or dict).\n * @param column - the column\n * @returns true for string / dict\n */\nfunction isText(column: Column): boolean {\n return TEXT_DTYPES.has(column.dtype);\n}\n\n/**\n * Whether a column is a list of numbers with a given item stride.\n * @param column - the column\n * @param itemComponents - the required item stride\n * @returns true for a numeric list of that stride\n */\nfunction isNumericList(column: Column, itemComponents: number): boolean {\n return (\n column.dtype === \"list\" &&\n column.meta.itemDtype !== null &&\n NUMERIC_DTYPES.has(column.meta.itemDtype) &&\n (column.meta.itemComponents ?? 1) === itemComponents\n );\n}\n\n/**\n * Whether a role column has the shape its GEXF field needs.\n * @param role - the role\n * @param column - the column\n * @param domain - node or edge\n * @returns true when writable\n */\nfunction roleShapeOk(role: string, column: Column, domain: \"node\" | \"edge\"): boolean {\n switch (role) {\n case \"label\":\n case \"shape\":\n return isText(column);\n case \"kind\":\n return domain === \"edge\" && isText(column);\n case \"id\":\n return domain === \"edge\" && (isText(column) || isNumericScalar(column));\n case \"start\":\n case \"end\":\n case \"timestamp\":\n case \"open\":\n return isNumericScalar(column);\n case \"size\":\n return domain === \"node\" && isNumericScalar(column);\n case \"thickness\":\n return domain === \"edge\" && isNumericScalar(column);\n case \"spells\":\n return isNumericList(column, 2);\n case \"spellsOpen\":\n return column.dtype === \"list\" && column.meta.itemDtype === \"u8\";\n case \"timestamps\":\n return isNumericList(column, 1);\n case \"position\":\n return domain === \"node\" && isNumericVector(column, [2, 3]);\n case \"color\":\n return isNumericVector(column, [3, 4]);\n case \"parent\":\n return domain === \"node\" && column.dtype === \"u32\" && column.meta.components === 1;\n case \"parents\":\n return domain === \"node\" && column.dtype === \"list\" && column.meta.itemDtype === \"u32\";\n default:\n return false;\n }\n}\n\nconst VIZ_NUMERIC_ROLES: ReadonlySet<string> = new Set([\"position\", \"color\", \"size\", \"thickness\"]);\n\nconst MAPPED_ROLES: ReadonlySet<string> = new Set([\n \"label\",\n \"id\",\n \"kind\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"spells\",\n \"spellsOpen\",\n \"timestamps\",\n \"open\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"parent\",\n \"parents\",\n]);\n\n/** The column name the importer gives each mapped role on re-import (design section 5.6 fixed names). */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: NODE_COLUMNS.label,\n id: \"id\",\n kind: \"kind\",\n start: NODE_COLUMNS.start,\n end: NODE_COLUMNS.end,\n timestamp: NODE_COLUMNS.timestamp,\n spells: NODE_COLUMNS.spells,\n spellsOpen: NODE_COLUMNS.spellsOpen,\n timestamps: NODE_COLUMNS.timestamps,\n open: NODE_COLUMNS.open,\n position: NODE_COLUMNS.position,\n color: NODE_COLUMNS.color,\n size: NODE_COLUMNS.size,\n shape: NODE_COLUMNS.shape,\n thickness: \"thickness\",\n parent: NODE_COLUMNS.parent,\n parents: NODE_COLUMNS.parents,\n});\n\n/**\n * Find the role columns of a table; a role column of the wrong shape is noted and left to the\n * attribute pass.\n * @param table - the node or edge table\n * @param domain - node or edge\n * @param note - the note recorder\n * @returns the role columns\n */\nfunction collectRoles(\n table: Iterable<Column>,\n domain: \"node\" | \"edge\",\n note: (code: string, message: string, column?: string | null, count?: number | null) => void,\n): RoleColumns {\n const companions = new Map<string, Column>();\n const roles: RoleColumns = {\n label: null,\n id: null,\n kind: null,\n start: null,\n end: null,\n timestamp: null,\n spells: null,\n spellsOpen: null,\n timestamps: null,\n open: null,\n position: null,\n color: null,\n size: null,\n shape: null,\n shapeUri: null,\n thickness: null,\n parent: null,\n parents: null,\n companions,\n };\n for (const column of table) {\n const { meta } = column;\n const forName = meta.extra.for;\n if ((meta.role === \"timeText\" || typeof forName === \"string\") && column.dtype === \"string\") {\n if (typeof forName === \"string\") {\n companions.set(forName, column);\n }\n continue;\n }\n if (domain === \"node\" && meta.name === NODE_COLUMNS.shapeUri && meta.origin?.namespace === VIZ_NAMESPACE) {\n roles.shapeUri = column.dtype === \"string\" ? column : null;\n continue;\n }\n const { role } = meta;\n if (role === null || !MAPPED_ROLES.has(role)) {\n continue;\n }\n if (!roleShapeOk(role, column, domain)) {\n note(\n GEXF_LOSS.ROLE_SHAPE,\n `${domain} column \"${meta.name}\" (${role}) has a shape GEXF cannot map (${describeShape(column)}); written as a plain attribute`,\n meta.name,\n null,\n );\n // the generic check skips role columns; report what the attribute path loses\n const set = column.length - column.nullCount;\n if (NUMERIC_DTYPES.has(column.dtype) && meta.components > 1) {\n note(\n LOSS.COMPONENTS,\n `${domain} column \"${meta.name}\" has ${meta.components} components; written as a list`,\n meta.name,\n set,\n );\n }\n if (column.dtype === \"json\") {\n note(\n LOSS.JSON,\n `${domain} column \"${meta.name}\" holds nested values; written as JSON text`,\n meta.name,\n set,\n );\n }\n if (column.dtype === \"u32\" || column.dtype === \"u8\") {\n note(\n LOSS.DTYPE,\n `${domain} column \"${meta.name}\" is ${column.dtype}; the format cannot keep that dtype`,\n meta.name,\n set,\n );\n }\n continue;\n }\n if (VIZ_NUMERIC_ROLES.has(role) && column.dtype !== \"f32\") {\n note(\n GEXF_LOSS.VIZ_DTYPE,\n `${domain} column \"${meta.name}\" (${role}) is ${column.dtype}; viz values read back as f32`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n roles[role as keyof Omit<RoleColumns, \"companions\">] = column;\n }\n return roles;\n}\n\n/**\n * A short description of a column's shape for messages.\n * @param column - the column\n * @returns \"dtype x components\" or \"list of item\"\n */\nfunction describeShape(column: Column): string {\n if (column.dtype === \"list\") {\n return `list of ${column.meta.itemDtype ?? \"?\"} x ${column.meta.itemComponents ?? 1}`;\n }\n return `${column.dtype} x ${column.meta.components}`;\n}\n\n/**\n * Resolve every temporal extension table (design section 5.10) into its columns, grouped by\n * domain and keyed by the static column's name; a table without the required columns is noted.\n * @param snapshot - the snapshot\n * @param version - the target version\n * @param note - the note recorder\n * @returns tables by domain, then by column name\n */\nfunction collectTemporalTables(\n snapshot: GraphSnapshot,\n version: GexfVersion,\n note: (code: string, message: string, column?: string | null, count?: number | null) => void,\n): Map<\"node\" | \"edge\", Map<string, TemporalTable>> {\n const out = new Map<\"node\" | \"edge\", Map<string, TemporalTable>>();\n for (const [name, table] of snapshot.extensions) {\n const parsed = parseTemporalTableName(name);\n if (parsed === null) {\n continue;\n }\n const element = table.get(TEMPORAL_COLUMNS.element);\n const start = table.get(TEMPORAL_COLUMNS.start);\n const end = table.get(TEMPORAL_COLUMNS.end);\n const value = table.get(TEMPORAL_COLUMNS.value);\n if (\n element === null ||\n element.dtype !== \"u32\" ||\n start === null ||\n !isNumericScalar(start) ||\n end === null ||\n !isNumericScalar(end) ||\n value === null\n ) {\n note(\n GEXF_LOSS.TEMPORAL_TABLE_SHAPE,\n `extension table \"${name}\" lacks the element / start / end / value columns and cannot be written`,\n name,\n table.rowCount,\n );\n continue;\n }\n const rows = new Map<number, number[]>();\n for (let r = 0; r < table.rowCount; r++) {\n if (!element.isSet(r)) {\n continue;\n }\n const e = element.value(r) as number;\n const list = rows.get(e);\n if (list === undefined) {\n rows.set(e, [r]);\n } else {\n list.push(r);\n }\n }\n const typed = attributeType(value, version);\n const open = optionalNumeric(table.get(TEMPORAL_COLUMNS.open));\n if (version === \"1.3\" && open !== null && open.length - open.nullCount > 0) {\n note(\n LOSS.OPEN_INTERVAL,\n `dynamic values of \"${name}\" carry open intervals, which GEXF 1.3 cannot write`,\n name,\n open.length - open.nullCount,\n );\n }\n const resolved: TemporalTable = {\n element,\n start,\n end,\n value,\n startText: optionalText(table.get(TEMPORAL_COLUMNS.startText)),\n endText: optionalText(table.get(TEMPORAL_COLUMNS.endText)),\n valueText: isTemporalType(typed.type) ? optionalText(table.get(TEMPORAL_COLUMNS.valueText)) : null,\n open,\n rows,\n format: typed.format,\n };\n let byDomain = out.get(parsed.domain);\n if (byDomain === undefined) {\n byDomain = new Map();\n out.set(parsed.domain, byDomain);\n }\n byDomain.set(parsed.column, resolved);\n }\n return out;\n}\n\n/**\n * A string column, or null.\n * @param column - the column or null\n * @returns the column when it is a string column\n */\nfunction optionalText(column: Column | null): Column | null {\n return column !== null && column.dtype === \"string\" ? column : null;\n}\n\n/**\n * A numeric scalar column, or null.\n * @param column - the column or null\n * @returns the column when numeric\n */\nfunction optionalNumeric(column: Column | null): Column | null {\n return column !== null && isNumericScalar(column) ? column : null;\n}\n\n/**\n * The GEXF type of a column and the formatter of its values: the declared `origin.type` when the\n * version knows it and it agrees with the dtype, the canonical type of the dtype otherwise; lists\n * become `list<item>` (1.3) or `liststring` (1.2); a stride column becomes a list of its lanes;\n * json becomes a string of JSON text.\n * @param column - the column\n * @param version - the target version\n * @returns the type text, whether it is a list, and the formatter\n */\nfunction attributeType(column: Column, version: GexfVersion): TypedAttribute {\n const { meta } = column;\n const originType = meta.origin?.type ?? null;\n if (meta.dtype === \"list\" || (NUMERIC_DTYPES.has(meta.dtype) && meta.components > 1)) {\n const itemDtype = meta.dtype === \"list\" ? (meta.itemDtype ?? \"string\") : meta.dtype;\n let itemType = canonicalScalarType(itemDtype);\n if (\n originType !== null &&\n meta.dtype === \"list\" &&\n isListType(originType, \"1.3\") &&\n agrees(originType, \"list\", itemDtype)\n ) {\n itemType = originType.slice(4);\n }\n if (version === \"1.2\") {\n const itemFormat = scalarFormatter(itemType, itemDtype);\n return {\n type: \"liststring\",\n list: true,\n itemType: \"string\",\n format: listFormatter(itemFormat, version),\n dropped: itemType === \"string\" ? null : `list${itemType}`,\n };\n }\n return {\n type: `list${itemType}`,\n list: true,\n itemType,\n format: listFormatter(scalarFormatter(itemType, itemDtype), version),\n dropped: null,\n };\n }\n let type = canonicalScalarType(meta.dtype);\n let dropped: string | null = null;\n const temporal = originType === null || meta.dtype !== \"f64\" ? null : gexfTemporalType(originType);\n if (temporal !== null) {\n // a date / dateTime column of any format (Neo4j spells them date / datetime /\n // localdatetime) keeps its temporal type, so the text companion is written back\n if (isScalarType(temporal, version)) {\n type = temporal;\n } else {\n dropped = temporal;\n }\n } else if (originType !== null && agrees(originType, meta.dtype, null)) {\n if (isScalarType(originType, version)) {\n type = originType;\n } else if (isScalarType(originType, \"1.3\")) {\n dropped = originType;\n }\n }\n return { type, list: false, itemType: type, format: scalarFormatter(type, meta.dtype), dropped };\n}\n\n/**\n * The GEXF temporal type a declared origin type of any format maps to: `date` for a date,\n * `dateTime` for a date-time with or without zone (GEXF's own spellings, Neo4j's `date` /\n * `datetime` / `localdatetime`), null for a non-temporal type or a time of day (GEXF has none).\n * @param originType - the declared type text\n * @returns \"date\", \"dateTime\" or null\n */\nfunction gexfTemporalType(originType: string): \"date\" | \"dateTime\" | null {\n switch (originType.toLowerCase()) {\n case \"date\":\n return \"date\";\n case \"datetime\":\n case \"localdatetime\":\n return \"dateTime\";\n default:\n return null;\n }\n}\n\n/**\n * Whether a declared GEXF type maps back to a dtype (so the exporter may restore it verbatim).\n * @param type - the declared type text\n * @param dtype - the column dtype\n * @param itemDtype - the item dtype of a list column, or null\n * @returns true when mapDeclaredType agrees\n */\nfunction agrees(type: string, dtype: string, itemDtype: string | null): boolean {\n const spec = mapDeclaredType(\"gexf\", type, \"f64\");\n if (spec === null) {\n return false;\n }\n if (dtype === \"list\") {\n return spec.list && spec.itemDtype === itemDtype;\n }\n if (spec.list) {\n return false;\n }\n // a dict column is a string column with options\n return spec.dtype === dtype || (dtype === \"dict\" && spec.dtype === \"string\");\n}\n\n/**\n * The formatter of one scalar value under a GEXF type.\n * @param type - the GEXF scalar type text\n * @param dtype - the column (or item) dtype the values come from\n * @returns the formatter\n */\nfunction scalarFormatter(type: string, dtype: string): ValueFormatter {\n switch (type) {\n case \"boolean\":\n return (value): string | null => {\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (typeof value !== \"number\") {\n return null;\n }\n return value !== 0 ? \"true\" : \"false\";\n };\n case \"integer\":\n case \"long\":\n case \"byte\":\n case \"short\":\n case \"biginteger\":\n return (value): string | null => {\n if (typeof value === \"number\") {\n return Number.isInteger(value) ? formatInteger(value) : formatF64(value);\n }\n return typeof value === \"string\" ? value : null;\n };\n case \"float\":\n return (value): string | null => (typeof value === \"number\" ? formatF32(value) : null);\n case \"double\":\n case \"bigdecimal\":\n return (value): string | null => {\n if (typeof value === \"number\") {\n return dtype === \"f32\" ? formatF32(value) : formatF64(value);\n }\n return typeof value === \"string\" ? value : null;\n };\n case \"date\":\n case \"dateTime\":\n return (value): string | null => {\n if (typeof value === \"number\") {\n return formatTemporal(value, type);\n }\n return typeof value === \"string\" ? value : null;\n };\n default:\n return (value): string | null => {\n switch (typeof value) {\n case \"string\":\n return value;\n case \"number\":\n return dtype === \"f32\" ? formatF32(value) : formatF64(value);\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"object\":\n return value === null ? null : JSON.stringify(value);\n default:\n return null;\n }\n };\n }\n}\n\n/**\n * The formatter of a list value: items through the item formatter, joined per version.\n * @param item - the item formatter\n * @param version - the target version (1.3 brackets, 1.2 pipes)\n * @returns the formatter; null when any item cannot be written\n */\nfunction listFormatter(item: ValueFormatter, version: GexfVersion): ValueFormatter {\n return (value): string | null => {\n if (!Array.isArray(value) && !ArrayBuffer.isView(value)) {\n return null;\n }\n const items: string[] = [];\n for (const entry of Array.from(value as ArrayLike<unknown>)) {\n const text = item(entry);\n if (text === null) {\n return null;\n }\n items.push(text);\n }\n return joinListText(items, version === \"1.2\" ? \"pipe\" : \"gexf\");\n };\n}\n\n/**\n * Decide the `<attribute>` declarations of a domain: every column that is neither structural, a\n * companion nor a mapped role column, in declaration order, plus the temporal tables without a\n * static column (the dynamic weight) as dynamic attributes.\n * @param snapshot - the snapshot\n * @param domain - node or edge\n * @param roles - the domain's role columns\n * @param tables - the domain's temporal tables by column name\n * @param version - the target version\n * @param note - the note recorder\n * @returns the declarations\n */\nfunction collectAttributes(\n snapshot: GraphSnapshot,\n domain: \"node\" | \"edge\",\n roles: RoleColumns,\n tables: ReadonlyMap<string, TemporalTable>,\n version: GexfVersion,\n note: (code: string, message: string, column?: string | null, count?: number | null) => void,\n): AttributeSpec[] {\n const table = domain === \"node\" ? snapshot.nodes : snapshot.edges;\n const reserved = domain === \"node\" ? RESERVED_NODE_NAMES : RESERVED_EDGE_NAMES;\n const roleColumns = new Set<Column>();\n for (const value of Object.values(roles)) {\n if (value !== null && !(value instanceof Map)) {\n roleColumns.add(value);\n }\n }\n const usedIds = new Set<string>();\n const specs: AttributeSpec[] = [];\n const usedTables = new Set<string>();\n const declare = (\n column: Column | null,\n name: string,\n origin: { id: string | null; title: string | null },\n typed: TypedAttribute,\n dynamic: boolean,\n temporal: TemporalTable | null,\n ): void => {\n const id = uniqueId(origin.id ?? name, name, usedIds);\n const title = origin.title ?? name;\n if (typed.dropped !== null) {\n note(\n GEXF_LOSS.DECLARED_TYPE,\n `${domain} column \"${name}\" is declared ${typed.dropped}, which GEXF ${version} lacks; written as ${typed.type}`,\n name,\n null,\n );\n }\n if (domain === \"edge\" && column !== null && column.meta.role === null && title === DEFAULT_WEIGHT_TITLE) {\n note(\n GEXF_LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${name}\" is written as an attribute titled \"${title}\", which the importer reads as THE weight (weightFrom); it reads back as the weight, not as a column`,\n name,\n column.length - column.nullCount,\n );\n }\n const reimportName = reserved.has(title) ? `${title}#${id}` : title;\n if (reimportName !== name) {\n note(\n GEXF_LOSS.ATTRIBUTE_RENAMED,\n `${domain} column \"${name}\" is written with title \"${title}\" and reads back as \"${reimportName}\"`,\n name,\n null,\n );\n }\n const { defaultText, optionsText } =\n column === null\n ? { defaultText: null, optionsText: null }\n : declaredTexts(column, domain, typed, version, note);\n const companion = column === null ? null : (roles.companions.get(name) ?? null);\n if (companion !== null && !isTemporalType(typed.type)) {\n note(\n LOSS.TEMPORAL_TEXT,\n `${domain} column \"${companion.meta.name}\" (the lexical form of \"${name}\") cannot be written: \"${name}\" is written as ${typed.type}, not a GEXF temporal type`,\n companion.meta.name,\n companion.length - companion.nullCount,\n );\n }\n specs.push({\n id,\n title,\n type: typed.type,\n column,\n companion: isTemporalType(typed.type) ? companion : null,\n format: typed.format,\n defaultText,\n optionsText,\n dynamic,\n table: temporal,\n });\n };\n for (const column of table) {\n const { meta } = column;\n if (roleColumns.has(column) || (meta.role !== null && STRUCTURAL_ROLES.has(meta.role))) {\n continue;\n }\n if (typeof meta.extra.for === \"string\" && column.dtype === \"string\") {\n continue;\n }\n if (domain === \"node\" && column === roles.shapeUri) {\n continue;\n }\n const temporal = tables.get(meta.name) ?? null;\n if (temporal !== null) {\n usedTables.add(meta.name);\n }\n declare(\n column,\n meta.name,\n { id: meta.origin?.id ?? null, title: meta.origin?.title ?? null },\n attributeType(column, version),\n meta.dynamic || temporal !== null,\n temporal,\n );\n }\n for (const [name, temporal] of tables) {\n if (usedTables.has(name)) {\n continue;\n }\n const { origin } = temporal.value.meta;\n const { weightOrigin } = snapshot.meta;\n const weightId =\n domain === \"edge\" && weightOrigin !== null && (weightOrigin.title ?? weightOrigin.id) === name\n ? weightOrigin.id\n : null;\n declare(\n null,\n name,\n { id: origin?.id ?? weightId, title: null },\n attributeType(temporal.value, version),\n true,\n temporal,\n );\n }\n return specs;\n}\n\n/**\n * The `<default>` and `<options>` texts of a declared attribute, with the notes about what cannot\n * be written as the declared type, about a dictionary written as options, and about 1.2 list items\n * holding the `|` separator.\n * @param column - the column\n * @param domain - node or edge\n * @param typed - the attribute's GEXF type and formatter\n * @param version - the target version\n * @param note - the note recorder\n * @returns the default and options texts (null when absent or unwritable)\n */\nfunction declaredTexts(\n column: Column,\n domain: \"node\" | \"edge\",\n typed: TypedAttribute,\n version: GexfVersion,\n note: (code: string, message: string, column?: string | null, count?: number | null) => void,\n): { defaultText: string | null; optionsText: string | null } {\n const { meta } = column;\n const { name } = meta;\n let defaultText: string | null = null;\n let optionsText: string | null = null;\n if (meta.default !== undefined) {\n defaultText = typed.format(meta.default);\n if (defaultText === null) {\n note(\n GEXF_LOSS.VALUE_UNWRITABLE,\n `${domain} column \"${name}\": the default cannot be written as ${typed.type}`,\n name,\n null,\n );\n }\n }\n const options = meta.options ?? (column.dtype === \"dict\" ? column.dictionary : null);\n if (meta.options === null && options !== null && options.length > 0) {\n note(\n GEXF_LOSS.OPTIONS_GAINED,\n `${domain} column \"${name}\" declares no options; its dictionary is written as <options> and reads back as declared options`,\n name,\n null,\n );\n }\n if (options !== null) {\n const itemFormat = typed.list ? scalarFormatter(typed.itemType, meta.itemDtype ?? \"string\") : typed.format;\n const texts: string[] = [];\n let ok = true;\n for (const option of options) {\n const text = itemFormat(option);\n if (text === null) {\n ok = false;\n break;\n }\n texts.push(text);\n }\n if (ok) {\n optionsText = joinListText(texts, version === \"1.2\" ? \"pipe\" : \"gexf\");\n } else {\n note(\n GEXF_LOSS.VALUE_UNWRITABLE,\n `${domain} column \"${name}\": the options cannot be written as ${typed.type}`,\n name,\n null,\n );\n }\n }\n if (version === \"1.2\" && column.dtype === \"list\") {\n let count = 0;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && listItems(column, r).some((item) => String(item).includes(\"|\"))) {\n count++;\n }\n }\n if (count > 0) {\n note(\n GEXF_LOSS.LIST_SEPARATOR,\n `${domain} column \"${name}\": ${count} row(s) hold an item containing \"|\", the 1.2 list separator`,\n name,\n count,\n );\n }\n }\n return { defaultText, optionsText };\n}\n\n/**\n * Whether a GEXF type is a temporal one whose values have text companions.\n * @param type - the type text\n * @returns true for date / dateTime\n */\nfunction isTemporalType(type: string): boolean {\n return type === \"date\" || type === \"dateTime\";\n}\n\n/**\n * A unique attribute id within a class.\n * @param preferred - the id to try first (the origin id or the name)\n * @param name - the column name, tried second\n * @param used - ids already taken\n * @returns a free id, recorded as used\n */\nfunction uniqueId(preferred: string, name: string, used: Set<string>): string {\n const candidates = [preferred, name];\n for (const candidate of candidates) {\n if (candidate.length > 0 && !used.has(candidate)) {\n used.add(candidate);\n return candidate;\n }\n }\n for (let n = 2; ; n++) {\n const candidate = `${name}#${n}`;\n if (!used.has(candidate)) {\n used.add(candidate);\n return candidate;\n }\n }\n}\n\n// ============================================================ writing\n\n/**\n * The text of a time bound: the companion text when present, the formatted number otherwise.\n * @param column - the numeric column\n * @param companion - its text companion, or null\n * @param row - the row\n * @param timeFormat - the graph's timeformat\n * @returns the text\n */\nfunction timeText(column: Column, companion: Column | null, row: number, timeFormat: TimeFormat | null): string {\n if (companion !== null && companion.isSet(row)) {\n return companion.value(row) as string;\n }\n return formatTimeValue(column.value(row) as number, timeFormat);\n}\n\n/**\n * The `start` / `end` / `timestamp` / open attributes of one element.\n * @param roles - the domain's role columns\n * @param row - the element's row\n * @param plan - the plan\n * @returns the attribute text, starting with a space when non-empty\n */\nfunction lifetimeAttrs(roles: RoleColumns, row: number, plan: ExportPlan): string {\n let out = \"\";\n const { timeFormat, version } = plan;\n let bits = 0;\n if (version === \"1.2\" && roles.open !== null && roles.open.isSet(row)) {\n bits = roles.open.value(row) as number;\n }\n const write = (name: string, column: Column | null, open: boolean): void => {\n if (column === null || !column.isSet(row)) {\n return;\n }\n const value = column.value(row) as number;\n if (!Number.isFinite(value)) {\n return;\n }\n const text = timeText(column, roles.companions.get(column.meta.name) ?? null, row, timeFormat);\n // GEXF 1.2: `startopen` / `endopen` hold the time of a non-inclusive bound (dynamics.xsd\n // time-type) and replace `start` / `end`\n out += ` ${open ? `${name}open` : name}=\"${escapeXmlAttribute(text)}\"`;\n };\n if (roles.timestamp !== null && roles.timestamp.isSet(row)) {\n if (version === \"1.3\" && plan.timeRepresentation === \"timestamp\") {\n write(\"timestamp\", roles.timestamp, false);\n } else {\n write(\"start\", roles.timestamp, false);\n write(\"end\", roles.timestamp, false);\n }\n } else {\n write(\"start\", roles.start, (bits & OPEN_START) !== 0);\n write(\"end\", roles.end, (bits & OPEN_END) !== 0);\n }\n if (version === \"1.3\" && roles.timestamps !== null && roles.timestamps.isSet(row)) {\n const items = listItems(roles.timestamps, row).map((t) => formatTimeValue(t as number, timeFormat));\n out += ` timestamps=\"${escapeXmlAttribute(`<[${items.join(\", \")}]>`)}\"`;\n }\n return out;\n}\n\n/**\n * The `<spells>` element of one element: its spells column, plus (1.2) its timestamps as [t, t].\n * In 1.2 a spell whose spells.open bits mark a bound open writes that bound as `startopen` /\n * `endopen`; 1.3 has no open bounds, and check() reports the loss.\n * @param roles - the domain's role columns\n * @param row - the element's row\n * @param plan - the plan\n * @param indent - the indentation of the element\n * @returns the lines, or an empty string\n */\nfunction spellsElement(roles: RoleColumns, row: number, plan: ExportPlan, indent: string): string {\n const pairs: (readonly [number, number, number])[] = [];\n if (roles.spells !== null && roles.spells.isSet(row)) {\n const open =\n plan.version === \"1.2\" && roles.spellsOpen !== null && roles.spellsOpen.isSet(row)\n ? listItems(roles.spellsOpen, row)\n : [];\n listItems(roles.spells, row).forEach((pair, i) => {\n const [s, e] = Array.from(pair as ArrayLike<number>);\n pairs.push([s, e, (open[i] as number | undefined) ?? 0]);\n });\n }\n if (plan.version === \"1.2\" && roles.timestamps !== null && roles.timestamps.isSet(row)) {\n for (const t of listItems(roles.timestamps, row)) {\n pairs.push([t as number, t as number, 0]);\n }\n }\n if (pairs.length === 0) {\n return \"\";\n }\n let out = `${indent}<spells>\\n`;\n for (const [s, e, open] of pairs) {\n let attrs = \"\";\n if (Number.isFinite(s)) {\n const name = (open & OPEN_START) === 0 ? \"start\" : \"startopen\";\n attrs += ` ${name}=\"${escapeXmlAttribute(formatTimeValue(s, plan.timeFormat))}\"`;\n }\n if (Number.isFinite(e)) {\n const name = (open & OPEN_END) === 0 ? \"end\" : \"endopen\";\n attrs += ` ${name}=\"${escapeXmlAttribute(formatTimeValue(e, plan.timeFormat))}\"`;\n }\n out += `${indent} <spell${attrs}/>\\n`;\n }\n return `${out}${indent}</spells>\\n`;\n}\n\n/**\n * The `<attvalues>` element of one node or edge: static cells and dynamic rows.\n * @param attrs - the domain's declarations\n * @param row - the element's row\n * @param plan - the plan\n * @param indent - the indentation of the element\n * @returns the lines, or an empty string\n */\nfunction attvaluesElement(attrs: readonly AttributeSpec[], row: number, plan: ExportPlan, indent: string): string {\n let out = \"\";\n for (const spec of attrs) {\n const { column } = spec;\n if (column !== null && column.isSet(row)) {\n let text: string | null;\n if (spec.companion !== null && spec.companion.isSet(row)) {\n text = spec.companion.value(row) as string;\n } else {\n text = spec.format(cellValue(column, row));\n }\n if (text !== null) {\n out += `${indent} <attvalue for=\"${escapeXmlAttribute(spec.id)}\" value=\"${escapeXmlAttribute(text)}\"/>\\n`;\n }\n }\n const { table } = spec;\n if (table === null) {\n continue;\n }\n const rows = table.rows.get(row);\n if (rows === undefined) {\n continue;\n }\n for (const r of rows) {\n if (!table.value.isSet(r)) {\n continue;\n }\n let text: string | null;\n if (table.valueText !== null && table.valueText.isSet(r)) {\n text = table.valueText.value(r) as string;\n } else {\n text = table.format(cellValue(table.value, r));\n }\n if (text === null) {\n continue;\n }\n out += `${indent} <attvalue for=\"${escapeXmlAttribute(spec.id)}\" value=\"${escapeXmlAttribute(text)}\"${timedAttrs(table, r, plan)}/>\\n`;\n }\n }\n return out.length === 0 ? \"\" : `${indent}<attvalues>\\n${out}${indent}</attvalues>\\n`;\n}\n\n/**\n * The time bounds of one temporal table row as attributes.\n * @param table - the table\n * @param r - the row\n * @param plan - the plan\n * @returns the attribute text, starting with a space when non-empty\n */\nfunction timedAttrs(table: TemporalTable, r: number, plan: ExportPlan): string {\n const start = table.start.isSet(r) ? (table.start.value(r) as number) : -Infinity;\n const end = table.end.isSet(r) ? (table.end.value(r) as number) : Infinity;\n let out = \"\";\n if (plan.version === \"1.3\" && plan.timeRepresentation === \"timestamp\" && start === end && Number.isFinite(start)) {\n return ` timestamp=\"${escapeXmlAttribute(timeText(table.start, table.startText, r, plan.timeFormat))}\"`;\n }\n let bits = 0;\n if (plan.version === \"1.2\" && table.open !== null && table.open.isSet(r)) {\n bits = table.open.value(r) as number;\n }\n if (Number.isFinite(start)) {\n const name = (bits & OPEN_START) !== 0 ? \"startopen\" : \"start\";\n out += ` ${name}=\"${escapeXmlAttribute(timeText(table.start, table.startText, r, plan.timeFormat))}\"`;\n }\n if (Number.isFinite(end)) {\n const name = (bits & OPEN_END) !== 0 ? \"endopen\" : \"end\";\n out += ` ${name}=\"${escapeXmlAttribute(timeText(table.end, table.endText, r, plan.timeFormat))}\"`;\n }\n return out;\n}\n\n/**\n * The value of a set cell as a plain JS value: lists through sliceOf, json through values, a\n * stride column as an array of lanes.\n * @param column - the column\n * @param row - the row\n * @returns the value\n */\nfunction cellValue(column: Column, row: number): unknown {\n switch (column.dtype) {\n case \"list\":\n return column.sliceOf(row);\n case \"json\":\n return column.values[row];\n default: {\n const value = column.value(row);\n return ArrayBuffer.isView(value) ? Array.from(value as ArrayLike<number>) : value;\n }\n }\n}\n\n/**\n * Whether `viz:position` gets a z attribute: always for a 3-d source, and for a 2-d source\n * (`extra.sourceDims === 2`) only when some node has since been given a non-zero z.\n * @param position - the position role column, or null\n * @returns true when z is written\n */\nfunction positionWritesZ(position: Column | null): boolean {\n if (position === null || position.meta.components < 3) {\n return false;\n }\n if (position.meta.extra.sourceDims !== 2) {\n return true;\n }\n const { components } = position.meta;\n let data: ArrayLike<number>;\n switch (position.dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\":\n ({ data } = position);\n break;\n default:\n // A non-numeric position column has no z lane to inspect; write z so nothing is lost.\n return true;\n }\n for (let i = 0; i < position.length; i++) {\n if (position.isSet(i) && data[i * components + 2] !== 0) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * The items of a set row of a list column.\n * @param column - a list column\n * @param row - the row\n * @returns the items; empty when the column is not a list\n */\nfunction listItems(column: Column, row: number): readonly unknown[] {\n return column.dtype === \"list\" ? column.sliceOf(row) : [];\n}\n\n/**\n * The viz elements of one node or edge.\n * @param roles - the domain's role columns\n * @param row - the element's row\n * @param indent - the indentation\n * @param writeZ - whether viz:position gets its z attribute\n * @returns the lines, or an empty string\n */\nfunction vizElements(roles: RoleColumns, row: number, indent: string, writeZ: boolean): string {\n let out = \"\";\n const { color } = roles;\n if (color !== null && color.isSet(row)) {\n const lanes = Array.from(color.value(row) as ArrayLike<number>);\n const scale = color.dtype === \"u8\" ? 1 : 255;\n const channel = (v: number): string => String(Math.max(0, Math.min(255, Math.round(v * scale))));\n let attrs = ` r=\"${channel(lanes[0])}\" g=\"${channel(lanes[1])}\" b=\"${channel(lanes[2])}\"`;\n if (lanes.length > 3) {\n const a = color.dtype === \"u8\" ? lanes[3] / 255 : lanes[3];\n if (a !== 1) {\n attrs += ` a=\"${formatF32(Math.fround(a))}\"`;\n }\n }\n out += `${indent}<viz:color${attrs}/>\\n`;\n }\n const { position } = roles;\n if (position !== null && position.isSet(row)) {\n const lanes = Array.from(position.value(row) as ArrayLike<number>);\n const fmt = position.dtype === \"f32\" ? formatF32 : formatF64;\n let attrs = ` x=\"${fmt(lanes[0])}\" y=\"${fmt(lanes[1])}\"`;\n if (lanes.length > 2 && writeZ) {\n attrs += ` z=\"${fmt(lanes[2])}\"`;\n }\n out += `${indent}<viz:position${attrs}/>\\n`;\n }\n for (const [name, column] of [\n [\"size\", roles.size],\n [\"thickness\", roles.thickness],\n ] as const) {\n if (column !== null && column.isSet(row)) {\n const value = column.value(row) as number;\n const text = column.dtype === \"f32\" ? formatF32(value) : formatF64(value);\n out += `${indent}<viz:${name} value=\"${escapeXmlAttribute(text)}\"/>\\n`;\n }\n }\n const { shape } = roles;\n if (shape !== null && shape.isSet(row)) {\n let attrs = ` value=\"${escapeXmlAttribute(String(shape.value(row)))}\"`;\n if (roles.shapeUri !== null && roles.shapeUri.isSet(row)) {\n attrs += ` uri=\"${escapeXmlAttribute(roles.shapeUri.value(row) as string)}\"`;\n }\n out += `${indent}<viz:shape${attrs}/>\\n`;\n }\n return out;\n}\n\n/**\n * The `<attributes>` groups of one class.\n * @param cls - node or edge\n * @param specs - the declarations\n * @param indent - the indentation\n * @returns the lines, or an empty string\n */\nfunction attributesGroups(cls: \"node\" | \"edge\", specs: readonly AttributeSpec[], indent: string): string {\n let out = \"\";\n for (const mode of [\"static\", \"dynamic\"] as const) {\n const group = specs.filter((s) => s.dynamic === (mode === \"dynamic\"));\n if (group.length === 0) {\n continue;\n }\n out += `${indent}<attributes class=\"${cls}\" mode=\"${mode}\">\\n`;\n for (const spec of group) {\n const head = `${indent} <attribute id=\"${escapeXmlAttribute(spec.id)}\" title=\"${escapeXmlAttribute(spec.title)}\" type=\"${spec.type}\"`;\n if (spec.defaultText === null && spec.optionsText === null) {\n out += `${head}/>\\n`;\n continue;\n }\n out += `${head}>\\n`;\n if (spec.defaultText !== null) {\n out += `${indent} <default>${escapeXmlText(spec.defaultText)}</default>\\n`;\n }\n if (spec.optionsText !== null) {\n out += `${indent} <options>${escapeXmlText(spec.optionsText)}</options>\\n`;\n }\n out += `${indent} </attribute>\\n`;\n }\n out += `${indent}</attributes>\\n`;\n }\n return out;\n}\n\n/**\n * The `type` of a logical edge after folding an expanded pair (design section 3.6).\n * @param snapshot - the snapshot\n * @param e - the logical edge index\n * @param folding - the pair-folding view (mutual pairs fold: GEXF has the mutual type)\n * @returns the edge type, or null when the edge is the mirror half of a pair\n */\nfunction edgeType(snapshot: GraphSnapshot, e: number, folding: PairFolding): GexfEdgeType | null {\n if (!snapshot.directed) {\n return \"undirected\";\n }\n if (folding.folded(e)) {\n return null;\n }\n if (!folding.sourceDirected(e)) {\n return \"undirected\";\n }\n if (folding.mateOf(e) !== INVALID_INDEX || folding.isMutual(e)) {\n return \"mutual\";\n }\n return \"directed\";\n}\n\n/**\n * Write the document as text parts.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @yields one part per element or line group\n * @returns nothing\n */\nfunction* writeGexf(\n snapshot: GraphSnapshot,\n options: (GexfExportOptions & CommonExportOptions) | undefined,\n): Generator<string, void, undefined> {\n const plan = planExport(snapshot, options);\n const { version } = plan;\n const ids = sanitizeIds(snapshot, \"any\", plan.options.sanitizeIds);\n const idText = (index: number): string => escapeXmlAttribute(String(ids.idAt(index)));\n const ns = GEXF_NAMESPACES[version];\n const { meta } = snapshot;\n\n yield '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n yield `<gexf xmlns=\"${ns.gexf}\" xmlns:viz=\"${ns.viz}\" version=\"${version}\">\\n`;\n yield metaElement(meta);\n yield graphStart(snapshot, plan);\n yield attributesGroups(\"node\", plan.nodeAttrs, \" \");\n yield attributesGroups(\"edge\", plan.edgeAttrs, \" \");\n\n // nodes\n const { nodeRoles } = plan;\n const writeZ = positionWritesZ(nodeRoles.position);\n yield ` <nodes count=\"${snapshot.nodeCount}\">\\n`;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n let attrs = ` id=\"${idText(i)}\"`;\n if (nodeRoles.label !== null && nodeRoles.label.isSet(i)) {\n attrs += ` label=\"${escapeXmlAttribute(String(nodeRoles.label.value(i)))}\"`;\n }\n if (nodeRoles.parent !== null && nodeRoles.parent.isSet(i)) {\n attrs += ` pid=\"${idText(nodeRoles.parent.value(i) as number)}\"`;\n }\n attrs += lifetimeAttrs(nodeRoles, i, plan);\n let body = attvaluesElement(plan.nodeAttrs, i, plan, \" \");\n if (nodeRoles.parents !== null && nodeRoles.parents.isSet(i)) {\n const parents = listItems(nodeRoles.parents, i) as readonly number[];\n if (parents.length > 0) {\n body += \" <parents>\\n\";\n for (const p of parents) {\n body += ` <parent for=\"${idText(p)}\"/>\\n`;\n }\n body += \" </parents>\\n\";\n }\n }\n body += spellsElement(nodeRoles, i, plan, \" \");\n body += vizElements(nodeRoles, i, \" \", writeZ);\n yield body.length === 0 ? ` <node${attrs}/>\\n` : ` <node${attrs}>\\n${body} </node>\\n`;\n }\n yield \" </nodes>\\n\";\n\n // edges: the count is decided in a cheap first pass (no strings built) so the section\n // streams element by element instead of buffering every edge\n const { edgeRoles } = plan;\n const edgeList = snapshot.edgeList();\n const folding = pairFolding(snapshot, { foldMutual: true });\n const weights = explicitWeights(snapshot);\n const defaultType = defaultEdgeType(snapshot);\n let written = 0;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (edgeType(snapshot, e, folding) !== null) {\n written++;\n }\n }\n yield ` <edges count=\"${written}\">\\n`;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n const type = edgeType(snapshot, e, folding);\n if (type === null) {\n continue;\n }\n let attrs = \"\";\n if (edgeRoles.id !== null && edgeRoles.id.isSet(e)) {\n attrs += ` id=\"${escapeXmlAttribute(String(edgeRoles.id.value(e)))}\"`;\n } else if (version === \"1.2\") {\n attrs += ` id=\"e${e}\"`;\n }\n attrs += ` source=\"${idText(edgeList.src[e])}\" target=\"${idText(edgeList.dst[e])}\"`;\n if (type !== defaultType) {\n attrs += ` type=\"${type}\"`;\n }\n const weight = weights.text(e);\n if (weight !== null) {\n attrs += ` weight=\"${weight}\"`;\n }\n if (edgeRoles.label !== null && edgeRoles.label.isSet(e)) {\n attrs += ` label=\"${escapeXmlAttribute(String(edgeRoles.label.value(e)))}\"`;\n }\n if (version === \"1.3\" && edgeRoles.kind !== null && edgeRoles.kind.isSet(e)) {\n attrs += ` kind=\"${escapeXmlAttribute(String(edgeRoles.kind.value(e)))}\"`;\n }\n attrs += lifetimeAttrs(edgeRoles, e, plan);\n let body = attvaluesElement(plan.edgeAttrs, e, plan, \" \");\n body += spellsElement(edgeRoles, e, plan, \" \");\n body += vizElements(edgeRoles, e, \" \", false);\n yield body.length === 0 ? ` <edge${attrs}/>\\n` : ` <edge${attrs}>\\n${body} </edge>\\n`;\n }\n yield \" </edges>\\n\";\n yield \" </graph>\\n\";\n yield \"</gexf>\\n\";\n}\n\n/**\n * The `<meta>` element.\n * @param meta - the graph meta\n * @returns the lines, or an empty string when nothing is set\n */\nfunction metaElement(meta: GraphSnapshot[\"meta\"]): string {\n let body = \"\";\n if (meta.creator !== null) {\n body += ` <creator>${escapeXmlText(meta.creator)}</creator>\\n`;\n }\n if (meta.description !== null) {\n body += ` <description>${escapeXmlText(meta.description)}</description>\\n`;\n }\n if (meta.keywords.length > 0) {\n body += ` <keywords>${escapeXmlText(meta.keywords.join(\", \"))}</keywords>\\n`;\n }\n const modified = meta.modified === null ? \"\" : ` lastmodifieddate=\"${escapeXmlAttribute(meta.modified)}\"`;\n if (body.length === 0 && modified.length === 0) {\n return \"\";\n }\n return body.length === 0 ? ` <meta${modified}/>\\n` : ` <meta${modified}>\\n${body} </meta>\\n`;\n}\n\n/**\n * The `<graph>` start tag with its header attributes.\n * @param snapshot - the snapshot\n * @param plan - the plan\n * @returns the line\n */\nfunction graphStart(snapshot: GraphSnapshot, plan: ExportPlan): string {\n const { meta } = snapshot;\n let attrs = ` defaultedgetype=\"${defaultEdgeType(snapshot)}\"`;\n let mode = meta.mode ?? \"static\";\n if (plan.temporal && mode === \"static\") {\n mode = \"dynamic\";\n }\n if (plan.version === \"1.2\" && mode === \"slice\") {\n mode = \"dynamic\";\n }\n attrs += ` mode=\"${mode}\"`;\n let { idType } = meta;\n if (idType === null) {\n const { kind } = snapshot.ids;\n if (kind === \"string\") {\n idType = \"string\";\n } else if (kind !== \"mixed\") {\n idType = \"integer\";\n }\n }\n if (idType === \"integer\" || idType === \"string\") {\n attrs += ` idtype=\"${idType}\"`;\n }\n if (plan.timeFormat !== null) {\n attrs += ` timeformat=\"${plan.timeFormat}\"`;\n } else if (plan.temporal) {\n attrs += ' timeformat=\"double\"';\n }\n if (plan.version === \"1.3\" && plan.timeRepresentation !== null) {\n attrs += ` timerepresentation=\"${plan.timeRepresentation}\"`;\n }\n const timestamp = graphExtraText(snapshot, \"timestamp\");\n const header: Record<string, string | null> = {\n start: graphExtraText(snapshot, \"start\"),\n end: graphExtraText(snapshot, \"end\"),\n timestamp,\n };\n if (plan.version === \"1.2\" && timestamp !== null) {\n // GEXF 1.2 has no timestamp: the graph's becomes a closed interval, as an element's does\n header.start ??= timestamp;\n header.end ??= timestamp;\n header.timestamp = null;\n }\n for (const [key, value] of Object.entries(header)) {\n if (value !== null) {\n attrs += ` ${key}=\"${escapeXmlAttribute(value)}\"`;\n }\n }\n return ` <graph${attrs}>\\n`;\n}\n\n/**\n * The `defaultedgetype` to write: the snapshot's direction, or `mutual` for a directed snapshot\n * whose source file declared a mutual default (the importer reads that default as directed, with\n * every untyped edge mutual), so the default survives a round trip.\n * @param snapshot - the snapshot\n * @returns the edge type the header declares, and every edge without its own `type` takes\n */\nfunction defaultEdgeType(snapshot: GraphSnapshot): GexfEdgeType {\n if (!snapshot.directed) {\n return \"undirected\";\n }\n return graphExtraText(snapshot, \"defaultedgetype\")?.trim().toLowerCase() === \"mutual\" ? \"mutual\" : \"directed\";\n}\n\n/**\n * A graph header value the GEXF importer recorded in `meta.extra.gexf` (defaultedgetype, start,\n * end, timestamp).\n * @param snapshot - the snapshot\n * @param key - the attribute name\n * @returns the text, or null when absent\n */\nfunction graphExtraText(snapshot: GraphSnapshot, key: string): string | null {\n const gexfExtra = snapshot.meta.extra.gexf;\n if (typeof gexfExtra !== \"object\" || gexfExtra === null) {\n return null;\n }\n const value = (gexfExtra as Record<string, unknown>)[key];\n return typeof value === \"string\" ? value : null;\n}\n\n/** The GEXF exporter (design section 8.5); `capabilities` describes the default 1.3 output. */\nexport const gexfExporter: GraphExporter<GexfExportOptions> = Object.freeze({\n format: GEXF_FORMAT,\n capabilities: CAPABILITIES_1_3,\n /**\n * Pre-flight: what export() would lose.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the loss notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: GexfExportOptions & CommonExportOptions): readonly LossNote[] {\n return Object.freeze(planExport(snapshot, options).notes);\n },\n /**\n * Write the snapshot as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: GexfExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(writeGexf(snapshot, options));\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the document\n */\n async exportToString(snapshot: GraphSnapshot, options?: GexfExportOptions & CommonExportOptions): Promise<string> {\n return joinText(writeGexf(snapshot, options));\n },\n});\n\n/** The capabilities of a 1.2 export, for callers that pass `version: \"1.2\"`. */\nexport const GEXF_1_2_CAPABILITIES: ExportCapabilities = CAPABILITIES_1_2;\n","/**\n * The GEXF subpath entry (`@graphty/graph-io/gexf`, design section 8.2): the importer and exporter\n * objects with their format-specific option types, the exporter's loss-note codes and the\n * importer's issue codes grouped in one table.\n */\n\nimport {\n BAD_DEFAULT_CODE,\n BAD_OPTIONS_CODE,\n COLUMN_RENAMED_CODE,\n COUNT_HINT_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_NODE_CODE,\n ENCODING_FALLBACK_CODE,\n ID_MERGED_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MIXED_DIRECTION_CODE,\n NO_GRAPH_CODE,\n OPTION_IGNORED_CODE,\n PRECISION_CODE,\n ROLE_TAKEN_CODE,\n SINK_OPTION_CODE,\n STRAY_TEXT_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ELEMENT_CODE,\n UNKNOWN_ENCODING_CODE,\n UNKNOWN_PARENT_CODE,\n XML_SYNTAX_CODE,\n} from \"../../common/codes.js\";\nimport {\n ATTRIBUTE_ID_CODE,\n ATTRIBUTE_TYPE_CODE,\n ATTRIBUTES_CLASS_CODE,\n ATTVALUE_SHAPE_CODE,\n DUPLICATE_ATTRIBUTE_CODE,\n EDGE_TYPE_CODE,\n HEADER_VALUE_CODE,\n MISSING_NODES_CODE,\n NOT_GEXF_CODE,\n OPEN_BOUND_CONFLICT_CODE,\n SPELL_OPEN_CODE,\n TIMED_STATIC_CODE,\n UNKNOWN_ATTRIBUTE_CODE,\n VIZ_DYNAMIC_CODE,\n VIZ_SKIPPED_CODE,\n VIZ_VALUE_CODE,\n WEIGHT_IGNORED_CODE,\n} from \"./importer.js\";\n\nexport { GEXF_1_2_CAPABILITIES, GEXF_LOSS, gexfExporter, type GexfExportOptions } from \"./exporter.js\";\nexport { gexfImporter, type GexfImportOptions } from \"./importer.js\";\nexport { type GexfVersion } from \"./schema.js\";\n\n/**\n * The issue codes the GEXF importer records (design section 8.6), by name: the codes shared with\n * the other importers (src/common/codes.ts) and the GEXF-specific ones. A key is the code without\n * its severity and format prefixes.\n */\nexport const GEXF_ISSUE = Object.freeze({\n /** The XML is not well-formed (fatal). */\n XML_SYNTAX: XML_SYNTAX_CODE,\n /** The input holds invalid UTF-8 (fatal). */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM, a declaration or the encoding option chose (fatal). */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** The root element is not `<gexf>` (fatal). */\n NOT_GEXF: NOT_GEXF_CODE,\n /** The document has no `<graph>` (fatal). */\n NO_GRAPH: NO_GRAPH_CODE,\n /** `<edges>` without `<nodes>`. */\n MISSING_NODES: MISSING_NODES_CODE,\n /** A node without an id. */\n MISSING_ID: MISSING_ID_CODE,\n /** An edge without a source or target. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** An edge `type` outside directed / undirected / mutual. */\n EDGE_TYPE: EDGE_TYPE_CODE,\n /** A `pid` / `<parent for>` naming an unknown node. */\n UNKNOWN_PARENT: UNKNOWN_PARENT_CODE,\n /** An `<attributes class>` outside node / edge. */\n ATTRIBUTES_CLASS: ATTRIBUTES_CLASS_CODE,\n /** An `<attribute>` without an id. */\n ATTRIBUTE_ID: ATTRIBUTE_ID_CODE,\n /** A `<graph>` header attribute with an unknown value. */\n HEADER_VALUE: HEADER_VALUE_CODE,\n /** A `count` hint the sink cannot reserve (ignored). */\n COUNT_HINT: COUNT_HINT_CODE,\n /** A node id declared twice. */\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 attribute id declared twice in one class. */\n DUPLICATE_ATTRIBUTE: DUPLICATE_ATTRIBUTE_CODE,\n /** An attribute type the importer maps to string. */\n ATTRIBUTE_TYPE: ATTRIBUTE_TYPE_CODE,\n /** A declared type the format does not define (kept as string). */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** A default that does not parse as the declared type. */\n BAD_DEFAULT: BAD_DEFAULT_CODE,\n /** Options that do not parse as the declared type. */\n BAD_OPTIONS: BAD_OPTIONS_CODE,\n /** A column renamed `<name>#<id>` because the name was taken (design section 5.6). */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A column declared without its role because the table already holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** An `<attvalue for>` naming an undeclared attribute. */\n UNKNOWN_ATTRIBUTE: UNKNOWN_ATTRIBUTE_CODE,\n /** An `<attvalue>` without a value. */\n ATTVALUE_SHAPE: ATTVALUE_SHAPE_CODE,\n /** A timed value on an attribute of a static group. */\n TIMED_VALUE_ON_STATIC: TIMED_STATIC_CODE,\n /** A long value beyond 2^53 rounded. */\n PRECISION: PRECISION_CODE,\n /** Two id texts merged into one number under ids \"number\". */\n ID_MERGED: ID_MERGED_CODE,\n /** The XML weight attribute ignored under weightFrom null. */\n WEIGHT_IGNORED: WEIGHT_IGNORED_CODE,\n /** viz elements skipped under viz: false. */\n VIZ_SKIPPED: VIZ_SKIPPED_CODE,\n /** A 1.2 dynamic viz element whose bounds were dropped. */\n VIZ_DYNAMIC_DROPPED: VIZ_DYNAMIC_CODE,\n /** Deprecated and no longer recorded: open spells are kept in the spells.open column. */\n SPELL_OPEN_DROPPED: SPELL_OPEN_CODE,\n /** A viz value that could not be read. */\n VIZ_VALUE: VIZ_VALUE_CODE,\n /** Both `start` and `startopen` (or `end` and `endopen`) on one element. */\n OPEN_BOUND_CONFLICT: OPEN_BOUND_CONFLICT_CODE,\n /** An element or attribute GEXF does not define was skipped. */\n UNKNOWN_ELEMENT: UNKNOWN_ELEMENT_CODE,\n /** Text where GEXF allows only elements was ignored. */\n STRAY_TEXT: STRAY_TEXT_CODE,\n /** A common option the importer has no use for was given. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder-policy option the sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n /** The sink refused the file's direction. */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges forced to the policy's direction. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /** A mixed file under onMixedDirection \"error\" (fatal). */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n});\n"],"names":["edgeType","declared"],"mappings":"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"}
1
+ {"version":3,"file":"gexf.js","sources":["../src/formats/gexf/schema.ts","../src/formats/gexf/importer.ts","../src/formats/gexf/exporter.ts","../src/formats/gexf/index.ts"],"sourcesContent":["/**\n * What the GEXF importer and exporter share (research note 07 section 2.1, design sections 5.1,\n * 5.5, 5.6 and 5.10): the namespaces of the two supported versions, the fixed names and\n * declarations of the columns derived from XML attributes and viz elements (design section 5.6:\n * XML-attribute-derived columns have fixed names and roles, and a declared attribute that would\n * take one of them is renamed `<name>#<id>`), the shape of a temporal extension table, and the\n * declared-type table of each version for the exporter.\n */\n\nimport { type ColumnDecl, type Dtype } from \"@graphty/graph-format\";\n\nimport { TIME_TEXT_ROLE, TIME_TEXT_SUFFIX } from \"../../common/temporal.js\";\n\n/** The GEXF versions the exporter writes. */\nexport type GexfVersion = \"1.2\" | \"1.3\";\n\n/** The format name. */\nexport const GEXF_FORMAT = \"gexf\";\n\n/** The namespace URIs of each version. */\nexport const GEXF_NAMESPACES: Readonly<Record<GexfVersion, { readonly gexf: string; readonly viz: string }>> = {\n \"1.2\": { gexf: \"http://www.gexf.net/1.2draft\", viz: \"http://www.gexf.net/1.2draft/viz\" },\n \"1.3\": { gexf: \"http://gexf.net/1.3\", viz: \"http://gexf.net/1.3/viz\" },\n};\n\n/** The default edge type values of `<graph defaultedgetype>` and `<edge type>`. */\nexport type GexfEdgeType = \"directed\" | \"undirected\" | \"mutual\";\n\n/** The GEXF `timeformat` values. */\nexport const TIME_FORMATS: ReadonlySet<string> = new Set([\"integer\", \"double\", \"date\", \"dateTime\"]);\n\n/** The GEXF graph `mode` values. */\nexport const GRAPH_MODES: ReadonlySet<string> = new Set([\"static\", \"dynamic\", \"slice\"]);\n\n/** The GEXF 1.3 `timerepresentation` values. */\nexport const TIME_REPRESENTATIONS: ReadonlySet<string> = new Set([\"interval\", \"timestamp\"]);\n\n/** The `origin.namespace` of viz-derived columns. */\nexport const VIZ_NAMESPACE = \"viz\";\n\n/** The origin every XML-derived column declares. */\nconst XML_ORIGIN = { format: GEXF_FORMAT };\n\n/** The origin of every viz-derived column. */\nconst VIZ_ORIGIN = { format: GEXF_FORMAT, namespace: VIZ_NAMESPACE };\n\n/**\n * The fixed node column names the importer owns (design section 5.6): a declared attribute with\n * one of these titles is renamed `<title>#<id>` so the XML-derived column keeps its name and role.\n */\nexport const NODE_COLUMNS = Object.freeze({\n label: \"label\",\n parent: \"parent\",\n parents: \"parents\",\n start: \"start\",\n end: \"end\",\n timestamp: \"timestamp\",\n spells: \"spells\",\n spellsOpen: \"spells.open\",\n timestamps: \"timestamps\",\n open: \"open\",\n position: \"position\",\n color: \"color\",\n size: \"size\",\n shape: \"shape\",\n shapeUri: \"shape.uri\",\n});\n\n/** The fixed edge column names the importer owns. */\nconst EDGE_COLUMNS = Object.freeze({\n id: \"id\",\n label: \"label\",\n kind: \"kind\",\n start: \"start\",\n end: \"end\",\n timestamp: \"timestamp\",\n spells: \"spells\",\n spellsOpen: \"spells.open\",\n timestamps: \"timestamps\",\n open: \"open\",\n color: \"color\",\n thickness: \"thickness\",\n shape: \"shape\",\n});\n\n/** Every reserved node column name, including the temporal companions. */\nexport const RESERVED_NODE_NAMES: ReadonlySet<string> = new Set([\n ...Object.values(NODE_COLUMNS),\n NODE_COLUMNS.start + TIME_TEXT_SUFFIX,\n NODE_COLUMNS.end + TIME_TEXT_SUFFIX,\n NODE_COLUMNS.timestamp + TIME_TEXT_SUFFIX,\n]);\n\n/** Every reserved edge column name, including the temporal companions. */\nexport const RESERVED_EDGE_NAMES: ReadonlySet<string> = new Set([\n ...Object.values(EDGE_COLUMNS),\n EDGE_COLUMNS.start + TIME_TEXT_SUFFIX,\n EDGE_COLUMNS.end + TIME_TEXT_SUFFIX,\n EDGE_COLUMNS.timestamp + TIME_TEXT_SUFFIX,\n]);\n\n/** The declarations of the XML-derived node columns, keyed as NODE_COLUMNS. */\nexport const NODE_DECLS: Readonly<Record<keyof typeof NODE_COLUMNS, ColumnDecl>> = {\n label: { name: NODE_COLUMNS.label, dtype: \"string\", role: \"label\", nullable: true, origin: XML_ORIGIN },\n parent: {\n name: NODE_COLUMNS.parent,\n dtype: \"u32\",\n role: \"parent\",\n refersTo: \"node\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n parents: {\n name: NODE_COLUMNS.parents,\n dtype: \"list\",\n itemDtype: \"u32\",\n role: \"parents\",\n refersTo: \"node\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n start: { name: NODE_COLUMNS.start, dtype: \"f64\", role: \"start\", nullable: true, origin: XML_ORIGIN },\n end: { name: NODE_COLUMNS.end, dtype: \"f64\", role: \"end\", nullable: true, origin: XML_ORIGIN },\n timestamp: { name: NODE_COLUMNS.timestamp, dtype: \"f64\", role: \"timestamp\", nullable: true, origin: XML_ORIGIN },\n spells: {\n name: NODE_COLUMNS.spells,\n dtype: \"list\",\n itemDtype: \"f64\",\n itemComponents: 2,\n role: \"spells\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n timestamps: {\n name: NODE_COLUMNS.timestamps,\n dtype: \"list\",\n itemDtype: \"f64\",\n role: \"timestamps\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n open: { name: NODE_COLUMNS.open, dtype: \"u8\", role: \"open\", nullable: true, origin: XML_ORIGIN },\n spellsOpen: {\n name: NODE_COLUMNS.spellsOpen,\n dtype: \"list\",\n itemDtype: \"u8\",\n role: \"spellsOpen\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n position: {\n name: NODE_COLUMNS.position,\n dtype: \"f32\",\n components: 3,\n role: \"position\",\n mutable: true,\n nullable: true,\n origin: VIZ_ORIGIN,\n extra: { units: \"file\" },\n },\n color: {\n name: NODE_COLUMNS.color,\n dtype: \"f32\",\n components: 4,\n role: \"color\",\n nullable: true,\n origin: VIZ_ORIGIN,\n },\n size: { name: NODE_COLUMNS.size, dtype: \"f32\", role: \"size\", nullable: true, origin: VIZ_ORIGIN },\n shape: { name: NODE_COLUMNS.shape, dtype: \"dict\", role: \"shape\", nullable: true, origin: VIZ_ORIGIN },\n shapeUri: { name: NODE_COLUMNS.shapeUri, dtype: \"string\", nullable: true, origin: VIZ_ORIGIN },\n};\n\n/** The declarations of the XML-derived edge columns, keyed as EDGE_COLUMNS. */\nexport const EDGE_DECLS: Readonly<Record<keyof typeof EDGE_COLUMNS, ColumnDecl>> = {\n id: { name: EDGE_COLUMNS.id, dtype: \"string\", role: \"id\", unique: true, nullable: true, origin: XML_ORIGIN },\n label: { name: EDGE_COLUMNS.label, dtype: \"string\", role: \"label\", nullable: true, origin: XML_ORIGIN },\n kind: { name: EDGE_COLUMNS.kind, dtype: \"dict\", role: \"kind\", nullable: true, origin: XML_ORIGIN },\n start: { name: EDGE_COLUMNS.start, dtype: \"f64\", role: \"start\", nullable: true, origin: XML_ORIGIN },\n end: { name: EDGE_COLUMNS.end, dtype: \"f64\", role: \"end\", nullable: true, origin: XML_ORIGIN },\n timestamp: { name: EDGE_COLUMNS.timestamp, dtype: \"f64\", role: \"timestamp\", nullable: true, origin: XML_ORIGIN },\n spells: {\n name: EDGE_COLUMNS.spells,\n dtype: \"list\",\n itemDtype: \"f64\",\n itemComponents: 2,\n role: \"spells\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n timestamps: {\n name: EDGE_COLUMNS.timestamps,\n dtype: \"list\",\n itemDtype: \"f64\",\n role: \"timestamps\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n open: { name: EDGE_COLUMNS.open, dtype: \"u8\", role: \"open\", nullable: true, origin: XML_ORIGIN },\n spellsOpen: {\n name: EDGE_COLUMNS.spellsOpen,\n dtype: \"list\",\n itemDtype: \"u8\",\n role: \"spellsOpen\",\n nullable: true,\n origin: XML_ORIGIN,\n },\n color: {\n name: EDGE_COLUMNS.color,\n dtype: \"f32\",\n components: 4,\n role: \"color\",\n nullable: true,\n origin: VIZ_ORIGIN,\n },\n thickness: { name: EDGE_COLUMNS.thickness, dtype: \"f32\", role: \"thickness\", nullable: true, origin: VIZ_ORIGIN },\n shape: { name: EDGE_COLUMNS.shape, dtype: \"dict\", role: \"shape\", nullable: true, origin: VIZ_ORIGIN },\n};\n\n/** The bit of the `open` column marking an open start (design section 5.1). */\nexport const OPEN_START = 1;\n\n/** The bit of the `open` column marking an open end. */\nexport const OPEN_END = 2;\n\n/** The prefix of a temporal extension table's name (design section 5.10). */\nconst TEMPORAL_TABLE_PREFIX = \"temporal:\";\n\n/** The column names of a temporal extension table (design section 5.10). */\nexport const TEMPORAL_COLUMNS = Object.freeze({\n element: \"element\",\n start: \"start\",\n end: \"end\",\n value: \"value\",\n open: \"open\",\n startText: `start${TIME_TEXT_SUFFIX}`,\n endText: `end${TIME_TEXT_SUFFIX}`,\n valueText: `value${TIME_TEXT_SUFFIX}`,\n});\n\n/**\n * The name of the temporal extension table of a dynamic attribute.\n * @param domain - node or edge\n * @param column - the static column's name\n * @returns `temporal:<domain>:<column>`\n */\nexport function temporalTableName(domain: \"node\" | \"edge\", column: string): string {\n return `${TEMPORAL_TABLE_PREFIX}${domain}:${column}`;\n}\n\n/**\n * Split a temporal table name into its domain and column.\n * @param name - the table name\n * @returns the parts, or null when the name is not a temporal table's\n */\nexport function parseTemporalTableName(name: string): { domain: \"node\" | \"edge\"; column: string } | null {\n if (!name.startsWith(TEMPORAL_TABLE_PREFIX)) {\n return null;\n }\n const rest = name.slice(TEMPORAL_TABLE_PREFIX.length);\n const colon = rest.indexOf(\":\");\n if (colon < 0) {\n return null;\n }\n const domain = rest.slice(0, colon);\n if (domain !== \"node\" && domain !== \"edge\") {\n return null;\n }\n return { domain, column: rest.slice(colon + 1) };\n}\n\n/**\n * The column declarations of a temporal extension table (design section 5.10): the element index,\n * the interval, the value in the attribute's dtype, the interval's text companions, an open-bounds\n * byte and, for a temporal-typed attribute, the value's text companion.\n * @param domain - the domain the element column refers to\n * @param value - the value column's declaration fields (dtype, itemDtype, options...)\n * @param temporalValue - whether the value is itself a temporal type needing a text companion\n * @returns the declarations in table order\n */\nexport function temporalTableDecls(\n domain: \"node\" | \"edge\",\n value: Pick<ColumnDecl, \"dtype\" | \"itemDtype\" | \"options\" | \"origin\">,\n temporalValue: boolean,\n): ColumnDecl[] {\n const decls: ColumnDecl[] = [\n { name: TEMPORAL_COLUMNS.element, dtype: \"u32\", refersTo: domain, nullable: false },\n { name: TEMPORAL_COLUMNS.start, dtype: \"f64\", role: \"start\", nullable: true },\n { name: TEMPORAL_COLUMNS.end, dtype: \"f64\", role: \"end\", nullable: true },\n { name: TEMPORAL_COLUMNS.value, ...value, nullable: true },\n {\n name: TEMPORAL_COLUMNS.startText,\n dtype: \"string\",\n role: TIME_TEXT_ROLE,\n nullable: true,\n extra: { for: TEMPORAL_COLUMNS.start },\n },\n { name: TEMPORAL_COLUMNS.endText, dtype: \"string\", nullable: true, extra: { for: TEMPORAL_COLUMNS.end } },\n { name: TEMPORAL_COLUMNS.open, dtype: \"u8\", role: \"open\", nullable: true },\n ];\n if (temporalValue) {\n decls.push({\n name: TEMPORAL_COLUMNS.valueText,\n dtype: \"string\",\n nullable: true,\n extra: { for: TEMPORAL_COLUMNS.value },\n });\n }\n return decls;\n}\n\n/** The scalar type names GEXF 1.2 declares. */\nconst TYPES_1_2: ReadonlySet<string> = new Set([\"integer\", \"long\", \"double\", \"float\", \"boolean\", \"string\", \"anyURI\"]);\n\n/** The scalar type names GEXF 1.3 declares (the list variants are derived). */\nconst TYPES_1_3: ReadonlySet<string> = new Set([\n ...TYPES_1_2,\n \"bigdecimal\",\n \"biginteger\",\n \"byte\",\n \"char\",\n \"short\",\n \"date\",\n \"dateTime\",\n]);\n\n/**\n * Whether a declared type text is a scalar type of a version (case-sensitive, as the schema spells\n * them).\n * @param type - the type text\n * @param version - the target version\n * @returns true when the version declares it\n */\nexport function isScalarType(type: string, version: GexfVersion): boolean {\n return (version === \"1.2\" ? TYPES_1_2 : TYPES_1_3).has(type);\n}\n\n/**\n * Whether a declared type text is a list type of a version: `liststring` in 1.2, `list<scalar>` in 1.3.\n * @param type - the type text\n * @param version - the target version\n * @returns true when the version declares it\n */\nexport function isListType(type: string, version: GexfVersion): boolean {\n if (version === \"1.2\") {\n return type === \"liststring\";\n }\n return type.startsWith(\"list\") && type.length > 4 && isScalarType(type.slice(4), \"1.3\");\n}\n\n/**\n * The canonical GEXF scalar type of a column dtype (design section 5.1 reversed).\n * @param dtype - a scalar dtype\n * @returns the type text; u32 becomes `long` (its range exceeds `integer`), u8 `integer`, json `string`\n */\nexport function canonicalScalarType(dtype: Dtype): string {\n switch (dtype) {\n case \"bool\":\n return \"boolean\";\n case \"i32\":\n case \"u8\":\n return \"integer\";\n case \"u32\":\n return \"long\";\n case \"f32\":\n return \"float\";\n case \"f64\":\n return \"double\";\n case \"dict\":\n case \"string\":\n case \"json\":\n case \"list\":\n return \"string\";\n default: {\n const name: string = dtype;\n return name;\n }\n }\n}\n","/**\n * The GEXF importer (design sections 8.4, 8.6, 5.1, 5.6, 5.10; research note 07 section 2.1):\n * GEXF 1.1, 1.2 and 1.3 documents read in one SAX-style pass over the shared streaming XML\n * tokenizer (src/common/xml.ts) and pushed into the sink one scalar at a time, so a document of\n * any size is never held in memory. Declared attributes become typed columns as they are read\n * (defaults, options, list types, temporal types with their text companions declared on the first\n * value whose text is not canonical); the viz namespace becomes the position / color / size /\n * shape / thickness role columns with origin.namespace \"viz\"; `pid`, nested `<nodes>` and\n * `<parents>` become the parent / parents columns, resolved once every node is declared so a\n * forward reference is legal; element lifetimes (`start` / `end` / `timestamp`, `<spells>`, 1.3\n * `timestamps` / `intervals`, 1.2 `startopen` / `endopen` holding the open bound's time) become\n * the temporal role columns; dynamic attribute values go into the temporal extension tables of\n * design section 5.10, and a spell's open bounds go to the spells.open column; the graph header's\n * `mode`, `timeformat`, `timerepresentation` and `idtype` land in the graph meta, and its\n * `defaultedgetype`, `start`, `end` and `timestamp` as written in `meta.extra.gexf` (`idtype` is\n * informational: Gephi writes `idtype=\"string\"` for every file, so ids follow the `ids` rule,\n * canonical by default).\n *\n * Direction follows design section 8.4: `defaultedgetype` (undirected when absent, per the spec and\n * the `defaultDirected` option) sets the sink's direction once, and every per-edge `type` override,\n * `mutual` included, goes through the common DirectionResolver and the `onMixedDirection` policy.\n * The weight is the `weight` XML attribute, overridden by a static value of the edge attribute\n * titled `weightFrom` (\"weight\" by default), applied with `setEdgeWeight` when that value arrives;\n * timed values of that attribute form the `temporal:edge:weight` table (design section 5.10). Ids\n * are coerced with the \"canonical\" rule of design section 4.1 by default. Edges may not reference\n * undeclared nodes unless `addMissingNodes` is set (the GEXF default is false, design section 8.4).\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n type ExtensionHandle,\n GraphFormatError,\n type GraphMetaPatch,\n type GraphSink,\n INVALID_INDEX,\n MAX_COUNT,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport {\n type AttributeDeclarationInput,\n declareAttribute,\n declareCompanion,\n type DeclaredAttribute,\n declareResolved,\n losesPrecision,\n parseDeclaredTemporal,\n parseDeclaredValue,\n PRECISION_CODE,\n} from \"../../common/attributes.js\";\nimport {\n COUNT_HINT_CODE,\n DUPLICATE_ATTRIBUTE_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_NODE_CODE,\n ID_MERGED_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n NO_GRAPH_CODE,\n STRAY_TEXT_CODE,\n UNKNOWN_ELEMENT_CODE,\n UNKNOWN_PARENT_CODE,\n XML_SYNTAX_CODE,\n} from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec, parseDecimalText } from \"../../common/declared-types.js\";\nimport { DirectionResolver, type EdgeKind } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { textChunks, throwIfAborted } from \"../../common/input.js\";\nimport { type ListSyntax, splitListText } from \"../../common/lists.js\";\nimport {\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder, type IssueLocation } from \"../../common/report.js\";\nimport { parseTimeText, type TemporalValue, type TimeFormat, timeTextCompanion } from \"../../common/temporal.js\";\nimport { isWeightField, parseWeightText } from \"../../common/weights.js\";\nimport {\n isWhitespace,\n localName,\n tokenizeXml,\n xmlDeclaredEncoding,\n type XmlHandler,\n XmlSyntaxError,\n} from \"../../common/xml.js\";\nimport { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from \"../../types.js\";\nimport {\n EDGE_DECLS,\n GEXF_FORMAT,\n type GexfEdgeType,\n GRAPH_MODES,\n NODE_DECLS,\n OPEN_END,\n OPEN_START,\n RESERVED_EDGE_NAMES,\n RESERVED_NODE_NAMES,\n temporalTableDecls,\n temporalTableName,\n TIME_FORMATS,\n TIME_REPRESENTATIONS,\n} from \"./schema.js\";\n\n/** The format-specific options of the GEXF importer. */\nexport interface GexfImportOptions {\n /**\n * Whether the viz namespace elements (color, position, size, shape, thickness) are imported as\n * role columns (default true); false ignores them and records one `unsupported` warning.\n */\n viz?: boolean | undefined;\n}\n\n/** Issue code: the document is not a GEXF document (no `<gexf>` root). */\nexport const NOT_GEXF_CODE = \"E_NOT_GEXF\";\n/** Issue code: the graph declares edges but no `<nodes>` section. */\nexport const MISSING_NODES_CODE = \"E_GEXF_MISSING_NODES\";\n/** Issue code: an edge `type` outside directed / undirected / mutual. */\nexport const EDGE_TYPE_CODE = \"E_GEXF_EDGE_TYPE\";\n/** Issue code: an `<attributes>` group without a class, or with an unknown one. */\nexport const ATTRIBUTES_CLASS_CODE = \"E_GEXF_ATTRIBUTES_CLASS\";\n/** Issue code: an `<attribute>` without an id. */\nexport const ATTRIBUTE_ID_CODE = \"E_GEXF_ATTRIBUTE_ID\";\n/** Issue code: a graph header value (`defaultedgetype`, `mode`, `timeformat`, ...) outside its set. */\nexport const HEADER_VALUE_CODE = \"W_GEXF_HEADER_VALUE\";\n/** Issue code: an `<attribute>` without a type (read as string). */\nexport const ATTRIBUTE_TYPE_CODE = \"W_GEXF_ATTRIBUTE_TYPE\";\n/** Issue code: an `<attvalue>` naming an attribute the document never declares (once per id). */\nexport const UNKNOWN_ATTRIBUTE_CODE = \"W_GEXF_UNKNOWN_ATTRIBUTE\";\n/** Issue code: an `<attvalue>` without a `for` or a `value`. */\nexport const ATTVALUE_SHAPE_CODE = \"W_GEXF_ATTVALUE_SHAPE\";\n/** Issue code: a timed value on an attribute declared in a static group (stored as dynamic anyway). */\nexport const TIMED_STATIC_CODE = \"W_GEXF_TIMED_VALUE_ON_STATIC\";\n/** Issue code: the `weight` XML attribute is present but `weightFrom` is null. */\nexport const WEIGHT_IGNORED_CODE = \"W_GEXF_WEIGHT_IGNORED\";\n/** Issue code: viz elements skipped under `viz: false`. */\nexport const VIZ_SKIPPED_CODE = \"W_GEXF_VIZ_SKIPPED\";\n/** Issue code: a 1.2 dynamic viz element (its bounds are dropped, the value kept). */\nexport const VIZ_DYNAMIC_CODE = \"W_GEXF_VIZ_DYNAMIC_DROPPED\";\n/**\n * Issue code: `startopen` / `endopen` on a `<spell>` stored closed. No longer recorded: the open\n * bits of each spell are kept in the spells.open column. Kept so the exported code table is stable.\n */\nexport const SPELL_OPEN_CODE = \"W_GEXF_SPELL_OPEN_DROPPED\";\n/** Issue code: a viz element with a value that does not parse (the element is skipped). */\nexport const VIZ_VALUE_CODE = \"W_GEXF_VIZ_VALUE\";\n/** Issue code: both `start` and `startopen` (or `end` and `endopen`) on one element; the closed bound wins. */\nexport const OPEN_BOUND_CONFLICT_CODE = \"W_GEXF_OPEN_BOUND_CONFLICT\";\n\nexport {\n DUPLICATE_ATTRIBUTE_CODE,\n DUPLICATE_NODE_CODE,\n ID_MERGED_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n NO_GRAPH_CODE,\n UNKNOWN_PARENT_CODE,\n};\n\nconst EDGE_TYPES: ReadonlySet<string> = new Set([\"directed\", \"undirected\", \"mutual\"]);\n\n/**\n * An edge type as a keyword of {@link EDGE_TYPES}: the schema spells them in lower case, but files\n * in the wild write `Directed`, and the keyword is read whatever its case or surrounding space.\n * @param text - a `defaultedgetype` or edge `type` value\n * @returns the text trimmed and in lower case\n */\nfunction edgeTypeKeyword(text: string): string {\n return text.trim().toLowerCase();\n}\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The XML attributes the importer reads on `<node>`; any other one is reported once. */\nconst NODE_ATTRIBUTES: ReadonlySet<string> = new Set([\n \"id\",\n \"label\",\n \"pid\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"startopen\",\n \"endopen\",\n \"timestamps\",\n \"intervals\",\n]);\n\n/** The XML attributes the importer reads on `<edge>`; any other one is reported once. */\nconst EDGE_ATTRIBUTES: ReadonlySet<string> = new Set([\n \"id\",\n \"source\",\n \"target\",\n \"type\",\n \"label\",\n \"weight\",\n \"kind\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"startopen\",\n \"endopen\",\n \"timestamps\",\n \"intervals\",\n]);\n\n/** The common options the GEXF importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** A GraphMetaPatch under construction (its fields are readonly once handed to the sink). */\ntype MetaPatchDraft = { -readonly [K in keyof GraphMetaPatch]: GraphMetaPatch[K] };\n\n/** A declared attribute as the importer tracks it: its column and how values are parsed and stored. */\ninterface TrackedAttribute {\n /** The attribute id as written. */\n readonly id: string;\n /** The column name. */\n readonly name: string;\n /** How values are parsed. */\n readonly spec: DeclaredTypeSpec;\n /** The list syntax of values. */\n readonly listSyntax: ListSyntax;\n /** The column handle. */\n readonly handle: ColumnHandle;\n /** The companion text column's declaration of a temporal attribute, or null. */\n readonly companionDecl: ColumnDecl | null;\n /** The companion's handle once a value needed it, or INVALID_INDEX. */\n companion: ColumnHandle;\n /** Whether the attribute was declared in a dynamic group. */\n readonly dynamic: boolean;\n /** The value column fields of the temporal table. */\n readonly valueDecl: Pick<ColumnDecl, \"dtype\" | \"itemDtype\" | \"options\" | \"origin\">;\n /** The temporal table, created on the first timed value. */\n table: ExtensionHandle;\n}\n\n/** A pending containment reference resolved after every node is declared. */\ninterface ParentRef {\n /** The child's node index. */\n readonly child: number;\n /** The parent's id (from `pid` / `<parent for>`), or null when the index is known. */\n readonly parentId: NodeId | null;\n /** The parent's index (nested `<nodes>`), or INVALID_INDEX. */\n readonly parentIndex: number;\n /** Where the reference was read. */\n readonly where: IssueLocation;\n}\n\n/** A column declared on first use, through the design section 5.6 rule. */\nclass LazyColumn {\n private handle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private readonly domain: \"node\" | \"edge\";\n\n private readonly decl: ColumnDecl;\n\n /**\n * Create a lazily declared column.\n * @param domain - node or edge\n * @param decl - the declaration\n */\n constructor(domain: \"node\" | \"edge\", decl: ColumnDecl) {\n this.domain = domain;\n this.decl = decl;\n }\n\n /**\n * The handle, declaring the column on the first call (renamed or without its role when the\n * sink already holds the name or the role, reported).\n * @param sink - the sink\n * @param report - the report\n * @param where - the location of the first use\n * @returns the handle\n */\n get(sink: GraphSink, report: ImportReportBuilder, where?: IssueLocation): ColumnHandle {\n if (this.handle === INVALID_INDEX) {\n this.handle = declareResolved(sink, this.domain, this.decl, report, where).handle;\n }\n return this.handle;\n }\n\n /**\n * Write one cell, declaring the column first when needed.\n * @param sink - the sink\n * @param report - the report\n * @param index - the row\n * @param value - the value\n * @param where - the location, for a declaration issue\n */\n set(sink: GraphSink, report: ImportReportBuilder, index: number, value: unknown, where?: IssueLocation): void {\n const handle = this.get(sink, report, where);\n if (this.domain === \"node\") {\n sink.setNodeValue(handle, index, value);\n } else {\n sink.setEdgeValue(handle, index, value);\n }\n }\n}\n\n/** A temporal role column with its lazily declared text companion. */\nclass TemporalColumn {\n private readonly column: LazyColumn;\n\n private companion: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private readonly domain: \"node\" | \"edge\";\n\n private readonly name: string;\n\n /**\n * Create the pair.\n * @param domain - node or edge\n * @param decl - the numeric column's declaration\n */\n constructor(domain: \"node\" | \"edge\", decl: ColumnDecl) {\n this.domain = domain;\n this.name = decl.name;\n this.column = new LazyColumn(domain, decl);\n }\n\n /**\n * Write a parsed time value and, when its text must be kept, the companion cell.\n * @param sink - the sink\n * @param report - the report\n * @param index - the row\n * @param value - the parsed value\n * @param where - the location, for a declaration issue\n */\n set(\n sink: GraphSink,\n report: ImportReportBuilder,\n index: number,\n value: TemporalValue,\n where?: IssueLocation,\n ): void {\n this.column.set(sink, report, index, value.value, where);\n if (value.text === null) {\n return;\n }\n if (this.companion === INVALID_INDEX) {\n this.companion = declareCompanion(sink, this.domain, timeTextCompanion(this.name), report);\n }\n if (this.domain === \"node\") {\n sink.setNodeValue(this.companion, index, value.text);\n } else {\n sink.setEdgeValue(this.companion, index, value.text);\n }\n }\n}\n\n/** The lazily declared columns of one domain. */\ninterface DomainColumns {\n readonly label: LazyColumn;\n readonly start: TemporalColumn;\n readonly end: TemporalColumn;\n readonly timestamp: TemporalColumn;\n readonly spells: LazyColumn;\n readonly spellsOpen: LazyColumn;\n readonly timestamps: LazyColumn;\n readonly open: LazyColumn;\n readonly color: LazyColumn;\n readonly shape: LazyColumn;\n}\n\n/** Where the reader is in the document. */\nconst enum Ctx {\n Gexf,\n Meta,\n MetaText,\n Graph,\n Attributes,\n Attribute,\n AttributeText,\n Nodes,\n Node,\n Attvalues,\n Parents,\n Spells,\n Edges,\n Edge,\n Skip,\n}\n\n/** An open `<node>`: its index (INVALID_INDEX when the node was skipped) and location. */\ninterface NodeFrame {\n readonly index: number;\n readonly where: IssueLocation;\n}\n\n/**\n * The open `<edge>`: its primary index, the mirror of an expanded pair (or INVALID_INDEX) and\n * location. One frame is reused for every edge (the hot loop allocates nothing per edge but the\n * tokenizer's attribute map): the report copies a location's fields into each issue, and nothing\n * keeps a reference to an edge's frame or location past the edge's end tag.\n */\ninterface EdgeFrame {\n index: number;\n mirror: number;\n readonly where: MutableLocation;\n}\n\n/** A location whose fields are overwritten per element (see EdgeFrame). */\ninterface MutableLocation {\n line: number;\n element: string | null;\n}\n\n/** An `<attribute>` being read: its start-tag fields and the texts of `<default>` / `<options>`. */\ninterface PendingAttribute {\n readonly domain: \"node\" | \"edge\";\n readonly dynamic: boolean;\n readonly attrs: ReadonlyMap<string, string>;\n readonly line: number;\n defaultText: string | null;\n optionsText: string | null;\n}\n\n/**\n * The event handler that turns the tokenizer's events into sink calls: one import call.\n */\nclass GexfReader implements XmlHandler {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly viz: boolean;\n\n private readonly coercer: IdCoercer;\n\n private readonly resolver: DirectionResolver;\n\n private readonly ctx: Ctx[] = [];\n\n private timeFormat: TimeFormat | null = null;\n\n private defaultKind: GexfEdgeType = \"undirected\";\n\n private readonly meta: MetaPatchDraft = { sourceFormat: GEXF_FORMAT };\n\n private metaText = \"\";\n\n private metaField: \"creator\" | \"description\" | \"keywords\" | null = null;\n\n private readonly nodeAttrs = new Map<string, TrackedAttribute>();\n\n private readonly edgeAttrs = new Map<string, TrackedAttribute>();\n\n private readonly declaredNodeNames = new Set<string>();\n\n private readonly declaredEdgeNames = new Set<string>();\n\n /** The edge attribute that is THE weight (its title equals weightFrom), or null. */\n private weightAttr: { readonly id: string; readonly spec: DeclaredTypeSpec; table: ExtensionHandle } | null = null;\n\n private readonly nodeColumns: DomainColumns;\n\n private readonly edgeColumns: DomainColumns;\n\n private readonly parentColumn = new LazyColumn(\"node\", NODE_DECLS.parent);\n\n private readonly parentsColumn = new LazyColumn(\"node\", NODE_DECLS.parents);\n\n private positionColumn: LazyColumn | null = null;\n\n private readonly sizeColumn = new LazyColumn(\"node\", NODE_DECLS.size);\n\n private readonly shapeUriColumn = new LazyColumn(\"node\", NODE_DECLS.shapeUri);\n\n private readonly thicknessColumn = new LazyColumn(\"edge\", EDGE_DECLS.thickness);\n\n private readonly edgeIdColumn = new LazyColumn(\"edge\", EDGE_DECLS.id);\n\n private readonly edgeKindColumn = new LazyColumn(\"edge\", EDGE_DECLS.kind);\n\n private readonly edgeIds = new Set<string>();\n\n private parentRefs: ParentRef[] = [];\n\n private parentsRefs: { readonly child: number; readonly ids: readonly NodeId[]; readonly where: IssueLocation }[] =\n [];\n\n private readonly unknownAttributes = new Set<string>();\n\n private readonly nodeStack: NodeFrame[] = [];\n\n private edge: EdgeFrame | null = null;\n\n /** The one edge frame, reused for every `<edge>` (see EdgeFrame). */\n private readonly edgeFrame: EdgeFrame = {\n index: INVALID_INDEX,\n mirror: INVALID_INDEX,\n where: { line: 0, element: null },\n };\n\n /** The one `<attvalue>` location, reused per value (its fields are copied into every issue). */\n private readonly valueWhere: MutableLocation = { line: 0, element: null };\n\n private attributeGroup: { readonly domain: \"node\" | \"edge\" | null; readonly dynamic: boolean } | null = null;\n\n private pendingAttribute: PendingAttribute | null = null;\n\n private attributeText: \"default\" | \"options\" | null = null;\n\n private attributeTextValue = \"\";\n\n private spellPairs: number[][] | null = null;\n\n /** The open bits of each spell in spellPairs, in the same order. */\n private spellOpen: number[] = [];\n\n private spellsWhere: IssueLocation | null = null;\n\n private parentIds: NodeId[] | null = null;\n\n private nodesSeen = false;\n\n private graphSeen = false;\n\n private elementsSinceCheck = 0;\n\n /**\n * Set up one import.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param viz - whether viz elements are imported\n */\n constructor(sink: GraphSink, report: ImportReportBuilder, options: ResolvedImportOptions, viz: boolean) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.viz = viz;\n this.coercer = new IdCoercer(options.ids);\n this.resolver = new DirectionResolver(sink, report, options.onMixedDirection);\n this.nodeColumns = {\n label: new LazyColumn(\"node\", NODE_DECLS.label),\n start: new TemporalColumn(\"node\", NODE_DECLS.start),\n end: new TemporalColumn(\"node\", NODE_DECLS.end),\n timestamp: new TemporalColumn(\"node\", NODE_DECLS.timestamp),\n spells: new LazyColumn(\"node\", NODE_DECLS.spells),\n spellsOpen: new LazyColumn(\"node\", NODE_DECLS.spellsOpen),\n timestamps: new LazyColumn(\"node\", NODE_DECLS.timestamps),\n open: new LazyColumn(\"node\", NODE_DECLS.open),\n color: new LazyColumn(\"node\", NODE_DECLS.color),\n shape: new LazyColumn(\"node\", NODE_DECLS.shape),\n };\n this.edgeColumns = {\n label: new LazyColumn(\"edge\", EDGE_DECLS.label),\n start: new TemporalColumn(\"edge\", EDGE_DECLS.start),\n end: new TemporalColumn(\"edge\", EDGE_DECLS.end),\n timestamp: new TemporalColumn(\"edge\", EDGE_DECLS.timestamp),\n spells: new LazyColumn(\"edge\", EDGE_DECLS.spells),\n spellsOpen: new LazyColumn(\"edge\", EDGE_DECLS.spellsOpen),\n timestamps: new LazyColumn(\"edge\", EDGE_DECLS.timestamps),\n open: new LazyColumn(\"edge\", EDGE_DECLS.open),\n color: new LazyColumn(\"edge\", EDGE_DECLS.color),\n shape: new LazyColumn(\"edge\", EDGE_DECLS.shape),\n };\n }\n\n // ---------------------------------------------------------------- events\n\n start(name: string, attrs: ReadonlyMap<string, string>, line: number): void {\n const parent = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];\n const local = localName(name);\n switch (parent) {\n case null:\n if (local !== \"gexf\") {\n this.report.fail(NOT_GEXF_CODE, `the root element is <${name}>, not <gexf>`, { line });\n }\n this.readRoot(attrs);\n this.ctx.push(Ctx.Gexf);\n return;\n case Ctx.Gexf:\n this.startInGexf(name, local, attrs, line);\n return;\n case Ctx.Meta:\n this.startInMeta(name, local, line);\n return;\n case Ctx.Graph:\n this.startInGraph(name, local, attrs, line);\n return;\n case Ctx.Attributes:\n this.startInAttributes(name, local, attrs, line);\n return;\n case Ctx.Attribute:\n this.startInAttribute(name, local, line);\n return;\n case Ctx.Nodes:\n this.startInNodes(name, local, attrs, line);\n return;\n case Ctx.Node:\n this.startInNode(name, local, attrs, line);\n return;\n case Ctx.Attvalues:\n this.startInAttvalues(name, local, attrs, line);\n return;\n case Ctx.Parents:\n this.startInParents(name, local, attrs, line);\n return;\n case Ctx.Spells:\n this.startInSpells(name, local, attrs, line);\n return;\n case Ctx.Edges:\n this.startInEdges(name, local, attrs, line);\n return;\n case Ctx.Edge:\n this.startInEdge(name, local, attrs, line);\n return;\n case Ctx.MetaText:\n case Ctx.AttributeText:\n case Ctx.Skip:\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * An element ends.\n * @param _name - the element name\n * @param _line - the line (unused: issues of an element cite its start line)\n */\n end(_name: string, _line: number): void {\n const ctx = this.ctx.pop();\n switch (ctx) {\n case Ctx.Meta:\n this.finishMeta();\n return;\n case Ctx.MetaText:\n this.finishMetaText();\n return;\n case Ctx.Graph:\n this.resolveParents();\n return;\n case Ctx.Attributes:\n this.attributeGroup = null;\n return;\n case Ctx.Attribute:\n this.finishAttribute();\n return;\n case Ctx.AttributeText:\n this.finishAttributeText();\n return;\n case Ctx.Node:\n this.nodeStack.pop();\n return;\n case Ctx.Edge:\n this.edge = null;\n return;\n case Ctx.Parents:\n this.finishParents();\n return;\n case Ctx.Spells:\n this.finishSpells();\n return;\n case Ctx.Gexf:\n case Ctx.Nodes:\n case Ctx.Edges:\n case Ctx.Attvalues:\n case Ctx.Skip:\n case undefined:\n return;\n default: {\n const value: never = ctx;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown reader state ${String(value)}`, {});\n }\n }\n }\n\n /**\n * Character data: kept inside `<creator>` / `<description>` / `<keywords>` and `<default>` /\n * `<options>`, ignored elsewhere (reported once when it is not whitespace).\n * @param text - the text\n * @param line - the line\n */\n text(text: string, line: number): void {\n const ctx = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];\n switch (ctx) {\n case Ctx.MetaText:\n this.metaText += text;\n return;\n case Ctx.AttributeText:\n this.attributeTextValue += text;\n return;\n case Ctx.Skip:\n return;\n default:\n if (!isWhitespace(text)) {\n this.report.warnOnce(\n \"validation-error\",\n STRAY_TEXT_CODE,\n \"text where GEXF allows only elements was ignored\",\n { line },\n );\n }\n }\n }\n\n /**\n * Apply what the root and `<meta>` gave to the sink; called once the graph's header is read.\n */\n finish(): void {\n if (!this.graphSeen) {\n this.report.fail(NO_GRAPH_CODE, \"the document has no <graph> element\");\n }\n }\n\n // ---------------------------------------------------------------- root, meta, graph\n\n /**\n * Record the root's version.\n * @param attrs - the `<gexf>` attributes\n */\n private readRoot(attrs: ReadonlyMap<string, string>): void {\n const version = attrs.get(\"version\");\n if (version !== undefined && version.length > 0) {\n this.meta.sourceVersion = version;\n }\n }\n\n /**\n * A child of `<gexf>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGexf(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"meta\": {\n const modified = attrs.get(\"lastmodifieddate\");\n if (modified !== undefined && modified.length > 0) {\n this.meta.modified = modified;\n }\n this.ctx.push(Ctx.Meta);\n return;\n }\n case \"graph\":\n if (this.graphSeen) {\n this.report.fail(NO_GRAPH_CODE, \"a second <graph> element; a GEXF document has one graph\", {\n line,\n });\n }\n this.graphSeen = true;\n this.readHeader(attrs, line);\n this.ctx.push(Ctx.Graph);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<meta>`.\n * @param name - the element name\n * @param local - its local name\n * @param line - the line\n */\n private startInMeta(name: string, local: string, line: number): void {\n if (local === \"creator\" || local === \"description\" || local === \"keywords\") {\n this.metaField = local;\n this.metaText = \"\";\n this.ctx.push(Ctx.MetaText);\n return;\n }\n this.unknownElement(name, line);\n }\n\n /** Close a `<creator>` / `<description>` / `<keywords>`. */\n private finishMetaText(): void {\n const text = this.metaText;\n switch (this.metaField) {\n case \"creator\":\n this.meta.creator = text;\n break;\n case \"description\":\n this.meta.description = text;\n break;\n case \"keywords\":\n this.meta.keywords = text\n .split(\",\")\n .map((k) => k.trim())\n .filter((k) => k.length > 0);\n break;\n default:\n break;\n }\n this.metaField = null;\n this.metaText = \"\";\n }\n\n /** Close `<meta>`: nothing more to do (the patch is applied at `<graph>`). */\n private finishMeta(): void {\n // the meta patch is applied when the graph header is read\n }\n\n /**\n * Read `<graph defaultedgetype mode timeformat timerepresentation idtype start end timestamp>`\n * into the meta and the importer's own state, apply the meta patch and set the sink's\n * direction; an unknown value is a warning and the default applies.\n * @param attrs - the `<graph>` attributes\n * @param line - the line\n */\n private readHeader(attrs: ReadonlyMap<string, string>, line: number): void {\n const where = { line };\n const patch = this.meta;\n const edgeType = attrs.get(\"defaultedgetype\");\n if (edgeType === undefined) {\n this.defaultKind = this.options.defaultDirected ? \"directed\" : \"undirected\";\n } else if (EDGE_TYPES.has(edgeTypeKeyword(edgeType))) {\n this.defaultKind = edgeTypeKeyword(edgeType) as GexfEdgeType;\n } else {\n this.defaultKind = this.options.defaultDirected ? \"directed\" : \"undirected\";\n this.warnHeader(\"defaultedgetype\", edgeType, where);\n }\n const mode = attrs.get(\"mode\") ?? attrs.get(\"type\");\n if (mode !== undefined) {\n if (GRAPH_MODES.has(mode)) {\n patch.mode = mode as \"static\" | \"dynamic\" | \"slice\";\n } else {\n this.warnHeader(\"mode\", mode, where);\n }\n }\n const timeFormat = attrs.get(\"timeformat\");\n if (timeFormat !== undefined) {\n if (TIME_FORMATS.has(timeFormat)) {\n this.timeFormat = timeFormat as TimeFormat;\n patch.timeFormat = this.timeFormat;\n } else {\n this.warnHeader(\"timeformat\", timeFormat, where);\n }\n }\n const representation = attrs.get(\"timerepresentation\");\n if (representation !== undefined) {\n if (TIME_REPRESENTATIONS.has(representation)) {\n patch.timeRepresentation = representation as \"interval\" | \"timestamp\";\n } else {\n this.warnHeader(\"timerepresentation\", representation, where);\n }\n }\n const idType = attrs.get(\"idtype\");\n if (idType !== undefined) {\n if (idType === \"string\") {\n // informational only: Gephi writes idtype=\"string\" unconditionally, so honouring it\n // would turn every Gephi export's integer ids into text; the canonical rule of\n // design section 4.1 applies and the exporter's check() reports W_ID_TEXT_TYPE\n patch.idType = \"string\";\n } else if (idType === \"integer\" || idType === \"long\") {\n patch.idType = \"integer\";\n } else {\n this.warnHeader(\"idtype\", idType, where);\n }\n }\n const extra: Record<string, unknown> = {};\n for (const key of [\"defaultedgetype\", \"start\", \"end\", \"timestamp\"]) {\n const value = attrs.get(key);\n if (value !== undefined) {\n extra[key] = value;\n }\n }\n if (Object.keys(extra).length > 0) {\n patch.extra = { gexf: extra };\n }\n this.sink.setMeta(patch);\n this.resolver.setHeader(this.defaultKind !== \"undirected\", where);\n }\n\n /**\n * Record a header value outside its set.\n * @param name - the attribute name\n * @param value - the value found\n * @param where - the header line\n */\n private warnHeader(name: string, value: string, where: IssueLocation): void {\n this.report.warning(\n \"validation-error\",\n HEADER_VALUE_CODE,\n `<graph ${name}=\"${value}\"> is not a known value; the default applies`,\n { ...where, element: name },\n );\n }\n\n /**\n * A child of `<graph>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGraph(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"attributes\":\n this.beginAttributes(attrs, line);\n return;\n case \"nodes\":\n this.nodesSeen = true;\n this.reserve(attrs, \"node\", line);\n this.ctx.push(Ctx.Nodes);\n return;\n case \"edges\":\n if (!this.nodesSeen) {\n this.report.error(\n \"validation-error\",\n MISSING_NODES_CODE,\n \"the graph declares <edges> but no <nodes>\",\n { line },\n );\n }\n this.resolveParents();\n this.reserve(attrs, \"edge\", line);\n this.ctx.push(Ctx.Edges);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * Pass a section's `count` hint to the sink; a hint the sink cannot reserve is a warning.\n * @param attrs - the `<nodes>` or `<edges>` attributes\n * @param domain - which count it is\n * @param line - the line\n */\n private reserve(attrs: ReadonlyMap<string, string>, domain: \"node\" | \"edge\", line: number): void {\n const text = attrs.get(\"count\");\n if (text === undefined) {\n return;\n }\n const count = Number(text);\n if (!Number.isInteger(count) || count < 0 || count > MAX_COUNT) {\n this.report.warning(\n \"validation-error\",\n COUNT_HINT_CODE,\n `<${domain}s count=\"${text}\"> is not a count the sink can reserve; ignored`,\n { line, element: \"count\" },\n );\n return;\n }\n if (count === 0) {\n return;\n }\n try {\n if (domain === \"node\") {\n this.sink.reserve(count, undefined);\n } else {\n this.sink.reserve(undefined, count);\n }\n } catch (err) {\n if (!(err instanceof GraphFormatError)) {\n throw err;\n }\n this.report.warning(\"validation-error\", COUNT_HINT_CODE, `count hint ${text} refused: ${err.message}`, {\n line,\n element: \"count\",\n });\n }\n }\n\n // ---------------------------------------------------------------- attribute declarations\n\n /**\n * Open an `<attributes class mode>` group.\n * @param attrs - the group's attributes\n * @param line - the line\n */\n private beginAttributes(attrs: ReadonlyMap<string, string>, line: number): void {\n const cls = attrs.get(\"class\");\n const where = { line };\n let domain: \"node\" | \"edge\" | null = null;\n if (cls === \"node\" || cls === \"edge\") {\n domain = cls;\n } else {\n this.report.error(\n \"validation-error\",\n ATTRIBUTES_CLASS_CODE,\n cls === undefined\n ? \"<attributes> without a class\"\n : `<attributes class=\"${cls}\"> is neither node nor edge`,\n where,\n );\n }\n const mode = attrs.get(\"mode\");\n if (mode !== undefined && mode !== \"static\" && mode !== \"dynamic\") {\n this.warnHeader(\"mode\", mode, where);\n }\n this.attributeGroup = { domain, dynamic: mode === \"dynamic\" };\n this.ctx.push(Ctx.Attributes);\n }\n\n /**\n * A child of `<attributes>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInAttributes(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"attribute\") {\n this.unknownElement(name, line);\n return;\n }\n const group = this.attributeGroup;\n if (group === null || group.domain === null) {\n // the group's class was refused; its attributes are dropped with it\n this.ctx.push(Ctx.Skip);\n return;\n }\n this.pendingAttribute = {\n domain: group.domain,\n dynamic: group.dynamic,\n attrs,\n line,\n defaultText: null,\n optionsText: null,\n };\n this.ctx.push(Ctx.Attribute);\n }\n\n /**\n * A child of `<attribute>`: `<default>` or `<options>`.\n * @param name - the element name\n * @param local - its local name\n * @param line - the line\n */\n private startInAttribute(name: string, local: string, line: number): void {\n if (local === \"default\" || local === \"options\") {\n this.attributeText = local;\n this.attributeTextValue = \"\";\n this.ctx.push(Ctx.AttributeText);\n return;\n }\n this.unknownElement(name, line);\n }\n\n /** Close a `<default>` / `<options>`. */\n private finishAttributeText(): void {\n const pending = this.pendingAttribute;\n if (pending !== null) {\n if (this.attributeText === \"default\") {\n pending.defaultText = this.attributeTextValue;\n } else if (this.attributeText === \"options\") {\n pending.optionsText = this.attributeTextValue;\n }\n }\n this.attributeText = null;\n this.attributeTextValue = \"\";\n }\n\n /** Close an `<attribute>`: declare it. */\n private finishAttribute(): void {\n const pending = this.pendingAttribute;\n this.pendingAttribute = null;\n if (pending === null) {\n return;\n }\n try {\n this.declareOne(pending);\n } catch (err) {\n this.report.recordError(err, { line: pending.line, element: pending.attrs.get(\"id\") ?? null });\n }\n }\n\n /**\n * Declare one `<attribute id title type>` with its `<default>` and `<options>` (design\n * sections 5.1, 5.5, 5.6). The edge attribute titled `weightFrom` is the weight and gets no\n * column; its declaration is recorded in meta.weightOrigin.\n * @param pending - the attribute as read\n */\n private declareOne(pending: PendingAttribute): void {\n const { report, sink, options } = this;\n const { domain, dynamic, attrs } = pending;\n const id = attrs.get(\"id\");\n const where = { line: pending.line, element: id ?? null };\n if (id === undefined) {\n report.error(\"validation-error\", ATTRIBUTE_ID_CODE, \"<attribute> without an id\", where);\n return;\n }\n const tracked = domain === \"node\" ? this.nodeAttrs : this.edgeAttrs;\n if (tracked.has(id) || (domain === \"edge\" && this.weightAttr !== null && this.weightAttr.id === id)) {\n report.warning(\n \"validation-error\",\n DUPLICATE_ATTRIBUTE_CODE,\n `${domain} attribute \"${id}\" is declared twice; the first declaration is kept`,\n where,\n );\n return;\n }\n const title = attrs.get(\"title\") ?? null;\n const type = attrs.get(\"type\") ?? null;\n if (type === null) {\n report.warning(\n \"validation-error\",\n ATTRIBUTE_TYPE_CODE,\n `attribute \"${id}\" declares no type; read as string`,\n where,\n );\n }\n const name = title !== null && title.length > 0 ? title : id;\n if (domain === \"edge\" && isWeightField(name, options.weightFrom)) {\n const declared = declareAttribute({ format: GEXF_FORMAT, id, title, type, long: options.long });\n for (const issue of declared.issues) {\n report.warning(issue.category, issue.code, issue.message, where);\n }\n this.weightAttr = { id, spec: declared.spec, table: INVALID_INDEX as ExtensionHandle };\n sink.setMeta({ weightOrigin: { format: GEXF_FORMAT, id, title, type, namespace: null } });\n return;\n }\n const declaredNames = domain === \"node\" ? this.declaredNodeNames : this.declaredEdgeNames;\n const reserved = domain === \"node\" ? RESERVED_NODE_NAMES : RESERVED_EDGE_NAMES;\n const taken = (candidate: string): boolean => reserved.has(candidate) || declaredNames.has(candidate);\n const input: AttributeDeclarationInput = {\n format: GEXF_FORMAT,\n id,\n title,\n type,\n defaultText: pending.defaultText,\n optionsText: pending.optionsText,\n listSyntax: \"gexf\",\n dynamic,\n long: options.long,\n taken,\n };\n const declared: DeclaredAttribute = declareAttribute(input);\n for (const issue of declared.issues) {\n report.warning(issue.category, issue.code, issue.message, where);\n }\n const resolved = declareResolved(sink, domain, declared.decl, report, where);\n declaredNames.add(resolved.decl.name);\n let companionDecl: ColumnDecl | null = null;\n if (declared.companion !== null) {\n companionDecl = {\n ...declared.companion,\n name: `${resolved.decl.name}.text`,\n extra: { for: resolved.decl.name },\n };\n declaredNames.add(companionDecl.name);\n }\n const valueDecl: Pick<ColumnDecl, \"dtype\" | \"itemDtype\" | \"options\" | \"origin\"> = {\n dtype: resolved.decl.dtype,\n itemDtype: resolved.decl.itemDtype,\n options: resolved.decl.options,\n origin: resolved.decl.origin,\n };\n tracked.set(id, {\n id,\n name: resolved.decl.name,\n spec: declared.spec,\n listSyntax: declared.listSyntax,\n handle: resolved.handle,\n companionDecl,\n companion: INVALID_INDEX as ColumnHandle,\n dynamic,\n valueDecl,\n table: INVALID_INDEX as ExtensionHandle,\n });\n }\n\n // ---------------------------------------------------------------- nodes\n\n /**\n * A child of `<nodes>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInNodes(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"node\") {\n this.unknownElement(name, line);\n return;\n }\n this.beginNode(attrs, line);\n }\n\n /**\n * Push one `<node>`.\n * @param attrs - its attributes\n * @param line - the line\n */\n private beginNode(attrs: ReadonlyMap<string, string>, line: number): void {\n const { report, sink } = this;\n this.checkAbort();\n const enclosing = this.nodeStack.length === 0 ? INVALID_INDEX : this.nodeStack[this.nodeStack.length - 1].index;\n const idText = attrs.get(\"id\");\n const where: IssueLocation = { line, element: idText ?? attrs.get(\"label\") ?? null };\n this.checkAttributeNames(attrs, NODE_ATTRIBUTES, \"node\", where);\n if (idText === undefined) {\n report.error(\"missing-value\", MISSING_ID_CODE, \"<node> without an id\", where);\n report.counts.skippedNodes++;\n this.nodeStack.push({ index: INVALID_INDEX, where });\n this.ctx.push(Ctx.Node);\n return;\n }\n let index: number;\n try {\n const id = this.coerceId(idText, where);\n const existing = sink.indexOf(id);\n if (existing !== INVALID_INDEX) {\n report.warning(\n \"validation-error\",\n DUPLICATE_NODE_CODE,\n `node \"${idText}\" is declared more than once; later attributes overwrite`,\n where,\n );\n index = existing;\n } else {\n index = sink.addNode(id);\n report.counts.nodes++;\n }\n } catch (err) {\n report.recordError(err, where);\n report.counts.skippedNodes++;\n this.nodeStack.push({ index: INVALID_INDEX, where });\n this.ctx.push(Ctx.Node);\n return;\n }\n this.nodeStack.push({ index, where });\n this.ctx.push(Ctx.Node);\n try {\n const label = attrs.get(\"label\");\n if (label !== undefined) {\n this.nodeColumns.label.set(sink, report, index, label, where);\n }\n const pid = attrs.get(\"pid\");\n if (pid !== undefined) {\n this.parentRefs.push({\n child: index,\n parentId: this.coerceId(pid, where),\n parentIndex: INVALID_INDEX,\n where,\n });\n } else if (enclosing !== INVALID_INDEX) {\n this.parentRefs.push({ child: index, parentId: null, parentIndex: enclosing, where });\n }\n this.writeLifetime(attrs, index, this.nodeColumns, where);\n } catch (err) {\n report.recordError(err, where);\n }\n }\n\n /**\n * A child of `<node>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInNode(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n const frame = this.nodeStack[this.nodeStack.length - 1];\n if (frame.index === INVALID_INDEX && local !== \"nodes\") {\n // the node was skipped; its children are too\n this.ctx.push(Ctx.Skip);\n return;\n }\n switch (local) {\n case \"attvalues\":\n this.ctx.push(Ctx.Attvalues);\n return;\n case \"parents\":\n this.parentIds = [];\n this.ctx.push(Ctx.Parents);\n return;\n case \"spells\":\n this.spellPairs = [];\n this.spellOpen = [];\n this.spellsWhere = frame.where;\n this.ctx.push(Ctx.Spells);\n return;\n case \"nodes\":\n this.reserve(attrs, \"node\", line);\n this.ctx.push(Ctx.Nodes);\n return;\n case \"color\":\n case \"position\":\n case \"size\":\n case \"shape\":\n this.writeViz(name, local, attrs, \"node\", frame.index, frame.where);\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A `<parent for>` inside `<parents>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInParents(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"parent\") {\n this.unknownElement(name, line);\n return;\n }\n this.ctx.push(Ctx.Skip);\n const frame = this.nodeStack[this.nodeStack.length - 1];\n const text = attrs.get(\"for\");\n if (text === undefined) {\n this.report.warning(\"missing-value\", ATTVALUE_SHAPE_CODE, \"<parent> without a for attribute\", frame.where);\n return;\n }\n try {\n this.parentIds?.push(this.coerceId(text, frame.where));\n } catch (err) {\n this.report.recordError(err, frame.where);\n }\n }\n\n /** Close `<parents>`: queue the list for resolution. */\n private finishParents(): void {\n const frame = this.nodeStack[this.nodeStack.length - 1];\n if (this.parentIds !== null && frame.index !== INVALID_INDEX) {\n this.parentsRefs.push({ child: frame.index, ids: this.parentIds, where: frame.where });\n }\n this.parentIds = null;\n }\n\n /**\n * Resolve every `pid`, nested and `<parents>` reference read so far now that every node is\n * declared (design section 8.4); an unknown parent is a missing-value error.\n */\n private resolveParents(): void {\n const { sink, report } = this;\n const refs = this.parentRefs;\n const lists = this.parentsRefs;\n this.parentRefs = [];\n this.parentsRefs = [];\n for (const ref of refs) {\n let parent = ref.parentIndex;\n if (ref.parentId !== null) {\n parent = sink.indexOf(ref.parentId);\n if (parent === INVALID_INDEX) {\n report.error(\n \"missing-value\",\n UNKNOWN_PARENT_CODE,\n `pid \"${String(ref.parentId)}\" names a node the document does not declare`,\n ref.where,\n );\n continue;\n }\n }\n try {\n this.parentColumn.set(sink, report, ref.child, parent, ref.where);\n } catch (err) {\n report.recordError(err, ref.where);\n }\n }\n for (const ref of lists) {\n const indices: number[] = [];\n for (const id of ref.ids) {\n const parent = sink.indexOf(id);\n if (parent === INVALID_INDEX) {\n report.error(\n \"missing-value\",\n UNKNOWN_PARENT_CODE,\n `<parent for=\"${String(id)}\"> names a node the document does not declare`,\n ref.where,\n );\n continue;\n }\n indices.push(parent);\n }\n try {\n this.parentsColumn.set(sink, report, ref.child, indices, ref.where);\n } catch (err) {\n report.recordError(err, ref.where);\n }\n }\n }\n\n // ---------------------------------------------------------------- edges\n\n /**\n * A child of `<edges>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInEdges(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"edge\") {\n this.unknownElement(name, line);\n return;\n }\n this.beginEdge(attrs, line);\n }\n\n /**\n * Push one `<edge>`.\n * @param attrs - its attributes\n * @param line - the line\n */\n private beginEdge(attrs: ReadonlyMap<string, string>, line: number): void {\n const { report, sink, options } = this;\n this.checkAbort();\n this.ctx.push(Ctx.Edge);\n this.edge = null;\n const sourceText = attrs.get(\"source\");\n const targetText = attrs.get(\"target\");\n const idText = attrs.get(\"id\");\n const { where } = this.edgeFrame;\n where.line = line;\n where.element = idText ?? edgeElement(sourceText, targetText);\n this.checkAttributeNames(attrs, EDGE_ATTRIBUTES, \"edge\", where);\n if (sourceText === undefined || targetText === undefined) {\n report.error(\n \"missing-value\",\n MISSING_ENDPOINT_CODE,\n `<edge> without a ${sourceText === undefined ? \"source\" : \"target\"}`,\n where,\n );\n report.counts.skippedEdges++;\n return;\n }\n let kind: EdgeKind = this.defaultKind;\n const typeText = attrs.get(\"type\");\n if (typeText !== undefined) {\n const type = edgeTypeKeyword(typeText);\n if (!EDGE_TYPES.has(type)) {\n report.error(\n \"validation-error\",\n EDGE_TYPE_CODE,\n `edge type \"${typeText}\" is not directed, undirected or mutual`,\n where,\n );\n report.counts.skippedEdges++;\n return;\n }\n kind = type as EdgeKind;\n }\n if (idText !== undefined) {\n if (this.edgeIds.has(idText)) {\n report.error(\n \"validation-error\",\n DUPLICATE_EDGE_ID_CODE,\n `edge id \"${idText}\" is declared more than once; the edge is skipped`,\n where,\n );\n report.counts.skippedEdges++;\n return;\n }\n this.edgeIds.add(idText);\n }\n let index: number;\n try {\n const source = this.coerceId(sourceText, where);\n const target = this.coerceId(targetText, where);\n if (!options.addMissingNodes) {\n if (sink.indexOf(source) === INVALID_INDEX) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge references undeclared node \"${sourceText}\"`, {\n id: source,\n });\n }\n if (sink.indexOf(target) === INVALID_INDEX) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge references undeclared node \"${targetText}\"`, {\n id: target,\n });\n }\n }\n const weight = this.xmlWeight(attrs, where);\n const before = sink.edgeCount;\n index = this.resolver.addEdge(source, target, kind, weight, where);\n report.counts.edges += sink.edgeCount - before;\n } catch (err) {\n report.recordError(err, where);\n report.counts.skippedEdges++;\n return;\n }\n const frame = this.edgeFrame;\n frame.index = index;\n frame.mirror = this.resolver.lastMirror;\n this.edge = frame;\n try {\n if (idText !== undefined) {\n this.edgeIdColumn.set(sink, report, index, idText, where);\n }\n const label = attrs.get(\"label\");\n if (label !== undefined) {\n this.edgeColumns.label.set(sink, report, index, label, where);\n }\n const edgeKind = attrs.get(\"kind\");\n if (edgeKind !== undefined) {\n this.edgeKindColumn.set(sink, report, index, edgeKind, where);\n }\n this.writeLifetime(attrs, index, this.edgeColumns, where);\n } catch (err) {\n report.recordError(err, where);\n }\n }\n\n /**\n * The weight argument of one edge from its `weight` XML attribute; undefined when absent (the\n * sink records a defaulted weight, design section 3.7).\n * @param attrs - the edge's attributes\n * @param where - the edge's location\n * @returns the weight, or undefined\n */\n private xmlWeight(attrs: ReadonlyMap<string, string>, where: IssueLocation): number | undefined {\n const text = attrs.get(\"weight\");\n if (text === undefined) {\n return undefined;\n }\n if (this.options.weightFrom === null) {\n this.report.warnOnce(\n \"coercion\",\n WEIGHT_IGNORED_CODE,\n \"the weight attribute is ignored because weightFrom is null; edges are unweighted\",\n where,\n );\n return undefined;\n }\n return parseWeightText(text);\n }\n\n /**\n * A child of `<edge>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInEdge(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n const { edge } = this;\n if (edge === null) {\n this.ctx.push(Ctx.Skip);\n return;\n }\n switch (local) {\n case \"attvalues\":\n this.ctx.push(Ctx.Attvalues);\n return;\n case \"spells\":\n this.spellPairs = [];\n this.spellOpen = [];\n this.spellsWhere = edge.where;\n this.ctx.push(Ctx.Spells);\n return;\n case \"color\":\n case \"thickness\":\n case \"shape\":\n this.writeViz(name, local, attrs, \"edge\", edge.index, edge.where);\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n // ---------------------------------------------------------------- attribute values\n\n /**\n * An `<attvalue>` of the open node or edge; a value that does not parse is recorded and skipped\n * without losing the element or its other values.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInAttvalues(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"attvalue\") {\n this.unknownElement(name, line);\n return;\n }\n this.ctx.push(Ctx.Skip);\n const { report, edge } = this;\n const domain: \"node\" | \"edge\" = edge === null ? \"node\" : \"edge\";\n let index: number;\n let element: string | null;\n if (edge !== null) {\n ({ index } = edge);\n element = edge.where.element ?? null;\n } else {\n const frame = this.nodeStack[this.nodeStack.length - 1];\n ({ index } = frame);\n element = frame.where.element ?? null;\n }\n if (index === INVALID_INDEX) {\n return;\n }\n const forId = attrs.get(\"for\");\n const { valueWhere } = this;\n valueWhere.line = line;\n valueWhere.element = element;\n if (forId === undefined) {\n report.warning(\"missing-value\", ATTVALUE_SHAPE_CODE, \"<attvalue> without a for attribute\", valueWhere);\n return;\n }\n const value = attrs.get(\"value\");\n if (value === undefined) {\n report.warning(\n \"missing-value\",\n ATTVALUE_SHAPE_CODE,\n `<attvalue for=\"${forId}\"> without a value attribute`,\n valueWhere,\n );\n return;\n }\n try {\n if (domain === \"edge\" && this.weightAttr !== null && this.weightAttr.id === forId) {\n if (isTimed(attrs)) {\n this.writeTimedWeight(attrs, value, index, valueWhere);\n } else {\n this.applyStaticWeight(value, valueWhere);\n }\n return;\n }\n const tracked = domain === \"node\" ? this.nodeAttrs : this.edgeAttrs;\n const attribute = tracked.get(forId);\n if (attribute === undefined) {\n const key = `${domain}:${forId}`;\n if (!this.unknownAttributes.has(key)) {\n this.unknownAttributes.add(key);\n report.warning(\n \"missing-value\",\n UNKNOWN_ATTRIBUTE_CODE,\n `<attvalue for=\"${forId}\"> names an undeclared ${domain} attribute; its values are dropped`,\n { ...valueWhere, element: forId },\n );\n }\n return;\n }\n if (isTimed(attrs)) {\n this.writeTimedValue(attribute, domain, attrs, value, index, valueWhere);\n } else {\n this.writeStaticValue(attribute, domain, value, index, valueWhere);\n }\n } catch (err) {\n report.recordError(err, { ...valueWhere, element: `${element ?? \"?\"}[${forId}]` });\n }\n }\n\n /**\n * A static value of the attribute titled `weightFrom` overrides the XML weight of the open\n * edge (and of its mirror half, design section 3.6).\n * @param text - the value text\n * @param where - the value's location\n */\n private applyStaticWeight(text: string, where: IssueLocation): void {\n const { edge, sink } = this;\n if (edge === null) {\n return;\n }\n const weight = parseWeightText(text);\n if (weight === undefined) {\n throw new GraphFormatError(\"E_INVALID_WEIGHT\", \"an edge weight cannot be blank\", {\n value: text,\n line: where.line ?? null,\n });\n }\n sink.setEdgeWeight(edge.index, weight);\n if (edge.mirror !== INVALID_INDEX) {\n sink.setEdgeWeight(edge.mirror, weight);\n }\n }\n\n /**\n * Parse a value by its declaration and write the cell (and the temporal companion, declared\n * on the first value whose text is not canonical, design section 5.1).\n * @param attribute - the declaration\n * @param domain - node or edge\n * @param text - the value text\n * @param index - the element's index\n * @param where - the value's location\n */\n private writeStaticValue(\n attribute: TrackedAttribute,\n domain: \"node\" | \"edge\",\n text: string,\n index: number,\n where: IssueLocation,\n ): void {\n const { spec } = attribute;\n if (spec.temporal !== null && !spec.list) {\n const parsed = parseDeclaredTemporal(text, spec);\n this.setCell(domain, attribute.handle, index, parsed.value);\n if (parsed.text !== null && attribute.companionDecl !== null) {\n if (attribute.companion === INVALID_INDEX) {\n attribute.companion = declareCompanion(this.sink, domain, attribute.companionDecl, this.report);\n }\n this.setCell(domain, attribute.companion, index, parsed.text);\n }\n return;\n }\n const value = parseDeclaredValue(text, spec, attribute.listSyntax);\n if (losesPrecision(spec, text)) {\n this.report.warning(\n \"precision\",\n PRECISION_CODE,\n `long value ${text.trim()} of \"${attribute.name}\" exceeds 2^53 and was rounded`,\n where,\n );\n }\n this.setCell(domain, attribute.handle, index, value);\n }\n\n /**\n * Append a timed value to the attribute's temporal table (design section 5.10), creating the\n * table on first use.\n * @param attribute - the declaration\n * @param domain - node or edge\n * @param attrs - the `<attvalue>` attributes carrying the bounds\n * @param text - the value text\n * @param index - the element's index\n * @param where - the value's location\n */\n private writeTimedValue(\n attribute: TrackedAttribute,\n domain: \"node\" | \"edge\",\n attrs: ReadonlyMap<string, string>,\n text: string,\n index: number,\n where: IssueLocation,\n ): void {\n const { sink, report } = this;\n if (!attribute.dynamic) {\n report.warnOnce(\n \"validation-error\",\n TIMED_STATIC_CODE,\n `attribute \"${attribute.name}\" is declared static but has timed values; they are stored as dynamic`,\n where,\n );\n }\n const { spec } = attribute;\n const temporalValue = spec.temporal !== null && !spec.list;\n if (attribute.table === INVALID_INDEX) {\n attribute.table = sink.addExtensionTable(\n temporalTableName(domain, attribute.name),\n temporalTableDecls(domain, attribute.valueDecl, temporalValue),\n );\n }\n let value: unknown;\n let valueText: string | null = null;\n if (temporalValue) {\n const parsed = parseDeclaredTemporal(text, spec);\n ({ value } = parsed);\n valueText = parsed.text;\n } else {\n value = parseDeclaredValue(text, spec, attribute.listSyntax);\n if (losesPrecision(spec, text)) {\n report.warning(\n \"precision\",\n PRECISION_CODE,\n `long value ${text.trim()} of \"${attribute.name}\" exceeds 2^53 and was rounded`,\n where,\n );\n }\n }\n const row = this.temporalRow(attrs, index, value, where);\n if (temporalValue) {\n row.push(valueText ?? undefined);\n }\n sink.addExtensionRow(attribute.table, row);\n }\n\n /**\n * Append a timed weight to the `temporal:edge:weight` table (design section 5.10).\n * @param attrs - the `<attvalue>` attributes carrying the bounds\n * @param text - the value text\n * @param index - the edge index\n * @param where - the value's location\n */\n private writeTimedWeight(\n attrs: ReadonlyMap<string, string>,\n text: string,\n index: number,\n where: IssueLocation,\n ): void {\n const { weightAttr } = this;\n if (weightAttr === null) {\n return;\n }\n const { sink } = this;\n if (weightAttr.table === INVALID_INDEX) {\n weightAttr.table = sink.addExtensionTable(\n temporalTableName(\"edge\", this.options.weightFrom ?? \"weight\"),\n temporalTableDecls(\n \"edge\",\n {\n dtype: \"f64\",\n origin: { format: GEXF_FORMAT, id: weightAttr.id, type: weightAttr.spec.declared },\n },\n false,\n ),\n );\n }\n const value = parseWeightText(text);\n if (value === undefined) {\n throw new GraphFormatError(\"E_INVALID_WEIGHT\", \"a timed edge weight cannot be blank\", {\n value: text,\n line: where.line ?? null,\n });\n }\n sink.addExtensionRow(weightAttr.table, this.temporalRow(attrs, index, value, where));\n }\n\n /**\n * The row of a temporal table for one timed value: element, bounds, value, bound texts, open bits.\n * @param attrs - the attributes carrying `start` / `end` / `timestamp` / `startopen` / `endopen`\n * @param index - the element's index\n * @param value - the parsed value\n * @param where - the value's location\n * @returns the row, without the optional value text\n */\n private temporalRow(\n attrs: ReadonlyMap<string, string>,\n index: number,\n value: unknown,\n where: IssueLocation,\n ): unknown[] {\n const bounds = this.readBounds(attrs, where);\n return [\n index,\n bounds.start.value,\n bounds.end.value,\n value,\n bounds.start.text ?? undefined,\n bounds.end.text ?? undefined,\n bounds.open === 0 ? undefined : bounds.open,\n ];\n }\n\n /**\n * The interval of an element or timed value: `timestamp`, or `start` / `startopen` and `end` /\n * `endopen` (GEXF 1.2: the open form carries the bound's time and marks the bound open, design\n * section 5.1); missing bounds are unbounded.\n * @param attrs - the attributes\n * @param where - the location, for the conflict warning\n * @returns the bounds and the open bits\n */\n private readBounds(\n attrs: ReadonlyMap<string, string>,\n where: IssueLocation,\n ): { start: TemporalValue; end: TemporalValue; open: number } {\n let start: TemporalValue = { value: -Infinity, text: null };\n let end: TemporalValue = { value: Infinity, text: null };\n let open = 0;\n const timestamp = attrs.get(\"timestamp\");\n if (timestamp !== undefined) {\n start = parseTimeText(timestamp, this.timeFormat);\n end = start;\n }\n const startText = attrs.get(\"start\");\n const startOpen = attrs.get(\"startopen\");\n if (startText !== undefined) {\n start = parseTimeText(startText, this.timeFormat);\n if (startOpen !== undefined) {\n this.warnOpenConflict(\"start\", where);\n }\n } else if (startOpen !== undefined) {\n start = parseTimeText(startOpen, this.timeFormat);\n open |= OPEN_START;\n }\n const endText = attrs.get(\"end\");\n const endOpen = attrs.get(\"endopen\");\n if (endText !== undefined) {\n end = parseTimeText(endText, this.timeFormat);\n if (endOpen !== undefined) {\n this.warnOpenConflict(\"end\", where);\n }\n } else if (endOpen !== undefined) {\n end = parseTimeText(endOpen, this.timeFormat);\n open |= OPEN_END;\n }\n return { start, end, open };\n }\n\n /**\n * Record a `start` next to a `startopen` (or `end` next to `endopen`), which the 1.2 primer forbids.\n * @param bound - which bound\n * @param where - the location\n */\n private warnOpenConflict(bound: \"start\" | \"end\", where: IssueLocation): void {\n this.report.warnOnce(\n \"validation-error\",\n OPEN_BOUND_CONFLICT_CODE,\n `both ${bound} and ${bound}open are given; the closed bound is kept`,\n where,\n );\n }\n\n // ---------------------------------------------------------------- lifetimes\n\n /**\n * Write an element's lifetime: `start` / `end` / `timestamp` (with text companions), the 1.2\n * `startopen` / `endopen` bounds and bits, and the 1.3 `timestamps` / `intervals` attributes.\n * @param attrs - the node or edge attributes\n * @param index - its index\n * @param columns - the domain's columns\n * @param where - the element's location\n */\n private writeLifetime(\n attrs: ReadonlyMap<string, string>,\n index: number,\n columns: DomainColumns,\n where: IssueLocation,\n ): void {\n const { sink, report } = this;\n if (\n attrs.has(\"start\") ||\n attrs.has(\"end\") ||\n attrs.has(\"timestamp\") ||\n attrs.has(\"startopen\") ||\n attrs.has(\"endopen\")\n ) {\n const bounds = this.readBounds(attrs, where);\n const timestamp = attrs.get(\"timestamp\");\n if (timestamp !== undefined) {\n columns.timestamp.set(sink, report, index, bounds.start, where);\n }\n if (attrs.has(\"start\") || attrs.has(\"startopen\")) {\n columns.start.set(sink, report, index, bounds.start, where);\n }\n if (attrs.has(\"end\") || attrs.has(\"endopen\")) {\n columns.end.set(sink, report, index, bounds.end, where);\n }\n if (bounds.open !== 0) {\n columns.open.set(sink, report, index, bounds.open, where);\n }\n }\n const timestamps = attrs.get(\"timestamps\");\n if (timestamps !== undefined) {\n const items = splitListText(stripAngles(timestamps), \"brackets\");\n columns.timestamps.set(\n sink,\n report,\n index,\n items.map((item) => parseTimeText(item, this.timeFormat).value),\n where,\n );\n }\n const intervals = attrs.get(\"intervals\");\n if (intervals !== undefined) {\n columns.spells.set(sink, report, index, this.parseIntervals(intervals, where), where);\n }\n }\n\n /**\n * Parse a 1.3 `intervals=\"<[s, e]; [s, e]>\"` attribute into spell pairs.\n * @param text - the attribute text\n * @param where - the element's location, for the error\n * @returns the pairs\n */\n private parseIntervals(text: string, where: IssueLocation): number[][] {\n const pairs: number[][] = [];\n for (const part of stripAngles(text).split(\";\")) {\n if (part.trim().length === 0) {\n continue;\n }\n const items = splitListText(part, \"brackets\");\n if (items.length !== 2) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `interval \"${part.trim()}\" is not a [start, end] pair`, {\n value: part,\n line: where.line ?? null,\n });\n }\n pairs.push([\n parseTimeText(items[0], this.timeFormat).value,\n parseTimeText(items[1], this.timeFormat).value,\n ]);\n }\n return pairs;\n }\n\n /**\n * A `<spell>` inside `<spells>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInSpells(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n if (local !== \"spell\") {\n this.unknownElement(name, line);\n return;\n }\n this.ctx.push(Ctx.Skip);\n const where = this.spellsWhere ?? { line };\n try {\n const bounds = this.readBounds(attrs, where);\n this.spellPairs?.push([bounds.start.value, bounds.end.value]);\n this.spellOpen.push(bounds.open);\n } catch (err) {\n this.report.recordError(err, where);\n }\n }\n\n /**\n * Close `<spells>`: write the pairs into the open element's spells column, and their open bits\n * into the spells.open column when any spell has an open bound.\n */\n private finishSpells(): void {\n const pairs = this.spellPairs;\n const open = this.spellOpen;\n const where = this.spellsWhere ?? undefined;\n this.spellPairs = null;\n this.spellOpen = [];\n this.spellsWhere = null;\n if (pairs === null) {\n return;\n }\n try {\n const columns = this.edge === null ? this.nodeColumns : this.edgeColumns;\n const { index } = this.edge ?? this.nodeStack[this.nodeStack.length - 1];\n if (index !== INVALID_INDEX) {\n columns.spells.set(this.sink, this.report, index, pairs, where);\n if (open.some((bits) => bits !== 0)) {\n columns.spellsOpen.set(this.sink, this.report, index, open, where);\n }\n }\n } catch (err) {\n this.report.recordError(err, where);\n }\n }\n\n // ---------------------------------------------------------------- viz\n\n /**\n * Write one viz element into its role column; a value that does not parse is a recorded\n * warning and the element is skipped.\n * @param name - the element name as written\n * @param local - its local name\n * @param attrs - its attributes\n * @param domain - node or edge\n * @param index - the element's index\n * @param where - the element's location\n */\n private writeViz(\n name: string,\n local: string,\n attrs: ReadonlyMap<string, string>,\n domain: \"node\" | \"edge\",\n index: number,\n where: IssueLocation,\n ): void {\n const { sink, report } = this;\n if (!this.viz) {\n report.warnOnce(\"unsupported\", VIZ_SKIPPED_CODE, \"viz elements are skipped (option viz: false)\", where);\n return;\n }\n if (isTimed(attrs)) {\n report.warnOnce(\n \"unsupported\",\n VIZ_DYNAMIC_CODE,\n \"dynamic viz elements are not supported; the bounds are dropped and the last value kept\",\n where,\n );\n }\n const columns = domain === \"node\" ? this.nodeColumns : this.edgeColumns;\n try {\n switch (local) {\n case \"color\":\n columns.color.set(sink, report, index, parseColor(attrs), where);\n break;\n case \"position\": {\n const x = vizNumber(attrs, \"x\");\n const y = vizNumber(attrs, \"y\");\n const z = attrs.has(\"z\") ? vizNumber(attrs, \"z\") : 0;\n this.positionColumn ??= new LazyColumn(\"node\", {\n ...NODE_DECLS.position,\n extra: { ...NODE_DECLS.position.extra, sourceDims: attrs.has(\"z\") ? 3 : 2 },\n });\n this.positionColumn.set(sink, report, index, [x, y, z], where);\n break;\n }\n case \"size\":\n this.sizeColumn.set(sink, report, index, vizNumber(attrs, \"value\"), where);\n break;\n case \"thickness\":\n this.thicknessColumn.set(sink, report, index, vizNumber(attrs, \"value\"), where);\n break;\n case \"shape\": {\n const value = attrs.get(\"value\");\n if (value === undefined) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", \"<viz:shape> without a value\", { element: name });\n }\n columns.shape.set(sink, report, index, value, where);\n const uri = attrs.get(\"uri\");\n if (domain === \"node\" && uri !== undefined) {\n this.shapeUriColumn.set(sink, report, index, uri, where);\n }\n break;\n }\n default:\n break;\n }\n } catch (err) {\n if (!(err instanceof GraphFormatError) || err.code !== \"E_COLUMN_TYPE\") {\n throw err;\n }\n report.warning(\"validation-error\", VIZ_VALUE_CODE, `<${name}> skipped: ${err.message}`, where);\n }\n }\n\n // ---------------------------------------------------------------- helpers\n\n /**\n * Report an element the schema does not define at this place and skip its subtree.\n * @param name - the element name\n * @param line - the line\n */\n private unknownElement(name: string, line: number): void {\n this.report.warnOnce(\"unsupported\", UNKNOWN_ELEMENT_CODE, `element <${name}> is not GEXF and was skipped`, {\n line,\n element: name,\n });\n this.ctx.push(Ctx.Skip);\n }\n\n /**\n * Report XML attributes the importer does not read (once per attribute name and domain).\n * @param attrs - the element's attributes\n * @param known - the attribute names read\n * @param domain - node or edge\n * @param where - the element's location\n */\n private checkAttributeNames(\n attrs: ReadonlyMap<string, string>,\n known: ReadonlySet<string>,\n domain: \"node\" | \"edge\",\n where: IssueLocation,\n ): void {\n for (const key of attrs.keys()) {\n if (!known.has(key)) {\n const seen = `${domain}@${key}`;\n if (!this.unknownAttributes.has(seen)) {\n this.unknownAttributes.add(seen);\n this.report.warning(\n \"unsupported\",\n UNKNOWN_ELEMENT_CODE,\n `attribute ${key} of <${domain}> is not GEXF and was ignored`,\n { ...where, element: key },\n );\n }\n }\n }\n }\n\n /**\n * Write one cell of a domain.\n * @param domain - node or edge\n * @param handle - the column\n * @param index - the row\n * @param value - the value\n */\n private setCell(domain: \"node\" | \"edge\", handle: ColumnHandle, index: number, value: unknown): void {\n if (domain === \"node\") {\n this.sink.setNodeValue(handle, index, value);\n } else {\n this.sink.setEdgeValue(handle, index, value);\n }\n }\n\n /**\n * Coerce an id text, recording a merge under ids \"number\".\n * @param text - the id text\n * @param where - the location, for the merge warning\n * @returns the id\n */\n private coerceId(text: string, where: IssueLocation): NodeId {\n const id = this.coercer.text(text);\n const merge = this.coercer.lastMerge;\n if (merge !== null) {\n this.report.warning(\n \"coercion\",\n ID_MERGED_CODE,\n `id text \"${merge.text}\" merged with \"${merge.previousText}\" as ${merge.id} under ids \"number\"`,\n where,\n );\n }\n return id;\n }\n\n /** Check the cancellation signal every ABORT_CHECK_INTERVAL elements. */\n private checkAbort(): void {\n if (++this.elementsSinceCheck >= ABORT_CHECK_INTERVAL) {\n this.elementsSinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n}\n\n/**\n * The element text of an edge without an id, for issues.\n * @param source - the source text, or undefined\n * @param target - the target text, or undefined\n * @returns `source->target`\n */\nfunction edgeElement(source: string | undefined, target: string | undefined): string {\n return `${source ?? \"?\"}->${target ?? \"?\"}`;\n}\n\n/**\n * Whether an element carries time bounds.\n * @param attrs - the element's attributes\n * @returns true when start, end, timestamp or an open bound is present\n */\nfunction isTimed(attrs: ReadonlyMap<string, string>): boolean {\n return (\n attrs.has(\"start\") ||\n attrs.has(\"end\") ||\n attrs.has(\"timestamp\") ||\n attrs.has(\"startopen\") ||\n attrs.has(\"endopen\")\n );\n}\n\n/**\n * Remove the `<` `>` wrapper of a 1.3 `timestamps` / `intervals` attribute value.\n * @param text - the attribute text\n * @returns the inner text\n */\nfunction stripAngles(text: string): string {\n let inner = text.trim();\n if (inner.startsWith(\"<\")) {\n inner = inner.slice(1);\n }\n if (inner.endsWith(\">\")) {\n inner = inner.slice(0, -1);\n }\n return inner;\n}\n\n/**\n * A numeric viz attribute.\n * @param attrs - the element's attributes\n * @param name - the attribute name\n * @returns the number; E_COLUMN_TYPE when absent or not a number\n */\nfunction vizNumber(attrs: ReadonlyMap<string, string>, name: string): number {\n const text = attrs.get(name);\n if (text === undefined) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `viz element without a ${name} attribute`, { attribute: name });\n }\n const value = parseDecimalText(text);\n if (Number.isNaN(value)) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `viz ${name}=\"${text}\" is not a number`, { attribute: name });\n }\n return value;\n}\n\n/**\n * Parse `<viz:color r g b a hex>` into rgba in 0..1 (design section 5.5: role color, f32 x4).\n * @param attrs - the element's attributes\n * @returns [r, g, b, a]\n */\nfunction parseColor(attrs: ReadonlyMap<string, string>): number[] {\n let r: number;\n let g: number;\n let b: number;\n const hex = attrs.get(\"hex\");\n if (hex !== undefined && !attrs.has(\"r\")) {\n const digits = hex.startsWith(\"#\") ? hex.slice(1) : hex;\n if (!/^[0-9a-fA-F]{6}$/.test(digits)) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `viz hex=\"${hex}\" is not a #RRGGBB colour`, {\n attribute: \"hex\",\n });\n }\n r = Number.parseInt(digits.slice(0, 2), 16);\n g = Number.parseInt(digits.slice(2, 4), 16);\n b = Number.parseInt(digits.slice(4, 6), 16);\n } else {\n r = vizNumber(attrs, \"r\");\n g = vizNumber(attrs, \"g\");\n b = vizNumber(attrs, \"b\");\n }\n const a = attrs.has(\"a\") ? vizNumber(attrs, \"a\") : 1;\n return [r / 255, g / 255, b / 255, a];\n}\n\n/** A head that starts with markup, after an optional byte-order mark and whitespace. */\nconst XML_START = /^\\uFEFF?\\s*</;\n\n/**\n * Confidence that a document head is GEXF.\n * @param head - the first bytes\n * @returns 1 for a `<gexf` tag, 0.8 for a gexf.net namespace, 0 otherwise or when the head does\n * not start with markup\n */\nfunction sniffGexf(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\", { fatal: false }).decode(head);\n // Only a document that starts as markup: a JSON or CSV value may mention a `<gexf>` tag.\n if (!XML_START.test(text)) {\n return 0;\n }\n if (/<(\\w+:)?gexf[\\s>]/.test(text)) {\n return 1;\n }\n return text.includes(\"gexf.net\") ? 0.8 : 0;\n}\n\n/**\n * Validate the format-specific options.\n * @param options - the caller's options\n * @returns whether viz elements are imported\n */\nfunction resolveGexfOptions(options: (GexfImportOptions & CommonImportOptions) | undefined): boolean {\n const viz = options?.viz;\n if (viz === undefined) {\n return true;\n }\n if (typeof viz !== \"boolean\") {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option viz: ${typeof viz} is not a boolean`, {\n option: \"viz\",\n found: viz,\n });\n }\n return viz;\n}\n\n/** The GEXF importer (design section 8.4). */\nexport const gexfImporter: GraphImporter<GexfImportOptions> = Object.freeze({\n format: GEXF_FORMAT,\n extensions: Object.freeze([\".gexf\"]),\n mimeTypes: Object.freeze([\"application/gexf+xml\", \"application/xml\", \"text/xml\"]),\n sniff: sniffGexf,\n /**\n * Read a GEXF document into the sink in one streaming pass.\n * @param input - the document as text, bytes, a stream or chunks\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: GexfImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const resolved = resolveImportOptions(options, {\n ids: \"canonical\",\n defaultDirected: false,\n weightFrom: \"weight\",\n addMissingNodes: false,\n });\n const viz = resolveGexfOptions(options);\n const report = new ImportReportBuilder(GEXF_FORMAT, resolved.errorLimit);\n reportSinkOptions(sink, options, report, true);\n // nodeIdFrom is among the options reportUnusedOptions() reports: GEXF ids are mandatory\n reportUnusedOptions(options, report, USED_OPTIONS);\n const reader = new GexfReader(sink, report, resolved, viz);\n try {\n await tokenizeXml(\n textChunks(input, report, { ...resolved, declaredEncoding: xmlDeclaredEncoding }),\n reader,\n );\n } catch (err) {\n if (err instanceof XmlSyntaxError) {\n report.fail(XML_SYNTAX_CODE, err.message, { line: err.line });\n }\n throw err;\n }\n reader.finish();\n // an abort raised during the last few elements (after the last periodic check) still rejects\n throwIfAborted(resolved.signal);\n return report.finish();\n },\n});\n","/**\n * The GEXF exporter (design sections 8.5, 3.6, 3.7, 5.1, 5.10; research note 07 section 9): writes\n * GEXF 1.3 by default (1.2 on request), restoring declared attributes from `origin` (id, title,\n * type, defaults, options), the viz namespace from the position / color / size / shape /\n * thickness role columns, containment from the parent / parents columns, element lifetimes from\n * the temporal role columns (with the text companions of design section 5.1), and dynamic\n * attribute values from the temporal extension tables of design section 5.10. Expanded\n * mixed-direction pairs are folded back through the `pair` / `directed` / `mutual` roles into one\n * undirected or mutual edge; weights are written for explicit rows only (the role-weight column's\n * validity, design section 3.7). check() lists every loss before anything is written: the generic\n * capability gaps (W_OPEN_INTERVAL in 1.3, u32 / u8 dtypes, strides, nested json, graph\n * attributes, foreign extension tables) and the GEXF-specific ones (1.2 has no `kind`, no\n * timestamps and no typed lists; role columns of an unexpected shape; roles the format cannot\n * carry; attribute titles the importer would rename).\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot, INVALID_INDEX } from \"@graphty/graph-format\";\n\nimport { mapDeclaredType } from \"../../common/declared-types.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { escapeXmlAttribute, escapeXmlText } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, LOSS, sanitizeIds } from \"../../common/export.js\";\nimport { formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { isCanonicalIntegerText } from \"../../common/ids.js\";\nimport { joinListText } from \"../../common/lists.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { formatTemporal, formatTimeValue, type TimeFormat } from \"../../common/temporal.js\";\nimport { explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { xmlIllegalTextNotes } from \"../../common/xml.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport {\n canonicalScalarType,\n GEXF_FORMAT,\n GEXF_NAMESPACES,\n type GexfEdgeType,\n type GexfVersion,\n isListType,\n isScalarType,\n NODE_COLUMNS,\n OPEN_END,\n OPEN_START,\n parseTemporalTableName,\n RESERVED_EDGE_NAMES,\n RESERVED_NODE_NAMES,\n TEMPORAL_COLUMNS,\n VIZ_NAMESPACE,\n} from \"./schema.js\";\n\n/** The format-specific options of the GEXF exporter. */\nexport interface GexfExportOptions {\n /** The GEXF version to write: \"1.3\" (default) or \"1.2\". */\n version?: GexfVersion | undefined;\n}\n\n/** LossNote codes specific to the GEXF exporter, next to the shared LOSS codes. */\nexport const GEXF_LOSS = Object.freeze({\n /** GEXF 1.2 has no parallel-edge `kind`; the kind column is dropped. */\n KIND_DROPPED: \"W_GEXF_KIND_DROPPED\",\n /** GEXF 1.2 has no timestamps; a timestamp becomes a closed interval [t, t]. */\n TIMESTAMP_AS_INTERVAL: \"W_TIMESTAMP_AS_INTERVAL\",\n /** GEXF 1.2 liststring items are separated by `|`; an item containing one cannot be split back. */\n LIST_SEPARATOR: \"W_LIST_SEPARATOR\",\n /** A role column of a shape GEXF cannot map (a string `start`, a 2-component color); written as a plain attribute. */\n ROLE_SHAPE: \"W_ROLE_SHAPE\",\n /** A temporal extension table without the element / start / end / value columns of design section 5.10. */\n TEMPORAL_TABLE_SHAPE: \"W_TEMPORAL_TABLE_SHAPE\",\n /** An attribute whose title the importer would rename on re-import (a reserved name). */\n ATTRIBUTE_RENAMED: \"W_ATTRIBUTE_RENAMED\",\n /** A cell, default or option the declared type cannot express (skipped). */\n VALUE_UNWRITABLE: \"W_VALUE_UNWRITABLE\",\n /** A declared type the target version lacks (1.2: date, dateTime, typed lists...); the canonical type is written. */\n DECLARED_TYPE: \"W_DECLARED_TYPE\",\n /** A node id whose text reads back as the other type under the canonical rule (design section 4.1): a non-integer number, a string of integer text. */\n ID_TEXT_TYPE: LOSS.ID_TEXT_TYPE,\n /** A numeric edge id column: GEXF edge ids read back as strings. */\n EDGE_ID_TEXT: \"W_GEXF_EDGE_ID_TEXT\",\n /** A viz role column (position, color, size, thickness) that is not f32; the importer reads viz values as f32. */\n VIZ_DTYPE: \"W_GEXF_VIZ_DTYPE\",\n /** A plain `weight` edge column reads back as THE weight (the importer's weightFrom default). */\n WEIGHT_KEY_CLASH: LOSS.WEIGHT_KEY_CLASH,\n /** A dict column without declared options gains one from its dictionary on re-import. */\n OPTIONS_GAINED: LOSS.OPTIONS_GAINED,\n /** A string cell holding a character XML 1.0 forbids; export() throws E_COLUMN_TYPE. */\n XML_ILLEGAL_CHAR: LOSS.XML_ILLEGAL_CHAR,\n});\n\nconst DTYPES_KEPT = [\"f32\", \"f64\", \"i32\", \"bool\", \"dict\", \"string\"] as const;\n\n/** GEXF 1.3: everything the model has but nested json, strides, graph attributes and open intervals. */\nconst CAPABILITIES_1_3: ExportCapabilities = capabilities({\n mixedDirection: true,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"optional\",\n idCharset: \"any\",\n dtypes: DTYPES_KEPT,\n lists: true,\n defaults: true,\n options: true,\n hierarchy: true,\n temporal: \"dynamic-values\",\n positions: true,\n viz: true,\n});\n\n/** GEXF 1.2: no parallel edges, required edge ids, `liststring` only. */\nconst CAPABILITIES_1_2: ExportCapabilities = capabilities({\n ...CAPABILITIES_1_3,\n multiEdges: false,\n edgeIds: \"required\",\n});\n\nconst STRUCTURAL_ROLES: ReadonlySet<string> = new Set([\"directed\", \"pair\", \"mutual\", \"weight\", \"timeText\"]);\n\n/** The attribute title the importer reads THE weight from by default (its weightFrom default). */\nconst DEFAULT_WEIGHT_TITLE = \"weight\";\nconst NUMERIC_DTYPES: ReadonlySet<string> = new Set([\"f32\", \"f64\", \"i32\", \"u32\", \"u8\"]);\nconst TEXT_DTYPES: ReadonlySet<string> = new Set([\"string\", \"dict\"]);\n\n/** Formats one cell value as GEXF text; null when the value cannot be expressed. */\ntype ValueFormatter = (value: unknown) => string | null;\n\n/** The GEXF type of a column and how its values are written. */\ninterface TypedAttribute {\n /** The type text written in the declaration. */\n readonly type: string;\n /** Whether it is a list type. */\n readonly list: boolean;\n /** The item type of a list, the type itself otherwise. */\n readonly itemType: string;\n /** The value formatter. */\n readonly format: ValueFormatter;\n /** A declared type the target version cannot express (written as `type` instead), or null. */\n readonly dropped: string | null;\n}\n\n/** A temporal extension table resolved to its columns (design section 5.10). */\ninterface TemporalTable {\n readonly element: Column;\n readonly start: Column;\n readonly end: Column;\n readonly value: Column;\n readonly startText: Column | null;\n readonly endText: Column | null;\n readonly valueText: Column | null;\n readonly open: Column | null;\n /** Row indices per element index. */\n readonly rows: ReadonlyMap<number, readonly number[]>;\n readonly format: ValueFormatter;\n}\n\n/** One `<attribute>` declaration and how its values are written. */\ninterface AttributeSpec {\n readonly id: string;\n readonly title: string;\n readonly type: string;\n readonly column: Column | null;\n /** The text companion of a temporal-typed column, used only when the written type is temporal. */\n readonly companion: Column | null;\n readonly format: ValueFormatter;\n readonly defaultText: string | null;\n readonly optionsText: string | null;\n readonly dynamic: boolean;\n readonly table: TemporalTable | null;\n}\n\n/** The role columns of one domain, each null when absent or of an unusable shape. */\ninterface RoleColumns {\n label: Column | null;\n id: Column | null;\n kind: Column | null;\n start: Column | null;\n end: Column | null;\n timestamp: Column | null;\n spells: Column | null;\n spellsOpen: Column | null;\n timestamps: Column | null;\n open: Column | null;\n position: Column | null;\n color: Column | null;\n size: Column | null;\n shape: Column | null;\n shapeUri: Column | null;\n thickness: Column | null;\n parent: Column | null;\n parents: Column | null;\n /** Text companions keyed by the column they accompany. */\n readonly companions: ReadonlyMap<string, Column>;\n}\n\n/** Everything check() decides and export() writes from. */\ninterface ExportPlan {\n readonly version: GexfVersion;\n readonly options: ResolvedExportOptions;\n readonly notes: LossNote[];\n readonly nodeRoles: RoleColumns;\n readonly edgeRoles: RoleColumns;\n readonly nodeAttrs: readonly AttributeSpec[];\n readonly edgeAttrs: readonly AttributeSpec[];\n readonly timeFormat: TimeFormat | null;\n readonly temporal: boolean;\n readonly timeRepresentation: \"interval\" | \"timestamp\" | null;\n}\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the version to write\n */\nfunction resolveVersion(options: (GexfExportOptions & CommonExportOptions) | undefined): GexfVersion {\n const version = options?.version;\n if (version === undefined) {\n return \"1.3\";\n }\n if (version !== \"1.2\" && version !== \"1.3\") {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option version: ${JSON.stringify(version)} is not \"1.2\" or \"1.3\"`,\n {\n option: \"version\",\n found: version,\n supported: [\"1.2\", \"1.3\"],\n },\n );\n }\n return version;\n}\n\n/**\n * Decide everything about an export: the capability notes, the role columns of each domain, the\n * attribute declarations and their formatters, the temporal tables and the graph header values.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction planExport(\n snapshot: GraphSnapshot,\n options: (GexfExportOptions & CommonExportOptions) | undefined,\n): ExportPlan {\n const version = resolveVersion(options);\n const resolved = resolveExportOptions(options);\n const caps = version === \"1.2\" ? CAPABILITIES_1_2 : CAPABILITIES_1_3;\n const notes = [\n ...checkCapabilities(snapshot, caps, resolved, {\n openIntervals: version === \"1.2\",\n temporalText: true,\n positionDtype: \"f32\",\n roles: MAPPED_ROLES,\n roleNames: ROLE_NAMES,\n }),\n ];\n const note = (code: string, message: string, column: string | null = null, count: number | null = null): void => {\n notes.push(Object.freeze({ code, message, column, count }));\n };\n notes.push(...xmlIllegalTextNotes(snapshot));\n let typeChanges = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id = snapshot.ids.idOf(i);\n if (typeof id === \"number\" ? !Number.isSafeInteger(id) : isCanonicalIntegerText(id)) {\n typeChanges++;\n }\n }\n if (typeChanges > 0) {\n note(\n GEXF_LOSS.ID_TEXT_TYPE,\n `${typeChanges} node id(s) change type when read back under ids: \"canonical\" (string ids that are integer text, non-integer numbers); the file's idtype is not honoured by the importer`,\n null,\n typeChanges,\n );\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n if (edgeIds !== null && edgeIds.dtype !== \"string\" && edgeIds.dtype !== \"dict\") {\n note(\n GEXF_LOSS.EDGE_ID_TEXT,\n `edge id column \"${edgeIds.meta.name}\" is ${edgeIds.dtype}; GEXF edge ids read back as strings`,\n edgeIds.meta.name,\n snapshot.edgeCount - edgeIds.nullCount,\n );\n }\n const tables = collectTemporalTables(snapshot, version, note);\n const nodeRoles = collectRoles(snapshot.nodes, \"node\", note);\n const edgeRoles = collectRoles(snapshot.edges, \"edge\", note);\n const nodeAttrs = collectAttributes(snapshot, \"node\", nodeRoles, tables.get(\"node\") ?? new Map(), version, note);\n const edgeAttrs = collectAttributes(snapshot, \"edge\", edgeRoles, tables.get(\"edge\") ?? new Map(), version, note);\n const temporal =\n hasLifetime(nodeRoles) ||\n hasLifetime(edgeRoles) ||\n nodeAttrs.some((a) => a.dynamic) ||\n edgeAttrs.some((a) => a.dynamic);\n if (version === \"1.2\") {\n for (const [domain, roles] of [\n [\"node\", nodeRoles],\n [\"edge\", edgeRoles],\n ] as const) {\n if (roles.timestamp !== null || roles.timestamps !== null) {\n note(\n GEXF_LOSS.TIMESTAMP_AS_INTERVAL,\n `${domain} timestamps are written as closed intervals; GEXF 1.2 has no timestamp representation`,\n (roles.timestamp ?? roles.timestamps)?.meta.name ?? null,\n null,\n );\n }\n }\n if (graphExtraText(snapshot, \"timestamp\") !== null) {\n note(\n GEXF_LOSS.TIMESTAMP_AS_INTERVAL,\n \"the graph timestamp is written as a closed interval (start = end); GEXF 1.2 has no timestamp representation\",\n null,\n null,\n );\n }\n if (edgeRoles.kind !== null) {\n note(\n GEXF_LOSS.KIND_DROPPED,\n `edge column \"${edgeRoles.kind.meta.name}\" (kind) cannot be written; GEXF 1.2 has no edge kind`,\n edgeRoles.kind.meta.name,\n edgeRoles.kind.length - edgeRoles.kind.nullCount,\n );\n }\n }\n const { meta } = snapshot;\n let { timeRepresentation } = meta;\n if (timeRepresentation === null && temporal) {\n const timestampOnly =\n (nodeRoles.timestamp !== null || edgeRoles.timestamp !== null) &&\n nodeRoles.start === null &&\n nodeRoles.end === null &&\n edgeRoles.start === null &&\n edgeRoles.end === null;\n timeRepresentation = timestampOnly ? \"timestamp\" : null;\n }\n return {\n version,\n options: resolved,\n notes,\n nodeRoles,\n edgeRoles,\n nodeAttrs,\n edgeAttrs,\n timeFormat: meta.timeFormat,\n temporal,\n timeRepresentation,\n };\n}\n\n/**\n * Whether a domain carries element lifetimes.\n * @param roles - the domain's role columns\n * @returns true when any temporal role column exists\n */\nfunction hasLifetime(roles: RoleColumns): boolean {\n return (\n roles.start !== null ||\n roles.end !== null ||\n roles.timestamp !== null ||\n roles.spells !== null ||\n roles.timestamps !== null\n );\n}\n\n/**\n * Whether a column is a scalar numeric column.\n * @param column - the column\n * @returns true for f32 / f64 / i32 / u32 / u8 with one component\n */\nfunction isNumericScalar(column: Column): boolean {\n return NUMERIC_DTYPES.has(column.dtype) && column.meta.components === 1;\n}\n\n/**\n * Whether a column is a numeric column with a given stride.\n * @param column - the column\n * @param components - the accepted strides\n * @returns true when numeric with one of the strides\n */\nfunction isNumericVector(column: Column, components: readonly number[]): boolean {\n return NUMERIC_DTYPES.has(column.dtype) && components.includes(column.meta.components);\n}\n\n/**\n * Whether a column holds text (string or dict).\n * @param column - the column\n * @returns true for string / dict\n */\nfunction isText(column: Column): boolean {\n return TEXT_DTYPES.has(column.dtype);\n}\n\n/**\n * Whether a column is a list of numbers with a given item stride.\n * @param column - the column\n * @param itemComponents - the required item stride\n * @returns true for a numeric list of that stride\n */\nfunction isNumericList(column: Column, itemComponents: number): boolean {\n return (\n column.dtype === \"list\" &&\n column.meta.itemDtype !== null &&\n NUMERIC_DTYPES.has(column.meta.itemDtype) &&\n (column.meta.itemComponents ?? 1) === itemComponents\n );\n}\n\n/**\n * Whether a role column has the shape its GEXF field needs.\n * @param role - the role\n * @param column - the column\n * @param domain - node or edge\n * @returns true when writable\n */\nfunction roleShapeOk(role: string, column: Column, domain: \"node\" | \"edge\"): boolean {\n switch (role) {\n case \"label\":\n case \"shape\":\n return isText(column);\n case \"kind\":\n return domain === \"edge\" && isText(column);\n case \"id\":\n return domain === \"edge\" && (isText(column) || isNumericScalar(column));\n case \"start\":\n case \"end\":\n case \"timestamp\":\n case \"open\":\n return isNumericScalar(column);\n case \"size\":\n return domain === \"node\" && isNumericScalar(column);\n case \"thickness\":\n return domain === \"edge\" && isNumericScalar(column);\n case \"spells\":\n return isNumericList(column, 2);\n case \"spellsOpen\":\n return column.dtype === \"list\" && column.meta.itemDtype === \"u8\";\n case \"timestamps\":\n return isNumericList(column, 1);\n case \"position\":\n return domain === \"node\" && isNumericVector(column, [2, 3]);\n case \"color\":\n return isNumericVector(column, [3, 4]);\n case \"parent\":\n return domain === \"node\" && column.dtype === \"u32\" && column.meta.components === 1;\n case \"parents\":\n return domain === \"node\" && column.dtype === \"list\" && column.meta.itemDtype === \"u32\";\n default:\n return false;\n }\n}\n\nconst VIZ_NUMERIC_ROLES: ReadonlySet<string> = new Set([\"position\", \"color\", \"size\", \"thickness\"]);\n\nconst MAPPED_ROLES: ReadonlySet<string> = new Set([\n \"label\",\n \"id\",\n \"kind\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"spells\",\n \"spellsOpen\",\n \"timestamps\",\n \"open\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"parent\",\n \"parents\",\n]);\n\n/** The column name the importer gives each mapped role on re-import (design section 5.6 fixed names). */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: NODE_COLUMNS.label,\n id: \"id\",\n kind: \"kind\",\n start: NODE_COLUMNS.start,\n end: NODE_COLUMNS.end,\n timestamp: NODE_COLUMNS.timestamp,\n spells: NODE_COLUMNS.spells,\n spellsOpen: NODE_COLUMNS.spellsOpen,\n timestamps: NODE_COLUMNS.timestamps,\n open: NODE_COLUMNS.open,\n position: NODE_COLUMNS.position,\n color: NODE_COLUMNS.color,\n size: NODE_COLUMNS.size,\n shape: NODE_COLUMNS.shape,\n thickness: \"thickness\",\n parent: NODE_COLUMNS.parent,\n parents: NODE_COLUMNS.parents,\n});\n\n/**\n * Find the role columns of a table; a role column of the wrong shape is noted and left to the\n * attribute pass.\n * @param table - the node or edge table\n * @param domain - node or edge\n * @param note - the note recorder\n * @returns the role columns\n */\nfunction collectRoles(\n table: Iterable<Column>,\n domain: \"node\" | \"edge\",\n note: (code: string, message: string, column?: string | null, count?: number | null) => void,\n): RoleColumns {\n const companions = new Map<string, Column>();\n const roles: RoleColumns = {\n label: null,\n id: null,\n kind: null,\n start: null,\n end: null,\n timestamp: null,\n spells: null,\n spellsOpen: null,\n timestamps: null,\n open: null,\n position: null,\n color: null,\n size: null,\n shape: null,\n shapeUri: null,\n thickness: null,\n parent: null,\n parents: null,\n companions,\n };\n for (const column of table) {\n const { meta } = column;\n const forName = meta.extra.for;\n if ((meta.role === \"timeText\" || typeof forName === \"string\") && column.dtype === \"string\") {\n if (typeof forName === \"string\") {\n companions.set(forName, column);\n }\n continue;\n }\n if (domain === \"node\" && meta.name === NODE_COLUMNS.shapeUri && meta.origin?.namespace === VIZ_NAMESPACE) {\n roles.shapeUri = column.dtype === \"string\" ? column : null;\n continue;\n }\n const { role } = meta;\n if (role === null || !MAPPED_ROLES.has(role)) {\n continue;\n }\n if (!roleShapeOk(role, column, domain)) {\n note(\n GEXF_LOSS.ROLE_SHAPE,\n `${domain} column \"${meta.name}\" (${role}) has a shape GEXF cannot map (${describeShape(column)}); written as a plain attribute`,\n meta.name,\n null,\n );\n // the generic check skips role columns; report what the attribute path loses\n const set = column.length - column.nullCount;\n if (NUMERIC_DTYPES.has(column.dtype) && meta.components > 1) {\n note(\n LOSS.COMPONENTS,\n `${domain} column \"${meta.name}\" has ${meta.components} components; written as a list`,\n meta.name,\n set,\n );\n }\n if (column.dtype === \"json\") {\n note(\n LOSS.JSON,\n `${domain} column \"${meta.name}\" holds nested values; written as JSON text`,\n meta.name,\n set,\n );\n }\n if (column.dtype === \"u32\" || column.dtype === \"u8\") {\n note(\n LOSS.DTYPE,\n `${domain} column \"${meta.name}\" is ${column.dtype}; the format cannot keep that dtype`,\n meta.name,\n set,\n );\n }\n continue;\n }\n if (VIZ_NUMERIC_ROLES.has(role) && column.dtype !== \"f32\") {\n note(\n GEXF_LOSS.VIZ_DTYPE,\n `${domain} column \"${meta.name}\" (${role}) is ${column.dtype}; viz values read back as f32`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n roles[role as keyof Omit<RoleColumns, \"companions\">] = column;\n }\n return roles;\n}\n\n/**\n * A short description of a column's shape for messages.\n * @param column - the column\n * @returns \"dtype x components\" or \"list of item\"\n */\nfunction describeShape(column: Column): string {\n if (column.dtype === \"list\") {\n return `list of ${column.meta.itemDtype ?? \"?\"} x ${column.meta.itemComponents ?? 1}`;\n }\n return `${column.dtype} x ${column.meta.components}`;\n}\n\n/**\n * Resolve every temporal extension table (design section 5.10) into its columns, grouped by\n * domain and keyed by the static column's name; a table without the required columns is noted.\n * @param snapshot - the snapshot\n * @param version - the target version\n * @param note - the note recorder\n * @returns tables by domain, then by column name\n */\nfunction collectTemporalTables(\n snapshot: GraphSnapshot,\n version: GexfVersion,\n note: (code: string, message: string, column?: string | null, count?: number | null) => void,\n): Map<\"node\" | \"edge\", Map<string, TemporalTable>> {\n const out = new Map<\"node\" | \"edge\", Map<string, TemporalTable>>();\n for (const [name, table] of snapshot.extensions) {\n const parsed = parseTemporalTableName(name);\n if (parsed === null) {\n continue;\n }\n const element = table.get(TEMPORAL_COLUMNS.element);\n const start = table.get(TEMPORAL_COLUMNS.start);\n const end = table.get(TEMPORAL_COLUMNS.end);\n const value = table.get(TEMPORAL_COLUMNS.value);\n if (\n element === null ||\n element.dtype !== \"u32\" ||\n start === null ||\n !isNumericScalar(start) ||\n end === null ||\n !isNumericScalar(end) ||\n value === null\n ) {\n note(\n GEXF_LOSS.TEMPORAL_TABLE_SHAPE,\n `extension table \"${name}\" lacks the element / start / end / value columns and cannot be written`,\n name,\n table.rowCount,\n );\n continue;\n }\n const rows = new Map<number, number[]>();\n for (let r = 0; r < table.rowCount; r++) {\n if (!element.isSet(r)) {\n continue;\n }\n const e = element.value(r) as number;\n const list = rows.get(e);\n if (list === undefined) {\n rows.set(e, [r]);\n } else {\n list.push(r);\n }\n }\n const typed = attributeType(value, version);\n const open = optionalNumeric(table.get(TEMPORAL_COLUMNS.open));\n if (version === \"1.3\" && open !== null && open.length - open.nullCount > 0) {\n note(\n LOSS.OPEN_INTERVAL,\n `dynamic values of \"${name}\" carry open intervals, which GEXF 1.3 cannot write`,\n name,\n open.length - open.nullCount,\n );\n }\n const resolved: TemporalTable = {\n element,\n start,\n end,\n value,\n startText: optionalText(table.get(TEMPORAL_COLUMNS.startText)),\n endText: optionalText(table.get(TEMPORAL_COLUMNS.endText)),\n valueText: isTemporalType(typed.type) ? optionalText(table.get(TEMPORAL_COLUMNS.valueText)) : null,\n open,\n rows,\n format: typed.format,\n };\n let byDomain = out.get(parsed.domain);\n if (byDomain === undefined) {\n byDomain = new Map();\n out.set(parsed.domain, byDomain);\n }\n byDomain.set(parsed.column, resolved);\n }\n return out;\n}\n\n/**\n * A string column, or null.\n * @param column - the column or null\n * @returns the column when it is a string column\n */\nfunction optionalText(column: Column | null): Column | null {\n return column !== null && column.dtype === \"string\" ? column : null;\n}\n\n/**\n * A numeric scalar column, or null.\n * @param column - the column or null\n * @returns the column when numeric\n */\nfunction optionalNumeric(column: Column | null): Column | null {\n return column !== null && isNumericScalar(column) ? column : null;\n}\n\n/**\n * The GEXF type of a column and the formatter of its values: the declared `origin.type` when the\n * version knows it and it agrees with the dtype, the canonical type of the dtype otherwise; lists\n * become `list<item>` (1.3) or `liststring` (1.2); a stride column becomes a list of its lanes;\n * json becomes a string of JSON text.\n * @param column - the column\n * @param version - the target version\n * @returns the type text, whether it is a list, and the formatter\n */\nfunction attributeType(column: Column, version: GexfVersion): TypedAttribute {\n const { meta } = column;\n const originType = meta.origin?.type ?? null;\n if (meta.dtype === \"list\" || (NUMERIC_DTYPES.has(meta.dtype) && meta.components > 1)) {\n const itemDtype = meta.dtype === \"list\" ? (meta.itemDtype ?? \"string\") : meta.dtype;\n let itemType = canonicalScalarType(itemDtype);\n if (\n originType !== null &&\n meta.dtype === \"list\" &&\n isListType(originType, \"1.3\") &&\n agrees(originType, \"list\", itemDtype)\n ) {\n itemType = originType.slice(4);\n }\n if (version === \"1.2\") {\n const itemFormat = scalarFormatter(itemType, itemDtype);\n return {\n type: \"liststring\",\n list: true,\n itemType: \"string\",\n format: listFormatter(itemFormat, version),\n dropped: itemType === \"string\" ? null : `list${itemType}`,\n };\n }\n return {\n type: `list${itemType}`,\n list: true,\n itemType,\n format: listFormatter(scalarFormatter(itemType, itemDtype), version),\n dropped: null,\n };\n }\n let type = canonicalScalarType(meta.dtype);\n let dropped: string | null = null;\n const temporal = originType === null || meta.dtype !== \"f64\" ? null : gexfTemporalType(originType);\n if (temporal !== null) {\n // a date / dateTime column of any format (Neo4j spells them date / datetime /\n // localdatetime) keeps its temporal type, so the text companion is written back\n if (isScalarType(temporal, version)) {\n type = temporal;\n } else {\n dropped = temporal;\n }\n } else if (originType !== null && agrees(originType, meta.dtype, null)) {\n if (isScalarType(originType, version)) {\n type = originType;\n } else if (isScalarType(originType, \"1.3\")) {\n dropped = originType;\n }\n }\n return { type, list: false, itemType: type, format: scalarFormatter(type, meta.dtype), dropped };\n}\n\n/**\n * The GEXF temporal type a declared origin type of any format maps to: `date` for a date,\n * `dateTime` for a date-time with or without zone (GEXF's own spellings, Neo4j's `date` /\n * `datetime` / `localdatetime`), null for a non-temporal type or a time of day (GEXF has none).\n * @param originType - the declared type text\n * @returns \"date\", \"dateTime\" or null\n */\nfunction gexfTemporalType(originType: string): \"date\" | \"dateTime\" | null {\n switch (originType.toLowerCase()) {\n case \"date\":\n return \"date\";\n case \"datetime\":\n case \"localdatetime\":\n return \"dateTime\";\n default:\n return null;\n }\n}\n\n/**\n * Whether a declared GEXF type maps back to a dtype (so the exporter may restore it verbatim).\n * @param type - the declared type text\n * @param dtype - the column dtype\n * @param itemDtype - the item dtype of a list column, or null\n * @returns true when mapDeclaredType agrees\n */\nfunction agrees(type: string, dtype: string, itemDtype: string | null): boolean {\n const spec = mapDeclaredType(\"gexf\", type, \"f64\");\n if (spec === null) {\n return false;\n }\n if (dtype === \"list\") {\n return spec.list && spec.itemDtype === itemDtype;\n }\n if (spec.list) {\n return false;\n }\n // a dict column is a string column with options\n return spec.dtype === dtype || (dtype === \"dict\" && spec.dtype === \"string\");\n}\n\n/**\n * The formatter of one scalar value under a GEXF type.\n * @param type - the GEXF scalar type text\n * @param dtype - the column (or item) dtype the values come from\n * @returns the formatter\n */\nfunction scalarFormatter(type: string, dtype: string): ValueFormatter {\n switch (type) {\n case \"boolean\":\n return (value): string | null => {\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (typeof value !== \"number\") {\n return null;\n }\n return value !== 0 ? \"true\" : \"false\";\n };\n case \"integer\":\n case \"long\":\n case \"byte\":\n case \"short\":\n case \"biginteger\":\n return (value): string | null => {\n if (typeof value === \"number\") {\n return Number.isInteger(value) ? formatInteger(value) : formatF64(value);\n }\n return typeof value === \"string\" ? value : null;\n };\n case \"float\":\n return (value): string | null => (typeof value === \"number\" ? formatF32(value) : null);\n case \"double\":\n case \"bigdecimal\":\n return (value): string | null => {\n if (typeof value === \"number\") {\n return dtype === \"f32\" ? formatF32(value) : formatF64(value);\n }\n return typeof value === \"string\" ? value : null;\n };\n case \"date\":\n case \"dateTime\":\n return (value): string | null => {\n if (typeof value === \"number\") {\n return formatTemporal(value, type);\n }\n return typeof value === \"string\" ? value : null;\n };\n default:\n return (value): string | null => {\n switch (typeof value) {\n case \"string\":\n return value;\n case \"number\":\n return dtype === \"f32\" ? formatF32(value) : formatF64(value);\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"object\":\n return value === null ? null : JSON.stringify(value);\n default:\n return null;\n }\n };\n }\n}\n\n/**\n * The formatter of a list value: items through the item formatter, joined per version.\n * @param item - the item formatter\n * @param version - the target version (1.3 brackets, 1.2 pipes)\n * @returns the formatter; null when any item cannot be written\n */\nfunction listFormatter(item: ValueFormatter, version: GexfVersion): ValueFormatter {\n return (value): string | null => {\n if (!Array.isArray(value) && !ArrayBuffer.isView(value)) {\n return null;\n }\n const items: string[] = [];\n for (const entry of Array.from(value as ArrayLike<unknown>)) {\n const text = item(entry);\n if (text === null) {\n return null;\n }\n items.push(text);\n }\n return joinListText(items, version === \"1.2\" ? \"pipe\" : \"gexf\");\n };\n}\n\n/**\n * Decide the `<attribute>` declarations of a domain: every column that is neither structural, a\n * companion nor a mapped role column, in declaration order, plus the temporal tables without a\n * static column (the dynamic weight) as dynamic attributes.\n * @param snapshot - the snapshot\n * @param domain - node or edge\n * @param roles - the domain's role columns\n * @param tables - the domain's temporal tables by column name\n * @param version - the target version\n * @param note - the note recorder\n * @returns the declarations\n */\nfunction collectAttributes(\n snapshot: GraphSnapshot,\n domain: \"node\" | \"edge\",\n roles: RoleColumns,\n tables: ReadonlyMap<string, TemporalTable>,\n version: GexfVersion,\n note: (code: string, message: string, column?: string | null, count?: number | null) => void,\n): AttributeSpec[] {\n const table = domain === \"node\" ? snapshot.nodes : snapshot.edges;\n const reserved = domain === \"node\" ? RESERVED_NODE_NAMES : RESERVED_EDGE_NAMES;\n const roleColumns = new Set<Column>();\n for (const value of Object.values(roles)) {\n if (value !== null && !(value instanceof Map)) {\n roleColumns.add(value);\n }\n }\n const usedIds = new Set<string>();\n const specs: AttributeSpec[] = [];\n const usedTables = new Set<string>();\n const declare = (\n column: Column | null,\n name: string,\n origin: { id: string | null; title: string | null },\n typed: TypedAttribute,\n dynamic: boolean,\n temporal: TemporalTable | null,\n ): void => {\n const id = uniqueId(origin.id ?? name, name, usedIds);\n const title = origin.title ?? name;\n if (typed.dropped !== null) {\n note(\n GEXF_LOSS.DECLARED_TYPE,\n `${domain} column \"${name}\" is declared ${typed.dropped}, which GEXF ${version} lacks; written as ${typed.type}`,\n name,\n null,\n );\n }\n if (domain === \"edge\" && column !== null && column.meta.role === null && title === DEFAULT_WEIGHT_TITLE) {\n note(\n GEXF_LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${name}\" is written as an attribute titled \"${title}\", which the importer reads as THE weight (weightFrom); it reads back as the weight, not as a column`,\n name,\n column.length - column.nullCount,\n );\n }\n const reimportName = reserved.has(title) ? `${title}#${id}` : title;\n if (reimportName !== name) {\n note(\n GEXF_LOSS.ATTRIBUTE_RENAMED,\n `${domain} column \"${name}\" is written with title \"${title}\" and reads back as \"${reimportName}\"`,\n name,\n null,\n );\n }\n const { defaultText, optionsText } =\n column === null\n ? { defaultText: null, optionsText: null }\n : declaredTexts(column, domain, typed, version, note);\n const companion = column === null ? null : (roles.companions.get(name) ?? null);\n if (companion !== null && !isTemporalType(typed.type)) {\n note(\n LOSS.TEMPORAL_TEXT,\n `${domain} column \"${companion.meta.name}\" (the lexical form of \"${name}\") cannot be written: \"${name}\" is written as ${typed.type}, not a GEXF temporal type`,\n companion.meta.name,\n companion.length - companion.nullCount,\n );\n }\n specs.push({\n id,\n title,\n type: typed.type,\n column,\n companion: isTemporalType(typed.type) ? companion : null,\n format: typed.format,\n defaultText,\n optionsText,\n dynamic,\n table: temporal,\n });\n };\n for (const column of table) {\n const { meta } = column;\n if (roleColumns.has(column) || (meta.role !== null && STRUCTURAL_ROLES.has(meta.role))) {\n continue;\n }\n if (typeof meta.extra.for === \"string\" && column.dtype === \"string\") {\n continue;\n }\n if (domain === \"node\" && column === roles.shapeUri) {\n continue;\n }\n const temporal = tables.get(meta.name) ?? null;\n if (temporal !== null) {\n usedTables.add(meta.name);\n }\n declare(\n column,\n meta.name,\n { id: meta.origin?.id ?? null, title: meta.origin?.title ?? null },\n attributeType(column, version),\n meta.dynamic || temporal !== null,\n temporal,\n );\n }\n for (const [name, temporal] of tables) {\n if (usedTables.has(name)) {\n continue;\n }\n const { origin } = temporal.value.meta;\n const { weightOrigin } = snapshot.meta;\n const weightId =\n domain === \"edge\" && weightOrigin !== null && (weightOrigin.title ?? weightOrigin.id) === name\n ? weightOrigin.id\n : null;\n declare(\n null,\n name,\n { id: origin?.id ?? weightId, title: null },\n attributeType(temporal.value, version),\n true,\n temporal,\n );\n }\n return specs;\n}\n\n/**\n * The `<default>` and `<options>` texts of a declared attribute, with the notes about what cannot\n * be written as the declared type, about a dictionary written as options, and about 1.2 list items\n * holding the `|` separator.\n * @param column - the column\n * @param domain - node or edge\n * @param typed - the attribute's GEXF type and formatter\n * @param version - the target version\n * @param note - the note recorder\n * @returns the default and options texts (null when absent or unwritable)\n */\nfunction declaredTexts(\n column: Column,\n domain: \"node\" | \"edge\",\n typed: TypedAttribute,\n version: GexfVersion,\n note: (code: string, message: string, column?: string | null, count?: number | null) => void,\n): { defaultText: string | null; optionsText: string | null } {\n const { meta } = column;\n const { name } = meta;\n let defaultText: string | null = null;\n let optionsText: string | null = null;\n if (meta.default !== undefined) {\n defaultText = typed.format(meta.default);\n if (defaultText === null) {\n note(\n GEXF_LOSS.VALUE_UNWRITABLE,\n `${domain} column \"${name}\": the default cannot be written as ${typed.type}`,\n name,\n null,\n );\n }\n }\n const options = meta.options ?? (column.dtype === \"dict\" ? column.dictionary : null);\n if (meta.options === null && options !== null && options.length > 0) {\n note(\n GEXF_LOSS.OPTIONS_GAINED,\n `${domain} column \"${name}\" declares no options; its dictionary is written as <options> and reads back as declared options`,\n name,\n null,\n );\n }\n if (options !== null) {\n const itemFormat = typed.list ? scalarFormatter(typed.itemType, meta.itemDtype ?? \"string\") : typed.format;\n const texts: string[] = [];\n let ok = true;\n for (const option of options) {\n const text = itemFormat(option);\n if (text === null) {\n ok = false;\n break;\n }\n texts.push(text);\n }\n if (ok) {\n optionsText = joinListText(texts, version === \"1.2\" ? \"pipe\" : \"gexf\");\n } else {\n note(\n GEXF_LOSS.VALUE_UNWRITABLE,\n `${domain} column \"${name}\": the options cannot be written as ${typed.type}`,\n name,\n null,\n );\n }\n }\n if (version === \"1.2\" && column.dtype === \"list\") {\n let count = 0;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && listItems(column, r).some((item) => String(item).includes(\"|\"))) {\n count++;\n }\n }\n if (count > 0) {\n note(\n GEXF_LOSS.LIST_SEPARATOR,\n `${domain} column \"${name}\": ${count} row(s) hold an item containing \"|\", the 1.2 list separator`,\n name,\n count,\n );\n }\n }\n return { defaultText, optionsText };\n}\n\n/**\n * Whether a GEXF type is a temporal one whose values have text companions.\n * @param type - the type text\n * @returns true for date / dateTime\n */\nfunction isTemporalType(type: string): boolean {\n return type === \"date\" || type === \"dateTime\";\n}\n\n/**\n * A unique attribute id within a class.\n * @param preferred - the id to try first (the origin id or the name)\n * @param name - the column name, tried second\n * @param used - ids already taken\n * @returns a free id, recorded as used\n */\nfunction uniqueId(preferred: string, name: string, used: Set<string>): string {\n const candidates = [preferred, name];\n for (const candidate of candidates) {\n if (candidate.length > 0 && !used.has(candidate)) {\n used.add(candidate);\n return candidate;\n }\n }\n for (let n = 2; ; n++) {\n const candidate = `${name}#${n}`;\n if (!used.has(candidate)) {\n used.add(candidate);\n return candidate;\n }\n }\n}\n\n// ============================================================ writing\n\n/**\n * The text of a time bound: the companion text when present, the formatted number otherwise.\n * @param column - the numeric column\n * @param companion - its text companion, or null\n * @param row - the row\n * @param timeFormat - the graph's timeformat\n * @returns the text\n */\nfunction timeText(column: Column, companion: Column | null, row: number, timeFormat: TimeFormat | null): string {\n if (companion !== null && companion.isSet(row)) {\n return companion.value(row) as string;\n }\n return formatTimeValue(column.value(row) as number, timeFormat);\n}\n\n/**\n * The `start` / `end` / `timestamp` / open attributes of one element.\n * @param roles - the domain's role columns\n * @param row - the element's row\n * @param plan - the plan\n * @returns the attribute text, starting with a space when non-empty\n */\nfunction lifetimeAttrs(roles: RoleColumns, row: number, plan: ExportPlan): string {\n let out = \"\";\n const { timeFormat, version } = plan;\n let bits = 0;\n if (version === \"1.2\" && roles.open !== null && roles.open.isSet(row)) {\n bits = roles.open.value(row) as number;\n }\n const write = (name: string, column: Column | null, open: boolean): void => {\n if (column === null || !column.isSet(row)) {\n return;\n }\n const value = column.value(row) as number;\n if (!Number.isFinite(value)) {\n return;\n }\n const text = timeText(column, roles.companions.get(column.meta.name) ?? null, row, timeFormat);\n // GEXF 1.2: `startopen` / `endopen` hold the time of a non-inclusive bound (dynamics.xsd\n // time-type) and replace `start` / `end`\n out += ` ${open ? `${name}open` : name}=\"${escapeXmlAttribute(text)}\"`;\n };\n if (roles.timestamp !== null && roles.timestamp.isSet(row)) {\n if (version === \"1.3\" && plan.timeRepresentation === \"timestamp\") {\n write(\"timestamp\", roles.timestamp, false);\n } else {\n write(\"start\", roles.timestamp, false);\n write(\"end\", roles.timestamp, false);\n }\n } else {\n write(\"start\", roles.start, (bits & OPEN_START) !== 0);\n write(\"end\", roles.end, (bits & OPEN_END) !== 0);\n }\n if (version === \"1.3\" && roles.timestamps !== null && roles.timestamps.isSet(row)) {\n const items = listItems(roles.timestamps, row).map((t) => formatTimeValue(t as number, timeFormat));\n out += ` timestamps=\"${escapeXmlAttribute(`<[${items.join(\", \")}]>`)}\"`;\n }\n return out;\n}\n\n/**\n * The `<spells>` element of one element: its spells column, plus (1.2) its timestamps as [t, t].\n * In 1.2 a spell whose spells.open bits mark a bound open writes that bound as `startopen` /\n * `endopen`; 1.3 has no open bounds, and check() reports the loss.\n * @param roles - the domain's role columns\n * @param row - the element's row\n * @param plan - the plan\n * @param indent - the indentation of the element\n * @returns the lines, or an empty string\n */\nfunction spellsElement(roles: RoleColumns, row: number, plan: ExportPlan, indent: string): string {\n const pairs: (readonly [number, number, number])[] = [];\n if (roles.spells !== null && roles.spells.isSet(row)) {\n const open =\n plan.version === \"1.2\" && roles.spellsOpen !== null && roles.spellsOpen.isSet(row)\n ? listItems(roles.spellsOpen, row)\n : [];\n listItems(roles.spells, row).forEach((pair, i) => {\n const [s, e] = Array.from(pair as ArrayLike<number>);\n pairs.push([s, e, (open[i] as number | undefined) ?? 0]);\n });\n }\n if (plan.version === \"1.2\" && roles.timestamps !== null && roles.timestamps.isSet(row)) {\n for (const t of listItems(roles.timestamps, row)) {\n pairs.push([t as number, t as number, 0]);\n }\n }\n if (pairs.length === 0) {\n return \"\";\n }\n let out = `${indent}<spells>\\n`;\n for (const [s, e, open] of pairs) {\n let attrs = \"\";\n if (Number.isFinite(s)) {\n const name = (open & OPEN_START) === 0 ? \"start\" : \"startopen\";\n attrs += ` ${name}=\"${escapeXmlAttribute(formatTimeValue(s, plan.timeFormat))}\"`;\n }\n if (Number.isFinite(e)) {\n const name = (open & OPEN_END) === 0 ? \"end\" : \"endopen\";\n attrs += ` ${name}=\"${escapeXmlAttribute(formatTimeValue(e, plan.timeFormat))}\"`;\n }\n out += `${indent} <spell${attrs}/>\\n`;\n }\n return `${out}${indent}</spells>\\n`;\n}\n\n/**\n * The `<attvalues>` element of one node or edge: static cells and dynamic rows.\n * @param attrs - the domain's declarations\n * @param row - the element's row\n * @param plan - the plan\n * @param indent - the indentation of the element\n * @returns the lines, or an empty string\n */\nfunction attvaluesElement(attrs: readonly AttributeSpec[], row: number, plan: ExportPlan, indent: string): string {\n let out = \"\";\n for (const spec of attrs) {\n const { column } = spec;\n if (column !== null && column.isSet(row)) {\n let text: string | null;\n if (spec.companion !== null && spec.companion.isSet(row)) {\n text = spec.companion.value(row) as string;\n } else {\n text = spec.format(cellValue(column, row));\n }\n if (text !== null) {\n out += `${indent} <attvalue for=\"${escapeXmlAttribute(spec.id)}\" value=\"${escapeXmlAttribute(text)}\"/>\\n`;\n }\n }\n const { table } = spec;\n if (table === null) {\n continue;\n }\n const rows = table.rows.get(row);\n if (rows === undefined) {\n continue;\n }\n for (const r of rows) {\n if (!table.value.isSet(r)) {\n continue;\n }\n let text: string | null;\n if (table.valueText !== null && table.valueText.isSet(r)) {\n text = table.valueText.value(r) as string;\n } else {\n text = table.format(cellValue(table.value, r));\n }\n if (text === null) {\n continue;\n }\n out += `${indent} <attvalue for=\"${escapeXmlAttribute(spec.id)}\" value=\"${escapeXmlAttribute(text)}\"${timedAttrs(table, r, plan)}/>\\n`;\n }\n }\n return out.length === 0 ? \"\" : `${indent}<attvalues>\\n${out}${indent}</attvalues>\\n`;\n}\n\n/**\n * The time bounds of one temporal table row as attributes.\n * @param table - the table\n * @param r - the row\n * @param plan - the plan\n * @returns the attribute text, starting with a space when non-empty\n */\nfunction timedAttrs(table: TemporalTable, r: number, plan: ExportPlan): string {\n const start = table.start.isSet(r) ? (table.start.value(r) as number) : -Infinity;\n const end = table.end.isSet(r) ? (table.end.value(r) as number) : Infinity;\n let out = \"\";\n if (plan.version === \"1.3\" && plan.timeRepresentation === \"timestamp\" && start === end && Number.isFinite(start)) {\n return ` timestamp=\"${escapeXmlAttribute(timeText(table.start, table.startText, r, plan.timeFormat))}\"`;\n }\n let bits = 0;\n if (plan.version === \"1.2\" && table.open !== null && table.open.isSet(r)) {\n bits = table.open.value(r) as number;\n }\n if (Number.isFinite(start)) {\n const name = (bits & OPEN_START) !== 0 ? \"startopen\" : \"start\";\n out += ` ${name}=\"${escapeXmlAttribute(timeText(table.start, table.startText, r, plan.timeFormat))}\"`;\n }\n if (Number.isFinite(end)) {\n const name = (bits & OPEN_END) !== 0 ? \"endopen\" : \"end\";\n out += ` ${name}=\"${escapeXmlAttribute(timeText(table.end, table.endText, r, plan.timeFormat))}\"`;\n }\n return out;\n}\n\n/**\n * The value of a set cell as a plain JS value: lists through sliceOf, json through values, a\n * stride column as an array of lanes.\n * @param column - the column\n * @param row - the row\n * @returns the value\n */\nfunction cellValue(column: Column, row: number): unknown {\n switch (column.dtype) {\n case \"list\":\n return column.sliceOf(row);\n case \"json\":\n return column.values[row];\n default: {\n const value = column.value(row);\n return ArrayBuffer.isView(value) ? Array.from(value as ArrayLike<number>) : value;\n }\n }\n}\n\n/**\n * Whether `viz:position` gets a z attribute: always for a 3-d source, and for a 2-d source\n * (`extra.sourceDims === 2`) only when some node has since been given a non-zero z.\n * @param position - the position role column, or null\n * @returns true when z is written\n */\nfunction positionWritesZ(position: Column | null): boolean {\n if (position === null || position.meta.components < 3) {\n return false;\n }\n if (position.meta.extra.sourceDims !== 2) {\n return true;\n }\n const { components } = position.meta;\n let data: ArrayLike<number>;\n switch (position.dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\":\n ({ data } = position);\n break;\n default:\n // A non-numeric position column has no z lane to inspect; write z so nothing is lost.\n return true;\n }\n for (let i = 0; i < position.length; i++) {\n if (position.isSet(i) && data[i * components + 2] !== 0) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * The items of a set row of a list column.\n * @param column - a list column\n * @param row - the row\n * @returns the items; empty when the column is not a list\n */\nfunction listItems(column: Column, row: number): readonly unknown[] {\n return column.dtype === \"list\" ? column.sliceOf(row) : [];\n}\n\n/**\n * The viz elements of one node or edge.\n * @param roles - the domain's role columns\n * @param row - the element's row\n * @param indent - the indentation\n * @param writeZ - whether viz:position gets its z attribute\n * @returns the lines, or an empty string\n */\nfunction vizElements(roles: RoleColumns, row: number, indent: string, writeZ: boolean): string {\n let out = \"\";\n const { color } = roles;\n if (color !== null && color.isSet(row)) {\n const lanes = Array.from(color.value(row) as ArrayLike<number>);\n const scale = color.dtype === \"u8\" ? 1 : 255;\n const channel = (v: number): string => String(Math.max(0, Math.min(255, Math.round(v * scale))));\n let attrs = ` r=\"${channel(lanes[0])}\" g=\"${channel(lanes[1])}\" b=\"${channel(lanes[2])}\"`;\n if (lanes.length > 3) {\n const a = color.dtype === \"u8\" ? lanes[3] / 255 : lanes[3];\n if (a !== 1) {\n attrs += ` a=\"${formatF32(Math.fround(a))}\"`;\n }\n }\n out += `${indent}<viz:color${attrs}/>\\n`;\n }\n const { position } = roles;\n if (position !== null && position.isSet(row)) {\n const lanes = Array.from(position.value(row) as ArrayLike<number>);\n const fmt = position.dtype === \"f32\" ? formatF32 : formatF64;\n let attrs = ` x=\"${fmt(lanes[0])}\" y=\"${fmt(lanes[1])}\"`;\n if (lanes.length > 2 && writeZ) {\n attrs += ` z=\"${fmt(lanes[2])}\"`;\n }\n out += `${indent}<viz:position${attrs}/>\\n`;\n }\n for (const [name, column] of [\n [\"size\", roles.size],\n [\"thickness\", roles.thickness],\n ] as const) {\n if (column !== null && column.isSet(row)) {\n const value = column.value(row) as number;\n const text = column.dtype === \"f32\" ? formatF32(value) : formatF64(value);\n out += `${indent}<viz:${name} value=\"${escapeXmlAttribute(text)}\"/>\\n`;\n }\n }\n const { shape } = roles;\n if (shape !== null && shape.isSet(row)) {\n let attrs = ` value=\"${escapeXmlAttribute(String(shape.value(row)))}\"`;\n if (roles.shapeUri !== null && roles.shapeUri.isSet(row)) {\n attrs += ` uri=\"${escapeXmlAttribute(roles.shapeUri.value(row) as string)}\"`;\n }\n out += `${indent}<viz:shape${attrs}/>\\n`;\n }\n return out;\n}\n\n/**\n * The `<attributes>` groups of one class.\n * @param cls - node or edge\n * @param specs - the declarations\n * @param indent - the indentation\n * @returns the lines, or an empty string\n */\nfunction attributesGroups(cls: \"node\" | \"edge\", specs: readonly AttributeSpec[], indent: string): string {\n let out = \"\";\n for (const mode of [\"static\", \"dynamic\"] as const) {\n const group = specs.filter((s) => s.dynamic === (mode === \"dynamic\"));\n if (group.length === 0) {\n continue;\n }\n out += `${indent}<attributes class=\"${cls}\" mode=\"${mode}\">\\n`;\n for (const spec of group) {\n const head = `${indent} <attribute id=\"${escapeXmlAttribute(spec.id)}\" title=\"${escapeXmlAttribute(spec.title)}\" type=\"${spec.type}\"`;\n if (spec.defaultText === null && spec.optionsText === null) {\n out += `${head}/>\\n`;\n continue;\n }\n out += `${head}>\\n`;\n if (spec.defaultText !== null) {\n out += `${indent} <default>${escapeXmlText(spec.defaultText)}</default>\\n`;\n }\n if (spec.optionsText !== null) {\n out += `${indent} <options>${escapeXmlText(spec.optionsText)}</options>\\n`;\n }\n out += `${indent} </attribute>\\n`;\n }\n out += `${indent}</attributes>\\n`;\n }\n return out;\n}\n\n/**\n * The `type` of a logical edge after folding an expanded pair (design section 3.6).\n * @param snapshot - the snapshot\n * @param e - the logical edge index\n * @param folding - the pair-folding view (mutual pairs fold: GEXF has the mutual type)\n * @returns the edge type, or null when the edge is the mirror half of a pair\n */\nfunction edgeType(snapshot: GraphSnapshot, e: number, folding: PairFolding): GexfEdgeType | null {\n if (!snapshot.directed) {\n return \"undirected\";\n }\n if (folding.folded(e)) {\n return null;\n }\n if (!folding.sourceDirected(e)) {\n return \"undirected\";\n }\n if (folding.mateOf(e) !== INVALID_INDEX || folding.isMutual(e)) {\n return \"mutual\";\n }\n return \"directed\";\n}\n\n/**\n * Write the document as text parts.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @yields one part per element or line group\n * @returns nothing\n */\nfunction* writeGexf(\n snapshot: GraphSnapshot,\n options: (GexfExportOptions & CommonExportOptions) | undefined,\n): Generator<string, void, undefined> {\n const plan = planExport(snapshot, options);\n const { version } = plan;\n const ids = sanitizeIds(snapshot, \"any\", plan.options.sanitizeIds);\n const idText = (index: number): string => escapeXmlAttribute(String(ids.idAt(index)));\n const ns = GEXF_NAMESPACES[version];\n const { meta } = snapshot;\n\n yield '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n yield `<gexf xmlns=\"${ns.gexf}\" xmlns:viz=\"${ns.viz}\" version=\"${version}\">\\n`;\n yield metaElement(meta);\n yield graphStart(snapshot, plan);\n yield attributesGroups(\"node\", plan.nodeAttrs, \" \");\n yield attributesGroups(\"edge\", plan.edgeAttrs, \" \");\n\n // nodes\n const { nodeRoles } = plan;\n const writeZ = positionWritesZ(nodeRoles.position);\n yield ` <nodes count=\"${snapshot.nodeCount}\">\\n`;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n let attrs = ` id=\"${idText(i)}\"`;\n if (nodeRoles.label !== null && nodeRoles.label.isSet(i)) {\n attrs += ` label=\"${escapeXmlAttribute(String(nodeRoles.label.value(i)))}\"`;\n }\n if (nodeRoles.parent !== null && nodeRoles.parent.isSet(i)) {\n attrs += ` pid=\"${idText(nodeRoles.parent.value(i) as number)}\"`;\n }\n attrs += lifetimeAttrs(nodeRoles, i, plan);\n let body = attvaluesElement(plan.nodeAttrs, i, plan, \" \");\n if (nodeRoles.parents !== null && nodeRoles.parents.isSet(i)) {\n const parents = listItems(nodeRoles.parents, i) as readonly number[];\n if (parents.length > 0) {\n body += \" <parents>\\n\";\n for (const p of parents) {\n body += ` <parent for=\"${idText(p)}\"/>\\n`;\n }\n body += \" </parents>\\n\";\n }\n }\n body += spellsElement(nodeRoles, i, plan, \" \");\n body += vizElements(nodeRoles, i, \" \", writeZ);\n yield body.length === 0 ? ` <node${attrs}/>\\n` : ` <node${attrs}>\\n${body} </node>\\n`;\n }\n yield \" </nodes>\\n\";\n\n // edges: the count is decided in a cheap first pass (no strings built) so the section\n // streams element by element instead of buffering every edge\n const { edgeRoles } = plan;\n const edgeList = snapshot.edgeList();\n const folding = pairFolding(snapshot, { foldMutual: true });\n const weights = explicitWeights(snapshot);\n const defaultType = defaultEdgeType(snapshot);\n let written = 0;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (edgeType(snapshot, e, folding) !== null) {\n written++;\n }\n }\n yield ` <edges count=\"${written}\">\\n`;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n const type = edgeType(snapshot, e, folding);\n if (type === null) {\n continue;\n }\n let attrs = \"\";\n if (edgeRoles.id !== null && edgeRoles.id.isSet(e)) {\n attrs += ` id=\"${escapeXmlAttribute(String(edgeRoles.id.value(e)))}\"`;\n } else if (version === \"1.2\") {\n attrs += ` id=\"e${e}\"`;\n }\n attrs += ` source=\"${idText(edgeList.src[e])}\" target=\"${idText(edgeList.dst[e])}\"`;\n if (type !== defaultType) {\n attrs += ` type=\"${type}\"`;\n }\n const weight = weights.text(e);\n if (weight !== null) {\n attrs += ` weight=\"${weight}\"`;\n }\n if (edgeRoles.label !== null && edgeRoles.label.isSet(e)) {\n attrs += ` label=\"${escapeXmlAttribute(String(edgeRoles.label.value(e)))}\"`;\n }\n if (version === \"1.3\" && edgeRoles.kind !== null && edgeRoles.kind.isSet(e)) {\n attrs += ` kind=\"${escapeXmlAttribute(String(edgeRoles.kind.value(e)))}\"`;\n }\n attrs += lifetimeAttrs(edgeRoles, e, plan);\n let body = attvaluesElement(plan.edgeAttrs, e, plan, \" \");\n body += spellsElement(edgeRoles, e, plan, \" \");\n body += vizElements(edgeRoles, e, \" \", false);\n yield body.length === 0 ? ` <edge${attrs}/>\\n` : ` <edge${attrs}>\\n${body} </edge>\\n`;\n }\n yield \" </edges>\\n\";\n yield \" </graph>\\n\";\n yield \"</gexf>\\n\";\n}\n\n/**\n * The `<meta>` element.\n * @param meta - the graph meta\n * @returns the lines, or an empty string when nothing is set\n */\nfunction metaElement(meta: GraphSnapshot[\"meta\"]): string {\n let body = \"\";\n if (meta.creator !== null) {\n body += ` <creator>${escapeXmlText(meta.creator)}</creator>\\n`;\n }\n if (meta.description !== null) {\n body += ` <description>${escapeXmlText(meta.description)}</description>\\n`;\n }\n if (meta.keywords.length > 0) {\n body += ` <keywords>${escapeXmlText(meta.keywords.join(\", \"))}</keywords>\\n`;\n }\n const modified = meta.modified === null ? \"\" : ` lastmodifieddate=\"${escapeXmlAttribute(meta.modified)}\"`;\n if (body.length === 0 && modified.length === 0) {\n return \"\";\n }\n return body.length === 0 ? ` <meta${modified}/>\\n` : ` <meta${modified}>\\n${body} </meta>\\n`;\n}\n\n/**\n * The `<graph>` start tag with its header attributes.\n * @param snapshot - the snapshot\n * @param plan - the plan\n * @returns the line\n */\nfunction graphStart(snapshot: GraphSnapshot, plan: ExportPlan): string {\n const { meta } = snapshot;\n let attrs = ` defaultedgetype=\"${defaultEdgeType(snapshot)}\"`;\n let mode = meta.mode ?? \"static\";\n if (plan.temporal && mode === \"static\") {\n mode = \"dynamic\";\n }\n if (plan.version === \"1.2\" && mode === \"slice\") {\n mode = \"dynamic\";\n }\n attrs += ` mode=\"${mode}\"`;\n let { idType } = meta;\n if (idType === null) {\n const { kind } = snapshot.ids;\n if (kind === \"string\") {\n idType = \"string\";\n } else if (kind !== \"mixed\") {\n idType = \"integer\";\n }\n }\n if (idType === \"integer\" || idType === \"string\") {\n attrs += ` idtype=\"${idType}\"`;\n }\n if (plan.timeFormat !== null) {\n attrs += ` timeformat=\"${plan.timeFormat}\"`;\n } else if (plan.temporal) {\n attrs += ' timeformat=\"double\"';\n }\n if (plan.version === \"1.3\" && plan.timeRepresentation !== null) {\n attrs += ` timerepresentation=\"${plan.timeRepresentation}\"`;\n }\n const timestamp = graphExtraText(snapshot, \"timestamp\");\n const header: Record<string, string | null> = {\n start: graphExtraText(snapshot, \"start\"),\n end: graphExtraText(snapshot, \"end\"),\n timestamp,\n };\n if (plan.version === \"1.2\" && timestamp !== null) {\n // GEXF 1.2 has no timestamp: the graph's becomes a closed interval, as an element's does\n header.start ??= timestamp;\n header.end ??= timestamp;\n header.timestamp = null;\n }\n for (const [key, value] of Object.entries(header)) {\n if (value !== null) {\n attrs += ` ${key}=\"${escapeXmlAttribute(value)}\"`;\n }\n }\n return ` <graph${attrs}>\\n`;\n}\n\n/**\n * The `defaultedgetype` to write: the snapshot's direction, or `mutual` for a directed snapshot\n * whose source file declared a mutual default (the importer reads that default as directed, with\n * every untyped edge mutual), so the default survives a round trip.\n * @param snapshot - the snapshot\n * @returns the edge type the header declares, and every edge without its own `type` takes\n */\nfunction defaultEdgeType(snapshot: GraphSnapshot): GexfEdgeType {\n if (!snapshot.directed) {\n return \"undirected\";\n }\n return graphExtraText(snapshot, \"defaultedgetype\")?.trim().toLowerCase() === \"mutual\" ? \"mutual\" : \"directed\";\n}\n\n/**\n * A graph header value the GEXF importer recorded in `meta.extra.gexf` (defaultedgetype, start,\n * end, timestamp).\n * @param snapshot - the snapshot\n * @param key - the attribute name\n * @returns the text, or null when absent\n */\nfunction graphExtraText(snapshot: GraphSnapshot, key: string): string | null {\n const gexfExtra = snapshot.meta.extra.gexf;\n if (typeof gexfExtra !== \"object\" || gexfExtra === null) {\n return null;\n }\n const value = (gexfExtra as Record<string, unknown>)[key];\n return typeof value === \"string\" ? value : null;\n}\n\n/** The GEXF exporter (design section 8.5); `capabilities` describes the default 1.3 output. */\nexport const gexfExporter: GraphExporter<GexfExportOptions> = Object.freeze({\n format: GEXF_FORMAT,\n capabilities: CAPABILITIES_1_3,\n /**\n * Pre-flight: what export() would lose.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the loss notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: GexfExportOptions & CommonExportOptions): readonly LossNote[] {\n return Object.freeze(planExport(snapshot, options).notes);\n },\n /**\n * Write the snapshot as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: GexfExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(writeGexf(snapshot, options));\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the document\n */\n async exportToString(snapshot: GraphSnapshot, options?: GexfExportOptions & CommonExportOptions): Promise<string> {\n return joinText(writeGexf(snapshot, options));\n },\n});\n\n/** The capabilities of a 1.2 export, for callers that pass `version: \"1.2\"`. */\nexport const GEXF_1_2_CAPABILITIES: ExportCapabilities = CAPABILITIES_1_2;\n","/**\n * The GEXF subpath entry (`@graphty/graph-io/gexf`, design section 8.2): the importer and exporter\n * objects with their format-specific option types, the exporter's loss-note codes and the\n * importer's issue codes grouped in one table.\n */\n\nimport {\n BAD_DEFAULT_CODE,\n BAD_OPTIONS_CODE,\n COLUMN_RENAMED_CODE,\n COUNT_HINT_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n DUPLICATE_ATTRIBUTE_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_NODE_CODE,\n ENCODING_FALLBACK_CODE,\n ID_MERGED_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MIXED_DIRECTION_CODE,\n NO_GRAPH_CODE,\n OPTION_IGNORED_CODE,\n PRECISION_CODE,\n ROLE_TAKEN_CODE,\n SINK_OPTION_CODE,\n STRAY_TEXT_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ELEMENT_CODE,\n UNKNOWN_ENCODING_CODE,\n UNKNOWN_PARENT_CODE,\n XML_SYNTAX_CODE,\n} from \"../../common/codes.js\";\nimport {\n ATTRIBUTE_ID_CODE,\n ATTRIBUTE_TYPE_CODE,\n ATTRIBUTES_CLASS_CODE,\n ATTVALUE_SHAPE_CODE,\n EDGE_TYPE_CODE,\n HEADER_VALUE_CODE,\n MISSING_NODES_CODE,\n NOT_GEXF_CODE,\n OPEN_BOUND_CONFLICT_CODE,\n SPELL_OPEN_CODE,\n TIMED_STATIC_CODE,\n UNKNOWN_ATTRIBUTE_CODE,\n VIZ_DYNAMIC_CODE,\n VIZ_SKIPPED_CODE,\n VIZ_VALUE_CODE,\n WEIGHT_IGNORED_CODE,\n} from \"./importer.js\";\n\nexport { GEXF_1_2_CAPABILITIES, GEXF_LOSS, gexfExporter, type GexfExportOptions } from \"./exporter.js\";\nexport { gexfImporter, type GexfImportOptions } from \"./importer.js\";\nexport { type GexfVersion } from \"./schema.js\";\n\n/**\n * The issue codes the GEXF importer records (design section 8.6), by name: the codes shared with\n * the other importers (src/common/codes.ts) and the GEXF-specific ones. A key is the code without\n * its severity and format prefixes.\n */\nexport const GEXF_ISSUE = Object.freeze({\n /** The XML is not well-formed (fatal). */\n XML_SYNTAX: XML_SYNTAX_CODE,\n /** The input holds invalid UTF-8 (fatal). */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM, a declaration or the encoding option chose (fatal). */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** The root element is not `<gexf>` (fatal). */\n NOT_GEXF: NOT_GEXF_CODE,\n /** The document has no `<graph>` (fatal). */\n NO_GRAPH: NO_GRAPH_CODE,\n /** `<edges>` without `<nodes>`. */\n MISSING_NODES: MISSING_NODES_CODE,\n /** A node without an id. */\n MISSING_ID: MISSING_ID_CODE,\n /** An edge without a source or target. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** An edge `type` outside directed / undirected / mutual. */\n EDGE_TYPE: EDGE_TYPE_CODE,\n /** A `pid` / `<parent for>` naming an unknown node. */\n UNKNOWN_PARENT: UNKNOWN_PARENT_CODE,\n /** An `<attributes class>` outside node / edge. */\n ATTRIBUTES_CLASS: ATTRIBUTES_CLASS_CODE,\n /** An `<attribute>` without an id. */\n ATTRIBUTE_ID: ATTRIBUTE_ID_CODE,\n /** A `<graph>` header attribute with an unknown value. */\n HEADER_VALUE: HEADER_VALUE_CODE,\n /** A `count` hint the sink cannot reserve (ignored). */\n COUNT_HINT: COUNT_HINT_CODE,\n /** A node id declared twice. */\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 attribute id declared twice in one class. */\n DUPLICATE_ATTRIBUTE: DUPLICATE_ATTRIBUTE_CODE,\n /** An attribute type the importer maps to string. */\n ATTRIBUTE_TYPE: ATTRIBUTE_TYPE_CODE,\n /** A declared type the format does not define (kept as string). */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** A default that does not parse as the declared type. */\n BAD_DEFAULT: BAD_DEFAULT_CODE,\n /** Options that do not parse as the declared type. */\n BAD_OPTIONS: BAD_OPTIONS_CODE,\n /** A column renamed `<name>#<id>` because the name was taken (design section 5.6). */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A column declared without its role because the table already holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** An `<attvalue for>` naming an undeclared attribute. */\n UNKNOWN_ATTRIBUTE: UNKNOWN_ATTRIBUTE_CODE,\n /** An `<attvalue>` without a value. */\n ATTVALUE_SHAPE: ATTVALUE_SHAPE_CODE,\n /** A timed value on an attribute of a static group. */\n TIMED_VALUE_ON_STATIC: TIMED_STATIC_CODE,\n /** A long value beyond 2^53 rounded. */\n PRECISION: PRECISION_CODE,\n /** Two id texts merged into one number under ids \"number\". */\n ID_MERGED: ID_MERGED_CODE,\n /** The XML weight attribute ignored under weightFrom null. */\n WEIGHT_IGNORED: WEIGHT_IGNORED_CODE,\n /** viz elements skipped under viz: false. */\n VIZ_SKIPPED: VIZ_SKIPPED_CODE,\n /** A 1.2 dynamic viz element whose bounds were dropped. */\n VIZ_DYNAMIC_DROPPED: VIZ_DYNAMIC_CODE,\n /** Deprecated and no longer recorded: open spells are kept in the spells.open column. */\n SPELL_OPEN_DROPPED: SPELL_OPEN_CODE,\n /** A viz value that could not be read. */\n VIZ_VALUE: VIZ_VALUE_CODE,\n /** Both `start` and `startopen` (or `end` and `endopen`) on one element. */\n OPEN_BOUND_CONFLICT: OPEN_BOUND_CONFLICT_CODE,\n /** An element or attribute GEXF does not define was skipped. */\n UNKNOWN_ELEMENT: UNKNOWN_ELEMENT_CODE,\n /** Text where GEXF allows only elements was ignored. */\n STRAY_TEXT: STRAY_TEXT_CODE,\n /** A common option the importer has no use for was given. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder-policy option the sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n /** The sink refused the file's direction. */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges forced to the policy's direction. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /** A mixed file under onMixedDirection \"error\" (fatal). */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n});\n"],"names":["edgeType","declared"],"mappings":"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"}