@graphty/graph-io 0.3.43 → 0.3.44

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 (674) hide show
  1. package/dist/chunks/approximations-3Q4TsdTh.js +40 -0
  2. package/dist/chunks/approximations-3Q4TsdTh.js.map +1 -0
  3. package/dist/chunks/block-JQiwViEt.js +2777 -0
  4. package/dist/chunks/block-JQiwViEt.js.map +1 -0
  5. package/dist/chunks/{choose-DvpbdRuz.js → choose-BemygfH8.js} +3 -2
  6. package/dist/chunks/{choose-DvpbdRuz.js.map → choose-BemygfH8.js.map} +1 -1
  7. package/dist/chunks/{constants-fT3E8JYY.js → constants-BFUR_CtU.js} +6 -2
  8. package/dist/chunks/constants-BFUR_CtU.js.map +1 -0
  9. package/dist/chunks/convert-BcQ8_jMo.js +59 -0
  10. package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
  11. package/dist/chunks/emit-DCwFLts5.js +3456 -0
  12. package/dist/chunks/emit-DCwFLts5.js.map +1 -0
  13. package/dist/chunks/{escape-B62ZGM_a.js → escape-B1rMftd9.js} +43 -20
  14. package/dist/chunks/escape-B1rMftd9.js.map +1 -0
  15. package/dist/chunks/{export-rKLeGQMo.js → export-D7IGzTG4.js} +196 -792
  16. package/dist/chunks/export-D7IGzTG4.js.map +1 -0
  17. package/dist/chunks/{exporter-BWwEuOPT.js → exporter-BtnqYuuj.js} +22 -12
  18. package/dist/chunks/exporter-BtnqYuuj.js.map +1 -0
  19. package/dist/chunks/{exporter-yLxKBvLE.js → exporter-ChPyhBOv.js} +4 -3
  20. package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter-ChPyhBOv.js.map} +1 -1
  21. package/dist/chunks/{exporter-8hLNemFk.js → exporter-KEPxYUXD.js} +133 -74
  22. package/dist/chunks/exporter-KEPxYUXD.js.map +1 -0
  23. package/dist/chunks/{exporter-RVtXVetw.js → exporter-quPUCBiC.js} +1805 -287
  24. package/dist/chunks/exporter-quPUCBiC.js.map +1 -0
  25. package/dist/chunks/format-GDmO6m6Q.js +676 -0
  26. package/dist/chunks/format-GDmO6m6Q.js.map +1 -0
  27. package/dist/chunks/generic-BL06jrJf.js +1347 -0
  28. package/dist/chunks/generic-BL06jrJf.js.map +1 -0
  29. package/dist/chunks/{importer-WrGRZb0N.js → importer-B7r2owVf.js} +449 -102
  30. package/dist/chunks/importer-B7r2owVf.js.map +1 -0
  31. package/dist/chunks/{importer-Ht7LNg8L.js → importer-BFmOP96W.js} +116 -296
  32. package/dist/chunks/importer-BFmOP96W.js.map +1 -0
  33. package/dist/chunks/{importer-BbNb7eNg.js → importer-C2nzGhdV.js} +1390 -129
  34. package/dist/chunks/importer-C2nzGhdV.js.map +1 -0
  35. package/dist/chunks/{importer-Dz7tI8Sa.js → importer-CbX2_rNF.js} +617 -115
  36. package/dist/chunks/importer-CbX2_rNF.js.map +1 -0
  37. package/dist/chunks/{importer-D794XUTe.js → importer-CdzeN6X4.js} +31 -8
  38. package/dist/chunks/importer-CdzeN6X4.js.map +1 -0
  39. package/dist/chunks/{importer-xZ-3suY1.js → importer-ChKNC_GN.js} +791 -135
  40. package/dist/chunks/importer-ChKNC_GN.js.map +1 -0
  41. package/dist/chunks/{importer-C98dpSH4.js → importer-dwoYpSqb.js} +141 -82
  42. package/dist/chunks/importer-dwoYpSqb.js.map +1 -0
  43. package/dist/chunks/index-B9fdNpTA.js +4310 -0
  44. package/dist/chunks/index-B9fdNpTA.js.map +1 -0
  45. package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-C4FwgnH5.js} +123 -32
  46. package/dist/chunks/json-elements-C4FwgnH5.js.map +1 -0
  47. package/dist/chunks/lexicon-B-knUi-l.js +508 -0
  48. package/dist/chunks/lexicon-B-knUi-l.js.map +1 -0
  49. package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-BSpbY5FL.js} +3 -2
  50. package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-BSpbY5FL.js.map} +1 -1
  51. package/dist/chunks/{records-Cu4bxYOm.js → records-Nwz_rbNt.js} +2 -2
  52. package/dist/chunks/{records-Cu4bxYOm.js.map → records-Nwz_rbNt.js.map} +1 -1
  53. package/dist/chunks/styles-Brt9JMfs.js +690 -0
  54. package/dist/chunks/styles-Brt9JMfs.js.map +1 -0
  55. package/dist/chunks/styles-_N-C8S-U.js +2102 -0
  56. package/dist/chunks/styles-_N-C8S-U.js.map +1 -0
  57. package/dist/chunks/styles-yed-DAfcIkf7.js +842 -0
  58. package/dist/chunks/styles-yed-DAfcIkf7.js.map +1 -0
  59. package/dist/chunks/{text-DHOJXnED.js → text-CgzMqHQb.js} +2 -2
  60. package/dist/chunks/{text-DHOJXnED.js.map → text-CgzMqHQb.js.map} +1 -1
  61. package/dist/chunks/units-XMZFIFe1.js +19 -0
  62. package/dist/chunks/units-XMZFIFe1.js.map +1 -0
  63. package/dist/csv.js +5 -4
  64. package/dist/csv.js.map +1 -1
  65. package/dist/cx.js +1 -1
  66. package/dist/cx2.js +2 -2
  67. package/dist/cys.js +1 -1
  68. package/dist/dot.js +5 -2
  69. package/dist/dot.js.map +1 -1
  70. package/dist/gexf.js +292 -412
  71. package/dist/gexf.js.map +1 -1
  72. package/dist/gml.js +8 -3031
  73. package/dist/gml.js.map +1 -1
  74. package/dist/graph-io.js +354 -240
  75. package/dist/graph-io.js.map +1 -1
  76. package/dist/graphml.js +4 -2
  77. package/dist/graphml.js.map +1 -1
  78. package/dist/json.js +1 -1
  79. package/dist/neo4j.js +4 -3
  80. package/dist/neo4j.js.map +1 -1
  81. package/dist/obo.js +1 -1
  82. package/dist/pajek.js +4 -2
  83. package/dist/positions.d.ts +1 -0
  84. package/dist/positions.js +427 -0
  85. package/dist/positions.js.map +1 -0
  86. package/dist/src/common/codes.d.ts +6 -0
  87. package/dist/src/common/codes.d.ts.map +1 -1
  88. package/dist/src/common/codes.js +6 -0
  89. package/dist/src/common/codes.js.map +1 -1
  90. package/dist/src/common/escape.d.ts.map +1 -1
  91. package/dist/src/common/escape.js +4 -2
  92. package/dist/src/common/escape.js.map +1 -1
  93. package/dist/src/common/export.d.ts +10 -0
  94. package/dist/src/common/export.d.ts.map +1 -1
  95. package/dist/src/common/export.js +123 -100
  96. package/dist/src/common/export.js.map +1 -1
  97. package/dist/src/common/input.d.ts.map +1 -1
  98. package/dist/src/common/input.js +8 -1
  99. package/dist/src/common/input.js.map +1 -1
  100. package/dist/src/common/json-elements.d.ts +12 -9
  101. package/dist/src/common/json-elements.d.ts.map +1 -1
  102. package/dist/src/common/json-elements.js +160 -37
  103. package/dist/src/common/json-elements.js.map +1 -1
  104. package/dist/src/common/notes.d.ts +42 -0
  105. package/dist/src/common/notes.d.ts.map +1 -0
  106. package/dist/src/common/notes.js +72 -0
  107. package/dist/src/common/notes.js.map +1 -0
  108. package/dist/src/common/report.d.ts +18 -0
  109. package/dist/src/common/report.d.ts.map +1 -1
  110. package/dist/src/common/report.js +36 -1
  111. package/dist/src/common/report.js.map +1 -1
  112. package/dist/src/common/units.d.ts +24 -0
  113. package/dist/src/common/units.d.ts.map +1 -0
  114. package/dist/src/common/units.js +26 -0
  115. package/dist/src/common/units.js.map +1 -0
  116. package/dist/src/common/xml.d.ts +18 -0
  117. package/dist/src/common/xml.d.ts.map +1 -1
  118. package/dist/src/common/xml.js +42 -5
  119. package/dist/src/common/xml.js.map +1 -1
  120. package/dist/src/formats/cx/exporter.d.ts +6 -0
  121. package/dist/src/formats/cx/exporter.d.ts.map +1 -1
  122. package/dist/src/formats/cx/exporter.js +71 -8
  123. package/dist/src/formats/cx/exporter.js.map +1 -1
  124. package/dist/src/formats/cx/importer.d.ts +5 -2
  125. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cx/importer.js +102 -72
  127. package/dist/src/formats/cx/importer.js.map +1 -1
  128. package/dist/src/formats/cx/styles.d.ts +102 -0
  129. package/dist/src/formats/cx/styles.d.ts.map +1 -0
  130. package/dist/src/formats/cx/styles.js +225 -0
  131. package/dist/src/formats/cx/styles.js.map +1 -0
  132. package/dist/src/formats/cx2/exporter.d.ts +5 -0
  133. package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
  134. package/dist/src/formats/cx2/exporter.js +181 -71
  135. package/dist/src/formats/cx2/exporter.js.map +1 -1
  136. package/dist/src/formats/cx2/importer.d.ts +4 -1
  137. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  138. package/dist/src/formats/cx2/importer.js +19 -1
  139. package/dist/src/formats/cx2/importer.js.map +1 -1
  140. package/dist/src/formats/cx2/styles.d.ts +18 -0
  141. package/dist/src/formats/cx2/styles.d.ts.map +1 -0
  142. package/dist/src/formats/cx2/styles.js +24 -0
  143. package/dist/src/formats/cx2/styles.js.map +1 -0
  144. package/dist/src/formats/cys/constants.d.ts +2 -0
  145. package/dist/src/formats/cys/constants.d.ts.map +1 -1
  146. package/dist/src/formats/cys/constants.js +2 -0
  147. package/dist/src/formats/cys/constants.js.map +1 -1
  148. package/dist/src/formats/cys/exporter.d.ts +6 -2
  149. package/dist/src/formats/cys/exporter.d.ts.map +1 -1
  150. package/dist/src/formats/cys/exporter.js +215 -53
  151. package/dist/src/formats/cys/exporter.js.map +1 -1
  152. package/dist/src/formats/cys/importer.d.ts +2 -1
  153. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  154. package/dist/src/formats/cys/importer.js +119 -6
  155. package/dist/src/formats/cys/importer.js.map +1 -1
  156. package/dist/src/formats/cys/session.d.ts +2 -0
  157. package/dist/src/formats/cys/session.d.ts.map +1 -1
  158. package/dist/src/formats/cys/session.js +5 -0
  159. package/dist/src/formats/cys/session.js.map +1 -1
  160. package/dist/src/formats/cys/styles.d.ts +38 -0
  161. package/dist/src/formats/cys/styles.d.ts.map +1 -0
  162. package/dist/src/formats/cys/styles.js +213 -0
  163. package/dist/src/formats/cys/styles.js.map +1 -0
  164. package/dist/src/formats/cys/tables.d.ts +8 -3
  165. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  166. package/dist/src/formats/cys/tables.js +88 -34
  167. package/dist/src/formats/cys/tables.js.map +1 -1
  168. package/dist/src/formats/dot/exporter.d.ts +2 -0
  169. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  170. package/dist/src/formats/dot/exporter.js +195 -81
  171. package/dist/src/formats/dot/exporter.js.map +1 -1
  172. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  173. package/dist/src/formats/dot/importer.js +100 -20
  174. package/dist/src/formats/dot/importer.js.map +1 -1
  175. package/dist/src/formats/dot/index.d.ts +1 -0
  176. package/dist/src/formats/dot/index.d.ts.map +1 -1
  177. package/dist/src/formats/dot/index.js +1 -0
  178. package/dist/src/formats/dot/index.js.map +1 -1
  179. package/dist/src/formats/dot/positions.d.ts +14 -0
  180. package/dist/src/formats/dot/positions.d.ts.map +1 -0
  181. package/dist/src/formats/dot/positions.js +70 -0
  182. package/dist/src/formats/dot/positions.js.map +1 -0
  183. package/dist/src/formats/dot/styles.d.ts +82 -0
  184. package/dist/src/formats/dot/styles.d.ts.map +1 -0
  185. package/dist/src/formats/dot/styles.js +1484 -0
  186. package/dist/src/formats/dot/styles.js.map +1 -0
  187. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  188. package/dist/src/formats/gexf/exporter.js +20 -5
  189. package/dist/src/formats/gexf/exporter.js.map +1 -1
  190. package/dist/src/formats/gexf/importer.d.ts +8 -1
  191. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  192. package/dist/src/formats/gexf/importer.js +251 -131
  193. package/dist/src/formats/gexf/importer.js.map +1 -1
  194. package/dist/src/formats/gexf/index.d.ts +8 -0
  195. package/dist/src/formats/gexf/index.d.ts.map +1 -1
  196. package/dist/src/formats/gexf/index.js +10 -2
  197. package/dist/src/formats/gexf/index.js.map +1 -1
  198. package/dist/src/formats/gexf/schema.d.ts +5 -0
  199. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  200. package/dist/src/formats/gexf/schema.js +5 -0
  201. package/dist/src/formats/gexf/schema.js.map +1 -1
  202. package/dist/src/formats/gexf/styles.d.ts +74 -0
  203. package/dist/src/formats/gexf/styles.d.ts.map +1 -0
  204. package/dist/src/formats/gexf/styles.js +604 -0
  205. package/dist/src/formats/gexf/styles.js.map +1 -0
  206. package/dist/src/formats/gml/exporter.d.ts +1 -5
  207. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  208. package/dist/src/formats/gml/exporter.js +19 -8
  209. package/dist/src/formats/gml/exporter.js.map +1 -1
  210. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  211. package/dist/src/formats/gml/importer.js +4 -0
  212. package/dist/src/formats/gml/importer.js.map +1 -1
  213. package/dist/src/formats/gml/index.d.ts +2 -1
  214. package/dist/src/formats/gml/index.d.ts.map +1 -1
  215. package/dist/src/formats/gml/index.js +2 -1
  216. package/dist/src/formats/gml/index.js.map +1 -1
  217. package/dist/src/formats/gml/positions.d.ts +14 -0
  218. package/dist/src/formats/gml/positions.d.ts.map +1 -0
  219. package/dist/src/formats/gml/positions.js +46 -0
  220. package/dist/src/formats/gml/positions.js.map +1 -0
  221. package/dist/src/formats/gml/styles.d.ts +59 -0
  222. package/dist/src/formats/gml/styles.d.ts.map +1 -0
  223. package/dist/src/formats/gml/styles.js +1056 -0
  224. package/dist/src/formats/gml/styles.js.map +1 -0
  225. package/dist/src/formats/gml/syntax.d.ts +11 -0
  226. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  227. package/dist/src/formats/gml/syntax.js +151 -62
  228. package/dist/src/formats/gml/syntax.js.map +1 -1
  229. package/dist/src/formats/graphml/constants.d.ts +4 -0
  230. package/dist/src/formats/graphml/constants.d.ts.map +1 -1
  231. package/dist/src/formats/graphml/constants.js +5 -1
  232. package/dist/src/formats/graphml/constants.js.map +1 -1
  233. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  234. package/dist/src/formats/graphml/exporter.js +133 -65
  235. package/dist/src/formats/graphml/exporter.js.map +1 -1
  236. package/dist/src/formats/graphml/importer.d.ts +4 -1
  237. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  238. package/dist/src/formats/graphml/importer.js +100 -44
  239. package/dist/src/formats/graphml/importer.js.map +1 -1
  240. package/dist/src/formats/graphml/index.d.ts +1 -0
  241. package/dist/src/formats/graphml/index.d.ts.map +1 -1
  242. package/dist/src/formats/graphml/index.js +1 -0
  243. package/dist/src/formats/graphml/index.js.map +1 -1
  244. package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
  245. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
  246. package/dist/src/formats/graphml/styles-plain.js +187 -0
  247. package/dist/src/formats/graphml/styles-plain.js.map +1 -0
  248. package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
  249. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
  250. package/dist/src/formats/graphml/styles-yed.js +1086 -0
  251. package/dist/src/formats/graphml/styles-yed.js.map +1 -0
  252. package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
  253. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
  254. package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
  255. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
  256. package/dist/src/formats/graphml/tree.d.ts.map +1 -1
  257. package/dist/src/formats/graphml/tree.js +34 -19
  258. package/dist/src/formats/graphml/tree.js.map +1 -1
  259. package/dist/src/formats/graphml/yfiles.d.ts +16 -2
  260. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  261. package/dist/src/formats/graphml/yfiles.js +83 -12
  262. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  263. package/dist/src/formats/json/exporter.d.ts +5 -0
  264. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  265. package/dist/src/formats/json/exporter.js +68 -25
  266. package/dist/src/formats/json/exporter.js.map +1 -1
  267. package/dist/src/formats/json/importer.d.ts +22 -3
  268. package/dist/src/formats/json/importer.d.ts.map +1 -1
  269. package/dist/src/formats/json/importer.js +439 -264
  270. package/dist/src/formats/json/importer.js.map +1 -1
  271. package/dist/src/formats/json/positions.d.ts +16 -0
  272. package/dist/src/formats/json/positions.d.ts.map +1 -0
  273. package/dist/src/formats/json/positions.js +44 -0
  274. package/dist/src/formats/json/positions.js.map +1 -0
  275. package/dist/src/formats/json/styles.d.ts +102 -0
  276. package/dist/src/formats/json/styles.d.ts.map +1 -0
  277. package/dist/src/formats/json/styles.js +1753 -0
  278. package/dist/src/formats/json/styles.js.map +1 -0
  279. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  280. package/dist/src/formats/neo4j/exporter.js +2 -1
  281. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  282. package/dist/src/formats/pajek/exporter.d.ts +2 -0
  283. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  284. package/dist/src/formats/pajek/exporter.js +142 -76
  285. package/dist/src/formats/pajek/exporter.js.map +1 -1
  286. package/dist/src/formats/pajek/importer.d.ts +4 -0
  287. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  288. package/dist/src/formats/pajek/importer.js +60 -6
  289. package/dist/src/formats/pajek/importer.js.map +1 -1
  290. package/dist/src/formats/pajek/index.d.ts +2 -0
  291. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  292. package/dist/src/formats/pajek/index.js +2 -0
  293. package/dist/src/formats/pajek/index.js.map +1 -1
  294. package/dist/src/formats/pajek/styles.d.ts +50 -0
  295. package/dist/src/formats/pajek/styles.d.ts.map +1 -0
  296. package/dist/src/formats/pajek/styles.js +569 -0
  297. package/dist/src/formats/pajek/styles.js.map +1 -0
  298. package/dist/src/formats/pajek/syntax.d.ts +6 -0
  299. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  300. package/dist/src/formats/pajek/syntax.js +6 -0
  301. package/dist/src/formats/pajek/syntax.js.map +1 -1
  302. package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
  303. package/dist/src/formats/xgmml/columns.js +34 -9
  304. package/dist/src/formats/xgmml/columns.js.map +1 -1
  305. package/dist/src/formats/xgmml/constants.d.ts +2 -0
  306. package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
  307. package/dist/src/formats/xgmml/constants.js +3 -1
  308. package/dist/src/formats/xgmml/constants.js.map +1 -1
  309. package/dist/src/formats/xgmml/document.d.ts +12 -8
  310. package/dist/src/formats/xgmml/document.d.ts.map +1 -1
  311. package/dist/src/formats/xgmml/document.js +56 -13
  312. package/dist/src/formats/xgmml/document.js.map +1 -1
  313. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  314. package/dist/src/formats/xgmml/emit.js +12 -6
  315. package/dist/src/formats/xgmml/emit.js.map +1 -1
  316. package/dist/src/formats/xgmml/exporter.d.ts +3 -1
  317. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  318. package/dist/src/formats/xgmml/exporter.js +22 -9
  319. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  320. package/dist/src/formats/xgmml/importer.d.ts +2 -1
  321. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  322. package/dist/src/formats/xgmml/importer.js +31 -24
  323. package/dist/src/formats/xgmml/importer.js.map +1 -1
  324. package/dist/src/formats/xgmml/styles.d.ts +104 -0
  325. package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
  326. package/dist/src/formats/xgmml/styles.js +310 -0
  327. package/dist/src/formats/xgmml/styles.js.map +1 -0
  328. package/dist/src/index.d.ts +9 -7
  329. package/dist/src/index.d.ts.map +1 -1
  330. package/dist/src/index.js +7 -7
  331. package/dist/src/index.js.map +1 -1
  332. package/dist/src/positions/codes.d.ts +31 -0
  333. package/dist/src/positions/codes.d.ts.map +1 -0
  334. package/dist/src/positions/codes.js +26 -0
  335. package/dist/src/positions/codes.js.map +1 -0
  336. package/dist/src/positions/convert.d.ts +58 -0
  337. package/dist/src/positions/convert.d.ts.map +1 -0
  338. package/dist/src/positions/convert.js +107 -0
  339. package/dist/src/positions/convert.js.map +1 -0
  340. package/dist/src/positions/extract.d.ts +27 -0
  341. package/dist/src/positions/extract.d.ts.map +1 -0
  342. package/dist/src/positions/extract.js +526 -0
  343. package/dist/src/positions/extract.js.map +1 -0
  344. package/dist/src/positions/index.d.ts +10 -0
  345. package/dist/src/positions/index.d.ts.map +1 -0
  346. package/dist/src/positions/index.js +9 -0
  347. package/dist/src/positions/index.js.map +1 -0
  348. package/dist/src/positions/types.d.ts +208 -0
  349. package/dist/src/positions/types.d.ts.map +1 -0
  350. package/dist/src/positions/types.js +10 -0
  351. package/dist/src/positions/types.js.map +1 -0
  352. package/dist/src/registry.d.ts +30 -0
  353. package/dist/src/registry.d.ts.map +1 -1
  354. package/dist/src/registry.js +130 -9
  355. package/dist/src/registry.js.map +1 -1
  356. package/dist/src/styles/annotations.d.ts +132 -0
  357. package/dist/src/styles/annotations.d.ts.map +1 -0
  358. package/dist/src/styles/annotations.js +320 -0
  359. package/dist/src/styles/annotations.js.map +1 -0
  360. package/dist/src/styles/budget.d.ts +45 -0
  361. package/dist/src/styles/budget.d.ts.map +1 -0
  362. package/dist/src/styles/budget.js +58 -0
  363. package/dist/src/styles/budget.js.map +1 -0
  364. package/dist/src/styles/canon/bends.d.ts +32 -0
  365. package/dist/src/styles/canon/bends.d.ts.map +1 -0
  366. package/dist/src/styles/canon/bends.js +74 -0
  367. package/dist/src/styles/canon/bends.js.map +1 -0
  368. package/dist/src/styles/canon/color-tables.d.ts +22 -0
  369. package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
  370. package/dist/src/styles/canon/color-tables.js +369 -0
  371. package/dist/src/styles/canon/color-tables.js.map +1 -0
  372. package/dist/src/styles/canon/color.d.ts +66 -0
  373. package/dist/src/styles/canon/color.d.ts.map +1 -0
  374. package/dist/src/styles/canon/color.js +548 -0
  375. package/dist/src/styles/canon/color.js.map +1 -0
  376. package/dist/src/styles/canon/enums.d.ts +25 -0
  377. package/dist/src/styles/canon/enums.d.ts.map +1 -0
  378. package/dist/src/styles/canon/enums.js +187 -0
  379. package/dist/src/styles/canon/enums.js.map +1 -0
  380. package/dist/src/styles/canon/graphviz.d.ts +48 -0
  381. package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
  382. package/dist/src/styles/canon/graphviz.js +160 -0
  383. package/dist/src/styles/canon/graphviz.js.map +1 -0
  384. package/dist/src/styles/canon/index.d.ts +13 -0
  385. package/dist/src/styles/canon/index.d.ts.map +1 -0
  386. package/dist/src/styles/canon/index.js +13 -0
  387. package/dist/src/styles/canon/index.js.map +1 -0
  388. package/dist/src/styles/canon/number.d.ts +59 -0
  389. package/dist/src/styles/canon/number.d.ts.map +1 -0
  390. package/dist/src/styles/canon/number.js +142 -0
  391. package/dist/src/styles/canon/number.js.map +1 -0
  392. package/dist/src/styles/canon/site.d.ts +51 -0
  393. package/dist/src/styles/canon/site.d.ts.map +1 -0
  394. package/dist/src/styles/canon/site.js +63 -0
  395. package/dist/src/styles/canon/site.js.map +1 -0
  396. package/dist/src/styles/canon/text.d.ts +61 -0
  397. package/dist/src/styles/canon/text.d.ts.map +1 -0
  398. package/dist/src/styles/canon/text.js +199 -0
  399. package/dist/src/styles/canon/text.js.map +1 -0
  400. package/dist/src/styles/codes.d.ts +95 -0
  401. package/dist/src/styles/codes.d.ts.map +1 -0
  402. package/dist/src/styles/codes.js +97 -0
  403. package/dist/src/styles/codes.js.map +1 -0
  404. package/dist/src/styles/cyjs/cascade.d.ts +134 -0
  405. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
  406. package/dist/src/styles/cyjs/cascade.js +2252 -0
  407. package/dist/src/styles/cyjs/cascade.js.map +1 -0
  408. package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
  409. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
  410. package/dist/src/styles/cyjs/defaults-table.js +76 -0
  411. package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
  412. package/dist/src/styles/cyjs/emit.d.ts +82 -0
  413. package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
  414. package/dist/src/styles/cyjs/emit.js +790 -0
  415. package/dist/src/styles/cyjs/emit.js.map +1 -0
  416. package/dist/src/styles/cyjs/index.d.ts +13 -0
  417. package/dist/src/styles/cyjs/index.d.ts.map +1 -0
  418. package/dist/src/styles/cyjs/index.js +13 -0
  419. package/dist/src/styles/cyjs/index.js.map +1 -0
  420. package/dist/src/styles/cyjs/live.d.ts +46 -0
  421. package/dist/src/styles/cyjs/live.d.ts.map +1 -0
  422. package/dist/src/styles/cyjs/live.js +108 -0
  423. package/dist/src/styles/cyjs/live.js.map +1 -0
  424. package/dist/src/styles/cyjs/mappers.d.ts +147 -0
  425. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
  426. package/dist/src/styles/cyjs/mappers.js +744 -0
  427. package/dist/src/styles/cyjs/mappers.js.map +1 -0
  428. package/dist/src/styles/cyjs/selector.d.ts +113 -0
  429. package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
  430. package/dist/src/styles/cyjs/selector.js +611 -0
  431. package/dist/src/styles/cyjs/selector.js.map +1 -0
  432. package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
  433. package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
  434. package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
  435. package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
  436. package/dist/src/styles/cytoscape/emit.d.ts +125 -0
  437. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
  438. package/dist/src/styles/cytoscape/emit.js +1025 -0
  439. package/dist/src/styles/cytoscape/emit.js.map +1 -0
  440. package/dist/src/styles/cytoscape/index.d.ts +10 -0
  441. package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
  442. package/dist/src/styles/cytoscape/index.js +10 -0
  443. package/dist/src/styles/cytoscape/index.js.map +1 -0
  444. package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
  445. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
  446. package/dist/src/styles/cytoscape/lexicon.js +603 -0
  447. package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
  448. package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
  449. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
  450. package/dist/src/styles/cytoscape/mappings.js +460 -0
  451. package/dist/src/styles/cytoscape/mappings.js.map +1 -0
  452. package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
  453. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
  454. package/dist/src/styles/cytoscape/resolve.js +381 -0
  455. package/dist/src/styles/cytoscape/resolve.js.map +1 -0
  456. package/dist/src/styles/cytoscape/translate.d.ts +50 -0
  457. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
  458. package/dist/src/styles/cytoscape/translate.js +156 -0
  459. package/dist/src/styles/cytoscape/translate.js.map +1 -0
  460. package/dist/src/styles/defaults.d.ts +90 -0
  461. package/dist/src/styles/defaults.d.ts.map +1 -0
  462. package/dist/src/styles/defaults.js +414 -0
  463. package/dist/src/styles/defaults.js.map +1 -0
  464. package/dist/src/styles/index.d.ts +15 -0
  465. package/dist/src/styles/index.d.ts.map +1 -0
  466. package/dist/src/styles/index.js +14 -0
  467. package/dist/src/styles/index.js.map +1 -0
  468. package/dist/src/styles/internal.d.ts +17 -0
  469. package/dist/src/styles/internal.d.ts.map +1 -0
  470. package/dist/src/styles/internal.js +16 -0
  471. package/dist/src/styles/internal.js.map +1 -0
  472. package/dist/src/styles/io/approximations.d.ts +24 -0
  473. package/dist/src/styles/io/approximations.d.ts.map +1 -0
  474. package/dist/src/styles/io/approximations.js +51 -0
  475. package/dist/src/styles/io/approximations.js.map +1 -0
  476. package/dist/src/styles/io/block.d.ts +166 -0
  477. package/dist/src/styles/io/block.d.ts.map +1 -0
  478. package/dist/src/styles/io/block.js +930 -0
  479. package/dist/src/styles/io/block.js.map +1 -0
  480. package/dist/src/styles/io/generic.d.ts +88 -0
  481. package/dist/src/styles/io/generic.d.ts.map +1 -0
  482. package/dist/src/styles/io/generic.js +516 -0
  483. package/dist/src/styles/io/generic.js.map +1 -0
  484. package/dist/src/styles/io/index.d.ts +8 -0
  485. package/dist/src/styles/io/index.d.ts.map +1 -0
  486. package/dist/src/styles/io/index.js +7 -0
  487. package/dist/src/styles/io/index.js.map +1 -0
  488. package/dist/src/styles/io/writer.d.ts +80 -0
  489. package/dist/src/styles/io/writer.d.ts.map +1 -0
  490. package/dist/src/styles/io/writer.js +596 -0
  491. package/dist/src/styles/io/writer.js.map +1 -0
  492. package/dist/src/styles/notes.d.ts +47 -0
  493. package/dist/src/styles/notes.d.ts.map +1 -0
  494. package/dist/src/styles/notes.js +140 -0
  495. package/dist/src/styles/notes.js.map +1 -0
  496. package/dist/src/styles/plan/classes.d.ts +31 -0
  497. package/dist/src/styles/plan/classes.d.ts.map +1 -0
  498. package/dist/src/styles/plan/classes.js +139 -0
  499. package/dist/src/styles/plan/classes.js.map +1 -0
  500. package/dist/src/styles/plan/continuous.d.ts +32 -0
  501. package/dist/src/styles/plan/continuous.d.ts.map +1 -0
  502. package/dist/src/styles/plan/continuous.js +165 -0
  503. package/dist/src/styles/plan/continuous.js.map +1 -0
  504. package/dist/src/styles/plan/discrete.d.ts +39 -0
  505. package/dist/src/styles/plan/discrete.d.ts.map +1 -0
  506. package/dist/src/styles/plan/discrete.js +127 -0
  507. package/dist/src/styles/plan/discrete.js.map +1 -0
  508. package/dist/src/styles/plan/families.d.ts +31 -0
  509. package/dist/src/styles/plan/families.d.ts.map +1 -0
  510. package/dist/src/styles/plan/families.js +95 -0
  511. package/dist/src/styles/plan/families.js.map +1 -0
  512. package/dist/src/styles/plan/features.d.ts +58 -0
  513. package/dist/src/styles/plan/features.d.ts.map +1 -0
  514. package/dist/src/styles/plan/features.js +185 -0
  515. package/dist/src/styles/plan/features.js.map +1 -0
  516. package/dist/src/styles/plan/index.d.ts +7 -0
  517. package/dist/src/styles/plan/index.d.ts.map +1 -0
  518. package/dist/src/styles/plan/index.js +7 -0
  519. package/dist/src/styles/plan/index.js.map +1 -0
  520. package/dist/src/styles/plan/plan.d.ts +71 -0
  521. package/dist/src/styles/plan/plan.d.ts.map +1 -0
  522. package/dist/src/styles/plan/plan.js +893 -0
  523. package/dist/src/styles/plan/plan.js.map +1 -0
  524. package/dist/src/styles/plan/resolve.d.ts +137 -0
  525. package/dist/src/styles/plan/resolve.d.ts.map +1 -0
  526. package/dist/src/styles/plan/resolve.js +587 -0
  527. package/dist/src/styles/plan/resolve.js.map +1 -0
  528. package/dist/src/styles/types.d.ts +702 -0
  529. package/dist/src/styles/types.d.ts.map +1 -0
  530. package/dist/src/styles/types.js +10 -0
  531. package/dist/src/styles/types.js.map +1 -0
  532. package/dist/src/styles/vocabulary.d.ts +41 -0
  533. package/dist/src/styles/vocabulary.d.ts.map +1 -0
  534. package/dist/src/styles/vocabulary.js +140 -0
  535. package/dist/src/styles/vocabulary.js.map +1 -0
  536. package/dist/src/types.d.ts +64 -1
  537. package/dist/src/types.d.ts.map +1 -1
  538. package/dist/src/types.js.map +1 -1
  539. package/dist/styles.d.ts +1 -0
  540. package/dist/styles.js +322 -0
  541. package/dist/styles.js.map +1 -0
  542. package/dist/xgmml.js +5 -4
  543. package/dist/xgmml.js.map +1 -1
  544. package/package.json +13 -2
  545. package/src/common/codes.ts +7 -0
  546. package/src/common/escape.ts +5 -2
  547. package/src/common/export.ts +179 -140
  548. package/src/common/input.ts +8 -4
  549. package/src/common/json-elements.ts +169 -38
  550. package/src/common/notes.ts +94 -0
  551. package/src/common/report.ts +41 -1
  552. package/src/common/units.ts +42 -0
  553. package/src/common/xml.ts +45 -5
  554. package/src/formats/cx/exporter.ts +95 -11
  555. package/src/formats/cx/importer.ts +126 -90
  556. package/src/formats/cx/styles.ts +304 -0
  557. package/src/formats/cx2/exporter.ts +234 -77
  558. package/src/formats/cx2/importer.ts +19 -1
  559. package/src/formats/cx2/styles.ts +29 -0
  560. package/src/formats/cys/constants.ts +3 -0
  561. package/src/formats/cys/exporter.ts +246 -60
  562. package/src/formats/cys/importer.ts +125 -9
  563. package/src/formats/cys/session.ts +6 -0
  564. package/src/formats/cys/styles.ts +254 -0
  565. package/src/formats/cys/tables.ts +117 -48
  566. package/src/formats/dot/exporter.ts +262 -126
  567. package/src/formats/dot/importer.ts +111 -20
  568. package/src/formats/dot/index.ts +1 -0
  569. package/src/formats/dot/positions.ts +77 -0
  570. package/src/formats/dot/styles.ts +1741 -0
  571. package/src/formats/gexf/exporter.ts +27 -11
  572. package/src/formats/gexf/importer.ts +308 -158
  573. package/src/formats/gexf/index.ts +10 -0
  574. package/src/formats/gexf/schema.ts +5 -0
  575. package/src/formats/gexf/styles.ts +719 -0
  576. package/src/formats/gml/exporter.ts +33 -14
  577. package/src/formats/gml/importer.ts +4 -0
  578. package/src/formats/gml/index.ts +2 -1
  579. package/src/formats/gml/positions.ts +52 -0
  580. package/src/formats/gml/styles.ts +1248 -0
  581. package/src/formats/gml/syntax.ts +173 -62
  582. package/src/formats/graphml/constants.ts +5 -0
  583. package/src/formats/graphml/exporter.ts +163 -71
  584. package/src/formats/graphml/importer.ts +119 -45
  585. package/src/formats/graphml/index.ts +1 -0
  586. package/src/formats/graphml/styles-plain.ts +236 -0
  587. package/src/formats/graphml/styles-yed.ts +1221 -0
  588. package/src/formats/graphml/styles-yfiles3.ts +573 -0
  589. package/src/formats/graphml/tree.ts +36 -20
  590. package/src/formats/graphml/yfiles.ts +89 -13
  591. package/src/formats/json/exporter.ts +76 -26
  592. package/src/formats/json/importer.ts +541 -322
  593. package/src/formats/json/positions.ts +50 -0
  594. package/src/formats/json/styles.ts +2082 -0
  595. package/src/formats/neo4j/exporter.ts +2 -1
  596. package/src/formats/pajek/exporter.ts +195 -106
  597. package/src/formats/pajek/importer.ts +78 -9
  598. package/src/formats/pajek/index.ts +2 -0
  599. package/src/formats/pajek/styles.ts +685 -0
  600. package/src/formats/pajek/syntax.ts +7 -0
  601. package/src/formats/xgmml/columns.ts +39 -9
  602. package/src/formats/xgmml/constants.ts +3 -0
  603. package/src/formats/xgmml/document.ts +54 -12
  604. package/src/formats/xgmml/emit.ts +11 -6
  605. package/src/formats/xgmml/exporter.ts +32 -13
  606. package/src/formats/xgmml/importer.ts +43 -29
  607. package/src/formats/xgmml/styles.ts +400 -0
  608. package/src/index.ts +16 -0
  609. package/src/positions/codes.ts +32 -0
  610. package/src/positions/convert.ts +123 -0
  611. package/src/positions/extract.ts +619 -0
  612. package/src/positions/index.ts +23 -0
  613. package/src/positions/types.ts +221 -0
  614. package/src/registry.ts +179 -8
  615. package/src/styles/annotations.ts +478 -0
  616. package/src/styles/budget.ts +60 -0
  617. package/src/styles/canon/bends.ts +84 -0
  618. package/src/styles/canon/color-tables.ts +386 -0
  619. package/src/styles/canon/color.ts +624 -0
  620. package/src/styles/canon/enums.ts +211 -0
  621. package/src/styles/canon/graphviz.ts +189 -0
  622. package/src/styles/canon/index.ts +13 -0
  623. package/src/styles/canon/number.ts +152 -0
  624. package/src/styles/canon/site.ts +87 -0
  625. package/src/styles/canon/text.ts +221 -0
  626. package/src/styles/codes.ts +104 -0
  627. package/src/styles/cyjs/cascade.ts +2670 -0
  628. package/src/styles/cyjs/defaults-table.ts +82 -0
  629. package/src/styles/cyjs/emit.ts +951 -0
  630. package/src/styles/cyjs/index.ts +37 -0
  631. package/src/styles/cyjs/live.ts +147 -0
  632. package/src/styles/cyjs/mappers.ts +879 -0
  633. package/src/styles/cyjs/selector.ts +778 -0
  634. package/src/styles/cyjs/stylesheet-text.ts +214 -0
  635. package/src/styles/cytoscape/emit.ts +1264 -0
  636. package/src/styles/cytoscape/index.ts +40 -0
  637. package/src/styles/cytoscape/lexicon.ts +656 -0
  638. package/src/styles/cytoscape/mappings.ts +603 -0
  639. package/src/styles/cytoscape/resolve.ts +521 -0
  640. package/src/styles/cytoscape/translate.ts +237 -0
  641. package/src/styles/defaults.ts +504 -0
  642. package/src/styles/index.ts +57 -0
  643. package/src/styles/internal.ts +17 -0
  644. package/src/styles/io/approximations.ts +47 -0
  645. package/src/styles/io/block.ts +1138 -0
  646. package/src/styles/io/generic.ts +687 -0
  647. package/src/styles/io/index.ts +18 -0
  648. package/src/styles/io/writer.ts +745 -0
  649. package/src/styles/notes.ts +165 -0
  650. package/src/styles/plan/classes.ts +166 -0
  651. package/src/styles/plan/continuous.ts +218 -0
  652. package/src/styles/plan/discrete.ts +165 -0
  653. package/src/styles/plan/families.ts +115 -0
  654. package/src/styles/plan/features.ts +234 -0
  655. package/src/styles/plan/index.ts +7 -0
  656. package/src/styles/plan/plan.ts +1129 -0
  657. package/src/styles/plan/resolve.ts +685 -0
  658. package/src/styles/types.ts +814 -0
  659. package/src/styles/vocabulary.ts +172 -0
  660. package/src/types.ts +76 -1
  661. package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
  662. package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
  663. package/dist/chunks/export-rKLeGQMo.js.map +0 -1
  664. package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
  665. package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
  666. package/dist/chunks/exporter-RVtXVetw.js.map +0 -1
  667. package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
  668. package/dist/chunks/importer-C98dpSH4.js.map +0 -1
  669. package/dist/chunks/importer-D794XUTe.js.map +0 -1
  670. package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
  671. package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
  672. package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
  673. package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
  674. package/dist/chunks/json-elements-DKSqpNW1.js.map +0 -1
@@ -0,0 +1,619 @@
1
+ /**
2
+ * `extractPositions()`: any format's stored node coordinates in the neutral convention (center,
3
+ * y up, the file's unit, 3 components). The snapshot's role-`position` column keeps the values the
4
+ * file wrote; this reads them through the spelling the column's `meta.extra` (or the importer's
5
+ * `positions()` hook) declares.
6
+ */
7
+
8
+ import type { Column, GraphSnapshot } from "@graphty/graph-format";
9
+
10
+ import { NoteCollector } from "../common/notes.js";
11
+ import { type GraphTool, toolOf } from "../common/units.js";
12
+ import type { GraphImporter, ImportReport } from "../types.js";
13
+ import { POSITION_ISSUE, type PositionNoteCode } from "./codes.js";
14
+ import { median, toNeutral } from "./convert.js";
15
+ import type {
16
+ ExtractPositionsOptions,
17
+ FilePositionGroup,
18
+ FilePositions,
19
+ ImporterGroupBox,
20
+ ImporterPositions,
21
+ PositionColumnExtra,
22
+ PositionNote,
23
+ } from "./types.js";
24
+
25
+ type Point = [number, number, number];
26
+
27
+ /** Reads one row's raw coordinates into `out`; false when the row has none. */
28
+ type RowReader = (row: number, out: Point) => boolean;
29
+
30
+ /** Reads one row's width and height; null when the row has no size. */
31
+ type SizeReader = (row: number) => readonly [number, number] | null;
32
+
33
+ /** Where a file's coordinates are and how they are spelled. */
34
+ interface Spelling {
35
+ readonly read: RowReader;
36
+ /** Reads a row's width and height from the size columns the spelling names; null without both. */
37
+ readonly size: SizeReader;
38
+ readonly extra: PositionColumnExtra;
39
+ readonly groups: readonly ImporterGroupBox[];
40
+ readonly medianNodeSize: number | null | undefined;
41
+ readonly tool: GraphTool | null | undefined;
42
+ }
43
+
44
+ /** Report codes of format readers that mean the file mixes 2- and 3-coordinate positions. */
45
+ const DIMS_MIXED_CODES: ReadonlySet<string> = new Set(["W_PAJEK_COORD_DIMS", "W_DOT_POS_DIMS"]);
46
+
47
+ /** graph-io's English for each note, for its own logs only. */
48
+ const PHRASES: Readonly<Record<PositionNoteCode, string>> = {
49
+ W_POSITION_STACKED: "every placed node is on one point; the positions were dropped",
50
+ W_POSITION_PARTIAL: "nodes have no position",
51
+ W_POSITION_NON_FINITE: "positions are not finite numbers",
52
+ W_POSITION_DIMS_MIXED: "positions mix 2 and 3 coordinates",
53
+ W_POSITION_ANCHOR_NO_SIZE: "top-left positions have no size and were not moved to the center",
54
+ W_POSITION_OTHER_VIEWS: "other views were not used",
55
+ W_POSITIONS_NOT_READ: "position-like columns this format does not read",
56
+ };
57
+
58
+ /**
59
+ * A file's stored node coordinates in the neutral convention: each node's center, y up, in the
60
+ * file's own unit. Call it with the importer that read the snapshot and the report it returned.
61
+ * @example
62
+ * ```ts
63
+ * const { snapshot, report } = await importGraph(text, { format: "gml" });
64
+ * const positions = extractPositions(gmlImporter, snapshot, report);
65
+ * if (positions?.usable) console.log(positions.coords.subarray(0, 3)); // node 0's x, y, z
66
+ * ```
67
+ * @param importer - the importer that read the snapshot (its `positions()` hook, when it has one, says how the coordinates are spelled)
68
+ * @param snapshot - the imported graph
69
+ * @param report - the import's report
70
+ * @param options - `signal` to abort
71
+ * @returns the positions, or null when the file stores none and has no position-like columns
72
+ * @category Positions
73
+ */
74
+ export function extractPositions(
75
+ importer: GraphImporter,
76
+ snapshot: GraphSnapshot,
77
+ report: ImportReport,
78
+ options: ExtractPositionsOptions = {},
79
+ ): FilePositions | null {
80
+ const signal = options.signal ?? null;
81
+ signal?.throwIfAborted();
82
+ const notes = new NoteCollector<PositionNoteCode>();
83
+ const spelling = spellingOf(importer, snapshot, signal);
84
+ if (spelling === null) {
85
+ noteUnread(snapshot, notes);
86
+ return notes.list().length === 0 ? null : emptyPositions(importer, snapshot, notes);
87
+ }
88
+ const n = snapshot.nodeCount;
89
+ const coords = readRows(n, spelling, notes);
90
+ signal?.throwIfAborted();
91
+ const containers = containersOf(snapshot);
92
+ const groups = applyGroups(spelling, coords);
93
+ collectGroups(spelling, coords, containers, groups);
94
+ const { placed, total } = countPlaced(coords, containers, notes);
95
+ const stacked = dropStacked(coords, placed, notes);
96
+ noteReport(report, notes);
97
+ noteOtherViews(snapshot, notes);
98
+ return {
99
+ version: 1,
100
+ source: {
101
+ format: importer.format,
102
+ tool: spelling.tool ?? toolOf(snapshot.meta.creator),
103
+ yAxis: spelling.extra.yAxis ?? "up",
104
+ },
105
+ units: spelling.extra.units ?? "file",
106
+ ...(spelling.extra.pxPerUnit === undefined ? {} : { pxPerUnit: spelling.extra.pxPerUnit }),
107
+ medianNodeSize: spelling.medianNodeSize ?? medianSize(spelling.size, n, containers),
108
+ dims: coords.realZ ? 3 : 2,
109
+ coords: coords.values,
110
+ placed: stacked ? 0 : placed,
111
+ total,
112
+ usable: !stacked && placed > 0,
113
+ bounds: stacked ? null : boundsOf(coords.values),
114
+ groups,
115
+ notes: noteList(notes),
116
+ };
117
+ }
118
+
119
+ // ------------------------------------------------------------ spelling
120
+
121
+ /**
122
+ * Where the coordinates are: the importer's hook wins over the column's `meta.extra`.
123
+ * @param importer - the importer
124
+ * @param snapshot - the graph
125
+ * @param signal - the abort signal
126
+ * @returns the spelling, or null when the file stores no coordinates
127
+ */
128
+ function spellingOf(importer: GraphImporter, snapshot: GraphSnapshot, signal: AbortSignal | null): Spelling | null {
129
+ const hook = importer.positions?.(snapshot, { signal }) ?? null;
130
+ if (hook?.x !== undefined && hook.y !== undefined) {
131
+ return plainSpelling(snapshot, hook);
132
+ }
133
+ const column = hook?.column === undefined ? snapshot.nodes.byRole("position") : snapshot.nodes.get(hook.column);
134
+ if (column === null || column.meta.components < 2) {
135
+ return null;
136
+ }
137
+ const extra = { ...extraOf(column.meta.extra), ...extraOf(hook ?? {}) };
138
+ return { read: vectorReader(column), size: sizeReader(snapshot, extra), extra, ...hookFields(hook) };
139
+ }
140
+
141
+ /**
142
+ * The spelling of the simple hook form: plain x / y (/ z) columns.
143
+ * @param snapshot - the graph
144
+ * @param hook - the hook's answer
145
+ * @returns the spelling, or null when a named column is missing
146
+ */
147
+ function plainSpelling(snapshot: GraphSnapshot, hook: ImporterPositions): Spelling | null {
148
+ const x = snapshot.nodes.get(hook.x ?? "");
149
+ const y = snapshot.nodes.get(hook.y ?? "");
150
+ const z = hook.z === undefined ? null : snapshot.nodes.get(hook.z);
151
+ if (x === null || y === null) {
152
+ return null;
153
+ }
154
+ const read: RowReader = (row, out) => {
155
+ if (!x.isSet(row) || !y.isSet(row)) {
156
+ return false;
157
+ }
158
+ out[0] = Number(x.value(row));
159
+ out[1] = Number(y.value(row));
160
+ out[2] = z?.isSet(row) === true ? Number(z.value(row)) : 0;
161
+ return true;
162
+ };
163
+ const extra = { ...extraOf(hook), sourceDims: z === null ? 2 : 3 } as const;
164
+ return { read, size: sizeReader(snapshot, extra), extra, ...hookFields(hook) };
165
+ }
166
+
167
+ /**
168
+ * The hook's fields beside the spelling.
169
+ * @param hook - the hook's answer, or null
170
+ * @returns groups, median node size and tool
171
+ */
172
+ function hookFields(hook: ImporterPositions | null): Pick<Spelling, "groups" | "medianNodeSize" | "tool"> {
173
+ return { groups: hook?.groups ?? [], medianNodeSize: hook?.medianNodeSize, tool: hook?.tool };
174
+ }
175
+
176
+ /**
177
+ * A reader over a 2- or 3-component column.
178
+ * @param column - the column
179
+ * @returns the reader
180
+ */
181
+ function vectorReader(column: Column): RowReader {
182
+ return (row, out) => {
183
+ if (!column.isSet(row)) {
184
+ return false;
185
+ }
186
+ const v = column.value(row) as ArrayLike<number>;
187
+ out[0] = v[0];
188
+ out[1] = v[1];
189
+ out[2] = v.length > 2 ? v[2] : 0;
190
+ return true;
191
+ };
192
+ }
193
+
194
+ /**
195
+ * The spelling fields of an extra (or a hook's answer), each kept only when well formed.
196
+ * @param source - a column's meta.extra or a hook's answer
197
+ * @returns the fields
198
+ */
199
+ function extraOf(source: object): PositionColumnExtra {
200
+ const extra = source as Readonly<Record<string, unknown>>;
201
+ const out: Record<string, unknown> = {};
202
+ const pick = (key: keyof PositionColumnExtra, ok: (v: unknown) => boolean): void => {
203
+ if (ok(extra[key])) {
204
+ out[key] = extra[key];
205
+ }
206
+ };
207
+ pick("units", (v) => v === "px" || v === "file");
208
+ pick("sourceDims", (v) => v === 2 || v === 3);
209
+ pick("yAxis", (v) => v === "up" || v === "down");
210
+ pick("anchor", (v) => v === "center" || v === "top-left");
211
+ pick("width", (v) => typeof v === "string");
212
+ pick("height", (v) => typeof v === "string");
213
+ pick("pxPerUnit", (v) => typeof v === "number" && Number.isFinite(v) && v > 0);
214
+ pick("zOrigin", (v) => typeof v === "number" && Number.isFinite(v));
215
+ pick("zeroUnplaced", (v) => typeof v === "boolean");
216
+ return out;
217
+ }
218
+
219
+ // ------------------------------------------------------------ rows
220
+
221
+ /** Coordinates by node index, with whether the file has a z that differs between nodes. */
222
+ interface Rows {
223
+ readonly values: Float64Array;
224
+ readonly realZ: boolean;
225
+ }
226
+
227
+ /**
228
+ * Read every row and convert it to the neutral convention.
229
+ * @param n - the node count
230
+ * @param spelling - how the coordinates are spelled
231
+ * @param notes - receives non-finite and anchor notes
232
+ * @returns the coordinates (NaN rows have none)
233
+ */
234
+ function readRows(n: number, spelling: Spelling, notes: NoteCollector<PositionNoteCode>): Rows {
235
+ const values = new Float64Array(3 * n).fill(Number.NaN);
236
+ const p: Point = [0, 0, 0];
237
+ for (let row = 0; row < n; row++) {
238
+ if (!spelling.read(row, p)) {
239
+ continue;
240
+ }
241
+ if (Number.isFinite(p[0]) && Number.isFinite(p[1]) && Number.isFinite(p[2])) {
242
+ values.set(p, 3 * row);
243
+ } else {
244
+ notes.add(POSITION_ISSUE.NON_FINITE, { element: row, sample: p.join(",") });
245
+ }
246
+ }
247
+ if (spelling.extra.zeroUnplaced === true) {
248
+ dropZeroPile(values);
249
+ }
250
+ const realZ = spelling.extra.sourceDims === 3 && !constantZ(values);
251
+ convertRows(values, spelling.extra, spelling.size, realZ, notes);
252
+ return { values, realZ };
253
+ }
254
+
255
+ /**
256
+ * Convert every placed row in place.
257
+ * @param values - the raw coordinates
258
+ * @param extra - the spelling
259
+ * @param size - reads a row's width and height
260
+ * @param realZ - whether z differs between nodes
261
+ * @param notes - receives the anchor note
262
+ */
263
+ function convertRows(
264
+ values: Float64Array,
265
+ extra: PositionColumnExtra,
266
+ size: SizeReader,
267
+ realZ: boolean,
268
+ notes: NoteCollector<PositionNoteCode>,
269
+ ): void {
270
+ const p: Point = [0, 0, 0];
271
+ for (let i = 0; i < values.length; i += 3) {
272
+ if (Number.isNaN(values[i])) {
273
+ continue;
274
+ }
275
+ const s = extra.anchor === "top-left" ? size(i / 3) : null;
276
+ if (extra.anchor === "top-left" && s === null) {
277
+ notes.add(POSITION_ISSUE.ANCHOR_NO_SIZE, { element: i / 3 });
278
+ }
279
+ p[0] = values[i];
280
+ p[1] = values[i + 1];
281
+ p[2] = values[i + 2];
282
+ toNeutral(p, extra, s, realZ);
283
+ values.set(p, i);
284
+ }
285
+ }
286
+
287
+ /**
288
+ * Reads a row's width and height from the size columns a spelling names.
289
+ * @param snapshot - the graph
290
+ * @param extra - the spelling
291
+ * @returns the reader; it answers null for a row without both, or when the columns are missing
292
+ */
293
+ function sizeReader(snapshot: GraphSnapshot, extra: PositionColumnExtra): SizeReader {
294
+ const w = extra.width === undefined ? null : snapshot.nodes.get(extra.width);
295
+ const h = extra.height === undefined ? null : snapshot.nodes.get(extra.height);
296
+ if (w === null || h === null) {
297
+ return () => null;
298
+ }
299
+ return (row) => {
300
+ if (!w.isSet(row) || !h.isSet(row)) {
301
+ return null;
302
+ }
303
+ const size: [number, number] = [Number(w.value(row)), Number(h.value(row))];
304
+ return Number.isFinite(size[0]) && Number.isFinite(size[1]) ? size : null;
305
+ };
306
+ }
307
+
308
+ /**
309
+ * NetworkX writes (0, 0) for a node with no position: when other rows are placed, an exact (0, 0)
310
+ * shared by two or more rows counts as unplaced.
311
+ * @param values - the raw coordinates, changed in place
312
+ */
313
+ function dropZeroPile(values: Float64Array): void {
314
+ const zeros: number[] = [];
315
+ let others = 0;
316
+ for (let i = 0; i < values.length; i += 3) {
317
+ if (values[i] === 0 && values[i + 1] === 0) {
318
+ zeros.push(i);
319
+ } else if (!Number.isNaN(values[i])) {
320
+ others++;
321
+ }
322
+ }
323
+ if (zeros.length >= 2 && others > 0) {
324
+ for (const i of zeros) {
325
+ values.fill(Number.NaN, i, i + 3);
326
+ }
327
+ }
328
+ }
329
+
330
+ /**
331
+ * Whether every placed row has the same z (Pajek writes z = 0.5 on 2D drawings).
332
+ * @param values - the raw coordinates
333
+ * @returns true when z never differs
334
+ */
335
+ function constantZ(values: Float64Array): boolean {
336
+ let z = Number.NaN;
337
+ for (let i = 0; i < values.length; i += 3) {
338
+ if (Number.isNaN(values[i])) {
339
+ continue;
340
+ }
341
+ if (Number.isNaN(z)) {
342
+ z = values[i + 2];
343
+ } else if (values[i + 2] !== z) {
344
+ return false;
345
+ }
346
+ }
347
+ return true;
348
+ }
349
+
350
+ // ------------------------------------------------------------ groups
351
+
352
+ /**
353
+ * The nodes another node names as its parent: group containers.
354
+ * @param snapshot - the graph
355
+ * @returns the container indexes
356
+ */
357
+ function containersOf(snapshot: GraphSnapshot): Set<number> {
358
+ const out = new Set<number>();
359
+ const parent = snapshot.nodes.byRole("parent");
360
+ if (parent === null) {
361
+ return out;
362
+ }
363
+ for (let row = 0; row < parent.length; row++) {
364
+ const v = parent.isSet(row) ? parent.value(row) : undefined;
365
+ if (typeof v === "number") {
366
+ out.add(v);
367
+ }
368
+ }
369
+ return out;
370
+ }
371
+
372
+ /**
373
+ * The hook's group boxes in the neutral convention; a container with no coordinate of its own is
374
+ * placed at its box's center.
375
+ * @param spelling - the spelling and the hook's boxes
376
+ * @param rows - the coordinates, changed in place
377
+ * @returns the boxes
378
+ */
379
+ function applyGroups(spelling: Spelling, rows: Rows): FilePositionGroup[] {
380
+ const out: FilePositionGroup[] = [];
381
+ for (const { node, box } of spelling.groups) {
382
+ const p: Point = [box.x, box.y, 0];
383
+ toNeutral(p, spelling.extra, [box.width, box.height], false);
384
+ if (Number.isNaN(rows.values[3 * node])) {
385
+ rows.values.set(p, 3 * node);
386
+ }
387
+ if (!out.some((g) => g.node === node)) {
388
+ out.push({ node, box: { x: p[0], y: p[1], width: box.width, height: box.height } });
389
+ }
390
+ }
391
+ return out;
392
+ }
393
+
394
+ /**
395
+ * Boxes for the containers the file gives a coordinate and a size (yEd groups).
396
+ * @param spelling - the size reader
397
+ * @param rows - the coordinates
398
+ * @param containers - the container indexes
399
+ * @param groups - receives the boxes
400
+ */
401
+ function collectGroups(
402
+ spelling: Spelling,
403
+ rows: Rows,
404
+ containers: ReadonlySet<number>,
405
+ groups: FilePositionGroup[],
406
+ ): void {
407
+ for (const node of containers) {
408
+ const size = spelling.size(node);
409
+ const i = 3 * node;
410
+ if (size !== null && !Number.isNaN(rows.values[i]) && !groups.some((g) => g.node === node)) {
411
+ groups.push({ node, box: { x: rows.values[i], y: rows.values[i + 1], width: size[0], height: size[1] } });
412
+ }
413
+ }
414
+ }
415
+
416
+ // ------------------------------------------------------------ counts and notes
417
+
418
+ /**
419
+ * Count the placed rows and the rows that need a position; note the unplaced ones.
420
+ * @param rows - the coordinates
421
+ * @param containers - containers without a coordinate do not need one
422
+ * @param notes - receives the partial note
423
+ * @returns placed and total
424
+ */
425
+ function countPlaced(
426
+ rows: Rows,
427
+ containers: ReadonlySet<number>,
428
+ notes: NoteCollector<PositionNoteCode>,
429
+ ): { placed: number; total: number } {
430
+ const { values } = rows;
431
+ const unplaced: number[] = [];
432
+ let placed = 0;
433
+ let total = 0;
434
+ for (let row = 0; 3 * row < values.length; row++) {
435
+ const has = !Number.isNaN(values[3 * row]);
436
+ if (has) {
437
+ placed++;
438
+ } else if (!containers.has(row)) {
439
+ unplaced.push(row);
440
+ }
441
+ total += has || !containers.has(row) ? 1 : 0;
442
+ }
443
+ if (placed > 0 && unplaced.length > 0) {
444
+ for (const element of unplaced) {
445
+ notes.add(POSITION_ISSUE.PARTIAL, { element });
446
+ }
447
+ }
448
+ return { placed, total };
449
+ }
450
+
451
+ /**
452
+ * Drop the coordinates when every placed node sits on one point.
453
+ * @param rows - the coordinates, cleared in place when stacked
454
+ * @param placed - the placed count
455
+ * @param notes - receives the stacked note
456
+ * @returns whether they were stacked
457
+ */
458
+ function dropStacked(rows: Rows, placed: number, notes: NoteCollector<PositionNoteCode>): boolean {
459
+ if (placed < 2) {
460
+ return false;
461
+ }
462
+ const { values } = rows;
463
+ let first = -1;
464
+ for (let i = 0; i < values.length; i += 3) {
465
+ if (Number.isNaN(values[i])) {
466
+ continue;
467
+ }
468
+ if (first < 0) {
469
+ first = i;
470
+ } else if (
471
+ values[i] !== values[first] ||
472
+ values[i + 1] !== values[first + 1] ||
473
+ values[i + 2] !== values[first + 2]
474
+ ) {
475
+ return false;
476
+ }
477
+ }
478
+ notes.add(POSITION_ISSUE.STACKED, {
479
+ count: placed,
480
+ sample: Array.from(values.subarray(first, first + 3)).join(","),
481
+ });
482
+ values.fill(Number.NaN);
483
+ return true;
484
+ }
485
+
486
+ /**
487
+ * Lift the format readers' mixed-dimension warnings into the shared code.
488
+ * @param report - the import report
489
+ * @param notes - receives the note
490
+ */
491
+ function noteReport(report: ImportReport, notes: NoteCollector<PositionNoteCode>): void {
492
+ for (const issue of report.issues) {
493
+ if (DIMS_MIXED_CODES.has(issue.code)) {
494
+ notes.add(POSITION_ISSUE.DIMS_MIXED, { sample: issue.code });
495
+ }
496
+ }
497
+ }
498
+
499
+ /**
500
+ * Note the extra view columns of a CX file (`position@2`, ...): only the first view is used.
501
+ * @param snapshot - the graph
502
+ * @param notes - receives the note
503
+ */
504
+ function noteOtherViews(snapshot: GraphSnapshot, notes: NoteCollector<PositionNoteCode>): void {
505
+ for (const column of snapshot.nodes) {
506
+ if (/^position@\d+$/.test(column.meta.name) && column.meta.role === null) {
507
+ notes.add(POSITION_ISSUE.OTHER_VIEWS, { sample: column.meta.name });
508
+ }
509
+ }
510
+ }
511
+
512
+ /**
513
+ * Note plain numeric `x` and `y` node columns a format does not read as positions.
514
+ * @param snapshot - the graph
515
+ * @param notes - receives the note
516
+ */
517
+ function noteUnread(snapshot: GraphSnapshot, notes: NoteCollector<PositionNoteCode>): void {
518
+ const numeric = (name: string): Column | undefined =>
519
+ [...snapshot.nodes].find(
520
+ (c) => c.meta.name.toLowerCase() === name && c.meta.components === 1 && isNumeric(c.dtype),
521
+ );
522
+ const x = numeric("x");
523
+ const y = numeric("y");
524
+ if (x !== undefined && y !== undefined) {
525
+ notes.add(POSITION_ISSUE.NOT_READ, { sample: x.meta.name });
526
+ notes.add(POSITION_ISSUE.NOT_READ, { sample: y.meta.name });
527
+ }
528
+ }
529
+
530
+ /**
531
+ * Whether a dtype holds numbers.
532
+ * @param dtype - the dtype
533
+ * @returns true for the numeric dtypes
534
+ */
535
+ function isNumeric(dtype: string): boolean {
536
+ return dtype === "f64" || dtype === "f32" || dtype === "i32" || dtype === "u32" || dtype === "u8";
537
+ }
538
+
539
+ /**
540
+ * The notes with graph-io's English.
541
+ * @param notes - the collector
542
+ * @returns the notes
543
+ */
544
+ function noteList(notes: NoteCollector<PositionNoteCode>): PositionNote[] {
545
+ return notes.list().map((n) => ({
546
+ code: n.code,
547
+ params: { count: n.count, samples: n.samples },
548
+ elements: n.elements,
549
+ message: `${PHRASES[n.code]} (${n.count})`,
550
+ }));
551
+ }
552
+
553
+ /**
554
+ * The answer for a file with no readable positions but position-like columns.
555
+ * @param importer - the importer
556
+ * @param snapshot - the graph
557
+ * @param notes - the notes
558
+ * @returns positions with nothing placed
559
+ */
560
+ function emptyPositions(
561
+ importer: GraphImporter,
562
+ snapshot: GraphSnapshot,
563
+ notes: NoteCollector<PositionNoteCode>,
564
+ ): FilePositions {
565
+ return {
566
+ version: 1,
567
+ source: { format: importer.format, tool: toolOf(snapshot.meta.creator), yAxis: "up" },
568
+ units: "file",
569
+ medianNodeSize: null,
570
+ dims: 2,
571
+ coords: new Float64Array(3 * snapshot.nodeCount).fill(Number.NaN),
572
+ placed: 0,
573
+ total: snapshot.nodeCount,
574
+ usable: false,
575
+ bounds: null,
576
+ groups: [],
577
+ notes: noteList(notes),
578
+ };
579
+ }
580
+
581
+ // ------------------------------------------------------------ sizes and bounds
582
+
583
+ /**
584
+ * The median node diameter from the size columns the spelling names.
585
+ * @param size - the size reader
586
+ * @param n - the node count
587
+ * @param containers - group containers, left out
588
+ * @returns the median of each node's mean of width and height, or null when no node has a size
589
+ */
590
+ function medianSize(size: SizeReader, n: number, containers: ReadonlySet<number>): number | null {
591
+ const sizes: number[] = [];
592
+ for (let row = 0; row < n; row++) {
593
+ const s = containers.has(row) ? null : size(row);
594
+ if (s !== null) {
595
+ sizes.push((s[0] + s[1]) / 2);
596
+ }
597
+ }
598
+ return median(sizes);
599
+ }
600
+
601
+ /**
602
+ * The box around every placed row.
603
+ * @param values - the coordinates
604
+ * @returns min and max, or null when none is placed
605
+ */
606
+ function boundsOf(values: Float64Array): FilePositions["bounds"] {
607
+ const min: Point = [Infinity, Infinity, Infinity];
608
+ const max: Point = [-Infinity, -Infinity, -Infinity];
609
+ for (let i = 0; i < values.length; i += 3) {
610
+ if (Number.isNaN(values[i])) {
611
+ continue;
612
+ }
613
+ for (let k = 0; k < 3; k++) {
614
+ min[k] = Math.min(min[k], values[i + k]);
615
+ max[k] = Math.max(max[k], values[i + k]);
616
+ }
617
+ }
618
+ return min[0] === Infinity ? null : { min, max };
619
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `@graphty/graph-io/positions`: any format's stored node coordinates in one neutral form (each
3
+ * node's center, y up, in the file's own unit), and the inverse a writer uses. This entry loads in
4
+ * Node and never loads a format module: pass it the importer that read the snapshot.
5
+ */
6
+
7
+ export { POSITION_ISSUE, type PositionNoteCode } from "./codes.js";
8
+ export { flipY, toFilePositions, writtenPositions } from "./convert.js";
9
+ export { extractPositions } from "./extract.js";
10
+ export type {
11
+ ExtractPositionsOptions,
12
+ FilePositionGroup,
13
+ FilePositions,
14
+ GraphTool,
15
+ ImporterGroupBox,
16
+ ImporterPositions,
17
+ LengthUnit,
18
+ PositionAnchor,
19
+ PositionColumnExtra,
20
+ PositionNote,
21
+ PositionReadContext,
22
+ YAxis,
23
+ } from "./types.js";