@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
@@ -1,9 +1,14 @@
1
1
  import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
2
- import { c as capabilities, R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, o as DUPLICATE_ATTRIBUTE_CODE, g as UNKNOWN_ELEMENT_CODE, b5 as EMPTY_COLUMN_DROPPED_CODE, ai as PARENT_CYCLE_CODE, P as PRECISION_CODE, w as UNKNOWN_ENCODING_CODE, a2 as JSON_NONSTANDARD_NUMBER_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, O as OPTION_IGNORED_CODE, S as SINK_OPTION_CODE, H as HYPEREDGE_CODE, ad as TOO_LARGE_CODE, i as DANGLING_REFERENCE_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, l as MULTIPLE_GRAPHS_CODE, I as ID_MERGED_CODE, m as DUPLICATE_EDGE_ID_CODE, n as DUPLICATE_NODE_CODE, q as UNKNOWN_PARENT_CODE, a3 as BAD_VALUE_CODE, s as MISSING_ENDPOINT_CODE, t as MISSING_ID_CODE, ak as SYNTAX_CODE, E as EMPTY_INPUT_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, al as resolveImportOptions, a8 as ImportReportBuilder, bB as readText, b as plural, ao as reportSinkOptions, an as reportUnusedOptions, am as throwIfAborted, ar as IdCoercer, aq as DirectionResolver, $ as agree, as as weightFromValue, a0 as uniqueColumnName, a7 as chooseGraph, ap as graphChosen, a1 as declareResolved, aB as GRAPH_COLUMN_AS_METADATA_CODE, aC as TYPEDEF_NODES_CODE, aD as RELATION_ASSUMED_CODE, at as COLUMN_AS_PROPERTY_VALUE_CODE, p as pairFolding, e as explicitWeights, bd as NONFINITE_AS_NULL_CODE, L as LOSS, b3 as DIRECTION_DROPPED_CODE, aA as NODE_ORDER_CODE, r as resolveExportOptions, b_ as otherFormatDialect, a as checkCapabilities, bD as countMixedEdges, aa as formatF32, ab as formatF64 } from "./export-rKLeGQMo.js";
3
- import { M as MAYBE_UNSAFE_INTEGER, j as MAYBE_INEXACT_EXPONENT, l as rewriteNumbers, m as findDuplicateKeys, f as flipY } from "./json-elements-DKSqpNW1.js";
2
+ import { R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, k as DUPLICATE_ATTRIBUTE_CODE, c as UNKNOWN_ELEMENT_CODE, ax as EMPTY_COLUMN_DROPPED_CODE, a6 as PARENT_CYCLE_CODE, P as PRECISION_CODE, r as UNKNOWN_ENCODING_CODE, W as JSON_NONSTANDARD_NUMBER_CODE, s as ENCODING_FALLBACK_CODE, t as INVALID_ENCODING_CODE, u as INVALID_UTF8_CODE, O as OPTION_IGNORED_CODE, S as SINK_OPTION_CODE, H as HYPEREDGE_CODE, a1 as TOO_LARGE_CODE, e as DANGLING_REFERENCE_CODE, a2 as AMBIGUOUS_GRAPH_NAME_CODE, a3 as GRAPH_NOT_FOUND_CODE, h as MULTIPLE_GRAPHS_CODE, I as ID_MERGED_CODE, i as DUPLICATE_EDGE_ID_CODE, j as DUPLICATE_NODE_CODE, l as UNKNOWN_PARENT_CODE, Y as BAD_VALUE_CODE, m as MISSING_ENDPOINT_CODE, n as MISSING_ID_CODE, a8 as SYNTAX_CODE, E as EMPTY_INPUT_CODE, x as ELEMENT_ISSUE, y as INPUT_ISSUE, Z as ImportReportBuilder, p as plural, V as agree, ag as GRAPH_COLUMN_AS_METADATA_CODE, ah as TYPEDEF_NODES_CODE, ai as RELATION_ASSUMED_CODE, a9 as COLUMN_AS_PROPERTY_VALUE_CODE, aE as NONFINITE_AS_NULL_CODE, av as DIRECTION_DROPPED_CODE, af as NODE_ORDER_CODE, $ as formatF32, a0 as formatF64 } from "./format-GDmO6m6Q.js";
3
+ import { c as capabilities, g as resolveImportOptions, ab as readText, j as reportSinkOptions, i as reportUnusedOptions, h as throwIfAborted, I as IdCoercer, l as DirectionResolver, w as weightFromValue, u as uniqueColumnName, f as chooseGraph, k as graphChosen, d as declareResolved, p as pairFolding, e as explicitWeights, L as LOSS, a as checkCapabilities, r as resolveExportOptions, ah as otherFormatDialect, ai as countMixedEdges } from "./export-D7IGzTG4.js";
4
4
  import { j as joinText, e as encodeChunks, i as indentUnit } from "./writer-DxjgHwSe.js";
5
- import { t as trimTrailingZeros } from "./text-DHOJXnED.js";
6
- import { d as OBOGRAPHS_PREDICATE_TAGS, g as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, h as synonymScopeOf, O as OBO_NODE_COLUMNS, c as capabilityNotes, s as slotColumn, e as emptyColumnNotes, j as OBO_PURL, f as framelessNodes, m as movedNodes, U as UNWRITTEN_ROLES, n as notePropertyColumn, a as cellOf, v as valuesOf, k as OBO_IN_OWL, b as fitsVocabulary, t as textOf, S as SYNONYM_SCOPES } from "./ontology-export-CtRXjg_i.js";
5
+ import { S as STYLE_BLOCK_NAME, w as toolDefaults, j as StyleNotes, p as parseStyleBlock, k as styleFingerprint, a as STYLE_ISSUE, m as plainCell, g as canonBoolean, h as canonText, b as canonNumber, l as blockStyles, c as canonColor, f as canonEnum, e as canonOpacity, r as resolveStyles } from "./block-JQiwViEt.js";
6
+ import { t as trimTrailingZeros } from "./text-CgzMqHQb.js";
7
+ import { d as OBOGRAPHS_PREDICATE_TAGS, g as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, h as synonymScopeOf, O as OBO_NODE_COLUMNS, c as capabilityNotes, s as slotColumn, e as emptyColumnNotes, j as OBO_PURL, f as framelessNodes, m as movedNodes, U as UNWRITTEN_ROLES, n as notePropertyColumn, a as cellOf, v as valuesOf$1, k as OBO_IN_OWL, b as fitsVocabulary, t as textOf, S as SYNONYM_SCOPES } from "./ontology-export-BSpbY5FL.js";
8
+ import { M as MAYBE_UNSAFE_INTEGER, g as MAYBE_INEXACT_EXPONENT, j as rewriteNumbers, l as findDuplicateKeys, m as keysInTextOrder } from "./json-elements-C4FwgnH5.js";
9
+ import { c as cytoscapeJsStyles, C as CYTOSCAPE_IMPORT_KEY, t as toCytoscapeStylesheet, a as cyjsHoldsExactly, b as CYJS_EDGE_PROPERTIES, d as CYJS_NODE_PROPERTIES } from "./emit-DCwFLts5.js";
10
+ import { S as StyleApproximations } from "./approximations-3Q4TsdTh.js";
11
+ import { f as flipY } from "./convert-BcQ8_jMo.js";
7
12
  const JSON_DIALECTS = Object.freeze([
8
13
  "node-link",
9
14
  "d3",
@@ -357,15 +362,15 @@ function sniffFormat(hints, importers) {
357
362
  function sniffJsonDialectHead(head) {
358
363
  const text = typeof head === "string" ? head : new TextDecoder("utf-8", { fatal: false }).decode(head);
359
364
  const body = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
360
- const trimmed = body.trimStart();
361
- if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
365
+ const trimmed2 = body.trimStart();
366
+ if (!trimmed2.startsWith("{") && !trimmed2.startsWith("[")) {
362
367
  return null;
363
368
  }
364
369
  let root;
365
370
  try {
366
- root = JSON.parse(trimmed);
371
+ root = JSON.parse(trimmed2);
367
372
  } catch {
368
- const skeleton = skeletonOf(trimmed);
373
+ const skeleton = skeletonOf(trimmed2);
369
374
  root = skeleton;
370
375
  if (typeof skeleton === "object" && skeleton !== null && !Array.isArray(skeleton) && !["edges", "links", "directed", "multigraph", "graph"].some((key) => key in skeleton)) {
371
376
  const guess = sniffJsonDialect(skeleton);
@@ -565,6 +570,1367 @@ function clamp(value) {
565
570
  }
566
571
  return Math.min(value, 1);
567
572
  }
573
+ const Y_DOWN_MARKERS = ["vx", "vy", "fx", "fy", "index", "physics"];
574
+ function jsonPositions(snapshot) {
575
+ if (snapshot.nodes.byRole("position") !== null) {
576
+ return null;
577
+ }
578
+ const x = numeric(snapshot.nodes.get("x"));
579
+ const y = numeric(snapshot.nodes.get("y"));
580
+ if (x === null || y === null) {
581
+ return null;
582
+ }
583
+ const z = numeric(snapshot.nodes.get("z"));
584
+ const down = z === null && Y_DOWN_MARKERS.some((name) => snapshot.nodes.get(name) !== null);
585
+ return {
586
+ x: x.meta.name,
587
+ y: y.meta.name,
588
+ ...z === null ? {} : { z: z.meta.name },
589
+ yAxis: down ? "down" : "up",
590
+ units: down ? "px" : "file"
591
+ };
592
+ }
593
+ function numeric(column) {
594
+ const numericDtypes = ["f64", "f32", "i32", "u32", "u8"];
595
+ return column !== null && column.meta.components === 1 && numericDtypes.includes(column.dtype) ? column : null;
596
+ }
597
+ const TARGETS = ["node", "edge"];
598
+ function jsonStyles(snapshot, context) {
599
+ const src = context.kept;
600
+ if (!isJsonObject(src)) {
601
+ return null;
602
+ }
603
+ switch (src.dialect) {
604
+ case "cytoscape":
605
+ return cytoscapeStyles(snapshot, src, context);
606
+ case "graphology":
607
+ return graphologyStyles(snapshot, src, context);
608
+ case "vis":
609
+ return visStyles(snapshot, src, context);
610
+ case "node-link":
611
+ if (src.networkx === true) {
612
+ return networkxStyles(snapshot);
613
+ }
614
+ return src.block === null ? null : { canonical: true, block: src.block };
615
+ default:
616
+ return src.block === null ? null : { canonical: true, block: src.block };
617
+ }
618
+ }
619
+ function cytoscapeStyles(snapshot, src, context) {
620
+ const sheetless = (src.style === void 0 || src.style === null) && src.generatedBy?.startsWith("cytoscape-") === true;
621
+ const graphty = src.block !== null && parseStyleBlock(src.block, styleFingerprint(snapshot)).ok;
622
+ const read = cytoscapeJsStyles({
623
+ elements: withGeneratedIds(src.elements, src.generatedIds),
624
+ style: sheetless ? [] : src.style ?? [],
625
+ snapshot,
626
+ toolDefaults: !graphty && !sheetless,
627
+ budget: context.budget,
628
+ signal: context.signal
629
+ });
630
+ if (!("canonical" in read)) {
631
+ return read;
632
+ }
633
+ let tool = "cytoscape-js";
634
+ if (graphty) {
635
+ tool = null;
636
+ exactFromBlock(
637
+ snapshot,
638
+ src.block,
639
+ { node: read.node?.values ?? {}, edge: read.edge?.values ?? {} },
640
+ CYJS_WRITTEN,
641
+ cyjsHoldsExactly
642
+ );
643
+ } else if (sheetless) {
644
+ tool = "cytoscape";
645
+ }
646
+ return { ...read, tool, block: src.block };
647
+ }
648
+ const trimmed = (property) => (want) => {
649
+ const v = want(property);
650
+ return typeof v === "string" ? v.trim() : null;
651
+ };
652
+ const CYJS_TEXT = {
653
+ node: ["label"],
654
+ edge: ["label", "sourceLabel", "targetLabel"]
655
+ };
656
+ const CYJS_WRITTEN = {
657
+ node: Object.fromEntries(CYJS_TEXT.node.map((p) => [p, trimmed(p)])),
658
+ edge: {
659
+ ...Object.fromEntries(CYJS_TEXT.edge.map((p) => [p, trimmed(p)])),
660
+ // Cytoscape.js draws a loop curved whatever its curve style says
661
+ curved: (want, e, snapshot) => snapshot.edgeSource(e) === snapshot.edgeTarget(e) && want("curved") !== null ? true : want("curved")
662
+ }
663
+ };
664
+ function withGeneratedIds(elements, ids) {
665
+ if (ids === void 0 || ids.size === 0) {
666
+ return elements;
667
+ }
668
+ const patch = (e) => {
669
+ const id = isJsonObject(e) ? ids.get(e) : void 0;
670
+ return id === void 0 || !isJsonObject(e) ? e : { ...e, data: { ...e.data, id } };
671
+ };
672
+ if (Array.isArray(elements)) {
673
+ return elements.map(patch);
674
+ }
675
+ if (isJsonObject(elements) && Array.isArray(elements.nodes)) {
676
+ return { ...elements, nodes: elements.nodes.map(patch) };
677
+ }
678
+ return elements;
679
+ }
680
+ function networkxStyles(snapshot) {
681
+ return {
682
+ canonical: true,
683
+ dialect: null,
684
+ tool: "networkx",
685
+ units: "px",
686
+ node: { values: {} },
687
+ edge: directedArrows(snapshot)
688
+ };
689
+ }
690
+ function directedArrows(snapshot) {
691
+ if (!snapshot.directed || snapshot.edgeCount === 0) {
692
+ return { values: {}, rules: [], columns: /* @__PURE__ */ new Map() };
693
+ }
694
+ const col = snapshot.edges.byRole("directed");
695
+ const flags = Array.from(
696
+ { length: snapshot.edgeCount },
697
+ (_v, e) => col === null || plainCell(col.value(e)) !== false ? true : null
698
+ );
699
+ return {
700
+ values: {},
701
+ rules: [
702
+ {
703
+ id: "edge.tool.arrow",
704
+ target: "edge",
705
+ role: "group",
706
+ origin: "tool",
707
+ where: { has: { style: "directed" } },
708
+ set: { targetArrow: "triangle" }
709
+ }
710
+ ],
711
+ columns: /* @__PURE__ */ new Map([["directed", flags]])
712
+ };
713
+ }
714
+ function cells(snapshot, target, name) {
715
+ const table = target === "node" ? snapshot.nodes : snapshot.edges;
716
+ return table.has(name) ? (i) => plainCell(table.value(name, i)) : null;
717
+ }
718
+ function valuesOf(n) {
719
+ const values = {};
720
+ return {
721
+ values,
722
+ put: (p, i, v) => {
723
+ if (v !== null) {
724
+ setValue(values, p, n, i, v);
725
+ }
726
+ }
727
+ };
728
+ }
729
+ function setValue(values, property, n, i, v) {
730
+ values[property] ??= new Array(n).fill(null);
731
+ values[property][i] = v;
732
+ }
733
+ function graphologyStyles(snapshot, src, context) {
734
+ const notes = new StyleNotes();
735
+ const out = { node: {}, edge: {} };
736
+ const readFrom = { node: [], edge: [] };
737
+ for (const target of TARGETS) {
738
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
739
+ const { values, put } = valuesOf(n);
740
+ const keys = {
741
+ color: cells(snapshot, target, "color"),
742
+ size: cells(snapshot, target, "size"),
743
+ label: cells(snapshot, target, "label"),
744
+ hidden: cells(snapshot, target, "hidden")
745
+ };
746
+ readFrom[target].push(...Object.entries(keys).flatMap(([name, c]) => c === null ? [] : [name]));
747
+ for (let i = 0; i < n; i++) {
748
+ const site = (property) => ({
749
+ notes,
750
+ target,
751
+ property,
752
+ element: i,
753
+ budget: context.budget
754
+ });
755
+ readSigmaRow(keys, target, i, put, site);
756
+ }
757
+ out[target] = values;
758
+ }
759
+ exactFromBlock(snapshot, blockText(snapshot, src), out, GRAPHOLOGY_WRITTEN);
760
+ return {
761
+ canonical: true,
762
+ dialect: "graphology",
763
+ tool: "sigma",
764
+ opacityInColor: true,
765
+ units: "relative",
766
+ node: { values: out.node },
767
+ edge: { values: out.edge },
768
+ notes: notes.list(),
769
+ readFrom
770
+ };
771
+ }
772
+ function readSigmaRow(keys, target, i, put, site) {
773
+ const { color, size, label, hidden } = keys;
774
+ if (color !== null) {
775
+ const [fill, opacity] = target === "node" ? ["fill", "fillOpacity"] : ["color", "opacity"];
776
+ putColor(put, fill, opacity, i, color(i), site(fill));
777
+ }
778
+ if (size !== null) {
779
+ const v = canonNumber(size(i), site("width"));
780
+ put("width", i, v);
781
+ if (target === "node") {
782
+ put("height", i, v);
783
+ }
784
+ }
785
+ if (label !== null) {
786
+ put("label", i, canonText(label(i), site("label")));
787
+ }
788
+ if (hidden !== null && canonBoolean(hidden(i), site("visible")) === true) {
789
+ put("visible", i, false);
790
+ }
791
+ }
792
+ function putColor(put, property, opacity, i, raw, site) {
793
+ if (raw === null || raw === void 0 || raw === "") {
794
+ return;
795
+ }
796
+ const c = canonColor(raw, "css", site);
797
+ if (c === null) {
798
+ return;
799
+ }
800
+ put(property, i, c.color);
801
+ if (c.alpha < 1) {
802
+ if (opacity === null) {
803
+ site.notes.add(STYLE_ISSUE.ALPHA_DROPPED, site.target, property, { sample: raw, element: i });
804
+ } else {
805
+ put(opacity, i, c.alpha);
806
+ }
807
+ }
808
+ }
809
+ function blockText(snapshot, src) {
810
+ if (src.block !== null) {
811
+ return src.block;
812
+ }
813
+ if (!snapshot.graph.has(STYLE_BLOCK_NAME)) {
814
+ return null;
815
+ }
816
+ const v = plainCell(snapshot.graph.value(STYLE_BLOCK_NAME, 0));
817
+ return typeof v === "string" ? v : null;
818
+ }
819
+ function exactFromBlock(snapshot, text, values, written, holdsExactly) {
820
+ if (text === null) {
821
+ return;
822
+ }
823
+ const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
824
+ const ex = parsed.ok ? blockStyles(parsed.block, snapshot, "json") : null;
825
+ if (ex === null) {
826
+ return;
827
+ }
828
+ for (const target of TARGETS) {
829
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
830
+ const cache = /* @__PURE__ */ new Map();
831
+ const resolved = (p) => {
832
+ let r = cache.get(p);
833
+ if (r === void 0) {
834
+ r = resolveStyles(ex, target, p, snapshot);
835
+ cache.set(p, r);
836
+ }
837
+ return r;
838
+ };
839
+ if (holdsExactly !== void 0) {
840
+ const properties = new Set(
841
+ ex.styles.rules.filter((r) => r.target === target).flatMap((r) => [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})])
842
+ );
843
+ for (const property of properties) {
844
+ const held = (w) => holdsExactly(target, property, w);
845
+ takeUnheld(values[target], property, resolved(property), n, held);
846
+ }
847
+ }
848
+ for (const [property, write2] of Object.entries(written[target] ?? {})) {
849
+ takeWritten(values[target], property, n, resolved, write2, snapshot);
850
+ }
851
+ }
852
+ }
853
+ function takeWritten(column, property, n, resolved, write2, snapshot) {
854
+ const want = resolved(property);
855
+ for (let i = 0; i < n; i++) {
856
+ const w = want[i];
857
+ const native = column[property]?.[i] ?? null;
858
+ if (native !== w && native !== null && native === write2((p) => resolved(p)[i], i, snapshot)) {
859
+ setValue(column, property, n, i, w);
860
+ }
861
+ }
862
+ }
863
+ function takeUnheld(values, property, want, n, held) {
864
+ for (let i = 0; i < n; i++) {
865
+ const w = want[i];
866
+ if (w !== null && !held(w)) {
867
+ setValue(values, property, n, i, w);
868
+ }
869
+ }
870
+ }
871
+ const oneSize = (want) => {
872
+ const w = want("width");
873
+ const h = want("height");
874
+ return typeof w === "number" && typeof h === "number" ? Math.max(w, h) : w ?? h;
875
+ };
876
+ const GRAPHOLOGY_WRITTEN = { node: { width: oneSize, height: oneSize } };
877
+ const VIS_SIZED = /* @__PURE__ */ new Set([
878
+ "image",
879
+ "circularImage",
880
+ "diamond",
881
+ "dot",
882
+ "star",
883
+ "triangle",
884
+ "triangleDown",
885
+ "hexagon",
886
+ "square",
887
+ "icon"
888
+ ]);
889
+ const VIS_GROUP_PALETTE = [
890
+ ["#2B7CE9", "#97C2FC"],
891
+ ["#FFA500", "#FFFF00"],
892
+ ["#FA0A10", "#FB7E81"],
893
+ ["#41A906", "#7BE141"],
894
+ ["#E129F0", "#EB7DF4"],
895
+ ["#7C29F0", "#AD85E4"],
896
+ ["#C37F00", "#FFA807"],
897
+ ["#4220FB", "#6E6EFD"],
898
+ ["#FD5A77", "#FFC0CB"],
899
+ ["#4AD63A", "#C2FABC"],
900
+ ["#990000", "#EE0000"],
901
+ ["#FF6000", "#FF6000"],
902
+ ["#97C2FC", "#2B7CE9"],
903
+ ["#399605", "#255C03"],
904
+ ["#B70054", "#FF007E"],
905
+ ["#AD85E4", "#7C29F0"],
906
+ ["#4557FA", "#000EA1"],
907
+ ["#FFC0CB", "#FD5A77"],
908
+ ["#C2FABC", "#74D66A"],
909
+ ["#EE0000", "#990000"]
910
+ ];
911
+ const VIS_EDGE_COLOR = "#848484";
912
+ function visParseColor(text) {
913
+ let hex = text;
914
+ const rgb = /^rgb\( *(\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3}) *\)$/i.exec(text);
915
+ if (rgb?.slice(1).every((c) => Number(c) <= 255)) {
916
+ hex = `#${((1 << 24) + (Number(rgb[1]) << 16) + (Number(rgb[2]) << 8) + Number(rgb[3])).toString(16).slice(1)}`;
917
+ }
918
+ if (!/^#([0-9a-f]{6}|[0-9a-f]{3})$/i.test(hex)) {
919
+ return { background: text, border: text };
920
+ }
921
+ const full = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;
922
+ return { background: full, border: visBorder(full) };
923
+ }
924
+ function visBorder(full) {
925
+ const n = Number.parseInt(full.slice(1), 16);
926
+ const [r, g, b] = [n >> 16 & 255, n >> 8 & 255, n & 255].map((c) => c / 255);
927
+ const max = Math.max(r, g, b);
928
+ const min = Math.min(r, g, b);
929
+ let h = 0;
930
+ let s = 0;
931
+ if (max !== min) {
932
+ let d = b - r;
933
+ let k = 5;
934
+ if (r === min) {
935
+ d = g - b;
936
+ k = 3;
937
+ } else if (b === min) {
938
+ d = r - g;
939
+ k = 1;
940
+ }
941
+ h = 60 * (k - d / (max - min)) / 360;
942
+ s = (max - min) / max;
943
+ }
944
+ const sv = Math.min(1, s * 1.25);
945
+ const vv = max * 0.8;
946
+ const i = Math.floor(h * 6);
947
+ const f = h * 6 - i;
948
+ const p = vv * (1 - sv);
949
+ const q = vv * (1 - f * sv);
950
+ const t = vv * (1 - (1 - f) * sv);
951
+ const rgbOut = [
952
+ [vv, t, p],
953
+ [q, vv, p],
954
+ [p, vv, t],
955
+ [p, q, vv],
956
+ [t, p, vv],
957
+ [vv, p, q]
958
+ ][i % 6].map((c) => Math.floor(c * 255));
959
+ return `#${((1 << 24) + (rgbOut[0] << 16) + (rgbOut[1] << 8) + rgbOut[2]).toString(16).slice(1)}`;
960
+ }
961
+ function visLayer(o, target) {
962
+ if (!isJsonObject(o)) {
963
+ return {};
964
+ }
965
+ const layer = {};
966
+ const set = (k, v) => {
967
+ if (v !== void 0 && v !== null) {
968
+ layer[k] = v;
969
+ }
970
+ };
971
+ if (target === "node") {
972
+ visNodeLayer(o, set);
973
+ } else {
974
+ visEdgeLayer(o, set);
975
+ }
976
+ set("hidden", o.hidden);
977
+ set("label", o.label);
978
+ set("title", o.title);
979
+ visFontLayer(o.font, set);
980
+ return layer;
981
+ }
982
+ function visNodeLayer(o, set) {
983
+ const { color } = o;
984
+ if (typeof color === "string") {
985
+ const parsed = visParseColor(color.trim());
986
+ set("fill", parsed.background);
987
+ set("border", parsed.border);
988
+ } else if (isJsonObject(color)) {
989
+ set("fill", color.background);
990
+ set("border", color.border);
991
+ }
992
+ set("shape", o.shape);
993
+ set("size", o.size);
994
+ set("borderWidth", o.borderWidth);
995
+ set("opacity", o.opacity);
996
+ }
997
+ function visEdgeLayer(o, set) {
998
+ const { color } = o;
999
+ if (typeof color === "string") {
1000
+ set("edgeColor", color);
1001
+ set("inherit", false);
1002
+ } else if (isJsonObject(color)) {
1003
+ set("edgeColor", color.color);
1004
+ set("edgeOpacity", color.opacity);
1005
+ const own = color.color !== void 0 || color.highlight !== void 0 || color.hover !== void 0;
1006
+ set("inherit", own ? false : color.inherit);
1007
+ }
1008
+ set("width", o.width);
1009
+ set("dashes", o.dashes);
1010
+ set("arrows", o.arrows);
1011
+ }
1012
+ function visFontLayer(font, set) {
1013
+ if (isJsonObject(font)) {
1014
+ set("fontColor", font.color);
1015
+ set("fontSize", font.size);
1016
+ set("fontFace", font.face);
1017
+ } else if (typeof font === "string") {
1018
+ const m = /^\s*(\d+(?:\.\d+)?)(?:px)?\s+(\S+)(?:\s+(\S+))?/.exec(font.slice(0, 256));
1019
+ if (m !== null) {
1020
+ set("fontSize", Number(m[1]));
1021
+ set("fontFace", m[2]);
1022
+ set("fontColor", m[3]);
1023
+ }
1024
+ }
1025
+ }
1026
+ function visValues(layer, target, site, sized) {
1027
+ const out = {};
1028
+ const put = (p, v) => {
1029
+ if (v !== null) {
1030
+ out[p] = v;
1031
+ }
1032
+ };
1033
+ const color = (p, opacity, raw) => {
1034
+ if (raw === void 0 || raw === null || raw === "") {
1035
+ return;
1036
+ }
1037
+ const c = canonColor(raw, "vis", site(p));
1038
+ if (c !== null) {
1039
+ put(p, c.color);
1040
+ if (c.alpha < 1 && opacity !== null) {
1041
+ put(opacity, c.alpha);
1042
+ }
1043
+ }
1044
+ };
1045
+ if (target === "node") {
1046
+ color("fill", "fillOpacity", layer.fill);
1047
+ color("borderColor", null, layer.border);
1048
+ visNodeValues(layer, sized, put, site);
1049
+ } else {
1050
+ color("color", "opacity", layer.edgeColor);
1051
+ visEdgeValues(layer, put, site);
1052
+ }
1053
+ if (layer.hidden !== void 0 && canonBoolean(layer.hidden, site("visible")) === true) {
1054
+ put("visible", false);
1055
+ }
1056
+ if (layer.label !== void 0) {
1057
+ put("label", canonText(layer.label, site("label")));
1058
+ }
1059
+ if (layer.title !== void 0) {
1060
+ put("tooltip", canonText(layer.title, site("tooltip")));
1061
+ }
1062
+ color("labelColor", null, layer.fontColor);
1063
+ if (layer.fontSize !== void 0) {
1064
+ put("labelSize", canonNumber(layer.fontSize, site("labelSize")));
1065
+ }
1066
+ if (layer.fontFace !== void 0) {
1067
+ put("labelFont", canonText(layer.fontFace, site("labelFont")));
1068
+ }
1069
+ return out;
1070
+ }
1071
+ function visNodeValues(layer, sized, put, site) {
1072
+ if (layer.shape !== void 0) {
1073
+ put("shape", canonEnum("shape", layer.shape, "vis", site("shape")));
1074
+ }
1075
+ if (sized && layer.size !== void 0) {
1076
+ const v = canonNumber(layer.size, site("width"));
1077
+ put("width", v);
1078
+ put("height", v);
1079
+ }
1080
+ if (layer.borderWidth !== void 0) {
1081
+ put("borderWidth", canonNumber(layer.borderWidth, site("borderWidth")));
1082
+ }
1083
+ if (layer.opacity !== void 0) {
1084
+ put("opacity", canonOpacity(layer.opacity, "vis", site("opacity")));
1085
+ }
1086
+ }
1087
+ function visEdgeValues(layer, put, site) {
1088
+ if (layer.edgeOpacity !== void 0) {
1089
+ put("opacity", canonOpacity(layer.edgeOpacity, "vis", site("opacity")));
1090
+ }
1091
+ if (layer.width !== void 0) {
1092
+ put("width", canonNumber(layer.width, site("width")));
1093
+ }
1094
+ if (layer.dashes !== void 0) {
1095
+ put("lineStyle", layer.dashes === false || layer.dashes === "false" ? "solid" : "dashed");
1096
+ }
1097
+ if (layer.arrows !== void 0) {
1098
+ const [to, from] = visArrows(layer.arrows, site);
1099
+ put("targetArrow", to);
1100
+ put("sourceArrow", from);
1101
+ }
1102
+ }
1103
+ function visArrows(arrows, site) {
1104
+ const end = (name, property) => {
1105
+ if (typeof arrows === "string") {
1106
+ return new RegExp(String.raw`\b${name}\b`).test(arrows.slice(0, 256)) ? "triangle" : "none";
1107
+ }
1108
+ if (!isJsonObject(arrows)) {
1109
+ return null;
1110
+ }
1111
+ const a = arrows[name];
1112
+ if (a === true) {
1113
+ return "triangle";
1114
+ }
1115
+ if (!isJsonObject(a) || a.enabled === false) {
1116
+ return "none";
1117
+ }
1118
+ return canonEnum("arrow", a.type ?? "arrow", "vis", site(property));
1119
+ };
1120
+ return [end("to", "targetArrow"), end("from", "sourceArrow")];
1121
+ }
1122
+ function visStyles(snapshot, src, context) {
1123
+ const notes = new StyleNotes();
1124
+ const options = isJsonObject(src.options) ? src.options : {};
1125
+ const n = snapshot.nodeCount;
1126
+ const ruleSite = (target) => (property) => ({ notes, target, property });
1127
+ const nodeRules = [];
1128
+ const nodeColumns = /* @__PURE__ */ new Map();
1129
+ const nodeDefaults = visLayer(options.nodes, "node");
1130
+ const groupCol = cells(snapshot, "node", "group");
1131
+ const groupOf = (i) => {
1132
+ const g = groupCol?.(i);
1133
+ return typeof g === "string" || typeof g === "number" ? String(g) : null;
1134
+ };
1135
+ const { groupLayers, paletteRows } = visGroupLayers(n, groupOf, visGroupDefs(src, options));
1136
+ context.budget.spend("node", n);
1137
+ const node = valuesOf(n);
1138
+ const records = nodeRecords(snapshot);
1139
+ const rawShape = (layer) => typeof layer.shape === "string" ? layer.shape : null;
1140
+ for (let i = 0; i < n; i++) {
1141
+ const g = groupOf(i);
1142
+ const own = records(i);
1143
+ const group = g === null ? {} : groupLayers.get(g) ?? {};
1144
+ const shape = rawShape(own) ?? rawShape(group) ?? rawShape(nodeDefaults) ?? "ellipse";
1145
+ const site = (property) => ({
1146
+ notes,
1147
+ target: "node",
1148
+ property,
1149
+ element: i,
1150
+ budget: context.budget
1151
+ });
1152
+ const merged = { ...nodeDefaults, ...group, ...own };
1153
+ for (const [p, v] of Object.entries(visValues(merged, "node", site, VIS_SIZED.has(shape)))) {
1154
+ node.put(p, i, v);
1155
+ }
1156
+ }
1157
+ const declaredNode = visValues(nodeDefaults, "node", ruleSite("node"), true);
1158
+ if (Object.keys(declaredNode).length > 0) {
1159
+ nodeRules.push(rule("node.vis.defaults", "node", "defaults", "declared", { all: true }, declaredNode));
1160
+ }
1161
+ let k = 0;
1162
+ for (const [g, layer] of groupLayers) {
1163
+ const set = paletteRows.get(g) ?? visValues(layer, "node", ruleSite("node"), true);
1164
+ if (Object.keys(set).length === 0) {
1165
+ continue;
1166
+ }
1167
+ const key = `group.${String(k)}`;
1168
+ nodeColumns.set(
1169
+ key,
1170
+ Array.from({ length: n }, (_v, i) => groupOf(i) === g ? true : null)
1171
+ );
1172
+ const origin = paletteRows.has(g) ? "tool" : "declared";
1173
+ const r = rule(`node.vis.group.${String(k++)}`, "node", "group", origin, { has: { style: key } }, set);
1174
+ nodeRules.push({ ...r, facts: { names: [[key, g]] } });
1175
+ }
1176
+ const toolNode = toolDefaults("vis-network")?.node;
1177
+ const borderOf = (i) => node.values.borderColor?.[i] ?? toolNode?.borderColor?.value ?? "#2b7ce9";
1178
+ const edge = visEdges(snapshot, visLayer(options.edges, "edge"), borderOf, notes, context);
1179
+ const values = { node: node.values, edge: edge.values };
1180
+ exactFromBlock(snapshot, src.block, values, VIS_WRITTEN);
1181
+ return {
1182
+ canonical: true,
1183
+ dialect: "vis",
1184
+ tool: "vis-network",
1185
+ opacityInColor: true,
1186
+ units: "px",
1187
+ node: { values: values.node, rules: nodeRules, columns: nodeColumns },
1188
+ edge: { values: values.edge, rules: edge.rules, columns: edge.columns },
1189
+ notes: notes.list(),
1190
+ block: src.block,
1191
+ readFrom: {
1192
+ node: VIS_KEYS.node.filter((x) => snapshot.nodes.has(x)),
1193
+ edge: VIS_KEYS.edge.filter((x) => snapshot.edges.has(x))
1194
+ }
1195
+ };
1196
+ }
1197
+ function visGroupDefs(src, options) {
1198
+ if (isJsonObject(options.groups)) {
1199
+ return options.groups;
1200
+ }
1201
+ return isJsonObject(src.groups) ? src.groups : {};
1202
+ }
1203
+ function visGroupLayers(n, groupOf, groupDefs) {
1204
+ const groupLayers = /* @__PURE__ */ new Map();
1205
+ const paletteRows = /* @__PURE__ */ new Map();
1206
+ let palette = 0;
1207
+ for (let i = 0; i < n; i++) {
1208
+ const g = groupOf(i);
1209
+ if (g === null || groupLayers.has(g)) {
1210
+ continue;
1211
+ }
1212
+ if (Object.hasOwn(groupDefs, g)) {
1213
+ groupLayers.set(g, visLayer(groupDefs[g], "node"));
1214
+ } else {
1215
+ const [border, background] = VIS_GROUP_PALETTE[palette++ % VIS_GROUP_PALETTE.length];
1216
+ groupLayers.set(g, { fill: background, border });
1217
+ paletteRows.set(g, { fill: background.toLowerCase(), borderColor: border.toLowerCase() });
1218
+ }
1219
+ }
1220
+ return { groupLayers, paletteRows };
1221
+ }
1222
+ function visEdges(snapshot, edgeDefaults, borderOf, notes, context) {
1223
+ const m = snapshot.edgeCount;
1224
+ const edge = valuesOf(m);
1225
+ const edgeRecords = elementRecords(snapshot, "edge");
1226
+ const inherited = new Array(m).fill(null);
1227
+ let inheriting = 0;
1228
+ for (let e = 0; e < m; e++) {
1229
+ const own = edgeRecords(e);
1230
+ const merged = { ...edgeDefaults, ...own };
1231
+ const site = (property) => ({
1232
+ notes,
1233
+ target: "edge",
1234
+ property,
1235
+ element: e,
1236
+ budget: context.budget
1237
+ });
1238
+ const vals = visValues(merged, "edge", site, true);
1239
+ for (const [p, v] of Object.entries(vals)) {
1240
+ edge.put(p, e, v);
1241
+ }
1242
+ const inherit = own.inherit ?? edgeDefaults.inherit ?? "from";
1243
+ if (inherit === false || inherit === "false") {
1244
+ if (vals.color === void 0) {
1245
+ edge.put("color", e, VIS_EDGE_COLOR);
1246
+ }
1247
+ continue;
1248
+ }
1249
+ if (inherit === "both") {
1250
+ notes.add(STYLE_ISSUE.GRADIENT, "edge", "color", { sample: "inherit both", element: e });
1251
+ }
1252
+ inherited[e] = borderOf(inherit === "to" ? snapshot.edgeTarget(e) : snapshot.edgeSource(e));
1253
+ inheriting++;
1254
+ }
1255
+ context.budget.spend("edge", m);
1256
+ const edgeRules = [];
1257
+ const edgeColumns = /* @__PURE__ */ new Map();
1258
+ const declaredEdge = visValues(edgeDefaults, "edge", (property) => ({ notes, target: "edge", property }), true);
1259
+ if (Object.keys(declaredEdge).length > 0) {
1260
+ edgeRules.push(rule("edge.vis.defaults", "edge", "defaults", "declared", { all: true }, declaredEdge));
1261
+ }
1262
+ if (inheriting > 0) {
1263
+ edgeColumns.set("source-color", inherited);
1264
+ edgeRules.push({
1265
+ id: "edge.tool.source-color",
1266
+ target: "edge",
1267
+ role: "passthrough",
1268
+ origin: "tool",
1269
+ where: { has: { style: "source-color" } },
1270
+ map: { color: { kind: "passthrough", by: { style: "source-color" } } },
1271
+ facts: { elements: inheriting, reason: "SOURCE_NODE_COLOR" }
1272
+ });
1273
+ }
1274
+ return { values: edge.values, rules: edgeRules, columns: edgeColumns };
1275
+ }
1276
+ const VIS_KEYS = {
1277
+ node: ["color", "shape", "size", "borderWidth", "opacity", "hidden", "label", "title", "font"],
1278
+ edge: ["color", "width", "dashes", "arrows", "hidden", "label", "title", "font"]
1279
+ };
1280
+ function nodeRecords(snapshot) {
1281
+ return elementRecords(snapshot, "node");
1282
+ }
1283
+ function elementRecords(snapshot, target) {
1284
+ const readers = VIS_KEYS[target].map((name) => [name, cells(snapshot, target, name)]).filter((x) => x[1] !== null);
1285
+ return (i) => {
1286
+ const record = {};
1287
+ for (const [name, read] of readers) {
1288
+ const v = read(i);
1289
+ if (v !== null) {
1290
+ record[name] = v;
1291
+ }
1292
+ }
1293
+ return visLayer(record, target);
1294
+ };
1295
+ }
1296
+ function rule(id, target, role, origin, where, set) {
1297
+ const values = {};
1298
+ for (const [p, v] of Object.entries(set)) {
1299
+ if (v !== null) {
1300
+ values[p] = v;
1301
+ }
1302
+ }
1303
+ return { id, target, role, origin, where, set: values };
1304
+ }
1305
+ const VIS_SHAPES = /* @__PURE__ */ new Map([
1306
+ ["ellipse", ["dot", true]],
1307
+ ["rectangle", ["square", true]],
1308
+ ["round-rectangle", ["box", true]],
1309
+ ["triangle", ["triangle", true]],
1310
+ ["diamond", ["diamond", true]],
1311
+ ["star", ["star", true]],
1312
+ ["hexagon", ["hexagon", true]],
1313
+ ["none", ["text", true]],
1314
+ ["pentagon", ["hexagon", false]],
1315
+ ["octagon", ["hexagon", false]],
1316
+ ["parallelogram", ["box", false]],
1317
+ ["trapezoid", ["box", false]],
1318
+ ["vee", ["triangle", false]]
1319
+ ]);
1320
+ const VIS_ARROW_TYPES = /* @__PURE__ */ new Map([
1321
+ ["triangle", ["arrow", true]],
1322
+ ["tee", ["bar", true]],
1323
+ ["circle", ["circle", true]],
1324
+ ["square", ["box", true]],
1325
+ ["crow", ["crow", true]],
1326
+ ["diamond", ["diamond", true]],
1327
+ ["vee", ["vee", true]],
1328
+ ["inverted", ["inv_triangle", true]],
1329
+ ["triangle-open", ["arrow", false]],
1330
+ ["diamond-open", ["diamond", false]],
1331
+ ["circle-open", ["circle", false]],
1332
+ ["half", ["arrow", false]]
1333
+ ]);
1334
+ function visShape(shape) {
1335
+ const known = VIS_SHAPES.get(shape);
1336
+ if (known !== void 0) {
1337
+ return known;
1338
+ }
1339
+ return shape.startsWith("other:") ? [shape.slice(6), true] : ["dot", false];
1340
+ }
1341
+ function visArrowType(arrow) {
1342
+ if (arrow === "none") {
1343
+ return [null, true];
1344
+ }
1345
+ const known = VIS_ARROW_TYPES.get(arrow);
1346
+ if (known !== void 0) {
1347
+ return known;
1348
+ }
1349
+ return arrow.startsWith("other:") ? [arrow.slice(6), true] : ["arrow", false];
1350
+ }
1351
+ const visSize = (want) => {
1352
+ const s = want("shape");
1353
+ const shape = typeof s === "string" ? visShape(s)[0] : "ellipse";
1354
+ return VIS_SIZED.has(shape) ? oneSize(want) : null;
1355
+ };
1356
+ const VIS_WRITTEN = {
1357
+ node: {
1358
+ width: visSize,
1359
+ height: visSize,
1360
+ shape: (want) => {
1361
+ const s = want("shape");
1362
+ if (typeof s !== "string") {
1363
+ return null;
1364
+ }
1365
+ const site = { notes: new StyleNotes(), target: "node", property: "shape" };
1366
+ return canonEnum("shape", visShape(s)[0], "vis", site);
1367
+ }
1368
+ },
1369
+ edge: {
1370
+ lineStyle: (want) => {
1371
+ const s = want("lineStyle");
1372
+ if (s === null) {
1373
+ return null;
1374
+ }
1375
+ return s === "solid" ? "solid" : "dashed";
1376
+ },
1377
+ targetArrow: (want) => arrowBack(want("targetArrow")),
1378
+ sourceArrow: (want) => arrowBack(want("sourceArrow"))
1379
+ }
1380
+ };
1381
+ function arrowBack(a) {
1382
+ if (typeof a !== "string") {
1383
+ return null;
1384
+ }
1385
+ const [type] = visArrowType(a);
1386
+ const site = { notes: new StyleNotes(), target: "edge", property: "targetArrow" };
1387
+ return type === null ? "none" : canonEnum("arrow", type, "vis", site);
1388
+ }
1389
+ function cyjsProperties(map, extra) {
1390
+ const out = /* @__PURE__ */ new Set();
1391
+ for (const spec of map.values()) {
1392
+ if (!spec.property.startsWith("_")) {
1393
+ out.add(spec.property);
1394
+ }
1395
+ }
1396
+ for (const p of extra) {
1397
+ out.add(p);
1398
+ }
1399
+ return [...out];
1400
+ }
1401
+ const NATIVE = {
1402
+ cytoscape: {
1403
+ node: cyjsProperties(CYJS_NODE_PROPERTIES, ["labelPosition", "labelItalic", "visible"]),
1404
+ edge: cyjsProperties(CYJS_EDGE_PROPERTIES, ["curved", "labelItalic", "visible"])
1405
+ },
1406
+ graphology: {
1407
+ node: ["fill", "fillOpacity", "width", "height", "label", "visible"],
1408
+ edge: ["color", "opacity", "width", "label", "visible"]
1409
+ },
1410
+ vis: {
1411
+ node: [
1412
+ "fill",
1413
+ "fillOpacity",
1414
+ "borderColor",
1415
+ "borderWidth",
1416
+ "shape",
1417
+ "width",
1418
+ "height",
1419
+ "opacity",
1420
+ "label",
1421
+ "tooltip",
1422
+ "labelColor",
1423
+ "labelSize",
1424
+ "labelFont",
1425
+ "visible"
1426
+ ],
1427
+ edge: [
1428
+ "color",
1429
+ "opacity",
1430
+ "width",
1431
+ "lineStyle",
1432
+ "targetArrow",
1433
+ "sourceArrow",
1434
+ "label",
1435
+ "tooltip",
1436
+ "labelColor",
1437
+ "labelSize",
1438
+ "labelFont",
1439
+ "visible"
1440
+ ]
1441
+ }
1442
+ };
1443
+ const JSON_STYLE_CAPABILITIES = Object.freeze({
1444
+ node: Object.freeze([
1445
+ .../* @__PURE__ */ new Set([...NATIVE.cytoscape.node, ...NATIVE.vis.node, ...NATIVE.graphology.node])
1446
+ ]),
1447
+ edge: Object.freeze([
1448
+ .../* @__PURE__ */ new Set([...NATIVE.cytoscape.edge, ...NATIVE.vis.edge, ...NATIVE.graphology.edge])
1449
+ ]),
1450
+ block: "native"
1451
+ });
1452
+ const BLOCK_AS_ATTRIBUTE = /* @__PURE__ */ new Set(["node-link", "jgf", "graphology"]);
1453
+ function jsonStyledExport(snapshot, dialect, input) {
1454
+ if (input === void 0) {
1455
+ return null;
1456
+ }
1457
+ const native = dialect === "cytoscape" || dialect === "graphology" || dialect === "vis" ? NATIVE[dialect] : null;
1458
+ const notes = [...notWritten(input, dialect, native), ...rulesNotKept(snapshot, dialect, input)];
1459
+ if (dialect === "obographs") {
1460
+ return { snapshot, topLevelBlock: null, stylesheet: null, groups: null, notes };
1461
+ }
1462
+ const out = snapshot.withColumns();
1463
+ const read = dataColumnsRead(input.rules.styles.rules);
1464
+ for (const [table, target] of [
1465
+ [out.nodes, "node"],
1466
+ [out.edges, "edge"]
1467
+ ]) {
1468
+ removeEarlierStyleKeys(table, dialect, read[target]);
1469
+ for (const [name, col] of input.tags[target]) {
1470
+ setColumn(table, name, col);
1471
+ }
1472
+ }
1473
+ if (out.graph.has(STYLE_BLOCK_NAME)) {
1474
+ out.graph.remove(STYLE_BLOCK_NAME);
1475
+ }
1476
+ if (BLOCK_AS_ATTRIBUTE.has(dialect)) {
1477
+ out.graph.set(STYLE_BLOCK_NAME, [input.block], { dtype: "string" });
1478
+ }
1479
+ let stylesheet = null;
1480
+ const approximated = new StyleApproximations();
1481
+ const replaced = new Replaced(out.nodes);
1482
+ if (dialect === "cytoscape") {
1483
+ const emitted = writeCytoscapeStyles(out, input);
1484
+ ({ stylesheet } = emitted);
1485
+ notes.push(...emitted.notes.map(lossOf));
1486
+ addUntrimmedText(input, approximated);
1487
+ } else if (dialect === "graphology") {
1488
+ writeGraphology$1(out, input, approximated, replaced);
1489
+ } else if (dialect === "vis") {
1490
+ writeVis$1(out, input, approximated, replaced);
1491
+ }
1492
+ notes.push(...approximated.notes(`the ${dialect} dialect of JSON`), ...replaced.notes(dialect));
1493
+ return {
1494
+ snapshot: out,
1495
+ topLevelBlock: BLOCK_AS_ATTRIBUTE.has(dialect) ? null : input.block,
1496
+ stylesheet,
1497
+ groups: dialect === "vis" ? visGroups(out) : null,
1498
+ notes
1499
+ };
1500
+ }
1501
+ function rulesNotKept(snapshot, dialect, input) {
1502
+ let message = null;
1503
+ if (dialect === "jgf" && !jgfKeepsNodes(snapshot)) {
1504
+ message = "the style rules are not kept: JGF changes the node ids' type or order (number ids become text, integer-like ids are read first), so the graphty.styles block no longer matches the graph read back";
1505
+ } else if (dialect === "obographs") {
1506
+ message = "the style rules are not kept: OBO Graphs has no place for them";
1507
+ }
1508
+ if (message === null) {
1509
+ return [];
1510
+ }
1511
+ return [
1512
+ Object.freeze({
1513
+ code: STYLE_ISSUE.RULES_NOT_KEPT,
1514
+ message,
1515
+ column: null,
1516
+ count: input.rules.styles.rules.length
1517
+ })
1518
+ ];
1519
+ }
1520
+ function removeEarlierStyleKeys(table, dialect, read) {
1521
+ for (const name of table.names()) {
1522
+ const styleKey = name.startsWith("graphty.style.") || name.startsWith("graphty_style_") || name === CYTOSCAPE_IMPORT_KEY;
1523
+ if (styleKey && !read.has(name)) {
1524
+ table.remove(name);
1525
+ }
1526
+ }
1527
+ if (dialect === "cytoscape") {
1528
+ for (const name of ["style#element", "css#element"].filter((c) => table.has(c))) {
1529
+ table.remove(name);
1530
+ }
1531
+ }
1532
+ }
1533
+ function writeCytoscapeStyles(out, input) {
1534
+ const features = {
1535
+ node: input.rules.features.node.filter((f) => !("data" in f.ref) || out.nodes.has(f.ref.data)),
1536
+ edge: input.rules.features.edge.filter((f) => !("data" in f.ref) || out.edges.has(f.ref.data))
1537
+ };
1538
+ const emitted = toCytoscapeStylesheet({ ...input.rules, features });
1539
+ for (const [table, target] of [
1540
+ [out.nodes, "node"],
1541
+ [out.edges, "edge"]
1542
+ ]) {
1543
+ const rows = emitted.elementData[target];
1544
+ const keys = new Set(rows.flatMap((row) => Object.keys(row ?? {})));
1545
+ for (const key of keys) {
1546
+ setColumn(
1547
+ table,
1548
+ key,
1549
+ rows.map((row) => row?.[key] ?? null)
1550
+ );
1551
+ }
1552
+ const bypass = emitted.bypass[target].map((b) => b === null || Object.keys(b).length === 0 ? null : b);
1553
+ if (bypass.some((b) => b !== null)) {
1554
+ setColumn(table, "style#element", bypass);
1555
+ }
1556
+ }
1557
+ return emitted;
1558
+ }
1559
+ function addUntrimmedText(input, approximated) {
1560
+ for (const target of TARGETS) {
1561
+ for (const property of CYJS_TEXT[target]) {
1562
+ for (const v of input.picture(target, property)) {
1563
+ if (typeof v === "string" && v.trim() !== v) {
1564
+ approximated.add(target, property, JSON.stringify(v));
1565
+ }
1566
+ }
1567
+ }
1568
+ }
1569
+ }
1570
+ function visGroups(snapshot) {
1571
+ const column = snapshot.nodes.get("group");
1572
+ if (column === null || column === void 0) {
1573
+ return null;
1574
+ }
1575
+ const groups = /* @__PURE__ */ new Map();
1576
+ for (let i = 0; i < snapshot.nodeCount; i++) {
1577
+ const value = column.isSet(i) ? column.value(i) : null;
1578
+ if (typeof value === "string" || typeof value === "number") {
1579
+ groups.set(String(value), {});
1580
+ }
1581
+ }
1582
+ return groups.size === 0 ? null : Object.fromEntries(groups);
1583
+ }
1584
+ function dataColumnsRead(rules) {
1585
+ const out = { node: /* @__PURE__ */ new Set(), edge: /* @__PURE__ */ new Set() };
1586
+ for (const rule2 of rules) {
1587
+ const refs = [
1588
+ ...predicateRefs(rule2.where),
1589
+ ...Object.values(rule2.map ?? {}).flatMap((m) => m === void 0 ? [] : [m.by])
1590
+ ];
1591
+ for (const ref of refs) {
1592
+ if ("data" in ref) {
1593
+ out[rule2.target].add(ref.data);
1594
+ }
1595
+ }
1596
+ }
1597
+ return out;
1598
+ }
1599
+ function predicateRefs(where) {
1600
+ const refs = [];
1601
+ const stack = [where];
1602
+ while (stack.length > 0) {
1603
+ const p = stack.pop();
1604
+ if ("has" in p) {
1605
+ refs.push(p.has);
1606
+ } else if ("eq" in p) {
1607
+ refs.push(p.eq[0]);
1608
+ } else if ("in" in p) {
1609
+ refs.push(p.in[0]);
1610
+ } else if ("and" in p) {
1611
+ stack.push(...p.and);
1612
+ } else if ("or" in p) {
1613
+ stack.push(...p.or);
1614
+ } else if ("not" in p) {
1615
+ stack.push(p.not);
1616
+ }
1617
+ }
1618
+ return refs;
1619
+ }
1620
+ function jgfKeepsNodes(snapshot) {
1621
+ let last = -1;
1622
+ let other = false;
1623
+ for (let i = 0; i < snapshot.nodeCount; i++) {
1624
+ const id = snapshot.ids.idOf(i);
1625
+ if (typeof id === "number") {
1626
+ return false;
1627
+ }
1628
+ if (/^(0|[1-9]\d*)$/.test(id) && Number(id) < 4294967295) {
1629
+ if (other || Number(id) <= last) {
1630
+ return false;
1631
+ }
1632
+ last = Number(id);
1633
+ } else {
1634
+ other = true;
1635
+ }
1636
+ }
1637
+ return true;
1638
+ }
1639
+ function notWritten(input, dialect, native) {
1640
+ const out = [];
1641
+ for (const target of TARGETS) {
1642
+ const all = new Set(JSON_STYLE_CAPABILITIES[target]);
1643
+ const held = new Set(native?.[target] ?? []);
1644
+ const used = /* @__PURE__ */ new Set();
1645
+ for (const r of input.rules.styles.rules) {
1646
+ if (r.target === target) {
1647
+ for (const p of [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})]) {
1648
+ used.add(p);
1649
+ }
1650
+ }
1651
+ }
1652
+ for (const property of used) {
1653
+ if (!all.has(property) || held.has(property)) {
1654
+ continue;
1655
+ }
1656
+ const count = input.picture(target, property).filter((v) => v !== null).length;
1657
+ out.push(
1658
+ Object.freeze({
1659
+ code: STYLE_ISSUE.NOT_WRITTEN,
1660
+ message: `${target} ${property} is not written: the ${dialect} dialect of JSON has no place for it`,
1661
+ column: null,
1662
+ count,
1663
+ style: Object.freeze({ target, property })
1664
+ })
1665
+ );
1666
+ }
1667
+ }
1668
+ return out;
1669
+ }
1670
+ function lossOf(n) {
1671
+ return Object.freeze({
1672
+ code: n.code,
1673
+ message: n.message,
1674
+ column: null,
1675
+ count: n.params.count,
1676
+ style: n.params.target === null || n.params.property === null ? void 0 : Object.freeze({ target: n.params.target, property: n.params.property })
1677
+ });
1678
+ }
1679
+ function setColumn(table, name, values) {
1680
+ const kinds = new Set(values.filter((v) => v !== null && v !== void 0).map((v) => typeof v));
1681
+ let dtype = "json";
1682
+ if (kinds.size === 1) {
1683
+ if (kinds.has("number")) {
1684
+ dtype = "f64";
1685
+ } else if (kinds.has("boolean")) {
1686
+ dtype = "bool";
1687
+ } else if (kinds.has("string")) {
1688
+ dtype = "string";
1689
+ }
1690
+ }
1691
+ table.set(
1692
+ name,
1693
+ values.map((v) => v === null ? void 0 : v),
1694
+ { dtype }
1695
+ );
1696
+ }
1697
+ function writeKey(table, name, values, replaced) {
1698
+ const old = table.get(name);
1699
+ let changed = 0;
1700
+ if (old !== null) {
1701
+ for (let i = 0; i < values.length; i++) {
1702
+ const before = plainCell(old.value(i));
1703
+ const after = values[i] ?? null;
1704
+ if (before !== null && JSON.stringify(before) !== JSON.stringify(after)) {
1705
+ changed++;
1706
+ }
1707
+ }
1708
+ }
1709
+ if (changed > 0) {
1710
+ replaced.add(table === replaced.nodes ? "node" : "edge", name, changed);
1711
+ }
1712
+ if (values.every((v) => v === null || v === void 0)) {
1713
+ if (old !== null) {
1714
+ table.remove(name);
1715
+ }
1716
+ return;
1717
+ }
1718
+ setColumn(table, name, values);
1719
+ }
1720
+ const STYLE_KEY_REPLACED_CODE = "W_JSON_STYLE_KEY_REPLACED";
1721
+ class Replaced {
1722
+ /**
1723
+ * Counts the replaced values of one export.
1724
+ * @param nodes - the node table being written, which tells node columns from edge columns
1725
+ */
1726
+ constructor(nodes) {
1727
+ this.nodes = nodes;
1728
+ }
1729
+ #counts = /* @__PURE__ */ new Map();
1730
+ /**
1731
+ * Counts replaced values.
1732
+ * @param target - nodes or edges
1733
+ * @param key - the key
1734
+ * @param count - how many
1735
+ */
1736
+ add(target, key, count) {
1737
+ this.#counts.set(`${target}\0${key}`, (this.#counts.get(`${target}\0${key}`) ?? 0) + count);
1738
+ }
1739
+ /**
1740
+ * The notes, one per key.
1741
+ * @param dialect - the dialect, for the message
1742
+ * @returns the notes
1743
+ */
1744
+ notes(dialect) {
1745
+ return Array.from(this.#counts, ([key, count]) => {
1746
+ const [target, name] = key.split("\0");
1747
+ return Object.freeze({
1748
+ code: STYLE_KEY_REPLACED_CODE,
1749
+ message: `${target} column "${name}" is the ${dialect} dialect's style key: ${String(count)} ${target}${count === 1 ? "" : "s"} get what graphty draws instead of the value the column held`,
1750
+ column: name,
1751
+ count
1752
+ });
1753
+ });
1754
+ }
1755
+ }
1756
+ function cssColor(color, alpha) {
1757
+ if (typeof color !== "string") {
1758
+ return null;
1759
+ }
1760
+ if (typeof alpha !== "number" || alpha >= 1) {
1761
+ return color;
1762
+ }
1763
+ const n = Number.parseInt(color.slice(1), 16);
1764
+ return `rgba(${String(n >> 16 & 255)},${String(n >> 8 & 255)},${String(n & 255)},${String(alpha)})`;
1765
+ }
1766
+ function nodeSizes(width, height, approximated) {
1767
+ return width.map((_v, i) => {
1768
+ const w = width[i];
1769
+ const h = height[i];
1770
+ if (typeof w === "number" && typeof h === "number" && w !== h) {
1771
+ approximated.add("node", w > h ? "height" : "width", `${String(w)} x ${String(h)}`);
1772
+ return Math.max(w, h);
1773
+ }
1774
+ if (typeof w === "number") {
1775
+ return w;
1776
+ }
1777
+ return typeof h === "number" ? h : null;
1778
+ });
1779
+ }
1780
+ function writeGraphology$1(out, input, approximated, replaced) {
1781
+ const p = (target, property) => input.picture(target, property);
1782
+ for (const [table, target] of [
1783
+ [out.nodes, "node"],
1784
+ [out.edges, "edge"]
1785
+ ]) {
1786
+ const [fill, opacity] = target === "node" ? ["fill", "fillOpacity"] : ["color", "opacity"];
1787
+ const colors = p(target, fill);
1788
+ const alphas = p(target, opacity);
1789
+ writeKey(
1790
+ table,
1791
+ "color",
1792
+ colors.map((c, i) => cssColor(c, alphas[i])),
1793
+ replaced
1794
+ );
1795
+ writeKey(
1796
+ table,
1797
+ "size",
1798
+ target === "node" ? nodeSizes(p("node", "width"), p("node", "height"), approximated) : p("edge", "width"),
1799
+ replaced
1800
+ );
1801
+ writeKey(table, "label", p(target, "label"), replaced);
1802
+ writeKey(
1803
+ table,
1804
+ "hidden",
1805
+ p(target, "visible").map((v) => v === false ? true : null),
1806
+ replaced
1807
+ );
1808
+ }
1809
+ }
1810
+ function writeVis$1(out, input, approximated, replaced) {
1811
+ const p = (target, property) => input.picture(target, property);
1812
+ const font = (target) => {
1813
+ const color2 = p(target, "labelColor");
1814
+ const size = p(target, "labelSize");
1815
+ const face = p(target, "labelFont");
1816
+ return color2.map((_v, i) => {
1817
+ const f = {};
1818
+ if (color2[i] !== null) {
1819
+ f.color = color2[i];
1820
+ }
1821
+ if (size[i] !== null) {
1822
+ f.size = size[i];
1823
+ }
1824
+ if (face[i] !== null) {
1825
+ f.face = face[i];
1826
+ }
1827
+ return Object.keys(f).length === 0 ? null : f;
1828
+ });
1829
+ };
1830
+ const label = (table, target) => {
1831
+ writeKey(table, "label", p(target, "label"), replaced);
1832
+ writeKey(table, "title", p(target, "tooltip"), replaced);
1833
+ writeKey(table, "font", font(target), replaced);
1834
+ writeKey(
1835
+ table,
1836
+ "hidden",
1837
+ p(target, "visible").map((v) => v === false ? true : null),
1838
+ replaced
1839
+ );
1840
+ };
1841
+ const fill = p("node", "fill");
1842
+ const fillOpacity = p("node", "fillOpacity");
1843
+ const border = p("node", "borderColor");
1844
+ writeKey(
1845
+ out.nodes,
1846
+ "color",
1847
+ fill.map((_v, i) => {
1848
+ const c = {};
1849
+ const bg = cssColor(fill[i], fillOpacity[i]);
1850
+ if (bg !== null) {
1851
+ c.background = bg;
1852
+ }
1853
+ if (typeof border[i] === "string") {
1854
+ c.border = border[i];
1855
+ }
1856
+ return Object.keys(c).length === 0 ? null : c;
1857
+ }),
1858
+ replaced
1859
+ );
1860
+ const sizes = nodeSizes(p("node", "width"), p("node", "height"), approximated);
1861
+ const shapes = p("node", "shape").map((s, i) => {
1862
+ const [shape, exact] = typeof s === "string" ? visShape(s) : [null, true];
1863
+ if (!exact) {
1864
+ approximated.add("node", "shape", s);
1865
+ }
1866
+ if (sizes[i] !== null && !VIS_SIZED.has(shape ?? "ellipse")) {
1867
+ approximated.add("node", "width", `${String(s ?? "ellipse")} sized by its label`);
1868
+ }
1869
+ return shape;
1870
+ });
1871
+ writeKey(out.nodes, "shape", shapes, replaced);
1872
+ writeKey(out.nodes, "size", sizes, replaced);
1873
+ writeKey(out.nodes, "borderWidth", p("node", "borderWidth"), replaced);
1874
+ writeKey(out.nodes, "opacity", p("node", "opacity"), replaced);
1875
+ label(out.nodes, "node");
1876
+ const color = p("edge", "color");
1877
+ const opacity = p("edge", "opacity");
1878
+ writeKey(
1879
+ out.edges,
1880
+ "color",
1881
+ color.map((_v, e) => {
1882
+ const c = {};
1883
+ if (typeof color[e] === "string") {
1884
+ c.color = color[e];
1885
+ }
1886
+ if (typeof opacity[e] === "number") {
1887
+ c.opacity = opacity[e];
1888
+ }
1889
+ return Object.keys(c).length === 0 ? null : c;
1890
+ }),
1891
+ replaced
1892
+ );
1893
+ writeKey(out.edges, "width", p("edge", "width"), replaced);
1894
+ writeKey(
1895
+ out.edges,
1896
+ "dashes",
1897
+ p("edge", "lineStyle").map((s) => {
1898
+ if (typeof s !== "string") {
1899
+ return null;
1900
+ }
1901
+ if (s !== "solid" && s !== "dashed") {
1902
+ approximated.add("edge", "lineStyle", s);
1903
+ }
1904
+ return s !== "solid";
1905
+ }),
1906
+ replaced
1907
+ );
1908
+ const to = p("edge", "targetArrow");
1909
+ const from = p("edge", "sourceArrow");
1910
+ writeKey(
1911
+ out.edges,
1912
+ "arrows",
1913
+ to.map((_v, e) => {
1914
+ const a = {};
1915
+ for (const [end, value, property] of [
1916
+ ["to", to[e], "targetArrow"],
1917
+ ["from", from[e], "sourceArrow"]
1918
+ ]) {
1919
+ if (typeof value !== "string") {
1920
+ continue;
1921
+ }
1922
+ const [type, exact] = visArrowType(value);
1923
+ if (!exact) {
1924
+ approximated.add("edge", property, value);
1925
+ }
1926
+ a[end] = type === null ? { enabled: false } : { enabled: true, type };
1927
+ }
1928
+ return Object.keys(a).length === 0 ? null : a;
1929
+ }),
1930
+ replaced
1931
+ );
1932
+ label(out.edges, "edge");
1933
+ }
568
1934
  const JSON_ISSUE = Object.freeze({
569
1935
  ...INPUT_ISSUE,
570
1936
  ...ELEMENT_ISSUE,
@@ -726,9 +2092,12 @@ const JGF_EDGE_KEYS = /* @__PURE__ */ new Set([
726
2092
  "metadata"
727
2093
  ]);
728
2094
  const JGF_HYPEREDGE_KEYS = /* @__PURE__ */ new Set([...JGF_EDGE_KEYS, "nodes"]);
2095
+ const ARRAY_INDEX = /^(?:0|[1-9]\d{0,9})$/;
729
2096
  const JGF_NODE_KEYS = /* @__PURE__ */ new Set(["label", "metadata"]);
730
2097
  const GRAPHOLOGY_NODE_KEYS = /* @__PURE__ */ new Set(["key", "attributes"]);
731
2098
  const GRAPHOLOGY_EDGE_KEYS = /* @__PURE__ */ new Set(["key", "source", "target", "attributes", "undirected"]);
2099
+ const GEPHI_NODE_KEYS = /* @__PURE__ */ new Set(["id", "attributes"]);
2100
+ const GEPHI_EDGE_KEYS = /* @__PURE__ */ new Set([...GRAPHOLOGY_EDGE_KEYS, "id"]);
732
2101
  const VIS_SOURCE_KEYS = Object.freeze(["from"]);
733
2102
  const VIS_TARGET_KEYS = Object.freeze(["to"]);
734
2103
  const PATH_DIALECTS = /* @__PURE__ */ new Set([
@@ -1050,11 +2419,13 @@ class ImportContext {
1050
2419
  * @param explicitDefaultDirected - whether the caller passed defaultDirected
1051
2420
  */
1052
2421
  constructor(sink, report, options, json2, explicitDefaultDirected) {
2422
+ this.text = "";
1053
2423
  this.elementsSinceCheck = 0;
1054
2424
  this.fileDirected = false;
1055
2425
  this.danglingIds = [];
1056
2426
  this.danglingCount = 0;
1057
2427
  this.nodesFromEdges = false;
2428
+ this.styleSource = null;
1058
2429
  this.nearMatches = [];
1059
2430
  this.sink = sink;
1060
2431
  this.report = report;
@@ -1213,10 +2584,34 @@ class ImportContext {
1213
2584
  if (missingSource) {
1214
2585
  this.dangling(source);
1215
2586
  }
1216
- if (missingTarget) {
1217
- this.dangling(target);
2587
+ if (missingTarget) {
2588
+ this.dangling(target);
2589
+ }
2590
+ return edge;
2591
+ }
2592
+ /**
2593
+ * A Cytoscape.js endpoint or parent id: Cytoscape.js holds every id as text, so an endpoint `0` names the node
2594
+ * `"0"` and an endpoint `"0"` the node `0` when the file has no node of the endpoint's own type.
2595
+ * @param raw - the JSON value
2596
+ * @param element - the element name for issues
2597
+ * @returns the id, or null when the value was reported
2598
+ */
2599
+ textualId(raw, element) {
2600
+ const id = this.coerceId(raw, element);
2601
+ if (id === null || this.sink.indexOf(id) !== INVALID_INDEX) {
2602
+ return id;
2603
+ }
2604
+ let other = null;
2605
+ if (typeof raw === "number" && Number.isFinite(raw)) {
2606
+ other = String(raw);
2607
+ } else if (typeof raw === "string" && /^-?\d+(?:\.\d+)?$/.test(raw)) {
2608
+ other = Number(raw);
1218
2609
  }
1219
- return edge;
2610
+ if (other === null) {
2611
+ return id;
2612
+ }
2613
+ const alt = this.ids.value(other);
2614
+ return this.sink.indexOf(alt) === INVALID_INDEX ? id : alt;
1220
2615
  }
1221
2616
  /**
1222
2617
  * Count a placeholder node an edge endpoint created.
@@ -1379,10 +2774,14 @@ class ImportContext {
1379
2774
  * @param record - the element record
1380
2775
  * @param dict - the nested attribute dict
1381
2776
  * @param structural - the element keys that are not attributes
1382
- * @param weightFrom - the weight key to skip in the dict, or null
1383
2777
  * @param element - the element name for issues
2778
+ * @param how - `weightFrom`: the weight key to skip in the dict; `plain`: write the element-level keys under their
2779
+ * own names, not with the `#element` suffix
2780
+ * @param how.weightFrom - the weight key to skip in the dict, or null (the default)
2781
+ * @param how.plain - write the element-level keys under their own names (default false)
1384
2782
  */
1385
- writeNested(writer, row, record, dict, structural, weightFrom, element) {
2783
+ writeNested(writer, row, record, dict, structural, element, how = {}) {
2784
+ const { weightFrom = null, plain = false } = how;
1386
2785
  for (const key of Object.keys(dict)) {
1387
2786
  if (key !== weightFrom) {
1388
2787
  writer.write(row, key, dict[key], SUFFIX.data, element);
@@ -1390,7 +2789,7 @@ class ImportContext {
1390
2789
  }
1391
2790
  for (const key of Object.keys(record)) {
1392
2791
  if (!structural.has(key)) {
1393
- writer.write(row, `${key}${SUFFIX.element}`, record[key], SUFFIX.data, element);
2792
+ writer.write(row, plain ? key : `${key}${SUFFIX.element}`, record[key], SUFFIX.data, element);
1394
2793
  }
1395
2794
  }
1396
2795
  }
@@ -1728,8 +3127,14 @@ function reportUnreadKeys(ctx, record, known, prefix) {
1728
3127
  );
1729
3128
  }
1730
3129
  }
1731
- const VIS_DOCUMENT_KEYS = /* @__PURE__ */ new Set(["nodes", "edges"]);
1732
- const GRAPHOLOGY_DOCUMENT_KEYS = /* @__PURE__ */ new Set(["nodes", "edges", "options", "attributes"]);
3130
+ const VIS_DOCUMENT_KEYS = /* @__PURE__ */ new Set(["nodes", "edges", STYLE_BLOCK_NAME]);
3131
+ const GRAPHOLOGY_DOCUMENT_KEYS = /* @__PURE__ */ new Set([
3132
+ "nodes",
3133
+ "edges",
3134
+ "options",
3135
+ "attributes",
3136
+ STYLE_BLOCK_NAME
3137
+ ]);
1733
3138
  const JGF_GRAPH_KEYS = /* @__PURE__ */ new Set([
1734
3139
  "id",
1735
3140
  "type",
@@ -1748,10 +3153,46 @@ function isIndexBelow(value, bound) {
1748
3153
  }
1749
3154
  function importNodeLink(ctx, root, dialect) {
1750
3155
  const { report, json: json2 } = ctx;
1751
- let { edgesKey } = json2;
1752
- if (edgesKey === null) {
1753
- edgesKey = hasKey(root, "edges") || !hasKey(root, "links") ? "edges" : "links";
3156
+ const edgesKey = json2.edgesKey ?? (hasKey(root, "edges") || !hasKey(root, "links") ? "edges" : "links");
3157
+ const { nodeList, edgeList } = nodeLinkSections(ctx, root, edgesKey);
3158
+ const directed = flagOf(root.directed, "directed", ctx.defaultDirected(dialect), report);
3159
+ const multigraph = hasKey(root, "multigraph") ? flagOf(root.multigraph, "multigraph", false, report) : null;
3160
+ ctx.setHeader(directed);
3161
+ ctx.writeGraphDict(root.graph, "graph");
3162
+ reportUnreadKeys(ctx, root, /* @__PURE__ */ new Set(["nodes", edgesKey, "directed", "multigraph", "graph", STYLE_BLOCK_NAME]), "");
3163
+ const networkx = hasKey(root, "directed") && hasKey(root, "multigraph") && hasKey(root, "graph");
3164
+ ctx.styleSource = { dialect, block: blockOf(root), networkx };
3165
+ ctx.sink.reserve(nodeList.length, edgeList.length);
3166
+ const nodeIdKey = nodeLinkIdKey(ctx, nodeList);
3167
+ const positional = nodeIdKey === null;
3168
+ let indexLinks;
3169
+ if (positional) {
3170
+ indexLinks = true;
3171
+ } else if (json2.indexLinks === "auto") {
3172
+ indexLinks = looksIndexLinked(nodeList, edgeList, nodeIdKey, json2);
3173
+ } else {
3174
+ ({ indexLinks } = json2);
1754
3175
  }
3176
+ if (indexLinks && !positional && json2.indexLinks === "auto") {
3177
+ reportAmbiguousIndexLinks(ctx, nodeList, edgeList, nodeIdKey);
3178
+ }
3179
+ const positionIds = importNodeLinkNodes(ctx, nodeList, nodeIdKey, indexLinks);
3180
+ throwIfAborted(ctx.options.signal);
3181
+ const endpointKeys = importNodeLinkEdges(ctx, edgeList, edgesKey, positionIds, multigraph);
3182
+ ctx.setMeta(
3183
+ {
3184
+ dialect,
3185
+ edgesKey,
3186
+ nodeIdKey,
3187
+ indexLinks,
3188
+ sourceKey: endpointKeys.source ?? void 0,
3189
+ targetKey: endpointKeys.target ?? void 0
3190
+ },
3191
+ { declaredMultigraph: multigraph, ...ctx.weightOriginPatch() }
3192
+ );
3193
+ }
3194
+ function nodeLinkSections(ctx, root, edgesKey) {
3195
+ const { report } = ctx;
1755
3196
  const nodes = arraySection(root.nodes, "nodes", report);
1756
3197
  const edges = arraySection(root[edgesKey], edgesKey, report);
1757
3198
  if (nodes === null) {
@@ -1771,94 +3212,67 @@ function importNodeLink(ctx, root, dialect) {
1771
3212
  { element: edgesKey }
1772
3213
  );
1773
3214
  }
1774
- const directed = flagOf(root.directed, "directed", ctx.defaultDirected(dialect), report);
1775
- const multigraph = hasKey(root, "multigraph") ? flagOf(root.multigraph, "multigraph", false, report) : null;
1776
- ctx.setHeader(directed);
1777
- ctx.writeGraphDict(root.graph, "graph");
1778
- reportUnreadKeys(ctx, root, /* @__PURE__ */ new Set(["nodes", edgesKey, "directed", "multigraph", "graph"]), "");
1779
- const nodeList = nodes ?? [];
1780
- const edgeList = edges ?? [];
1781
- ctx.sink.reserve(nodeList.length, edgeList.length);
1782
- let { nodeIdKey } = json2;
1783
- let positional = ctx.options.nodeIdFrom === "index";
1784
- if (!positional && nodeIdKey === null) {
1785
- const candidates = ctx.options.nodeIdFrom === "label" ? ["label", "name", "id"] : ["id", "name"];
1786
- nodeIdKey = candidates.find((key) => anyHas(nodeList, key)) ?? null;
1787
- if (ctx.options.nodeIdFrom === "label" && (nodeIdKey === "id" || nodeIdKey === "name")) {
1788
- report.warning(
1789
- "unsupported",
1790
- JSON_ISSUE.OPTION_IGNORED,
1791
- nodeIdKey === "id" ? 'nodeIdFrom "label": no node has a label or name key; ids are read from "id"' : 'nodeIdFrom "label": no node has a "label" key; ids are read from "name"',
1792
- { element: "nodeIdFrom" }
1793
- );
1794
- }
1795
- if (nodeIdKey === null) {
1796
- if (nodeList.length > 0) {
1797
- positional = true;
1798
- report.warning(
1799
- "missing-value",
1800
- JSON_ISSUE.POSITIONAL_NODES,
1801
- "no node has an id or name key; array positions are the node ids",
1802
- { element: "nodes" }
1803
- );
1804
- } else {
1805
- nodeIdKey = "id";
1806
- }
1807
- }
3215
+ return { nodeList: nodes ?? [], edgeList: edges ?? [] };
3216
+ }
3217
+ function nodeLinkIdKey(ctx, nodeList) {
3218
+ const { report, json: json2 } = ctx;
3219
+ if (ctx.options.nodeIdFrom === "index") {
3220
+ return null;
1808
3221
  }
1809
- if (positional) {
1810
- nodeIdKey = null;
3222
+ if (json2.nodeIdKey !== null) {
3223
+ return json2.nodeIdKey;
1811
3224
  }
1812
- let indexLinks;
1813
- if (positional) {
1814
- indexLinks = true;
1815
- } else if (json2.indexLinks === "auto") {
1816
- indexLinks = nodeIdKey !== null && looksIndexLinked(nodeList, edgeList, nodeIdKey, json2);
1817
- } else {
1818
- ({ indexLinks } = json2);
3225
+ const byLabel = ctx.options.nodeIdFrom === "label";
3226
+ const candidates = byLabel ? ["label", "name", "id"] : ["id", "name"];
3227
+ const found = candidates.find((key) => anyHas(nodeList, key)) ?? null;
3228
+ if (byLabel && (found === "id" || found === "name")) {
3229
+ report.warning(
3230
+ "unsupported",
3231
+ JSON_ISSUE.OPTION_IGNORED,
3232
+ found === "id" ? 'nodeIdFrom "label": no node has a label or name key; ids are read from "id"' : 'nodeIdFrom "label": no node has a "label" key; ids are read from "name"',
3233
+ { element: "nodeIdFrom" }
3234
+ );
1819
3235
  }
1820
- const positionIds = indexLinks ? [] : null;
1821
- if (indexLinks && !positional && json2.indexLinks === "auto" && nodeIdKey !== null) {
1822
- reportAmbiguousIndexLinks(ctx, nodeList, edgeList, nodeIdKey);
3236
+ if (found !== null || nodeList.length === 0) {
3237
+ return found ?? "id";
1823
3238
  }
3239
+ report.warning(
3240
+ "missing-value",
3241
+ JSON_ISSUE.POSITIONAL_NODES,
3242
+ "no node has an id or name key; array positions are the node ids",
3243
+ { element: "nodes" }
3244
+ );
3245
+ return null;
3246
+ }
3247
+ function importNodeLinkNodes(ctx, nodeList, nodeIdKey, indexLinks) {
3248
+ const positionIds = indexLinks ? [] : null;
1824
3249
  for (let i = 0; i < nodeList.length; i++) {
1825
3250
  const element = `nodes[${i}]`;
1826
3251
  const record = nodeList[i];
1827
3252
  let pushed = null;
1828
- if (!isJsonObject(record)) {
1829
- ctx.badElement("node", element);
3253
+ if (isJsonObject(record)) {
3254
+ pushed = pushNodeLinkNode(ctx, record, i, nodeIdKey);
1830
3255
  } else {
1831
- let id;
1832
- if (nodeIdKey === null) {
1833
- id = i;
1834
- } else {
1835
- id = ctx.coerceId(hasKey(record, nodeIdKey) ? record[nodeIdKey] : void 0, element);
1836
- }
1837
- if (id === null) {
1838
- ctx.countSkipped("node");
1839
- } else {
1840
- const index = ctx.pushNode(id, element);
1841
- if (index >= 0) {
1842
- pushed = id;
1843
- writeFlat(ctx.nodes, index, record, id, (key) => key !== nodeIdKey);
1844
- }
1845
- }
3256
+ ctx.badElement("node", element);
1846
3257
  }
1847
3258
  positionIds?.push(pushed);
1848
3259
  }
1849
- throwIfAborted(ctx.options.signal);
1850
- const endpointKeys = importNodeLinkEdges(ctx, edgeList, edgesKey, positionIds, multigraph);
1851
- ctx.setMeta(
1852
- {
1853
- dialect,
1854
- edgesKey,
1855
- nodeIdKey,
1856
- indexLinks,
1857
- sourceKey: endpointKeys.source ?? void 0,
1858
- targetKey: endpointKeys.target ?? void 0
1859
- },
1860
- { declaredMultigraph: multigraph, ...ctx.weightOriginPatch() }
1861
- );
3260
+ return positionIds;
3261
+ }
3262
+ function pushNodeLinkNode(ctx, record, i, nodeIdKey) {
3263
+ const element = `nodes[${i}]`;
3264
+ const raw = nodeIdKey !== null && hasKey(record, nodeIdKey) ? record[nodeIdKey] : void 0;
3265
+ const id = nodeIdKey === null ? i : ctx.coerceId(raw, element);
3266
+ if (id === null) {
3267
+ ctx.countSkipped("node");
3268
+ return null;
3269
+ }
3270
+ const index = ctx.pushNode(id, element);
3271
+ if (index < 0) {
3272
+ return null;
3273
+ }
3274
+ writeFlat(ctx.nodes, index, record, id, (key) => key !== nodeIdKey);
3275
+ return id;
1862
3276
  }
1863
3277
  function importNodeLinkEdges(ctx, edgeList, edgesKey, positionIds, multigraph) {
1864
3278
  const { json: json2 } = ctx;
@@ -2088,6 +3502,7 @@ function importVis(ctx, root) {
2088
3502
  { element: "arrows" }
2089
3503
  );
2090
3504
  }
3505
+ ctx.styleSource = { dialect: "vis", block: blockOf(root), options: root.options, groups: root.groups };
2091
3506
  ctx.setMeta(
2092
3507
  { dialect: "vis", nodeIdKey, sourceKey: sourceKey ?? void 0, targetKey: targetKey ?? void 0 },
2093
3508
  ctx.weightOriginPatch()
@@ -2353,28 +3768,19 @@ function importGraphology(ctx, root) {
2353
3768
  });
2354
3769
  }
2355
3770
  const type = graphologyType(ctx, options);
2356
- ctx.setHeader(graphologyDirected(ctx, type, edges));
3771
+ ctx.setHeader(type === "mixed" ? mostlyDirected(ctx, edges) : type === "directed");
2357
3772
  const multi = hasKey(options, "multi") ? flagOf(options.multi, "options.multi", false, report) : null;
2358
3773
  const allowSelfLoops = hasKey(options, "allowSelfLoops") ? flagOf(options.allowSelfLoops, "options.allowSelfLoops", true, report) : void 0;
2359
3774
  ctx.writeGraphDict(root.attributes, "attributes");
3775
+ const firstNode = nodes.find((n) => isJsonObject(n));
3776
+ const gephi = isJsonObject(firstNode) && !hasKey(firstNode, "key") && hasKey(firstNode, "id");
3777
+ ctx.styleSource = { dialect: "graphology", block: blockOf(root), gephi };
2360
3778
  ctx.reportNodeIdFrom("graphology", "the node key");
2361
3779
  ctx.sink.reserve(nodes.length, edges.length);
2362
- for (let i = 0; i < nodes.length; i++) {
2363
- pushGraphologyNode(ctx, nodes[i], `nodes[${i}]`);
2364
- }
3780
+ importGraphologyNodes(ctx, nodes, gephi);
2365
3781
  throwIfAborted(ctx.options.signal);
2366
- const reading = {
2367
- ids: ctx.declareEdgeIds(edges, (edge) => edge.key, "key", true),
2368
- type,
2369
- allowSelfLoops,
2370
- // what the edges do against the declared options: graphology itself refuses such a document
2371
- violations: { selfLoops: 0, parallels: 0, flags: 0 },
2372
- pairs: multi === false ? /* @__PURE__ */ new Set() : null
2373
- };
2374
- for (let i = 0; i < edges.length; i++) {
2375
- readGraphologyEdge(ctx, reading, edges[i], `edges[${i}]`);
2376
- }
2377
- reportGraphologyViolations(ctx, reading.violations, type);
3782
+ const violations = importGraphologyEdges(ctx, edges, { type, gephi, multi, allowSelfLoops });
3783
+ reportGraphologyViolations(ctx, violations, type);
2378
3784
  ctx.setMeta({ dialect: "graphology", allowSelfLoops }, { declaredMultigraph: multi, ...ctx.weightOriginPatch() });
2379
3785
  }
2380
3786
  function graphologyType(ctx, options) {
@@ -2391,81 +3797,101 @@ function graphologyType(ctx, options) {
2391
3797
  }
2392
3798
  return "mixed";
2393
3799
  }
2394
- function graphologyDirected(ctx, type, edges) {
2395
- if (type !== "mixed") {
2396
- return type === "directed";
2397
- }
3800
+ function mostlyDirected(ctx, edges) {
2398
3801
  const objects = edges.filter((edge) => isJsonObject(edge));
2399
3802
  const undirectedEdges = objects.filter((edge) => edge.undirected === true).length;
2400
3803
  return objects.length === 0 ? ctx.defaultDirected("graphology") : undirectedEdges < objects.length;
2401
3804
  }
2402
- function pushGraphologyNode(ctx, record, element) {
2403
- if (!isJsonObject(record)) {
2404
- ctx.badElement("node", element);
2405
- return;
3805
+ function importGraphologyNodes(ctx, nodes, gephi) {
3806
+ const nodeKey = gephi ? "id" : "key";
3807
+ for (let i = 0; i < nodes.length; i++) {
3808
+ const element = `nodes[${i}]`;
3809
+ const record = nodes[i];
3810
+ if (!isJsonObject(record)) {
3811
+ ctx.badElement("node", element);
3812
+ continue;
3813
+ }
3814
+ const id = ctx.coerceId(hasKey(record, nodeKey) ? record[nodeKey] : void 0, element);
3815
+ if (id === null) {
3816
+ ctx.countSkipped("node");
3817
+ continue;
3818
+ }
3819
+ pushNestedNode(ctx, id, record, "attributes", gephi ? GEPHI_NODE_KEYS : GRAPHOLOGY_NODE_KEYS, element, gephi);
2406
3820
  }
2407
- const id = ctx.coerceId(hasKey(record, "key") ? record.key : void 0, element);
2408
- if (id === null) {
2409
- ctx.countSkipped("node");
2410
- return;
3821
+ }
3822
+ function importGraphologyEdges(ctx, edges, declared) {
3823
+ const { gephi } = declared;
3824
+ const ids = ctx.declareEdgeIds(edges, (edge) => gephi && !hasKey(edge, "key") ? edge.id : edge.key, "key", true);
3825
+ const violations = { selfLoops: 0, parallels: 0, flags: 0 };
3826
+ const pairs = declared.multi === false ? /* @__PURE__ */ new Set() : null;
3827
+ for (let i = 0; i < edges.length; i++) {
3828
+ const element = `edges[${i}]`;
3829
+ const record = graphologyEdgeRecord(ctx, edges[i], element);
3830
+ if (record === null) {
3831
+ continue;
3832
+ }
3833
+ try {
3834
+ const pushed = pushGraphologyEdge(ctx, record, element, ids, declared, violations);
3835
+ if (pushed !== null && pairs !== null) {
3836
+ violations.parallels += pairs.has(pushed) ? 1 : 0;
3837
+ pairs.add(pushed);
3838
+ }
3839
+ } catch (err) {
3840
+ ctx.skip(err, "edge", element);
3841
+ }
2411
3842
  }
2412
- pushNestedNode(ctx, id, record, "attributes", GRAPHOLOGY_NODE_KEYS, element);
3843
+ return violations;
2413
3844
  }
2414
- function readGraphologyEdge(ctx, reading, record, element) {
3845
+ function graphologyEdgeRecord(ctx, record, element) {
2415
3846
  if (!isJsonObject(record)) {
2416
3847
  ctx.badElement("edge", element);
2417
- return;
3848
+ return null;
2418
3849
  }
2419
3850
  if (!present(record, "source") || !present(record, "target")) {
2420
3851
  ctx.missingEndpoint(element, present(record, "source") ? "target" : "source");
2421
- return;
2422
- }
2423
- try {
2424
- const u = ctx.coerceId(record.source, `${element}.source`);
2425
- const v = ctx.coerceId(record.target, `${element}.target`);
2426
- if (u === null || v === null) {
2427
- ctx.countSkipped("edge");
2428
- return;
2429
- }
2430
- const kind = graphologyEdgeKind(ctx, reading, record, element);
2431
- const attributes = graphologyEdgeAttributes(ctx, record, element);
2432
- const idValue = ctx.edgeIdValue(reading.ids, record.key);
2433
- const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(attributes), element);
2434
- ctx.setEdgeId(reading.ids, edge, idValue);
2435
- ctx.writeNested(ctx.edges, edge, record, attributes, GRAPHOLOGY_EDGE_KEYS, ctx.options.weightFrom, element);
2436
- if (reading.allowSelfLoops === false && u === v) {
2437
- reading.violations.selfLoops++;
2438
- }
2439
- if (reading.pairs !== null) {
2440
- const pair = `${kind} ${pairKey(u, v, kind === "directed")}`;
2441
- reading.violations.parallels += reading.pairs.has(pair) ? 1 : 0;
2442
- reading.pairs.add(pair);
2443
- }
2444
- } catch (err) {
2445
- ctx.skip(err, "edge", element);
3852
+ return null;
2446
3853
  }
3854
+ return record;
2447
3855
  }
2448
- function graphologyEdgeKind(ctx, reading, record, element) {
2449
- const { type } = reading;
2450
- if (type === "mixed") {
2451
- return flagOf(record.undirected, `${element}.undirected`, false, ctx.report) ? "undirected" : "directed";
3856
+ function pushGraphologyEdge(ctx, record, element, ids, declared, violations) {
3857
+ const { report } = ctx;
3858
+ const { type, gephi } = declared;
3859
+ const u = ctx.coerceId(record.source, `${element}.source`);
3860
+ const v = ctx.coerceId(record.target, `${element}.target`);
3861
+ if (u === null || v === null) {
3862
+ ctx.countSkipped("edge");
3863
+ return null;
2452
3864
  }
2453
- if (typeof record.undirected === "boolean" && record.undirected !== (type === "undirected")) {
2454
- reading.violations.flags++;
3865
+ let kind;
3866
+ if (type === "mixed") {
3867
+ kind = flagOf(record.undirected, `${element}.undirected`, false, report) ? "undirected" : "directed";
3868
+ } else {
3869
+ kind = type;
3870
+ if (typeof record.undirected === "boolean" && record.undirected !== (type === "undirected")) {
3871
+ violations.flags++;
3872
+ }
2455
3873
  }
2456
- return type;
2457
- }
2458
- function graphologyEdgeAttributes(ctx, record, element) {
2459
- const { attributes } = record;
2460
- if (attributes !== void 0 && attributes !== null && !isJsonObject(attributes)) {
2461
- ctx.report.error(
3874
+ const { attributes: rawAttributes } = record;
3875
+ if (rawAttributes !== void 0 && rawAttributes !== null && !isJsonObject(rawAttributes)) {
3876
+ report.error(
2462
3877
  "validation-error",
2463
3878
  JSON_ISSUE.BAD_VALUE,
2464
- `${element}: attributes must be an object, found ${describe(attributes)}`,
3879
+ `${element}: attributes must be an object, found ${describe(rawAttributes)}`,
2465
3880
  { element }
2466
3881
  );
2467
3882
  }
2468
- return isJsonObject(attributes) ? attributes : {};
3883
+ const attributes = isJsonObject(rawAttributes) ? rawAttributes : {};
3884
+ const idValue = ctx.edgeIdValue(ids, record.key);
3885
+ const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(attributes), element);
3886
+ ctx.setEdgeId(ids, edge, idValue);
3887
+ ctx.writeNested(ctx.edges, edge, record, attributes, gephi ? GEPHI_EDGE_KEYS : GRAPHOLOGY_EDGE_KEYS, element, {
3888
+ weightFrom: ctx.options.weightFrom,
3889
+ plain: gephi
3890
+ });
3891
+ if (declared.allowSelfLoops === false && u === v) {
3892
+ violations.selfLoops++;
3893
+ }
3894
+ return `${kind} ${pairKey(u, v, kind === "directed")}`;
2469
3895
  }
2470
3896
  function reportGraphologyViolations(ctx, violations, type) {
2471
3897
  const notes = [];
@@ -2490,7 +3916,7 @@ function reportGraphologyViolations(ctx, violations, type) {
2490
3916
  });
2491
3917
  }
2492
3918
  }
2493
- function pushNestedNode(ctx, id, record, dictKey, structural, element) {
3919
+ function pushNestedNode(ctx, id, record, dictKey, structural, element, plain = false) {
2494
3920
  const index = ctx.pushNode(id, element);
2495
3921
  if (index < 0) {
2496
3922
  return index;
@@ -2505,7 +3931,7 @@ function pushNestedNode(ctx, id, record, dictKey, structural, element) {
2505
3931
  { element }
2506
3932
  );
2507
3933
  }
2508
- ctx.writeNested(ctx.nodes, index, record, isJsonObject(dict) ? dict : {}, structural, null, element);
3934
+ ctx.writeNested(ctx.nodes, index, record, isJsonObject(dict) ? dict : {}, structural, element, { plain });
2509
3935
  } catch (err) {
2510
3936
  ctx.report.recordError(err, { element: String(id) });
2511
3937
  }
@@ -2523,7 +3949,7 @@ function importJgf(ctx, root) {
2523
3949
  `graph.nodes must be an object keyed by id or an array, found ${describe(nodesRaw)}`
2524
3950
  );
2525
3951
  }
2526
- const nodeRecords = Array.isArray(nodesRaw) ? nodesRaw : Object.values(nodesRaw ?? {});
3952
+ const nodeRecords2 = Array.isArray(nodesRaw) ? nodesRaw : Object.values(nodesRaw ?? {});
2527
3953
  const directed = jgfDirected(ctx, graph, edges);
2528
3954
  ctx.setHeader(directed);
2529
3955
  ctx.writeGraphDict(graph.metadata, "graph.metadata");
@@ -2534,18 +3960,18 @@ function importJgf(ctx, root) {
2534
3960
  };
2535
3961
  const label = typeof graph.label === "string" ? graph.label : null;
2536
3962
  ctx.reportNodeIdFrom("jgf", "the node keys");
2537
- ctx.sink.reserve(nodeRecords.length, edges.length);
3963
+ ctx.sink.reserve(nodeRecords2.length, edges.length);
2538
3964
  const labelColumn = ctx.nodes.declareIf(
2539
3965
  { name: "label", dtype: "string", role: "label", nullable: true },
2540
- anyHas(nodeRecords, "label")
3966
+ anyHas(nodeRecords2, "label")
2541
3967
  );
2542
3968
  if (isJsonObject(nodesRaw)) {
2543
- for (const key of Object.keys(nodesRaw)) {
3969
+ for (const key of jgfNodeKeys(ctx, root, graph, nodesRaw)) {
2544
3970
  pushJgfKeyedNode(ctx, key, nodesRaw[key], labelColumn);
2545
3971
  }
2546
3972
  } else {
2547
- for (let i = 0; i < nodeRecords.length; i++) {
2548
- pushJgfListedNode(ctx, nodeRecords[i], labelColumn, `nodes[${i}]`);
3973
+ for (let i = 0; i < nodeRecords2.length; i++) {
3974
+ pushJgfListedNode(ctx, nodeRecords2[i], labelColumn, `nodes[${i}]`);
2549
3975
  }
2550
3976
  }
2551
3977
  throwIfAborted(ctx.options.signal);
@@ -2630,7 +4056,7 @@ function jgfEdgeWriter(ctx, edges, hyperedges) {
2630
4056
  element
2631
4057
  });
2632
4058
  }
2633
- ctx.writeNested(ctx.edges, edge, record, dict, structural, ctx.options.weightFrom, element);
4059
+ ctx.writeNested(ctx.edges, edge, record, dict, structural, element, { weightFrom: ctx.options.weightFrom });
2634
4060
  };
2635
4061
  }
2636
4062
  function readJgfEdge(ctx, record, element, directed, writeJgfEdge) {
@@ -2655,6 +4081,14 @@ function readJgfEdge(ctx, record, element, directed, writeJgfEdge) {
2655
4081
  ctx.skip(err, "edge", element);
2656
4082
  }
2657
4083
  }
4084
+ function jgfNodeKeys(ctx, root, graph, nodes) {
4085
+ const keys = Object.keys(nodes);
4086
+ if (!keys.some((k) => ARRAY_INDEX.test(k))) {
4087
+ return keys;
4088
+ }
4089
+ const path = isJsonObject(root.graph) ? ["graph", "nodes"] : ["graphs", root.graphs.indexOf(graph), "nodes"];
4090
+ return keysInTextOrder(ctx.text, path) ?? keys;
4091
+ }
2658
4092
  function jgfGraphOf(ctx, root) {
2659
4093
  const single = isJsonObject(root.graph);
2660
4094
  reportUnreadKeys(ctx, root, /* @__PURE__ */ new Set([single ? "graph" : "graphs"]), "");
@@ -2761,7 +4195,7 @@ function pushJgfNode(ctx, id, record, labelColumn, element) {
2761
4195
  element
2762
4196
  });
2763
4197
  }
2764
- ctx.writeNested(ctx.nodes, index, record, isJsonObject(metadata) ? metadata : {}, JGF_NODE_KEYS, null, element);
4198
+ ctx.writeNested(ctx.nodes, index, record, isJsonObject(metadata) ? metadata : {}, JGF_NODE_KEYS, element);
2765
4199
  } catch (err) {
2766
4200
  ctx.report.recordError(err, { element: String(id) });
2767
4201
  }
@@ -2910,44 +4344,35 @@ function distinctMembers(ctx, members, element) {
2910
4344
  function importCytoscape(ctx, root) {
2911
4345
  const { elements, extra } = cytoscapeRoot(ctx, root);
2912
4346
  const { nodes, edges } = cytoscapeSections(ctx, elements);
4347
+ const generatedIds = cytoscapeGeneratedIds(nodes);
4348
+ ctx.styleSource = {
4349
+ dialect: "cytoscape",
4350
+ block: blockOf(root),
4351
+ elements: elements ?? [],
4352
+ style: isJsonObject(root) ? root.style : void 0,
4353
+ generatedBy: isJsonObject(root) && typeof root.generated_by === "string" ? root.generated_by : null,
4354
+ generatedIds
4355
+ };
2913
4356
  ctx.setHeader(ctx.defaultDirected("cytoscape"));
2914
4357
  ctx.reportNodeIdFrom("cytoscape", "data.id");
2915
4358
  ctx.sink.reserve(nodes.length, edges.length);
2916
- const dataHas = (items, key) => items.some((item) => isJsonObject(item) && isJsonObject(item.data) && item.data[key] !== void 0);
2917
- const reading = {
2918
- positionColumn: ctx.nodes.declareIf(
2919
- {
2920
- name: POSITION_COLUMN,
2921
- dtype: "f64",
2922
- components: 3,
2923
- role: "position",
2924
- mutable: true,
2925
- nullable: true,
2926
- // 3D layouts written by Cytoscape-compatible tools carry a z
2927
- extra: { sourceDims: nodes.some(hasPositionZ) ? 3 : 2, units: "file" },
2928
- origin: { format: "json", namespace: "cytoscape" }
2929
- },
2930
- anyHas(nodes, "position")
2931
- ),
2932
- classesColumn: ctx.nodes.declareIf(
2933
- { name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
2934
- anyHas(nodes, "classes")
2935
- ),
2936
- parents: [],
2937
- point: [0, 0, 0]
2938
- };
2939
- const parentColumn = ctx.nodes.declareIf(
2940
- { name: PARENT_COLUMN, dtype: "u32", role: "parent", refersTo: "node", nullable: true },
2941
- dataHas(nodes, "parent")
2942
- );
4359
+ const columns = cytoscapeNodeColumns(ctx, nodes);
2943
4360
  const edgeClassesColumn = ctx.edges.declareIf(
2944
4361
  { name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
2945
4362
  anyHas(edges, "classes")
2946
4363
  );
4364
+ const parents = [];
2947
4365
  for (let i = 0; i < nodes.length; i++) {
2948
- readCytoscapeNode(ctx, reading, nodes[i], `nodes[${i}]`);
4366
+ const element = `nodes[${i}]`;
4367
+ const record = nodes[i];
4368
+ if (isJsonObject(record) && isJsonObject(record.data)) {
4369
+ const raw = record.data.id === void 0 ? generatedIds.get(record) : record.data.id;
4370
+ importCytoscapeNode(ctx, record, record.data, raw, element, columns, parents);
4371
+ } else {
4372
+ ctx.badElement("node", element, "an element with a data object");
4373
+ }
2949
4374
  }
2950
- resolveCytoscapeParents(ctx, reading.parents, parentColumn);
4375
+ resolveCytoscapeParents(ctx, parents, columns.parent);
2951
4376
  throwIfAborted(ctx.options.signal);
2952
4377
  importCytoscapeEdges(ctx, edges, edgeClassesColumn);
2953
4378
  ctx.setMeta({ dialect: "cytoscape", cytoscape: extra }, ctx.weightOriginPatch());
@@ -2962,23 +4387,46 @@ function cytoscapeRoot(ctx, root) {
2962
4387
  `a Cytoscape document must be an object or an array, found ${describe(root)}`
2963
4388
  );
2964
4389
  }
2965
- ctx.writeGraphDict(root.data, "data");
4390
+ const object = root;
4391
+ ctx.writeGraphDict(object.data, "data");
2966
4392
  const rest = {};
2967
- for (const key of Object.keys(root)) {
2968
- if (key !== "elements" && key !== "data") {
2969
- rest[key] = root[key];
4393
+ for (const key of Object.keys(object)) {
4394
+ if (key !== "elements" && key !== "data" && key !== STYLE_BLOCK_NAME) {
4395
+ rest[key] = object[key];
2970
4396
  }
2971
4397
  }
2972
- return Object.keys(rest).length > 0 ? { elements: root.elements, extra: rest } : { elements: root.elements };
4398
+ return Object.keys(rest).length > 0 ? { elements: object.elements, extra: rest } : { elements: object.elements };
4399
+ }
4400
+ function cytoscapeNodeColumns(ctx, nodes) {
4401
+ const dataHas = (items, key) => items.some((item) => isJsonObject(item) && isJsonObject(item.data) && item.data[key] !== void 0);
4402
+ return {
4403
+ position: ctx.nodes.declareIf(
4404
+ {
4405
+ name: POSITION_COLUMN,
4406
+ dtype: "f64",
4407
+ components: 3,
4408
+ role: "position",
4409
+ mutable: true,
4410
+ nullable: true,
4411
+ // 3D layouts written by Cytoscape-compatible tools carry a z
4412
+ extra: { sourceDims: nodes.some(hasPositionZ) ? 3 : 2, units: "file" },
4413
+ origin: { format: "json", namespace: "cytoscape" }
4414
+ },
4415
+ anyHas(nodes, "position")
4416
+ ),
4417
+ classes: ctx.nodes.declareIf(
4418
+ { name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
4419
+ anyHas(nodes, "classes")
4420
+ ),
4421
+ parent: ctx.nodes.declareIf(
4422
+ { name: PARENT_COLUMN, dtype: "u32", role: "parent", refersTo: "node", nullable: true },
4423
+ dataHas(nodes, "parent")
4424
+ )
4425
+ };
2973
4426
  }
2974
- function readCytoscapeNode(ctx, reading, record, element) {
4427
+ function importCytoscapeNode(ctx, record, data, raw, element, columns, parents) {
2975
4428
  const { report } = ctx;
2976
- if (!isJsonObject(record) || !isJsonObject(record.data)) {
2977
- ctx.badElement("node", element, "an element with a data object");
2978
- return;
2979
- }
2980
- const { data } = record;
2981
- const id = ctx.coerceId(hasKey(data, "id") ? data.id : void 0, element);
4429
+ const id = ctx.coerceId(raw, element);
2982
4430
  if (id === null) {
2983
4431
  ctx.countSkipped("node");
2984
4432
  return;
@@ -2996,44 +4444,30 @@ function readCytoscapeNode(ctx, reading, record, element) {
2996
4444
  );
2997
4445
  }
2998
4446
  try {
2999
- writeCytoscapeData(ctx, reading, index, data, element);
3000
- writeCytoscapePosition$1(ctx, reading, index, record.position, element);
3001
- writeClasses(ctx, ctx.nodes, reading.classesColumn, index, record.classes, element);
4447
+ for (const key of Object.keys(data).filter((k) => k !== "id")) {
4448
+ if (key !== "parent") {
4449
+ ctx.nodes.write(index, key, data[key], SUFFIX.data, element);
4450
+ continue;
4451
+ }
4452
+ const parent = data.parent === null ? null : ctx.coerceId(data.parent, `${element}.data.parent`);
4453
+ if (parent !== null) {
4454
+ parents.push({ index, parent, element });
4455
+ }
4456
+ }
4457
+ writeCytoscapePosition$1(ctx, columns.position, index, record.position, element);
4458
+ writeClasses(ctx, ctx.nodes, columns.classes, index, record.classes, element);
3002
4459
  writeElementKeys(ctx.nodes, index, record, element);
3003
4460
  } catch (err) {
3004
4461
  report.recordError(err, { element: String(id) });
3005
4462
  }
3006
4463
  }
3007
- function writeCytoscapeData(ctx, reading, index, data, element) {
3008
- for (const key of Object.keys(data)) {
3009
- if (key === "id") {
3010
- continue;
3011
- }
3012
- if (key !== "parent") {
3013
- ctx.nodes.write(index, key, data[key], SUFFIX.data, element);
3014
- continue;
3015
- }
3016
- const raw = data.parent;
3017
- if (raw === void 0 || raw === null) {
3018
- continue;
3019
- }
3020
- const parent = ctx.coerceId(raw, `${element}.data.parent`);
3021
- if (parent !== null) {
3022
- reading.parents.push({ index, parent, element });
3023
- }
3024
- }
3025
- }
3026
- function writeCytoscapePosition$1(ctx, reading, index, position, element) {
4464
+ function writeCytoscapePosition$1(ctx, column, index, position, element) {
3027
4465
  if (position === void 0 || position === null) {
3028
4466
  return;
3029
4467
  }
3030
4468
  const z = isJsonObject(position) ? position.z ?? 0 : 0;
3031
4469
  if (isJsonObject(position) && isCoordinate(position.x) && isCoordinate(position.y) && isCoordinate(z)) {
3032
- const { point } = reading;
3033
- point[0] = position.x;
3034
- point[1] = flipY(position.y);
3035
- point[2] = z;
3036
- ctx.nodes.set(reading.positionColumn, index, point);
4470
+ ctx.nodes.set(column, index, [position.x, flipY(position.y), z]);
3037
4471
  } else {
3038
4472
  ctx.report.error(
3039
4473
  "validation-error",
@@ -3047,7 +4481,11 @@ function resolveCytoscapeParents(ctx, parents, parentColumn) {
3047
4481
  const { report } = ctx;
3048
4482
  const linkOf = /* @__PURE__ */ new Map();
3049
4483
  for (let order = 0; order < parents.length; order++) {
3050
- const { index, parent, element } = parents[order];
4484
+ const { index, element } = parents[order];
4485
+ let { parent } = parents[order];
4486
+ if (ctx.sink.indexOf(parent) === INVALID_INDEX) {
4487
+ parent = ctx.textualId(parent, element) ?? parent;
4488
+ }
3051
4489
  const parentIndex = ctx.sink.indexOf(parent);
3052
4490
  if (parentIndex === INVALID_INDEX) {
3053
4491
  report.error(
@@ -3122,8 +4560,8 @@ function importCytoscapeEdges(ctx, edges, edgeClassesColumn) {
3122
4560
  function importCytoscapeEdge(ctx, shared, record, data, element) {
3123
4561
  const { ids, kind, edgeClassesColumn } = shared;
3124
4562
  try {
3125
- const u = ctx.coerceId(data.source, `${element}.data.source`);
3126
- const v = ctx.coerceId(data.target, `${element}.data.target`);
4563
+ const u = ctx.textualId(data.source, `${element}.data.source`);
4564
+ const v = ctx.textualId(data.target, `${element}.data.target`);
3127
4565
  if (u === null || v === null) {
3128
4566
  ctx.countSkipped("edge");
3129
4567
  return;
@@ -3175,6 +4613,36 @@ function cytoscapeSections(ctx, elements) {
3175
4613
  }
3176
4614
  return report.fail(JSON_ISSUE.SHAPE, `elements must be an object or an array, found ${describe(elements)}`);
3177
4615
  }
4616
+ function cytoscapeGeneratedIds(nodes) {
4617
+ const out = /* @__PURE__ */ new Map();
4618
+ const missing = nodes.filter(
4619
+ (n) => isJsonObject(n) && isJsonObject(n.data) && n.data.id === void 0
4620
+ );
4621
+ if (missing.length === 0) {
4622
+ return out;
4623
+ }
4624
+ const taken = /* @__PURE__ */ new Set();
4625
+ for (const n of nodes) {
4626
+ const id = isJsonObject(n) && isJsonObject(n.data) ? n.data.id : void 0;
4627
+ if (typeof id === "string" || typeof id === "number") {
4628
+ taken.add(String(id));
4629
+ }
4630
+ }
4631
+ for (let k = 0; k < missing.length; k++) {
4632
+ let id = `n${String(k)}`;
4633
+ let j = 2;
4634
+ while (taken.has(id)) {
4635
+ id = `n${String(k)}_${String(j)}`;
4636
+ j++;
4637
+ }
4638
+ taken.add(id);
4639
+ out.set(missing[k], id);
4640
+ }
4641
+ return out;
4642
+ }
4643
+ function blockOf(root) {
4644
+ return isJsonObject(root) && typeof root[STYLE_BLOCK_NAME] === "string" ? root[STYLE_BLOCK_NAME] : null;
4645
+ }
3178
4646
  function hasPositionZ(element) {
3179
4647
  return isJsonObject(element) && isJsonObject(element.position) && typeof element.position.z === "number";
3180
4648
  }
@@ -3235,6 +4703,7 @@ const jsonImporter = Object.freeze({
3235
4703
  "typedefs"
3236
4704
  ]),
3237
4705
  extensions: Object.freeze([".json"]),
4706
+ positions: jsonPositions,
3238
4707
  mimeTypes: Object.freeze(["application/json"]),
3239
4708
  /**
3240
4709
  * Confidence that the head is a JSON graph document: 0 unless it starts with `{` or `[`, 0.5
@@ -3245,12 +4714,12 @@ const jsonImporter = Object.freeze({
3245
4714
  */
3246
4715
  sniff(head) {
3247
4716
  const text = new TextDecoder("utf-8").decode(headBytes(head).subarray(0, SNIFF_BYTES));
3248
- const trimmed = (text.startsWith(BOM) ? text.slice(1) : text).trimStart();
3249
- if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
4717
+ const trimmed2 = (text.startsWith(BOM) ? text.slice(1) : text).trimStart();
4718
+ if (!trimmed2.startsWith("{") && !trimmed2.startsWith("[")) {
3250
4719
  return 0;
3251
4720
  }
3252
- const score = SNIFF_KEYS.some((key) => trimmed.includes(key)) ? 0.9 : 0.5;
3253
- return trimmed.startsWith("[") && sniffJsonDialectHead(trimmed) !== "cytoscape" ? Math.min(score, 0.3) : score;
4721
+ const score = SNIFF_KEYS.some((key) => trimmed2.includes(key)) ? 0.9 : 0.5;
4722
+ return trimmed2.startsWith("[") && sniffJsonDialectHead(trimmed2) !== "cytoscape" ? Math.min(score, 0.3) : score;
3254
4723
  },
3255
4724
  /**
3256
4725
  * Read a JSON graph document into the sink.
@@ -3265,7 +4734,7 @@ const jsonImporter = Object.freeze({
3265
4734
  const report = new ImportReportBuilder("json", resolved.errorLimit);
3266
4735
  const text = await readText(input, report, { ...resolved, bomlessUtf16: true });
3267
4736
  const { root, dialect } = documentOf(parseDocument(text, report), json2, report);
3268
- readGraph(root, dialect, sink, report, resolved, json2, options);
4737
+ readGraph({ root, dialect, text }, sink, report, resolved, json2, options);
3269
4738
  return report.finish();
3270
4739
  },
3271
4740
  /**
@@ -3302,17 +4771,35 @@ const jsonImporter = Object.freeze({
3302
4771
  const reports = [];
3303
4772
  for (let i = 0; i < Math.max(graphs, 1); i++) {
3304
4773
  const report = i === 0 ? first : new ImportReportBuilder("json", resolved.errorLimit);
3305
- readGraph(root, dialect, sinkFor(i), report, resolved, { ...json2, graphIndex: i, all: true }, options);
4774
+ readGraph(
4775
+ { root, dialect, text },
4776
+ sinkFor(i),
4777
+ report,
4778
+ resolved,
4779
+ { ...json2, graphIndex: i, all: true },
4780
+ options
4781
+ );
3306
4782
  reports.push(report.finish());
3307
4783
  }
3308
4784
  return reports;
3309
- }
4785
+ },
4786
+ /**
4787
+ * The document's styles, read by its dialect's reader (Cytoscape.js stylesheets, graphology and vis.js keys,
4788
+ * NetworkX's defaults); a `graphty.styles` block gives back the rules graphty wrote.
4789
+ * @param snapshot - the graph the import built
4790
+ * @param context - the work budget and what the import kept
4791
+ * @returns the styles, or null when the dialect has none
4792
+ */
4793
+ styles: jsonStyles
3310
4794
  });
3311
- function readGraph(root, dialect, sink, report, resolved, json2, options) {
4795
+ function readGraph(doc, sink, report, resolved, json2, options) {
4796
+ const { root, dialect, text } = doc;
3312
4797
  const ctx = new ImportContext(sink, report, resolved, json2, options?.defaultDirected !== void 0);
4798
+ ctx.text = text;
3313
4799
  reportSinkOptions(sink, options, report, dialect === "obographs");
3314
4800
  reportUnusedOptions(options, report, USED_OPTIONS);
3315
4801
  readDialect(ctx, root, dialect);
4802
+ report.keepForStyles(ctx.styleSource ?? { dialect, block: blockOf(root) });
3316
4803
  ctx.reportDangling();
3317
4804
  ctx.nodes.reportNullOnly();
3318
4805
  ctx.edges.reportNullOnly();
@@ -4043,7 +5530,7 @@ function graphPropertyValues(snapshot) {
4043
5530
  const values = [];
4044
5531
  for (const column of snapshot.graph) {
4045
5532
  const dtype = column.dtype === "list" ? column.child.dtype : column.dtype;
4046
- for (const item of valuesOf(cellOf(column, 0))) {
5533
+ for (const item of valuesOf$1(cellOf(column, 0))) {
4047
5534
  values.push({ pred: column.meta.name, val: typeof item === "string" ? item : textOf(item, dtype) });
4048
5535
  }
4049
5536
  }
@@ -4222,10 +5709,10 @@ ${settings.indent}` : "";
4222
5709
  planIds() {
4223
5710
  const { snapshot } = this;
4224
5711
  const typeColumn = snapshot.nodes.get("type");
4225
- let numeric = 0;
5712
+ let numeric2 = 0;
4226
5713
  for (let i = 0; i < snapshot.nodeCount; i++) {
4227
5714
  const id = snapshot.ids.idOf(i);
4228
- numeric += typeof id === "number" ? 1 : 0;
5715
+ numeric2 += typeof id === "number" ? 1 : 0;
4229
5716
  const text = String(id);
4230
5717
  let { iri, exact } = this.iriOf(text);
4231
5718
  const typedef = typeColumn !== null && typeColumn.isSet(i) && typeColumn.value(i) === "Typedef";
@@ -4241,12 +5728,12 @@ ${settings.indent}` : "";
4241
5728
  this.changedRows.add(i);
4242
5729
  }
4243
5730
  }
4244
- if (numeric > 0) {
5731
+ if (numeric2 > 0) {
4245
5732
  this.note(
4246
5733
  LOSS.ID_TEXT_TYPE,
4247
- `${numeric} numeric node id${plural(numeric)} ${agree(numeric, "is", "are")} written as text and read back as strings`,
5734
+ `${numeric2} numeric node id${plural(numeric2)} ${agree(numeric2, "is", "are")} written as text and read back as strings`,
4248
5735
  null,
4249
- numeric
5736
+ numeric2
4250
5737
  );
4251
5738
  }
4252
5739
  }
@@ -4594,7 +6081,7 @@ ${settings.indent}` : "";
4594
6081
  for (const tag of PROPERTY_TAGS) {
4595
6082
  const v = this.at(tag, i);
4596
6083
  const pred = TAG_PREDICATES.get(tag) ?? tag;
4597
- for (const item of valuesOf(v)) {
6084
+ for (const item of valuesOf$1(v)) {
4598
6085
  const text = String(item);
4599
6086
  values.push({ pred, val: tag === "replaced_by" || tag === "consider" ? this.iriOf(text).iri : text });
4600
6087
  }
@@ -4873,7 +6360,12 @@ const JSON_LOSS = Object.freeze({
4873
6360
  * OBO Graphs: an OBO attribute stored as text where graph-io uses a dictionary (or the other way round); it reads
4874
6361
  * back with graph-io's usual type. The values are the same.
4875
6362
  */
4876
- DTYPE_UNSUPPORTED: LOSS.DTYPE
6363
+ DTYPE_UNSUPPORTED: LOSS.DTYPE,
6364
+ /**
6365
+ * Saving with styles: a column named like one of the dialect's style keys (graphology's `color`, `size`, `label`,
6366
+ * vis.js's `color`, `shape`, `font`, ...) is written with what graphty draws, so the values it held differ.
6367
+ */
6368
+ STYLE_KEY_REPLACED: STYLE_KEY_REPLACED_CODE
4877
6369
  });
4878
6370
  const SLOT_ROLES = Object.freeze({
4879
6371
  "node-link": /* @__PURE__ */ new Set(),
@@ -5132,7 +6624,9 @@ function plan(snapshot, resolved) {
5132
6624
  const caps = dialectCapabilities(dialect);
5133
6625
  const notes = checkCapabilities(snapshot, caps, resolved.common, {
5134
6626
  roles: SLOT_ROLES[dialect],
5135
- positionDtype: "f64"
6627
+ positionDtype: "f64",
6628
+ // Deprecated (next major): role columns are written as plain attributes; styles go through the style writer.
6629
+ vizAsAttributes: true
5136
6630
  }).filter((n) => n.code !== LOSS.POSITIONS && n.code !== LOSS.EDGE_IDS_DROPPED);
5137
6631
  const note = (code, message, column = null, count = null) => {
5138
6632
  notes.push(Object.freeze({ code, message, column, count }));
@@ -5202,7 +6696,7 @@ function reservedKeys(snapshot, resolved) {
5202
6696
  break;
5203
6697
  case "vis":
5204
6698
  node.add(resolved.nodeIdKey ?? "id");
5205
- edge.add(resolved.sourceKey).add(resolved.targetKey);
6699
+ edge.add(resolved.sourceKey).add(resolved.targetKey).add("source").add("target");
5206
6700
  break;
5207
6701
  case "cytoscape":
5208
6702
  node.add("id").add("parent");
@@ -5443,7 +6937,7 @@ function countNonZeroZ(column) {
5443
6937
  function jgfIdNotes(snapshot, note) {
5444
6938
  const { ids } = snapshot;
5445
6939
  const seen = /* @__PURE__ */ new Set();
5446
- let numeric = 0;
6940
+ let numeric2 = 0;
5447
6941
  let collisions = 0;
5448
6942
  let indexLike = 0;
5449
6943
  let lastIndex = -1;
@@ -5453,7 +6947,7 @@ function jgfIdNotes(snapshot, note) {
5453
6947
  const id = ids.idOf(i);
5454
6948
  const text = String(id);
5455
6949
  if (typeof id === "number") {
5456
- numeric++;
6950
+ numeric2++;
5457
6951
  }
5458
6952
  if (seen.has(text)) {
5459
6953
  collisions++;
@@ -5470,12 +6964,12 @@ function jgfIdNotes(snapshot, note) {
5470
6964
  sawOther = true;
5471
6965
  }
5472
6966
  }
5473
- if (numeric > 0) {
6967
+ if (numeric2 > 0) {
5474
6968
  note(
5475
6969
  JSON_LOSS.NUMERIC_IDS_STRINGIFIED,
5476
- `${numeric} numeric node id${plural(numeric)} ${agree(numeric, "becomes", "become")} JGF object keys (strings); pass ids: "canonical" on re-import`,
6970
+ `${numeric2} numeric node id${plural(numeric2)} ${agree(numeric2, "becomes", "become")} JGF object keys (strings); pass ids: "canonical" on re-import`,
5477
6971
  null,
5478
- numeric
6972
+ numeric2
5479
6973
  );
5480
6974
  }
5481
6975
  if (collisions > 0) {
@@ -5664,9 +7158,20 @@ function* writeNodeLink(snapshot, p) {
5664
7158
  yield w.take();
5665
7159
  }
5666
7160
  w.close("]");
7161
+ writeTopLevelBlock(c, p);
5667
7162
  w.close("}");
5668
7163
  yield w.take();
5669
7164
  }
7165
+ function writeTopLevelBlock(c, p) {
7166
+ const groups = p.resolved.styled?.groups ?? null;
7167
+ if (groups !== null) {
7168
+ c.w.member("groups", JSON.stringify(groups));
7169
+ }
7170
+ const block = p.resolved.styled?.topLevelBlock ?? null;
7171
+ if (block !== null) {
7172
+ c.w.member(STYLE_BLOCK_NAME, JSON.stringify(block));
7173
+ }
7174
+ }
5670
7175
  function* writeVis(snapshot, p) {
5671
7176
  const { resolved } = p;
5672
7177
  const c = { w: new JsonWriter(resolved.indent), ids: snapshot.ids, nonfinite: { count: 0 } };
@@ -5709,6 +7214,7 @@ function* writeVis(snapshot, p) {
5709
7214
  yield w.take();
5710
7215
  }
5711
7216
  w.close("]");
7217
+ writeTopLevelBlock(c, p);
5712
7218
  w.close("}");
5713
7219
  yield w.take();
5714
7220
  }
@@ -5891,7 +7397,7 @@ function* writeCytoscape(snapshot, p) {
5891
7397
  writeSlots(c, p.nodes, i, parentSlots);
5892
7398
  writeSlots(c, p.nodes, i, ATTRIBUTE_SLOTS);
5893
7399
  w.close("}");
5894
- writeCytoscapePosition(c, p.nodes, i);
7400
+ writeCytoscapePosition(c, p, i);
5895
7401
  writeSlots(c, p.nodes, i, ELEMENT_SLOTS);
5896
7402
  w.close("}");
5897
7403
  yield w.take();
@@ -5928,13 +7434,14 @@ function* writeCytoscape(snapshot, p) {
5928
7434
  w.key("data");
5929
7435
  writeGraphObject(c, p);
5930
7436
  }
5931
- writeCytoscapeExtra(c, resolved.shape.cytoscape);
7437
+ writeCytoscapeTopLevel(c, p);
7438
+ writeTopLevelBlock(c, p);
5932
7439
  w.close("}");
5933
7440
  yield w.take();
5934
7441
  }
5935
- function writeCytoscapePosition(c, items, i) {
7442
+ function writeCytoscapePosition(c, p, i) {
5936
7443
  const { w } = c;
5937
- for (const item of items) {
7444
+ for (const item of p.nodes) {
5938
7445
  if (item.slot === "cytoscapePosition" && item.column.isSet(i)) {
5939
7446
  const value = item.column.value(i);
5940
7447
  const f32 = item.column.dtype === "f32";
@@ -5946,15 +7453,18 @@ function writeCytoscapePosition(c, items, i) {
5946
7453
  }
5947
7454
  }
5948
7455
  }
5949
- function writeCytoscapeExtra(c, extra) {
5950
- if (extra === void 0) {
5951
- return;
5952
- }
7456
+ function writeCytoscapeTopLevel(c, p) {
7457
+ const { w } = c;
7458
+ const extra = p.resolved.shape.cytoscape ?? {};
7459
+ const stylesheet = p.resolved.styled?.stylesheet ?? null;
5953
7460
  for (const key of Object.keys(extra)) {
5954
- if (key !== "elements" && key !== "data") {
5955
- c.w.member(key, valueText(extra[key], false, c.nonfinite));
7461
+ if (key !== "elements" && key !== "data" && !(key === "style" && stylesheet !== null)) {
7462
+ w.member(key, valueText(extra[key], false, c.nonfinite));
5956
7463
  }
5957
7464
  }
7465
+ if (stylesheet !== null) {
7466
+ w.member("style", valueText(stylesheet, false, c.nonfinite));
7467
+ }
5958
7468
  }
5959
7469
  function edgeIdGenerator(snapshot, p) {
5960
7470
  const used = /* @__PURE__ */ new Set();
@@ -5979,7 +7489,13 @@ function edgeIdGenerator(snapshot, p) {
5979
7489
  };
5980
7490
  }
5981
7491
  function parts(snapshot, resolved) {
5982
- return resolved.dialect === "obographs" ? planObographs(snapshot, resolved).write() : write(snapshot, plan(snapshot, resolved));
7492
+ const s = resolved.styled?.snapshot ?? snapshot;
7493
+ return resolved.dialect === "obographs" ? planObographs(s, resolved).write() : write(s, plan(s, resolved));
7494
+ }
7495
+ function resolveStyled(snapshot, options) {
7496
+ const resolved = resolve(snapshot, options);
7497
+ const styled = jsonStyledExport(snapshot, resolved.dialect, options?.styles);
7498
+ return styled === null ? resolved : { ...resolved, styled };
5983
7499
  }
5984
7500
  const jsonExporter = Object.freeze({
5985
7501
  format: "json",
@@ -5995,6 +7511,7 @@ const jsonExporter = Object.freeze({
5995
7511
  "weightKey"
5996
7512
  ]),
5997
7513
  capabilities: dialectCapabilities("node-link"),
7514
+ styles: Object.freeze({ capabilities: JSON_STYLE_CAPABILITIES }),
5998
7515
  /**
5999
7516
  * Pre-flight: every loss of the selected dialect, without writing anything.
6000
7517
  * @param snapshot - the snapshot
@@ -6002,9 +7519,10 @@ const jsonExporter = Object.freeze({
6002
7519
  * @returns the notes, empty when the export is exact
6003
7520
  */
6004
7521
  check(snapshot, options) {
6005
- const resolved = resolve(snapshot, options);
6006
- const notes = resolved.dialect === "obographs" ? planObographs(snapshot, resolved).notes : plan(snapshot, resolved).notes;
6007
- return Object.freeze([...notes]);
7522
+ const resolved = resolveStyled(snapshot, options);
7523
+ const s = resolved.styled?.snapshot ?? snapshot;
7524
+ const notes = resolved.dialect === "obographs" ? planObographs(s, resolved).notes : plan(s, resolved).notes;
7525
+ return Object.freeze([...notes, ...resolved.styled?.notes ?? []]);
6008
7526
  },
6009
7527
  /**
6010
7528
  * Write the document as UTF-8 chunks.
@@ -6013,7 +7531,7 @@ const jsonExporter = Object.freeze({
6013
7531
  * @returns the chunks
6014
7532
  */
6015
7533
  export(snapshot, options) {
6016
- return encodeChunks(parts(snapshot, resolve(snapshot, options)));
7534
+ return encodeChunks(parts(snapshot, resolveStyled(snapshot, options)));
6017
7535
  },
6018
7536
  /**
6019
7537
  * Write the document as one string.
@@ -6022,7 +7540,7 @@ const jsonExporter = Object.freeze({
6022
7540
  * @returns the document
6023
7541
  */
6024
7542
  exportToString(snapshot, options) {
6025
- return joinText(parts(snapshot, resolve(snapshot, options)));
7543
+ return joinText(parts(snapshot, resolveStyled(snapshot, options)));
6026
7544
  }
6027
7545
  });
6028
7546
  function jsonCapabilities(dialect) {
@@ -6046,4 +7564,4 @@ export {
6046
7564
  rankFormats as r,
6047
7565
  sniffFormat as s
6048
7566
  };
6049
- //# sourceMappingURL=exporter-RVtXVetw.js.map
7567
+ //# sourceMappingURL=exporter-quPUCBiC.js.map