@graphty/graph-io 0.3.42 → 0.3.44

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