@graphty/graph-io 0.3.43 → 0.3.45

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-DJMHdDvv.js +40 -0
  2. package/dist/chunks/approximations-DJMHdDvv.js.map +1 -0
  3. package/dist/chunks/block-CPCHkX42.js +2777 -0
  4. package/dist/chunks/block-CPCHkX42.js.map +1 -0
  5. package/dist/chunks/{choose-DvpbdRuz.js → choose--jM0yYCo.js} +3 -2
  6. package/dist/chunks/{choose-DvpbdRuz.js.map → choose--jM0yYCo.js.map} +1 -1
  7. package/dist/chunks/{constants-fT3E8JYY.js → constants-BKwqelYD.js} +6 -2
  8. package/dist/chunks/constants-BKwqelYD.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-DZy6JgdA.js +3456 -0
  12. package/dist/chunks/emit-DZy6JgdA.js.map +1 -0
  13. package/dist/chunks/{escape-B62ZGM_a.js → escape-CgzxiYPg.js} +44 -21
  14. package/dist/chunks/escape-CgzxiYPg.js.map +1 -0
  15. package/dist/chunks/{export-rKLeGQMo.js → export-BvqAXCKh.js} +196 -792
  16. package/dist/chunks/export-BvqAXCKh.js.map +1 -0
  17. package/dist/chunks/{exporter-yLxKBvLE.js → exporter--Mk9gXCJ.js} +4 -3
  18. package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter--Mk9gXCJ.js.map} +1 -1
  19. package/dist/chunks/{exporter-RVtXVetw.js → exporter-C-9cgZKa.js} +1805 -287
  20. package/dist/chunks/exporter-C-9cgZKa.js.map +1 -0
  21. package/dist/chunks/{exporter-8hLNemFk.js → exporter-DFqJhBnj.js} +133 -74
  22. package/dist/chunks/exporter-DFqJhBnj.js.map +1 -0
  23. package/dist/chunks/{exporter-BWwEuOPT.js → exporter-DteVeJki.js} +22 -12
  24. package/dist/chunks/exporter-DteVeJki.js.map +1 -0
  25. package/dist/chunks/format-BpQBx8MZ.js +676 -0
  26. package/dist/chunks/format-BpQBx8MZ.js.map +1 -0
  27. package/dist/chunks/generic-BGO71QBv.js +1347 -0
  28. package/dist/chunks/generic-BGO71QBv.js.map +1 -0
  29. package/dist/chunks/{importer-C98dpSH4.js → importer-B-9Rc1zO.js} +141 -82
  30. package/dist/chunks/importer-B-9Rc1zO.js.map +1 -0
  31. package/dist/chunks/{importer-D794XUTe.js → importer-BVVR740x.js} +31 -8
  32. package/dist/chunks/importer-BVVR740x.js.map +1 -0
  33. package/dist/chunks/{importer-WrGRZb0N.js → importer-C0AjA3Ax.js} +449 -102
  34. package/dist/chunks/importer-C0AjA3Ax.js.map +1 -0
  35. package/dist/chunks/{importer-BbNb7eNg.js → importer-C7pvJe1L.js} +1398 -129
  36. package/dist/chunks/importer-C7pvJe1L.js.map +1 -0
  37. package/dist/chunks/{importer-xZ-3suY1.js → importer-ClwoVx3O.js} +791 -135
  38. package/dist/chunks/importer-ClwoVx3O.js.map +1 -0
  39. package/dist/chunks/{importer-Ht7LNg8L.js → importer-D0sC_6bO.js} +116 -296
  40. package/dist/chunks/importer-D0sC_6bO.js.map +1 -0
  41. package/dist/chunks/{importer-Dz7tI8Sa.js → importer-EHQk1jbM.js} +617 -115
  42. package/dist/chunks/importer-EHQk1jbM.js.map +1 -0
  43. package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-DJZRZ6jd.js} +123 -32
  44. package/dist/chunks/json-elements-DJZRZ6jd.js.map +1 -0
  45. package/dist/chunks/lexicon-WMsNddyU.js +509 -0
  46. package/dist/chunks/lexicon-WMsNddyU.js.map +1 -0
  47. package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-G4MqRdux.js} +3 -2
  48. package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-G4MqRdux.js.map} +1 -1
  49. package/dist/chunks/{records-Cu4bxYOm.js → records-CiaWZrFH.js} +2 -2
  50. package/dist/chunks/{records-Cu4bxYOm.js.map → records-CiaWZrFH.js.map} +1 -1
  51. package/dist/chunks/styles-DvoFBKCK.js +690 -0
  52. package/dist/chunks/styles-DvoFBKCK.js.map +1 -0
  53. package/dist/chunks/styles-yed-Cz9rLBCP.js +842 -0
  54. package/dist/chunks/styles-yed-Cz9rLBCP.js.map +1 -0
  55. package/dist/chunks/styles-zNTmz5R7.js +2102 -0
  56. package/dist/chunks/styles-zNTmz5R7.js.map +1 -0
  57. package/dist/chunks/{text-DHOJXnED.js → text-CzJNFOS9.js} +2 -2
  58. package/dist/chunks/{text-DHOJXnED.js.map → text-CzJNFOS9.js.map} +1 -1
  59. package/dist/chunks/units-XMZFIFe1.js +19 -0
  60. package/dist/chunks/units-XMZFIFe1.js.map +1 -0
  61. package/dist/chunks/writer-gQ8kx99H.js +448 -0
  62. package/dist/chunks/writer-gQ8kx99H.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 +927 -74
  73. package/dist/gml.js.map +1 -1
  74. package/dist/graph-io.js +351 -236
  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 +1496 -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 +791 -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 +605 -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 +89 -0
  489. package/dist/src/styles/io/writer.d.ts.map +1 -0
  490. package/dist/src/styles/io/writer.js +626 -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 +1755 -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 +952 -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 +658 -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 +780 -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
@@ -1,10 +1,16 @@
1
1
  import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
2
2
  import { c as childrenCsr } from "./children-CA4coBi0.js";
3
- import { L as LOSS, r as resolveExportOptions, a as checkCapabilities, c as capabilities, bD as countMixedEdges, e as explicitWeights, p as pairFolding, b as plural, aE as sanitizeIds, aa as formatF32, ab as formatF64, a9 as idText, $ as agree, aF as formatDecimal, aG as formatInteger, aH as canonicalId, M as MIXED_DIRECTION_CODE, D as DIRECTION_FORCED_CODE, d as DIRECTION_REFUSED_CODE, S as SINK_OPTION_CODE, I as ID_MERGED_CODE, O as OPTION_IGNORED_CODE, C as COLUMN_RENAMED_CODE, R as ROLE_TAKEN_CODE, o as DUPLICATE_ATTRIBUTE_CODE, P as PRECISION_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, l as MULTIPLE_GRAPHS_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, ak as SYNTAX_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, al as resolveImportOptions, a8 as ImportReportBuilder, an as reportUnusedOptions, bB as readText, ao as reportSinkOptions, am as throwIfAborted, ap as graphChosen, ar as IdCoercer, aq as DirectionResolver, aK as parseWeightText, bE as canonicalEncoding, a1 as declareResolved } from "./export-rKLeGQMo.js";
4
- import { c as quoteDotId, d as isWritableDotText } from "./escape-B62ZGM_a.js";
5
- import { i as inferTextDtype, W as WIDENING_UNSUPPORTED_CODE, p as parseTextCell, T as TextCellWriter } from "./text-DHOJXnED.js";
3
+ import { L as LOSS, c as capabilities, r as resolveExportOptions, a as checkCapabilities, ai as countMixedEdges, e as explicitWeights, p as pairFolding, G as sanitizeIds, a1 as canonicalId, g as resolveImportOptions, i as reportUnusedOptions, ab as readText, j as reportSinkOptions, h as throwIfAborted, k as graphChosen, I as IdCoercer, l as DirectionResolver, s as parseWeightText, aj as canonicalEncoding, d as declareResolved } from "./export-BvqAXCKh.js";
4
+ import { k as isWritableDotText, m as quoteDotId } from "./escape-CgzxiYPg.js";
5
+ import { p as plural, a as agree, $ as formatF32, a0 as formatF64, _ as idText, aO as formatDecimal, ad as formatInteger, M as MIXED_DIRECTION_CODE, D as DIRECTION_FORCED_CODE, b as DIRECTION_REFUSED_CODE, S as SINK_OPTION_CODE, I as ID_MERGED_CODE, O as OPTION_IGNORED_CODE, C as COLUMN_RENAMED_CODE, R as ROLE_TAKEN_CODE, l as DUPLICATE_ATTRIBUTE_CODE, P as PRECISION_CODE, a2 as AMBIGUOUS_GRAPH_NAME_CODE, a3 as GRAPH_NOT_FOUND_CODE, i as MULTIPLE_GRAPHS_CODE, r as ENCODING_CONFLICT_CODE, s as UNKNOWN_ENCODING_CODE, t as ENCODING_FALLBACK_CODE, u as INVALID_ENCODING_CODE, v as INVALID_UTF8_CODE, E as EMPTY_INPUT_CODE, a8 as SYNTAX_CODE, y as ELEMENT_ISSUE, z as INPUT_ISSUE, Z as ImportReportBuilder } from "./format-BpQBx8MZ.js";
6
+ import { i as inferTextDtype, W as WIDENING_UNSUPPORTED_CODE, p as parseTextCell, T as TextCellWriter } from "./text-CzJNFOS9.js";
6
7
  import { j as joinText, e as encodeChunks, i as indentUnit } from "./writer-DxjgHwSe.js";
7
- import { i as importChosenGraph } from "./choose-DvpbdRuz.js";
8
+ import { i as importChosenGraph } from "./choose--jM0yYCo.js";
9
+ import { m as median } from "./convert-BcQ8_jMo.js";
10
+ import { t as StyleNotes, n as noteAt, a as STYLE_ISSUE, E as htmlLabelText, F as dotLabelText, p as plainCell, g as canonColor, x as colorOpacity, S as STYLE_BLOCK_NAME, u as parseStyleBlock, s as styleFingerprint, v as blockStyles, M as MAX_STYLE_VALUE_LENGTH, h as canonNumber, l as canonEnum, G as recordLabelText, i as num6, r as resolveStyles, H as DOT_POINTS_PER_INCH, C as toolDefaults, w as writeStyleBlock, c as styleBlockLosses } from "./block-CPCHkX42.js";
11
+ import { S as StyleApproximations } from "./approximations-DJMHdDvv.js";
12
+ import { s as sharedInExportCall } from "./writer-gQ8kx99H.js";
13
+ import { v as valueColumns } from "./styles-yed-Cz9rLBCP.js";
8
14
  const DOT_FORMAT = "dot";
9
15
  const DOT_ORIGIN = Object.freeze({ format: DOT_FORMAT });
10
16
  const CLUSTER_COLUMN = "graphty.cluster";
@@ -17,6 +23,1045 @@ const POSITION_COLUMN = "graphty.position";
17
23
  const KEY_ATTRIBUTE = "key";
18
24
  const PIN_ATTRIBUTE = "pin";
19
25
  const DOT_META_KEY = "dot";
26
+ const DOT_STYLE_CAPABILITIES = Object.freeze({
27
+ node: Object.freeze([
28
+ "fill",
29
+ "fillOpacity",
30
+ "borderColor",
31
+ "borderWidth",
32
+ "borderStyle",
33
+ "shape",
34
+ "width",
35
+ "height",
36
+ "label",
37
+ "labelColor",
38
+ "labelSize",
39
+ "labelFont",
40
+ "tooltip",
41
+ "visible"
42
+ ]),
43
+ edge: Object.freeze([
44
+ "color",
45
+ "opacity",
46
+ "width",
47
+ "lineStyle",
48
+ "sourceArrow",
49
+ "targetArrow",
50
+ "arrowSize",
51
+ "label",
52
+ "sourceLabel",
53
+ "targetLabel",
54
+ "labelColor",
55
+ "labelSize",
56
+ "labelFont",
57
+ "tooltip",
58
+ "visible"
59
+ ]),
60
+ graph: Object.freeze(["background"]),
61
+ block: "native"
62
+ });
63
+ const NAME_KEY = "name";
64
+ const DIRECTED_KEY = "directed";
65
+ const CLUSTER_KEY = "cluster";
66
+ const NODE_ATTRIBUTES = [
67
+ "colorscheme",
68
+ "color",
69
+ "fillcolor",
70
+ "bgcolor",
71
+ "pencolor",
72
+ "style",
73
+ "shape",
74
+ "width",
75
+ "height",
76
+ "fixedsize",
77
+ "regular",
78
+ "penwidth",
79
+ "fontname",
80
+ "fontsize",
81
+ "fontcolor",
82
+ "tooltip"
83
+ ];
84
+ const EDGE_ATTRIBUTES = [
85
+ "colorscheme",
86
+ "color",
87
+ "style",
88
+ "penwidth",
89
+ "fontname",
90
+ "fontsize",
91
+ "fontcolor",
92
+ "tooltip",
93
+ "edgetooltip",
94
+ "arrowhead",
95
+ "arrowtail",
96
+ "dir",
97
+ "arrowsize",
98
+ "headlabel",
99
+ "taillabel"
100
+ ];
101
+ const NOTED_ATTRIBUTES = ["peripheries", "xlabel"];
102
+ const CIRCLE_LIKE = /* @__PURE__ */ new Set(["circle", "doublecircle", "mcircle", "square", "msquare"]);
103
+ const BOX_LIKE = /* @__PURE__ */ new Set(["box", "rect", "rectangle", "square"]);
104
+ const ELLIPSE_LIKE = /* @__PURE__ */ new Set(["", "ellipse", "oval", "circle"]);
105
+ const NO_OUTLINE = /* @__PURE__ */ new Set(["plain", "plaintext", "none"]);
106
+ const RECORD = /* @__PURE__ */ new Set(["record", "mrecord"]);
107
+ const TRUE_TEXTS$1 = /* @__PURE__ */ new Set(["true", "yes", "shape"]);
108
+ const POINT_SIZE = 0.05;
109
+ const REGULAR_SIZE = 0.5;
110
+ function isHtmlString(text) {
111
+ if (text.length < 2 || !text.startsWith("<") || !text.endsWith(">")) {
112
+ return false;
113
+ }
114
+ let depth = 0;
115
+ for (let i = 0; i < text.length; i++) {
116
+ const c = text.codePointAt(i);
117
+ if (c === 60) {
118
+ depth++;
119
+ } else if (c === 62) {
120
+ depth--;
121
+ if (depth === 0 && i !== text.length - 1) {
122
+ return false;
123
+ }
124
+ }
125
+ }
126
+ return depth === 0;
127
+ }
128
+ function cellText$1(table, name, i) {
129
+ if (!table.has(name)) {
130
+ return null;
131
+ }
132
+ const v = plainCell(table.value(name, i));
133
+ if (typeof v === "string") {
134
+ return v;
135
+ }
136
+ return typeof v === "number" || typeof v === "boolean" ? String(v) : null;
137
+ }
138
+ function nonEmpty(v) {
139
+ return v === null || v === "" ? null : v;
140
+ }
141
+ function styleTokens(raw, at) {
142
+ if (raw === null) {
143
+ return [];
144
+ }
145
+ if (raw.length > MAX_STYLE_VALUE_LENGTH) {
146
+ noteAt(at, STYLE_ISSUE.VALUE_TOO_LONG, `${String(raw.length)} characters`);
147
+ return [];
148
+ }
149
+ return raw.toLowerCase().split(",").map((t) => t.replace(/^[ \t\r\n]+/, "")).filter((t) => t !== "");
150
+ }
151
+ function setLineWidth(tokens) {
152
+ for (const t of tokens) {
153
+ if (t.startsWith("setlinewidth(") && t.endsWith(")")) {
154
+ return t.slice("setlinewidth(".length, -1).trim();
155
+ }
156
+ }
157
+ return null;
158
+ }
159
+ function isTrue(raw) {
160
+ if (raw === null) {
161
+ return false;
162
+ }
163
+ const t = raw.trim().toLowerCase();
164
+ return TRUE_TEXTS$1.has(t) || /^-?\d+$/.test(t) && Number(t) !== 0;
165
+ }
166
+ function labelText(raw, names, html, record, at) {
167
+ if (isHtmlString(raw)) {
168
+ return htmlLabelText(raw, at);
169
+ }
170
+ if (html.has(`<${raw}>`)) {
171
+ return htmlLabelText(`<${raw}>`, at);
172
+ }
173
+ return dotLabelText(record ? recordLabelText(raw, at) : raw, names, at);
174
+ }
175
+ function readColor(raw, scheme, use, property, opacity, put, at) {
176
+ if (raw === null) {
177
+ return null;
178
+ }
179
+ const c = canonColor(raw, "graphviz", at(property), { scheme, use });
180
+ if (c === null) {
181
+ return null;
182
+ }
183
+ put(property, c.color);
184
+ if (opacity !== null) {
185
+ put(opacity, c.alpha);
186
+ } else if (c.alpha > 0 || property !== "borderColor") {
187
+ colorOpacity(c, null, at(property), false);
188
+ }
189
+ return c.alpha;
190
+ }
191
+ function inchesOf(points) {
192
+ const want = num6(points);
193
+ for (let digits = 6; digits < 17; digits++) {
194
+ const inches2 = Number((points / DOT_POINTS_PER_INCH).toPrecision(digits));
195
+ if (num6(inches2 * DOT_POINTS_PER_INCH) === want) {
196
+ return inches2 + 0;
197
+ }
198
+ }
199
+ return points / DOT_POINTS_PER_INCH;
200
+ }
201
+ function inches(raw, at) {
202
+ if (raw === null) {
203
+ return null;
204
+ }
205
+ const v = raw.trim() === "" ? Number.NaN : Number(raw);
206
+ if (!Number.isFinite(v) || v < 0) {
207
+ noteAt(at, STYLE_ISSUE.BAD_VALUE, raw.slice(0, MAX_STYLE_VALUE_LENGTH));
208
+ return null;
209
+ }
210
+ return v;
211
+ }
212
+ function readCommon(get, tokens, scheme, names, put, at) {
213
+ if (tokens.includes("invis")) {
214
+ put("visible", false);
215
+ }
216
+ readColor(nonEmpty(get("fontcolor")), scheme, "line", "labelColor", null, put, at);
217
+ const size = get("fontsize");
218
+ put("labelSize", size === null ? null : canonNumber(size, at("labelSize")));
219
+ const font = get("fontname");
220
+ if (font !== null && font.length <= MAX_STYLE_VALUE_LENGTH) {
221
+ put("labelFont", font);
222
+ }
223
+ const tip = get("tooltip") ?? get("edgetooltip");
224
+ if (tip !== null) {
225
+ put("tooltip", dotLabelText(tip, names, at("tooltip")));
226
+ }
227
+ }
228
+ function readNode(get, cx, put, at) {
229
+ const tokens = styleTokens(get("style"), at("visible"));
230
+ const shapeRaw = nonEmpty(get("shape"));
231
+ const shape = (shapeRaw ?? "").toLowerCase();
232
+ const n = {
233
+ get,
234
+ cx,
235
+ put,
236
+ at,
237
+ tokens,
238
+ shapeRaw,
239
+ shape,
240
+ point: !cx.cluster && shape === "point",
241
+ scheme: get("colorscheme"),
242
+ color: nonEmpty(get("color"))
243
+ };
244
+ const names = cx.cluster ? { graph: cx.name } : { node: cx.name, graph: cx.graph, edge: "" };
245
+ readCommon(get, tokens, n.scheme, names, put, at);
246
+ if (cx.cluster) {
247
+ readClusterFill(n);
248
+ } else {
249
+ readNodeFill(n);
250
+ }
251
+ readNodeOutline(n);
252
+ readNodeShape(n);
253
+ const label = n.point ? null : get(LABEL_ATTRIBUTE);
254
+ if (label !== null) {
255
+ put("label", labelText(label, names, cx.html, RECORD.has(shape), at("label")));
256
+ }
257
+ if (!cx.cluster) {
258
+ readSize(get, shape, n.point, label ?? (n.point ? null : cx.name), put, at);
259
+ }
260
+ if (Number(get("peripheries")) > 1 || nonEmpty(get("xlabel")) !== null) {
261
+ noteAt(at("label"), STYLE_ISSUE.NOT_CARRIED, nonEmpty(get("xlabel")) === null ? "peripheries" : "xlabel");
262
+ }
263
+ }
264
+ function readClusterFill(n) {
265
+ const { get, tokens } = n;
266
+ const filled = tokens.includes("filled") || tokens.includes("radial") || tokens.includes("striped");
267
+ const bg = nonEmpty(get("bgcolor"));
268
+ const raw = filled ? nonEmpty(get("fillcolor")) ?? n.color ?? bg ?? "lightgrey" : bg;
269
+ readColor(raw, n.scheme, "fill", "fill", "fillOpacity", n.put, n.at);
270
+ }
271
+ function readNodeFill(n) {
272
+ const { shape, point } = n;
273
+ const fillcolor = nonEmpty(n.get("fillcolor"));
274
+ const filled = point || n.tokens.some(
275
+ (t) => t === "filled" || t === "radial" || t === "striped" && BOX_LIKE.has(shape) || t === "wedged" && ELLIPSE_LIKE.has(shape)
276
+ );
277
+ if (filled) {
278
+ const raw = fillcolor ?? n.color ?? (point ? "black" : "lightgrey");
279
+ readColor(raw, n.scheme, "fill", "fill", "fillOpacity", n.put, n.at);
280
+ } else if (fillcolor !== null) {
281
+ noteAt(n.at("fill"), STYLE_ISSUE.UNFILLED, fillcolor.slice(0, MAX_STYLE_VALUE_LENGTH));
282
+ }
283
+ }
284
+ function readNodeOutline(n) {
285
+ const { get, cx, put, at, tokens } = n;
286
+ if (!cx.cluster && NO_OUTLINE.has(n.shape)) {
287
+ put("borderWidth", 0);
288
+ } else {
289
+ const outline = cx.cluster ? nonEmpty(get("pencolor")) ?? n.color : n.color;
290
+ const alpha = readColor(outline, n.scheme, "line", "borderColor", null, put, at);
291
+ const width = nonEmpty(get("penwidth")) ?? setLineWidth(tokens);
292
+ if (alpha === 0) {
293
+ put("borderWidth", 0);
294
+ } else if (width !== null) {
295
+ put("borderWidth", penWidth(width, get("penwidth") !== null, at("borderWidth")));
296
+ } else if (tokens.includes("bold")) {
297
+ put("borderWidth", 2);
298
+ }
299
+ }
300
+ if (tokens.includes("dashed")) {
301
+ put("borderStyle", "dashed");
302
+ } else if (tokens.includes("dotted")) {
303
+ put("borderStyle", "dotted");
304
+ }
305
+ }
306
+ function readNodeShape(n) {
307
+ const rounded = n.tokens.includes("rounded");
308
+ if (n.cx.cluster) {
309
+ n.put("shape", rounded ? "round-rectangle" : "rectangle");
310
+ } else if (n.shapeRaw !== null) {
311
+ n.put(
312
+ "shape",
313
+ rounded && BOX_LIKE.has(n.shape) ? "round-rectangle" : canonEnum("shape", n.shapeRaw, "graphviz", n.at("shape"))
314
+ );
315
+ }
316
+ }
317
+ function penWidth(raw, attribute, site) {
318
+ const value = Number(raw.trim());
319
+ if (attribute && Number.isFinite(value) && value < 0) {
320
+ noteAt(site, STYLE_ISSUE.BAD_VALUE, raw.slice(0, MAX_STYLE_VALUE_LENGTH));
321
+ return 0;
322
+ }
323
+ return canonNumber(raw, site);
324
+ }
325
+ function readSize(get, shape, point, label, put, at) {
326
+ let w = inches(get("width"), at("width"));
327
+ let h = inches(get("height"), at("height"));
328
+ const same = point || CIRCLE_LIKE.has(shape) || isTrue(get("regular"));
329
+ if (shape === "plain") {
330
+ w = h = 0;
331
+ } else if (w === null && h === null) {
332
+ if (point) {
333
+ put("width", num6(POINT_SIZE * DOT_POINTS_PER_INCH));
334
+ put("height", num6(POINT_SIZE * DOT_POINTS_PER_INCH));
335
+ return;
336
+ }
337
+ if (!same) {
338
+ return;
339
+ }
340
+ w = h = REGULAR_SIZE;
341
+ }
342
+ let ww = w;
343
+ let hh = h;
344
+ if (point) {
345
+ ww = hh = Math.min(w ?? Infinity, h ?? Infinity);
346
+ } else if (same) {
347
+ ww = hh = Math.max(w ?? 0, h ?? 0);
348
+ }
349
+ const exact = point || isTrue(get("fixedsize")) || label === "" && !RECORD.has(shape);
350
+ if (!exact) {
351
+ noteAt(at("width"), STYLE_ISSUE.SIZE_MINIMUM, "grows to fit its label");
352
+ }
353
+ put("width", ww === null ? null : canonNumber(ww, at("width"), DOT_POINTS_PER_INCH));
354
+ put("height", hh === null ? null : canonNumber(hh, at("height"), DOT_POINTS_PER_INCH));
355
+ }
356
+ function readEdge(get, cx, put, at) {
357
+ const tokens = styleTokens(get("style"), at("visible"));
358
+ const scheme = get("colorscheme");
359
+ readCommon(get, tokens, scheme, cx.names, put, at);
360
+ readColor(nonEmpty(get("color")), scheme, "edge", "color", "opacity", put, at);
361
+ readEdgeLine(get, tokens, put, at);
362
+ readEdgeArrows(get, cx, put, at);
363
+ for (const [attribute, property] of [
364
+ [LABEL_ATTRIBUTE, "label"],
365
+ ["headlabel", "targetLabel"],
366
+ ["taillabel", "sourceLabel"]
367
+ ]) {
368
+ const raw = get(attribute);
369
+ if (raw !== null) {
370
+ put(property, labelText(raw, cx.names, cx.html, false, at(property)));
371
+ }
372
+ }
373
+ if (nonEmpty(get("xlabel")) !== null) {
374
+ noteAt(at("label"), STYLE_ISSUE.NOT_CARRIED, "xlabel");
375
+ }
376
+ }
377
+ function readEdgeLine(get, tokens, put, at) {
378
+ const width = nonEmpty(get("penwidth")) ?? setLineWidth(tokens);
379
+ if (width !== null) {
380
+ put("width", penWidth(width, get("penwidth") !== null, at("width")));
381
+ } else if (tokens.includes("bold")) {
382
+ put("width", 2);
383
+ }
384
+ if (tokens.includes("dashed")) {
385
+ put("lineStyle", "dashed");
386
+ } else if (tokens.includes("dotted")) {
387
+ put("lineStyle", "dotted");
388
+ } else if (tokens.includes("solid") || tokens.includes("bold")) {
389
+ put("lineStyle", "solid");
390
+ } else if (tokens.includes("tapered")) {
391
+ put("lineStyle", "other:tapered");
392
+ }
393
+ }
394
+ function readEdgeArrows(get, cx, put, at) {
395
+ const dirRaw = nonEmpty(get("dir"));
396
+ const head = nonEmpty(get("arrowhead"));
397
+ const tail = nonEmpty(get("arrowtail"));
398
+ if (dirRaw !== null || head !== null || tail !== null) {
399
+ const dir = (dirRaw ?? (cx.directed ? "forward" : "none")).trim().toLowerCase();
400
+ const forward = dir === "forward" || dir === "both";
401
+ const back = dir === "back" || dir === "both";
402
+ put("targetArrow", forward ? canonEnum("arrow", head ?? "normal", "graphviz", at("targetArrow")) : "none");
403
+ put("sourceArrow", back ? canonEnum("arrow", tail ?? "normal", "graphviz", at("sourceArrow")) : "none");
404
+ }
405
+ const size = get("arrowsize");
406
+ if (size !== null) {
407
+ put("arrowSize", canonNumber(size, at("arrowSize")));
408
+ }
409
+ }
410
+ function htmlStrings(snapshot) {
411
+ const out = /* @__PURE__ */ new Set();
412
+ for (let i = 0; i < snapshot.nodeCount; i++) {
413
+ const id = snapshot.ids.idOf(i);
414
+ if (typeof id === "string" && isHtmlString(id)) {
415
+ out.add(id);
416
+ }
417
+ }
418
+ for (const [table, n] of [
419
+ [snapshot.nodes, snapshot.nodeCount],
420
+ [snapshot.edges, snapshot.edgeCount]
421
+ ]) {
422
+ for (const name of [LABEL_ATTRIBUTE, "headlabel", "taillabel"].filter((c) => table.has(c))) {
423
+ addHtmlCells(table, name, n, out);
424
+ }
425
+ }
426
+ return out;
427
+ }
428
+ function addHtmlCells(table, name, n, out) {
429
+ for (let i = 0; i < n; i++) {
430
+ const v = cellText$1(table, name, i);
431
+ if (v !== null && isHtmlString(v)) {
432
+ out.add(v);
433
+ }
434
+ }
435
+ }
436
+ function directedEdges(snapshot) {
437
+ const out = new Array(snapshot.edgeCount).fill(snapshot.directed);
438
+ const col = snapshot.directed ? snapshot.edges.byRole("directed") : null;
439
+ if (col !== null) {
440
+ for (let e = 0; e < snapshot.edgeCount; e++) {
441
+ const v = plainCell(col.value(e));
442
+ if (typeof v === "boolean") {
443
+ out[e] = v;
444
+ }
445
+ }
446
+ }
447
+ return out;
448
+ }
449
+ function isCluster(snapshot, i) {
450
+ return snapshot.nodes.has(CLUSTER_COLUMN) && snapshot.nodes.value(CLUSTER_COLUMN, i) === true;
451
+ }
452
+ function contexts(snapshot, written = null) {
453
+ const html = htmlStrings(snapshot);
454
+ const graph = snapshot.meta.name ?? "";
455
+ const own = directedEdges(snapshot);
456
+ const directed = written === null || own.every((d) => d === snapshot.directed) ? own : own.map(() => written);
457
+ const name = (i) => String(snapshot.ids.idOf(i));
458
+ return {
459
+ node: (i) => ({ name: name(i), graph, cluster: isCluster(snapshot, i), html }),
460
+ edge: (e) => {
461
+ const tail = name(snapshot.edgeSource(e));
462
+ const head = name(snapshot.edgeTarget(e));
463
+ return {
464
+ names: { graph, tail, head, edge: `${tail}${directed[e] ? "->" : "--"}${head}` },
465
+ directed: directed[e],
466
+ html
467
+ };
468
+ }
469
+ };
470
+ }
471
+ function defaultLabel(cx, shape, notes) {
472
+ if (cx.cluster || shape === "point") {
473
+ return null;
474
+ }
475
+ const at = { notes, target: "node", property: "label" };
476
+ return isHtmlString(cx.name) ? htmlLabelText(cx.name, at) : dotLabelText(String.raw`\N`, { node: cx.name, graph: cx.graph }, at);
477
+ }
478
+ function styleColumns(table, attributes) {
479
+ const own = /* @__PURE__ */ new Set([...attributes, ...NOTED_ATTRIBUTES]);
480
+ return [...table.names()].filter((c) => own.has(c) || c.startsWith("graphty.style."));
481
+ }
482
+ function dotStyles(snapshot, context) {
483
+ const notes = new StyleNotes();
484
+ const cx = contexts(snapshot);
485
+ const node = valueColumns(snapshot.nodeCount);
486
+ const nameColumn = new Array(snapshot.nodeCount).fill(null);
487
+ const clusterColumn = new Array(snapshot.nodeCount).fill(null);
488
+ let named = 0;
489
+ let clusters = 0;
490
+ for (let i = 0; i < snapshot.nodeCount; i++) {
491
+ context.budget.spend("node", NODE_ATTRIBUTES.length);
492
+ const get = (name) => cellText$1(snapshot.nodes, name, i);
493
+ const ncx = cx.node(i);
494
+ const at = (property) => ({ notes, target: "node", property, element: i, budget: context.budget });
495
+ readNode(
496
+ get,
497
+ ncx,
498
+ (p, v) => {
499
+ node.put(i, p, v);
500
+ },
501
+ at
502
+ );
503
+ const shown = defaultLabel(ncx, (get("shape") ?? "").toLowerCase(), notes);
504
+ if (shown !== null) {
505
+ nameColumn[i] = shown;
506
+ named++;
507
+ }
508
+ if (ncx.cluster) {
509
+ clusterColumn[i] = true;
510
+ clusters++;
511
+ }
512
+ }
513
+ const edge = valueColumns(snapshot.edgeCount);
514
+ for (let e = 0; e < snapshot.edgeCount; e++) {
515
+ context.budget.spend("edge", EDGE_ATTRIBUTES.length);
516
+ const get = (name) => cellText$1(snapshot.edges, name, e);
517
+ const at = (property) => ({ notes, target: "edge", property, element: e, budget: context.budget });
518
+ readEdge(
519
+ get,
520
+ cx.edge(e),
521
+ (p, v) => {
522
+ edge.put(e, p, v);
523
+ },
524
+ at
525
+ );
526
+ }
527
+ const graph = {};
528
+ const bg = nonEmpty(cellText$1(snapshot.graph, "bgcolor", 0));
529
+ if (snapshot.graph.has("bgcolor") && bg !== null) {
530
+ readColor(
531
+ bg,
532
+ cellText$1(snapshot.graph, "colorscheme", 0),
533
+ "fill",
534
+ "background",
535
+ null,
536
+ (p, v) => {
537
+ if (v !== null) {
538
+ graph[p] = v;
539
+ }
540
+ },
541
+ (property) => ({ notes, target: "graph", property })
542
+ );
543
+ }
544
+ const blockText = cellText$1(snapshot.graph, STYLE_BLOCK_NAME, 0);
545
+ if (blockText !== null) {
546
+ exactFromBlock(snapshot, blockText, { node: node.values, edge: edge.values }, cx);
547
+ }
548
+ const nodeRules = [];
549
+ const nodeColumns = /* @__PURE__ */ new Map();
550
+ if (named > 0) {
551
+ nodeColumns.set(NAME_KEY, nameColumn);
552
+ nodeRules.push({
553
+ id: "node.tool.name-label",
554
+ target: "node",
555
+ role: "passthrough",
556
+ origin: "tool",
557
+ where: { has: { style: NAME_KEY } },
558
+ map: { label: { kind: "passthrough", by: { style: NAME_KEY } } },
559
+ facts: { elements: named, reason: "NODE_NAME" }
560
+ });
561
+ }
562
+ const features = clusters > 0 ? [{ ref: { style: CLUSTER_KEY }, values: clusterColumn }] : [];
563
+ const edgeRules = [];
564
+ const edgeColumns = /* @__PURE__ */ new Map();
565
+ const directed = directedEdges(snapshot);
566
+ if (directed.some(Boolean)) {
567
+ edgeColumns.set(
568
+ DIRECTED_KEY,
569
+ directed.map((d) => d ? true : null)
570
+ );
571
+ edgeRules.push({
572
+ id: "edge.tool.arrow",
573
+ target: "edge",
574
+ role: "group",
575
+ origin: "tool",
576
+ where: { has: { style: DIRECTED_KEY } },
577
+ set: { targetArrow: "triangle" }
578
+ });
579
+ }
580
+ return {
581
+ canonical: true,
582
+ dialect: "graphviz",
583
+ tool: "graphviz",
584
+ units: "px",
585
+ node: { values: node.values, rules: nodeRules, columns: nodeColumns, features },
586
+ edge: { values: edge.values, rules: edgeRules, columns: edgeColumns },
587
+ graph,
588
+ notes: notes.list(),
589
+ readFrom: {
590
+ node: styleColumns(snapshot.nodes, NODE_ATTRIBUTES),
591
+ edge: styleColumns(snapshot.edges, EDGE_ATTRIBUTES)
592
+ }
593
+ };
594
+ }
595
+ const SHAPES = /* @__PURE__ */ new Map([
596
+ ["ellipse", "ellipse"],
597
+ ["rectangle", "box"],
598
+ ["round-rectangle", "box"],
599
+ ["triangle", "triangle"],
600
+ ["diamond", "diamond"],
601
+ ["pentagon", "pentagon"],
602
+ ["hexagon", "hexagon"],
603
+ ["octagon", "octagon"],
604
+ ["parallelogram", "parallelogram"],
605
+ ["trapezoid", "trapezium"],
606
+ ["star", "star"],
607
+ ["none", "none"]
608
+ ]);
609
+ const ARROWS = /* @__PURE__ */ new Map([
610
+ ["none", "none"],
611
+ ["triangle", "normal"],
612
+ ["triangle-open", "onormal"],
613
+ ["vee", "vee"],
614
+ ["tee", "tee"],
615
+ ["diamond", "diamond"],
616
+ ["diamond-open", "odiamond"],
617
+ ["circle", "dot"],
618
+ ["circle-open", "odot"],
619
+ ["square", "box"],
620
+ ["crow", "crow"],
621
+ ["half", "lnormal"],
622
+ ["inverted", "inv"]
623
+ ]);
624
+ const STROKES = /* @__PURE__ */ new Map([
625
+ ["dashed", "dashed"],
626
+ ["dotted", "dotted"]
627
+ ]);
628
+ function graphvizDefaults(target) {
629
+ const t = toolDefaults("graphviz")?.[target];
630
+ const out = /* @__PURE__ */ new Map();
631
+ const add = (attribute, property, scale = 1) => {
632
+ const v = t[property]?.value;
633
+ if (typeof v === "number") {
634
+ out.set(attribute, num6(v / scale));
635
+ } else if (typeof v === "string") {
636
+ out.set(attribute, v);
637
+ }
638
+ };
639
+ add("fontcolor", "labelColor");
640
+ add("fontsize", "labelSize");
641
+ add("fontname", "labelFont");
642
+ if (target === "node") {
643
+ add("color", "borderColor");
644
+ add("pencolor", "borderColor");
645
+ add("penwidth", "borderWidth");
646
+ add("shape", "shape");
647
+ add("width", "width", DOT_POINTS_PER_INCH);
648
+ add("height", "height", DOT_POINTS_PER_INCH);
649
+ } else {
650
+ add("color", "color");
651
+ add("penwidth", "width");
652
+ add("arrowsize", "arrowSize");
653
+ }
654
+ return out;
655
+ }
656
+ const DEFAULT_ATTRIBUTES = {
657
+ node: graphvizDefaults("node"),
658
+ edge: graphvizDefaults("edge")
659
+ };
660
+ function withoutDefaults(out, target) {
661
+ for (const [attribute, value] of DEFAULT_ATTRIBUTES[target]) {
662
+ if (out.get(attribute) === value) {
663
+ out.delete(attribute);
664
+ }
665
+ }
666
+ if (!out.has("width") && !out.has("height")) {
667
+ out.delete("fixedsize");
668
+ }
669
+ return out;
670
+ }
671
+ function gvColor(color, opacity) {
672
+ if (typeof opacity !== "number" || opacity >= 1) {
673
+ return color;
674
+ }
675
+ const a = Math.max(0, Math.min(255, Math.round(opacity * 255)));
676
+ return color + a.toString(16).padStart(2, "0");
677
+ }
678
+ function escapeLabel(text) {
679
+ return text.replaceAll("\\", String.raw`\\`).replaceAll("\n", String.raw`\n`);
680
+ }
681
+ function spelled(table, value, nearest, property, approximate) {
682
+ const exact = table.get(value);
683
+ if (exact !== void 0) {
684
+ return exact;
685
+ }
686
+ if (value.startsWith("other:")) {
687
+ return value.slice("other:".length);
688
+ }
689
+ approximate(property, value);
690
+ return nearest;
691
+ }
692
+ function writeCommon(get, out, tokens) {
693
+ const color = get("labelColor");
694
+ if (typeof color === "string") {
695
+ out.set("fontcolor", color);
696
+ }
697
+ const size = get("labelSize");
698
+ if (typeof size === "number") {
699
+ out.set("fontsize", size);
700
+ }
701
+ const font = get("labelFont");
702
+ if (typeof font === "string") {
703
+ out.set("fontname", font);
704
+ }
705
+ const tip = get("tooltip");
706
+ if (typeof tip === "string") {
707
+ out.set("tooltip", escapeLabel(tip));
708
+ }
709
+ if (get("visible") === false) {
710
+ tokens.push("invis");
711
+ }
712
+ }
713
+ function nodeAttributes(get, cx, approximate, notes) {
714
+ const out = /* @__PURE__ */ new Map();
715
+ const tokens = [];
716
+ writeCommon(get, out, tokens);
717
+ writeNodeOutline(get, cx, approximate, out, tokens);
718
+ const gvShape = writeNodeShape(get, cx, approximate, out, tokens);
719
+ if (!cx.cluster) {
720
+ writeNodeSize(get, out);
721
+ }
722
+ const label = get("label");
723
+ const shown = defaultLabel(cx, gvShape, notes);
724
+ if (typeof label === "string" && label !== shown) {
725
+ out.set(LABEL_ATTRIBUTE, escapeLabel(label));
726
+ } else if (label === null && shown !== null) {
727
+ out.set(LABEL_ATTRIBUTE, "");
728
+ }
729
+ if (tokens.length > 0) {
730
+ out.set("style", tokens.join(","));
731
+ }
732
+ return withoutDefaults(out, "node");
733
+ }
734
+ function writeNodeOutline(get, cx, approximate, out, tokens) {
735
+ const fill = get("fill");
736
+ const fillOpacity = get("fillOpacity");
737
+ if (typeof fill === "string" && fillOpacity !== 0) {
738
+ tokens.push("filled");
739
+ out.set("fillcolor", gvColor(fill, fillOpacity));
740
+ }
741
+ const border = get("borderColor");
742
+ if (typeof border === "string") {
743
+ out.set(cx.cluster ? "pencolor" : "color", border);
744
+ }
745
+ const borderWidth = get("borderWidth");
746
+ if (typeof borderWidth === "number") {
747
+ out.set("penwidth", borderWidth);
748
+ }
749
+ const borderStyle = get("borderStyle");
750
+ if (typeof borderStyle === "string" && borderStyle !== "solid") {
751
+ const nearest = borderStyle.includes("dash") ? "dashed" : "solid";
752
+ tokens.push(spelled(STROKES, borderStyle, nearest, "borderStyle", approximate));
753
+ }
754
+ }
755
+ function writeNodeShape(get, cx, approximate, out, tokens) {
756
+ const shape = get("shape");
757
+ if (typeof shape !== "string") {
758
+ return "";
759
+ }
760
+ if (shape === "round-rectangle") {
761
+ tokens.push("rounded");
762
+ }
763
+ if (cx.cluster) {
764
+ if (shape !== "rectangle" && shape !== "round-rectangle") {
765
+ approximate("shape", shape);
766
+ }
767
+ return "";
768
+ }
769
+ const gvShape = spelled(SHAPES, shape, shape === "vee" ? "invtriangle" : "box", "shape", approximate);
770
+ out.set("shape", gvShape);
771
+ return gvShape;
772
+ }
773
+ function writeNodeSize(get, out) {
774
+ const width = get("width");
775
+ const height = get("height");
776
+ if (typeof width === "number" || typeof height === "number") {
777
+ out.set("fixedsize", "true");
778
+ }
779
+ if (typeof width === "number") {
780
+ out.set("width", inchesOf(width));
781
+ }
782
+ if (typeof height === "number") {
783
+ out.set("height", inchesOf(height));
784
+ }
785
+ }
786
+ function edgeAttributes(get, directed, approximate) {
787
+ const out = /* @__PURE__ */ new Map();
788
+ const tokens = [];
789
+ writeCommon(get, out, tokens);
790
+ const color = get("color");
791
+ if (typeof color === "string") {
792
+ out.set("color", gvColor(color, get("opacity")));
793
+ }
794
+ const width = get("width");
795
+ if (typeof width === "number") {
796
+ out.set("penwidth", width);
797
+ }
798
+ const line = get("lineStyle");
799
+ if (typeof line === "string" && line !== "solid") {
800
+ tokens.push(spelled(STROKES, line, line.includes("dash") ? "dashed" : "solid", "lineStyle", approximate));
801
+ }
802
+ writeEdgeArrows(get, directed, approximate, out);
803
+ const arrowSize = get("arrowSize");
804
+ if (typeof arrowSize === "number") {
805
+ out.set("arrowsize", arrowSize);
806
+ }
807
+ for (const [property, attribute] of [
808
+ ["label", LABEL_ATTRIBUTE],
809
+ ["targetLabel", "headlabel"],
810
+ ["sourceLabel", "taillabel"]
811
+ ]) {
812
+ const v = get(property);
813
+ if (typeof v === "string") {
814
+ out.set(attribute, escapeLabel(v));
815
+ }
816
+ }
817
+ if (tokens.length > 0) {
818
+ out.set("style", tokens.join(","));
819
+ }
820
+ return withoutDefaults(out, "edge");
821
+ }
822
+ function writeEdgeArrows(get, directed, approximate, out) {
823
+ const source = get("sourceArrow");
824
+ const target = get("targetArrow");
825
+ const tail = typeof source === "string" && source !== "none";
826
+ const head = typeof target === "string" && target !== "none";
827
+ const plain = directed ? head && !tail && target === "triangle" : !head && !tail;
828
+ if (plain || source === null && target === null) {
829
+ return;
830
+ }
831
+ let dir = "none";
832
+ if (head && tail) {
833
+ dir = "both";
834
+ } else if (head) {
835
+ dir = "forward";
836
+ } else if (tail) {
837
+ dir = "back";
838
+ }
839
+ out.set("dir", dir);
840
+ if (head) {
841
+ out.set("arrowhead", spelled(ARROWS, target, "normal", "targetArrow", approximate));
842
+ }
843
+ if (tail) {
844
+ out.set("arrowtail", spelled(ARROWS, source, "normal", "sourceArrow", approximate));
845
+ }
846
+ }
847
+ function getter(picture, target) {
848
+ const columns = /* @__PURE__ */ new Map();
849
+ for (const p of DOT_STYLE_CAPABILITIES[target]) {
850
+ columns.set(p, picture(target, p));
851
+ }
852
+ return (i) => (property) => columns.get(property)?.[i] ?? null;
853
+ }
854
+ function exactFromBlock(snapshot, text, read, cx) {
855
+ const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
856
+ const ex = parsed.ok ? blockStyles(parsed.block, snapshot, "dot") : null;
857
+ if (ex === null) {
858
+ return;
859
+ }
860
+ const notes = new StyleNotes();
861
+ for (const target of ["node", "edge"]) {
862
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
863
+ const get = getter((t, p) => resolveStyles(ex, t, p, snapshot), target);
864
+ const values = read[target];
865
+ for (let i = 0; i < n; i++) {
866
+ const want = get(i);
867
+ const back = writtenAndReadBack(target, i, want, cx, notes);
868
+ for (const property of DOT_STYLE_CAPABILITIES[target]) {
869
+ const native = values[property]?.[i] ?? null;
870
+ const w = want(property);
871
+ if (native !== w && native === (back.get(property) ?? null)) {
872
+ values[property] ??= new Array(n).fill(null);
873
+ values[property][i] = w;
874
+ }
875
+ }
876
+ }
877
+ }
878
+ }
879
+ function writtenAndReadBack(target, i, want, cx, notes) {
880
+ const ignore = () => void 0;
881
+ const back = /* @__PURE__ */ new Map();
882
+ const put = (property, value) => {
883
+ if (value !== null) {
884
+ back.set(property, value);
885
+ }
886
+ };
887
+ const at = (property) => ({ notes, target, property });
888
+ if (target === "node") {
889
+ const ncx = cx.node(i);
890
+ const attrs = nodeAttributes(want, ncx, ignore, notes);
891
+ readNode((name) => textOf(attrs.get(name)), ncx, put, at);
892
+ } else {
893
+ const ecx = cx.edge(i);
894
+ const attrs = edgeAttributes(want, ecx.directed, ignore);
895
+ readEdge((name) => textOf(attrs.get(name)), ecx, put, at);
896
+ }
897
+ return back;
898
+ }
899
+ function textOf(v) {
900
+ return v === void 0 ? null : String(v);
901
+ }
902
+ function readsBack(col) {
903
+ const vals = col.filter((v) => v !== null);
904
+ if (vals.every((v) => typeof v === "number")) {
905
+ return vals.every((v) => Number.isFinite(v));
906
+ }
907
+ if (vals.every((v) => typeof v === "boolean")) {
908
+ return true;
909
+ }
910
+ if (vals.every((v) => typeof v === "string")) {
911
+ return vals.some((v) => inferTextDtype(v) === "string") && vals.every((v) => isWritableDotText(v));
912
+ }
913
+ return false;
914
+ }
915
+ function dotSafeJson(json) {
916
+ return json.replaceAll(/\\(["\\])/g, (_m, c) => c === '"' ? String.raw`\u0022` : String.raw`\u005c`);
917
+ }
918
+ function dotStyledExport(snapshot, input, onMixedDirection) {
919
+ if (input === void 0) {
920
+ return null;
921
+ }
922
+ return sharedInExportCall(
923
+ input,
924
+ [snapshot, onMixedDirection],
925
+ () => styledExport(snapshot, input, onMixedDirection)
926
+ );
927
+ }
928
+ function styledExport(snapshot, input, onMixedDirection) {
929
+ const approximated = new StyleApproximations();
930
+ const replaced = [];
931
+ const out = snapshot.withColumns();
932
+ const written = onMixedDirection === "directed" || onMixedDirection === "undirected";
933
+ const cx = contexts(snapshot, written ? onMixedDirection === "directed" : null);
934
+ const notes = new StyleNotes();
935
+ for (const target of ["node", "edge"]) {
936
+ const table = target === "node" ? out.nodes : out.edges;
937
+ const read = dataRead(input.rules.styles.rules, target);
938
+ const approximate = (property, value) => {
939
+ approximated.add(target, property, value);
940
+ };
941
+ const columns = attributeColumns(snapshot, input, target, { cx, approximate, notes, read });
942
+ replaced.push(...removeStyleAttributes(table, target, columns, read));
943
+ setAttributeColumns(table, columns);
944
+ }
945
+ const { background } = input.rules.styles.graph;
946
+ if (out.graph.has("bgcolor")) {
947
+ out.graph.remove("bgcolor");
948
+ }
949
+ if (typeof background === "string") {
950
+ out.graph.set("bgcolor", [background], { dtype: "string" });
951
+ }
952
+ const inline = [...input.tags.node.values(), ...input.tags.edge.values()].some((col) => !readsBack(col));
953
+ if (!inline) {
954
+ setTagColumns(out, input);
955
+ }
956
+ const block = inline ? writeStyleBlock(input.rules, { inlineColumns: true, snapshot }) : input.block;
957
+ out.graph.set(STYLE_BLOCK_NAME, [dotSafeJson(block)], { dtype: "string" });
958
+ const losses = approximated.notes("Graphviz");
959
+ if (inline) {
960
+ losses.push(...styleBlockLosses(block, input.rules.styles.rules.length, "size"));
961
+ }
962
+ return { snapshot: out, notes: [...replaced, ...losses] };
963
+ }
964
+ function attributeColumns(snapshot, input, target, w) {
965
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
966
+ const get = getter((t, p) => input.picture(t, p), target);
967
+ const columns = /* @__PURE__ */ new Map();
968
+ for (let i = 0; i < n; i++) {
969
+ const attrs = target === "node" ? nodeAttributes(get(i), w.cx.node(i), w.approximate, w.notes) : edgeAttributes(get(i), w.cx.edge(i).directed, w.approximate);
970
+ if (w.read.has(LABEL_ATTRIBUTE) && attrs.get(LABEL_ATTRIBUTE) === "" && get(i)("label") === null) {
971
+ w.approximate("label", "");
972
+ }
973
+ for (const [name, value] of attrs) {
974
+ let col = columns.get(name);
975
+ if (col === void 0) {
976
+ col = new Array(n).fill(null);
977
+ columns.set(name, col);
978
+ }
979
+ col[i] = value;
980
+ }
981
+ }
982
+ return columns;
983
+ }
984
+ function removeStyleAttributes(table, target, columns, read) {
985
+ const attributes = target === "node" ? NODE_ATTRIBUTES : EDGE_ATTRIBUTES;
986
+ const replaced = [];
987
+ for (const name of table.names()) {
988
+ if (!attributes.includes(name) && name !== LABEL_ATTRIBUTE && !name.startsWith("graphty.style.")) {
989
+ continue;
990
+ }
991
+ const differs = read.has(name) ? replacedRows(table, name, columns.get(name)) : 0;
992
+ if (differs > 0) {
993
+ replaced.push(
994
+ Object.freeze({
995
+ code: DOT_ATTRIBUTE_CLASH_CODE,
996
+ message: `${target} column "${name}" is not written: the ${name} attribute holds what graphty draws (${String(differs)} ${target}${differs === 1 ? "" : "s"} differ)`,
997
+ column: name,
998
+ count: differs
999
+ })
1000
+ );
1001
+ }
1002
+ table.remove(name);
1003
+ }
1004
+ return replaced;
1005
+ }
1006
+ function setAttributeColumns(table, columns) {
1007
+ for (const [name, col] of columns) {
1008
+ if (name === LABEL_ATTRIBUTE) {
1009
+ table.set(name, col, { dtype: "string", role: "label" }, { replaceRole: true });
1010
+ } else if (col.every((v) => v === null || typeof v === "number")) {
1011
+ table.set(name, col, { dtype: "f64" });
1012
+ } else {
1013
+ table.set(
1014
+ name,
1015
+ col.map((v) => v === null ? null : String(v)),
1016
+ { dtype: "string" }
1017
+ );
1018
+ }
1019
+ }
1020
+ }
1021
+ function setTagColumns(out, input) {
1022
+ for (const target of ["node", "edge"]) {
1023
+ const table = target === "node" ? out.nodes : out.edges;
1024
+ for (const [name, col] of input.tags[target]) {
1025
+ const kinds = new Set(col.filter((v) => v !== null).map((v) => typeof v));
1026
+ let dtype = "string";
1027
+ if (kinds.has("number")) {
1028
+ dtype = "f64";
1029
+ } else if (kinds.has("boolean")) {
1030
+ dtype = "bool";
1031
+ }
1032
+ table.set(name, col, { dtype });
1033
+ }
1034
+ }
1035
+ }
1036
+ function dataRead(rules, target) {
1037
+ const out = /* @__PURE__ */ new Set();
1038
+ for (const { ext: _ext, ...rule } of rules.filter((r) => r.target === target)) {
1039
+ JSON.stringify(rule, (_k, v) => {
1040
+ if (typeof v === "object" && v !== null && !Array.isArray(v) && Object.keys(v).length === 1) {
1041
+ const { data } = v;
1042
+ if (typeof data === "string") {
1043
+ out.add(data);
1044
+ }
1045
+ }
1046
+ return v;
1047
+ });
1048
+ }
1049
+ return out;
1050
+ }
1051
+ const DOT_ATTRIBUTE_CLASH_CODE = "W_DOT_ATTRIBUTE_CLASH";
1052
+ function replacedRows(table, name, written) {
1053
+ const column = table.get(name);
1054
+ let n = 0;
1055
+ for (let i = 0; column !== null && i < column.length; i++) {
1056
+ const cell = column.isSet(i) ? plainCell(column.value(i)) : null;
1057
+ const w = written?.[i] ?? null;
1058
+ const text = typeof cell === "string" ? cell : JSON.stringify(cell);
1059
+ if (cell !== null && (w === null || String(w) !== text)) {
1060
+ n++;
1061
+ }
1062
+ }
1063
+ return n;
1064
+ }
20
1065
  const DOT_LOSS = Object.freeze({
21
1066
  /**
22
1067
  * An id, name or text with a backslash before a quote or a line break, or at its end, cannot be written as a DOT
@@ -31,7 +1076,7 @@ const DOT_LOSS = Object.freeze({
31
1076
  */
32
1077
  TEXT_INFERRED: LOSS.TEXT_INFERRED,
33
1078
  /** A plain column named like an attribute the exporter writes for a role (weight, key, pos) is not written. */
34
- ATTRIBUTE_CLASH: "W_DOT_ATTRIBUTE_CLASH",
1079
+ ATTRIBUTE_CLASH: DOT_ATTRIBUTE_CLASH_CODE,
35
1080
  /** A mutual pair is written as two directed edges. */
36
1081
  MUTUAL_EXPANDED: LOSS.MUTUAL_EXPANDED,
37
1082
  /** A parents (multi-parent) column cannot be written; DOT clusters nest. */
@@ -48,8 +1093,28 @@ const DOT_LOSS = Object.freeze({
48
1093
  */
49
1094
  ROLE_ASSUMED: LOSS.ROLE_ASSUMED,
50
1095
  /** A parent that is a plain node is written as a node and a cluster of one name; it reads back marked as a cluster. */
51
- CLUSTER_MARKED: "W_DOT_CLUSTER_MARKED"
1096
+ CLUSTER_MARKED: "W_DOT_CLUSTER_MARKED",
1097
+ /** The file is written in UTF-8, so a graph `charset` naming another encoding is written as `UTF-8`. */
1098
+ CHARSET_REWRITTEN: "W_DOT_CHARSET_REWRITTEN"
52
1099
  });
1100
+ const UTF8_CHARSET = /^utf-?8$/i;
1101
+ function charsetNotes(column) {
1102
+ const declared = isCharset(column) && column.isSet(0) ? cellText(column, 0) : null;
1103
+ if (declared === null || UTF8_CHARSET.test(declared)) {
1104
+ return [];
1105
+ }
1106
+ return [
1107
+ Object.freeze({
1108
+ code: DOT_LOSS.CHARSET_REWRITTEN,
1109
+ message: `graph attribute charset ${JSON.stringify(declared)} is written as "UTF-8", the encoding the file is written in`,
1110
+ column: column.meta.name,
1111
+ count: 1
1112
+ })
1113
+ ];
1114
+ }
1115
+ function isCharset(column) {
1116
+ return column.meta.name.toLowerCase() === "charset";
1117
+ }
53
1118
  const KEPT_ROLES = /* @__PURE__ */ new Set(["label", "id", "sourcePort", "targetPort", "parent"]);
54
1119
  const ROLE_NAMES = Object.freeze({
55
1120
  label: LABEL_ATTRIBUTE,
@@ -131,21 +1196,20 @@ const dotExporter = Object.freeze({
131
1196
  format: DOT_FORMAT,
132
1197
  options: Object.freeze(["indent", "name", "strict"]),
133
1198
  capabilities: CAPABILITIES,
1199
+ styles: Object.freeze({ capabilities: DOT_STYLE_CAPABILITIES }),
134
1200
  /**
135
- * Pre-flight: every loss the DOT text would incur, without writing anything.
1201
+ * Pre-flight: every loss the DOT text would incur, without writing anything; with styles, also the values
1202
+ * written as the nearest ones Graphviz has.
136
1203
  * @param snapshot - the snapshot to check
137
1204
  * @param options - format-specific and common options
138
1205
  * @returns the notes, empty when the export is exact
139
1206
  */
140
1207
  check(snapshot, options) {
141
- const resolved = resolveExportOptions(options);
142
- const notes = checkCapabilities(snapshot, CAPABILITIES, resolved, {
143
- positionDtype: "f64",
144
- roles: KEPT_ROLES,
145
- roleNames: ROLE_NAMES
146
- });
147
- const plan = new ExportPlan(snapshot, resolved, options);
148
- return [...notes, ...plan.notes()];
1208
+ const styled = dotStyledExport(snapshot, options?.styles, options?.onMixedDirection);
1209
+ if (styled === null) {
1210
+ return checkPlain(snapshot, options);
1211
+ }
1212
+ return Object.freeze([...checkPlain(styled.snapshot, options), ...styled.notes]);
149
1213
  },
150
1214
  /**
151
1215
  * Write the snapshot as UTF-8 chunks.
@@ -154,7 +1218,12 @@ const dotExporter = Object.freeze({
154
1218
  * @returns the encoded chunks
155
1219
  */
156
1220
  export(snapshot, options) {
157
- return encodeChunks(writeDot(snapshot, options));
1221
+ return encodeChunks(
1222
+ writeDot(
1223
+ dotStyledExport(snapshot, options?.styles, options?.onMixedDirection)?.snapshot ?? snapshot,
1224
+ options
1225
+ )
1226
+ );
158
1227
  },
159
1228
  /**
160
1229
  * Write the snapshot as one string.
@@ -163,9 +1232,24 @@ const dotExporter = Object.freeze({
163
1232
  * @returns the whole document
164
1233
  */
165
1234
  exportToString(snapshot, options) {
166
- return joinText(writeDot(snapshot, options));
1235
+ return joinText(
1236
+ writeDot(
1237
+ dotStyledExport(snapshot, options?.styles, options?.onMixedDirection)?.snapshot ?? snapshot,
1238
+ options
1239
+ )
1240
+ );
167
1241
  }
168
1242
  });
1243
+ function checkPlain(snapshot, options) {
1244
+ const resolved = resolveExportOptions(options);
1245
+ const notes = checkCapabilities(snapshot, CAPABILITIES, resolved, {
1246
+ positionDtype: "f64",
1247
+ roles: KEPT_ROLES,
1248
+ roleNames: ROLE_NAMES
1249
+ });
1250
+ const plan = new ExportPlan(snapshot, resolved, options);
1251
+ return [...notes, ...plan.notes()];
1252
+ }
169
1253
  function* writeDot(snapshot, options) {
170
1254
  const resolved = resolveExportOptions(options);
171
1255
  const plan = new ExportPlan(snapshot, resolved, options);
@@ -175,24 +1259,6 @@ function* writeDot(snapshot, options) {
175
1259
  function endsWithBackslash(text) {
176
1260
  return !isWritableDotText(text);
177
1261
  }
178
- function isHtmlString(text) {
179
- if (text.length < 2 || !text.startsWith("<") || !text.endsWith(">")) {
180
- return false;
181
- }
182
- let depth = 0;
183
- for (let i = 0; i < text.length; i++) {
184
- const c = text.charCodeAt(i);
185
- if (c === 60) {
186
- depth++;
187
- } else if (c === 62) {
188
- depth--;
189
- if (depth === 0 && i !== text.length - 1) {
190
- return false;
191
- }
192
- }
193
- }
194
- return depth === 0;
195
- }
196
1262
  function writeId(text) {
197
1263
  return isHtmlString(text) ? text : quoteDotId(text);
198
1264
  }
@@ -216,6 +1282,69 @@ function badOption(option, found, expected) {
216
1282
  }
217
1283
  );
218
1284
  }
1285
+ function columnNotes(label, column, note) {
1286
+ const { name, role } = column.meta;
1287
+ const text = column.dtype === "string" || column.dtype === "dict";
1288
+ if (label !== "graph" && column.nullCount === column.length) {
1289
+ note(
1290
+ DOT_LOSS.EMPTY_COLUMN_DROPPED,
1291
+ `${label} column "${name}" has no set cell and is not written: DOT writes cells, never declarations`,
1292
+ name,
1293
+ 0
1294
+ );
1295
+ return;
1296
+ }
1297
+ if (label !== "graph" && role === null && name === LABEL_ATTRIBUTE && text) {
1298
+ note(
1299
+ DOT_LOSS.ROLE_ASSUMED,
1300
+ `${label} column "${name}" reads back with the label role`,
1301
+ name,
1302
+ column.length - column.nullCount
1303
+ );
1304
+ }
1305
+ const bad = column.dtype === "f32" || column.dtype === "f64" ? countNonFinite(column) : 0;
1306
+ if (bad > 0) {
1307
+ note(
1308
+ DOT_LOSS.NON_FINITE,
1309
+ `${label} column "${name}" holds ${bad} non-finite value${plural(bad)} with no numeric DOT spelling; they read back as text`,
1310
+ name,
1311
+ bad
1312
+ );
1313
+ }
1314
+ const typed = text && (role === null || !TEXT_ROLES.has(role)) ? countTypedLookingText(column) : 0;
1315
+ if (typed > 0) {
1316
+ note(
1317
+ DOT_LOSS.TEXT_INFERRED,
1318
+ `${label} column "${name}" holds ${typed} text value${plural(typed)} that look like numbers or booleans; DOT values are untyped and they read back as such`,
1319
+ name,
1320
+ typed
1321
+ );
1322
+ }
1323
+ }
1324
+ function positionNotes(snapshot, position, note) {
1325
+ if (position !== null && position.meta.components !== 2 && position.meta.components !== 3) {
1326
+ note(
1327
+ DOT_LOSS.POSITION_SHAPE,
1328
+ `node column "${position.meta.name}" (position) has ${position.meta.components} components and is not written; pos takes 2 or 3`,
1329
+ position.meta.name,
1330
+ position.length - position.nullCount
1331
+ );
1332
+ }
1333
+ for (const [label, table] of [
1334
+ ["edge", snapshot.edges],
1335
+ ["graph", snapshot.graph]
1336
+ ]) {
1337
+ const column = table.byRole("position");
1338
+ if (column !== null) {
1339
+ note(
1340
+ DOT_LOSS.POSITION_SHAPE,
1341
+ `${label} column "${column.meta.name}" (position) is not written; only node positions map to pos`,
1342
+ column.meta.name,
1343
+ column.length - column.nullCount
1344
+ );
1345
+ }
1346
+ }
1347
+ }
219
1348
  class ExportPlan {
220
1349
  /**
221
1350
  * Plan one export.
@@ -264,6 +1393,49 @@ class ExportPlan {
264
1393
  this.children = childrenCsr(snapshot, {
265
1394
  column: this.parent !== null && this.parent.dtype === "u32" ? this.parent : null
266
1395
  });
1396
+ this.nodeColumns = firstSeenOrder(this.nodeColumns, this.nodeTextOrder());
1397
+ const edgeRows = [];
1398
+ for (let e = 0; e < snapshot.edgeCount; e++) {
1399
+ if (!this.folding.folded(e)) {
1400
+ edgeRows.push(e);
1401
+ }
1402
+ }
1403
+ this.edgeColumns = firstSeenOrder(this.edgeColumns, edgeRows);
1404
+ }
1405
+ /**
1406
+ * The nodes in the order a reader of the document takes their attributes: a node's statement before the members
1407
+ * of its cluster, and a cluster's own `graph [...]` attributes when its subgraph closes, after its members.
1408
+ * @returns the node indices
1409
+ */
1410
+ nodeTextOrder() {
1411
+ const order = [];
1412
+ const seen = new Uint8Array(this.snapshot.nodeCount);
1413
+ const stack = [];
1414
+ for (let root = this.snapshot.nodeCount - 1; root >= 0; root--) {
1415
+ stack.push(root);
1416
+ }
1417
+ while (stack.length > 0) {
1418
+ const i = stack.pop();
1419
+ if (i < 0) {
1420
+ order.push(-i - 1);
1421
+ continue;
1422
+ }
1423
+ if (seen[i] === 1) {
1424
+ continue;
1425
+ }
1426
+ seen[i] = 1;
1427
+ const marked = this.cluster !== null && this.cluster.isSet(i) && this.cluster.value(i) === true;
1428
+ if (marked) {
1429
+ stack.push(-i - 1);
1430
+ } else {
1431
+ order.push(i);
1432
+ }
1433
+ const kids = this.children.childrenOf(i);
1434
+ for (let k = kids.length - 1; k >= 0; k--) {
1435
+ stack.push(kids[k]);
1436
+ }
1437
+ }
1438
+ return order;
267
1439
  }
268
1440
  /**
269
1441
  * Whether a node column is written as node attributes.
@@ -363,50 +1535,34 @@ class ExportPlan {
363
1535
  ["graph", this.graphColumns]
364
1536
  ]) {
365
1537
  for (const column of columns) {
366
- if (label !== "graph" && column.nullCount === column.length) {
367
- note(
368
- DOT_LOSS.EMPTY_COLUMN_DROPPED,
369
- `${label} column "${column.meta.name}" has no set cell and is not written: DOT writes cells, never declarations`,
370
- column.meta.name,
371
- 0
372
- );
373
- continue;
374
- }
375
- if (label !== "graph" && column.meta.role === null && column.meta.name === LABEL_ATTRIBUTE && (column.dtype === "string" || column.dtype === "dict")) {
376
- note(
377
- DOT_LOSS.ROLE_ASSUMED,
378
- `${label} column "${column.meta.name}" reads back with the label role`,
379
- column.meta.name,
380
- column.length - column.nullCount
381
- );
382
- }
383
- if (column.dtype === "f32" || column.dtype === "f64") {
384
- const bad = countNonFinite(column);
385
- if (bad > 0) {
386
- note(
387
- DOT_LOSS.NON_FINITE,
388
- `${label} column "${column.meta.name}" holds ${bad} non-finite value${plural(bad)} with no numeric DOT spelling; they read back as text`,
389
- column.meta.name,
390
- bad
391
- );
392
- }
393
- }
394
- if ((column.dtype === "string" || column.dtype === "dict") && (column.meta.role === null || !TEXT_ROLES.has(column.meta.role))) {
395
- const typed = countTypedLookingText(column);
396
- if (typed > 0) {
397
- note(
398
- DOT_LOSS.TEXT_INFERRED,
399
- `${label} column "${column.meta.name}" holds ${typed} text value${plural(typed)} that look like numbers or booleans; DOT values are untyped and they read back as such`,
400
- column.meta.name,
401
- typed
402
- );
403
- }
1538
+ if (label === "graph") {
1539
+ notes.push(...charsetNotes(column));
404
1540
  }
1541
+ columnNotes(label, column, note);
405
1542
  }
406
1543
  }
1544
+ this.structureNotes(note);
1545
+ positionNotes(snapshot, this.position, note);
1546
+ const textIds = countTextIds(snapshot);
1547
+ if (textIds > 0) {
1548
+ note(
1549
+ DOT_LOSS.ID_TEXT_TYPE,
1550
+ `${textIds} node id${plural(textIds)} ${agree(textIds, "reads", "read")} back as the other type under ids: "canonical" (a string "1" becomes 1, a number 1.5 becomes "1.5")`,
1551
+ null,
1552
+ textIds
1553
+ );
1554
+ }
1555
+ return notes;
1556
+ }
1557
+ /**
1558
+ * The notes of the graph's structure DOT changes: parents written as clusters, mutual pairs and parents lists.
1559
+ * @param note - the recorder
1560
+ */
1561
+ structureNotes(note) {
1562
+ const { snapshot } = this;
407
1563
  let unmarked = 0;
408
1564
  for (let i = 0; i < snapshot.nodeCount; i++) {
409
- const marked = this.cluster !== null && this.cluster.isSet(i) && this.cluster.value(i) === true;
1565
+ const marked = this.cluster?.isSet(i) === true && this.cluster.value(i) === true;
410
1566
  if (!marked && this.children.childrenOf(i).length > 0) {
411
1567
  unmarked++;
412
1568
  }
@@ -437,38 +1593,6 @@ class ExportPlan {
437
1593
  parents.length - parents.nullCount
438
1594
  );
439
1595
  }
440
- if (this.position !== null && this.position.meta.components !== 2 && this.position.meta.components !== 3) {
441
- note(
442
- DOT_LOSS.POSITION_SHAPE,
443
- `node column "${this.position.meta.name}" (position) has ${this.position.meta.components} components and is not written; pos takes 2 or 3`,
444
- this.position.meta.name,
445
- this.position.length - this.position.nullCount
446
- );
447
- }
448
- for (const [label, table] of [
449
- ["edge", snapshot.edges],
450
- ["graph", snapshot.graph]
451
- ]) {
452
- const column = table.byRole("position");
453
- if (column !== null) {
454
- note(
455
- DOT_LOSS.POSITION_SHAPE,
456
- `${label} column "${column.meta.name}" (position) is not written; only node positions map to pos`,
457
- column.meta.name,
458
- column.length - column.nullCount
459
- );
460
- }
461
- }
462
- const textIds = countTextIds(snapshot);
463
- if (textIds > 0) {
464
- note(
465
- DOT_LOSS.ID_TEXT_TYPE,
466
- `${textIds} node id${plural(textIds)} ${agree(textIds, "reads", "read")} back as the other type under ids: "canonical" (a string "1" becomes 1, a number 1.5 becomes "1.5")`,
467
- null,
468
- textIds
469
- );
470
- }
471
- return notes;
472
1596
  }
473
1597
  /**
474
1598
  * Throw for the conditions check() reports as errors: mixed direction under "error", and an
@@ -700,7 +1824,10 @@ class ExportPlan {
700
1824
  if (!column.isSet(row)) {
701
1825
  continue;
702
1826
  }
703
- const text = cellText(column, row);
1827
+ let text = cellText(column, row);
1828
+ if (text !== null && columns === this.graphColumns && isCharset(column) && !UTF8_CHARSET.test(text)) {
1829
+ text = "UTF-8";
1830
+ }
704
1831
  if (text !== null) {
705
1832
  out.push(`${quoteDotId(this.attributeName(column))}=${writeId(text)}`);
706
1833
  }
@@ -787,6 +1914,22 @@ function positionDims(column) {
787
1914
  }
788
1915
  return column.meta.components === 2 ? 2 : 3;
789
1916
  }
1917
+ function firstSeenOrder(columns, rows) {
1918
+ const left = new Set(columns);
1919
+ const out = [];
1920
+ for (const row of rows) {
1921
+ if (left.size === 0) {
1922
+ break;
1923
+ }
1924
+ for (const column of columns) {
1925
+ if (left.has(column) && column.isSet(row) && cellText(column, row) !== null) {
1926
+ out.push(column);
1927
+ left.delete(column);
1928
+ }
1929
+ }
1930
+ }
1931
+ return [...out, ...left];
1932
+ }
790
1933
  function cellText(column, row) {
791
1934
  switch (column.dtype) {
792
1935
  case "bool":
@@ -867,6 +2010,53 @@ function countTextIds(snapshot) {
867
2010
  }
868
2011
  return count;
869
2012
  }
2013
+ const POINTS_PER_INCH = 72;
2014
+ function dotPositions(snapshot) {
2015
+ if (snapshot.nodes.byRole("position") === null) {
2016
+ return null;
2017
+ }
2018
+ const bb = snapshot.graph.get("bb");
2019
+ const laidOut = bb !== null && bb.isSet(0) && boxOf(bb.value(0)) !== null;
2020
+ const width = snapshot.nodes.get("width");
2021
+ const widths = [];
2022
+ for (let row = 0; width !== null && row < width.length; row++) {
2023
+ const w = width.isSet(row) ? Number(width.value(row)) : Number.NaN;
2024
+ if (Number.isFinite(w)) {
2025
+ widths.push(laidOut ? w * POINTS_PER_INCH : w);
2026
+ }
2027
+ }
2028
+ return {
2029
+ units: laidOut ? "px" : "file",
2030
+ // input inches are drawn beside the styles' point lengths at 72 points each
2031
+ ...laidOut ? {} : { pxPerUnit: POINTS_PER_INCH },
2032
+ yAxis: "up",
2033
+ groups: clusterBoxes(snapshot),
2034
+ medianNodeSize: median(widths),
2035
+ ...laidOut ? { tool: "graphviz" } : {}
2036
+ };
2037
+ }
2038
+ function clusterBoxes(snapshot) {
2039
+ const bb = snapshot.nodes.get("bb");
2040
+ const out = [];
2041
+ for (let node = 0; bb !== null && node < bb.length; node++) {
2042
+ const box = bb.isSet(node) ? boxOf(bb.value(node)) : null;
2043
+ if (box !== null) {
2044
+ out.push({ node, box });
2045
+ }
2046
+ }
2047
+ return out;
2048
+ }
2049
+ function boxOf(value) {
2050
+ if (typeof value !== "string") {
2051
+ return null;
2052
+ }
2053
+ const parts = value.split(",").map(Number);
2054
+ if (parts.length !== 4 || !parts.every(Number.isFinite)) {
2055
+ return null;
2056
+ }
2057
+ const [llx, lly, urx, ury] = parts;
2058
+ return { x: (llx + urx) / 2, y: (lly + ury) / 2, width: urx - llx, height: ury - lly };
2059
+ }
870
2060
  class DotSyntaxError extends Error {
871
2061
  /**
872
2062
  * Create a syntax error.
@@ -1354,6 +2544,8 @@ const dotImporter = Object.freeze({
1354
2544
  options: Object.freeze(["keepPositionSource", "mismatchedEdgeOperator", "positions"]),
1355
2545
  extensions: EXTENSIONS,
1356
2546
  mimeTypes: MIME_TYPES,
2547
+ styles: dotStyles,
2548
+ positions: dotPositions,
1357
2549
  /**
1358
2550
  * Confidence that the head of an input is DOT: the `[strict] graph | digraph` header after
1359
2551
  * optional comments.
@@ -1765,22 +2957,41 @@ class DotParser {
1765
2957
  }
1766
2958
  throw new DotSyntaxError(`unexpected ${describeToken(token)} at the start of a statement`, token.line);
1767
2959
  }
1768
- if (!token.quoted && !token.html) {
1769
- const keyword = token.text.toLowerCase();
1770
- if (keyword === "node" || keyword === "edge" || keyword === "graph") {
1771
- lexer.next();
1772
- this.attributeStatement(scope, keyword, token.line);
1773
- return;
1774
- }
1775
- if (keyword === "subgraph") {
1776
- const group = this.subgraph(scope);
1777
- this.maybeEdgeStatement(scope, group, token.line);
1778
- return;
1779
- }
1780
- if (keyword === "digraph" || keyword === "strict") {
1781
- throw new DotSyntaxError(`unexpected keyword ${describeToken(token)} inside a graph`, token.line);
1782
- }
2960
+ if (!token.quoted && !token.html && this.keywordStatement(scope, token)) {
2961
+ return;
2962
+ }
2963
+ this.idStatement(scope);
2964
+ }
2965
+ /**
2966
+ * Parse a statement that starts with a keyword: an attribute statement or a subgraph.
2967
+ * @param scope - the scope
2968
+ * @param token - the statement's first token, not yet read
2969
+ * @returns false when the token is no statement keyword (an ID)
2970
+ */
2971
+ keywordStatement(scope, token) {
2972
+ const keyword = token.text.toLowerCase();
2973
+ if (keyword === "node" || keyword === "edge" || keyword === "graph") {
2974
+ this.lexer.next();
2975
+ this.attributeStatement(scope, keyword, token.line);
2976
+ return true;
1783
2977
  }
2978
+ if (keyword === "subgraph") {
2979
+ const group = this.subgraph(scope);
2980
+ this.maybeEdgeStatement(scope, group, token.line);
2981
+ return true;
2982
+ }
2983
+ if (keyword === "digraph" || keyword === "strict") {
2984
+ throw new DotSyntaxError(`unexpected keyword ${describeToken(token)} inside a graph`, token.line);
2985
+ }
2986
+ return false;
2987
+ }
2988
+ /**
2989
+ * Parse a statement that starts with an ID: `ID = ID`, a node statement, or an edge statement starting with a
2990
+ * node.
2991
+ * @param scope - the scope
2992
+ */
2993
+ idStatement(scope) {
2994
+ const { lexer } = this;
1784
2995
  const id = this.identifier();
1785
2996
  if (isPunct(lexer.peek(), "=")) {
1786
2997
  lexer.next();
@@ -1789,6 +3000,10 @@ class DotParser {
1789
3000
  return;
1790
3001
  }
1791
3002
  const port = this.port();
3003
+ if (isPunct(lexer.peek(), ",")) {
3004
+ this.nodeListStatement(scope, [{ id, port }, ...this.moreNodes()]);
3005
+ return;
3006
+ }
1792
3007
  if (isEdgeOp(lexer.peek())) {
1793
3008
  const endpoint = this.mentionEndpoint(scope, id, port);
1794
3009
  this.edgeStatement(scope, endpoint === null ? [] : [endpoint], id.line);
@@ -1796,6 +3011,35 @@ class DotParser {
1796
3011
  }
1797
3012
  this.nodeStatement(scope, id, port);
1798
3013
  }
3014
+ /**
3015
+ * Read the rest of a node list after its first node: `, ID [port]` repeated (`a, b, c`).
3016
+ * @returns the further nodes, in order
3017
+ */
3018
+ moreNodes() {
3019
+ const out = [];
3020
+ while (isPunct(this.lexer.peek(), ",")) {
3021
+ this.lexer.next();
3022
+ const id = this.identifier();
3023
+ out.push({ id, port: this.port() });
3024
+ }
3025
+ return out;
3026
+ }
3027
+ /**
3028
+ * A statement starting with a node list (`a, b [attrs]` or `a, b -> c`): an edge statement from every node of
3029
+ * the list, or a node statement for each.
3030
+ * @param scope - the scope
3031
+ * @param nodes - the listed nodes with their ports
3032
+ */
3033
+ nodeListStatement(scope, nodes) {
3034
+ if (isEdgeOp(this.lexer.peek())) {
3035
+ this.edgeStatement(scope, this.mentionAll(scope, nodes), nodes[0].id.line);
3036
+ return;
3037
+ }
3038
+ const attributes = this.attributeList();
3039
+ for (const n of nodes) {
3040
+ this.applyNodeStatement(scope, n.id, n.port, attributes);
3041
+ }
3042
+ }
1799
3043
  /**
1800
3044
  * Read an ID, concatenating quoted strings joined by `+`.
1801
3045
  * @returns the id token (the concatenation keeps the first token's line and quoted flag)
@@ -2128,7 +3372,16 @@ class DotParser {
2128
3372
  * @param port - the port, if any (dropped with a warning)
2129
3373
  */
2130
3374
  nodeStatement(scope, id, port) {
2131
- const attributes = this.attributeList();
3375
+ this.applyNodeStatement(scope, id, port, this.attributeList());
3376
+ }
3377
+ /**
3378
+ * Mention a node of a node statement and apply the statement's attributes to it.
3379
+ * @param scope - the scope
3380
+ * @param id - the id token
3381
+ * @param port - the port, if any (dropped with a warning)
3382
+ * @param attributes - the statement's attributes
3383
+ */
3384
+ applyNodeStatement(scope, id, port, attributes) {
2132
3385
  const endpoint = this.mentionEndpoint(scope, id, null);
2133
3386
  if (endpoint === null) {
2134
3387
  return;
@@ -2174,20 +3427,35 @@ class DotParser {
2174
3427
  groups.push(this.subgraph(scope));
2175
3428
  } else {
2176
3429
  const id = this.identifier();
2177
- const port = this.port();
2178
- const endpoint = this.mentionEndpoint(scope, id, port);
2179
- groups.push(endpoint === null ? [] : [endpoint]);
3430
+ groups.push(this.mentionAll(scope, [{ id, port: this.port() }, ...this.moreNodes()]));
2180
3431
  }
2181
3432
  }
2182
3433
  const attributes = this.attributeList();
2183
3434
  for (let k = 0; k < kinds.length; k++) {
3435
+ const targets = groups[k + 1];
2184
3436
  for (const source of groups[k]) {
2185
- for (const target of groups[k + 1]) {
3437
+ for (const target of targets) {
2186
3438
  this.pushEdge(scope, source, target, kinds[k], attributes, line);
2187
3439
  }
2188
3440
  }
2189
3441
  }
2190
3442
  }
3443
+ /**
3444
+ * Mention each listed node as an edge endpoint.
3445
+ * @param scope - the scope
3446
+ * @param nodes - the nodes with their ports
3447
+ * @returns the endpoints of the nodes that could be created
3448
+ */
3449
+ mentionAll(scope, nodes) {
3450
+ const group = [];
3451
+ for (const n of nodes) {
3452
+ const endpoint = this.mentionEndpoint(scope, n.id, n.port);
3453
+ if (endpoint !== null) {
3454
+ group.push(endpoint);
3455
+ }
3456
+ }
3457
+ return group;
3458
+ }
2191
3459
  /**
2192
3460
  * The direction of an edge from its operator, checked against the graph keyword.
2193
3461
  * @param op - the operator token
@@ -2718,7 +3986,8 @@ class DotParser {
2718
3986
  export {
2719
3987
  DOT_ISSUE as D,
2720
3988
  DOT_LOSS as a,
2721
- dotImporter as b,
3989
+ DOT_STYLE_CAPABILITIES as b,
3990
+ dotImporter as c,
2722
3991
  dotExporter as d
2723
3992
  };
2724
- //# sourceMappingURL=importer-BbNb7eNg.js.map
3993
+ //# sourceMappingURL=importer-C7pvJe1L.js.map