@graphty/graph-io 0.3.43 → 0.3.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (674) hide show
  1. package/dist/chunks/approximations-3Q4TsdTh.js +40 -0
  2. package/dist/chunks/approximations-3Q4TsdTh.js.map +1 -0
  3. package/dist/chunks/block-JQiwViEt.js +2777 -0
  4. package/dist/chunks/block-JQiwViEt.js.map +1 -0
  5. package/dist/chunks/{choose-DvpbdRuz.js → choose-BemygfH8.js} +3 -2
  6. package/dist/chunks/{choose-DvpbdRuz.js.map → choose-BemygfH8.js.map} +1 -1
  7. package/dist/chunks/{constants-fT3E8JYY.js → constants-BFUR_CtU.js} +6 -2
  8. package/dist/chunks/constants-BFUR_CtU.js.map +1 -0
  9. package/dist/chunks/convert-BcQ8_jMo.js +59 -0
  10. package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
  11. package/dist/chunks/emit-DCwFLts5.js +3456 -0
  12. package/dist/chunks/emit-DCwFLts5.js.map +1 -0
  13. package/dist/chunks/{escape-B62ZGM_a.js → escape-B1rMftd9.js} +43 -20
  14. package/dist/chunks/escape-B1rMftd9.js.map +1 -0
  15. package/dist/chunks/{export-rKLeGQMo.js → export-D7IGzTG4.js} +196 -792
  16. package/dist/chunks/export-D7IGzTG4.js.map +1 -0
  17. package/dist/chunks/{exporter-BWwEuOPT.js → exporter-BtnqYuuj.js} +22 -12
  18. package/dist/chunks/exporter-BtnqYuuj.js.map +1 -0
  19. package/dist/chunks/{exporter-yLxKBvLE.js → exporter-ChPyhBOv.js} +4 -3
  20. package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter-ChPyhBOv.js.map} +1 -1
  21. package/dist/chunks/{exporter-8hLNemFk.js → exporter-KEPxYUXD.js} +133 -74
  22. package/dist/chunks/exporter-KEPxYUXD.js.map +1 -0
  23. package/dist/chunks/{exporter-RVtXVetw.js → exporter-quPUCBiC.js} +1805 -287
  24. package/dist/chunks/exporter-quPUCBiC.js.map +1 -0
  25. package/dist/chunks/format-GDmO6m6Q.js +676 -0
  26. package/dist/chunks/format-GDmO6m6Q.js.map +1 -0
  27. package/dist/chunks/generic-BL06jrJf.js +1347 -0
  28. package/dist/chunks/generic-BL06jrJf.js.map +1 -0
  29. package/dist/chunks/{importer-WrGRZb0N.js → importer-B7r2owVf.js} +449 -102
  30. package/dist/chunks/importer-B7r2owVf.js.map +1 -0
  31. package/dist/chunks/{importer-Ht7LNg8L.js → importer-BFmOP96W.js} +116 -296
  32. package/dist/chunks/importer-BFmOP96W.js.map +1 -0
  33. package/dist/chunks/{importer-BbNb7eNg.js → importer-C2nzGhdV.js} +1390 -129
  34. package/dist/chunks/importer-C2nzGhdV.js.map +1 -0
  35. package/dist/chunks/{importer-Dz7tI8Sa.js → importer-CbX2_rNF.js} +617 -115
  36. package/dist/chunks/importer-CbX2_rNF.js.map +1 -0
  37. package/dist/chunks/{importer-D794XUTe.js → importer-CdzeN6X4.js} +31 -8
  38. package/dist/chunks/importer-CdzeN6X4.js.map +1 -0
  39. package/dist/chunks/{importer-xZ-3suY1.js → importer-ChKNC_GN.js} +791 -135
  40. package/dist/chunks/importer-ChKNC_GN.js.map +1 -0
  41. package/dist/chunks/{importer-C98dpSH4.js → importer-dwoYpSqb.js} +141 -82
  42. package/dist/chunks/importer-dwoYpSqb.js.map +1 -0
  43. package/dist/chunks/index-B9fdNpTA.js +4310 -0
  44. package/dist/chunks/index-B9fdNpTA.js.map +1 -0
  45. package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-C4FwgnH5.js} +123 -32
  46. package/dist/chunks/json-elements-C4FwgnH5.js.map +1 -0
  47. package/dist/chunks/lexicon-B-knUi-l.js +508 -0
  48. package/dist/chunks/lexicon-B-knUi-l.js.map +1 -0
  49. package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-BSpbY5FL.js} +3 -2
  50. package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-BSpbY5FL.js.map} +1 -1
  51. package/dist/chunks/{records-Cu4bxYOm.js → records-Nwz_rbNt.js} +2 -2
  52. package/dist/chunks/{records-Cu4bxYOm.js.map → records-Nwz_rbNt.js.map} +1 -1
  53. package/dist/chunks/styles-Brt9JMfs.js +690 -0
  54. package/dist/chunks/styles-Brt9JMfs.js.map +1 -0
  55. package/dist/chunks/styles-_N-C8S-U.js +2102 -0
  56. package/dist/chunks/styles-_N-C8S-U.js.map +1 -0
  57. package/dist/chunks/styles-yed-DAfcIkf7.js +842 -0
  58. package/dist/chunks/styles-yed-DAfcIkf7.js.map +1 -0
  59. package/dist/chunks/{text-DHOJXnED.js → text-CgzMqHQb.js} +2 -2
  60. package/dist/chunks/{text-DHOJXnED.js.map → text-CgzMqHQb.js.map} +1 -1
  61. package/dist/chunks/units-XMZFIFe1.js +19 -0
  62. package/dist/chunks/units-XMZFIFe1.js.map +1 -0
  63. package/dist/csv.js +5 -4
  64. package/dist/csv.js.map +1 -1
  65. package/dist/cx.js +1 -1
  66. package/dist/cx2.js +2 -2
  67. package/dist/cys.js +1 -1
  68. package/dist/dot.js +5 -2
  69. package/dist/dot.js.map +1 -1
  70. package/dist/gexf.js +292 -412
  71. package/dist/gexf.js.map +1 -1
  72. package/dist/gml.js +8 -3031
  73. package/dist/gml.js.map +1 -1
  74. package/dist/graph-io.js +354 -240
  75. package/dist/graph-io.js.map +1 -1
  76. package/dist/graphml.js +4 -2
  77. package/dist/graphml.js.map +1 -1
  78. package/dist/json.js +1 -1
  79. package/dist/neo4j.js +4 -3
  80. package/dist/neo4j.js.map +1 -1
  81. package/dist/obo.js +1 -1
  82. package/dist/pajek.js +4 -2
  83. package/dist/positions.d.ts +1 -0
  84. package/dist/positions.js +427 -0
  85. package/dist/positions.js.map +1 -0
  86. package/dist/src/common/codes.d.ts +6 -0
  87. package/dist/src/common/codes.d.ts.map +1 -1
  88. package/dist/src/common/codes.js +6 -0
  89. package/dist/src/common/codes.js.map +1 -1
  90. package/dist/src/common/escape.d.ts.map +1 -1
  91. package/dist/src/common/escape.js +4 -2
  92. package/dist/src/common/escape.js.map +1 -1
  93. package/dist/src/common/export.d.ts +10 -0
  94. package/dist/src/common/export.d.ts.map +1 -1
  95. package/dist/src/common/export.js +123 -100
  96. package/dist/src/common/export.js.map +1 -1
  97. package/dist/src/common/input.d.ts.map +1 -1
  98. package/dist/src/common/input.js +8 -1
  99. package/dist/src/common/input.js.map +1 -1
  100. package/dist/src/common/json-elements.d.ts +12 -9
  101. package/dist/src/common/json-elements.d.ts.map +1 -1
  102. package/dist/src/common/json-elements.js +160 -37
  103. package/dist/src/common/json-elements.js.map +1 -1
  104. package/dist/src/common/notes.d.ts +42 -0
  105. package/dist/src/common/notes.d.ts.map +1 -0
  106. package/dist/src/common/notes.js +72 -0
  107. package/dist/src/common/notes.js.map +1 -0
  108. package/dist/src/common/report.d.ts +18 -0
  109. package/dist/src/common/report.d.ts.map +1 -1
  110. package/dist/src/common/report.js +36 -1
  111. package/dist/src/common/report.js.map +1 -1
  112. package/dist/src/common/units.d.ts +24 -0
  113. package/dist/src/common/units.d.ts.map +1 -0
  114. package/dist/src/common/units.js +26 -0
  115. package/dist/src/common/units.js.map +1 -0
  116. package/dist/src/common/xml.d.ts +18 -0
  117. package/dist/src/common/xml.d.ts.map +1 -1
  118. package/dist/src/common/xml.js +42 -5
  119. package/dist/src/common/xml.js.map +1 -1
  120. package/dist/src/formats/cx/exporter.d.ts +6 -0
  121. package/dist/src/formats/cx/exporter.d.ts.map +1 -1
  122. package/dist/src/formats/cx/exporter.js +71 -8
  123. package/dist/src/formats/cx/exporter.js.map +1 -1
  124. package/dist/src/formats/cx/importer.d.ts +5 -2
  125. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cx/importer.js +102 -72
  127. package/dist/src/formats/cx/importer.js.map +1 -1
  128. package/dist/src/formats/cx/styles.d.ts +102 -0
  129. package/dist/src/formats/cx/styles.d.ts.map +1 -0
  130. package/dist/src/formats/cx/styles.js +225 -0
  131. package/dist/src/formats/cx/styles.js.map +1 -0
  132. package/dist/src/formats/cx2/exporter.d.ts +5 -0
  133. package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
  134. package/dist/src/formats/cx2/exporter.js +181 -71
  135. package/dist/src/formats/cx2/exporter.js.map +1 -1
  136. package/dist/src/formats/cx2/importer.d.ts +4 -1
  137. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  138. package/dist/src/formats/cx2/importer.js +19 -1
  139. package/dist/src/formats/cx2/importer.js.map +1 -1
  140. package/dist/src/formats/cx2/styles.d.ts +18 -0
  141. package/dist/src/formats/cx2/styles.d.ts.map +1 -0
  142. package/dist/src/formats/cx2/styles.js +24 -0
  143. package/dist/src/formats/cx2/styles.js.map +1 -0
  144. package/dist/src/formats/cys/constants.d.ts +2 -0
  145. package/dist/src/formats/cys/constants.d.ts.map +1 -1
  146. package/dist/src/formats/cys/constants.js +2 -0
  147. package/dist/src/formats/cys/constants.js.map +1 -1
  148. package/dist/src/formats/cys/exporter.d.ts +6 -2
  149. package/dist/src/formats/cys/exporter.d.ts.map +1 -1
  150. package/dist/src/formats/cys/exporter.js +215 -53
  151. package/dist/src/formats/cys/exporter.js.map +1 -1
  152. package/dist/src/formats/cys/importer.d.ts +2 -1
  153. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  154. package/dist/src/formats/cys/importer.js +119 -6
  155. package/dist/src/formats/cys/importer.js.map +1 -1
  156. package/dist/src/formats/cys/session.d.ts +2 -0
  157. package/dist/src/formats/cys/session.d.ts.map +1 -1
  158. package/dist/src/formats/cys/session.js +5 -0
  159. package/dist/src/formats/cys/session.js.map +1 -1
  160. package/dist/src/formats/cys/styles.d.ts +38 -0
  161. package/dist/src/formats/cys/styles.d.ts.map +1 -0
  162. package/dist/src/formats/cys/styles.js +213 -0
  163. package/dist/src/formats/cys/styles.js.map +1 -0
  164. package/dist/src/formats/cys/tables.d.ts +8 -3
  165. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  166. package/dist/src/formats/cys/tables.js +88 -34
  167. package/dist/src/formats/cys/tables.js.map +1 -1
  168. package/dist/src/formats/dot/exporter.d.ts +2 -0
  169. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  170. package/dist/src/formats/dot/exporter.js +195 -81
  171. package/dist/src/formats/dot/exporter.js.map +1 -1
  172. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  173. package/dist/src/formats/dot/importer.js +100 -20
  174. package/dist/src/formats/dot/importer.js.map +1 -1
  175. package/dist/src/formats/dot/index.d.ts +1 -0
  176. package/dist/src/formats/dot/index.d.ts.map +1 -1
  177. package/dist/src/formats/dot/index.js +1 -0
  178. package/dist/src/formats/dot/index.js.map +1 -1
  179. package/dist/src/formats/dot/positions.d.ts +14 -0
  180. package/dist/src/formats/dot/positions.d.ts.map +1 -0
  181. package/dist/src/formats/dot/positions.js +70 -0
  182. package/dist/src/formats/dot/positions.js.map +1 -0
  183. package/dist/src/formats/dot/styles.d.ts +82 -0
  184. package/dist/src/formats/dot/styles.d.ts.map +1 -0
  185. package/dist/src/formats/dot/styles.js +1484 -0
  186. package/dist/src/formats/dot/styles.js.map +1 -0
  187. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  188. package/dist/src/formats/gexf/exporter.js +20 -5
  189. package/dist/src/formats/gexf/exporter.js.map +1 -1
  190. package/dist/src/formats/gexf/importer.d.ts +8 -1
  191. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  192. package/dist/src/formats/gexf/importer.js +251 -131
  193. package/dist/src/formats/gexf/importer.js.map +1 -1
  194. package/dist/src/formats/gexf/index.d.ts +8 -0
  195. package/dist/src/formats/gexf/index.d.ts.map +1 -1
  196. package/dist/src/formats/gexf/index.js +10 -2
  197. package/dist/src/formats/gexf/index.js.map +1 -1
  198. package/dist/src/formats/gexf/schema.d.ts +5 -0
  199. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  200. package/dist/src/formats/gexf/schema.js +5 -0
  201. package/dist/src/formats/gexf/schema.js.map +1 -1
  202. package/dist/src/formats/gexf/styles.d.ts +74 -0
  203. package/dist/src/formats/gexf/styles.d.ts.map +1 -0
  204. package/dist/src/formats/gexf/styles.js +604 -0
  205. package/dist/src/formats/gexf/styles.js.map +1 -0
  206. package/dist/src/formats/gml/exporter.d.ts +1 -5
  207. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  208. package/dist/src/formats/gml/exporter.js +19 -8
  209. package/dist/src/formats/gml/exporter.js.map +1 -1
  210. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  211. package/dist/src/formats/gml/importer.js +4 -0
  212. package/dist/src/formats/gml/importer.js.map +1 -1
  213. package/dist/src/formats/gml/index.d.ts +2 -1
  214. package/dist/src/formats/gml/index.d.ts.map +1 -1
  215. package/dist/src/formats/gml/index.js +2 -1
  216. package/dist/src/formats/gml/index.js.map +1 -1
  217. package/dist/src/formats/gml/positions.d.ts +14 -0
  218. package/dist/src/formats/gml/positions.d.ts.map +1 -0
  219. package/dist/src/formats/gml/positions.js +46 -0
  220. package/dist/src/formats/gml/positions.js.map +1 -0
  221. package/dist/src/formats/gml/styles.d.ts +59 -0
  222. package/dist/src/formats/gml/styles.d.ts.map +1 -0
  223. package/dist/src/formats/gml/styles.js +1056 -0
  224. package/dist/src/formats/gml/styles.js.map +1 -0
  225. package/dist/src/formats/gml/syntax.d.ts +11 -0
  226. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  227. package/dist/src/formats/gml/syntax.js +151 -62
  228. package/dist/src/formats/gml/syntax.js.map +1 -1
  229. package/dist/src/formats/graphml/constants.d.ts +4 -0
  230. package/dist/src/formats/graphml/constants.d.ts.map +1 -1
  231. package/dist/src/formats/graphml/constants.js +5 -1
  232. package/dist/src/formats/graphml/constants.js.map +1 -1
  233. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  234. package/dist/src/formats/graphml/exporter.js +133 -65
  235. package/dist/src/formats/graphml/exporter.js.map +1 -1
  236. package/dist/src/formats/graphml/importer.d.ts +4 -1
  237. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  238. package/dist/src/formats/graphml/importer.js +100 -44
  239. package/dist/src/formats/graphml/importer.js.map +1 -1
  240. package/dist/src/formats/graphml/index.d.ts +1 -0
  241. package/dist/src/formats/graphml/index.d.ts.map +1 -1
  242. package/dist/src/formats/graphml/index.js +1 -0
  243. package/dist/src/formats/graphml/index.js.map +1 -1
  244. package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
  245. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
  246. package/dist/src/formats/graphml/styles-plain.js +187 -0
  247. package/dist/src/formats/graphml/styles-plain.js.map +1 -0
  248. package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
  249. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
  250. package/dist/src/formats/graphml/styles-yed.js +1086 -0
  251. package/dist/src/formats/graphml/styles-yed.js.map +1 -0
  252. package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
  253. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
  254. package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
  255. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
  256. package/dist/src/formats/graphml/tree.d.ts.map +1 -1
  257. package/dist/src/formats/graphml/tree.js +34 -19
  258. package/dist/src/formats/graphml/tree.js.map +1 -1
  259. package/dist/src/formats/graphml/yfiles.d.ts +16 -2
  260. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  261. package/dist/src/formats/graphml/yfiles.js +83 -12
  262. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  263. package/dist/src/formats/json/exporter.d.ts +5 -0
  264. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  265. package/dist/src/formats/json/exporter.js +68 -25
  266. package/dist/src/formats/json/exporter.js.map +1 -1
  267. package/dist/src/formats/json/importer.d.ts +22 -3
  268. package/dist/src/formats/json/importer.d.ts.map +1 -1
  269. package/dist/src/formats/json/importer.js +439 -264
  270. package/dist/src/formats/json/importer.js.map +1 -1
  271. package/dist/src/formats/json/positions.d.ts +16 -0
  272. package/dist/src/formats/json/positions.d.ts.map +1 -0
  273. package/dist/src/formats/json/positions.js +44 -0
  274. package/dist/src/formats/json/positions.js.map +1 -0
  275. package/dist/src/formats/json/styles.d.ts +102 -0
  276. package/dist/src/formats/json/styles.d.ts.map +1 -0
  277. package/dist/src/formats/json/styles.js +1753 -0
  278. package/dist/src/formats/json/styles.js.map +1 -0
  279. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  280. package/dist/src/formats/neo4j/exporter.js +2 -1
  281. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  282. package/dist/src/formats/pajek/exporter.d.ts +2 -0
  283. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  284. package/dist/src/formats/pajek/exporter.js +142 -76
  285. package/dist/src/formats/pajek/exporter.js.map +1 -1
  286. package/dist/src/formats/pajek/importer.d.ts +4 -0
  287. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  288. package/dist/src/formats/pajek/importer.js +60 -6
  289. package/dist/src/formats/pajek/importer.js.map +1 -1
  290. package/dist/src/formats/pajek/index.d.ts +2 -0
  291. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  292. package/dist/src/formats/pajek/index.js +2 -0
  293. package/dist/src/formats/pajek/index.js.map +1 -1
  294. package/dist/src/formats/pajek/styles.d.ts +50 -0
  295. package/dist/src/formats/pajek/styles.d.ts.map +1 -0
  296. package/dist/src/formats/pajek/styles.js +569 -0
  297. package/dist/src/formats/pajek/styles.js.map +1 -0
  298. package/dist/src/formats/pajek/syntax.d.ts +6 -0
  299. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  300. package/dist/src/formats/pajek/syntax.js +6 -0
  301. package/dist/src/formats/pajek/syntax.js.map +1 -1
  302. package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
  303. package/dist/src/formats/xgmml/columns.js +34 -9
  304. package/dist/src/formats/xgmml/columns.js.map +1 -1
  305. package/dist/src/formats/xgmml/constants.d.ts +2 -0
  306. package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
  307. package/dist/src/formats/xgmml/constants.js +3 -1
  308. package/dist/src/formats/xgmml/constants.js.map +1 -1
  309. package/dist/src/formats/xgmml/document.d.ts +12 -8
  310. package/dist/src/formats/xgmml/document.d.ts.map +1 -1
  311. package/dist/src/formats/xgmml/document.js +56 -13
  312. package/dist/src/formats/xgmml/document.js.map +1 -1
  313. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  314. package/dist/src/formats/xgmml/emit.js +12 -6
  315. package/dist/src/formats/xgmml/emit.js.map +1 -1
  316. package/dist/src/formats/xgmml/exporter.d.ts +3 -1
  317. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  318. package/dist/src/formats/xgmml/exporter.js +22 -9
  319. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  320. package/dist/src/formats/xgmml/importer.d.ts +2 -1
  321. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  322. package/dist/src/formats/xgmml/importer.js +31 -24
  323. package/dist/src/formats/xgmml/importer.js.map +1 -1
  324. package/dist/src/formats/xgmml/styles.d.ts +104 -0
  325. package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
  326. package/dist/src/formats/xgmml/styles.js +310 -0
  327. package/dist/src/formats/xgmml/styles.js.map +1 -0
  328. package/dist/src/index.d.ts +9 -7
  329. package/dist/src/index.d.ts.map +1 -1
  330. package/dist/src/index.js +7 -7
  331. package/dist/src/index.js.map +1 -1
  332. package/dist/src/positions/codes.d.ts +31 -0
  333. package/dist/src/positions/codes.d.ts.map +1 -0
  334. package/dist/src/positions/codes.js +26 -0
  335. package/dist/src/positions/codes.js.map +1 -0
  336. package/dist/src/positions/convert.d.ts +58 -0
  337. package/dist/src/positions/convert.d.ts.map +1 -0
  338. package/dist/src/positions/convert.js +107 -0
  339. package/dist/src/positions/convert.js.map +1 -0
  340. package/dist/src/positions/extract.d.ts +27 -0
  341. package/dist/src/positions/extract.d.ts.map +1 -0
  342. package/dist/src/positions/extract.js +526 -0
  343. package/dist/src/positions/extract.js.map +1 -0
  344. package/dist/src/positions/index.d.ts +10 -0
  345. package/dist/src/positions/index.d.ts.map +1 -0
  346. package/dist/src/positions/index.js +9 -0
  347. package/dist/src/positions/index.js.map +1 -0
  348. package/dist/src/positions/types.d.ts +208 -0
  349. package/dist/src/positions/types.d.ts.map +1 -0
  350. package/dist/src/positions/types.js +10 -0
  351. package/dist/src/positions/types.js.map +1 -0
  352. package/dist/src/registry.d.ts +30 -0
  353. package/dist/src/registry.d.ts.map +1 -1
  354. package/dist/src/registry.js +130 -9
  355. package/dist/src/registry.js.map +1 -1
  356. package/dist/src/styles/annotations.d.ts +132 -0
  357. package/dist/src/styles/annotations.d.ts.map +1 -0
  358. package/dist/src/styles/annotations.js +320 -0
  359. package/dist/src/styles/annotations.js.map +1 -0
  360. package/dist/src/styles/budget.d.ts +45 -0
  361. package/dist/src/styles/budget.d.ts.map +1 -0
  362. package/dist/src/styles/budget.js +58 -0
  363. package/dist/src/styles/budget.js.map +1 -0
  364. package/dist/src/styles/canon/bends.d.ts +32 -0
  365. package/dist/src/styles/canon/bends.d.ts.map +1 -0
  366. package/dist/src/styles/canon/bends.js +74 -0
  367. package/dist/src/styles/canon/bends.js.map +1 -0
  368. package/dist/src/styles/canon/color-tables.d.ts +22 -0
  369. package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
  370. package/dist/src/styles/canon/color-tables.js +369 -0
  371. package/dist/src/styles/canon/color-tables.js.map +1 -0
  372. package/dist/src/styles/canon/color.d.ts +66 -0
  373. package/dist/src/styles/canon/color.d.ts.map +1 -0
  374. package/dist/src/styles/canon/color.js +548 -0
  375. package/dist/src/styles/canon/color.js.map +1 -0
  376. package/dist/src/styles/canon/enums.d.ts +25 -0
  377. package/dist/src/styles/canon/enums.d.ts.map +1 -0
  378. package/dist/src/styles/canon/enums.js +187 -0
  379. package/dist/src/styles/canon/enums.js.map +1 -0
  380. package/dist/src/styles/canon/graphviz.d.ts +48 -0
  381. package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
  382. package/dist/src/styles/canon/graphviz.js +160 -0
  383. package/dist/src/styles/canon/graphviz.js.map +1 -0
  384. package/dist/src/styles/canon/index.d.ts +13 -0
  385. package/dist/src/styles/canon/index.d.ts.map +1 -0
  386. package/dist/src/styles/canon/index.js +13 -0
  387. package/dist/src/styles/canon/index.js.map +1 -0
  388. package/dist/src/styles/canon/number.d.ts +59 -0
  389. package/dist/src/styles/canon/number.d.ts.map +1 -0
  390. package/dist/src/styles/canon/number.js +142 -0
  391. package/dist/src/styles/canon/number.js.map +1 -0
  392. package/dist/src/styles/canon/site.d.ts +51 -0
  393. package/dist/src/styles/canon/site.d.ts.map +1 -0
  394. package/dist/src/styles/canon/site.js +63 -0
  395. package/dist/src/styles/canon/site.js.map +1 -0
  396. package/dist/src/styles/canon/text.d.ts +61 -0
  397. package/dist/src/styles/canon/text.d.ts.map +1 -0
  398. package/dist/src/styles/canon/text.js +199 -0
  399. package/dist/src/styles/canon/text.js.map +1 -0
  400. package/dist/src/styles/codes.d.ts +95 -0
  401. package/dist/src/styles/codes.d.ts.map +1 -0
  402. package/dist/src/styles/codes.js +97 -0
  403. package/dist/src/styles/codes.js.map +1 -0
  404. package/dist/src/styles/cyjs/cascade.d.ts +134 -0
  405. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
  406. package/dist/src/styles/cyjs/cascade.js +2252 -0
  407. package/dist/src/styles/cyjs/cascade.js.map +1 -0
  408. package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
  409. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
  410. package/dist/src/styles/cyjs/defaults-table.js +76 -0
  411. package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
  412. package/dist/src/styles/cyjs/emit.d.ts +82 -0
  413. package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
  414. package/dist/src/styles/cyjs/emit.js +790 -0
  415. package/dist/src/styles/cyjs/emit.js.map +1 -0
  416. package/dist/src/styles/cyjs/index.d.ts +13 -0
  417. package/dist/src/styles/cyjs/index.d.ts.map +1 -0
  418. package/dist/src/styles/cyjs/index.js +13 -0
  419. package/dist/src/styles/cyjs/index.js.map +1 -0
  420. package/dist/src/styles/cyjs/live.d.ts +46 -0
  421. package/dist/src/styles/cyjs/live.d.ts.map +1 -0
  422. package/dist/src/styles/cyjs/live.js +108 -0
  423. package/dist/src/styles/cyjs/live.js.map +1 -0
  424. package/dist/src/styles/cyjs/mappers.d.ts +147 -0
  425. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
  426. package/dist/src/styles/cyjs/mappers.js +744 -0
  427. package/dist/src/styles/cyjs/mappers.js.map +1 -0
  428. package/dist/src/styles/cyjs/selector.d.ts +113 -0
  429. package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
  430. package/dist/src/styles/cyjs/selector.js +611 -0
  431. package/dist/src/styles/cyjs/selector.js.map +1 -0
  432. package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
  433. package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
  434. package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
  435. package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
  436. package/dist/src/styles/cytoscape/emit.d.ts +125 -0
  437. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
  438. package/dist/src/styles/cytoscape/emit.js +1025 -0
  439. package/dist/src/styles/cytoscape/emit.js.map +1 -0
  440. package/dist/src/styles/cytoscape/index.d.ts +10 -0
  441. package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
  442. package/dist/src/styles/cytoscape/index.js +10 -0
  443. package/dist/src/styles/cytoscape/index.js.map +1 -0
  444. package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
  445. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
  446. package/dist/src/styles/cytoscape/lexicon.js +603 -0
  447. package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
  448. package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
  449. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
  450. package/dist/src/styles/cytoscape/mappings.js +460 -0
  451. package/dist/src/styles/cytoscape/mappings.js.map +1 -0
  452. package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
  453. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
  454. package/dist/src/styles/cytoscape/resolve.js +381 -0
  455. package/dist/src/styles/cytoscape/resolve.js.map +1 -0
  456. package/dist/src/styles/cytoscape/translate.d.ts +50 -0
  457. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
  458. package/dist/src/styles/cytoscape/translate.js +156 -0
  459. package/dist/src/styles/cytoscape/translate.js.map +1 -0
  460. package/dist/src/styles/defaults.d.ts +90 -0
  461. package/dist/src/styles/defaults.d.ts.map +1 -0
  462. package/dist/src/styles/defaults.js +414 -0
  463. package/dist/src/styles/defaults.js.map +1 -0
  464. package/dist/src/styles/index.d.ts +15 -0
  465. package/dist/src/styles/index.d.ts.map +1 -0
  466. package/dist/src/styles/index.js +14 -0
  467. package/dist/src/styles/index.js.map +1 -0
  468. package/dist/src/styles/internal.d.ts +17 -0
  469. package/dist/src/styles/internal.d.ts.map +1 -0
  470. package/dist/src/styles/internal.js +16 -0
  471. package/dist/src/styles/internal.js.map +1 -0
  472. package/dist/src/styles/io/approximations.d.ts +24 -0
  473. package/dist/src/styles/io/approximations.d.ts.map +1 -0
  474. package/dist/src/styles/io/approximations.js +51 -0
  475. package/dist/src/styles/io/approximations.js.map +1 -0
  476. package/dist/src/styles/io/block.d.ts +166 -0
  477. package/dist/src/styles/io/block.d.ts.map +1 -0
  478. package/dist/src/styles/io/block.js +930 -0
  479. package/dist/src/styles/io/block.js.map +1 -0
  480. package/dist/src/styles/io/generic.d.ts +88 -0
  481. package/dist/src/styles/io/generic.d.ts.map +1 -0
  482. package/dist/src/styles/io/generic.js +516 -0
  483. package/dist/src/styles/io/generic.js.map +1 -0
  484. package/dist/src/styles/io/index.d.ts +8 -0
  485. package/dist/src/styles/io/index.d.ts.map +1 -0
  486. package/dist/src/styles/io/index.js +7 -0
  487. package/dist/src/styles/io/index.js.map +1 -0
  488. package/dist/src/styles/io/writer.d.ts +80 -0
  489. package/dist/src/styles/io/writer.d.ts.map +1 -0
  490. package/dist/src/styles/io/writer.js +596 -0
  491. package/dist/src/styles/io/writer.js.map +1 -0
  492. package/dist/src/styles/notes.d.ts +47 -0
  493. package/dist/src/styles/notes.d.ts.map +1 -0
  494. package/dist/src/styles/notes.js +140 -0
  495. package/dist/src/styles/notes.js.map +1 -0
  496. package/dist/src/styles/plan/classes.d.ts +31 -0
  497. package/dist/src/styles/plan/classes.d.ts.map +1 -0
  498. package/dist/src/styles/plan/classes.js +139 -0
  499. package/dist/src/styles/plan/classes.js.map +1 -0
  500. package/dist/src/styles/plan/continuous.d.ts +32 -0
  501. package/dist/src/styles/plan/continuous.d.ts.map +1 -0
  502. package/dist/src/styles/plan/continuous.js +165 -0
  503. package/dist/src/styles/plan/continuous.js.map +1 -0
  504. package/dist/src/styles/plan/discrete.d.ts +39 -0
  505. package/dist/src/styles/plan/discrete.d.ts.map +1 -0
  506. package/dist/src/styles/plan/discrete.js +127 -0
  507. package/dist/src/styles/plan/discrete.js.map +1 -0
  508. package/dist/src/styles/plan/families.d.ts +31 -0
  509. package/dist/src/styles/plan/families.d.ts.map +1 -0
  510. package/dist/src/styles/plan/families.js +95 -0
  511. package/dist/src/styles/plan/families.js.map +1 -0
  512. package/dist/src/styles/plan/features.d.ts +58 -0
  513. package/dist/src/styles/plan/features.d.ts.map +1 -0
  514. package/dist/src/styles/plan/features.js +185 -0
  515. package/dist/src/styles/plan/features.js.map +1 -0
  516. package/dist/src/styles/plan/index.d.ts +7 -0
  517. package/dist/src/styles/plan/index.d.ts.map +1 -0
  518. package/dist/src/styles/plan/index.js +7 -0
  519. package/dist/src/styles/plan/index.js.map +1 -0
  520. package/dist/src/styles/plan/plan.d.ts +71 -0
  521. package/dist/src/styles/plan/plan.d.ts.map +1 -0
  522. package/dist/src/styles/plan/plan.js +893 -0
  523. package/dist/src/styles/plan/plan.js.map +1 -0
  524. package/dist/src/styles/plan/resolve.d.ts +137 -0
  525. package/dist/src/styles/plan/resolve.d.ts.map +1 -0
  526. package/dist/src/styles/plan/resolve.js +587 -0
  527. package/dist/src/styles/plan/resolve.js.map +1 -0
  528. package/dist/src/styles/types.d.ts +702 -0
  529. package/dist/src/styles/types.d.ts.map +1 -0
  530. package/dist/src/styles/types.js +10 -0
  531. package/dist/src/styles/types.js.map +1 -0
  532. package/dist/src/styles/vocabulary.d.ts +41 -0
  533. package/dist/src/styles/vocabulary.d.ts.map +1 -0
  534. package/dist/src/styles/vocabulary.js +140 -0
  535. package/dist/src/styles/vocabulary.js.map +1 -0
  536. package/dist/src/types.d.ts +64 -1
  537. package/dist/src/types.d.ts.map +1 -1
  538. package/dist/src/types.js.map +1 -1
  539. package/dist/styles.d.ts +1 -0
  540. package/dist/styles.js +322 -0
  541. package/dist/styles.js.map +1 -0
  542. package/dist/xgmml.js +5 -4
  543. package/dist/xgmml.js.map +1 -1
  544. package/package.json +13 -2
  545. package/src/common/codes.ts +7 -0
  546. package/src/common/escape.ts +5 -2
  547. package/src/common/export.ts +179 -140
  548. package/src/common/input.ts +8 -4
  549. package/src/common/json-elements.ts +169 -38
  550. package/src/common/notes.ts +94 -0
  551. package/src/common/report.ts +41 -1
  552. package/src/common/units.ts +42 -0
  553. package/src/common/xml.ts +45 -5
  554. package/src/formats/cx/exporter.ts +95 -11
  555. package/src/formats/cx/importer.ts +126 -90
  556. package/src/formats/cx/styles.ts +304 -0
  557. package/src/formats/cx2/exporter.ts +234 -77
  558. package/src/formats/cx2/importer.ts +19 -1
  559. package/src/formats/cx2/styles.ts +29 -0
  560. package/src/formats/cys/constants.ts +3 -0
  561. package/src/formats/cys/exporter.ts +246 -60
  562. package/src/formats/cys/importer.ts +125 -9
  563. package/src/formats/cys/session.ts +6 -0
  564. package/src/formats/cys/styles.ts +254 -0
  565. package/src/formats/cys/tables.ts +117 -48
  566. package/src/formats/dot/exporter.ts +262 -126
  567. package/src/formats/dot/importer.ts +111 -20
  568. package/src/formats/dot/index.ts +1 -0
  569. package/src/formats/dot/positions.ts +77 -0
  570. package/src/formats/dot/styles.ts +1741 -0
  571. package/src/formats/gexf/exporter.ts +27 -11
  572. package/src/formats/gexf/importer.ts +308 -158
  573. package/src/formats/gexf/index.ts +10 -0
  574. package/src/formats/gexf/schema.ts +5 -0
  575. package/src/formats/gexf/styles.ts +719 -0
  576. package/src/formats/gml/exporter.ts +33 -14
  577. package/src/formats/gml/importer.ts +4 -0
  578. package/src/formats/gml/index.ts +2 -1
  579. package/src/formats/gml/positions.ts +52 -0
  580. package/src/formats/gml/styles.ts +1248 -0
  581. package/src/formats/gml/syntax.ts +173 -62
  582. package/src/formats/graphml/constants.ts +5 -0
  583. package/src/formats/graphml/exporter.ts +163 -71
  584. package/src/formats/graphml/importer.ts +119 -45
  585. package/src/formats/graphml/index.ts +1 -0
  586. package/src/formats/graphml/styles-plain.ts +236 -0
  587. package/src/formats/graphml/styles-yed.ts +1221 -0
  588. package/src/formats/graphml/styles-yfiles3.ts +573 -0
  589. package/src/formats/graphml/tree.ts +36 -20
  590. package/src/formats/graphml/yfiles.ts +89 -13
  591. package/src/formats/json/exporter.ts +76 -26
  592. package/src/formats/json/importer.ts +541 -322
  593. package/src/formats/json/positions.ts +50 -0
  594. package/src/formats/json/styles.ts +2082 -0
  595. package/src/formats/neo4j/exporter.ts +2 -1
  596. package/src/formats/pajek/exporter.ts +195 -106
  597. package/src/formats/pajek/importer.ts +78 -9
  598. package/src/formats/pajek/index.ts +2 -0
  599. package/src/formats/pajek/styles.ts +685 -0
  600. package/src/formats/pajek/syntax.ts +7 -0
  601. package/src/formats/xgmml/columns.ts +39 -9
  602. package/src/formats/xgmml/constants.ts +3 -0
  603. package/src/formats/xgmml/document.ts +54 -12
  604. package/src/formats/xgmml/emit.ts +11 -6
  605. package/src/formats/xgmml/exporter.ts +32 -13
  606. package/src/formats/xgmml/importer.ts +43 -29
  607. package/src/formats/xgmml/styles.ts +400 -0
  608. package/src/index.ts +16 -0
  609. package/src/positions/codes.ts +32 -0
  610. package/src/positions/convert.ts +123 -0
  611. package/src/positions/extract.ts +619 -0
  612. package/src/positions/index.ts +23 -0
  613. package/src/positions/types.ts +221 -0
  614. package/src/registry.ts +179 -8
  615. package/src/styles/annotations.ts +478 -0
  616. package/src/styles/budget.ts +60 -0
  617. package/src/styles/canon/bends.ts +84 -0
  618. package/src/styles/canon/color-tables.ts +386 -0
  619. package/src/styles/canon/color.ts +624 -0
  620. package/src/styles/canon/enums.ts +211 -0
  621. package/src/styles/canon/graphviz.ts +189 -0
  622. package/src/styles/canon/index.ts +13 -0
  623. package/src/styles/canon/number.ts +152 -0
  624. package/src/styles/canon/site.ts +87 -0
  625. package/src/styles/canon/text.ts +221 -0
  626. package/src/styles/codes.ts +104 -0
  627. package/src/styles/cyjs/cascade.ts +2670 -0
  628. package/src/styles/cyjs/defaults-table.ts +82 -0
  629. package/src/styles/cyjs/emit.ts +951 -0
  630. package/src/styles/cyjs/index.ts +37 -0
  631. package/src/styles/cyjs/live.ts +147 -0
  632. package/src/styles/cyjs/mappers.ts +879 -0
  633. package/src/styles/cyjs/selector.ts +778 -0
  634. package/src/styles/cyjs/stylesheet-text.ts +214 -0
  635. package/src/styles/cytoscape/emit.ts +1264 -0
  636. package/src/styles/cytoscape/index.ts +40 -0
  637. package/src/styles/cytoscape/lexicon.ts +656 -0
  638. package/src/styles/cytoscape/mappings.ts +603 -0
  639. package/src/styles/cytoscape/resolve.ts +521 -0
  640. package/src/styles/cytoscape/translate.ts +237 -0
  641. package/src/styles/defaults.ts +504 -0
  642. package/src/styles/index.ts +57 -0
  643. package/src/styles/internal.ts +17 -0
  644. package/src/styles/io/approximations.ts +47 -0
  645. package/src/styles/io/block.ts +1138 -0
  646. package/src/styles/io/generic.ts +687 -0
  647. package/src/styles/io/index.ts +18 -0
  648. package/src/styles/io/writer.ts +745 -0
  649. package/src/styles/notes.ts +165 -0
  650. package/src/styles/plan/classes.ts +166 -0
  651. package/src/styles/plan/continuous.ts +218 -0
  652. package/src/styles/plan/discrete.ts +165 -0
  653. package/src/styles/plan/families.ts +115 -0
  654. package/src/styles/plan/features.ts +234 -0
  655. package/src/styles/plan/index.ts +7 -0
  656. package/src/styles/plan/plan.ts +1129 -0
  657. package/src/styles/plan/resolve.ts +685 -0
  658. package/src/styles/types.ts +814 -0
  659. package/src/styles/vocabulary.ts +172 -0
  660. package/src/types.ts +76 -1
  661. package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
  662. package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
  663. package/dist/chunks/export-rKLeGQMo.js.map +0 -1
  664. package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
  665. package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
  666. package/dist/chunks/exporter-RVtXVetw.js.map +0 -1
  667. package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
  668. package/dist/chunks/importer-C98dpSH4.js.map +0 -1
  669. package/dist/chunks/importer-D794XUTe.js.map +0 -1
  670. package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
  671. package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
  672. package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
  673. package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
  674. package/dist/chunks/json-elements-DKSqpNW1.js.map +0 -1
@@ -0,0 +1,1056 @@
1
+ /**
2
+ * GML styles: each node's and edge's `graphics [ ... ]` and `LabelGraphics [ ... ]` records read the way the program
3
+ * that wrote the file draws them, and a graph's styles written back as yEd GML graphics.
4
+ *
5
+ * GML has one syntax and many vocabularies. The `Creator` line (top level, or inside the graph as Gephi writes it,
6
+ * quoted or not) names the writer: yEd and yFiles, Cytoscape, Gephi, OGDF and igraph are recognized; every other file
7
+ * (NetworkX writes no `Creator`) is read with the keys of the GML draft (Graphlet). A recognized drawing program's
8
+ * defaults go beneath the file's own values; igraph and unknown writers get none.
9
+ *
10
+ * Writing: the yEd keys (`fill`, `outline`, `outlineWidth`, `outlineStyle`, `w`, `h`, `type`; edge `fill`, `width`,
11
+ * `style`, `sourceArrow`, `targetArrow`, `smoothBends`; `LabelGraphics` `text`, `color`, `fontSize`, `fontName`,
12
+ * `fontStyle`) replace every style key any reader here reads, inside the records the graph already has, so positions,
13
+ * bends and other keys stay. The `graphty.styles` block and the per-element values its rules read are keys too,
14
+ * named by the GML writer's rule for names that are not GML keys (`graphty_styles`, `graphty_style_node_<key>`).
15
+ */
16
+ import { bendsToPoints, canonBends } from "../../styles/canon/bends.js";
17
+ import { canonColor, colorOpacity } from "../../styles/canon/color.js";
18
+ import { canonEnum } from "../../styles/canon/enums.js";
19
+ import { canonNumber } from "../../styles/canon/number.js";
20
+ import { MAX_STYLE_VALUE_LENGTH, noteAt, scalarText } from "../../styles/canon/site.js";
21
+ import { canonText } from "../../styles/canon/text.js";
22
+ import { STYLE_ISSUE } from "../../styles/codes.js";
23
+ import { CYTOSCAPE_LEXICON } from "../../styles/cytoscape/lexicon.js";
24
+ import { StyleApproximations } from "../../styles/io/approximations.js";
25
+ import { blockStyles, parseStyleBlock, STYLE_BLOCK_NAME, styleBlockLosses, styleTag, writeStyleBlock, } from "../../styles/io/block.js";
26
+ import { dataRead } from "../../styles/io/writer.js";
27
+ import { StyleNotes } from "../../styles/notes.js";
28
+ import { styleFingerprint } from "../../styles/plan/features.js";
29
+ import { plainCell, resolveStyles } from "../../styles/plan/resolve.js";
30
+ import { gephiRules } from "../gexf/styles.js";
31
+ import { flowchartShape, FONT_STYLES, valueColumns, YED_ARROWS, YED_LINES, YED_SHAPES, yedColor, yedSpelled, yedValue, } from "../graphml/styles-yed.js";
32
+ import { KEY_MANGLED_CODE, mangleGmlKey } from "./syntax.js";
33
+ /** The writers recognized by their `Creator` text, first match wins. */
34
+ const WRITERS = [
35
+ [
36
+ /^\s*(yfiles|yed)\b/i,
37
+ { dialect: "yed", tool: "yed", vocabulary: "yed", spelling: "yed", units: "px", labelKey: false },
38
+ ],
39
+ [
40
+ /^\s*cytoscape\b/i,
41
+ {
42
+ dialect: "cytoscape",
43
+ tool: "cytoscape",
44
+ vocabulary: "cytoscape",
45
+ spelling: "cytoscape",
46
+ units: "px",
47
+ labelKey: true,
48
+ },
49
+ ],
50
+ [
51
+ /^\s*gephi\b/i,
52
+ {
53
+ dialect: "gephi",
54
+ tool: "gephi",
55
+ vocabulary: "graphlet",
56
+ spelling: "css",
57
+ units: "relative",
58
+ labelKey: false,
59
+ },
60
+ ],
61
+ [
62
+ /^\s*ogdf::/i,
63
+ { dialect: "ogdf", tool: "ogdf", vocabulary: "ogdf", spelling: "css", units: "px", labelKey: true },
64
+ ],
65
+ // igraph writes a Creator line, but no drawing defaults of igraph's are stated by a primary source
66
+ [
67
+ /^\s*igraph\b/i,
68
+ { dialect: "igraph", tool: null, vocabulary: "graphlet", spelling: "css", units: "px", labelKey: true },
69
+ ],
70
+ ];
71
+ /** Any other writer (NetworkX, SNDlib, hand-written files): the GML draft's keys, no defaults. */
72
+ const UNKNOWN_WRITER = {
73
+ dialect: "gml",
74
+ tool: null,
75
+ vocabulary: "graphlet",
76
+ spelling: "css",
77
+ units: "px",
78
+ labelKey: true,
79
+ };
80
+ /** A file graphty wrote: yEd keys, and the `graphty.styles` block gives the rules. */
81
+ const GRAPHTY_WRITER = { ...WRITERS[0][1], tool: null };
82
+ /**
83
+ * The graph key holding the `graphty.styles` block: the block's name under the GML writer's rule for names that are
84
+ * not GML keys.
85
+ * @category Built-in formats
86
+ */
87
+ export const GML_STYLE_BLOCK_KEY = mangleGmlKey(STYLE_BLOCK_NAME);
88
+ /** The key prefix of the per-element style values (`graphty.style.` under the same rule). */
89
+ const TAG_PREFIX = mangleGmlKey("graphty.style.");
90
+ /**
91
+ * The GML key of one style column's per-element values.
92
+ * @param target - nodes or edges
93
+ * @param key - the style column's key
94
+ * @returns the key
95
+ */
96
+ function tagKey(target, key) {
97
+ return mangleGmlKey(styleTag(target, key));
98
+ }
99
+ /**
100
+ * A graph value as text, or null.
101
+ * @param snapshot - the graph
102
+ * @param name - the graph column
103
+ * @returns the text
104
+ */
105
+ function graphText(snapshot, name) {
106
+ if (!snapshot.graph.has(name)) {
107
+ return null;
108
+ }
109
+ const v = plainCell(snapshot.graph.value(name, 0));
110
+ if (typeof v === "string") {
111
+ return v;
112
+ }
113
+ return typeof v === "number" ? String(v) : null;
114
+ }
115
+ /**
116
+ * Who wrote a GML file: the `Creator` line (top level, or a key of the graph block as Gephi writes it), or graphty when
117
+ * the file holds a `graphty.styles` block.
118
+ * @param snapshot - the graph
119
+ * @returns the writer
120
+ */
121
+ function writerOf(snapshot) {
122
+ if (snapshot.graph.has(GML_STYLE_BLOCK_KEY)) {
123
+ return GRAPHTY_WRITER;
124
+ }
125
+ const creator = snapshot.meta.creator ?? graphText(snapshot, "Creator") ?? "";
126
+ for (const [pattern, writer] of WRITERS) {
127
+ if (pattern.test(creator)) {
128
+ return writer;
129
+ }
130
+ }
131
+ return UNKNOWN_WRITER;
132
+ }
133
+ /** The edge's `arrow` key of the GML draft: which ends have an arrow. */
134
+ const ARROW_ENDS = new Map([
135
+ ["none", ["none", "none"]],
136
+ ["last", ["none", "triangle"]],
137
+ ["first", ["triangle", "none"]],
138
+ ["both", ["triangle", "triangle"]],
139
+ ]);
140
+ /** OGDF's stroke types (`stipple`), by number. */
141
+ const OGDF_STROKES = ["none", "solid", "dashed", "dotted", "dash-dot", "dash-dot"];
142
+ /** OGDF's shape names the common table does not know. */
143
+ const OGDF_SHAPES = new Map([
144
+ ["rect", "rectangle"],
145
+ ["rhomb", "diamond"],
146
+ ["trapeze", "trapezoid"],
147
+ ["invtrapeze", "trapezoid"],
148
+ ["invtriangle", "triangle"],
149
+ ["invparallelogram", "parallelogram"],
150
+ ]);
151
+ /** Keys only yEd writes in a label record: its `fill` is the label's background, not the text color. */
152
+ const YED_LABEL_KEYS = [
153
+ "outline",
154
+ "autoSizePolicy",
155
+ "model",
156
+ "configuration",
157
+ "borderDistance",
158
+ "modelName",
159
+ "modelPosition",
160
+ ];
161
+ /** Cytoscape's legacy numbered arrows (`source_arrow 3`), read as Cytoscape reads them. */
162
+ const cytoscapeArrow = CYTOSCAPE_LEXICON.edge.get("targetArrow")?.[0]?.[1];
163
+ /**
164
+ * A short sample of a value for a note.
165
+ * @param raw - the value
166
+ * @returns its text, or "a record" for a record
167
+ */
168
+ function sampleOf(raw) {
169
+ return typeof raw === "string" || typeof raw === "number"
170
+ ? String(raw).slice(0, MAX_STYLE_VALUE_LENGTH)
171
+ : "a record";
172
+ }
173
+ /**
174
+ * Whether a value is a GML record.
175
+ * @param v - the value
176
+ * @returns true for a non-array object
177
+ */
178
+ function isRec(v) {
179
+ return typeof v === "object" && v !== null && !Array.isArray(v);
180
+ }
181
+ /**
182
+ * The first defined value of some keys of a record.
183
+ * @param r - the record
184
+ * @param keys - the keys, in order of preference
185
+ * @returns the value, or undefined
186
+ */
187
+ function first(r, ...keys) {
188
+ for (const k of keys) {
189
+ if (Object.hasOwn(r, k) && r[k] !== undefined) {
190
+ return r[k];
191
+ }
192
+ }
193
+ return undefined;
194
+ }
195
+ /**
196
+ * Reads a color and its alpha.
197
+ * @param raw - the value
198
+ * @param property - the color property
199
+ * @param opacity - its opacity property, or null
200
+ * @param writer - the writer
201
+ * @param put - receives the values
202
+ * @param at - the sites
203
+ */
204
+ function readColor(raw, property, opacity, writer, put, at) {
205
+ if (raw === undefined) {
206
+ return;
207
+ }
208
+ const c = canonColor(raw, writer.spelling, at(property));
209
+ if (c === null) {
210
+ return;
211
+ }
212
+ put(property, c.color);
213
+ const alpha = colorOpacity(c, null, at(property), opacity !== null);
214
+ if (opacity !== null) {
215
+ put(opacity, alpha);
216
+ }
217
+ }
218
+ /**
219
+ * A stroke style: OGDF's numbered `stipple`, or a line type name.
220
+ * @param raw - the value
221
+ * @param kind - border or line style
222
+ * @param writer - the writer
223
+ * @param at - the site
224
+ * @returns the style, or null
225
+ */
226
+ function strokeStyle(raw, kind, writer, at) {
227
+ if (raw === undefined) {
228
+ return null;
229
+ }
230
+ if (writer.vocabulary === "ogdf") {
231
+ const stroke = OGDF_STROKES[Number(raw)];
232
+ if (stroke === undefined || stroke === "none") {
233
+ noteAt(at, STYLE_ISSUE.UNKNOWN_VALUE, sampleOf(raw));
234
+ return null;
235
+ }
236
+ return stroke;
237
+ }
238
+ return canonEnum(kind, raw, writer.spelling, at);
239
+ }
240
+ /**
241
+ * Reads one node's `graphics` record.
242
+ * @param g - the record
243
+ * @param writer - the writer
244
+ * @param put - receives the values
245
+ * @param at - the sites
246
+ */
247
+ function readNodeGraphics(g, writer, put, at) {
248
+ const v = writer.vocabulary;
249
+ readNodeFill(g, writer, put, at);
250
+ readNodeOutline(g, writer, put, at);
251
+ put("borderStyle", strokeStyle(v === "ogdf" ? g.stipple : g.outlineStyle, "borderStyle", writer, at("borderStyle")));
252
+ put("width", g.w === undefined ? null : canonNumber(g.w, at("width")));
253
+ put("height", g.h === undefined ? null : canonNumber(g.h, at("height")));
254
+ if (g.type !== undefined) {
255
+ const raw = v === "ogdf" && typeof g.type === "string" ? (OGDF_SHAPES.get(g.type.toLowerCase()) ?? g.type) : g.type;
256
+ put("shape", canonEnum("shape", raw, writer.spelling, at("shape")));
257
+ }
258
+ else if (v === "yed" && typeof g.customconfiguration === "string") {
259
+ // yEd's flowchart palette keeps a node's shape as a configuration, not a `type`.
260
+ put("shape", flowchartShape(g.customconfiguration));
261
+ }
262
+ }
263
+ /**
264
+ * Reads the fill of one node's `graphics` record.
265
+ * @param g - the record
266
+ * @param writer - the writer
267
+ * @param put - receives the values
268
+ * @param at - the sites
269
+ */
270
+ function readNodeFill(g, writer, put, at) {
271
+ if (writer.vocabulary === "yed" && Number(g.hasFill) === 0) {
272
+ noteAt(at("fill"), STYLE_ISSUE.NO_FILL, "hasFill 0");
273
+ put("fillOpacity", 0);
274
+ return;
275
+ }
276
+ readColor(g.fill, "fill", "fillOpacity", writer, put, at);
277
+ if (g.fill2 !== undefined) {
278
+ noteAt(at("fill"), STYLE_ISSUE.GRADIENT, sampleOf(g.fill2));
279
+ }
280
+ }
281
+ /**
282
+ * Reads the outline color and width of one node's `graphics` record.
283
+ * @param g - the record
284
+ * @param writer - the writer
285
+ * @param put - receives the values
286
+ * @param at - the sites
287
+ */
288
+ function readNodeOutline(g, writer, put, at) {
289
+ const v = writer.vocabulary;
290
+ if (v === "yed" && Number(g.hasOutline) === 0) {
291
+ put("borderWidth", 0);
292
+ return;
293
+ }
294
+ readColor(v === "ogdf" ? g.line : g.outline, "borderColor", null, writer, put, at);
295
+ const width = outlineWidthOf(g, v);
296
+ put("borderWidth", width === undefined ? null : canonNumber(width, at("borderWidth")));
297
+ }
298
+ /**
299
+ * The outline width of a node's `graphics` record, under the key its writer uses.
300
+ * @param g - the record
301
+ * @param v - the writer's vocabulary
302
+ * @returns the raw width, or undefined
303
+ */
304
+ function outlineWidthOf(g, v) {
305
+ switch (v) {
306
+ case "yed":
307
+ return g.outlineWidth;
308
+ case "cytoscape":
309
+ return first(g, "outline_width", "width");
310
+ case "ogdf":
311
+ return g.lineWidth;
312
+ default:
313
+ return first(g, "width", "outlineWidth");
314
+ }
315
+ }
316
+ /**
317
+ * Reads one edge's `graphics` record.
318
+ * @param g - the record
319
+ * @param writer - the writer
320
+ * @param put - receives the values
321
+ * @param at - the sites
322
+ */
323
+ function readEdgeGraphics(g, writer, put, at) {
324
+ const v = writer.vocabulary;
325
+ readColor(g.fill, "color", "opacity", writer, put, at);
326
+ const width = v === "ogdf" ? first(g, "lineWidth", "width") : g.width;
327
+ put("width", width === undefined ? null : canonNumber(width, at("width")));
328
+ put("lineStyle", strokeStyle(v === "ogdf" ? g.stipple : g.style, "lineStyle", writer, at("lineStyle")));
329
+ if (typeof g.arrow === "string") {
330
+ const ends = ARROW_ENDS.get(g.arrow.trim().toLowerCase());
331
+ if (ends === undefined) {
332
+ noteAt(at("targetArrow"), STYLE_ISSUE.UNKNOWN_VALUE, g.arrow.slice(0, MAX_STYLE_VALUE_LENGTH));
333
+ }
334
+ else {
335
+ put("sourceArrow", ends[0]);
336
+ put("targetArrow", ends[1]);
337
+ }
338
+ }
339
+ for (const [keys, property] of [
340
+ [["sourceArrow", "source_arrow"], "sourceArrow"],
341
+ [["targetArrow", "target_arrow"], "targetArrow"],
342
+ ]) {
343
+ const raw = first(g, ...keys);
344
+ if (raw === undefined) {
345
+ continue;
346
+ }
347
+ put(property, v === "cytoscape" && cytoscapeArrow !== undefined
348
+ ? cytoscapeArrow(raw, at(property))
349
+ : canonEnum("arrow", raw, writer.spelling, at(property)));
350
+ }
351
+ if (v === "yed") {
352
+ readYedCurve(g, put);
353
+ }
354
+ }
355
+ /**
356
+ * Reads whether yEd draws an edge curved: `smoothBends` rounds the bends of its `Line`, whose points run from the
357
+ * source through the bends to the target, so a line of two points (or none) stays straight.
358
+ * @param g - the edge's `graphics` record
359
+ * @param put - receives the value
360
+ */
361
+ function readYedCurve(g, put) {
362
+ if (g.smoothBends !== undefined) {
363
+ const points = isRec(g.Line) ? g.Line.point : undefined;
364
+ put("curved", Number(g.smoothBends) === 1 && Array.isArray(points) && points.length > 2);
365
+ }
366
+ }
367
+ /**
368
+ * Reads an element's label records: the first visible one with text; further visible ones are noted.
369
+ * @param raw - the `LabelGraphics` value (one record or several)
370
+ * @param writer - the writer
371
+ * @param put - receives the values
372
+ * @param at - the sites
373
+ */
374
+ function readLabelGraphics(raw, writer, put, at) {
375
+ const visible = (Array.isArray(raw) ? raw : [raw]).filter((l) => isRec(l) && Number(l.visible) !== 0);
376
+ const lg = visible.at(0);
377
+ if (lg === undefined) {
378
+ return;
379
+ }
380
+ const extra = visible.slice(1).filter((l) => l.text !== undefined).length;
381
+ if (extra > 0) {
382
+ noteAt(at("label"), STYLE_ISSUE.EXTRA_LABELS, `${String(extra + 1)} labels`);
383
+ }
384
+ if (lg.text !== undefined) {
385
+ put("label", canonText(lg.text, at("label")));
386
+ }
387
+ // the GML draft's `fill` is the text color; yEd's is the label's background box, its `color` the text color
388
+ const yedLabel = writer.vocabulary === "yed" || YED_LABEL_KEYS.some((k) => Object.hasOwn(lg, k));
389
+ if (lg.color !== undefined) {
390
+ readColor(lg.color, "labelColor", null, writer, put, at);
391
+ }
392
+ else if (lg.fill !== undefined && !yedLabel) {
393
+ readColor(lg.fill, "labelColor", null, writer, put, at);
394
+ }
395
+ if (lg.fill !== undefined && yedLabel) {
396
+ noteAt(at("label"), STYLE_ISSUE.NOT_CARRIED, "label background");
397
+ }
398
+ readLabelFont(lg, put, at);
399
+ }
400
+ /**
401
+ * Reads a label record's font: its size, name, weight and slant.
402
+ * @param lg - the record
403
+ * @param put - receives the values
404
+ * @param at - the sites
405
+ */
406
+ function readLabelFont(lg, put, at) {
407
+ put("labelSize", lg.fontSize === undefined ? null : canonNumber(lg.fontSize, at("labelSize")));
408
+ put("labelFont", lg.fontName === undefined ? null : canonText(lg.fontName, at("labelFont")));
409
+ const style = scalarText(lg.fontStyle, at("labelWeight"))?.trim().toLowerCase();
410
+ if (style !== undefined) {
411
+ const known = FONT_STYLES.get(style);
412
+ if (known === undefined) {
413
+ noteAt(at("labelWeight"), STYLE_ISSUE.UNKNOWN_VALUE, style.slice(0, MAX_STYLE_VALUE_LENGTH));
414
+ }
415
+ else {
416
+ put("labelWeight", known[0]);
417
+ put("labelItalic", known[1]);
418
+ }
419
+ }
420
+ }
421
+ /**
422
+ * Reads one element: its `graphics` and `LabelGraphics`, and the `label` key where the writer draws it.
423
+ * @param target - nodes or edges
424
+ * @param g - the graphics value
425
+ * @param lg - the LabelGraphics value
426
+ * @param label - the `label` key's value
427
+ * @param writer - the writer
428
+ * @param put - receives the values
429
+ * @param at - the sites
430
+ */
431
+ function readElement(target, g, lg, label, writer, put, at) {
432
+ let text = false;
433
+ const putLabel = (property, value) => {
434
+ text || (text = property === "label" && value !== null);
435
+ put(property, value);
436
+ };
437
+ if (isRec(g)) {
438
+ (target === "node" ? readNodeGraphics : readEdgeGraphics)(g, writer, put, at);
439
+ }
440
+ if (lg !== null && lg !== undefined) {
441
+ readLabelGraphics(lg, writer, putLabel, at);
442
+ }
443
+ // the GML draft draws the label key; Cytoscape reads it as the node's name, which its default style shows
444
+ const drawn = writer.vocabulary === "cytoscape" ? target === "node" : writer.labelKey && (isRec(g) || lg !== undefined);
445
+ if (!text && drawn && label !== null && label !== undefined) {
446
+ put("label", canonText(label, at("label")));
447
+ }
448
+ }
449
+ /**
450
+ * The value of a column, or undefined when the table has no such column.
451
+ * @param table - the node or edge table
452
+ * @param name - the column
453
+ * @param i - the row
454
+ * @returns the value
455
+ */
456
+ function cellOf(table, name, i) {
457
+ if (!table.has(name)) {
458
+ return undefined;
459
+ }
460
+ const v = plainCell(table.value(name, i));
461
+ return v ?? undefined;
462
+ }
463
+ /**
464
+ * A node's center: the `graphics` `x` and `y` the importer moved into the position column.
465
+ * @param snapshot - the graph
466
+ * @param i - the node's index
467
+ * @returns the center; NaN where the node has none
468
+ */
469
+ function centerOf(snapshot, i) {
470
+ const column = snapshot.nodes.byRole("position");
471
+ const v = column?.isSet(i) === true ? column.value(i) : null;
472
+ return v === null ? [Number.NaN, Number.NaN] : [v[0], v[1]];
473
+ }
474
+ /**
475
+ * An edge's bends: the points of its `graphics` `Line` between the first and the last, which are where it leaves
476
+ * the source and meets the target.
477
+ * @param snapshot - the graph
478
+ * @param g - the edge's `graphics` value
479
+ * @param e - the edge's row
480
+ * @returns the `bends` value, or null without bends
481
+ */
482
+ function lineBends(snapshot, g, e) {
483
+ const raw = isRec(g) && isRec(g.Line) ? g.Line.point : undefined;
484
+ if (!Array.isArray(raw) || raw.length < 3) {
485
+ return null;
486
+ }
487
+ const points = raw.slice(1, -1).map((p) => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]));
488
+ return canonBends(centerOf(snapshot, snapshot.edgeSource(e)), centerOf(snapshot, snapshot.edgeTarget(e)), points, true);
489
+ }
490
+ /**
491
+ * Every element's values, read with a writer's vocabulary.
492
+ * @param snapshot - the graph
493
+ * @param writer - the writer
494
+ * @param notes - where problems are noted
495
+ * @param context - the work budget
496
+ * @returns the values per target, and whether anything was read
497
+ */
498
+ function readValues(snapshot, writer, notes, context) {
499
+ let found = false;
500
+ const read = (target) => {
501
+ const table = target === "node" ? snapshot.nodes : snapshot.edges;
502
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
503
+ const out = valueColumns(n);
504
+ if (!table.has("graphics") && !table.has("LabelGraphics") && writer.vocabulary !== "cytoscape") {
505
+ return out.values;
506
+ }
507
+ for (let i = 0; i < n; i++) {
508
+ context.budget.spend(target, 1);
509
+ const at = (property) => ({ notes, target, property, element: i, budget: context.budget });
510
+ readElement(target, cellOf(table, "graphics", i), cellOf(table, "LabelGraphics", i), cellOf(table, "label", i), writer, (property, value) => {
511
+ if (value !== null) {
512
+ found = true;
513
+ out.put(i, property, value);
514
+ }
515
+ }, at);
516
+ if (target === "edge") {
517
+ const bends = lineBends(snapshot, cellOf(table, "graphics", i), i);
518
+ if (bends !== null) {
519
+ found = true;
520
+ out.put(i, "bends", bends);
521
+ }
522
+ }
523
+ }
524
+ return out.values;
525
+ };
526
+ const node = read("node");
527
+ const edge = read("edge");
528
+ return { node, edge, found };
529
+ }
530
+ /**
531
+ * The `graphty.styles` block of a file graphty wrote, with the per-element values its rules read moved inside it from
532
+ * their `graphty_style_*` keys; the block as written when it is ignored anyway (graph-io then says why).
533
+ * @param snapshot - the graph
534
+ * @param text - the block's text
535
+ * @returns the block's text for graph-io to read
536
+ */
537
+ function blockWithValues(snapshot, text) {
538
+ const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
539
+ if (!parsed.ok || parsed.block.values !== undefined) {
540
+ return text;
541
+ }
542
+ const node = tagValues(snapshot, "node", parsed.block.columns.node);
543
+ const edge = tagValues(snapshot, "edge", parsed.block.columns.edge);
544
+ if (node === null || edge === null) {
545
+ // a style column is missing: graph-io ignores the block with a note
546
+ return text;
547
+ }
548
+ const raw = JSON.parse(text);
549
+ return JSON.stringify({ ...raw, values: { node, edge } });
550
+ }
551
+ /**
552
+ * The per-element values of a target's style columns, read from their `graphty_style_*` keys.
553
+ * @param snapshot - the graph
554
+ * @param target - nodes or edges
555
+ * @param keys - the style columns the block names
556
+ * @returns the values by key, or null when a key is missing
557
+ */
558
+ function tagValues(snapshot, target, keys) {
559
+ const table = target === "node" ? snapshot.nodes : snapshot.edges;
560
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
561
+ const values = {};
562
+ for (const key of keys) {
563
+ const name = tagKey(target, key);
564
+ if (!table.has(name)) {
565
+ return null;
566
+ }
567
+ values[key] = Array.from({ length: n }, (_, i) => {
568
+ const v = plainCell(table.value(name, i));
569
+ return typeof v === "string" || typeof v === "number" || typeof v === "boolean" ? v : null;
570
+ });
571
+ }
572
+ return values;
573
+ }
574
+ /**
575
+ * The columns of a table that hold styles: the graphics records and graphty's per-element style values.
576
+ * @param table - the node or edge table
577
+ * @returns the column names
578
+ */
579
+ function styleColumns(table) {
580
+ return [...table.names()].filter((c) => c === "graphics" || c === "LabelGraphics" || c.startsWith(TAG_PREFIX));
581
+ }
582
+ /**
583
+ * The styles of a GML file, read the way the program that wrote it draws them, with that program's defaults beneath:
584
+ * yEd, Cytoscape, Gephi and OGDF are recognized by the `Creator` line; igraph and every other writer get the GML
585
+ * draft's keys and no defaults. A file graphty wrote gives back its `graphty.styles` block.
586
+ * @param snapshot - the graph the import built
587
+ * @param context - the work budget
588
+ * @returns the styles, or null when the file has none
589
+ */
590
+ export function gmlStyles(snapshot, context) {
591
+ const notes = new StyleNotes();
592
+ const writer = writerOf(snapshot);
593
+ const values = readValues(snapshot, writer, notes, context);
594
+ const blockText = graphText(snapshot, GML_STYLE_BLOCK_KEY);
595
+ const block = blockText === null ? null : blockWithValues(snapshot, blockText);
596
+ if (block !== null) {
597
+ exactFromBlock(snapshot, block, values);
598
+ }
599
+ if (writer.tool === null && !values.found && block === null) {
600
+ return null;
601
+ }
602
+ const gephi = writer.tool === "gephi"
603
+ ? gephiRules(snapshot, values.node.fill, values.edge.color, context.budget, values.edge.width)
604
+ : { rules: [], columns: new Map() };
605
+ return {
606
+ canonical: true,
607
+ dialect: writer.dialect,
608
+ tool: writer.tool,
609
+ units: writer.units,
610
+ node: { values: values.node },
611
+ edge: { values: values.edge, rules: gephi.rules, columns: gephi.columns },
612
+ notes: notes.list(),
613
+ opacityInColor: true,
614
+ block,
615
+ // the graphics records and the per-element style values of a file graphty wrote hold styles, not data
616
+ readFrom: { node: styleColumns(snapshot.nodes), edge: styleColumns(snapshot.edges) },
617
+ };
618
+ }
619
+ // ============================================================ writing
620
+ /**
621
+ * What the GML writer holds natively: yEd GML `graphics` and `LabelGraphics`. The `graphty.styles` block and the
622
+ * per-element values its rules read are keys of the graph and of each element.
623
+ * @category Built-in formats
624
+ */
625
+ export const GML_STYLE_CAPABILITIES = Object.freeze({
626
+ node: Object.freeze([
627
+ "fill",
628
+ "fillOpacity",
629
+ "borderColor",
630
+ "borderWidth",
631
+ "borderStyle",
632
+ "shape",
633
+ "width",
634
+ "height",
635
+ "label",
636
+ "labelColor",
637
+ "labelSize",
638
+ "labelFont",
639
+ "labelWeight",
640
+ "labelItalic",
641
+ ]),
642
+ edge: Object.freeze([
643
+ "color",
644
+ "opacity",
645
+ "width",
646
+ "lineStyle",
647
+ "sourceArrow",
648
+ "targetArrow",
649
+ "curved",
650
+ "bends",
651
+ "label",
652
+ "labelColor",
653
+ "labelSize",
654
+ "labelFont",
655
+ "labelWeight",
656
+ "labelItalic",
657
+ ]),
658
+ block: "native",
659
+ });
660
+ /** Every style key a reader here reads, per record: the writer replaces them all. */
661
+ const OWNED = {
662
+ node: new Set([
663
+ "fill",
664
+ "fill2",
665
+ "hasFill",
666
+ "outline",
667
+ "hasOutline",
668
+ "outlineWidth",
669
+ "outline_width",
670
+ "outlineStyle",
671
+ "width",
672
+ "line",
673
+ "lineWidth",
674
+ "stipple",
675
+ "w",
676
+ "h",
677
+ "type",
678
+ ]),
679
+ edge: new Set([
680
+ "fill",
681
+ "width",
682
+ "lineWidth",
683
+ "style",
684
+ "stipple",
685
+ "arrow",
686
+ "sourceArrow",
687
+ "targetArrow",
688
+ "source_arrow",
689
+ "target_arrow",
690
+ "smoothBends",
691
+ ]),
692
+ label: new Set(["text", "color", "fill", "fontSize", "fontName", "fontStyle", "visible"]),
693
+ };
694
+ /**
695
+ * A node's yEd `graphics` keys from its values.
696
+ * @param get - the node's values
697
+ * @param approximate - records approximations
698
+ * @returns the keys
699
+ */
700
+ function nodeGraphics(get, approximate) {
701
+ const g = {};
702
+ const width = get("width");
703
+ const height = get("height");
704
+ if (typeof width === "number") {
705
+ g.w = width;
706
+ }
707
+ if (typeof height === "number") {
708
+ g.h = height;
709
+ }
710
+ const shape = get("shape");
711
+ if (typeof shape === "string") {
712
+ const w = yedValue(YED_SHAPES, shape, shape === "vee" ? "triangle" : "rectangle");
713
+ if (!w.exact) {
714
+ approximate("shape", shape);
715
+ }
716
+ g.type = w.value;
717
+ }
718
+ const fill = get("fill");
719
+ const fillOpacity = get("fillOpacity");
720
+ if (typeof fill === "string") {
721
+ g.fill = yedColor(fill, fillOpacity);
722
+ }
723
+ else if (fillOpacity === 0) {
724
+ g.hasFill = 0;
725
+ }
726
+ const borderColor = get("borderColor");
727
+ const borderWidth = get("borderWidth");
728
+ const borderStyle = get("borderStyle");
729
+ if (typeof borderColor === "string") {
730
+ g.outline = borderColor.toUpperCase();
731
+ }
732
+ if (typeof borderStyle === "string") {
733
+ const w = yedValue(YED_LINES, borderStyle, "line");
734
+ if (!w.exact) {
735
+ approximate("borderStyle", borderStyle);
736
+ }
737
+ g.outlineStyle = w.value;
738
+ }
739
+ if (borderWidth === 0) {
740
+ g.hasOutline = 0;
741
+ }
742
+ else if (typeof borderWidth === "number") {
743
+ g.outlineWidth = borderWidth;
744
+ }
745
+ return g;
746
+ }
747
+ /**
748
+ * An edge's yEd `graphics` keys from its values.
749
+ * @param get - the edge's values
750
+ * @param approximate - records approximations
751
+ * @returns the keys
752
+ */
753
+ function edgeGraphics(get, approximate) {
754
+ const g = {};
755
+ const color = get("color");
756
+ if (typeof color === "string") {
757
+ g.fill = yedColor(color, get("opacity"));
758
+ }
759
+ const width = get("width");
760
+ if (typeof width === "number") {
761
+ g.width = width;
762
+ }
763
+ const lineStyle = get("lineStyle");
764
+ if (typeof lineStyle === "string") {
765
+ g.style = yedSpelled(YED_LINES, lineStyle, lineStyle === "long-dash" ? "dashed" : "line", "lineStyle", approximate);
766
+ }
767
+ for (const property of ["sourceArrow", "targetArrow"]) {
768
+ const arrow = get(property);
769
+ if (typeof arrow === "string") {
770
+ g[property] = yedSpelled(YED_ARROWS, arrow, "standard", property, approximate);
771
+ }
772
+ }
773
+ const curved = get("curved");
774
+ if (typeof curved === "boolean") {
775
+ g.smoothBends = curved ? 1 : 0;
776
+ }
777
+ return g;
778
+ }
779
+ /**
780
+ * An element's yEd `LabelGraphics` keys from its values, or null when it has no label text.
781
+ * @param get - the element's values
782
+ * @returns the keys
783
+ */
784
+ function labelGraphics(get) {
785
+ const text = get("label");
786
+ if (typeof text !== "string" || text.trim().length === 0) {
787
+ return null;
788
+ }
789
+ const lg = { text };
790
+ const color = get("labelColor");
791
+ if (typeof color === "string") {
792
+ lg.color = color.toUpperCase();
793
+ }
794
+ const size = get("labelSize");
795
+ if (typeof size === "number") {
796
+ lg.fontSize = size;
797
+ }
798
+ const font = get("labelFont");
799
+ if (typeof font === "string") {
800
+ lg.fontName = font;
801
+ }
802
+ const weight = get("labelWeight");
803
+ const italic = get("labelItalic");
804
+ if (weight !== null || italic !== null) {
805
+ const style = (weight === "bold" ? "bold" : "") + (italic === true ? "italic" : "");
806
+ lg.fontStyle = style.length === 0 ? "plain" : style;
807
+ }
808
+ return lg;
809
+ }
810
+ /**
811
+ * A record with the style keys replaced: the kept keys of the old record, then the written ones.
812
+ * @param old - the record the element had, or anything else
813
+ * @param owned - the style keys
814
+ * @param written - the new style keys
815
+ * @returns the record, or undefined (an unset cell) when it is empty
816
+ */
817
+ function merged(old, owned, written) {
818
+ const out = {};
819
+ if (isRec(old)) {
820
+ for (const [k, v] of Object.entries(old)) {
821
+ if (!owned.has(k)) {
822
+ out[k] = v;
823
+ }
824
+ }
825
+ }
826
+ Object.assign(out, written);
827
+ return Object.keys(out).length === 0 ? undefined : out;
828
+ }
829
+ /**
830
+ * An element's `LabelGraphics` value with its first label's style keys replaced; further labels are kept.
831
+ * @param old - the value the element had
832
+ * @param written - the new label keys, or null for no label
833
+ * @returns the value, or undefined (an unset cell)
834
+ */
835
+ function mergedLabels(old, written) {
836
+ const labels = Array.isArray(old) ? old : [old];
837
+ const head = merged(labels[0], OWNED.label, written ?? {});
838
+ const rest = labels.slice(1).filter((l) => l !== null && l !== undefined);
839
+ if (rest.length === 0) {
840
+ return head;
841
+ }
842
+ return head === undefined ? rest : [head, ...rest];
843
+ }
844
+ /**
845
+ * Each element's values of the properties the writer writes, as a getter per element.
846
+ * @param picture - each element's value of a property
847
+ * @param target - nodes or edges
848
+ * @returns the getter
849
+ */
850
+ function getter(picture, target) {
851
+ const columns = new Map();
852
+ for (const p of GML_STYLE_CAPABILITIES[target]) {
853
+ columns.set(p, picture(target, p));
854
+ }
855
+ return (i) => (property) => columns.get(property)?.[i] ?? null;
856
+ }
857
+ /**
858
+ * For a file graphty wrote: where a value read from the graphics is what the writer writes for the block's own value
859
+ * (a pentagon written as a rectangle, an opacity rounded to 255 steps), the block's exact value is the truth, so a
860
+ * re-import gives back the same rules; a value another program changed since stays the truth.
861
+ * @param snapshot - the graph
862
+ * @param text - the block's text
863
+ * @param read - the values read, changed in place
864
+ * @param read.node - the node values
865
+ * @param read.edge - the edge values
866
+ */
867
+ function exactFromBlock(snapshot, text, read) {
868
+ const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
869
+ const ex = parsed.ok ? blockStyles(parsed.block, snapshot, "gml") : null;
870
+ if (ex === null) {
871
+ return;
872
+ }
873
+ const notes = new StyleNotes();
874
+ for (const target of ["node", "edge"]) {
875
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
876
+ const get = getter((t, p) => resolveStyles(ex, t, p, snapshot), target);
877
+ const values = read[target];
878
+ for (let i = 0; i < n; i++) {
879
+ const want = get(i);
880
+ const back = writtenAndReadBack(target, want, notes);
881
+ for (const property of GML_STYLE_CAPABILITIES[target]) {
882
+ const native = values[property]?.[i] ?? null;
883
+ const w = want(property);
884
+ if (native !== w && native === (back.get(property) ?? null)) {
885
+ values[property] ?? (values[property] = new Array(n).fill(null));
886
+ values[property][i] = w;
887
+ }
888
+ }
889
+ }
890
+ }
891
+ }
892
+ /**
893
+ * An element's values written as the writer writes them and read back as the reader reads them.
894
+ * @param target - nodes or edges
895
+ * @param want - its values
896
+ * @param notes - a scratch for the notes the round trip makes
897
+ * @returns the values read back, by property
898
+ */
899
+ function writtenAndReadBack(target, want, notes) {
900
+ const ignore = () => undefined;
901
+ const g = target === "node" ? nodeGraphics(want, ignore) : edgeGraphics(want, ignore);
902
+ const back = new Map();
903
+ readElement(target, g, labelGraphics(want) ?? undefined, undefined, GRAPHTY_WRITER, (property, value) => {
904
+ if (value !== null) {
905
+ back.set(property, value);
906
+ }
907
+ }, (property) => ({ notes, target, property }));
908
+ return back;
909
+ }
910
+ /**
911
+ * Works out a GML export with styles: every node's and edge's `graphics` and `LabelGraphics` records get yEd's keys
912
+ * for what graphty draws in place of every style key they had (positions, bends and other keys stay), the
913
+ * `graphty.styles` block becomes the graph key `graphty_styles` and the per-element values its rules read become
914
+ * element keys. Should two style columns map to one key, the values go inside the block instead.
915
+ * @param snapshot - the graph handed to the exporter
916
+ * @param input - the styles, or undefined when none are written
917
+ * @returns the styled export, or null without styles
918
+ */
919
+ export function gmlStyledExport(snapshot, input) {
920
+ if (input === undefined) {
921
+ return null;
922
+ }
923
+ const approximated = new StyleApproximations();
924
+ const out = snapshot.withColumns();
925
+ const renames = [];
926
+ for (const target of ["node", "edge"]) {
927
+ const table = target === "node" ? out.nodes : out.edges;
928
+ writeGraphicsColumns(snapshot, input, target, table, approximated);
929
+ // the per-element style values of an earlier write go; a data column the rules read, or any other whose key
930
+ // would read back as a style value, is renamed out of the keys the style values take
931
+ const read = dataRead(input.rules.styles.rules, target);
932
+ for (const name of table.names().filter((c) => mangleGmlKey(c).startsWith(TAG_PREFIX))) {
933
+ const col = table.get(name);
934
+ table.remove(name);
935
+ if (col !== null && !(name.startsWith(TAG_PREFIX) && !read.has(name))) {
936
+ renames.push(renameDataColumn(table, target, name, col));
937
+ }
938
+ }
939
+ }
940
+ let { block } = input;
941
+ const keys = [...input.rules.columns.node.keys()].map((k) => tagKey("node", k));
942
+ const edgeKeys = [...input.rules.columns.edge.keys()].map((k) => tagKey("edge", k));
943
+ if (new Set(keys).size !== keys.length || new Set(edgeKeys).size !== edgeKeys.length) {
944
+ block = writeStyleBlock(input.rules, { inlineColumns: true, snapshot });
945
+ }
946
+ else {
947
+ setTagColumns(out, input);
948
+ }
949
+ out.graph.set(GML_STYLE_BLOCK_KEY, [block], { dtype: "string" });
950
+ const notes = [
951
+ ...renames,
952
+ ...(block === input.block ? [] : styleBlockLosses(block, input.rules.styles.rules.length, "size")),
953
+ ...approximated.notes("yEd's GML"),
954
+ ];
955
+ return { snapshot: out, notes };
956
+ }
957
+ /**
958
+ * Writes every element's `graphics` and `LabelGraphics` records of a target with yEd's keys for what graphty draws,
959
+ * keeping the keys that are not style keys.
960
+ * @param snapshot - the graph handed to the exporter
961
+ * @param input - the styles
962
+ * @param target - nodes or edges
963
+ * @param table - the target's table being written, changed in place
964
+ * @param approximated - where approximations are counted
965
+ */
966
+ function writeGraphicsColumns(snapshot, input, target, table, approximated) {
967
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
968
+ const approximate = (property, value) => {
969
+ approximated.add(target, property, value);
970
+ };
971
+ const get = getter((t, p) => input.picture(t, p), target);
972
+ const graphics = [];
973
+ const labels = [];
974
+ for (let i = 0; i < n; i++) {
975
+ const g = target === "node" ? nodeGraphics(get(i), approximate) : edgeGraphics(get(i), approximate);
976
+ if (target === "edge") {
977
+ const line = bendsLine(snapshot, get(i)("bends"), i);
978
+ if (line !== null) {
979
+ g.Line = line;
980
+ }
981
+ }
982
+ graphics.push(merged(cellOf(table, "graphics", i), OWNED[target], g));
983
+ labels.push(mergedLabels(cellOf(table, "LabelGraphics", i), labelGraphics(get(i))));
984
+ }
985
+ for (const [name, cells] of [
986
+ ["graphics", graphics],
987
+ ["LabelGraphics", labels],
988
+ ]) {
989
+ if (cells.some((c) => c !== undefined)) {
990
+ table.set(name, cells, { dtype: "json", nullable: true });
991
+ }
992
+ else if (table.has(name)) {
993
+ table.remove(name);
994
+ }
995
+ }
996
+ }
997
+ /**
998
+ * An edge's `Line` from its `bends` value: the node centers it is written between, with the bends placed between them,
999
+ * so the bends read back as written.
1000
+ * @param snapshot - the graph handed to the exporter
1001
+ * @param bends - the edge's `bends` value
1002
+ * @param e - the edge's row
1003
+ * @returns the `Line` record, or null without a value or without both centers
1004
+ */
1005
+ function bendsLine(snapshot, bends, e) {
1006
+ const source = centerOf(snapshot, snapshot.edgeSource(e));
1007
+ const target = centerOf(snapshot, snapshot.edgeTarget(e));
1008
+ const points = typeof bends === "string" ? bendsToPoints(source, target, bends, true) : null;
1009
+ if (points === null || ![...source, ...target].every(Number.isFinite)) {
1010
+ return null;
1011
+ }
1012
+ return { point: [source, ...points, target].map(([x, y]) => ({ x, y })) };
1013
+ }
1014
+ /**
1015
+ * Writes a data column under a name out of the keys the style values take.
1016
+ * @param table - the table, changed in place
1017
+ * @param target - nodes or edges
1018
+ * @param name - the column's name
1019
+ * @param col - the column
1020
+ * @returns the note saying so
1021
+ */
1022
+ function renameDataColumn(table, target, name, col) {
1023
+ let renamed = `data_${name}`;
1024
+ let k = 2;
1025
+ while (table.has(renamed)) {
1026
+ renamed = `data_${name}_${String(k)}`;
1027
+ k++;
1028
+ }
1029
+ table.set(renamed, col);
1030
+ return Object.freeze({
1031
+ code: KEY_MANGLED_CODE,
1032
+ message: `${target} column "${name}" is written as "${renamed}": keys starting with ${TAG_PREFIX} hold graphty's style values`,
1033
+ column: name,
1034
+ count: null,
1035
+ });
1036
+ }
1037
+ /**
1038
+ * Sets the per-element values the rules read as element keys.
1039
+ * @param out - the graph, changed in place
1040
+ * @param input - the styles
1041
+ */
1042
+ function setTagColumns(out, input) {
1043
+ for (const target of ["node", "edge"]) {
1044
+ const table = target === "node" ? out.nodes : out.edges;
1045
+ for (const [key, col] of input.rules.columns[target]) {
1046
+ const kinds = new Set(col.filter((v) => v !== null).map((v) => typeof v));
1047
+ const text = kinds.size > 1 || kinds.has("string");
1048
+ let dtype = kinds.has("boolean") ? "bool" : "f64";
1049
+ if (text) {
1050
+ dtype = "string";
1051
+ }
1052
+ table.set(tagKey(target, key), text ? col.map((v) => (v === null ? null : String(v))) : col, { dtype });
1053
+ }
1054
+ }
1055
+ }
1056
+ //# sourceMappingURL=styles.js.map