@graphty/graph-io 0.3.40 → 0.3.42

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 (210) hide show
  1. package/README.md +2 -0
  2. package/dist/chunks/{children-CL3Cy0ez.js → children-CA4coBi0.js} +36 -27
  3. package/dist/chunks/children-CA4coBi0.js.map +1 -0
  4. package/dist/chunks/{choose-CS3fvGT1.js → choose-DvpbdRuz.js} +2 -2
  5. package/dist/chunks/{choose-CS3fvGT1.js.map → choose-DvpbdRuz.js.map} +1 -1
  6. package/dist/chunks/{constants-DqKZT6cH.js → constants-fT3E8JYY.js} +2 -2
  7. package/dist/chunks/{constants-DqKZT6cH.js.map → constants-fT3E8JYY.js.map} +1 -1
  8. package/dist/chunks/{escape-BJRLd3vJ.js → escape-B62ZGM_a.js} +2 -2
  9. package/dist/chunks/{escape-BJRLd3vJ.js.map → escape-B62ZGM_a.js.map} +1 -1
  10. package/dist/chunks/{export-B-aVCwyG.js → export-rKLeGQMo.js} +404 -243
  11. package/dist/chunks/export-rKLeGQMo.js.map +1 -0
  12. package/dist/chunks/{exporter-6ocL_9x_.js → exporter-8hLNemFk.js} +4 -4
  13. package/dist/chunks/{exporter-6ocL_9x_.js.map → exporter-8hLNemFk.js.map} +1 -1
  14. package/dist/chunks/{exporter-BVXnV9-9.js → exporter-BWwEuOPT.js} +29 -17
  15. package/dist/chunks/exporter-BWwEuOPT.js.map +1 -0
  16. package/dist/chunks/{exporter-Bcp-l4Bo.js → exporter-CpRyHZ3H.js} +574 -475
  17. package/dist/chunks/exporter-CpRyHZ3H.js.map +1 -0
  18. package/dist/chunks/{exporter-SFYkDzD0.js → exporter-yLxKBvLE.js} +23 -20
  19. package/dist/chunks/{exporter-SFYkDzD0.js.map → exporter-yLxKBvLE.js.map} +1 -1
  20. package/dist/chunks/{importer-DcKB97kW.js → importer-BbNb7eNg.js} +111 -71
  21. package/dist/chunks/importer-BbNb7eNg.js.map +1 -0
  22. package/dist/chunks/{importer-D_srHyj6.js → importer-C98dpSH4.js} +5 -5
  23. package/dist/chunks/{importer-D_srHyj6.js.map → importer-C98dpSH4.js.map} +1 -1
  24. package/dist/chunks/{importer-BJlGAOht.js → importer-D794XUTe.js} +3 -3
  25. package/dist/chunks/{importer-BJlGAOht.js.map → importer-D794XUTe.js.map} +1 -1
  26. package/dist/chunks/{importer-AjwOJrn2.js → importer-Dz7tI8Sa.js} +202 -181
  27. package/dist/chunks/importer-Dz7tI8Sa.js.map +1 -0
  28. package/dist/chunks/{importer-DEp_fYjf.js → importer-Ht7LNg8L.js} +92 -64
  29. package/dist/chunks/importer-Ht7LNg8L.js.map +1 -0
  30. package/dist/chunks/{importer-CPqnIY8m.js → importer-WrGRZb0N.js} +42 -29
  31. package/dist/chunks/importer-WrGRZb0N.js.map +1 -0
  32. package/dist/chunks/{importer-BpuS3J8C.js → importer-xZ-3suY1.js} +74 -61
  33. package/dist/chunks/importer-xZ-3suY1.js.map +1 -0
  34. package/dist/chunks/{json-elements-DpO6AXIc.js → json-elements-DKSqpNW1.js} +3 -3
  35. package/dist/chunks/{json-elements-DpO6AXIc.js.map → json-elements-DKSqpNW1.js.map} +1 -1
  36. package/dist/chunks/{ontology-export-50L9DOV4.js → ontology-export-CtRXjg_i.js} +2 -2
  37. package/dist/chunks/{ontology-export-50L9DOV4.js.map → ontology-export-CtRXjg_i.js.map} +1 -1
  38. package/dist/chunks/{records-r3SFHz11.js → records-Cu4bxYOm.js} +69 -36
  39. package/dist/chunks/records-Cu4bxYOm.js.map +1 -0
  40. package/dist/chunks/{text-Bjfa1xYL.js → text-DHOJXnED.js} +20 -11
  41. package/dist/chunks/text-DHOJXnED.js.map +1 -0
  42. package/dist/csv.js +323 -241
  43. package/dist/csv.js.map +1 -1
  44. package/dist/cx.js +1 -1
  45. package/dist/cx2.js +2 -2
  46. package/dist/cys.js +1 -1
  47. package/dist/dot.js +1 -1
  48. package/dist/gexf.js +195 -97
  49. package/dist/gexf.js.map +1 -1
  50. package/dist/gml.js +170 -149
  51. package/dist/gml.js.map +1 -1
  52. package/dist/graph-io.js +27 -27
  53. package/dist/graphml.js +2 -2
  54. package/dist/json.js +1 -1
  55. package/dist/neo4j.js +103 -65
  56. package/dist/neo4j.js.map +1 -1
  57. package/dist/obo.js +1 -1
  58. package/dist/pajek.js +1 -1
  59. package/dist/src/children.d.ts.map +1 -1
  60. package/dist/src/children.js +50 -27
  61. package/dist/src/children.js.map +1 -1
  62. package/dist/src/common/attributes.d.ts.map +1 -1
  63. package/dist/src/common/attributes.js +86 -42
  64. package/dist/src/common/attributes.js.map +1 -1
  65. package/dist/src/common/input.d.ts.map +1 -1
  66. package/dist/src/common/input.js +358 -184
  67. package/dist/src/common/input.js.map +1 -1
  68. package/dist/src/common/lists.js +30 -15
  69. package/dist/src/common/lists.js.map +1 -1
  70. package/dist/src/common/text.d.ts +7 -0
  71. package/dist/src/common/text.d.ts.map +1 -1
  72. package/dist/src/common/text.js +15 -7
  73. package/dist/src/common/text.js.map +1 -1
  74. package/dist/src/common/zip.d.ts.map +1 -1
  75. package/dist/src/common/zip.js +36 -19
  76. package/dist/src/common/zip.js.map +1 -1
  77. package/dist/src/formats/csv/exporter.d.ts.map +1 -1
  78. package/dist/src/formats/csv/exporter.js +288 -146
  79. package/dist/src/formats/csv/exporter.js.map +1 -1
  80. package/dist/src/formats/csv/importer.d.ts.map +1 -1
  81. package/dist/src/formats/csv/importer.js +129 -80
  82. package/dist/src/formats/csv/importer.js.map +1 -1
  83. package/dist/src/formats/csv/records.d.ts.map +1 -1
  84. package/dist/src/formats/csv/records.js +78 -36
  85. package/dist/src/formats/csv/records.js.map +1 -1
  86. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  87. package/dist/src/formats/cys/tables.js +11 -8
  88. package/dist/src/formats/cys/tables.js.map +1 -1
  89. package/dist/src/formats/dot/tokenizer.d.ts +39 -0
  90. package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
  91. package/dist/src/formats/dot/tokenizer.js +112 -66
  92. package/dist/src/formats/dot/tokenizer.js.map +1 -1
  93. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  94. package/dist/src/formats/gexf/exporter.js +65 -37
  95. package/dist/src/formats/gexf/exporter.js.map +1 -1
  96. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  97. package/dist/src/formats/gexf/importer.js +138 -50
  98. package/dist/src/formats/gexf/importer.js.map +1 -1
  99. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  100. package/dist/src/formats/gml/exporter.js +51 -35
  101. package/dist/src/formats/gml/exporter.js.map +1 -1
  102. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  103. package/dist/src/formats/gml/importer.js +103 -58
  104. package/dist/src/formats/gml/importer.js.map +1 -1
  105. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  106. package/dist/src/formats/gml/syntax.js +17 -8
  107. package/dist/src/formats/gml/syntax.js.map +1 -1
  108. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  109. package/dist/src/formats/graphml/exporter.js +34 -24
  110. package/dist/src/formats/graphml/exporter.js.map +1 -1
  111. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  112. package/dist/src/formats/graphml/importer.js +17 -13
  113. package/dist/src/formats/graphml/importer.js.map +1 -1
  114. package/dist/src/formats/graphml/tree.js +23 -14
  115. package/dist/src/formats/graphml/tree.js.map +1 -1
  116. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  117. package/dist/src/formats/graphml/yfiles.js +22 -10
  118. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  119. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  120. package/dist/src/formats/json/dialect.js +54 -20
  121. package/dist/src/formats/json/dialect.js.map +1 -1
  122. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  123. package/dist/src/formats/json/exporter.js +38 -21
  124. package/dist/src/formats/json/exporter.js.map +1 -1
  125. package/dist/src/formats/json/importer.d.ts.map +1 -1
  126. package/dist/src/formats/json/importer.js +536 -343
  127. package/dist/src/formats/json/importer.js.map +1 -1
  128. package/dist/src/formats/json/obographs.js +29 -17
  129. package/dist/src/formats/json/obographs.js.map +1 -1
  130. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  131. package/dist/src/formats/neo4j/exporter.js +73 -43
  132. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  133. package/dist/src/formats/neo4j/header.d.ts.map +1 -1
  134. package/dist/src/formats/neo4j/header.js +37 -16
  135. package/dist/src/formats/neo4j/header.js.map +1 -1
  136. package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
  137. package/dist/src/formats/neo4j/importer.js +21 -11
  138. package/dist/src/formats/neo4j/importer.js.map +1 -1
  139. package/dist/src/formats/obo/exporter.d.ts.map +1 -1
  140. package/dist/src/formats/obo/exporter.js +18 -7
  141. package/dist/src/formats/obo/exporter.js.map +1 -1
  142. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  143. package/dist/src/formats/pajek/exporter.js +142 -73
  144. package/dist/src/formats/pajek/exporter.js.map +1 -1
  145. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  146. package/dist/src/formats/pajek/importer.js +26 -15
  147. package/dist/src/formats/pajek/importer.js.map +1 -1
  148. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  149. package/dist/src/formats/pajek/syntax.js +85 -58
  150. package/dist/src/formats/pajek/syntax.js.map +1 -1
  151. package/dist/src/formats/xgmml/emit.d.ts +7 -0
  152. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  153. package/dist/src/formats/xgmml/emit.js +79 -40
  154. package/dist/src/formats/xgmml/emit.js.map +1 -1
  155. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  156. package/dist/src/formats/xgmml/exporter.js +38 -12
  157. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  158. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  159. package/dist/src/formats/xgmml/importer.js +38 -18
  160. package/dist/src/formats/xgmml/importer.js.map +1 -1
  161. package/dist/src/sniff.js +109 -57
  162. package/dist/src/sniff.js.map +1 -1
  163. package/dist/xgmml.js +2 -2
  164. package/package.json +2 -2
  165. package/src/children.ts +54 -27
  166. package/src/common/attributes.ts +118 -49
  167. package/src/common/input.ts +439 -197
  168. package/src/common/lists.ts +29 -15
  169. package/src/common/text.ts +24 -15
  170. package/src/common/zip.ts +47 -18
  171. package/src/formats/csv/exporter.ts +377 -175
  172. package/src/formats/csv/importer.ts +155 -84
  173. package/src/formats/csv/records.ts +90 -35
  174. package/src/formats/cys/tables.ts +11 -10
  175. package/src/formats/dot/tokenizer.ts +118 -68
  176. package/src/formats/gexf/exporter.ts +67 -36
  177. package/src/formats/gexf/importer.ts +173 -63
  178. package/src/formats/gml/exporter.ts +78 -82
  179. package/src/formats/gml/importer.ts +119 -68
  180. package/src/formats/gml/syntax.ts +18 -8
  181. package/src/formats/graphml/exporter.ts +44 -24
  182. package/src/formats/graphml/importer.ts +18 -11
  183. package/src/formats/graphml/tree.ts +22 -12
  184. package/src/formats/graphml/yfiles.ts +23 -10
  185. package/src/formats/json/dialect.ts +61 -22
  186. package/src/formats/json/exporter.ts +40 -21
  187. package/src/formats/json/importer.ts +701 -385
  188. package/src/formats/json/obographs.ts +35 -15
  189. package/src/formats/neo4j/exporter.ts +79 -41
  190. package/src/formats/neo4j/header.ts +50 -16
  191. package/src/formats/neo4j/importer.ts +21 -10
  192. package/src/formats/obo/exporter.ts +34 -17
  193. package/src/formats/pajek/exporter.ts +180 -117
  194. package/src/formats/pajek/importer.ts +27 -15
  195. package/src/formats/pajek/syntax.ts +99 -58
  196. package/src/formats/xgmml/emit.ts +88 -40
  197. package/src/formats/xgmml/exporter.ts +40 -12
  198. package/src/formats/xgmml/importer.ts +45 -23
  199. package/src/sniff.ts +115 -59
  200. package/dist/chunks/children-CL3Cy0ez.js.map +0 -1
  201. package/dist/chunks/export-B-aVCwyG.js.map +0 -1
  202. package/dist/chunks/exporter-BVXnV9-9.js.map +0 -1
  203. package/dist/chunks/exporter-Bcp-l4Bo.js.map +0 -1
  204. package/dist/chunks/importer-AjwOJrn2.js.map +0 -1
  205. package/dist/chunks/importer-BpuS3J8C.js.map +0 -1
  206. package/dist/chunks/importer-CPqnIY8m.js.map +0 -1
  207. package/dist/chunks/importer-DEp_fYjf.js.map +0 -1
  208. package/dist/chunks/importer-DcKB97kW.js.map +0 -1
  209. package/dist/chunks/records-r3SFHz11.js.map +0 -1
  210. package/dist/chunks/text-Bjfa1xYL.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { INVALID_INDEX, GraphFormatError } from "@graphty/graph-format";
2
- import { M as MIXED_DIRECTION_CODE, D as DIRECTION_FORCED_CODE, d as DIRECTION_REFUSED_CODE, S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, I as ID_MERGED_CODE, R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, l as MULTIPLE_GRAPHS_CODE, f as STRAY_TEXT_CODE, g as UNKNOWN_ELEMENT_CODE, U as UNKNOWN_ATTR_TYPE_CODE, b6 as EQUATION_AS_TEXT_CODE, ai as PARENT_CYCLE_CODE, q as UNKNOWN_PARENT_CODE, o as DUPLICATE_ATTRIBUTE_CODE, i as DANGLING_REFERENCE_CODE, P as PRECISION_CODE, aj as WIDENED_CODE, a3 as BAD_VALUE_CODE, m as DUPLICATE_EDGE_ID_CODE, n as DUPLICATE_NODE_CODE, s as MISSING_ENDPOINT_CODE, t as MISSING_ID_CODE, N as NO_GRAPH_CODE, v as ENCODING_CONFLICT_CODE, w as UNKNOWN_ENCODING_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, E as EMPTY_INPUT_CODE, X as XML_SYNTAX_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, bj as STORAGE_CLASS_CODE, bp as WEIGHT_KEY_CLASH_CODE, au as ROLE_ASSUMED_CODE, a$ as COLUMN_RENAMED_LOSS_CODE, J as ID_TEXT_TYPE_CODE, bc as MUTUAL_EXPANDED_CODE, Q as PARENTS_DROPPED_CODE, K as ROLE_DROPPED_CODE, bl as TEMPORAL_TEXT_DROPPED_CODE, bk as TEMPORAL_DROPPED_CODE, ax as XML_ILLEGAL_CHAR_CODE, a0 as uniqueColumnName, a1 as declareResolved, ac as DictHeuristic, ar as IdCoercer, aq as DirectionResolver, b as plural, $ as agree, am as throwIfAborted, aK as parseWeightText, ao as reportSinkOptions, an as reportUnusedOptions, a7 as chooseGraph, ap as graphChosen, al as resolveImportOptions, a8 as ImportReportBuilder, a4 as textChunks, c0 as elementCount } from "./export-B-aVCwyG.js";
3
- import { l as localName, a as escapeXmlText, j as isWhitespace, e as escapeXmlAttribute, t as tokenizeXml, f as xmlDeclaredEncoding, X as XmlSyntaxError } from "./escape-BJRLd3vJ.js";
4
- import { p as parseTextCell, i as inferTextDtype } from "./text-Bjfa1xYL.js";
2
+ import { M as MIXED_DIRECTION_CODE, D as DIRECTION_FORCED_CODE, d as DIRECTION_REFUSED_CODE, S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, I as ID_MERGED_CODE, R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, l as MULTIPLE_GRAPHS_CODE, f as STRAY_TEXT_CODE, g as UNKNOWN_ELEMENT_CODE, U as UNKNOWN_ATTR_TYPE_CODE, b6 as EQUATION_AS_TEXT_CODE, ai as PARENT_CYCLE_CODE, q as UNKNOWN_PARENT_CODE, o as DUPLICATE_ATTRIBUTE_CODE, i as DANGLING_REFERENCE_CODE, P as PRECISION_CODE, aj as WIDENED_CODE, a3 as BAD_VALUE_CODE, m as DUPLICATE_EDGE_ID_CODE, n as DUPLICATE_NODE_CODE, s as MISSING_ENDPOINT_CODE, t as MISSING_ID_CODE, N as NO_GRAPH_CODE, v as ENCODING_CONFLICT_CODE, w as UNKNOWN_ENCODING_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, E as EMPTY_INPUT_CODE, X as XML_SYNTAX_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, bj as STORAGE_CLASS_CODE, bp as WEIGHT_KEY_CLASH_CODE, au as ROLE_ASSUMED_CODE, a$ as COLUMN_RENAMED_LOSS_CODE, J as ID_TEXT_TYPE_CODE, bc as MUTUAL_EXPANDED_CODE, Q as PARENTS_DROPPED_CODE, K as ROLE_DROPPED_CODE, bl as TEMPORAL_TEXT_DROPPED_CODE, bk as TEMPORAL_DROPPED_CODE, ax as XML_ILLEGAL_CHAR_CODE, a0 as uniqueColumnName, a1 as declareResolved, ac as DictHeuristic, ar as IdCoercer, aq as DirectionResolver, b as plural, $ as agree, am as throwIfAborted, aK as parseWeightText, ao as reportSinkOptions, an as reportUnusedOptions, a7 as chooseGraph, ap as graphChosen, al as resolveImportOptions, a8 as ImportReportBuilder, a4 as textChunks, c0 as elementCount } from "./export-rKLeGQMo.js";
3
+ import { l as localName, a as escapeXmlText, j as isWhitespace, e as escapeXmlAttribute, t as tokenizeXml, f as xmlDeclaredEncoding, X as XmlSyntaxError } from "./escape-B62ZGM_a.js";
4
+ import { p as parseTextCell, i as inferTextDtype } from "./text-DHOJXnED.js";
5
5
  const FORMAT = "xgmml";
6
6
  const EXTENSIONS = Object.freeze([".xgmml", ".xml"]);
7
7
  const MIME_TYPES = Object.freeze(["application/xgmml", "text/xgmml", "text/xgmml+xml"]);
@@ -1760,19 +1760,7 @@ function membersOf(doc, graph) {
1760
1760
  const edges = [];
1761
1761
  let dangling = 0;
1762
1762
  for (const member of graph.members) {
1763
- if (member.href === null) {
1764
- if (member.kind === "node") {
1765
- nodes.push(member);
1766
- } else {
1767
- edges.push(member);
1768
- }
1769
- continue;
1770
- }
1771
- const id = localRef(member.href);
1772
- let target;
1773
- if (id !== null) {
1774
- target = member.kind === "node" ? nodeById.get(id) : edgeById.get(id);
1775
- }
1763
+ const target = resolveMember(member, nodeById, edgeById);
1776
1764
  if (target === void 0) {
1777
1765
  dangling++;
1778
1766
  } else if (target.kind === "node") {
@@ -1783,6 +1771,16 @@ function membersOf(doc, graph) {
1783
1771
  }
1784
1772
  return { nodes, edges, dangling };
1785
1773
  }
1774
+ function resolveMember(member, nodeById, edgeById) {
1775
+ if (member.href === null) {
1776
+ return member;
1777
+ }
1778
+ const id = localRef(member.href);
1779
+ if (id === null) {
1780
+ return void 0;
1781
+ }
1782
+ return member.kind === "node" ? nodeById.get(id) : edgeById.get(id);
1783
+ }
1786
1784
  function indexById(records) {
1787
1785
  const out = /* @__PURE__ */ new Map();
1788
1786
  for (const record of records) {
@@ -1792,6 +1790,26 @@ function indexById(records) {
1792
1790
  }
1793
1791
  return out;
1794
1792
  }
1793
+ function isRepeat(seen, record) {
1794
+ if (seen === null) {
1795
+ return false;
1796
+ }
1797
+ const key2 = record.id ?? (record.label === null ? null : JSON.stringify([record.label, record.source, record.target]));
1798
+ if (key2 === null) {
1799
+ return false;
1800
+ }
1801
+ if (seen.has(key2)) {
1802
+ return true;
1803
+ }
1804
+ seen.add(key2);
1805
+ return false;
1806
+ }
1807
+ function isGraphValueAtt(att) {
1808
+ if (att.name !== null && META_ATTS.has(att.name)) {
1809
+ return false;
1810
+ }
1811
+ return !(att.hasGraph && att.name === null);
1812
+ }
1795
1813
  class XgmmlEmitter {
1796
1814
  /**
1797
1815
  * Create an emitter for one graph.
@@ -2165,16 +2183,7 @@ class XgmmlEmitter {
2165
2183
  if (graph.owner !== null && isGroup(graph.owner)) {
2166
2184
  continue;
2167
2185
  }
2168
- for (const member of graph.members) {
2169
- if (member.href === null) {
2170
- continue;
2171
- }
2172
- const id = localRef(member.href);
2173
- const known = id !== null && (member.kind === "node" ? this.rows.has(id) : edgeIds.has(id));
2174
- if (!known) {
2175
- dangling++;
2176
- }
2177
- }
2186
+ dangling += this.danglingReferences(graph, edgeIds);
2178
2187
  }
2179
2188
  if (dangling > 0) {
2180
2189
  this.report.warning(
@@ -2184,6 +2193,26 @@ class XgmmlEmitter {
2184
2193
  );
2185
2194
  }
2186
2195
  }
2196
+ /**
2197
+ * How many `xlink:href` members of a graph name no node or edge of the document.
2198
+ * @param graph - the graph
2199
+ * @param edgeIds - the id of every edge
2200
+ * @returns the count
2201
+ */
2202
+ danglingReferences(graph, edgeIds) {
2203
+ let dangling = 0;
2204
+ for (const member of graph.members) {
2205
+ if (member.href === null) {
2206
+ continue;
2207
+ }
2208
+ const id = localRef(member.href);
2209
+ const known = id !== null && (member.kind === "node" ? this.rows.has(id) : edgeIds.has(id));
2210
+ if (!known) {
2211
+ dangling++;
2212
+ }
2213
+ }
2214
+ return dangling;
2215
+ }
2187
2216
  /**
2188
2217
  * Write the per-node values: label, attributes, XML attributes, graphics, positions, nested
2189
2218
  * network pointers and subgraph memberships.
@@ -2376,14 +2405,10 @@ class XgmmlEmitter {
2376
2405
  this.decideNameLabel("edge", records);
2377
2406
  for (const record of records) {
2378
2407
  const where = { line: record.line, element: record.id ?? record.label };
2379
- const key2 = record.id ?? (record.label === null ? null : JSON.stringify([record.label, record.source, record.target]));
2380
- if (dedupe !== null && key2 !== null) {
2381
- if (dedupe.has(key2)) {
2382
- repeats++;
2383
- firstRepeat ??= where;
2384
- continue;
2385
- }
2386
- dedupe.add(key2);
2408
+ if (isRepeat(dedupe, record)) {
2409
+ repeats++;
2410
+ firstRepeat ??= where;
2411
+ continue;
2387
2412
  }
2388
2413
  const index = this.addEdge(record, header, ids, where);
2389
2414
  this.checkAbort();
@@ -2632,13 +2657,9 @@ class XgmmlEmitter {
2632
2657
  }
2633
2658
  }
2634
2659
  for (const att of g.atts) {
2635
- if (att.name !== null && META_ATTS.has(att.name)) {
2636
- continue;
2660
+ if (isGraphValueAtt(att)) {
2661
+ this.graphColumns.addAtt(0, att, where);
2637
2662
  }
2638
- if (att.hasGraph && att.name === null) {
2639
- continue;
2640
- }
2641
- this.graphColumns.addAtt(0, att, where);
2642
2663
  }
2643
2664
  this.graphColumns.write(this.sink, () => 0);
2644
2665
  const json = { ...this.extras.graphJson };
@@ -3107,19 +3128,7 @@ function booleanOption(name, value, fallback) {
3107
3128
  return value;
3108
3129
  }
3109
3130
  async function parseXgmml(input, report, common, options) {
3110
- const repairs = {
3111
- bareAmpersand: booleanOption("repairBareAmpersands", options?.repairBareAmpersands, false) ? (line) => {
3112
- report.warning("parse-error", XGMML_ISSUE.AMPERSAND_REPAIRED, "a bare & was read as &", { line });
3113
- } : void 0,
3114
- surrogatePair: booleanOption("pairSurrogateReferences", options?.pairSurrogateReferences, false) ? (line) => {
3115
- report.warning(
3116
- "parse-error",
3117
- XGMML_ISSUE.SURROGATE_PAIRED,
3118
- "two surrogate character references were joined into one character",
3119
- { line }
3120
- );
3121
- } : void 0
3122
- };
3131
+ const repairs = repairsOf(options, report);
3123
3132
  const parser = new XgmmlParser(report);
3124
3133
  const seen = { content: false };
3125
3134
  try {
@@ -3129,12 +3138,7 @@ async function parseXgmml(input, report, common, options) {
3129
3138
  repairs
3130
3139
  );
3131
3140
  } catch (err) {
3132
- if (err instanceof XmlSyntaxError) {
3133
- if (!seen.content) {
3134
- report.fail(XGMML_ISSUE.EMPTY_INPUT, "the input is empty");
3135
- }
3136
- report.fail(XGMML_ISSUE.XML_SYNTAX, err.message, { line: err.line });
3137
- }
3141
+ failOnSyntax(err, seen.content, report);
3138
3142
  throw err;
3139
3143
  }
3140
3144
  const doc = parser.document();
@@ -3148,6 +3152,30 @@ async function parseXgmml(input, report, common, options) {
3148
3152
  }
3149
3153
  return doc;
3150
3154
  }
3155
+ function repairsOf(options, report) {
3156
+ return {
3157
+ bareAmpersand: booleanOption("repairBareAmpersands", options?.repairBareAmpersands, false) ? (line) => {
3158
+ report.warning("parse-error", XGMML_ISSUE.AMPERSAND_REPAIRED, "a bare & was read as &", { line });
3159
+ } : void 0,
3160
+ surrogatePair: booleanOption("pairSurrogateReferences", options?.pairSurrogateReferences, false) ? (line) => {
3161
+ report.warning(
3162
+ "parse-error",
3163
+ XGMML_ISSUE.SURROGATE_PAIRED,
3164
+ "two surrogate character references were joined into one character",
3165
+ { line }
3166
+ );
3167
+ } : void 0
3168
+ };
3169
+ }
3170
+ function failOnSyntax(err, content, report) {
3171
+ if (!(err instanceof XmlSyntaxError)) {
3172
+ return;
3173
+ }
3174
+ if (!content) {
3175
+ report.fail(XGMML_ISSUE.EMPTY_INPUT, "the input is empty");
3176
+ }
3177
+ report.fail(XGMML_ISSUE.XML_SYNTAX, err.message, { line: err.line });
3178
+ }
3151
3179
  async function* watch(chunks, seen) {
3152
3180
  for await (const chunk of chunks) {
3153
3181
  seen.content ||= !isWhitespace(chunk);
@@ -3308,10 +3336,10 @@ export {
3308
3336
  XLINK_NAMESPACE as b,
3309
3337
  XGMML_NAMESPACE as c,
3310
3338
  aliasesOf as d,
3311
- NETWORK_POINTER_COLUMN as e,
3312
- NETWORKS_COLUMN as f,
3313
- PARENT_COLUMN as g,
3314
- PARENTS_COLUMN as h,
3339
+ PARENT_COLUMN as e,
3340
+ PARENTS_COLUMN as f,
3341
+ NETWORK_POINTER_COLUMN as g,
3342
+ NETWORKS_COLUMN as h,
3315
3343
  XGMML_ORIGIN_NAMESPACE as i,
3316
3344
  CYTOSCAPE_ORIGIN_NAMESPACE as j,
3317
3345
  XgmmlEmitter as k,
@@ -3323,4 +3351,4 @@ export {
3323
3351
  resolveSettings as r,
3324
3352
  xgmmlImporter as x
3325
3353
  };
3326
- //# sourceMappingURL=importer-DEp_fYjf.js.map
3354
+ //# sourceMappingURL=importer-Ht7LNg8L.js.map