@graphty/graph-io 0.3.43 → 0.3.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (674) hide show
  1. package/dist/chunks/approximations-DJMHdDvv.js +40 -0
  2. package/dist/chunks/approximations-DJMHdDvv.js.map +1 -0
  3. package/dist/chunks/block-CPCHkX42.js +2777 -0
  4. package/dist/chunks/block-CPCHkX42.js.map +1 -0
  5. package/dist/chunks/{choose-DvpbdRuz.js → choose--jM0yYCo.js} +3 -2
  6. package/dist/chunks/{choose-DvpbdRuz.js.map → choose--jM0yYCo.js.map} +1 -1
  7. package/dist/chunks/{constants-fT3E8JYY.js → constants-BKwqelYD.js} +6 -2
  8. package/dist/chunks/constants-BKwqelYD.js.map +1 -0
  9. package/dist/chunks/convert-BcQ8_jMo.js +59 -0
  10. package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
  11. package/dist/chunks/emit-DZy6JgdA.js +3456 -0
  12. package/dist/chunks/emit-DZy6JgdA.js.map +1 -0
  13. package/dist/chunks/{escape-B62ZGM_a.js → escape-CgzxiYPg.js} +44 -21
  14. package/dist/chunks/escape-CgzxiYPg.js.map +1 -0
  15. package/dist/chunks/{export-rKLeGQMo.js → export-BvqAXCKh.js} +196 -792
  16. package/dist/chunks/export-BvqAXCKh.js.map +1 -0
  17. package/dist/chunks/{exporter-yLxKBvLE.js → exporter--Mk9gXCJ.js} +4 -3
  18. package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter--Mk9gXCJ.js.map} +1 -1
  19. package/dist/chunks/{exporter-RVtXVetw.js → exporter-C-9cgZKa.js} +1805 -287
  20. package/dist/chunks/exporter-C-9cgZKa.js.map +1 -0
  21. package/dist/chunks/{exporter-8hLNemFk.js → exporter-DFqJhBnj.js} +133 -74
  22. package/dist/chunks/exporter-DFqJhBnj.js.map +1 -0
  23. package/dist/chunks/{exporter-BWwEuOPT.js → exporter-DteVeJki.js} +22 -12
  24. package/dist/chunks/exporter-DteVeJki.js.map +1 -0
  25. package/dist/chunks/format-BpQBx8MZ.js +676 -0
  26. package/dist/chunks/format-BpQBx8MZ.js.map +1 -0
  27. package/dist/chunks/generic-BGO71QBv.js +1347 -0
  28. package/dist/chunks/generic-BGO71QBv.js.map +1 -0
  29. package/dist/chunks/{importer-C98dpSH4.js → importer-B-9Rc1zO.js} +141 -82
  30. package/dist/chunks/importer-B-9Rc1zO.js.map +1 -0
  31. package/dist/chunks/{importer-D794XUTe.js → importer-BVVR740x.js} +31 -8
  32. package/dist/chunks/importer-BVVR740x.js.map +1 -0
  33. package/dist/chunks/{importer-WrGRZb0N.js → importer-C0AjA3Ax.js} +449 -102
  34. package/dist/chunks/importer-C0AjA3Ax.js.map +1 -0
  35. package/dist/chunks/{importer-BbNb7eNg.js → importer-C7pvJe1L.js} +1398 -129
  36. package/dist/chunks/importer-C7pvJe1L.js.map +1 -0
  37. package/dist/chunks/{importer-xZ-3suY1.js → importer-ClwoVx3O.js} +791 -135
  38. package/dist/chunks/importer-ClwoVx3O.js.map +1 -0
  39. package/dist/chunks/{importer-Ht7LNg8L.js → importer-D0sC_6bO.js} +116 -296
  40. package/dist/chunks/importer-D0sC_6bO.js.map +1 -0
  41. package/dist/chunks/{importer-Dz7tI8Sa.js → importer-EHQk1jbM.js} +617 -115
  42. package/dist/chunks/importer-EHQk1jbM.js.map +1 -0
  43. package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-DJZRZ6jd.js} +123 -32
  44. package/dist/chunks/json-elements-DJZRZ6jd.js.map +1 -0
  45. package/dist/chunks/lexicon-WMsNddyU.js +509 -0
  46. package/dist/chunks/lexicon-WMsNddyU.js.map +1 -0
  47. package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-G4MqRdux.js} +3 -2
  48. package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-G4MqRdux.js.map} +1 -1
  49. package/dist/chunks/{records-Cu4bxYOm.js → records-CiaWZrFH.js} +2 -2
  50. package/dist/chunks/{records-Cu4bxYOm.js.map → records-CiaWZrFH.js.map} +1 -1
  51. package/dist/chunks/styles-DvoFBKCK.js +690 -0
  52. package/dist/chunks/styles-DvoFBKCK.js.map +1 -0
  53. package/dist/chunks/styles-yed-Cz9rLBCP.js +842 -0
  54. package/dist/chunks/styles-yed-Cz9rLBCP.js.map +1 -0
  55. package/dist/chunks/styles-zNTmz5R7.js +2102 -0
  56. package/dist/chunks/styles-zNTmz5R7.js.map +1 -0
  57. package/dist/chunks/{text-DHOJXnED.js → text-CzJNFOS9.js} +2 -2
  58. package/dist/chunks/{text-DHOJXnED.js.map → text-CzJNFOS9.js.map} +1 -1
  59. package/dist/chunks/units-XMZFIFe1.js +19 -0
  60. package/dist/chunks/units-XMZFIFe1.js.map +1 -0
  61. package/dist/chunks/writer-gQ8kx99H.js +448 -0
  62. package/dist/chunks/writer-gQ8kx99H.js.map +1 -0
  63. package/dist/csv.js +5 -4
  64. package/dist/csv.js.map +1 -1
  65. package/dist/cx.js +1 -1
  66. package/dist/cx2.js +2 -2
  67. package/dist/cys.js +1 -1
  68. package/dist/dot.js +5 -2
  69. package/dist/dot.js.map +1 -1
  70. package/dist/gexf.js +292 -412
  71. package/dist/gexf.js.map +1 -1
  72. package/dist/gml.js +927 -74
  73. package/dist/gml.js.map +1 -1
  74. package/dist/graph-io.js +351 -236
  75. package/dist/graph-io.js.map +1 -1
  76. package/dist/graphml.js +4 -2
  77. package/dist/graphml.js.map +1 -1
  78. package/dist/json.js +1 -1
  79. package/dist/neo4j.js +4 -3
  80. package/dist/neo4j.js.map +1 -1
  81. package/dist/obo.js +1 -1
  82. package/dist/pajek.js +4 -2
  83. package/dist/positions.d.ts +1 -0
  84. package/dist/positions.js +427 -0
  85. package/dist/positions.js.map +1 -0
  86. package/dist/src/common/codes.d.ts +6 -0
  87. package/dist/src/common/codes.d.ts.map +1 -1
  88. package/dist/src/common/codes.js +6 -0
  89. package/dist/src/common/codes.js.map +1 -1
  90. package/dist/src/common/escape.d.ts.map +1 -1
  91. package/dist/src/common/escape.js +4 -2
  92. package/dist/src/common/escape.js.map +1 -1
  93. package/dist/src/common/export.d.ts +10 -0
  94. package/dist/src/common/export.d.ts.map +1 -1
  95. package/dist/src/common/export.js +123 -100
  96. package/dist/src/common/export.js.map +1 -1
  97. package/dist/src/common/input.d.ts.map +1 -1
  98. package/dist/src/common/input.js +8 -1
  99. package/dist/src/common/input.js.map +1 -1
  100. package/dist/src/common/json-elements.d.ts +12 -9
  101. package/dist/src/common/json-elements.d.ts.map +1 -1
  102. package/dist/src/common/json-elements.js +160 -37
  103. package/dist/src/common/json-elements.js.map +1 -1
  104. package/dist/src/common/notes.d.ts +42 -0
  105. package/dist/src/common/notes.d.ts.map +1 -0
  106. package/dist/src/common/notes.js +72 -0
  107. package/dist/src/common/notes.js.map +1 -0
  108. package/dist/src/common/report.d.ts +18 -0
  109. package/dist/src/common/report.d.ts.map +1 -1
  110. package/dist/src/common/report.js +36 -1
  111. package/dist/src/common/report.js.map +1 -1
  112. package/dist/src/common/units.d.ts +24 -0
  113. package/dist/src/common/units.d.ts.map +1 -0
  114. package/dist/src/common/units.js +26 -0
  115. package/dist/src/common/units.js.map +1 -0
  116. package/dist/src/common/xml.d.ts +18 -0
  117. package/dist/src/common/xml.d.ts.map +1 -1
  118. package/dist/src/common/xml.js +42 -5
  119. package/dist/src/common/xml.js.map +1 -1
  120. package/dist/src/formats/cx/exporter.d.ts +6 -0
  121. package/dist/src/formats/cx/exporter.d.ts.map +1 -1
  122. package/dist/src/formats/cx/exporter.js +71 -8
  123. package/dist/src/formats/cx/exporter.js.map +1 -1
  124. package/dist/src/formats/cx/importer.d.ts +5 -2
  125. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cx/importer.js +102 -72
  127. package/dist/src/formats/cx/importer.js.map +1 -1
  128. package/dist/src/formats/cx/styles.d.ts +102 -0
  129. package/dist/src/formats/cx/styles.d.ts.map +1 -0
  130. package/dist/src/formats/cx/styles.js +225 -0
  131. package/dist/src/formats/cx/styles.js.map +1 -0
  132. package/dist/src/formats/cx2/exporter.d.ts +5 -0
  133. package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
  134. package/dist/src/formats/cx2/exporter.js +181 -71
  135. package/dist/src/formats/cx2/exporter.js.map +1 -1
  136. package/dist/src/formats/cx2/importer.d.ts +4 -1
  137. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  138. package/dist/src/formats/cx2/importer.js +19 -1
  139. package/dist/src/formats/cx2/importer.js.map +1 -1
  140. package/dist/src/formats/cx2/styles.d.ts +18 -0
  141. package/dist/src/formats/cx2/styles.d.ts.map +1 -0
  142. package/dist/src/formats/cx2/styles.js +24 -0
  143. package/dist/src/formats/cx2/styles.js.map +1 -0
  144. package/dist/src/formats/cys/constants.d.ts +2 -0
  145. package/dist/src/formats/cys/constants.d.ts.map +1 -1
  146. package/dist/src/formats/cys/constants.js +2 -0
  147. package/dist/src/formats/cys/constants.js.map +1 -1
  148. package/dist/src/formats/cys/exporter.d.ts +6 -2
  149. package/dist/src/formats/cys/exporter.d.ts.map +1 -1
  150. package/dist/src/formats/cys/exporter.js +215 -53
  151. package/dist/src/formats/cys/exporter.js.map +1 -1
  152. package/dist/src/formats/cys/importer.d.ts +2 -1
  153. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  154. package/dist/src/formats/cys/importer.js +119 -6
  155. package/dist/src/formats/cys/importer.js.map +1 -1
  156. package/dist/src/formats/cys/session.d.ts +2 -0
  157. package/dist/src/formats/cys/session.d.ts.map +1 -1
  158. package/dist/src/formats/cys/session.js +5 -0
  159. package/dist/src/formats/cys/session.js.map +1 -1
  160. package/dist/src/formats/cys/styles.d.ts +38 -0
  161. package/dist/src/formats/cys/styles.d.ts.map +1 -0
  162. package/dist/src/formats/cys/styles.js +213 -0
  163. package/dist/src/formats/cys/styles.js.map +1 -0
  164. package/dist/src/formats/cys/tables.d.ts +8 -3
  165. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  166. package/dist/src/formats/cys/tables.js +88 -34
  167. package/dist/src/formats/cys/tables.js.map +1 -1
  168. package/dist/src/formats/dot/exporter.d.ts +2 -0
  169. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  170. package/dist/src/formats/dot/exporter.js +195 -81
  171. package/dist/src/formats/dot/exporter.js.map +1 -1
  172. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  173. package/dist/src/formats/dot/importer.js +100 -20
  174. package/dist/src/formats/dot/importer.js.map +1 -1
  175. package/dist/src/formats/dot/index.d.ts +1 -0
  176. package/dist/src/formats/dot/index.d.ts.map +1 -1
  177. package/dist/src/formats/dot/index.js +1 -0
  178. package/dist/src/formats/dot/index.js.map +1 -1
  179. package/dist/src/formats/dot/positions.d.ts +14 -0
  180. package/dist/src/formats/dot/positions.d.ts.map +1 -0
  181. package/dist/src/formats/dot/positions.js +70 -0
  182. package/dist/src/formats/dot/positions.js.map +1 -0
  183. package/dist/src/formats/dot/styles.d.ts +82 -0
  184. package/dist/src/formats/dot/styles.d.ts.map +1 -0
  185. package/dist/src/formats/dot/styles.js +1496 -0
  186. package/dist/src/formats/dot/styles.js.map +1 -0
  187. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  188. package/dist/src/formats/gexf/exporter.js +20 -5
  189. package/dist/src/formats/gexf/exporter.js.map +1 -1
  190. package/dist/src/formats/gexf/importer.d.ts +8 -1
  191. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  192. package/dist/src/formats/gexf/importer.js +251 -131
  193. package/dist/src/formats/gexf/importer.js.map +1 -1
  194. package/dist/src/formats/gexf/index.d.ts +8 -0
  195. package/dist/src/formats/gexf/index.d.ts.map +1 -1
  196. package/dist/src/formats/gexf/index.js +10 -2
  197. package/dist/src/formats/gexf/index.js.map +1 -1
  198. package/dist/src/formats/gexf/schema.d.ts +5 -0
  199. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  200. package/dist/src/formats/gexf/schema.js +5 -0
  201. package/dist/src/formats/gexf/schema.js.map +1 -1
  202. package/dist/src/formats/gexf/styles.d.ts +74 -0
  203. package/dist/src/formats/gexf/styles.d.ts.map +1 -0
  204. package/dist/src/formats/gexf/styles.js +604 -0
  205. package/dist/src/formats/gexf/styles.js.map +1 -0
  206. package/dist/src/formats/gml/exporter.d.ts +1 -5
  207. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  208. package/dist/src/formats/gml/exporter.js +19 -8
  209. package/dist/src/formats/gml/exporter.js.map +1 -1
  210. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  211. package/dist/src/formats/gml/importer.js +4 -0
  212. package/dist/src/formats/gml/importer.js.map +1 -1
  213. package/dist/src/formats/gml/index.d.ts +2 -1
  214. package/dist/src/formats/gml/index.d.ts.map +1 -1
  215. package/dist/src/formats/gml/index.js +2 -1
  216. package/dist/src/formats/gml/index.js.map +1 -1
  217. package/dist/src/formats/gml/positions.d.ts +14 -0
  218. package/dist/src/formats/gml/positions.d.ts.map +1 -0
  219. package/dist/src/formats/gml/positions.js +46 -0
  220. package/dist/src/formats/gml/positions.js.map +1 -0
  221. package/dist/src/formats/gml/styles.d.ts +59 -0
  222. package/dist/src/formats/gml/styles.d.ts.map +1 -0
  223. package/dist/src/formats/gml/styles.js +1056 -0
  224. package/dist/src/formats/gml/styles.js.map +1 -0
  225. package/dist/src/formats/gml/syntax.d.ts +11 -0
  226. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  227. package/dist/src/formats/gml/syntax.js +151 -62
  228. package/dist/src/formats/gml/syntax.js.map +1 -1
  229. package/dist/src/formats/graphml/constants.d.ts +4 -0
  230. package/dist/src/formats/graphml/constants.d.ts.map +1 -1
  231. package/dist/src/formats/graphml/constants.js +5 -1
  232. package/dist/src/formats/graphml/constants.js.map +1 -1
  233. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  234. package/dist/src/formats/graphml/exporter.js +133 -65
  235. package/dist/src/formats/graphml/exporter.js.map +1 -1
  236. package/dist/src/formats/graphml/importer.d.ts +4 -1
  237. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  238. package/dist/src/formats/graphml/importer.js +100 -44
  239. package/dist/src/formats/graphml/importer.js.map +1 -1
  240. package/dist/src/formats/graphml/index.d.ts +1 -0
  241. package/dist/src/formats/graphml/index.d.ts.map +1 -1
  242. package/dist/src/formats/graphml/index.js +1 -0
  243. package/dist/src/formats/graphml/index.js.map +1 -1
  244. package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
  245. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
  246. package/dist/src/formats/graphml/styles-plain.js +187 -0
  247. package/dist/src/formats/graphml/styles-plain.js.map +1 -0
  248. package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
  249. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
  250. package/dist/src/formats/graphml/styles-yed.js +1086 -0
  251. package/dist/src/formats/graphml/styles-yed.js.map +1 -0
  252. package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
  253. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
  254. package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
  255. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
  256. package/dist/src/formats/graphml/tree.d.ts.map +1 -1
  257. package/dist/src/formats/graphml/tree.js +34 -19
  258. package/dist/src/formats/graphml/tree.js.map +1 -1
  259. package/dist/src/formats/graphml/yfiles.d.ts +16 -2
  260. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  261. package/dist/src/formats/graphml/yfiles.js +83 -12
  262. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  263. package/dist/src/formats/json/exporter.d.ts +5 -0
  264. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  265. package/dist/src/formats/json/exporter.js +68 -25
  266. package/dist/src/formats/json/exporter.js.map +1 -1
  267. package/dist/src/formats/json/importer.d.ts +22 -3
  268. package/dist/src/formats/json/importer.d.ts.map +1 -1
  269. package/dist/src/formats/json/importer.js +439 -264
  270. package/dist/src/formats/json/importer.js.map +1 -1
  271. package/dist/src/formats/json/positions.d.ts +16 -0
  272. package/dist/src/formats/json/positions.d.ts.map +1 -0
  273. package/dist/src/formats/json/positions.js +44 -0
  274. package/dist/src/formats/json/positions.js.map +1 -0
  275. package/dist/src/formats/json/styles.d.ts +102 -0
  276. package/dist/src/formats/json/styles.d.ts.map +1 -0
  277. package/dist/src/formats/json/styles.js +1753 -0
  278. package/dist/src/formats/json/styles.js.map +1 -0
  279. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  280. package/dist/src/formats/neo4j/exporter.js +2 -1
  281. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  282. package/dist/src/formats/pajek/exporter.d.ts +2 -0
  283. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  284. package/dist/src/formats/pajek/exporter.js +142 -76
  285. package/dist/src/formats/pajek/exporter.js.map +1 -1
  286. package/dist/src/formats/pajek/importer.d.ts +4 -0
  287. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  288. package/dist/src/formats/pajek/importer.js +60 -6
  289. package/dist/src/formats/pajek/importer.js.map +1 -1
  290. package/dist/src/formats/pajek/index.d.ts +2 -0
  291. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  292. package/dist/src/formats/pajek/index.js +2 -0
  293. package/dist/src/formats/pajek/index.js.map +1 -1
  294. package/dist/src/formats/pajek/styles.d.ts +50 -0
  295. package/dist/src/formats/pajek/styles.d.ts.map +1 -0
  296. package/dist/src/formats/pajek/styles.js +569 -0
  297. package/dist/src/formats/pajek/styles.js.map +1 -0
  298. package/dist/src/formats/pajek/syntax.d.ts +6 -0
  299. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  300. package/dist/src/formats/pajek/syntax.js +6 -0
  301. package/dist/src/formats/pajek/syntax.js.map +1 -1
  302. package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
  303. package/dist/src/formats/xgmml/columns.js +34 -9
  304. package/dist/src/formats/xgmml/columns.js.map +1 -1
  305. package/dist/src/formats/xgmml/constants.d.ts +2 -0
  306. package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
  307. package/dist/src/formats/xgmml/constants.js +3 -1
  308. package/dist/src/formats/xgmml/constants.js.map +1 -1
  309. package/dist/src/formats/xgmml/document.d.ts +12 -8
  310. package/dist/src/formats/xgmml/document.d.ts.map +1 -1
  311. package/dist/src/formats/xgmml/document.js +56 -13
  312. package/dist/src/formats/xgmml/document.js.map +1 -1
  313. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  314. package/dist/src/formats/xgmml/emit.js +12 -6
  315. package/dist/src/formats/xgmml/emit.js.map +1 -1
  316. package/dist/src/formats/xgmml/exporter.d.ts +3 -1
  317. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  318. package/dist/src/formats/xgmml/exporter.js +22 -9
  319. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  320. package/dist/src/formats/xgmml/importer.d.ts +2 -1
  321. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  322. package/dist/src/formats/xgmml/importer.js +31 -24
  323. package/dist/src/formats/xgmml/importer.js.map +1 -1
  324. package/dist/src/formats/xgmml/styles.d.ts +104 -0
  325. package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
  326. package/dist/src/formats/xgmml/styles.js +310 -0
  327. package/dist/src/formats/xgmml/styles.js.map +1 -0
  328. package/dist/src/index.d.ts +9 -7
  329. package/dist/src/index.d.ts.map +1 -1
  330. package/dist/src/index.js +7 -7
  331. package/dist/src/index.js.map +1 -1
  332. package/dist/src/positions/codes.d.ts +31 -0
  333. package/dist/src/positions/codes.d.ts.map +1 -0
  334. package/dist/src/positions/codes.js +26 -0
  335. package/dist/src/positions/codes.js.map +1 -0
  336. package/dist/src/positions/convert.d.ts +58 -0
  337. package/dist/src/positions/convert.d.ts.map +1 -0
  338. package/dist/src/positions/convert.js +107 -0
  339. package/dist/src/positions/convert.js.map +1 -0
  340. package/dist/src/positions/extract.d.ts +27 -0
  341. package/dist/src/positions/extract.d.ts.map +1 -0
  342. package/dist/src/positions/extract.js +526 -0
  343. package/dist/src/positions/extract.js.map +1 -0
  344. package/dist/src/positions/index.d.ts +10 -0
  345. package/dist/src/positions/index.d.ts.map +1 -0
  346. package/dist/src/positions/index.js +9 -0
  347. package/dist/src/positions/index.js.map +1 -0
  348. package/dist/src/positions/types.d.ts +208 -0
  349. package/dist/src/positions/types.d.ts.map +1 -0
  350. package/dist/src/positions/types.js +10 -0
  351. package/dist/src/positions/types.js.map +1 -0
  352. package/dist/src/registry.d.ts +30 -0
  353. package/dist/src/registry.d.ts.map +1 -1
  354. package/dist/src/registry.js +130 -9
  355. package/dist/src/registry.js.map +1 -1
  356. package/dist/src/styles/annotations.d.ts +132 -0
  357. package/dist/src/styles/annotations.d.ts.map +1 -0
  358. package/dist/src/styles/annotations.js +320 -0
  359. package/dist/src/styles/annotations.js.map +1 -0
  360. package/dist/src/styles/budget.d.ts +45 -0
  361. package/dist/src/styles/budget.d.ts.map +1 -0
  362. package/dist/src/styles/budget.js +58 -0
  363. package/dist/src/styles/budget.js.map +1 -0
  364. package/dist/src/styles/canon/bends.d.ts +32 -0
  365. package/dist/src/styles/canon/bends.d.ts.map +1 -0
  366. package/dist/src/styles/canon/bends.js +74 -0
  367. package/dist/src/styles/canon/bends.js.map +1 -0
  368. package/dist/src/styles/canon/color-tables.d.ts +22 -0
  369. package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
  370. package/dist/src/styles/canon/color-tables.js +369 -0
  371. package/dist/src/styles/canon/color-tables.js.map +1 -0
  372. package/dist/src/styles/canon/color.d.ts +66 -0
  373. package/dist/src/styles/canon/color.d.ts.map +1 -0
  374. package/dist/src/styles/canon/color.js +548 -0
  375. package/dist/src/styles/canon/color.js.map +1 -0
  376. package/dist/src/styles/canon/enums.d.ts +25 -0
  377. package/dist/src/styles/canon/enums.d.ts.map +1 -0
  378. package/dist/src/styles/canon/enums.js +187 -0
  379. package/dist/src/styles/canon/enums.js.map +1 -0
  380. package/dist/src/styles/canon/graphviz.d.ts +48 -0
  381. package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
  382. package/dist/src/styles/canon/graphviz.js +160 -0
  383. package/dist/src/styles/canon/graphviz.js.map +1 -0
  384. package/dist/src/styles/canon/index.d.ts +13 -0
  385. package/dist/src/styles/canon/index.d.ts.map +1 -0
  386. package/dist/src/styles/canon/index.js +13 -0
  387. package/dist/src/styles/canon/index.js.map +1 -0
  388. package/dist/src/styles/canon/number.d.ts +59 -0
  389. package/dist/src/styles/canon/number.d.ts.map +1 -0
  390. package/dist/src/styles/canon/number.js +142 -0
  391. package/dist/src/styles/canon/number.js.map +1 -0
  392. package/dist/src/styles/canon/site.d.ts +51 -0
  393. package/dist/src/styles/canon/site.d.ts.map +1 -0
  394. package/dist/src/styles/canon/site.js +63 -0
  395. package/dist/src/styles/canon/site.js.map +1 -0
  396. package/dist/src/styles/canon/text.d.ts +61 -0
  397. package/dist/src/styles/canon/text.d.ts.map +1 -0
  398. package/dist/src/styles/canon/text.js +199 -0
  399. package/dist/src/styles/canon/text.js.map +1 -0
  400. package/dist/src/styles/codes.d.ts +95 -0
  401. package/dist/src/styles/codes.d.ts.map +1 -0
  402. package/dist/src/styles/codes.js +97 -0
  403. package/dist/src/styles/codes.js.map +1 -0
  404. package/dist/src/styles/cyjs/cascade.d.ts +134 -0
  405. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
  406. package/dist/src/styles/cyjs/cascade.js +2252 -0
  407. package/dist/src/styles/cyjs/cascade.js.map +1 -0
  408. package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
  409. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
  410. package/dist/src/styles/cyjs/defaults-table.js +76 -0
  411. package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
  412. package/dist/src/styles/cyjs/emit.d.ts +82 -0
  413. package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
  414. package/dist/src/styles/cyjs/emit.js +791 -0
  415. package/dist/src/styles/cyjs/emit.js.map +1 -0
  416. package/dist/src/styles/cyjs/index.d.ts +13 -0
  417. package/dist/src/styles/cyjs/index.d.ts.map +1 -0
  418. package/dist/src/styles/cyjs/index.js +13 -0
  419. package/dist/src/styles/cyjs/index.js.map +1 -0
  420. package/dist/src/styles/cyjs/live.d.ts +46 -0
  421. package/dist/src/styles/cyjs/live.d.ts.map +1 -0
  422. package/dist/src/styles/cyjs/live.js +108 -0
  423. package/dist/src/styles/cyjs/live.js.map +1 -0
  424. package/dist/src/styles/cyjs/mappers.d.ts +147 -0
  425. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
  426. package/dist/src/styles/cyjs/mappers.js +744 -0
  427. package/dist/src/styles/cyjs/mappers.js.map +1 -0
  428. package/dist/src/styles/cyjs/selector.d.ts +113 -0
  429. package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
  430. package/dist/src/styles/cyjs/selector.js +611 -0
  431. package/dist/src/styles/cyjs/selector.js.map +1 -0
  432. package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
  433. package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
  434. package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
  435. package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
  436. package/dist/src/styles/cytoscape/emit.d.ts +125 -0
  437. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
  438. package/dist/src/styles/cytoscape/emit.js +1025 -0
  439. package/dist/src/styles/cytoscape/emit.js.map +1 -0
  440. package/dist/src/styles/cytoscape/index.d.ts +10 -0
  441. package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
  442. package/dist/src/styles/cytoscape/index.js +10 -0
  443. package/dist/src/styles/cytoscape/index.js.map +1 -0
  444. package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
  445. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
  446. package/dist/src/styles/cytoscape/lexicon.js +605 -0
  447. package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
  448. package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
  449. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
  450. package/dist/src/styles/cytoscape/mappings.js +460 -0
  451. package/dist/src/styles/cytoscape/mappings.js.map +1 -0
  452. package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
  453. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
  454. package/dist/src/styles/cytoscape/resolve.js +381 -0
  455. package/dist/src/styles/cytoscape/resolve.js.map +1 -0
  456. package/dist/src/styles/cytoscape/translate.d.ts +50 -0
  457. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
  458. package/dist/src/styles/cytoscape/translate.js +156 -0
  459. package/dist/src/styles/cytoscape/translate.js.map +1 -0
  460. package/dist/src/styles/defaults.d.ts +90 -0
  461. package/dist/src/styles/defaults.d.ts.map +1 -0
  462. package/dist/src/styles/defaults.js +414 -0
  463. package/dist/src/styles/defaults.js.map +1 -0
  464. package/dist/src/styles/index.d.ts +15 -0
  465. package/dist/src/styles/index.d.ts.map +1 -0
  466. package/dist/src/styles/index.js +14 -0
  467. package/dist/src/styles/index.js.map +1 -0
  468. package/dist/src/styles/internal.d.ts +17 -0
  469. package/dist/src/styles/internal.d.ts.map +1 -0
  470. package/dist/src/styles/internal.js +16 -0
  471. package/dist/src/styles/internal.js.map +1 -0
  472. package/dist/src/styles/io/approximations.d.ts +24 -0
  473. package/dist/src/styles/io/approximations.d.ts.map +1 -0
  474. package/dist/src/styles/io/approximations.js +51 -0
  475. package/dist/src/styles/io/approximations.js.map +1 -0
  476. package/dist/src/styles/io/block.d.ts +166 -0
  477. package/dist/src/styles/io/block.d.ts.map +1 -0
  478. package/dist/src/styles/io/block.js +930 -0
  479. package/dist/src/styles/io/block.js.map +1 -0
  480. package/dist/src/styles/io/generic.d.ts +88 -0
  481. package/dist/src/styles/io/generic.d.ts.map +1 -0
  482. package/dist/src/styles/io/generic.js +516 -0
  483. package/dist/src/styles/io/generic.js.map +1 -0
  484. package/dist/src/styles/io/index.d.ts +8 -0
  485. package/dist/src/styles/io/index.d.ts.map +1 -0
  486. package/dist/src/styles/io/index.js +7 -0
  487. package/dist/src/styles/io/index.js.map +1 -0
  488. package/dist/src/styles/io/writer.d.ts +89 -0
  489. package/dist/src/styles/io/writer.d.ts.map +1 -0
  490. package/dist/src/styles/io/writer.js +626 -0
  491. package/dist/src/styles/io/writer.js.map +1 -0
  492. package/dist/src/styles/notes.d.ts +47 -0
  493. package/dist/src/styles/notes.d.ts.map +1 -0
  494. package/dist/src/styles/notes.js +140 -0
  495. package/dist/src/styles/notes.js.map +1 -0
  496. package/dist/src/styles/plan/classes.d.ts +31 -0
  497. package/dist/src/styles/plan/classes.d.ts.map +1 -0
  498. package/dist/src/styles/plan/classes.js +139 -0
  499. package/dist/src/styles/plan/classes.js.map +1 -0
  500. package/dist/src/styles/plan/continuous.d.ts +32 -0
  501. package/dist/src/styles/plan/continuous.d.ts.map +1 -0
  502. package/dist/src/styles/plan/continuous.js +165 -0
  503. package/dist/src/styles/plan/continuous.js.map +1 -0
  504. package/dist/src/styles/plan/discrete.d.ts +39 -0
  505. package/dist/src/styles/plan/discrete.d.ts.map +1 -0
  506. package/dist/src/styles/plan/discrete.js +127 -0
  507. package/dist/src/styles/plan/discrete.js.map +1 -0
  508. package/dist/src/styles/plan/families.d.ts +31 -0
  509. package/dist/src/styles/plan/families.d.ts.map +1 -0
  510. package/dist/src/styles/plan/families.js +95 -0
  511. package/dist/src/styles/plan/families.js.map +1 -0
  512. package/dist/src/styles/plan/features.d.ts +58 -0
  513. package/dist/src/styles/plan/features.d.ts.map +1 -0
  514. package/dist/src/styles/plan/features.js +185 -0
  515. package/dist/src/styles/plan/features.js.map +1 -0
  516. package/dist/src/styles/plan/index.d.ts +7 -0
  517. package/dist/src/styles/plan/index.d.ts.map +1 -0
  518. package/dist/src/styles/plan/index.js +7 -0
  519. package/dist/src/styles/plan/index.js.map +1 -0
  520. package/dist/src/styles/plan/plan.d.ts +71 -0
  521. package/dist/src/styles/plan/plan.d.ts.map +1 -0
  522. package/dist/src/styles/plan/plan.js +893 -0
  523. package/dist/src/styles/plan/plan.js.map +1 -0
  524. package/dist/src/styles/plan/resolve.d.ts +137 -0
  525. package/dist/src/styles/plan/resolve.d.ts.map +1 -0
  526. package/dist/src/styles/plan/resolve.js +587 -0
  527. package/dist/src/styles/plan/resolve.js.map +1 -0
  528. package/dist/src/styles/types.d.ts +702 -0
  529. package/dist/src/styles/types.d.ts.map +1 -0
  530. package/dist/src/styles/types.js +10 -0
  531. package/dist/src/styles/types.js.map +1 -0
  532. package/dist/src/styles/vocabulary.d.ts +41 -0
  533. package/dist/src/styles/vocabulary.d.ts.map +1 -0
  534. package/dist/src/styles/vocabulary.js +140 -0
  535. package/dist/src/styles/vocabulary.js.map +1 -0
  536. package/dist/src/types.d.ts +64 -1
  537. package/dist/src/types.d.ts.map +1 -1
  538. package/dist/src/types.js.map +1 -1
  539. package/dist/styles.d.ts +1 -0
  540. package/dist/styles.js +322 -0
  541. package/dist/styles.js.map +1 -0
  542. package/dist/xgmml.js +5 -4
  543. package/dist/xgmml.js.map +1 -1
  544. package/package.json +13 -2
  545. package/src/common/codes.ts +7 -0
  546. package/src/common/escape.ts +5 -2
  547. package/src/common/export.ts +179 -140
  548. package/src/common/input.ts +8 -4
  549. package/src/common/json-elements.ts +169 -38
  550. package/src/common/notes.ts +94 -0
  551. package/src/common/report.ts +41 -1
  552. package/src/common/units.ts +42 -0
  553. package/src/common/xml.ts +45 -5
  554. package/src/formats/cx/exporter.ts +95 -11
  555. package/src/formats/cx/importer.ts +126 -90
  556. package/src/formats/cx/styles.ts +304 -0
  557. package/src/formats/cx2/exporter.ts +234 -77
  558. package/src/formats/cx2/importer.ts +19 -1
  559. package/src/formats/cx2/styles.ts +29 -0
  560. package/src/formats/cys/constants.ts +3 -0
  561. package/src/formats/cys/exporter.ts +246 -60
  562. package/src/formats/cys/importer.ts +125 -9
  563. package/src/formats/cys/session.ts +6 -0
  564. package/src/formats/cys/styles.ts +254 -0
  565. package/src/formats/cys/tables.ts +117 -48
  566. package/src/formats/dot/exporter.ts +262 -126
  567. package/src/formats/dot/importer.ts +111 -20
  568. package/src/formats/dot/index.ts +1 -0
  569. package/src/formats/dot/positions.ts +77 -0
  570. package/src/formats/dot/styles.ts +1755 -0
  571. package/src/formats/gexf/exporter.ts +27 -11
  572. package/src/formats/gexf/importer.ts +308 -158
  573. package/src/formats/gexf/index.ts +10 -0
  574. package/src/formats/gexf/schema.ts +5 -0
  575. package/src/formats/gexf/styles.ts +719 -0
  576. package/src/formats/gml/exporter.ts +33 -14
  577. package/src/formats/gml/importer.ts +4 -0
  578. package/src/formats/gml/index.ts +2 -1
  579. package/src/formats/gml/positions.ts +52 -0
  580. package/src/formats/gml/styles.ts +1248 -0
  581. package/src/formats/gml/syntax.ts +173 -62
  582. package/src/formats/graphml/constants.ts +5 -0
  583. package/src/formats/graphml/exporter.ts +163 -71
  584. package/src/formats/graphml/importer.ts +119 -45
  585. package/src/formats/graphml/index.ts +1 -0
  586. package/src/formats/graphml/styles-plain.ts +236 -0
  587. package/src/formats/graphml/styles-yed.ts +1221 -0
  588. package/src/formats/graphml/styles-yfiles3.ts +573 -0
  589. package/src/formats/graphml/tree.ts +36 -20
  590. package/src/formats/graphml/yfiles.ts +89 -13
  591. package/src/formats/json/exporter.ts +76 -26
  592. package/src/formats/json/importer.ts +541 -322
  593. package/src/formats/json/positions.ts +50 -0
  594. package/src/formats/json/styles.ts +2082 -0
  595. package/src/formats/neo4j/exporter.ts +2 -1
  596. package/src/formats/pajek/exporter.ts +195 -106
  597. package/src/formats/pajek/importer.ts +78 -9
  598. package/src/formats/pajek/index.ts +2 -0
  599. package/src/formats/pajek/styles.ts +685 -0
  600. package/src/formats/pajek/syntax.ts +7 -0
  601. package/src/formats/xgmml/columns.ts +39 -9
  602. package/src/formats/xgmml/constants.ts +3 -0
  603. package/src/formats/xgmml/document.ts +54 -12
  604. package/src/formats/xgmml/emit.ts +11 -6
  605. package/src/formats/xgmml/exporter.ts +32 -13
  606. package/src/formats/xgmml/importer.ts +43 -29
  607. package/src/formats/xgmml/styles.ts +400 -0
  608. package/src/index.ts +16 -0
  609. package/src/positions/codes.ts +32 -0
  610. package/src/positions/convert.ts +123 -0
  611. package/src/positions/extract.ts +619 -0
  612. package/src/positions/index.ts +23 -0
  613. package/src/positions/types.ts +221 -0
  614. package/src/registry.ts +179 -8
  615. package/src/styles/annotations.ts +478 -0
  616. package/src/styles/budget.ts +60 -0
  617. package/src/styles/canon/bends.ts +84 -0
  618. package/src/styles/canon/color-tables.ts +386 -0
  619. package/src/styles/canon/color.ts +624 -0
  620. package/src/styles/canon/enums.ts +211 -0
  621. package/src/styles/canon/graphviz.ts +189 -0
  622. package/src/styles/canon/index.ts +13 -0
  623. package/src/styles/canon/number.ts +152 -0
  624. package/src/styles/canon/site.ts +87 -0
  625. package/src/styles/canon/text.ts +221 -0
  626. package/src/styles/codes.ts +104 -0
  627. package/src/styles/cyjs/cascade.ts +2670 -0
  628. package/src/styles/cyjs/defaults-table.ts +82 -0
  629. package/src/styles/cyjs/emit.ts +952 -0
  630. package/src/styles/cyjs/index.ts +37 -0
  631. package/src/styles/cyjs/live.ts +147 -0
  632. package/src/styles/cyjs/mappers.ts +879 -0
  633. package/src/styles/cyjs/selector.ts +778 -0
  634. package/src/styles/cyjs/stylesheet-text.ts +214 -0
  635. package/src/styles/cytoscape/emit.ts +1264 -0
  636. package/src/styles/cytoscape/index.ts +40 -0
  637. package/src/styles/cytoscape/lexicon.ts +658 -0
  638. package/src/styles/cytoscape/mappings.ts +603 -0
  639. package/src/styles/cytoscape/resolve.ts +521 -0
  640. package/src/styles/cytoscape/translate.ts +237 -0
  641. package/src/styles/defaults.ts +504 -0
  642. package/src/styles/index.ts +57 -0
  643. package/src/styles/internal.ts +17 -0
  644. package/src/styles/io/approximations.ts +47 -0
  645. package/src/styles/io/block.ts +1138 -0
  646. package/src/styles/io/generic.ts +687 -0
  647. package/src/styles/io/index.ts +18 -0
  648. package/src/styles/io/writer.ts +780 -0
  649. package/src/styles/notes.ts +165 -0
  650. package/src/styles/plan/classes.ts +166 -0
  651. package/src/styles/plan/continuous.ts +218 -0
  652. package/src/styles/plan/discrete.ts +165 -0
  653. package/src/styles/plan/families.ts +115 -0
  654. package/src/styles/plan/features.ts +234 -0
  655. package/src/styles/plan/index.ts +7 -0
  656. package/src/styles/plan/plan.ts +1129 -0
  657. package/src/styles/plan/resolve.ts +685 -0
  658. package/src/styles/types.ts +814 -0
  659. package/src/styles/vocabulary.ts +172 -0
  660. package/src/types.ts +76 -1
  661. package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
  662. package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
  663. package/dist/chunks/export-rKLeGQMo.js.map +0 -1
  664. package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
  665. package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
  666. package/dist/chunks/exporter-RVtXVetw.js.map +0 -1
  667. package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
  668. package/dist/chunks/importer-C98dpSH4.js.map +0 -1
  669. package/dist/chunks/importer-D794XUTe.js.map +0 -1
  670. package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
  671. package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
  672. package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
  673. package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
  674. package/dist/chunks/json-elements-DKSqpNW1.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importer-C0AjA3Ax.js","sources":["../../src/formats/cys/constants.ts","../../src/common/zip.ts","../../src/formats/cys/exporter.ts","../../src/formats/cys/session.ts","../../src/formats/cys/styles.ts","../../src/formats/cys/tables.ts","../../src/formats/cys/importer.ts"],"sourcesContent":["/**\n * What the Cytoscape session importer's modules share: the format facts, the column and metadata\n * names it adds, and its issue code table.\n */\n\nimport {\n AMBIGUOUS_GRAPH_NAME_CODE,\n DANGLING_REFERENCE_CODE,\n ELEMENT_ISSUE,\n EMPTY_INPUT_CODE,\n ENCODING_FALLBACK_CODE,\n GRAPH_NOT_FOUND_CODE,\n INPUT_ISSUE,\n MULTIPLE_GRAPHS_CODE,\n NO_GRAPH_CODE,\n STYLES_NOT_IMPORTED_CODE,\n TOO_LARGE_CODE,\n UNKNOWN_ENCODING_CODE,\n} from \"../../common/codes.js\";\nimport { XGMML_ISSUE } from \"../xgmml/constants.js\";\n\n/**\n * The format name.\n * @category Plugin helpers\n */\nexport const FORMAT = \"cys\";\n\n/**\n * File extensions.\n * @category Plugin helpers\n */\nexport const EXTENSIONS: readonly string[] = Object.freeze([\".cys\"]);\n\n/**\n * MIME types: Cytoscape declares none, so the generic zip type.\n * @category Plugin helpers\n */\nexport const MIME_TYPES: readonly string[] = Object.freeze([\"application/zip\"]);\n\n/**\n * The `meta.extra` key of the session facts.\n * @category Plugin helpers\n */\nexport const META_KEY = \"cytoscape\";\n\n/**\n * The origin namespace of the columns the session importer adds (selection, hidden state).\n * @category Plugin helpers\n */\nexport const CYTOSCAPE_NAMESPACE = \"cytoscape\";\n\n/**\n * The 2.x selected state (bool node and edge column).\n * @category Plugin helpers\n */\nexport const SELECTED_COLUMN = \"cytoscape.selected\";\n\n/**\n * The 2.x hidden state (bool node and edge column).\n * @category Plugin helpers\n */\nexport const HIDDEN_COLUMN = \"cytoscape.hidden\";\n\n/**\n * The prefix of the node columns of a second and further view's positions (`position@2`).\n * @category Plugin helpers\n */\nexport const VIEW_POSITION_PREFIX = \"position@\";\n\n/**\n * The default total of uncompressed bytes one import may inflate (2 GiB).\n * @category Plugin helpers\n */\nexport const DEFAULT_MAX_UNCOMPRESSED = 2 * 1024 * 1024 * 1024;\n\n/**\n * The largest uncompressed-to-compressed ratio an entry may have (real sessions reach 30:1).\n * @category Plugin helpers\n */\nexport const MAX_RATIO = 1000;\n\n/**\n * The XGMML codes the session importer relays from the network and view files inside, keyed as\n * every table is (the code without its `E_` / `W_` prefix).\n */\nconst RELAYED: Readonly<Record<string, string>> = Object.fromEntries(\n Object.values(XGMML_ISSUE).map((code) => [code.replace(/^[EW]_/, \"\"), code]),\n);\n\n/**\n * Issue codes of the Cytoscape session importer: its own, the shared ones it records and the\n * XGMML codes it relays from the files inside (with the entry name in the message).\n * @category Built-in formats\n */\nexport const CYS_ISSUE = Object.freeze({\n ...INPUT_ISSUE,\n ...ELEMENT_ISSUE,\n /** A session XML entry that is not UTF-8 and declares no encoding was read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A session XML entry declares an encoding the platform cannot decode; read as UTF-8. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n ...RELAYED,\n /** The input is not a zip archive (or is text). */\n NOT_ZIP: \"E_CYS_NOT_ZIP\",\n /** The archive is damaged: no end record, offsets outside the file, a bad CRC, truncated data. */\n CORRUPT: \"E_CYS_CORRUPT\",\n /** A zip without a session marker (`<x.y.z>.version` or `cysession.xml`). */\n NOT_SESSION: \"E_CYS_NOT_SESSION\",\n /** A zip feature the reader does not support: encryption, a compression method, split archives. */\n UNSUPPORTED: \"E_CYS_UNSUPPORTED\",\n /** A session version graph-io cannot read: a major above 3, or the 2011 3.0 pre-release layout. */\n VERSION: \"E_CYS_VERSION\",\n /** A table or a virtual column that cannot be read at all; it is skipped. */\n TABLE: \"E_CYS_TABLE\",\n /** Table rows with too few or too many cells, a repeated key, or a key matching no element. */\n TABLE_ROW: \"W_CYS_TABLE_ROW\",\n /** The members of a collapsed group are not in the network itself; they are listed in `snapshot.meta.extra`. */\n COLLAPSED_GROUP: \"W_CYS_COLLAPSED_GROUP\",\n /** Entries the importer does not read (apps, global tables, properties, images, thumbnails). */\n ENTRY_SKIPPED: \"W_CYS_ENTRY_SKIPPED\",\n /** Two entries with one name; the first is read. */\n DUPLICATE_ENTRY: \"W_CYS_DUPLICATE_ENTRY\",\n /** A cysession.xml network record without an id, or naming a file an earlier record names. */\n SESSION_RECORD: \"W_CYS_SESSION_RECORD\",\n /** The archive inflates beyond maxUncompressedBytes, or an entry beyond the ratio limit. */\n TOO_LARGE: TOO_LARGE_CODE,\n /** The session's styles are not applied. */\n STYLES_NOT_IMPORTED: STYLES_NOT_IMPORTED_CODE,\n /** A view, table or network the session names but does not hold. */\n DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,\n /** The input is empty. */\n EMPTY_INPUT: EMPTY_INPUT_CODE,\n /** The session holds no network. */\n NO_GRAPH: NO_GRAPH_CODE,\n /**\n * The file holds several graphs and only the first was read. It is not added when `graphIndex` or `graphName` chose the graph.\n * `importAllGraphs()` reads every one.\n */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** `graphIndex` or `graphName` matches no network in the session. The import stops. */\n GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,\n /** `graphName` matches several networks in the session. The import stops. */\n AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,\n});\n\n/** The name prefix of the per-element style value columns graphty writes into a session's tables. */\nexport const STYLE_COLUMN_PREFIX = \"graphty.style.\";\n","/**\n * A zip reader with no dependency (design `design/graph-io/cytoscape-and-obo/design.md` section\n * 3.3; PKWARE APPNOTE 6.3.10, https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT), for\n * the Cytoscape session importer.\n *\n * The whole archive is in memory: every Cytoscape-written entry has a data descriptor and zero\n * sizes in its local header, so the sizes come from the central directory at the end. The end\n * record is searched in the last 65,557 bytes (a comment can be 65,535 bytes long); the zip64\n * locator and the `0x0001` extra field are followed; bytes prepended to the archive (a\n * self-extracting stub) are tolerated by the shift between the directory's stated and actual\n * offsets. Deflate (method 8) is inflated by wrapping the raw deflate bytes in a gzip member\n * (header, data, the directory's CRC-32 and size) and passing it to `DecompressionStream(\"gzip\")`,\n * which every supported runtime has (Node 18, unlike `\"deflate-raw\"`) and which checks the CRC and\n * the length itself; stored entries (method 0) are checked against a CRC-32 table here. Every\n * other method, and encryption, is refused by name. Entry names are decoded by `decodeEntryName()`\n * (the one place bytes become text) and are matching keys only, never paths.\n *\n * `writeZip()` is the matching writer, for the Cytoscape session exporter: stored entries only,\n * each with its CRC-32 and sizes in its local header (Java's `ZipInputStream`, which Cytoscape\n * reads sessions with, refuses a stored entry that defers them to a data descriptor).\n */\n\nimport { GraphFormatError } from \"@graphty/graph-format\";\n\nimport { decodeEntryName, throwIfAborted } from \"./input.js\";\n\n/** Why a zip could not be read; the importer maps each kind to its own issue code. */\ntype ZipErrorKind = \"not-zip\" | \"corrupt\" | \"unsupported\" | \"too-large\";\n\n/**\n * A zip that cannot be read, or an entry that cannot be inflated.\n * @category Plugin helpers\n */\nexport class ZipError extends Error {\n /** What went wrong. */\n readonly kind: ZipErrorKind;\n\n /**\n * Create the error.\n * @param kind - what went wrong\n * @param message - a plain-ASCII message\n */\n constructor(kind: ZipErrorKind, message: string) {\n super(message);\n this.name = \"ZipError\";\n this.kind = kind;\n }\n}\n\n/**\n * One entry of the central directory.\n * @category Plugin helpers\n */\nexport interface ZipEntry {\n /** The name, decoded, as the central directory spells it. */\n readonly name: string;\n /** The compression method (0 stored, 8 deflate, ...). */\n readonly method: number;\n /** The general purpose bit flags. */\n readonly flags: number;\n /** The CRC-32 of the uncompressed data. */\n readonly crc32: number;\n /** The compressed size in bytes. */\n readonly compressedSize: number;\n /** The uncompressed size in bytes. */\n readonly size: number;\n /** The offset of the local header in the archive bytes (the prepended-data shift applied). */\n readonly localOffset: number;\n /** The name ends in `/`: a directory entry, which holds no data. */\n readonly directory: boolean;\n}\n\n/**\n * How one entry is read.\n * @category Plugin helpers\n */\nexport interface ReadEntryOptions {\n /** The cancellation signal. */\n readonly signal?: AbortSignal | null | undefined;\n /** Called with the bytes inflated so far by this call. */\n readonly onBytes?: ((inflated: number) => void) | undefined;\n /** The most uncompressed bytes this entry may have (the import's remaining budget). */\n readonly maxBytes: number;\n /** The largest uncompressed-to-compressed ratio allowed (above `RATIO_FLOOR` bytes). */\n readonly maxRatio: number;\n}\n\n/**\n * A per-entry size under which the ratio limit does not apply (tiny entries compress well).\n * @category Plugin helpers\n */\nexport const RATIO_FLOOR = 1024 * 1024;\n\nconst EOCD_SIGNATURE = 0x06054b50;\nconst ZIP64_LOCATOR_SIGNATURE = 0x07064b50;\nconst ZIP64_EOCD_SIGNATURE = 0x06064b50;\nconst CENTRAL_SIGNATURE = 0x02014b50;\nconst LOCAL_SIGNATURE = 0x04034b50;\nconst EOCD_SIZE = 22;\nconst MAX_COMMENT = 65535;\nconst CENTRAL_SIZE = 46;\nconst LOCAL_SIZE = 30;\nconst ZIP64_EOCD_SIZE = 56;\nconst ZIP64_LOCATOR_SIZE = 20;\nconst U16_MAX = 0xffff;\nconst U32_MAX = 0xffffffff;\n/** General purpose bit 11: the name is UTF-8. */\nconst UTF8_FLAG = 0x800;\n/** Bytes between two cancellation checks while a stored entry's CRC is computed. */\nconst CRC_SLICE = 1024 * 1024;\n\n/** The compression methods other tools write, by number, for the refusal message. */\nconst METHOD_NAMES: Readonly<Record<number, string>> = {\n 1: \"shrink\",\n 6: \"implode\",\n 9: \"deflate64\",\n 12: \"bzip2\",\n 14: \"LZMA\",\n 93: \"zstd\",\n 95: \"xz\",\n 96: \"JPEG\",\n 97: \"WavPack\",\n 98: \"PPMd\",\n 99: \"AES encryption\",\n};\n\n/**\n * Whether bytes start with a local file header signature (`PK\\x03\\x04`).\n * @param bytes - the bytes\n * @returns true for the start of a zip\n * @category Plugin helpers\n */\nexport function startsLikeZip(bytes: Uint8Array): boolean {\n return bytes.byteLength >= 4 && bytes[0] === 0x50 && bytes[1] === 0x4b && bytes[2] === 3 && bytes[3] === 4;\n}\n\n/**\n * Read the end of central directory record, following the zip64 locator when there is one.\n * @param view - the whole archive\n * @param eocd - the offset of the end record\n * @returns the disk numbers, the entry count and where the central directory is; ZipError\n * \"corrupt\" when the end record needs a zip64 record the archive does not have\n */\nfunction readEndRecord(\n view: DataView,\n eocd: number,\n): {\n disk: number;\n directoryDisk: number;\n count: number;\n directorySize: number;\n directoryOffset: number;\n directoryEnd: number;\n} {\n const locator = eocd - ZIP64_LOCATOR_SIZE;\n if (locator >= 0 && view.getUint32(locator, true) === ZIP64_LOCATOR_SIGNATURE) {\n const record = zip64EndRecord(view, locator);\n return {\n disk: view.getUint32(record + 16, true),\n directoryDisk: view.getUint32(record + 20, true),\n count: readU64(view, record + 32),\n directorySize: readU64(view, record + 40),\n directoryOffset: readU64(view, record + 48),\n directoryEnd: record,\n };\n }\n const count = view.getUint16(eocd + 10, true);\n const directorySize = view.getUint32(eocd + 12, true);\n const directoryOffset = view.getUint32(eocd + 16, true);\n if (count === U16_MAX || directorySize === U32_MAX || directoryOffset === U32_MAX) {\n throw new ZipError(\"corrupt\", \"the end record needs a zip64 record the archive does not have\");\n }\n return {\n disk: view.getUint16(eocd + 4, true),\n directoryDisk: view.getUint16(eocd + 6, true),\n count,\n directorySize,\n directoryOffset,\n directoryEnd: eocd,\n };\n}\n\n/**\n * Read the central directory.\n * @param bytes - the whole archive\n * @returns the entries in directory order; ZipError \"not-zip\" when there is no end record and the\n * bytes do not start like a zip, \"corrupt\" for an end record or directory that does not fit,\n * \"unsupported\" for a split archive\n * @category Plugin helpers\n */\nexport function readZipDirectory(bytes: Uint8Array): ZipEntry[] {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const eocd = findEndRecord(bytes, view);\n if (eocd < 0) {\n throw startsLikeZip(bytes)\n ? new ZipError(\"corrupt\", \"the archive has no end of central directory record (truncated?)\")\n : new ZipError(\"not-zip\", \"the input is not a zip archive\");\n }\n const { disk, directoryDisk, count, directorySize, directoryOffset, directoryEnd } = readEndRecord(view, eocd);\n if (disk !== 0 || directoryDisk !== 0) {\n throw new ZipError(\"unsupported\", \"a split (multi-disk) archive cannot be read\");\n }\n const start = directoryEnd - directorySize;\n if (start < 0 || directoryOffset > bytes.byteLength) {\n throw new ZipError(\"corrupt\", \"the central directory lies outside the archive\");\n }\n // data prepended to the archive moves every offset by the same amount\n const shift = start - directoryOffset;\n if (shift < 0) {\n throw new ZipError(\"corrupt\", \"the central directory offset does not match its position\");\n }\n const entries: ZipEntry[] = [];\n let at = start;\n for (let i = 0; i < count; i++) {\n if (at + CENTRAL_SIZE > directoryEnd || view.getUint32(at, true) !== CENTRAL_SIGNATURE) {\n throw new ZipError(\"corrupt\", `central directory entry ${i + 1} of ${count} is damaged`);\n }\n const nameLength = view.getUint16(at + 28, true);\n const extraLength = view.getUint16(at + 30, true);\n const commentLength = view.getUint16(at + 32, true);\n const next = at + CENTRAL_SIZE + nameLength + extraLength + commentLength;\n if (next > directoryEnd) {\n throw new ZipError(\"corrupt\", `central directory entry ${i + 1} runs past the directory`);\n }\n const flags = view.getUint16(at + 8, true);\n const name = decodeEntryName(\n bytes.subarray(at + CENTRAL_SIZE, at + CENTRAL_SIZE + nameLength),\n (flags & UTF8_FLAG) === 0,\n );\n let compressedSize = view.getUint32(at + 20, true);\n let size = view.getUint32(at + 24, true);\n let localOffset = view.getUint32(at + 42, true);\n if (compressedSize === U32_MAX || size === U32_MAX || localOffset === U32_MAX) {\n ({ compressedSize, size, localOffset } = zip64Extra(view, at + CENTRAL_SIZE + nameLength, extraLength, {\n compressedSize,\n size,\n localOffset,\n }));\n }\n entries.push(\n Object.freeze({\n name,\n method: view.getUint16(at + 10, true),\n flags,\n crc32: view.getUint32(at + 16, true),\n compressedSize,\n size,\n localOffset: localOffset + shift,\n directory: name.endsWith(\"/\"),\n }),\n );\n at = next;\n }\n if (at + 4 <= directoryEnd && view.getUint32(at, true) === CENTRAL_SIGNATURE) {\n throw new ZipError(\n \"corrupt\",\n `the end record counts ${count} entries but the central directory holds more; entries would go unread`,\n );\n }\n checkOverlap(entries, view);\n return entries;\n}\n\n/**\n * Refuse entries whose local header and data overlap (several directory entries naming one local\n * header is a known zip bomb: each inflates the same bytes again). An entry spans its local\n * header, its local name and extra field, and its compressed data; a trailing data descriptor is\n * not counted, since overlapping it inflates nothing twice. A damaged local header counts as a bare\n * header here and is refused when the entry is read.\n * @param entries - the entries\n * @param view - the archive\n */\nfunction checkOverlap(entries: readonly ZipEntry[], view: DataView): void {\n const sorted = [...entries].sort((a, b) => a.localOffset - b.localOffset);\n const end = (entry: ZipEntry): number => {\n const at = entry.localOffset;\n const intact = at + LOCAL_SIZE <= view.byteLength && view.getUint32(at, true) === LOCAL_SIGNATURE;\n const lengths = intact ? view.getUint16(at + 26, true) + view.getUint16(at + 28, true) : 0;\n return at + LOCAL_SIZE + lengths + entry.compressedSize;\n };\n for (let i = 1; i < sorted.length; i++) {\n const before = sorted[i - 1];\n if (sorted[i].localOffset < end(before)) {\n throw new ZipError(\"corrupt\", `the entries ${before.name} and ${sorted[i].name} overlap`);\n }\n }\n}\n\n/**\n * The position of the end of central directory record: the last signature whose comment length\n * fits the archive, else the last signature at all (an archive with bytes after its comment).\n * @param bytes - the archive\n * @param view - a view of it\n * @returns the offset, or -1\n */\nfunction findEndRecord(bytes: Uint8Array, view: DataView): number {\n const lowest = Math.max(0, bytes.byteLength - EOCD_SIZE - MAX_COMMENT);\n let fallback = -1;\n for (let at = bytes.byteLength - EOCD_SIZE; at >= lowest; at--) {\n if (view.getUint32(at, true) !== EOCD_SIGNATURE) {\n continue;\n }\n if (at + EOCD_SIZE + view.getUint16(at + 20, true) === bytes.byteLength) {\n return at;\n }\n if (fallback < 0) {\n fallback = at;\n }\n }\n return fallback;\n}\n\n/**\n * The zip64 end of central directory record a locator points at (or, when the archive has bytes\n * prepended, the one right before the locator).\n * @param view - the archive\n * @param locator - the locator's offset\n * @returns the record's offset\n */\nfunction zip64EndRecord(view: DataView, locator: number): number {\n const stated = readU64(view, locator + 8);\n for (const at of [stated, locator - ZIP64_EOCD_SIZE]) {\n if (at >= 0 && at + ZIP64_EOCD_SIZE <= locator && view.getUint32(at, true) === ZIP64_EOCD_SIGNATURE) {\n return at;\n }\n }\n throw new ZipError(\"corrupt\", \"the zip64 end record the locator names is missing\");\n}\n\n/**\n * The zip64 extended information extra field (header id 0x0001) of a central entry: the 64-bit\n * values of the fields whose 32-bit slot is 0xFFFFFFFF, in the order APPNOTE 4.5.3 gives.\n * @param view - the archive\n * @param at - the start of the extra field\n * @param length - its length\n * @param fields - the 32-bit values\n * @param fields.compressedSize - the compressed size slot\n * @param fields.size - the uncompressed size slot\n * @param fields.localOffset - the local header offset slot\n * @returns the resolved values\n */\nfunction zip64Extra(\n view: DataView,\n at: number,\n length: number,\n fields: { compressedSize: number; size: number; localOffset: number },\n): { compressedSize: number; size: number; localOffset: number } {\n const out = { ...fields };\n for (let p = at; p + 4 <= at + length;) {\n const id = view.getUint16(p, true);\n const dataLength = view.getUint16(p + 2, true);\n if (id === 1) {\n let q = p + 4;\n const end = q + dataLength;\n for (const key of [\"size\", \"compressedSize\", \"localOffset\"] as const) {\n if (fields[key] === U32_MAX) {\n if (q + 8 > end) {\n throw new ZipError(\"corrupt\", \"a zip64 extra field is too short\");\n }\n out[key] = readU64(view, q);\n q += 8;\n }\n }\n return out;\n }\n p += 4 + dataLength;\n }\n throw new ZipError(\"corrupt\", \"an entry needs a zip64 extra field it does not have\");\n}\n\n/**\n * An unsigned 64-bit little-endian integer as a number (exact up to 2^53).\n * @param view - the bytes\n * @param at - the offset\n * @returns the value; ZipError \"unsupported\" beyond 2^53\n */\nfunction readU64(view: DataView, at: number): number {\n const high = view.getUint32(at + 4, true);\n if (high >= 0x200000) {\n throw new ZipError(\"unsupported\", \"a zip64 size or offset beyond 2^53 cannot be read\");\n }\n return high * 0x100000000 + view.getUint32(at, true);\n}\n\n/**\n * Read one entry's data: stored entries are sliced and CRC-checked, deflated ones inflated.\n * @param bytes - the whole archive\n * @param entry - the entry\n * @param options - cancellation, progress and the size limits\n * @returns the uncompressed bytes; ZipError for a damaged, encrypted, unsupported or oversized entry\n */\nexport async function readZipEntry(bytes: Uint8Array, entry: ZipEntry, options: ReadEntryOptions): Promise<Uint8Array> {\n if ((entry.flags & 1) !== 0 || entry.method === 99) {\n throw new ZipError(\"unsupported\", `${entry.name}: the entry is encrypted`);\n }\n if (entry.method !== 0 && entry.method !== 8) {\n const name = METHOD_NAMES[entry.method] ?? `method ${entry.method}`;\n throw new ZipError(\n \"unsupported\",\n `${entry.name}: compression ${name} is not supported (only stored and deflate)`,\n );\n }\n if (entry.size > options.maxBytes) {\n throw new ZipError(\n \"too-large\",\n `${entry.name}: ${entry.size} uncompressed bytes exceed the limit of ${options.maxBytes}`,\n );\n }\n if (entry.size > RATIO_FLOOR && entry.size > options.maxRatio * Math.max(entry.compressedSize, 1)) {\n throw new ZipError(\n \"too-large\",\n `${entry.name}: ${entry.size} bytes from ${entry.compressedSize} is a compression ratio above ${options.maxRatio}:1`,\n );\n }\n const data = entryData(bytes, entry);\n if (entry.method === 0) {\n if (data.byteLength !== entry.size) {\n throw new ZipError(\"corrupt\", `${entry.name}: a stored entry's sizes disagree`);\n }\n let crc = 0xffffffff;\n for (let at = 0; at < data.byteLength; at += CRC_SLICE) {\n throwIfAborted(options.signal);\n crc = crcUpdate(crc, data.subarray(at, Math.min(at + CRC_SLICE, data.byteLength)));\n options.onBytes?.(Math.min(at + CRC_SLICE, data.byteLength));\n }\n if ((crc ^ 0xffffffff) >>> 0 !== entry.crc32) {\n throw new ZipError(\"corrupt\", `${entry.name}: the data does not match its CRC-32`);\n }\n return data;\n }\n return inflate(data, entry, options);\n}\n\n/**\n * The compressed bytes of an entry, located through its local header (whose name and extra\n * lengths can differ from the central directory's).\n * @param bytes - the archive\n * @param entry - the entry\n * @returns exactly compressedSize bytes\n */\nfunction entryData(bytes: Uint8Array, entry: ZipEntry): Uint8Array {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const at = entry.localOffset;\n if (at + LOCAL_SIZE > bytes.byteLength || view.getUint32(at, true) !== LOCAL_SIGNATURE) {\n throw new ZipError(\"corrupt\", `${entry.name}: the local header is missing`);\n }\n const nameLength = view.getUint16(at + 26, true);\n const localName = decodeEntryName(\n bytes.subarray(at + LOCAL_SIZE, Math.min(bytes.byteLength, at + LOCAL_SIZE + nameLength)),\n (entry.flags & UTF8_FLAG) === 0,\n );\n if (localName !== entry.name) {\n throw new ZipError(\n \"corrupt\",\n `${entry.name}: the local header names the entry ${JSON.stringify(localName)}, the central directory ${JSON.stringify(entry.name)}`,\n );\n }\n const start = at + LOCAL_SIZE + nameLength + view.getUint16(at + 28, true);\n const end = start + entry.compressedSize;\n if (end > bytes.byteLength) {\n throw new ZipError(\"corrupt\", `${entry.name}: the entry's data runs past the end of the archive (truncated?)`);\n }\n return bytes.subarray(start, end);\n}\n\n/**\n * Inflate a deflate stream through `DecompressionStream(\"gzip\")`, wrapped in a gzip member that\n * carries the directory's CRC-32 and size, so the platform checks both.\n * @param data - the raw deflate bytes\n * @param entry - the entry\n * @param options - cancellation, progress and limits\n * @returns the bytes\n */\nasync function inflate(data: Uint8Array, entry: ZipEntry, options: ReadEntryOptions): Promise<Uint8Array> {\n if (typeof DecompressionStream !== \"function\") {\n throw new ZipError(\n \"unsupported\",\n \"this runtime has no DecompressionStream, so deflated entries cannot be read\",\n );\n }\n const member = new Uint8Array(10 + data.byteLength + 8);\n member.set([0x1f, 0x8b, 8, 0, 0, 0, 0, 0, 0, 0xff]);\n member.set(data, 10);\n const trailer = new DataView(member.buffer, 10 + data.byteLength, 8);\n trailer.setUint32(0, entry.crc32, true);\n trailer.setUint32(4, entry.size % 0x100000000, true);\n const source = new ReadableStream<BufferSource>({\n start(controller): void {\n controller.enqueue(member);\n controller.close();\n },\n });\n const reader = source.pipeThrough(new DecompressionStream(\"gzip\")).getReader();\n const parts: Uint8Array[] = [];\n let total = 0;\n try {\n for (;;) {\n throwIfAborted(options.signal);\n let chunk: ReadableStreamReadResult<Uint8Array>;\n try {\n chunk = await reader.read();\n } catch {\n throw new ZipError(\n \"corrupt\",\n `${entry.name}: the deflate data is damaged or does not match its CRC-32 and size`,\n );\n }\n if (chunk.done) {\n break;\n }\n total += chunk.value.byteLength;\n if (total > entry.size) {\n throw new ZipError(\"corrupt\", `${entry.name}: the data is longer than its directory size`);\n }\n parts.push(chunk.value);\n options.onBytes?.(total);\n }\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n if (total !== entry.size) {\n throw new ZipError(\"corrupt\", `${entry.name}: the data is shorter than its directory size`);\n }\n if (parts.length === 1) {\n return parts[0];\n }\n const out = new Uint8Array(total);\n let at = 0;\n for (const part of parts) {\n out.set(part, at);\n at += part.byteLength;\n }\n return out;\n}\n\n/** The CRC-32 table (polynomial 0xEDB88320). */\nconst CRC_TABLE = ((): Uint32Array => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = (c & 1) === 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\n/**\n * Continue a CRC-32 over more bytes.\n * @param crc - the running value (start with 0xFFFFFFFF)\n * @param bytes - the bytes\n * @returns the running value (XOR with 0xFFFFFFFF to finish)\n */\nfunction crcUpdate(crc: number, bytes: Uint8Array): number {\n let c = crc;\n for (const byte of bytes) {\n c = CRC_TABLE[(c ^ byte) & 0xff] ^ (c >>> 8);\n }\n return c >>> 0;\n}\n\n/**\n * The CRC-32 of bytes.\n * @param bytes - the bytes\n * @returns the checksum\n * @category Plugin helpers\n */\nexport function crc32(bytes: Uint8Array): number {\n return (crcUpdate(0xffffffff, bytes) ^ 0xffffffff) >>> 0;\n}\n\n/**\n * One entry for writeZip(): its name and its bytes.\n * @category Plugin helpers\n */\nexport interface ZipWriteEntry {\n /** The entry name (UTF-8, `/` separated). */\n readonly name: string;\n /** The data. */\n readonly data: Uint8Array;\n}\n\n/** The DOS time and date written on every entry: 1980-01-01 00:00, so equal input gives equal bytes. */\nconst DOS_DATE = (0 << 9) | (1 << 5) | 1;\n/** Version needed to extract a stored entry (1.0). */\nconst STORED_VERSION = 10;\n\n/**\n * Write a zip archive of stored (uncompressed) entries, one entry at a time: each entry's local\n * header and data are yielded as soon as the entry is produced, then the central directory and\n * the end record. Entries are not compressed (ponytail: deflate through `CompressionStream` when\n * the archive size matters). Zip64 is not written: an entry or archive of 4 GiB or more, or more\n * than 65,535 entries, is E_TOO_LARGE.\n * @param entries - the entries, in archive order (may be produced lazily)\n * @yields the archive bytes\n * @returns nothing\n */\nexport function* writeZip(entries: Iterable<ZipWriteEntry>): Generator<Uint8Array, void, undefined> {\n const encoder = new TextEncoder();\n const central: Uint8Array[] = [];\n let offset = 0;\n let count = 0;\n for (const entry of entries) {\n const name = encoder.encode(entry.name);\n const { data } = entry;\n if (offset + LOCAL_SIZE + name.byteLength + data.byteLength >= U32_MAX || count === U16_MAX) {\n throw new GraphFormatError(\"E_TOO_LARGE\", \"the archive needs zip64, which graph-io does not write\", {\n entry: entry.name,\n });\n }\n const crc = crc32(data);\n const local = new Uint8Array(LOCAL_SIZE + name.byteLength);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, LOCAL_SIGNATURE, true);\n lv.setUint16(4, STORED_VERSION, true);\n lv.setUint16(6, UTF8_FLAG, true);\n lv.setUint16(8, 0, true);\n lv.setUint16(10, 0, true);\n lv.setUint16(12, DOS_DATE, true);\n lv.setUint32(14, crc, true);\n lv.setUint32(18, data.byteLength, true);\n lv.setUint32(22, data.byteLength, true);\n lv.setUint16(26, name.byteLength, true);\n lv.setUint16(28, 0, true);\n local.set(name, LOCAL_SIZE);\n const record = new Uint8Array(CENTRAL_SIZE + name.byteLength);\n const cv = new DataView(record.buffer);\n cv.setUint32(0, CENTRAL_SIGNATURE, true);\n cv.setUint16(4, STORED_VERSION, true);\n cv.setUint16(6, STORED_VERSION, true);\n cv.setUint16(8, UTF8_FLAG, true);\n cv.setUint16(10, 0, true);\n cv.setUint16(12, 0, true);\n cv.setUint16(14, DOS_DATE, true);\n cv.setUint32(16, crc, true);\n cv.setUint32(20, data.byteLength, true);\n cv.setUint32(24, data.byteLength, true);\n cv.setUint16(28, name.byteLength, true);\n cv.setUint32(42, offset, true);\n record.set(name, CENTRAL_SIZE);\n central.push(record);\n yield local;\n if (data.byteLength > 0) {\n yield data;\n }\n offset += local.byteLength + data.byteLength;\n count++;\n }\n let size = 0;\n for (const record of central) {\n size += record.byteLength;\n yield record;\n }\n const end = new Uint8Array(EOCD_SIZE);\n const ev = new DataView(end.buffer);\n ev.setUint32(0, EOCD_SIGNATURE, true);\n ev.setUint16(8, count, true);\n ev.setUint16(10, count, true);\n ev.setUint32(12, size, true);\n ev.setUint32(16, offset, true);\n yield end;\n}\n","/**\n * The Cytoscape session exporter: writes a snapshot as a `.cys` file that Cytoscape Desktop 3.x\n * opens as a session holding one network (one collection with one registered subnetwork).\n *\n * The archive holds what Cytoscape's session reader needs and nothing more:\n * - `CytoscapeSession/3.0.0.version`, the empty marker that makes Cytoscape read a 3.x session;\n * - `networks/<root>-<name>.xgmml`, the topology: one root network holding one registered\n * subnetwork, its nodes and edges by SUID, each edge with `cy:directed`;\n * - `tables/<subnetwork>-<name>/LOCAL_ATTRS-org.cytoscape.model.Cy{Node,Edge,Network}-*.cytable`,\n * every column as a CyCSV table keyed by SUID (a session network file carries no attributes:\n * Cytoscape ignores atts on the nodes and edges of a 3.x session), with the label in `name`,\n * which Cytoscape's default style shows; plus the root network's own table with its name;\n * - `views/<subnetwork>-<view>-<name>.xgmml`, the node coordinates (y negated back to screen\n * coordinates), only when the snapshot has positions: graph-io computes no layout.\n *\n * Given styles (`exportGraph(..., { styles })`), the session also holds `session_vizmap.xml` with one style named\n * for the network, which the view names, the view's per-element bypasses, and the `graphty.styles` block as an\n * archive entry of its own (Cytoscape ignores it), with the style values its rules read inside it: a CyCSV text\n * cell cannot be unset, so a table column would read an element without a value back as \"\". Without styles the\n * view names Cytoscape's default style. The network list, properties and thumbnails are not written. Entries are\n * stored, not compressed. Every SUID comes from one counter, above\n * the node ids that are kept as SUIDs; Cytoscape renumbers them all on load.\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot, type NodeId } from \"@graphty/graph-format\";\n\nimport { DictHeuristic } from \"../../common/attributes.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { escapeXmlAttribute, quoteCsvCell } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, LOSS } from \"../../common/export.js\";\nimport { formatDecimal, formatF32, formatF64 } from \"../../common/format.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { hasIllegalXmlChar } from \"../../common/xml.js\";\nimport { writeZip, type ZipWriteEntry } from \"../../common/zip.js\";\nimport { type CytoscapeEmitted, cytoscapeVizmapXml, emitCytoscapeStyle } from \"../../styles/cytoscape/emit.js\";\nimport { STYLE_BLOCK_NAME, styleBlockLosses, writeStyleBlock } from \"../../styles/io/block.js\";\nimport type { ExporterStyleOptions } from \"../../styles/io/writer.js\";\nimport { StyleNotes } from \"../../styles/notes.js\";\nimport type { StyleValue, StyleWriteCapabilities } from \"../../styles/types.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport { lossOf, snapshotBlock } from \"../cx/styles.js\";\nimport { ORIGINAL_ID_ATTRIBUTE } from \"../graphml/constants.js\";\nimport {\n CY_NAMESPACE,\n EDGE_ID_COLUMN,\n GRAPHICS_COLUMN,\n NESTED_NETWORK_COLUMN,\n NETWORK_POINTER_COLUMN,\n NETWORKS_COLUMN,\n PARENT_COLUMN,\n PARENTS_COLUMN,\n POSITION_COLUMN,\n SUBGRAPH_COLUMN,\n XGMML_NAMESPACE,\n XGMML_ORIGIN_NAMESPACE,\n XLINK_NAMESPACE,\n Z_COLUMN,\n} from \"../xgmml/constants.js\";\nimport { XGMML_STYLE_CAPABILITIES } from \"../xgmml/styles.js\";\nimport { FORMAT, STYLE_COLUMN_PREFIX } from \"./constants.js\";\n\n/**\n * The options of the Cytoscape session exporter: the common export options; it has none of its own. The\n * collection and network names come from the snapshot's `meta.name` (default \"Network\").\n * @category Built-in formats\n */\nexport type CysExportOptions = CommonExportOptions;\n\n/**\n * The loss notes the session exporter's check() returns, by name. A key is the code without its\n * severity and format prefixes.\n * @category Built-in formats\n */\nexport const CYS_LOSS = Object.freeze({\n /** CyCSV has no unset text cell: an unset cell of a text column reads back as \"\". */\n UNSET_AS_EMPTY_STRING: \"W_CYS_UNSET_AS_EMPTY_STRING\",\n /**\n * List cells CyCSV cannot hold exactly: an unset or empty list of text reads back as [\"\"], an\n * empty list of numbers or booleans reads back unset, trailing empty text items vanish, and an\n * item holding a newline splits in two.\n */\n LIST_ITEMS: \"W_CYS_LIST_ITEMS\",\n /** A text cell starting with \"=\" is a formula to Cytoscape (an error cell there); graph-io reads it back as text. */\n TEXT_AS_EQUATION: \"W_CYS_TEXT_AS_EQUATION\",\n /** A nested (json) column is written as a text column holding its JSON text. */\n JSON_AS_STRING: \"W_CYS_JSON_AS_STRING\",\n /** A position that cannot be written as it is: another shape, a non-finite coordinate, a z read back in the z column. */\n POSITION: \"W_CYS_POSITION\",\n /**\n * An attribute with a role (for example, the label) is written where the format keeps that role, and reads back under the\n * name the format's importer gives it.\n */\n COLUMN_NAME_CHANGED: LOSS.COLUMN_NAME_CHANGED,\n /**\n * An attribute without a role is written where the format keeps a role (for example, a `name` column as the label), and\n * reads back with that role.\n */\n ROLE_ASSUMED: LOSS.ROLE_ASSUMED,\n /** A mutual pair is written as two directed edges without its mark. */\n MUTUAL_EXPANDED: LOSS.MUTUAL_EXPANDED,\n /** Node ids that are numbers read back as their text. */\n ID_TEXT_TYPE: LOSS.ID_TEXT_TYPE,\n /**\n * Two node ids would be written as the same text (the number 5 and the text \"5\"); the save fails with\n * E_INVALID_ID.\n */\n ID_TEXT_COLLISION: LOSS.ID_TEXT_COLLISION,\n /**\n * Node ids the format cannot write, under `sanitizeIds: \"error\"`; the save fails with E_INVALID_ID. Pass\n * `sanitizeIds: \"mangle\"` to rewrite them.\n */\n ID_CHARSET: LOSS.ID_CHARSET,\n /** Node ids that are not positive integers under sanitizeIds \"mangle\": renumbered, originals kept. */\n ID_MANGLED: LOSS.ID_MANGLED,\n /** Edges without a usable id get generated SUIDs. */\n EDGE_IDS_GENERATED: LOSS.EDGE_IDS_GENERATED,\n /**\n * An attribute type Cytoscape stores as a wider one (a 32-bit float as Double, a byte as Integer), or a label that\n * is not text and is written as text; it reads back with the Cytoscape type.\n */\n DTYPE_UNSUPPORTED: LOSS.DTYPE,\n /** A column whose every cell is unset (and which is not text) vanishes. */\n EMPTY_COLUMN_DROPPED: LOSS.EMPTY_COLUMN,\n /**\n * A text attribute reads back as a dictionary attribute, or the reverse, because the importer chooses by how often\n * its values repeat. The values are the same.\n */\n STORAGE_CLASS_CHANGED: LOSS.STORAGE_CLASS,\n /** A plain `weight` edge column reads back as the edge weight. */\n WEIGHT_KEY_CLASH: LOSS.WEIGHT_KEY_CLASH,\n /** A parent / parents column: groups are not written. */\n HIERARCHY_DROPPED: LOSS.HIERARCHY,\n /** A start / end / timestamp column: sessions have no time. */\n TEMPORAL_DROPPED: LOSS.TEMPORAL,\n /** An attribute with a role the format has no place for is written as a plain attribute; the role is lost. */\n ROLE_DROPPED: LOSS.ROLE,\n /** An extension table the session cannot carry. */\n EXTENSION_TABLE_DROPPED: LOSS.EXTENSION_TABLE,\n});\n\n/**\n * What a Cytoscape session keeps: mixed direction, parallel edges and self-loops, integer SUIDs\n * for nodes and edges, String / Double / Integer / Long / Boolean columns and lists of them,\n * graph columns and positions. Groups, defaults, styles and time are not written.\n * @category Built-in formats\n */\nexport const CYS_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: true,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"required\",\n idCharset: \"integer\",\n dtypes: [\"string\", \"dict\", \"f64\", \"i32\", \"bool\", \"list\"],\n components: false,\n lists: true,\n json: false,\n defaults: false,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: true,\n positions: true,\n viz: false,\n});\n\n/** The roles with a slot (the label as `name`, the edge id as the SUID, positions in the view) and their read-back names. */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"label\", \"id\", \"position\"]);\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: \"name\",\n id: EDGE_ID_COLUMN,\n position: POSITION_COLUMN,\n});\n\n/** Roles whose columns are not written as table columns (structure, or reported dropped by checkCapabilities). */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n]);\n\n/** A table of the session. */\ntype Domain = \"node\" | \"edge\" | \"network\";\n\n/** The Java classes of the columns Cytoscape creates in every table, by lower-case name. */\nconst BUILT_IN: Readonly<Record<Domain, ReadonlyMap<string, string>>> = {\n node: new Map([\n [\"name\", \"java.lang.String\"],\n [\"shared name\", \"java.lang.String\"],\n [\"selected\", \"java.lang.Boolean\"],\n ]),\n edge: new Map([\n [\"name\", \"java.lang.String\"],\n [\"shared name\", \"java.lang.String\"],\n [\"interaction\", \"java.lang.String\"],\n [\"shared interaction\", \"java.lang.String\"],\n [\"selected\", \"java.lang.Boolean\"],\n ]),\n network: new Map([\n [\"name\", \"java.lang.String\"],\n [\"shared name\", \"java.lang.String\"],\n [\"selected\", \"java.lang.Boolean\"],\n [\"__annotations\", \"java.util.List<java.lang.String>\"],\n ]),\n};\n\n/** Column names graph-io's session importer gives its own columns; a table column of such a name reads back renamed. */\nconst IMPORTER_NAMES: Readonly<Record<Domain, ReadonlySet<string>>> = {\n node: new Set([\n POSITION_COLUMN,\n Z_COLUMN,\n GRAPHICS_COLUMN,\n PARENT_COLUMN,\n PARENTS_COLUMN,\n SUBGRAPH_COLUMN,\n NESTED_NETWORK_COLUMN,\n NETWORK_POINTER_COLUMN,\n NETWORKS_COLUMN,\n ]),\n edge: new Set([EDGE_ID_COLUMN, GRAPHICS_COLUMN]),\n network: new Set([GRAPHICS_COLUMN]),\n};\n\nconst STRING = \"java.lang.String\";\nconst DOUBLE = \"java.lang.Double\";\nconst INTEGER = \"java.lang.Integer\";\nconst LONG = \"java.lang.Long\";\nconst BOOLEAN = \"java.lang.Boolean\";\nconst I32_MAX = 2147483647;\n\n/**\n * What the session writer holds of a graph's styles: every visual property Cytoscape keeps, as a named style and\n * view bypasses, and the graph's background; the block, with the style values its rules read, in an entry of its own.\n */\nconst CYS_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({ ...XGMML_STYLE_CAPABILITIES, block: \"native\" });\n\n/** The folder every entry lives under (Cytoscape needs one; the name is free). */\nconst ROOT_FOLDER = \"CytoscapeSession/\";\n\n/** The default network name. */\nconst DEFAULT_NAME = \"Network\";\n\n/** A record-a-note callback. */\ntype NoteFn = (code: string, message: string, column?: string | null, count?: number | null) => void;\n\n/** One column of a CyCSV table. */\ninterface TableColumn {\n /** The written name. */\n readonly name: string;\n /** The Java class text (`java.lang.Double`, `java.util.List<java.lang.String>`). */\n readonly javaClass: string;\n /** The cell text of a row (node, edge or network), or null for an unset cell (written empty). */\n readonly cell: (row: number) => string | null;\n}\n\n/** A column to place in a table before its name is settled. */\ninterface Candidate {\n /** The name it wants. */\n readonly name: string;\n /** The snapshot column it came from, or null for one the exporter makes. */\n readonly source: Column | null;\n /** The Java class text. */\n readonly javaClass: string;\n /** The cell text of a row, or null for an unset cell. */\n readonly cell: (row: number) => string | null;\n}\n\n/** Everything check() and export() agree on. */\ninterface Plan {\n readonly notes: LossNote[];\n readonly fatal: GraphFormatError | null;\n /** The SUID of each node. */\n readonly nodeSuids: readonly number[];\n /** The SUID of each edge (meaningless for a folded mirror). */\n readonly edgeSuids: readonly number[];\n readonly rootSuid: number;\n readonly subSuid: number;\n /** The view's SUID, or null when nothing is placed. */\n readonly viewSuid: number | null;\n /** The first SUID of the view's nodes. */\n readonly viewNodeBase: number;\n readonly name: string;\n readonly folding: PairFolding;\n readonly nodeTable: readonly TableColumn[];\n readonly edgeTable: readonly TableColumn[];\n readonly networkTable: readonly TableColumn[];\n readonly rootTable: readonly TableColumn[];\n readonly position: Column | null;\n /** The z column written as the view's z, or null. */\n readonly z: Column | null;\n /** Whether a position's own z is written as the view's z (no z column). */\n readonly positionZ: boolean;\n /** The styles as a Cytoscape style, its bypasses and the columns its mappings add, or null without styles. */\n readonly styled: CytoscapeEmitted | null;\n /** Every style value written approximately or flattened into bypasses, as loss notes. */\n readonly styleNotes: readonly LossNote[];\n /** The `graphty.styles` block, written as its own entry: the styles being written, else the one the snapshot carries as a graph attribute; or null. */\n readonly block: string | null;\n}\n\n// ============================================================ ids\n\n/** Positive integer text a Long holds exactly. */\nconst SUID_TEXT = /^[1-9]\\d*$/;\n\n/**\n * The SUID a node id can keep, or null: a positive safe integer, or its canonical digits.\n * @param id - the id\n * @returns the SUID, or null\n */\nfunction suidOf(id: NodeId): number | null {\n if (typeof id === \"number\") {\n return Number.isSafeInteger(id) && id > 0 ? id : null;\n }\n if (SUID_TEXT.test(id)) {\n const n = Number(id);\n return Number.isSafeInteger(n) ? n : null;\n }\n return null;\n}\n\n/** The node SUIDs and what the id rule found. */\ninterface NodeSuids {\n /** The kept SUID of each node, or 0 for a node that needs a new one. */\n readonly kept: number[];\n /** The nodes that need a new SUID. */\n readonly bad: number[];\n}\n\n/**\n * The SUIDs node ids keep (the first of two ids naming one SUID keeps it).\n * @param snapshot - the snapshot\n * @returns the kept SUIDs and the nodes without one\n */\nfunction keptNodeSuids(snapshot: GraphSnapshot): NodeSuids {\n const kept: number[] = [];\n const bad: number[] = [];\n const used = new Set<number>();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const suid = suidOf(snapshot.ids.idOf(i));\n if (suid === null || used.has(suid)) {\n kept.push(0);\n bad.push(i);\n } else {\n used.add(suid);\n kept.push(suid);\n }\n }\n return { kept, bad };\n}\n\n/**\n * The edge SUIDs the id role column keeps: positive integers, distinct, and not node SUIDs.\n * @param snapshot - the snapshot\n * @param nodeSuids - the SUIDs nodes keep\n * @returns the kept SUID of each edge, 0 where one is generated\n */\nfunction keptEdgeSuids(snapshot: GraphSnapshot, nodeSuids: ReadonlySet<number>): number[] {\n const column = snapshot.edges.byRole(\"id\");\n const out = new Array<number>(snapshot.edgeCount).fill(0);\n if (column === null) {\n return out;\n }\n const used = new Set<number>();\n for (let e = 0; e < snapshot.edgeCount; e++) {\n const value = column.isSet(e) ? column.value(e) : null;\n const suid = typeof value === \"number\" || typeof value === \"string\" ? suidOf(value) : null;\n if (suid !== null && !used.has(suid) && !nodeSuids.has(suid)) {\n used.add(suid);\n out[e] = suid;\n }\n }\n return out;\n}\n\n// ============================================================ columns\n\n/**\n * The Java class of a scalar dtype.\n * @param column - the column (for the long origin and the u32 range)\n * @param dtype - the dtype (a list's item dtype)\n * @returns the class text\n */\nfunction scalarClass(column: Column, dtype: string | null): string {\n switch (dtype) {\n case \"bool\":\n return BOOLEAN;\n case \"i32\":\n case \"u8\":\n return INTEGER;\n case \"u32\":\n return maxValue(column) > I32_MAX ? LONG : INTEGER;\n case \"f32\":\n case \"f64\":\n return /long$/i.test(column.meta.origin?.type ?? \"\") && allSafeIntegers(column) ? LONG : DOUBLE;\n default:\n return STRING;\n }\n}\n\n/**\n * The items of a set cell: a list's items, or the scalar itself.\n * @param column - the column\n * @param row - the row\n * @returns the values\n */\nfunction itemsOf(column: Column, row: number): unknown[] {\n return column.dtype === \"list\" ? [...column.sliceOf(row)] : [column.value(row)];\n}\n\n/**\n * Whether every set value of a numeric column (or of its list items) is a safe integer.\n * @param column - the column\n * @returns true when Long can carry every value\n */\nfunction allSafeIntegers(column: Column): boolean {\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && !itemsOf(column, r).every((v) => typeof v === \"number\" && Number.isSafeInteger(v))) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * The largest value of a numeric column (or of its list items).\n * @param column - the column\n * @returns the maximum, 0 when empty\n */\nfunction maxValue(column: Column): number {\n let max = 0;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r)) {\n for (const v of itemsOf(column, r)) {\n if (typeof v === \"number\" && v > max) {\n max = v;\n }\n }\n }\n }\n return max;\n}\n\n/**\n * The CyCSV text of one value of a class.\n * @param value - the value\n * @param javaClass - the scalar class\n * @param dtype - the dtype it came from\n * @returns the text Cytoscape's `valueOf` reads back\n */\nfunction valueText(value: unknown, javaClass: string, dtype: string | null): string {\n if (javaClass === BOOLEAN) {\n return value === true ? \"true\" : \"false\";\n }\n if (javaClass === DOUBLE) {\n return formatDecimal(value as number, dtype === \"f32\" ? \"f32\" : \"f64\");\n }\n if (javaClass === INTEGER || javaClass === LONG) {\n return String(value);\n }\n return textOf(value);\n}\n\n/**\n * A value as text: strings as they are, numbers in their shortest form, anything else as JSON.\n * @param value - the value\n * @returns the text\n */\nfunction textOf(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\") {\n return formatF64(value);\n }\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (ArrayBuffer.isView(value)) {\n return JSON.stringify(Array.from(value as unknown as ArrayLike<number>).map(finiteOrText));\n }\n return JSON.stringify(value) ?? \"\";\n}\n\n/**\n * A number for JSON text (JSON has no NaN or infinities: those are written as their names).\n * @param v - the number\n * @returns the number or its name\n */\nfunction finiteOrText(v: number): number | string {\n return Number.isFinite(v) ? v : String(v);\n}\n\n/**\n * A snapshot column as a table candidate: its class and cell texts.\n * @param column - the column\n * @param name - the name it wants\n * @returns the candidate\n */\nfunction candidateOf(column: Column, name: string): Candidate {\n const { meta } = column;\n if (column.dtype === \"list\") {\n const item = meta.itemDtype;\n const itemClass = scalarClass(column, item === \"json\" ? null : item);\n return {\n name,\n source: column,\n javaClass: `java.util.List<${itemClass}>`,\n cell: (row) =>\n column.isSet(row)\n ? [...column.sliceOf(row)].map((v) => valueText(v, itemClass, item)).join(\"\\n\")\n : null,\n };\n }\n const javaClass = meta.dtype === \"json\" || meta.components > 1 ? STRING : scalarClass(column, meta.dtype);\n return {\n name,\n source: column,\n javaClass,\n cell: (row) => (column.isSet(row) ? valueText(column.value(row), javaClass, meta.dtype) : null),\n };\n}\n\n/**\n * Settle the names of a table's columns: case-insensitively unique, `SUID` and Cytoscape's own\n * columns of another class renamed `<name>#2`, `#3`...\n * @param domain - the table\n * @param candidates - the columns in order\n * @param note - the recorder\n * @returns the table's columns (the SUID key first)\n */\nfunction settleNames(domain: Domain, candidates: readonly Candidate[], note: NoteFn): TableColumn[] {\n const taken = new Set<string>([\"suid\"]);\n const out: TableColumn[] = [];\n for (const c of candidates) {\n const lower = c.name.toLowerCase();\n const builtIn = BUILT_IN[domain].get(lower);\n let { name } = c;\n const clash = builtIn !== undefined && builtIn !== c.javaClass ? builtIn : null;\n if (taken.has(lower) || clash !== null) {\n let k = 2;\n while (taken.has(`${lower}#${k}`)) {\n k++;\n }\n name = `${c.name}#${k}`;\n const why = renameReason(lower, clash);\n const set = c.source === null ? null : c.source.length - c.source.nullCount;\n note(LOSS.COLUMN_NAME_CHANGED, `${domain} column \"${c.name}\" is written as \"${name}\": ${why}`, c.name, set);\n } else if (c.source !== null && IMPORTER_NAMES[domain].has(c.name)) {\n note(\n LOSS.COLUMN_NAME_CHANGED,\n `${domain} column \"${c.name}\" is written to the session's table and reads back as \"${c.name}#2\": graph-io's session reader makes a \"${c.name}\" column of its own`,\n c.name,\n c.source.length - c.source.nullCount,\n );\n }\n taken.add(name.toLowerCase());\n out.push({ name, javaClass: c.javaClass, cell: c.cell });\n }\n return out;\n}\n\n/**\n * Why a column is renamed.\n * @param lower - the column name, lower-cased\n * @param clash - the Java class of Cytoscape's own column of that name when it holds another, else null\n * @returns the reason\n */\nfunction renameReason(lower: string, clash: string | null): string {\n if (lower === \"suid\") {\n return \"SUID is Cytoscape's key column\";\n }\n if (clash !== null) {\n return `Cytoscape's own \"${lower}\" column holds ${clash}`;\n }\n return \"its name is taken (Cytoscape column names ignore case)\";\n}\n\n/**\n * Java's `String.split(\"\\n\")`: trailing empty items are removed.\n * @param text - the cell\n * @returns the items\n */\nfunction javaSplit(text: string): string[] {\n if (!text.includes(\"\\n\")) {\n return [text];\n }\n const items = text.split(\"\\n\");\n while (items.at(-1) === \"\") {\n items.pop();\n }\n return items;\n}\n\n/**\n * The notes of one written column: what CyCSV cannot hold of its cells.\n * @param domain - the table\n * @param c - the candidate\n * @param rows - the row count\n * @param note - the recorder\n */\nfunction cellNotes(domain: Domain, c: Candidate, rows: number, note: NoteFn): void {\n const { source } = c;\n if (source === null) {\n return;\n }\n const label = `${domain} column \"${source.meta.name}\"`;\n const { name } = source.meta;\n const text = c.javaClass === STRING;\n const { unset, equations, lists, set, heuristic } = cellCounts(c, source, rows);\n if (source.dtype === \"json\") {\n note(CYS_LOSS.JSON_AS_STRING, `${label} holds nested values; written as their JSON text`, name, set);\n }\n if (set === 0 && (!text || rows === 0)) {\n note(LOSS.EMPTY_COLUMN, `${label} has no value; it is not in the re-import`, name, null);\n return;\n }\n if (text && unset > 0) {\n note(\n CYS_LOSS.UNSET_AS_EMPTY_STRING,\n `${label}: ${unset} unset cell${plural(unset)} ${agree(unset, \"is\", \"are\")} written empty and read back as \"\"`,\n name,\n unset,\n );\n }\n if (lists > 0) {\n note(\n CYS_LOSS.LIST_ITEMS,\n `${label}: ${lists} list cell${plural(lists)} ${agree(lists, \"reads\", \"read\")} back changed (an unset or empty list of text as [\"\"], an empty list of numbers unset, trailing empty items dropped, items holding a newline split)`,\n name,\n lists,\n );\n }\n if (equations > 0) {\n note(\n CYS_LOSS.TEXT_AS_EQUATION,\n `${label}: ${equations} cell${plural(equations)} start with \"=\", which Cytoscape reads as a formula (an error cell); graph-io reads them back as text`,\n name,\n equations,\n );\n }\n if (text && (source.dtype === \"string\" || source.dtype === \"dict\")) {\n const readsAs = heuristic.decide();\n if (readsAs !== source.dtype) {\n note(LOSS.STORAGE_CLASS, `${label} reads back as ${readsAs} (the cardinality heuristic)`, name, null);\n }\n }\n}\n\n/**\n * Count what CyCSV changes in a column's cells: unset cells, text read as a formula, lists that\n * read back changed; and feed the text cells to the dict heuristic.\n * @param c - the candidate\n * @param source - its column\n * @param rows - the row count\n * @returns the counts and the heuristic\n */\nfunction cellCounts(\n c: Candidate,\n source: Column,\n rows: number,\n): { unset: number; equations: number; lists: number; set: number; heuristic: DictHeuristic } {\n const text = c.javaClass === STRING;\n const stringList = c.javaClass === `java.util.List<${STRING}>`;\n const counts = { unset: 0, equations: 0, lists: 0, set: 0, heuristic: new DictHeuristic() };\n for (let r = 0; r < rows; r++) {\n const cell = c.cell(r);\n if (cell === null) {\n counts.unset++;\n } else {\n counts.set++;\n }\n const written = cell ?? \"\";\n if (text && !counts.heuristic.decided) {\n counts.heuristic.observe(written);\n }\n if (written.startsWith(\"=\")) {\n counts.equations++;\n } else if (source.dtype === \"list\" && listChanges(source, r, cell, stringList)) {\n counts.lists++;\n }\n }\n return counts;\n}\n\n/**\n * Whether a list cell reads back changed from the text CyCSV writes for it.\n * @param source - the list column\n * @param r - the row\n * @param cell - the written text, or null when unset\n * @param stringList - whether Cytoscape reads the column as a list of text\n * @returns true when it changes\n */\nfunction listChanges(\n source: Extract<Column, { dtype: \"list\" }>,\n r: number,\n cell: string | null,\n stringList: boolean,\n): boolean {\n const written = cell ?? \"\";\n let back: string[] | null = null;\n if (stringList) {\n back = written.length === 0 ? [\"\"] : javaSplit(written);\n } else if (written.length > 0) {\n back = javaSplit(written).filter((item) => item.length > 0);\n }\n const items = cell === null ? null : [...source.sliceOf(r)].map((v) => valueText(v, \"\", null));\n if (back === null || items === null) {\n return back !== items;\n }\n return back.length !== items.length || (stringList && back.some((b, i) => b !== items[i]));\n}\n\n/**\n * Whether a column is the z slot (a role-less f64 `z` column, as the importer makes it).\n * @param column - the column\n * @returns true for the z column\n */\nfunction isZ(column: Column): boolean {\n return column.meta.name === Z_COLUMN && column.meta.dtype === \"f64\" && column.meta.role === null;\n}\n\n/**\n * The candidates of the node or edge table: the label as `name`, then the exporter's own columns,\n * then every other column in order.\n * @param snapshot - the snapshot\n * @param domain - node or edge\n * @param own - the exporter's columns after the label\n * @param skip - columns written elsewhere\n * @param note - the recorder\n * @returns the candidates\n */\nfunction elementCandidates(\n snapshot: GraphSnapshot,\n domain: \"node\" | \"edge\",\n own: readonly Candidate[],\n skip: (column: Column) => boolean,\n note: NoteFn,\n): Candidate[] {\n const table = domain === \"node\" ? snapshot.nodes : snapshot.edges;\n const label = table.byRole(\"label\");\n const out: Candidate[] = [];\n if (label !== null) {\n const c = candidateOf(label, \"name\");\n out.push({ ...c, javaClass: STRING, cell: (row) => (label.isSet(row) ? textOf(label.value(row)) : null) });\n if (label.dtype !== \"string\" && label.dtype !== \"dict\") {\n note(\n LOSS.DTYPE,\n `${domain} label column \"${label.meta.name}\" (${label.dtype}) is written as text and reads back as string`,\n label.meta.name,\n label.length - label.nullCount,\n );\n }\n }\n out.push(...own);\n for (const column of table) {\n const { role } = column.meta;\n if (column === label || (role !== null && (SKIPPED_ROLES.has(role) || role === \"id\")) || skip(column)) {\n continue;\n }\n out.push(candidateOf(column, column.meta.name));\n if (\n label === null &&\n role === null &&\n column.meta.name === \"name\" &&\n scalarClass(column, column.dtype) === STRING\n ) {\n note(\n LOSS.ROLE_ASSUMED,\n `${domain} column \"name\" is Cytoscape's name and reads back as the label`,\n \"name\",\n column.length - column.nullCount,\n );\n }\n }\n return out;\n}\n\n/**\n * Settle a table and record the notes of its cells.\n * @param domain - the table\n * @param candidates - its columns\n * @param rows - its row count\n * @param note - the recorder\n * @returns the columns\n */\nfunction planTable(domain: Domain, candidates: readonly Candidate[], rows: number, note: NoteFn): TableColumn[] {\n for (const c of candidates) {\n cellNotes(domain, c, rows, note);\n }\n return settleNames(domain, candidates, note);\n}\n\n// ============================================================ the plan\n\n/** The SUIDs of the nodes and edges, and what the id rule found. */\ninterface PlannedIds {\n readonly nodeSuids: readonly number[];\n readonly edgeSuids: readonly number[];\n /** The next free SUID. */\n readonly next: number;\n /** E_INVALID_ID when the ids cannot be written, else null. */\n readonly fatal: GraphFormatError | null;\n /** Whether nodes were renumbered (the originals are written). */\n readonly mangled: boolean;\n}\n\n/**\n * Note the node ids whose text changes on the way back: numbers read back as text, and the error\n * for two ids with the same text.\n * @param snapshot - the snapshot\n * @param note - the recorder\n * @returns the error the save throws for a collision, or null\n */\nfunction idTextNotes(snapshot: GraphSnapshot, note: NoteFn): GraphFormatError | null {\n let collisions = 0;\n let numeric = 0;\n const texts = new Set<string>();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id = snapshot.ids.idOf(i);\n numeric += typeof id === \"number\" ? 1 : 0;\n const text = String(id);\n if (texts.has(text)) {\n collisions++;\n }\n texts.add(text);\n }\n let fatal: GraphFormatError | null = null;\n if (collisions > 0) {\n note(\n LOSS.ID_TEXT_COLLISION,\n `${collisions} node id${plural(collisions)} ${agree(collisions, \"shares\", \"share\")} their text with another id (a number and a string); the save fails with E_INVALID_ID`,\n null,\n collisions,\n );\n fatal = new GraphFormatError(\n \"E_INVALID_ID\",\n `${collisions} node id${plural(collisions)} ${agree(collisions, \"shares\", \"share\")} their text with another id`,\n { reason: \"collision\", count: collisions },\n );\n }\n if (numeric > 0) {\n note(\n LOSS.ID_TEXT_TYPE,\n `${numeric} numeric node id${plural(numeric)} ${agree(numeric, \"reads\", \"read\")} back as their text`,\n null,\n numeric,\n );\n }\n return fatal;\n}\n\n/**\n * Note the node ids that are not positive integers: renumbered under \"mangle\", else refused.\n * @param snapshot - the snapshot\n * @param bad - the indices of those ids\n * @param mangle - whether sanitizeIds is \"mangle\"\n * @param note - the recorder\n * @returns the error the save throws, or null under \"mangle\"\n */\nfunction badIdNotes(\n snapshot: GraphSnapshot,\n bad: readonly number[],\n mangle: boolean,\n note: NoteFn,\n): GraphFormatError | null {\n if (mangle) {\n note(\n LOSS.ID_MANGLED,\n `${bad.length} node id${plural(bad.length)} that ${agree(bad.length, \"is\", \"are\")} not positive integers ${agree(bad.length, \"is\", \"are\")} renumbered, since Cytoscape ids are positive integers; the originals are kept in the \"${ORIGINAL_ID_ATTRIBUTE}\" column (restored by restoreMangledIds)`,\n null,\n bad.length,\n );\n return null;\n }\n note(\n LOSS.ID_CHARSET,\n `${bad.length} node id${plural(bad.length)} ${agree(bad.length, \"is\", \"are\")} not positive integers, which Cytoscape requires; the save fails unless sanitizeIds is \"mangle\"`,\n null,\n bad.length,\n );\n const first = snapshot.ids.idOf(bad[0]);\n return new GraphFormatError(\n \"E_INVALID_ID\",\n `${bad.length} node id${plural(bad.length)} cannot be written as Cytoscape ids, which are positive integers (first: ${JSON.stringify(first)} at index ${bad[0]}); pass sanitizeIds: \"mangle\" to rewrite them`,\n { reason: \"charset\", charset: \"integer\", count: bad.length, index: bad[0] },\n );\n}\n\n/**\n * The SUIDs: node ids that are positive integers keep them, the others get new ones (or refuse\n * under sanitizeIds \"error\"); edge ids likewise, from the id role column. Every new SUID comes\n * from one counter above the kept ones.\n * @param snapshot - the snapshot\n * @param common - the resolved common options\n * @param note - the recorder\n * @returns the SUIDs\n */\nfunction planIds(snapshot: GraphSnapshot, common: ResolvedExportOptions, note: NoteFn): PlannedIds {\n const { kept, bad } = keptNodeSuids(snapshot);\n const collision = idTextNotes(snapshot, note);\n const charset = bad.length > 0 ? badIdNotes(snapshot, bad, common.sanitizeIds === \"mangle\", note) : null;\n const fatal = collision ?? charset;\n const nodeSet = new Set(kept.filter((s) => s > 0));\n const edgeKept = keptEdgeSuids(snapshot, nodeSet);\n let next = 1;\n for (const s of [...nodeSet, ...edgeKept]) {\n next = Math.max(next, s + 1);\n }\n const nodeSuids = kept.map((s) => (s > 0 ? s : next++));\n const idColumn = snapshot.edges.byRole(\"id\");\n let generated = 0;\n const edgeSuids = edgeKept.map((s) => {\n if (s > 0) {\n return s;\n }\n generated++;\n return next++;\n });\n if (idColumn !== null && generated > 0) {\n note(\n LOSS.EDGE_IDS_GENERATED,\n `${generated} edge${plural(generated)} ${agree(generated, \"has\", \"have\")} no distinct positive integer id in \"${idColumn.meta.name}\"; they are written with new positive integer ids`,\n idColumn.meta.name,\n generated,\n );\n }\n if (idColumn !== null && idColumn.dtype !== \"string\") {\n note(\n LOSS.DTYPE,\n `edge id column \"${idColumn.meta.name}\" is ${idColumn.dtype}; edge ids read back as text`,\n idColumn.meta.name,\n snapshot.edgeCount - idColumn.nullCount,\n );\n }\n return { nodeSuids, edgeSuids, next, fatal, mangled: common.sanitizeIds === \"mangle\" && bad.length > 0 };\n}\n\n/**\n * The columns of the network's own table: its name (from meta.name unless a text graph column\n * holds it), its description, and the graph columns.\n * @param snapshot - the snapshot\n * @param name - the network name\n * @returns the candidates\n */\nfunction networkCandidates(snapshot: GraphSnapshot, name: string): Candidate[] {\n const out: Candidate[] = [];\n const graphName = snapshot.graph.get(\"name\");\n if (graphName === null || (graphName.dtype !== \"string\" && graphName.dtype !== \"dict\")) {\n out.push({ name: \"name\", source: null, javaClass: STRING, cell: () => name });\n }\n const { description } = snapshot.meta;\n if (description !== null && snapshot.graph.get(\"description\") === null) {\n out.push({ name: \"description\", source: null, javaClass: STRING, cell: () => description });\n }\n for (const column of snapshot.graph) {\n // the graphty.styles block goes into an archive entry of its own, not the network table\n if (column.meta.name !== STYLE_BLOCK_NAME) {\n out.push(candidateOf(column, column.meta.name));\n }\n }\n return out;\n}\n\n/**\n * The columns a Cytoscape style's mappings read that the graph does not hold (a computed degree), as table\n * candidates.\n * @param table - the node or edge table\n * @param added - the columns by name, each element's value\n * @returns the candidates\n */\nfunction addedCandidates(\n table: GraphSnapshot[\"nodes\"],\n added: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): Candidate[] {\n const out: Candidate[] = [];\n for (const [name, values] of added) {\n if (table.has(name)) {\n continue;\n }\n const kinds = new Set(values.filter((v) => v !== null).map((v) => typeof v));\n const [kind] = kinds;\n let javaClass = STRING;\n if (kinds.size === 1 && kind === \"number\") {\n javaClass = DOUBLE;\n } else if (kinds.size === 1 && kind === \"boolean\") {\n javaClass = BOOLEAN;\n }\n out.push({\n name,\n source: null,\n javaClass,\n cell: (row) => {\n const v = values[row] ?? null;\n if (v === null) {\n return null;\n }\n return typeof v === \"number\" ? formatDecimal(v) : String(v);\n },\n });\n }\n return out;\n}\n\n/**\n * Plan an export: the notes, the fatal condition, the SUIDs and the tables.\n * @param snapshot - the snapshot\n * @param common - the resolved common options\n * @param styles - the styles being written, or undefined\n * @returns the plan\n */\nfunction plan(snapshot: GraphSnapshot, common: ResolvedExportOptions, styles?: ExporterStyleOptions[\"styles\"]): Plan {\n const notes: LossNote[] = [];\n const note: NoteFn = (code, message, column = null, count = null) => {\n notes.push(Object.freeze({ code, message, column, count }));\n };\n const generic = checkCapabilities(snapshot, CYS_CAPABILITIES, common, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n positionDtype: \"f64\",\n });\n // json is reported per column below; ids by the SUID rule (positive integers)\n notes.push(...generic.filter((gen) => !SESSION_OWN_CODES.has(gen.code)));\n\n const ids = planIds(snapshot, common, note);\n const { nodeSuids, edgeSuids, mangled, fatal } = ids;\n let { next } = ids;\n const rootSuid = next++;\n const subSuid = next++;\n\n // direction\n const folding = pairFolding(snapshot);\n noteMutualPairs(folding.mutualCount, note);\n\n // positions\n const position = snapshot.nodes.byRole(\"position\");\n const z = [...snapshot.nodes].find(isZ) ?? null;\n const positionZ = position !== null && z === null;\n if (position !== null) {\n positionNotes(position, z, note);\n }\n const placed = holdsValues(position) || holdsValues(z);\n const emitNotes = new StyleNotes();\n const styled =\n styles === undefined\n ? null\n : emitCytoscapeStyle(styles.rules, snapshot, { dialect: \"desktop\", notes: emitNotes });\n // written with styles, the graphics an XGMML or session import kept are the view's to say, from the styles\n const superseded = (c: Column): boolean => styled !== null && isKeptGraphics(c);\n // a styled session always has a view: the view names the style and holds the bypasses\n const viewSuid = placed || styled !== null ? next++ : null;\n const viewNodeBase = next;\n\n // node table\n const nodeOwn = mangled ? [originalIdCandidate(snapshot)] : [];\n const nodeTable = planTable(\n \"node\",\n [\n ...elementCandidates(snapshot, \"node\", nodeOwn, (c) => (placed && c === z) || superseded(c), note),\n ...(styled === null ? [] : addedCandidates(snapshot.nodes, styled.columns.node)),\n ],\n snapshot.nodeCount,\n note,\n );\n\n // edge table\n const edgeOwn = weightCandidates(snapshot, note);\n const edgeRows = snapshot.edgeCount;\n const edgeTable = planTable(\n \"edge\",\n [\n ...elementCandidates(snapshot, \"edge\", edgeOwn, superseded, note),\n ...(styled === null ? [] : addedCandidates(snapshot.edges, styled.columns.edge)),\n ],\n edgeRows,\n note,\n );\n\n const name = snapshot.meta.name ?? DEFAULT_NAME;\n const networkTable = planTable(\"network\", networkCandidates(snapshot, name), 1, note);\n const rootTable: TableColumn[] = [{ name: \"name\", javaClass: STRING, cell: () => name }];\n const inlineBlock = styles === undefined ? null : writeStyleBlock(styles.rules, { inlineColumns: true, snapshot });\n const blockNotes =\n inlineBlock === null ? [] : styleBlockLosses(inlineBlock, styles?.rules.styles.rules.length ?? 0, \"size\");\n return {\n notes,\n fatal,\n nodeSuids,\n edgeSuids,\n rootSuid,\n subSuid,\n viewSuid,\n viewNodeBase,\n name,\n folding,\n nodeTable,\n edgeTable,\n networkTable,\n rootTable,\n position,\n z: placed ? z : null,\n positionZ,\n styled,\n styleNotes: [...emitNotes.list().map(lossOf), ...blockNotes],\n block: styles === undefined ? snapshotBlock(snapshot) : inlineBlock,\n };\n}\n\n/** The generic notes a session export reports itself: json per column, ids by the SUID rule (positive integers). */\nconst SESSION_OWN_CODES: ReadonlySet<string> = new Set([LOSS.JSON, LOSS.ID_CHARSET, LOSS.ID_MANGLED]);\n\n/**\n * MUTUAL_EXPANDED for the mutual pairs written as two directed edges.\n * @param mutualCount - how many mutual pairs\n * @param note - the recorder\n */\nfunction noteMutualPairs(mutualCount: number, note: NoteFn): void {\n if (mutualCount > 0) {\n note(\n LOSS.MUTUAL_EXPANDED,\n `${mutualCount} mutual pair${plural(mutualCount)} ${agree(mutualCount, \"is\", \"are\")} written as two directed edges; the mutual mark is lost`,\n null,\n mutualCount,\n );\n }\n}\n\n/**\n * Whether a column holds any value.\n * @param column - the column, or null\n * @returns false for null or an empty column\n */\nfunction holdsValues(column: Column | null): boolean {\n return column !== null && column.nullCount < column.length;\n}\n\n/**\n * Whether a column is the graphics an XGMML or session import kept.\n * @param c - the column\n * @returns true for kept graphics\n */\nfunction isKeptGraphics(c: Column): boolean {\n return (\n c.dtype === \"json\" && c.meta.origin?.type === \"graphics\" && c.meta.origin.namespace === XGMML_ORIGIN_NAMESPACE\n );\n}\n\n/**\n * The node column of original ids, for ids written as SUIDs.\n * @param snapshot - the snapshot\n * @returns the candidate\n */\nfunction originalIdCandidate(snapshot: GraphSnapshot): Candidate {\n return {\n name: ORIGINAL_ID_ATTRIBUTE,\n source: null,\n javaClass: STRING,\n // every node carries its original, so an empty id (\"\") is told apart from an unset cell\n cell: (row) => String(snapshot.ids.idOf(row)),\n };\n}\n\n/**\n * The edge weight column, when the graph is weighted, and WEIGHT_KEY_CLASH for a plain column named weight.\n * @param snapshot - the snapshot\n * @param note - the recorder\n * @returns the candidates\n */\nfunction weightCandidates(snapshot: GraphSnapshot, note: NoteFn): Candidate[] {\n const weights: ExplicitWeights = explicitWeights(snapshot);\n const plainWeight = snapshot.edges.get(\"weight\");\n if (plainWeight !== null && plainWeight.meta.role === null && !weights.weighted) {\n note(LOSS.WEIGHT_KEY_CLASH, `edge column \"weight\" reads back as the edge weight`, \"weight\", null);\n }\n if (!weights.weighted) {\n return [];\n }\n return [\n {\n name: \"weight\",\n source: null,\n javaClass: DOUBLE,\n cell: (e) => (weights.isExplicit(e) ? formatDecimal(weights.value(e)) : null),\n },\n ];\n}\n\n/**\n * The notes of the position column: its shape, non-finite coordinates, and a z that reads back\n * in the z column.\n * @param position - the position column\n * @param z - the z column, or null\n * @param note - the recorder\n */\nfunction positionNotes(position: Column, z: Column | null, note: NoteFn): void {\n const { name, components } = position.meta;\n if (components !== 3) {\n note(\n CYS_LOSS.POSITION,\n `position column \"${name}\" has ${components} component${plural(components)} and reads back with 3`,\n name,\n null,\n );\n }\n let nonFinite = 0;\n let depth = 0;\n for (let r = 0; r < position.length; r++) {\n if (!position.isSet(r)) {\n continue;\n }\n const xyz = Array.from(position.value(r) as ArrayLike<number>);\n if (xyz.slice(0, 2).some((v) => !Number.isFinite(v))) {\n nonFinite++;\n } else if ((xyz[2] ?? 0) !== 0) {\n depth++;\n }\n }\n if (nonFinite > 0) {\n note(\n CYS_LOSS.POSITION,\n `${nonFinite} position${plural(nonFinite)} with a non-finite coordinate ${agree(nonFinite, \"is\", \"are\")} not written`,\n name,\n nonFinite,\n );\n }\n if (depth > 0) {\n note(\n CYS_LOSS.POSITION,\n z === null\n ? `${depth} position${plural(depth)} ${agree(depth, \"has\", \"have\")} a z; it is written as the view's z and reads back in the z column`\n : `${depth} position${plural(depth)} ${agree(depth, \"has\", \"have\")} a z, but the view's z holds the z column; the position z is lost`,\n name,\n depth,\n );\n }\n}\n\n// ============================================================ writing\n\n/**\n * Cytoscape's `SessionUtil.escape`: Java's `URLEncoder.encode(text, \"UTF-8\")` (letters, digits\n * and `.-*_` kept, space as `+`, everything else `%XX`), then `-` as `%2D`.\n * @param text - the text\n * @returns the escaped text\n * @category Plugin helpers\n */\nexport function sessionEscape(text: string): string {\n const wellFormed = text.replaceAll(/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g, \"�\");\n return encodeURIComponent(wellFormed)\n .replaceAll(/[!~'()]/g, (c) => `%${(c.codePointAt(0) ?? 0).toString(16).toUpperCase()}`)\n .replaceAll(\"%20\", \"+\")\n .replaceAll(\"-\", \"%2D\");\n}\n\n/**\n * One CyCSV table (schema version 1): the key column SUID, then the columns.\n * @param title - the table title\n * @param columns - the columns\n * @param rows - the SUID of each row, with its row index\n * @yields the table text\n * @returns nothing\n */\nfunction* cyTable(\n title: string,\n columns: readonly TableColumn[],\n rows: Iterable<readonly [number, number]>,\n): Generator<string, void, undefined> {\n // null is an unquoted empty cell: no value, where `\"\"` is the empty string\n const line = (cells: readonly (string | null)[]): string =>\n `${cells.map((c) => (c === null ? \"\" : quoteCsvCell(c))).join(\",\")}\\n`;\n yield line([\"CyCSV-Version\", \"1\"]);\n yield line([\"SUID\", ...columns.map((c) => c.name)]);\n yield line([LONG, ...columns.map((c) => c.javaClass)]);\n yield line([\"\", ...columns.map(() => \"mutable\")]);\n yield line([title, \"\"]);\n for (const [suid, row] of rows) {\n // a graphty style column tells an element without a value from one whose value is the empty string\n yield line([\n String(suid),\n ...columns.map((c) => c.cell(row) ?? (c.name.startsWith(STYLE_COLUMN_PREFIX) ? null : \"\")),\n ]);\n }\n}\n\n/** The XML declaration and the namespaces of a session XGMML document. */\nconst XML_DECLARATION = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\nconst NAMESPACES = `xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:xlink=\"${XLINK_NAMESPACE}\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:cy=\"${CY_NAMESPACE}\" xmlns=\"${XGMML_NAMESPACE}\"`;\n\n/**\n * The network file: the root network holding the one registered subnetwork, nodes and edges by\n * SUID. No attributes: a 3.x session keeps them in the tables.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @yields the document's text\n * @returns nothing\n */\nfunction* networkFile(snapshot: GraphSnapshot, p: Plan): Generator<string, void, undefined> {\n const label = !hasIllegalXmlChar(p.name) ? ` label=\"${escapeXmlAttribute(p.name)}\"` : \"\";\n yield XML_DECLARATION;\n yield `<graph id=\"${p.rootSuid}\"${label} directed=\"${snapshot.directed ? \"1\" : \"0\"}\" cy:view=\"0\" cy:registered=\"0\" cy:documentVersion=\"3.0\" ${NAMESPACES}>\\n`;\n yield ` <att>\\n <graph id=\"${p.subSuid}\"${label} cy:registered=\"1\">\\n`;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n yield ` <node id=\"${p.nodeSuids[i]}\"/>\\n`;\n }\n const { src, dst } = snapshot.edgeList();\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (p.folding.folded(e)) {\n continue;\n }\n const directed = snapshot.directed && p.folding.sourceDirected(e);\n yield ` <edge id=\"${p.edgeSuids[e]}\" source=\"${p.nodeSuids[src[e]]}\" target=\"${p.nodeSuids[dst[e]]}\" cy:directed=\"${directed ? \"1\" : \"0\"}\"/>\\n`;\n }\n yield \" </graph>\\n </att>\\n</graph>\\n\";\n}\n\n/**\n * The view file: one view node per placed node, x and y (y negated back to screen coordinates)\n * and z.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @param viewSuid - the view's SUID\n * @yields the document's text\n * @returns nothing\n */\nfunction* viewFile(snapshot: GraphSnapshot, p: Plan, viewSuid: number): Generator<string, void, undefined> {\n const style = p.styled === null ? \"default\" : p.name;\n yield XML_DECLARATION;\n yield `<graph id=\"${viewSuid}\" label=\"${viewSuid}\" cy:view=\"1\" cy:networkId=\"${p.subSuid}\" cy:visualStyle=\"${escapeXmlAttribute(style)}\" cy:rendererId=\"org.cytoscape.ding\" cy:documentVersion=\"3.0\" ${NAMESPACES}>\\n`;\n let view = p.viewNodeBase;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const coords = viewCoords(p, i);\n const locked = p.styled?.bypasses.node[i] ?? null;\n if (coords.length > 0 || locked !== null) {\n yield ` <node id=\"${view++}\" cy:nodeId=\"${p.nodeSuids[i]}\">\\n`;\n yield* viewGraphics(coords, locked);\n yield \" </node>\\n\";\n }\n }\n for (let e = 0; e < snapshot.edgeCount; e++) {\n const locked = p.styled?.bypasses.edge[e] ?? null;\n if (locked !== null && !p.folding.folded(e)) {\n yield ` <edge id=\"${view++}\" cy:edgeId=\"${p.edgeSuids[e]}\">\\n`;\n yield* viewGraphics([], locked);\n yield \" </edge>\\n\";\n }\n }\n yield \"</graph>\\n\";\n}\n\n/**\n * One view element's graphics: its coordinates, and its bypasses as `lockedVisualProperties`.\n * @param coords - the coordinate attributes\n * @param locked - the bypasses, or null\n * @yields the graphics element\n * @returns nothing\n */\nfunction* viewGraphics(coords: readonly string[], locked: ReadonlyMap<string, unknown> | null): Generator<string> {\n const head = coords.length === 0 ? \" <graphics\" : ` <graphics ${coords.join(\" \")}`;\n if (locked === null) {\n yield `${head}/>\\n`;\n return;\n }\n yield `${head}>\\n <att name=\"lockedVisualProperties\">\\n`;\n for (const [vp, value] of locked) {\n yield ` <att name=\"${escapeXmlAttribute(vp)}\" value=\"${escapeXmlAttribute(String(value))}\" type=\"string\" cy:type=\"String\"/>\\n`;\n }\n yield \" </att>\\n </graphics>\\n\";\n}\n\n/**\n * The graphics attributes of one node's view: x and y (y down, as Cytoscape draws), and z.\n * @param p - the plan\n * @param i - the node\n * @returns the attributes, none when the node has no position\n */\nfunction viewCoords(p: Plan, i: number): string[] {\n const coords: string[] = [];\n if (p.position?.isSet(i) === true) {\n const [x, y, z] = Array.from(p.position.value(i) as ArrayLike<number>);\n const fmt = p.position.dtype === \"f32\" ? formatF32 : formatF64;\n if (Number.isFinite(x) && Number.isFinite(y)) {\n coords.push(`x=\"${fmt(x)}\"`, `y=\"${fmt(y === 0 ? 0 : -y)}\"`);\n }\n if (\n Number.isFinite(x) &&\n Number.isFinite(y) &&\n p.positionZ &&\n z !== undefined &&\n z !== 0 &&\n Number.isFinite(z)\n ) {\n coords.push(`z=\"${fmt(z)}\"`);\n }\n }\n if (p.z?.isSet(i) === true) {\n coords.push(`z=\"${formatDecimal(p.z.value(i) as number)}\"`);\n }\n return coords;\n}\n\n/**\n * The text of string parts, UTF-8 encoded.\n * @param parts - the parts\n * @returns the bytes\n */\nfunction encode(parts: Iterable<string>): Uint8Array {\n let text = \"\";\n for (const part of parts) {\n text += part;\n }\n return new TextEncoder().encode(text);\n}\n\n/**\n * The archive's entries, each built when the zip writer asks for it.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @yields the entries\n * @returns nothing\n */\nfunction* entries(snapshot: GraphSnapshot, p: Plan): Generator<ZipWriteEntry, void, undefined> {\n if (p.fatal !== null) {\n throw p.fatal;\n }\n const name = sessionEscape(p.name);\n const tables = `${ROOT_FOLDER}tables/${p.subSuid}-${name}/LOCAL_ATTRS-org.cytoscape.model.`;\n const rowsOf = (suids: readonly number[], skip?: (row: number) => boolean): [number, number][] =>\n suids.flatMap((suid, row) => (skip?.(row) === true ? [] : [[suid, row] as [number, number]]));\n const nodeTable = `${p.name} default node`;\n const edgeTable = `${p.name} default edge`;\n const networkTable = `${p.name} default network`;\n yield { name: `${ROOT_FOLDER}3.0.0.version`, data: new Uint8Array(0) };\n yield { name: `${ROOT_FOLDER}networks/${p.rootSuid}-${name}.xgmml`, data: encode(networkFile(snapshot, p)) };\n yield {\n name: `${tables}CyNode-${sessionEscape(nodeTable)}.cytable`,\n data: encode(cyTable(nodeTable, p.nodeTable, rowsOf(p.nodeSuids))),\n };\n yield {\n name: `${tables}CyEdge-${sessionEscape(edgeTable)}.cytable`,\n data: encode(\n cyTable(\n edgeTable,\n p.edgeTable,\n rowsOf(p.edgeSuids, (e) => p.folding.folded(e)),\n ),\n ),\n };\n yield {\n name: `${tables}CyNetwork-${sessionEscape(networkTable)}.cytable`,\n data: encode(cyTable(networkTable, p.networkTable, [[p.subSuid, 0]])),\n };\n yield {\n name: `${ROOT_FOLDER}tables/${p.rootSuid}-${name}/LOCAL_ATTRS-org.cytoscape.model.CyNetwork-${p.rootSuid}+default+network.cytable`,\n data: encode(cyTable(`${p.rootSuid} default network`, p.rootTable, [[p.rootSuid, 0]])),\n };\n if (p.viewSuid !== null) {\n yield {\n name: `${ROOT_FOLDER}views/${p.subSuid}-${p.viewSuid}-${name}.xgmml`,\n data: encode(viewFile(snapshot, p, p.viewSuid)),\n };\n }\n if (p.styled !== null) {\n yield {\n name: `${ROOT_FOLDER}session_vizmap.xml`,\n data: encode([\n XML_DECLARATION,\n '<vizmap documentVersion=\"3.0\" id=\"VizMap-graphty\">\\n',\n cytoscapeVizmapXml(p.styled.style, p.name),\n \"\\n</vizmap>\\n\",\n ]),\n };\n }\n if (p.block !== null) {\n yield { name: `${ROOT_FOLDER}${STYLE_BLOCK_NAME}`, data: new TextEncoder().encode(p.block) };\n }\n}\n\n/**\n * The archive as byte chunks.\n * @param snapshot - the snapshot\n * @param options - the options\n * @yields the bytes\n * @returns nothing\n */\nasync function* write(\n snapshot: GraphSnapshot,\n options: (CysExportOptions & ExporterStyleOptions) | undefined,\n): AsyncGenerator<Uint8Array, void, undefined> {\n const p = plan(snapshot, resolveExportOptions(options), options?.styles);\n await Promise.resolve();\n yield* writeZip(entries(snapshot, p));\n}\n\n/**\n * The Cytoscape session exporter.\n * @category Built-in formats\n */\nexport const cysExporter: GraphExporter<CysExportOptions> = Object.freeze({\n format: FORMAT,\n options: Object.freeze([]),\n capabilities: CYS_CAPABILITIES,\n styles: Object.freeze({ capabilities: CYS_STYLE_CAPABILITIES }),\n\n /**\n * Pre-flight: what export() would lose, without writing anything.\n * @param snapshot - the snapshot\n * @param options - the common options\n * @returns the notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: CysExportOptions & ExporterStyleOptions): readonly LossNote[] {\n const p = plan(snapshot, resolveExportOptions(options), options?.styles);\n return Object.freeze([...p.notes, ...p.styleNotes]);\n },\n\n /**\n * Write the session as zip bytes (stored entries, one at a time).\n * @param snapshot - the snapshot\n * @param options - the common options\n * @returns the bytes\n */\n export(snapshot: GraphSnapshot, options?: CysExportOptions): AsyncIterable<Uint8Array> {\n return write(snapshot, options);\n },\n\n /**\n * A session is a zip archive, not text: always rejects with E_UNSUPPORTED (use exportGraphToBytes() or exportGraphToBlob()).\n * @returns never\n */\n exportToString(): Promise<string> {\n return Promise.reject(\n new GraphFormatError(\n \"E_UNSUPPORTED\",\n \"a Cytoscape session is a zip file, not text; use exportGraphToBytes() or exportGraphToBlob()\",\n { reason: \"binary\" },\n ),\n );\n },\n});\n","/**\n * The layout of a Cytoscape session archive (`research-session-and-style.md` sections 2.1 to 2.3;\n * Cytoscape's `Cy3SessionReaderImpl`, `Cy2SessionReaderImpl` and `SessionUtil`): which entries\n * are the version marker, the networks, views, tables, styles and the rest, read from the central\n * directory alone. Entries are inflated one at a time, only when asked for, within the import's\n * byte budget.\n */\n\nimport { readBytes, textChunks } from \"../../common/input.js\";\nimport { type ResolvedImportOptions } from \"../../common/options.js\";\nimport { plural } from \"../../common/plural.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { tokenizeXml, xmlDeclaredEncoding, XmlSyntaxError } from \"../../common/xml.js\";\nimport { readZipDirectory, readZipEntry, type ZipEntry, ZipError } from \"../../common/zip.js\";\nimport { STYLE_BLOCK_NAME } from \"../../styles/io/block.js\";\nimport { ImportError, type ImportInput } from \"../../types.js\";\nimport { CYS_ISSUE, FORMAT, MAX_RATIO } from \"./constants.js\";\n\n/**\n * An entry of the session, by its path under the session's root folder.\n * @category Plugin helpers\n */\nexport interface SessionEntry {\n /** The path under the root folder, as the archive spells it (URL-encoded parts). */\n readonly path: string;\n /** The full entry name, for messages. */\n readonly name: string;\n /** The zip entry. */\n readonly zip: ZipEntry;\n}\n\n/**\n * A 3.x network file: one root network (a collection).\n * @category Plugin helpers\n */\nexport interface NetworkEntry extends SessionEntry {\n /** The root network's saved SUID. */\n readonly suid: string;\n /** The file name's network name, decoded. */\n readonly title: string;\n}\n\n/** A 3.x view file. */\ninterface ViewEntry extends SessionEntry {\n /** The SUID of the network the view shows. */\n readonly network: string;\n /** The view's SUID. */\n readonly view: string;\n}\n\n/**\n * A 3.x table file.\n * @category Plugin helpers\n */\nexport interface TableEntry extends SessionEntry {\n /** The path under `tables/` (what `cytables.xml` names). */\n readonly tablePath: string;\n /** The SUID of the network the table belongs to. */\n readonly network: string;\n /** The namespace: LOCAL_ATTRS, SHARED_ATTRS, HIDDEN or an app's. */\n readonly namespace: string;\n /** The element class: CyNode, CyEdge or CyNetwork. */\n readonly element: \"node\" | \"edge\" | \"network\" | null;\n}\n\n/** What a session archive holds, by kind. */\ninterface SessionLayout {\n /** \"3\" for a 3.x session, \"2\" for a 2.x one. */\n readonly era: \"2\" | \"3\";\n /** The version marker as written (`3.0.0`), or the 2.x cysession.xml documentVersion. */\n readonly version: string;\n /** The root folder, with its trailing slash (\"\" when the entries have none). */\n readonly root: string;\n readonly networks: readonly NetworkEntry[];\n readonly views: readonly ViewEntry[];\n readonly tables: readonly TableEntry[];\n /** `tables/cytables.xml`, if present. */\n readonly cytables: SessionEntry | null;\n /** `apps/org.cytoscape.swing-application/network_list.xml`, if present. */\n readonly networkList: SessionEntry | null;\n /** 2.x: `cysession.xml`. */\n readonly cysession: SessionEntry | null;\n /** 2.x: the network files by their path. */\n readonly files: ReadonlyMap<string, SessionEntry>;\n /** The style entries (`session_vizmap.xml`, `session_vizmap.props`). */\n readonly styles: readonly SessionEntry[];\n /** 3.x: the `graphty.styles` entry a session graphty wrote holds, if present. */\n readonly block: SessionEntry | null;\n /** Every entry the importer does not read. */\n readonly skipped: readonly string[];\n}\n\n/**\n * An opened session: its bytes, its layout and an entry reader within the byte budget.\n * @category Plugin helpers\n */\nexport interface Session {\n readonly layout: SessionLayout;\n /**\n * Inflate one entry. Each entry counts against the byte budget and the progress once, however\n * often it is read.\n * @param entry - the entry\n * @param report - the report a damaged or over-budget entry fails (the network being imported)\n * @returns its bytes\n */\n read(entry: SessionEntry, report: ImportReportBuilder): Promise<Uint8Array>;\n /** Report the progress complete: the import has read everything it needs. */\n done(): void;\n}\n\n/**\n * Java's `URLDecoder.decode` (UTF-8): `+` is a space, `%XX` a byte; a malformed escape leaves the\n * text as it is.\n * @param text - the encoded text\n * @returns the decoded text\n * @category Plugin helpers\n */\nexport function urlDecode(text: string): string {\n const plus = text.replaceAll(\"+\", \" \");\n try {\n return decodeURIComponent(plus);\n } catch {\n return plus;\n }\n}\n\n/**\n * Read the input as a zip and lay out its session entries. Fatal: text input or not a zip\n * (E_CYS_NOT_ZIP), an empty input, a damaged archive (E_CYS_CORRUPT), a split archive\n * (E_CYS_UNSUPPORTED), no session marker (E_CYS_NOT_SESSION), a version graph-io cannot read\n * (E_CYS_VERSION).\n * @param input - the input\n * @param report - the report\n * @param common - cancellation and progress\n * @param maxBytes - the import's uncompressed byte budget\n * @returns the session\n */\nexport async function openSession(\n input: ImportInput,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n maxBytes: number,\n): Promise<Session> {\n const bytes = await readBytes(input, common);\n if (bytes === null) {\n report.fail(\n CYS_ISSUE.NOT_ZIP,\n \"a Cytoscape session is a zip archive; text input cannot hold one (pass the bytes)\",\n );\n }\n if (bytes.byteLength === 0) {\n report.fail(CYS_ISSUE.EMPTY_INPUT, \"the input is empty\");\n }\n let zipEntries: ZipEntry[];\n try {\n zipEntries = readZipDirectory(bytes);\n } catch (err) {\n return zipFailure(err, report);\n }\n const layout = layoutOf(zipEntries, report);\n let budget = maxBytes;\n let inflated = 0;\n // the progress total: the entries the importer may read, not images and app files\n const total = [\n ...layout.networks,\n ...layout.views,\n ...layout.tables,\n ...layout.files.values(),\n ...[layout.cytables, layout.networkList, layout.cysession].filter((e) => e !== null),\n ].reduce((sum, e) => sum + e.zip.size, 0);\n const charged = new Set<string>();\n return {\n layout,\n read: async (entry: SessionEntry, into: ImportReportBuilder): Promise<Uint8Array> => {\n const first = !charged.has(entry.name);\n const before = inflated;\n try {\n const data = await readZipEntry(bytes, entry.zip, {\n signal: common.signal,\n maxBytes: first ? budget : entry.zip.size,\n maxRatio: MAX_RATIO,\n onBytes: first ? (n): void => common.onProgress?.(Math.min(before + n, total), total) : undefined,\n });\n if (first) {\n charged.add(entry.name);\n budget -= data.byteLength;\n inflated += data.byteLength;\n }\n return data;\n } catch (err) {\n return zipFailure(err, into);\n }\n },\n done: (): void => {\n common.onProgress?.(total, total);\n },\n };\n}\n\n/**\n * Fail the import with the fatal issue of a zip error (any other error is rethrown).\n * @param err - the error\n * @param report - the report\n */\nfunction zipFailure(err: unknown, report: ImportReportBuilder): never {\n if (!(err instanceof ZipError)) {\n throw err;\n }\n const code = {\n \"not-zip\": CYS_ISSUE.NOT_ZIP,\n corrupt: CYS_ISSUE.CORRUPT,\n unsupported: CYS_ISSUE.UNSUPPORTED,\n \"too-large\": CYS_ISSUE.TOO_LARGE,\n }[err.kind];\n if (err.kind === \"too-large\") {\n // the size limits are not a parse error: graph-io records E_TOO_LARGE as unsupported\n report.error(\"unsupported\", code, err.message);\n throw report.abort(err.message, { code });\n }\n report.fail(code, err.message);\n}\n\n/**\n * The session marker of the archive: the shallowest entry whose name ends in `.version` (a\n * session re-zipped inside another folder keeps its layout one level down), else null.\n * @param names - the entry names\n * @param suffix - the marker's file name pattern\n * @returns the names of the shallowest such entries, in directory order\n */\nfunction shallowest(names: readonly string[], suffix: RegExp): string[] {\n const depth = (name: string): number => name.split(\"/\").length;\n const found = names.filter((n) => suffix.test(n));\n const least = Math.min(...found.map(depth));\n return found.filter((n) => depth(n) === least);\n}\n\n/** A 3.x network entry name: `<SUID>[-<name>].xgmml`. */\nconst NETWORK_FILE = /^networks\\/(\\d+)(?:-([^/]*))?\\.xgmml$/;\n/** A 3.x view entry name: `<networkSUID>-<viewSUID>[-<title>].xgmml`. */\nconst VIEW_FILE = /^views\\/(\\d+)-(\\d+)(?:-[^/]*)?\\.xgmml$/;\n/** A 3.x table: `tables/<networkSUID>[-<name>]/<namespace>-<class>-<title>.cytable`. */\nconst TABLE_FILE = /^tables\\/((\\d+)(?:-[^/]*)?\\/([^/-]+)-([^/-]+)-[^/]*\\.cytable)$/;\n\n/** Entries of other tools that carry nothing: macOS resource forks and folder metadata. */\nconst NOISE = /(^|\\/)(__MACOSX\\/|\\.DS_Store$)/;\n\n/**\n * Lay out the entries: drop directory entries and macOS noise, keep the first of a repeated name\n * (W_CYS_DUPLICATE_ENTRY), find the session marker and its root folder, classify what is under\n * it, and list what is not read.\n * @param zipEntries - the central directory\n * @param report - the report\n * @returns the layout\n */\nfunction layoutOf(zipEntries: readonly ZipEntry[], report: ImportReportBuilder): SessionLayout {\n const byName = new Map<string, ZipEntry>();\n const repeated: string[] = [];\n for (const entry of zipEntries) {\n // a Windows tool may write backslashes, which APPNOTE 4.4.17 forbids: read them as \"/\"\n const name = entry.name.replaceAll(\"\\\\\", \"/\");\n if (name.endsWith(\"/\") || NOISE.test(name)) {\n continue;\n }\n if (byName.has(name)) {\n repeated.push(name);\n continue;\n }\n byName.set(name, entry);\n }\n if (repeated.length > 0) {\n report.warning(\n \"unsupported\",\n CYS_ISSUE.DUPLICATE_ENTRY,\n `${repeated.length} entry name${plural(repeated.length)} appear more than once; the first of each is read: ${listed(repeated)}`,\n );\n }\n const names = [...byName.keys()];\n const markers = shallowest(names, /(^|\\/)[^/]+\\.version$/);\n const marker = markers.at(0);\n const cysession = shallowest(names, /(^|\\/)cysession\\.xml$/).at(0);\n if (markers.length > 1) {\n report.warning(\n \"validation-error\",\n CYS_ISSUE.ENTRY_SKIPPED,\n `the session has ${markers.length} version markers (${listed(markers)}); ${markers[0]} is used and the others are not read`,\n );\n }\n const anchor = marker ?? cysession;\n if (anchor === undefined) {\n report.fail(\n CYS_ISSUE.NOT_SESSION,\n \"the zip holds neither a session version marker (<x.y.z>.version) nor cysession.xml: it is not a Cytoscape session\",\n );\n }\n const root = anchor.slice(0, anchor.lastIndexOf(\"/\") + 1);\n let era: \"2\" | \"3\" = \"2\";\n let version = \"2.0.0\";\n if (marker !== undefined) {\n version = marker.slice(root.length, -\".version\".length);\n if (!/^\\d+(\\.\\d+)*$/.test(version)) {\n report.fail(\n CYS_ISSUE.VERSION,\n `the session version marker ${marker} does not parse as a version (<major>.<minor>.<patch>.version)`,\n );\n }\n const major = Number(version.split(\".\")[0]);\n if (major > 3) {\n report.fail(\n CYS_ISSUE.VERSION,\n `the session version ${version} is newer than the Cytoscape 3 sessions graph-io reads`,\n );\n }\n era = major === 3 ? \"3\" : \"2\";\n }\n const layout = {\n era,\n version,\n root,\n networks: [] as NetworkEntry[],\n views: [] as ViewEntry[],\n tables: [] as TableEntry[],\n cytables: null as SessionEntry | null,\n networkList: null as SessionEntry | null,\n cysession: null as SessionEntry | null,\n files: new Map<string, SessionEntry>(),\n styles: [] as SessionEntry[],\n block: null as SessionEntry | null,\n skipped: [] as string[],\n };\n for (const [name, zip] of byName) {\n if (!name.startsWith(root) || name === marker) {\n if (name !== marker && !markers.includes(name)) {\n layout.skipped.push(name);\n }\n continue;\n }\n const path = name.slice(root.length);\n const entry: SessionEntry = { path, name, zip };\n if (era === \"3\") {\n classify3(entry, layout);\n } else {\n classify2(entry, layout);\n }\n }\n return layout;\n}\n\n/**\n * Classify one entry of a 3.x session.\n * @param entry - the entry\n * @param layout - the layout being built\n */\nfunction classify3(entry: SessionEntry, layout: Mutable): void {\n const { path } = entry;\n const network = NETWORK_FILE.exec(path);\n const view = VIEW_FILE.exec(path);\n const table = TABLE_FILE.exec(path);\n if (network !== null) {\n layout.networks.push({ ...entry, suid: network[1], title: urlDecode(network[2] ?? \"\") });\n } else if (view !== null) {\n layout.views.push({ ...entry, network: view[1], view: view[2] });\n } else if (path === \"tables/cytables.xml\") {\n layout.cytables = entry;\n } else if (table !== null) {\n const element = {\n \"org.cytoscape.model.CyNode\": \"node\",\n \"org.cytoscape.model.CyEdge\": \"edge\",\n \"org.cytoscape.model.CyNetwork\": \"network\",\n }[urlDecode(table[4])] as TableEntry[\"element\"] | undefined;\n if (element === undefined) {\n // a table of an element class graph-io has no model for\n layout.skipped.push(entry.name);\n return;\n }\n layout.tables.push({\n ...entry,\n tablePath: table[1],\n network: table[2],\n namespace: urlDecode(table[3]),\n element,\n });\n } else if (path === \"apps/org.cytoscape.swing-application/network_list.xml\") {\n layout.networkList = entry;\n } else if (/(^|\\/)session_vizmap\\.(xml|props)$/.test(path)) {\n layout.styles.push(entry);\n } else if (path === STYLE_BLOCK_NAME) {\n layout.block = entry;\n } else {\n layout.skipped.push(entry.name);\n }\n}\n\n/**\n * Classify one entry of a 2.x session.\n * @param entry - the entry\n * @param layout - the layout being built\n */\nfunction classify2(entry: SessionEntry, layout: Mutable): void {\n const { path } = entry;\n if (path === \"cysession.xml\") {\n layout.cysession = entry;\n } else if (/^[^/]+\\.xgmml$/.test(path)) {\n layout.files.set(path, entry);\n } else if (/^session_vizmap\\.(props|xml)$/.test(path)) {\n layout.styles.push(entry);\n } else {\n layout.skipped.push(entry.name);\n }\n}\n\n/** The layout while it is built. */\ntype Mutable = {\n -readonly [K in keyof SessionLayout]: SessionLayout[K] extends readonly (infer T)[] ? T[] : SessionLayout[K];\n} & { files: Map<string, SessionEntry> };\n\n/**\n * A list of names for a message: the first ten, then a count.\n * @param names - the names\n * @returns the text\n * @category Plugin helpers\n */\nexport function listed(names: readonly string[]): string {\n const head = names.slice(0, 10).map(entryLabel).join(\", \");\n return names.length > 10 ? `${head} and ${names.length - 10} more` : head;\n}\n\n/**\n * An entry name as a message shows it: without the session folder every entry sits in\n * (`CytoscapeSession-2026_10_02-12_00/networks/10-Collection.xgmml` is `networks/10-Collection.xgmml`).\n * @param name - the zip entry name\n * @returns the name inside the session\n */\nexport function entryLabel(name: string): string {\n return name.replace(/^[^/]*CytoscapeSession[^/]*\\//, \"\");\n}\n\n/**\n * One element of a small XML document, as a tree.\n * @category Plugin helpers\n */\nexport interface XmlNode {\n /** The local name. */\n readonly name: string;\n /** The attributes by name as written (prefix included). */\n readonly attrs: ReadonlyMap<string, string>;\n /** The child elements. */\n readonly children: XmlNode[];\n}\n\n/**\n * Read a small XML entry (`cytables.xml`, `network_list.xml`, `cysession.xml`) as a tree. A\n * document that is not well-formed is E_CYS_CORRUPT naming the entry.\n * @param bytes - the entry's bytes\n * @param entry - the entry name\n * @param report - the report\n * @param common - cancellation\n * @returns the root element\n */\nexport async function readXmlTree(\n bytes: Uint8Array,\n entry: string,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n): Promise<XmlNode> {\n const tree = await parseXmlTree(bytes, entry, report, common);\n return typeof tree === \"string\" ? report.fail(CYS_ISSUE.CORRUPT, `${entry}: ${tree}`) : tree;\n}\n\n/**\n * Read a small XML entry as a tree; its decoding warnings (W_ENCODING_FALLBACK,\n * W_UNKNOWN_ENCODING) go into the report with the entry name.\n * @param bytes - the entry's bytes\n * @param entry - the entry name\n * @param report - the report\n * @param common - cancellation\n * @returns the root element, or why the entry cannot be read\n */\nexport async function parseXmlTree(\n bytes: Uint8Array,\n entry: string,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n): Promise<XmlNode | string> {\n const scratch = new ImportReportBuilder(FORMAT, 0);\n const stack: XmlNode[] = [{ name: \"\", attrs: new Map(), children: [] }];\n try {\n await tokenizeXml(\n textChunks(bytes, scratch, { signal: common.signal, declaredEncoding: xmlDeclaredEncoding, xml: true }),\n {\n start(name, attrs): void {\n const node: XmlNode = { name: name.slice(name.lastIndexOf(\":\") + 1), attrs, children: [] };\n stack[stack.length - 1].children.push(node);\n stack.push(node);\n },\n end(): void {\n stack.pop();\n },\n text(): void {\n // the session documents keep everything in attributes\n },\n },\n );\n } catch (err) {\n if (err instanceof XmlSyntaxError || err instanceof ImportError) {\n return err.message;\n }\n throw err;\n }\n // the decoder's warnings (an encoding fallback, an unknown declared encoding) name the entry\n for (const issue of scratch.issues) {\n if (issue.severity === \"warning\") {\n report.warning(issue.category, issue.code, `${entry}: ${issue.message}`, {\n line: issue.line,\n element: entry,\n });\n }\n }\n const [root] = stack[0].children;\n return root ?? \"the document is empty\";\n}\n\n/**\n * Every element of a tree with a local name, depth first.\n * @param node - the tree\n * @param name - the local name\n * @returns the elements\n * @category Plugin helpers\n */\nexport function elementsNamed(node: XmlNode, name: string): XmlNode[] {\n const out: XmlNode[] = [];\n const stack = [node];\n while (stack.length > 0) {\n const n = stack.pop() as XmlNode;\n if (n.name === name) {\n out.push(n);\n }\n for (let i = n.children.length - 1; i >= 0; i--) {\n stack.push(n.children[i]);\n }\n }\n return out;\n}\n","/**\n * The styles of a Cytoscape session. A 3.x session keeps its named visual styles in `session_vizmap.xml` and each\n * view names the one it uses (`cy:visualStyle`); the view's elements carry only their bypasses\n * (`lockedVisualProperties`). The import reads the style the imported network's view names, resolved the way\n * Cytoscape draws it (bypass over mapping over default), with Cytoscape's renderer fallbacks for what the style\n * leaves unset. A 2.x session's network files carry every element's resolved values, read like XGMML, and its\n * hidden elements come back invisible. The writer emits the graph's styles as a named style, bypasses and columns.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { STYLE_ISSUE } from \"../../styles/codes.js\";\nimport {\n type CytoscapeMapping,\n type CytoscapeStyle,\n emptyCytoscapeStyle,\n typedKey,\n} from \"../../styles/cytoscape/mappings.js\";\nimport { cytoscapeBackground, type CytoscapeElements, resolveCytoscape } from \"../../styles/cytoscape/resolve.js\";\nimport { cytoscapeRules } from \"../../styles/cytoscape/translate.js\";\nimport { StyleNotes } from \"../../styles/notes.js\";\nimport { dataCell } from \"../../styles/plan/resolve.js\";\nimport type { ImporterStyles, ReaderOutput, StyleReadContext, StyleTarget } from \"../../styles/types.js\";\nimport { exactFromBlock, graphicsBypasses, hiddenToVisible, nonEmpty, readXgmmlStyles } from \"../xgmml/styles.js\";\nimport { HIDDEN_COLUMN } from \"./constants.js\";\nimport type { XmlNode } from \"./session.js\";\n\n/**\n * What a session import keeps for its styles (through `report.keepForStyles()`): the era, the parsed\n * `session_vizmap.xml`, the style the imported network's view names, and which network was imported.\n */\nexport interface SessionStyleSource {\n /** \"3\" for a 3.x session, \"2\" for a 2.x one. */\n readonly era: \"2\" | \"3\";\n /** The root element of `session_vizmap.xml`, or null when the session has none or it cannot be read. */\n readonly vizmap: XmlNode | null;\n /** Why `session_vizmap.xml` could not be read, or null. */\n readonly problem: string | null;\n /** The style the imported view names, or null. */\n readonly visualStyle: string | null;\n /** The network the import read: its index among the session's networks, and its name. */\n readonly network: { readonly index: number; readonly name: string | null };\n}\n\n/**\n * The styles of an imported session network.\n * @param snapshot - the network\n * @param context - what the import kept, the budget and the cancel signal\n * @returns the styles\n */\nexport function readSessionStyles(snapshot: GraphSnapshot, context: StyleReadContext): ImporterStyles {\n const kept = context.kept as SessionStyleSource | undefined;\n if (kept?.era === \"2\") {\n return readXgmmlStyles(snapshot, context, { tool: \"cytoscape-fallbacks\", hiddenColumn: HIDDEN_COLUMN });\n }\n const notes = new StyleNotes();\n const style = sessionStyle(kept, notes);\n const out: Record<StyleTarget, ReaderOutput> = { node: { values: {} }, edge: { values: {} } };\n for (const target of [\"node\", \"edge\"] as const) {\n context.signal?.throwIfAborted();\n out[target] = sessionTargetStyles(snapshot, target, style, { notes, budget: context.budget });\n }\n const background = cytoscapeBackground(style, notes);\n return {\n canonical: true,\n dialect: \"cytoscape\",\n tool: \"cytoscape-fallbacks\",\n units: \"px\",\n node: out.node,\n edge: out.edge,\n graph: background === null ? {} : { background },\n notes: notes.list(),\n };\n}\n\n/**\n * The Cytoscape style of a session: its vizmap's, or an empty one with a note saying why there is none.\n * @param kept - what the import kept\n * @param notes - where problems are noted\n * @returns the style\n */\nfunction sessionStyle(kept: SessionStyleSource | undefined, notes: StyleNotes): CytoscapeStyle {\n if (kept?.vizmap === null || kept?.vizmap === undefined) {\n const problem = kept?.problem ?? null;\n notes.add(problem === null ? STYLE_ISSUE.NO_VIZMAP : STYLE_ISSUE.UNREADABLE, null, \"session_vizmap.xml\", {\n sample: problem ?? \"absent\",\n });\n return emptyCytoscapeStyle();\n }\n return cytoscapeStyleFromVizmap(kept.vizmap, kept.visualStyle, notes);\n}\n\n/**\n * The styles of a session's nodes or edges.\n * @param snapshot - the network\n * @param target - nodes or edges\n * @param style - the session's style\n * @param work - where problems are noted, and the work budget\n * @param work.notes - where problems are noted\n * @param work.budget - the work budget\n * @returns the reader output for the target\n */\nfunction sessionTargetStyles(\n snapshot: GraphSnapshot,\n target: StyleTarget,\n style: CytoscapeStyle,\n work: { readonly notes: StyleNotes; readonly budget: StyleReadContext[\"budget\"] },\n): ReaderOutput {\n const { notes } = work;\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n for (const m of style[target].mappings.values()) {\n if (!table.has(m.column)) {\n notes.add(STYLE_ISSUE.MAPPING_COLUMN_MISSING, target, m.column, { sample: m.kind });\n }\n }\n const elements: CytoscapeElements = {\n count: n,\n value: (column, i) => (table.has(column) ? dataCell(table, column, i) : null),\n bypasses: graphicsBypasses(table, target, n, notes),\n };\n const values = resolveCytoscape(target, style, elements, work);\n hiddenToVisible(table, HIDDEN_COLUMN, n, values);\n // a session graphty wrote: a value its style writes as the nearest Cytoscape value is the block's\n exactFromBlock(snapshot, target, values);\n const { rules, columns } = cytoscapeRules(target, style, elements, work);\n return { values: nonEmpty(values), rules, columns };\n}\n\n/**\n * One named style of a `session_vizmap.xml` as a Cytoscape style: the one named `name`, else the first with a\n * `W_STYLE_VIEW_STYLE_MISSING` note; the other styles are noted as `W_STYLE_OTHER_STYLES`.\n * @param root - the `<vizmap>` element\n * @param name - the style the view names, or null\n * @param notes - where problems are noted\n * @returns the style\n */\nfunction cytoscapeStyleFromVizmap(root: XmlNode, name: string | null, notes: StyleNotes): CytoscapeStyle {\n const style = emptyCytoscapeStyle();\n const styles = root.children.filter((c) => c.name === \"visualStyle\");\n let chosen = styles.find((s) => s.attrs.get(\"name\") === name);\n if (chosen === undefined) {\n chosen = styles.at(0);\n if (chosen === undefined) {\n notes.add(STYLE_ISSUE.NO_VIZMAP, null, \"visualStyle\", { sample: \"no visualStyle\" });\n return style;\n }\n notes.add(STYLE_ISSUE.VIEW_STYLE_MISSING, null, \"visualStyle\", { sample: String(name) });\n }\n if (styles.length > 1) {\n notes.add(STYLE_ISSUE.OTHER_STYLES, null, \"visualStyle\", {\n sample: `${styles.length - 1} unused`,\n count: styles.length - 1,\n });\n }\n for (const kind of [\"network\", \"node\", \"edge\"] as const) {\n const section = chosen.children.find((c) => c.name === kind);\n for (const child of section?.children ?? []) {\n readVizmapEntry(style, kind, child);\n }\n }\n return style;\n}\n\n/**\n * One dependency or visual property of a vizmap style section, into the style.\n * @param style - the style being read\n * @param kind - the section\n * @param child - the entry\n */\nfunction readVizmapEntry(style: CytoscapeStyle, kind: \"network\" | \"node\" | \"edge\", child: XmlNode): void {\n const childName = child.attrs.get(\"name\");\n if (childName === undefined) {\n return;\n }\n if (child.name === \"dependency\" && kind !== \"network\") {\n style[kind].dependencies.set(childName, child.attrs.get(\"value\")?.trim().toLowerCase() === \"true\");\n return;\n }\n if (child.name !== \"visualProperty\") {\n return;\n }\n const d = child.attrs.get(\"default\");\n if (d !== undefined) {\n style[kind].defaults.set(childName, d);\n }\n if (kind !== \"network\") {\n const mapping = vizmapMapping(child);\n if (mapping !== null) {\n style[kind].mappings.set(childName, mapping);\n }\n }\n}\n\n/**\n * The mapping of one `<visualProperty>`: a passthrough, discrete or continuous mapping element.\n * @param vp - the element\n * @returns the mapping, or null\n */\nfunction vizmapMapping(vp: XmlNode): CytoscapeMapping | null {\n for (const m of vp.children) {\n const column = m.attrs.get(\"attributeName\");\n if (column === undefined) {\n continue;\n }\n const type = m.attrs.get(\"attributeType\") ?? null;\n if (m.name === \"passthroughMapping\") {\n return { kind: \"passthrough\", column, type };\n }\n if (m.name === \"discreteMapping\") {\n return { kind: \"discrete\", column, type, table: discreteTable(m, type) };\n }\n if (m.name === \"continuousMapping\") {\n return { kind: \"continuous\", column, type, points: continuousPoints(m) };\n }\n }\n return null;\n}\n\n/**\n * The entries of a `<discreteMapping>`.\n * @param m - the element\n * @param type - the attribute type its keys are read as\n * @returns the key and value of each entry\n */\nfunction discreteTable(m: XmlNode, type: string | null): [string | number | boolean, unknown][] {\n const table: [string | number | boolean, unknown][] = [];\n for (const e of m.children) {\n const key = typedKey(e.attrs.get(\"attributeValue\"), type);\n const value = e.attrs.get(\"value\");\n if (e.name === \"discreteMappingEntry\" && key !== null && value !== undefined) {\n table.push([key, value]);\n }\n }\n return table;\n}\n\n/**\n * The points of a `<continuousMapping>`.\n * @param m - the element\n * @returns the points with a finite position\n */\nfunction continuousPoints(\n m: XmlNode,\n): { at: number; below: string | undefined; value: string | undefined; above: string | undefined }[] {\n return m.children\n .filter((p) => p.name === \"continuousMappingPoint\" && Number.isFinite(Number(p.attrs.get(\"attrValue\"))))\n .map((p) => ({\n at: Number(p.attrs.get(\"attrValue\")),\n below: p.attrs.get(\"lesserValue\"),\n value: p.attrs.get(\"equalValue\"),\n above: p.attrs.get(\"greaterValue\"),\n }));\n}\n","/**\n * The tables of a Cytoscape 3 session: the CyCSV `.cytable` files (`research-session-and-style.md`\n * section 2.4; Cytoscape's `CSVCyReader`) and the virtual columns `tables/cytables.xml` joins into\n * them. Cells become XGMML att records, typed by the column's Java class, so the XGMML emitter\n * applies the same column rules (types, widening, equations, hidden columns, renames) to a\n * session's tables as to an XGMML file's atts.\n */\n\nimport { type ResolvedImportOptions } from \"../../common/options.js\";\nimport { plural } from \"../../common/plural.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { ImportError } from \"../../types.js\";\nimport { CsvRecordReader } from \"../csv/records.js\";\nimport { type AttRec } from \"../xgmml/document.js\";\nimport { CYS_ISSUE, FORMAT, STYLE_COLUMN_PREFIX } from \"./constants.js\";\nimport { entryLabel } from \"./session.js\";\n\n/** The Cytoscape type names of the Java classes a CyCSV column can hold. */\nconst JAVA_TYPES: Readonly<Record<string, string>> = {\n \"java.lang.String\": \"String\",\n \"java.lang.Long\": \"Long\",\n \"java.lang.Integer\": \"Integer\",\n \"java.lang.Double\": \"Double\",\n \"java.lang.Boolean\": \"Boolean\",\n};\n\n/** A list column's class: `java.util.List<java.lang.X>`. */\nconst LIST_CLASS = /^java\\.util\\.List<\\s*([\\w.]+)\\s*>$/;\n\n/** One column of a table. */\ninterface CyColumn {\n /** The name. */\n readonly name: string;\n /** The Cytoscape type of a scalar column, or of a list's items. */\n readonly type: string;\n /** A list column. */\n readonly list: boolean;\n}\n\n/**\n * One table, read.\n * @category Plugin helpers\n */\nexport interface CyTable {\n /** The table's path under `tables/` as the archive spells it (what cytables.xml names). */\n readonly path: string;\n /** The entry name, for messages. */\n readonly entry: string;\n /** The columns; the first is the primary key. */\n readonly columns: readonly CyColumn[];\n /** The rows by key text, in file order (the first row of a repeated key). */\n readonly rows: ReadonlyMap<string, readonly string[]>;\n /** The line each row starts on, by key. */\n readonly lines: ReadonlyMap<string, number>;\n /** The cells of each row that are a quoted empty field (`\"\"`), by key; a row without one is absent. */\n readonly quotedEmpty?: ReadonlyMap<string, ReadonlySet<number>>;\n}\n\n/** What a table read reports besides its rows. */\ninterface RowProblems {\n short: number;\n long: number;\n repeated: number;\n}\n\n/** One CSV record of a table: its cells, its line, and the cells written as a quoted empty string. */\ninterface TableRecord {\n readonly cells: string[];\n readonly line: number;\n readonly quotedEmpty?: Set<number>;\n}\n\n/** The rows of a table, by key. */\ninterface TableRows {\n readonly rows: Map<string, readonly string[]>;\n readonly lines: Map<string, number>;\n readonly quotedEmpty: Map<string, ReadonlySet<number>>;\n readonly problems: RowProblems;\n}\n\n/**\n * Read one CyCSV table. A table that cannot be read at all (an unknown CyCSV version or column\n * class, a malformed header, broken CSV) is recorded as E_CYS_TABLE and skipped (null); rows with\n * the wrong number of cells or a repeated key are counted in one W_CYS_TABLE_ROW.\n * @param bytes - the entry's bytes\n * @param path - the table's path under `tables/`\n * @param entry - the entry name, for messages\n * @param report - the import's report\n * @param common - cancellation\n * @returns the table, or null\n */\nexport async function readCyTable(\n bytes: Uint8Array,\n path: string,\n entry: string,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n): Promise<CyTable | null> {\n const records = await tableRecords(bytes, common);\n if (typeof records === \"string\") {\n return tableError(report, entry, records);\n }\n const header = tableHeader(records);\n if (typeof header === \"string\") {\n return tableError(report, entry, header);\n }\n const columns = tableColumns(records[header.at].cells, records[header.at + 1].cells);\n if (typeof columns === \"string\") {\n return tableError(report, entry, columns);\n }\n const { rows, lines, quotedEmpty, problems } = tableRows(records.slice(header.at + header.lines), columns.length);\n if (problems.short + problems.long + problems.repeated > 0) {\n report.warning(\n \"parse-error\",\n CYS_ISSUE.TABLE_ROW,\n `${entryLabel(entry)}: ${problems.short} row${plural(problems.short)} with too few cells (the rest are unset), ${problems.long} with too many (the extra cells are ignored), ${problems.repeated} repeating a key (the first row is read)`,\n );\n }\n return { path, entry, columns, rows, lines, quotedEmpty };\n}\n\n/**\n * A table's CSV records.\n * @param bytes - the entry's bytes\n * @param common - cancellation\n * @returns the records, or why the CSV is broken\n */\nasync function tableRecords(bytes: Uint8Array, common: ResolvedImportOptions): Promise<TableRecord[] | string> {\n const scratch = new ImportReportBuilder(FORMAT, 0);\n const reader = new CsvRecordReader(bytes, scratch, { delimiter: \",\", encoding: \"utf-8\", signal: common.signal });\n const records: TableRecord[] = [];\n try {\n for await (const cells of reader) {\n const empty = cells.flatMap((cell, i) => (cell.length === 0 && reader.quoted[i] ? [i] : []));\n records.push({ cells, line: reader.line, quotedEmpty: empty.length === 0 ? undefined : new Set(empty) });\n }\n } catch (err) {\n if (err instanceof ImportError) {\n return scratch.issues.at(-1)?.message ?? err.message;\n }\n throw err;\n }\n return records;\n}\n\n/**\n * Where a table's header starts and how many lines it takes.\n * @param records - the table's records\n * @returns the header, or why it does not parse\n */\nfunction tableHeader(records: readonly TableRecord[]): { readonly at: number; readonly lines: number } | string {\n let at = 0;\n let version = 0;\n if (records[0]?.cells[0] === \"CyCSV-Version\") {\n const { cells } = records[0];\n if (cells.length !== 2 || !/^\\d+$/.test(cells[1].trim())) {\n return `the version row ${JSON.stringify(cells)} does not parse`;\n }\n version = Number(cells[1]);\n at = 1;\n }\n if (version !== 0 && version !== 1) {\n return `CyCSV version \"${records[0].cells[1]}\" is not 0 or 1`;\n }\n // version 1: names, types, column options, table title; version 0: names, types, table title\n const lines = version === 1 ? 4 : 3;\n if (records.length < at + lines - 1) {\n return \"the table header is incomplete\";\n }\n // the reader skips blank lines, so a blank title line (another tool's) shows only as a gap\n // in the line numbers: the record after the row before the title is then the first data row\n const beforeTitle = records[at + lines - 2];\n const title = records.at(at + lines - 1);\n const titleBlank =\n title === undefined || (title.line > beforeTitle.line + 1 && !beforeTitle.cells.some((c) => /[\\r\\n]/.test(c)));\n return { at, lines: titleBlank ? lines - 1 : lines };\n}\n\n/**\n * A table's columns.\n * @param names - the column names\n * @param classes - their Java classes\n * @returns the columns, or why they cannot be read\n */\nfunction tableColumns(names: readonly string[], classes: readonly string[]): CyColumn[] | string {\n if (names.length === 0 || classes.length !== names.length) {\n return `${names.length} column name${plural(names.length)} but ${classes.length} column class(es)`;\n }\n const columns: CyColumn[] = [];\n for (let i = 0; i < names.length; i++) {\n const column = columnOf(names[i], classes[i]);\n if (column === null) {\n return `column \"${names[i]}\" has the class \"${classes[i]}\", which graph-io cannot read`;\n }\n columns.push(column);\n }\n return columns;\n}\n\n/**\n * A table's rows by key: the first row of a repeated key is read, and rows of the wrong length are counted.\n * @param records - the data records\n * @param width - how many columns the table has\n * @returns the rows\n */\nfunction tableRows(records: readonly TableRecord[], width: number): TableRows {\n const rows = new Map<string, readonly string[]>();\n const lines = new Map<string, number>();\n const quotedEmpty = new Map<string, ReadonlySet<number>>();\n const problems: RowProblems = { short: 0, long: 0, repeated: 0 };\n for (const record of records) {\n const { cells } = record;\n if (cells.length < width) {\n problems.short++;\n } else if (cells.length > width) {\n problems.long++;\n }\n const key = cells[0];\n if (rows.has(key)) {\n problems.repeated++;\n continue;\n }\n rows.set(key, cells.slice(0, width));\n lines.set(key, record.line);\n if (record.quotedEmpty !== undefined) {\n quotedEmpty.set(key, record.quotedEmpty);\n }\n }\n return { rows, lines, quotedEmpty, problems };\n}\n\n/**\n * The column of a name and a Java class.\n * @param name - the name\n * @param javaClass - the class text\n * @returns the column, or null for a class graph-io cannot read\n */\nfunction columnOf(name: string, javaClass: string): CyColumn | null {\n const scalar = JAVA_TYPES[javaClass.trim()];\n if (scalar !== undefined) {\n return { name, type: scalar, list: false };\n }\n const list = LIST_CLASS.exec(javaClass.trim());\n const item = list === null ? undefined : JAVA_TYPES[list[1]];\n return item === undefined ? null : { name, type: item, list: true };\n}\n\n/**\n * Record E_CYS_TABLE for a table that is skipped.\n * @param report - the report\n * @param entry - the entry name\n * @param reason - why\n * @returns null\n */\nfunction tableError(report: ImportReportBuilder, entry: string, reason: string): null {\n report.error(\"parse-error\", CYS_ISSUE.TABLE, `${entryLabel(entry)}: ${reason}; the table is not read`);\n return null;\n}\n\n/**\n * The att record of one cell, or null for an unset cell. CyCSV's rules: an empty cell is unset\n * except in a String column, where it is the empty string (but in a `graphty.style.` column only when quoted,\n * `\"\"`: graphty writes an element without a style value as an unquoted empty cell); a list cell holds its items separated\n * by line breaks (`\\n`, or `\\r` as some Cytoscape versions write them; Java's `split`, so trailing empty items\n * vanish; an empty String-list cell is one\n * empty item, any other empty list cell unset); a cell starting with `=` is an equation.\n * @param column - the column\n * @param text - the cell text\n * @param line - the row's line\n * @param namespace - the table namespace the column belongs to (null for the network's own table)\n * @param hidden - whether the column is hidden (HIDDEN and app tables)\n * @param quoted - whether the cell was quoted\n * @returns the att, or null\n * @category Plugin helpers\n */\nexport function cellAtt(\n column: CyColumn,\n text: string,\n line: number,\n namespace: string | null,\n hidden: boolean,\n quoted = false,\n): AttRec | null {\n const cell = { line, namespace, hidden };\n if (text.startsWith(\"=\")) {\n return att(column.name, column.list ? \"List\" : column.type, null, text, true, cell);\n }\n if (!column.list) {\n // graphty writes an unset style value as an unquoted empty cell, and the empty string quoted (`\"\"`)\n if (\n text.length === 0 &&\n (column.type !== \"String\" || (!quoted && column.name.startsWith(STYLE_COLUMN_PREFIX)))\n ) {\n return null;\n }\n return att(column.name, column.type, null, text, false, cell);\n }\n if (text.length === 0 && column.type !== \"String\") {\n return null;\n }\n const list = att(column.name, \"List\", column.type, null, false, cell);\n for (const item of javaSplitLines(text)) {\n if (item.length === 0 && column.type !== \"String\") {\n continue;\n }\n list.children.push(att(column.name, column.type, null, item, false, cell));\n }\n return list;\n}\n\n/**\n * Java's `String.split(\"\\n\")`, with `\\r` and `\\r\\n` read as line breaks too (Cytoscape has written list cells\n * with each): trailing empty strings are removed, and a text without a line break is itself (so `\"\"` is one empty\n * item).\n * @param text - the cell\n * @returns the items\n */\nfunction javaSplitLines(text: string): string[] {\n if (!text.includes(\"\\n\") && !text.includes(\"\\r\")) {\n return [text];\n }\n const items = text.split(/\\r\\n|\\r|\\n/);\n while (items.at(-1)?.length === 0) {\n items.pop();\n }\n return items;\n}\n\n/**\n * An att record.\n * @param name - the name\n * @param cyType - the Cytoscape type\n * @param elementType - a list's item type, or null\n * @param value - the value, or null\n * @param equation - the value is a formula\n * @param cell - where the cell sits\n * @param cell.line - the line\n * @param cell.namespace - the table namespace, or null\n * @param cell.hidden - a hidden column\n * @returns the record\n */\nfunction att(\n name: string,\n cyType: string,\n elementType: string | null,\n value: string | null,\n equation: boolean,\n cell: { readonly line: number; readonly namespace: string | null; readonly hidden: boolean },\n): AttRec {\n const { line, namespace, hidden } = cell;\n return {\n name,\n type: null,\n cyType,\n elementType,\n value,\n hidden,\n equation,\n children: [],\n extra: {},\n xml: null,\n hasGraph: false,\n text: \"\",\n line,\n namespace,\n };\n}\n\n/**\n * One virtual column of `tables/cytables.xml`.\n * @category Plugin helpers\n */\nexport interface VirtualColumn {\n /** The column name in the target table. */\n readonly name: string;\n /** The target table's path under `tables/`. */\n readonly targetTable: string;\n /** The source table's path. */\n readonly sourceTable: string;\n /** The source column's name. */\n readonly sourceColumn: string;\n /** The join column of the source (normally SUID). */\n readonly sourceJoinKey: string;\n /** The join column of the target (normally SUID). */\n readonly targetJoinKey: string;\n}\n\n/** A resolved virtual column: its type and its value per target row key. */\ninterface VirtualValues {\n readonly column: CyColumn;\n readonly values: ReadonlyMap<string, string>;\n}\n\n/**\n * Resolve the virtual columns of one table: each one's values joined from its source table,\n * following a source that is itself a virtual column. A column whose source table or column is\n * missing, or whose sources form a cycle, is E_CYS_TABLE and skipped.\n * @param target - the table\n * @param virtuals - every virtual column of the session\n * @param tableOf - reads (and caches) a table by path, null when it cannot be read or is absent\n * @param report - the report\n * @returns the virtual columns of the table, in cytables.xml order\n */\nexport async function virtualColumnsOf(\n target: CyTable,\n virtuals: readonly VirtualColumn[],\n tableOf: (path: string) => Promise<CyTable | null>,\n report: ImportReportBuilder,\n): Promise<VirtualValues[]> {\n const out: VirtualValues[] = [];\n for (const virtual of virtuals) {\n if (virtual.targetTable !== target.path) {\n continue;\n }\n const resolved = await resolve(virtual, virtuals, tableOf, new Set());\n if (typeof resolved === \"string\") {\n report.error(\n \"parse-error\",\n CYS_ISSUE.TABLE,\n `${target.entry}: the virtual column \"${virtual.name}\" ${resolved}; the column is not read`,\n );\n continue;\n }\n const targetKey = target.columns.findIndex((c) => c.name === virtual.targetJoinKey);\n if (targetKey < 0) {\n report.error(\n \"parse-error\",\n CYS_ISSUE.TABLE,\n `${target.entry}: the virtual column \"${virtual.name}\" joins on the column \"${virtual.targetJoinKey}\", which the table does not have; the column is not read`,\n );\n continue;\n }\n const values = new Map<string, string>();\n for (const [key, cells] of target.rows) {\n const join = targetKey <= 0 ? key : cells[targetKey];\n const value = join === undefined ? undefined : resolved.values.get(join);\n if (value !== undefined) {\n values.set(key, value);\n }\n }\n out.push({ column: { ...resolved.column, name: virtual.name }, values });\n }\n return out;\n}\n\n/**\n * The values of a virtual column's source, by the source's join key.\n * @param virtual - the virtual column\n * @param virtuals - every virtual column\n * @param tableOf - the table reader\n * @param seen - the virtual columns on the current chain (a cycle check)\n * @returns the values, or the reason they cannot be read\n */\nasync function resolve(\n virtual: VirtualColumn,\n virtuals: readonly VirtualColumn[],\n tableOf: (path: string) => Promise<CyTable | null>,\n seen: Set<VirtualColumn>,\n): Promise<VirtualValues | string> {\n if (seen.has(virtual)) {\n return \"is part of a cycle of virtual columns\";\n }\n seen.add(virtual);\n const source = await tableOf(virtual.sourceTable);\n if (source === null) {\n return `names the source table \"${virtual.sourceTable}\", which the session does not hold or cannot read`;\n }\n const joinIndex = source.columns.findIndex((c) => c.name === virtual.sourceJoinKey);\n if (joinIndex < 0) {\n return `joins on the column \"${virtual.sourceJoinKey}\", which its source table does not have`;\n }\n const joinOf = (key: string, cells: readonly string[]): string | undefined =>\n joinIndex === 0 ? key : cells[joinIndex];\n const own = source.columns.findIndex((c) => c.name === virtual.sourceColumn);\n if (own >= 0) {\n const values = new Map<string, string>();\n for (const [key, cells] of source.rows) {\n const join = joinOf(key, cells);\n if (join !== undefined && cells[own] !== undefined) {\n values.set(join, cells[own]);\n }\n }\n return { column: source.columns[own], values };\n }\n const chained = virtuals.find((v) => v.targetTable === source.path && v.name === virtual.sourceColumn);\n if (chained === undefined) {\n return `names the source column \"${virtual.sourceColumn}\", which its source table does not have`;\n }\n const inner = await resolve(chained, virtuals, tableOf, seen);\n if (typeof inner === \"string\") {\n return inner;\n }\n // re-key the chained values (by the chained source's join key) to this source's join key\n const values = new Map<string, string>();\n const chainedJoin = source.columns.findIndex((c) => c.name === chained.targetJoinKey);\n if (chainedJoin < 0) {\n return `reads the virtual column \"${chained.name}\", which joins on the column \"${chained.targetJoinKey}\" its table does not have`;\n }\n for (const [key, cells] of source.rows) {\n const lookup = chainedJoin <= 0 ? key : cells[chainedJoin];\n const value = lookup === undefined ? undefined : inner.values.get(lookup);\n const join = joinOf(key, cells);\n if (value !== undefined && join !== undefined) {\n values.set(join, value);\n }\n }\n return { column: inner.column, values };\n}\n","/**\n * The Cytoscape session importer (design `design/graph-io/cytoscape-and-obo/design.md` sections\n * 1.4 and 3; `research-session-and-style.md`). A session is a zip of every network of a Cytoscape\n * desktop; the unit of import is the registered subnetwork (3.x) or the network (2.x), one\n * snapshot each: `import()` reads the one `graphIndex` / `graphName` picks (the first by default),\n * `importAll()` every one, and `listGraphs()` lists them from the network files alone.\n *\n * 3.x: the network file gives the topology (shared nodes through `xlink:href`, per-edge direction,\n * groups, nested-network pointers); the subnetwork's CyCSV tables give its columns (LOCAL_ATTRS as\n * they are, the SHARED_ATTRS columns `cytables.xml` joins in, HIDDEN and app tables as hidden\n * columns under their namespace); its first view gives positions (y flipped) and the `graphics`\n * column, further views `position@<n>` columns. A table's `name` is the label (what Cytoscape\n * shows), in a label column named `name`, and ids an exporter mangled are restored from the node\n * table's `graphty:originalId` (restoreMangledIds). 2.x: one full XGMML file per network, with\n * selection and hidden state from `cysession.xml`. Everything is resolved by the XGMML emitter, so\n * both readers share every column rule. Asked for styles, the importer reads the style the imported view names\n * from `session_vizmap.xml` (styles.ts), kept for it through the report; otherwise W_STYLES_NOT_IMPORTED.\n */\n\nimport { GraphFormatError, type GraphSink, INVALID_INDEX } from \"@graphty/graph-format\";\n\nimport { declareResolved } from \"../../common/attributes.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { decodeEntryName, readText, throwIfAborted } from \"../../common/input.js\";\nimport {\n chooseGraph,\n graphChosen,\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { agree, elementCount, plural } from \"../../common/plural.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { startsLikeZip } from \"../../common/zip.js\";\nimport { STYLE_BLOCK_NAME } from \"../../styles/io/block.js\";\nimport {\n type CommonImportOptions,\n type GraphChoiceOptions,\n type GraphImporter,\n type GraphListing,\n ImportError,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport { ORIGINAL_ID_ATTRIBUTE } from \"../graphml/constants.js\";\nimport { XGMML_ISSUE, XGMML_ORIGIN_NAMESPACE } from \"../xgmml/constants.js\";\nimport {\n type AttRec,\n type EdgeRec,\n type GraphRec,\n isCyTrue,\n type NodeRec,\n type XgmmlDocument,\n} from \"../xgmml/document.js\";\nimport {\n type Dialect,\n dialectOf,\n type EmitExtras,\n membersOf,\n parseCoordinate,\n XgmmlEmitter,\n type XgmmlSettings,\n} from \"../xgmml/emit.js\";\nimport { parseXgmml, resolveSettings } from \"../xgmml/importer.js\";\nimport {\n CYS_ISSUE,\n CYTOSCAPE_NAMESPACE,\n DEFAULT_MAX_UNCOMPRESSED,\n EXTENSIONS,\n FORMAT,\n HIDDEN_COLUMN,\n META_KEY,\n MIME_TYPES,\n SELECTED_COLUMN,\n VIEW_POSITION_PREFIX,\n} from \"./constants.js\";\nimport {\n elementsNamed,\n entryLabel,\n listed,\n type NetworkEntry,\n openSession,\n parseXmlTree,\n readXmlTree,\n type Session,\n type SessionEntry,\n type TableEntry,\n urlDecode,\n type XmlNode,\n} from \"./session.js\";\nimport { readSessionStyles, type SessionStyleSource } from \"./styles.js\";\nimport { cellAtt, type CyTable, readCyTable, type VirtualColumn, virtualColumnsOf } from \"./tables.js\";\n\n/**\n * The format-specific options of the session importer.\n * @category Built-in formats\n */\nexport interface CysImportOptions extends GraphChoiceOptions, CommonImportOptions {\n /**\n * Where Cytoscape's `z` value (a drawing order, not a depth) goes: \"column\" keeps it as a node\n * attribute named `z`; \"position\" makes it the third coordinate of the position.\n * @defaultValue \"column\"\n */\n zAs?: \"column\" | \"position\" | undefined;\n /**\n * The most bytes one import may unpack from the session archive, in total (2 GiB). A file that\n * would unpack to more, or one compressed more than 1000 to 1, fails with E_TOO_LARGE.\n * @defaultValue 2147483648\n */\n maxUncompressedBytes?: number | undefined;\n}\n\n/**\n * The per-format defaults: SUIDs as written, edges directed unless they say otherwise, the edge\n * `weight` column as the weight (as for XGMML, the format of the session's networks).\n */\nconst FORMAT_DEFAULTS: ImportFormatDefaults = {\n ids: \"keep\",\n defaultDirected: true,\n weightFrom: \"weight\",\n addMissingNodes: false,\n};\n\n/** The common options the session importer reads. */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"long\",\n \"restoreMangledIds\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** One network the session holds: a registered subnetwork of a 3.x network file, or a 2.x network. */\ntype Choice = Choice3 | Choice2;\n\n/** A registered subnetwork of a 3.x network file. */\ninterface Choice3 {\n readonly era: \"3\";\n readonly network: NetworkEntry;\n /** The subnetwork itself (two subnetworks can share an id). */\n readonly graph: GraphRec;\n readonly graphId: string;\n readonly name: string | null;\n readonly nodes: number;\n readonly edges: number;\n}\n\n/** A 2.x network and its `cysession.xml` record. */\ninterface Choice2 {\n readonly era: \"2\";\n readonly file: SessionEntry;\n readonly name: string;\n readonly record: XmlNode;\n readonly parent: string | null;\n}\n\n/** What every import call sets up. */\ninterface Prepared {\n readonly report: ImportReportBuilder;\n readonly common: ResolvedImportOptions;\n /** The options the entries inside are read with: no progress, no encoding override. */\n readonly inner: ResolvedImportOptions;\n readonly zAs: \"column\" | \"position\";\n readonly session: Session;\n readonly choices: readonly Choice[];\n /** The network file documents parsed for the listing, by entry name (3.x). */\n readonly docs: Map<string, Parsed>;\n}\n\n/** A parsed XGMML entry. */\ninterface Parsed {\n readonly doc: XgmmlDocument;\n readonly dialect: Dialect;\n}\n\n/**\n * The maxUncompressedBytes option, checked.\n * @param value - the caller's value\n * @returns the byte budget; E_UNSUPPORTED for anything but a positive number\n */\nfunction budgetOption(value: unknown): number {\n if (value === undefined) {\n return DEFAULT_MAX_UNCOMPRESSED;\n }\n if (typeof value !== \"number\" || !(value > 0)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option maxUncompressedBytes: ${JSON.stringify(value)} is not a positive number`,\n {\n option: \"maxUncompressedBytes\",\n found: value,\n },\n );\n }\n return value;\n}\n\n/**\n * Resolve the options, open the archive and list its networks.\n * @param input - the input\n * @param sink - the sink, or null for listGraphs\n * @param options - the options\n * @returns what the import needs\n */\nasync function prepare(\n input: ImportInput,\n sink: GraphSink | null,\n options: (CysImportOptions & CommonImportOptions) | undefined,\n): Promise<Prepared> {\n const common = resolveImportOptions(options, FORMAT_DEFAULTS);\n const report = new ImportReportBuilder(FORMAT, common.errorLimit);\n if (sink !== null) {\n reportSinkOptions(sink, options, report, true);\n reportUnusedOptions(options, report, USED_OPTIONS);\n }\n const { zAs } = resolveSettings({ zAs: options?.zAs }, false);\n const maxBytes = budgetOption(options?.maxUncompressedBytes);\n const session = await openSession(input, report, common, maxBytes);\n const inner: ResolvedImportOptions = Object.freeze({ ...common, onProgress: null, encoding: null });\n const docs = new Map<string, Parsed>();\n const choices =\n session.layout.era === \"3\"\n ? await networks3(session, report, inner, docs)\n : await networks2(session, report, inner);\n return { report, common, inner, zAs, session, choices, docs };\n}\n\n/**\n * Read an XGMML entry. Its issues are relayed into the import's report with the entry name in\n * the message; a fatal one fails the import.\n * @param session - the session\n * @param entry - the entry\n * @param report - the import's report\n * @param inner - the options entries are read with\n * @returns the document and its dialect\n */\nasync function parseEntry(\n session: Session,\n entry: SessionEntry,\n report: ImportReportBuilder,\n inner: ResolvedImportOptions,\n): Promise<Parsed> {\n return (await parseOptionalEntry(session, entry, report, inner, false)) as Parsed;\n}\n\n/**\n * Read an XGMML entry, its issues and counts relayed into the import's report (the entry name\n * in each message), parsing within what is left of the import's error limit. A fatal issue fails\n * the import, unless the entry is optional (a view): then it is recorded as an error and the\n * entry is skipped (null).\n * @param session - the session\n * @param entry - the entry\n * @param report - the import's report\n * @param inner - the options entries are read with\n * @param optional - whether the import can go on without the entry\n * @returns the document and its dialect, or null for an optional entry that cannot be read\n */\nasync function parseOptionalEntry(\n session: Session,\n entry: SessionEntry,\n report: ImportReportBuilder,\n inner: ResolvedImportOptions,\n optional: boolean,\n): Promise<Parsed | null> {\n const scratch = new ImportReportBuilder(FORMAT, Math.max(0, report.errorLimit - report.errorCount));\n try {\n // a damaged entry (bad CRC, truncated deflate) fails the scratch report like a parse error\n const bytes = await session.read(entry, scratch);\n const doc = await parseXgmml(bytes, scratch, inner, undefined);\n const dialect = dialectOf(doc, scratch);\n relay(scratch.issues, report, entry.name);\n addCounts(scratch, report);\n return { doc, dialect };\n } catch (err) {\n if (!(err instanceof ImportError)) {\n throw err;\n }\n addCounts(scratch, report);\n const { issues } = scratch;\n if (scratch.truncated) {\n // the entry reached the import's error limit: relaying its errors aborts the import\n relay(issues, report, entry.name);\n }\n const fatal = issues.at(-1);\n relay(issues.slice(0, -1), report, entry.name);\n const message = `${entryLabel(entry.name)}: ${fatal?.message ?? err.message}`;\n const where = { line: fatal?.line ?? null };\n if (fatal?.code === CYS_ISSUE.TOO_LARGE) {\n // the byte budget is a limit of the whole import, not damage to one entry\n report.error(\"unsupported\", fatal.code, message);\n throw report.abort(message, { code: fatal.code });\n }\n if (optional) {\n report.error(\"parse-error\", fatal?.code ?? CYS_ISSUE.CORRUPT, `${message}; the entry is not read`, where);\n return null;\n }\n return report.fail(fatal?.code ?? CYS_ISSUE.CORRUPT, message, where);\n }\n}\n\n/**\n * Add an entry's element counts (the nodes skipped while parsing it) to the import's.\n * @param from - the entry's report\n * @param to - the import's report\n */\nfunction addCounts(from: ImportReportBuilder, to: ImportReportBuilder): void {\n for (const key of Object.keys(from.counts) as (keyof typeof from.counts)[]) {\n to.counts[key] += from.counts[key];\n }\n}\n\n/**\n * Record issues of an entry in the import's report, the entry name before each message.\n * @param issues - the issues\n * @param report - the import's report\n * @param entry - the entry name\n */\nfunction relay(issues: ImportReport[\"issues\"], report: ImportReportBuilder, entry: string): void {\n for (const issue of issues) {\n const where = { line: issue.line, element: issue.element };\n if (issue.severity === \"error\") {\n report.error(issue.category, issue.code, `${entryLabel(entry)}: ${issue.message}`, where);\n } else {\n report.warning(issue.category, issue.code, `${entryLabel(entry)}: ${issue.message}`, where);\n }\n }\n}\n\n// ---------------------------------------------------------------------------------------- 3.x\n\n/**\n * The registered subnetworks of a 3.x session, in `network_list.xml` order (else entry order).\n * @param session - the session\n * @param report - the report\n * @param inner - the options entries are read with\n * @param docs - where the parsed network files are kept\n * @returns the networks\n */\nasync function networks3(\n session: Session,\n report: ImportReportBuilder,\n inner: ResolvedImportOptions,\n docs: Map<string, Parsed>,\n): Promise<Choice3[]> {\n const { layout } = session;\n const choices: Choice3[] = [];\n for (const network of layout.networks) {\n const parsed = await parseEntry(session, network, report, inner);\n if (parsed.dialect.view) {\n report.fail(\n XGMML_ISSUE.VIEW_DOCUMENT,\n `${network.name}: this is a session view file (cy:view), not a network file; it holds no topology`,\n { line: parsed.doc.root.line },\n );\n }\n docs.set(network.name, parsed);\n for (const graph of registeredGraphs(parsed)) {\n if (graph.id === null) {\n const label = graph.label === null ? \"\" : ` (\"${graph.label}\")`;\n report.error(\n \"missing-value\",\n XGMML_ISSUE.MISSING_ID,\n `${network.name}: a registered subnetwork${label} has no id; its tables and views cannot be found and it is skipped`,\n { line: graph.line },\n );\n continue;\n }\n const members = membersOf(parsed.doc, graph);\n choices.push({\n era: \"3\",\n network,\n graph,\n graphId: graph.id,\n name: graph.label ?? graph.id,\n nodes: new Set(members.nodes).size,\n edges: members.edges.length,\n });\n }\n }\n const known = new Set(choices.map((c) => c.graphId));\n const strayViews = layout.views.filter((v) => !known.has(v.network)).map((v) => v.name);\n const strayTables = layout.tables.filter(\n (t) =>\n !known.has(t.network) &&\n !layout.networks.some((n) => n.suid === t.network) &&\n !isGroupTable(t, session, docs),\n );\n if (strayViews.length > 0 || strayTables.length > 0) {\n report.warning(\n \"validation-error\",\n CYS_ISSUE.DANGLING_REFERENCE,\n `${strayViews.length + strayTables.length} view${plural(strayViews.length + strayTables.length)} or table${plural(strayViews.length + strayTables.length)} ${agree(strayViews.length + strayTables.length, \"belongs\", \"belong\")} to a network the session does not hold and were not read: ${listed([...strayViews, ...strayTables.map((t) => t.name)])}`,\n );\n }\n if (layout.networkList === null) {\n return choices;\n }\n const tree = await parseXmlTree(\n await session.read(layout.networkList, report),\n layout.networkList.name,\n report,\n inner,\n );\n if (typeof tree === \"string\") {\n // the list only orders the networks: without it they keep the order of their entries\n report.warning(\n \"unsupported\",\n CYS_ISSUE.ENTRY_SKIPPED,\n `${layout.networkList.name}: ${tree}; it is not read and the networks are listed in entry order`,\n );\n return choices;\n }\n const order = new Map<string, number>();\n for (const node of elementsNamed(tree, \"network\")) {\n const id = node.attrs.get(\"id\");\n const position = Number(node.attrs.get(\"order\"));\n if (id !== undefined && Number.isFinite(position)) {\n order.set(id, position);\n }\n }\n return choices\n .map((choice, index) => ({ choice, index }))\n .sort(\n (a, b) =>\n (order.get(a.choice.graphId) ?? Infinity) - (order.get(b.choice.graphId) ?? Infinity) ||\n a.index - b.index,\n )\n .map((c) => c.choice);\n}\n\n/**\n * Whether a table belongs to a graph declared in some network file (a group's network): those are\n * read with their network, not reported.\n * @param table - the table\n * @param session - the session\n * @param docs - the parsed network files\n * @returns true for a table of a known graph\n */\nfunction isGroupTable(table: TableEntry, session: Session, docs: ReadonlyMap<string, Parsed>): boolean {\n for (const network of session.layout.networks) {\n if (docs.get(network.name)?.doc.graphs.some((g) => g.id === table.network) === true) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * The registered subnetworks of a network file (`cy:registered` true under the root).\n * @param parsed - the network file\n * @returns the graphs\n */\nfunction registeredGraphs(parsed: Parsed): GraphRec[] {\n const subnetworks = parsed.doc.root.subgraphs.filter((g) => isCyTrue(g.registered));\n // a registered root with no subnetworks (another tool's network file) is the network itself\n return subnetworks.length === 0 && isCyTrue(parsed.doc.root.registered) ? [parsed.doc.root] : subnetworks;\n}\n\n/**\n * Import one registered subnetwork of a 3.x session.\n * @param prepared - the prepared import\n * @param choice - the subnetwork\n * @param sink - the sink\n * @param parsed - its network file, parsed for this import (its records are filled in)\n * @returns the style its view names, or null\n */\nasync function import3(prepared: Prepared, choice: Choice3, sink: GraphSink, parsed: Parsed): Promise<string | null> {\n const { graph } = choice;\n const members = membersOf(parsed.doc, graph);\n const nodes = byId(members.nodes);\n const edges = byId(members.edges);\n // the records are shared by every network of the file: what this import adds is undone after\n const restore = saveRecords(graph, nodes, edges);\n try {\n return await fill3(prepared, choice, sink, parsed, nodes, edges);\n } finally {\n restore();\n }\n}\n\n/**\n * The state of the records an import fills in (atts, coordinates, graphics), and a function that\n * puts it back.\n * @param graph - the subnetwork\n * @param nodes - its node records\n * @param edges - its edge records\n * @returns the restore function\n */\nfunction saveRecords(\n graph: GraphRec,\n nodes: ReadonlyMap<string, NodeRec>,\n edges: ReadonlyMap<string, EdgeRec>,\n): () => void {\n const saved = [...nodes.values()].map((n) => ({\n n,\n atts: n.atts.length,\n x: n.x,\n y: n.y,\n z: n.z,\n graphics: n.graphics,\n }));\n const savedEdges = [...edges.values()].map((e) => ({ e, atts: e.atts.length, graphics: e.graphics }));\n const graphAtts = graph.atts.length;\n const graphGraphics = graph.graphics;\n return (): void => {\n for (const { n, atts, x, y, z, graphics } of saved) {\n n.atts.length = atts;\n Object.assign(n, { x, y, z, graphics });\n }\n for (const { e, atts, graphics } of savedEdges) {\n e.atts.length = atts;\n e.graphics = graphics;\n }\n graph.atts.length = graphAtts;\n graph.graphics = graphGraphics;\n };\n}\n\n/**\n * Fill one subnetwork's records from its tables and views and emit it.\n * @param prepared - the prepared import\n * @param choice - the subnetwork\n * @param sink - the sink\n * @param parsed - its network file\n * @param nodes - its node records by id\n * @param edges - its edge records by id\n * @returns the style its view names, or null\n */\nasync function fill3(\n prepared: Prepared,\n choice: Choice3,\n sink: GraphSink,\n parsed: Parsed,\n nodes: ReadonlyMap<string, NodeRec>,\n edges: ReadonlyMap<string, EdgeRec>,\n): Promise<string | null> {\n const { report, inner } = prepared;\n const { doc, dialect } = parsed;\n const { graph } = choice;\n const members = membersOf(doc, graph);\n const unmatched = await applyTables(prepared, choice, doc, nodes, edges);\n if (unmatched > 0) {\n report.warning(\n \"parse-error\",\n CYS_ISSUE.TABLE_ROW,\n `${unmatched} table row${plural(unmatched)} of network ${choice.graphId} ${agree(unmatched, \"names\", \"name\")} no node, edge or network in it (left over from deleted elements) and ${agree(unmatched, \"is\", \"are\")} not read`,\n );\n }\n const restoredIds = inner.restoreMangledIds ? restoreIds(members.nodes) : new Map<string, string>();\n const { visualStyle, extraViews, extraIds } = await readViews(prepared, choice, nodes, edges);\n const block =\n prepared.session.layout.block === null ? null : await entryText(prepared, prepared.session.layout.block);\n if (block !== null) {\n // the graphty.styles block of a session graphty wrote: a graph attribute, as in every other format\n graph.atts.push(textAtt(STYLE_BLOCK_NAME, block));\n }\n const cyMeta = sessionMeta(prepared, {\n collection: doc.root.label ?? choice.network.title,\n network: choice.graphId,\n parentNetwork: parentNetwork(graph, prepared.choices),\n visualStyle,\n });\n const groups: { group: string; members: string[] }[] = [];\n cyMeta.groups = groups;\n const extras: EmitExtras = {\n sourceFormat: FORMAT,\n entry: choice.network.name,\n graphName: localName(graph) ?? choice.name,\n metaExtra: { [META_KEY]: cyMeta },\n labelFromName: true,\n restoredIds,\n groupNodes: groupNodeIds(members.nodes),\n resolvePointer: pointerResolver(prepared, doc),\n onMissingMember: (group, member): void => {\n addMissingMember(groups, group, member);\n },\n };\n const settings: XgmmlSettings = { labelAliases: false, cytoscapeEscapes: false, zAs: prepared.zAs };\n new XgmmlEmitter(doc, dialect, sink, report, prepared.inner, settings, extras).emit(graph);\n if (groups.length > 0) {\n const missing = groups.reduce((n, g) => n + g.members.length, 0);\n report.warning(\n \"unsupported\",\n CYS_ISSUE.COLLAPSED_GROUP,\n `${groups.length} collapsed group${plural(groups.length)} ${agree(groups.length, \"holds\", \"hold\")} ${missing} member${plural(missing)} that are not in the network; they are listed in meta.extra.cytoscape.groups`,\n );\n }\n reportRootOnly(parsed, report, choice.network.name);\n writeViewPositions(sink, extraViews, extraIds, report, prepared.inner, restoredIds);\n return visualStyle;\n}\n\n/**\n * The ids of the nodes Cytoscape marks as groups.\n * @param nodes - the network's node records\n * @returns their ids\n */\nfunction groupNodeIds(nodes: readonly NodeRec[]): Set<string> {\n return new Set(\n nodes\n .filter((n) => n.atts.some((a) => a.name === \"__isGroup\" && isCyTrue(a.value)))\n .flatMap((n) => (n.id === null ? [] : [n.id])),\n );\n}\n\n/**\n * Record a collapsed group's member that is not in the network.\n * @param groups - the groups with missing members, added to\n * @param group - the group's id\n * @param member - the member's id\n */\nfunction addMissingMember(groups: { group: string; members: string[] }[], group: string, member: string): void {\n const record = groups.find((g) => g.group === group);\n if (record === undefined) {\n groups.push({ group, members: [member] });\n } else if (!record.members.includes(member)) {\n record.members.push(member);\n }\n}\n\n/** What reading one subnetwork's tables shares. */\ninterface TableContext {\n readonly choice: Choice3;\n readonly graph: Choice3[\"graph\"];\n readonly nodes: ReadonlyMap<string, NodeRec>;\n readonly edges: ReadonlyMap<string, EdgeRec>;\n /** The ids of the elements the network file declares, inside this network or outside it. */\n readonly declared: ReadonlySet<string>;\n readonly virtuals: readonly VirtualColumn[];\n readonly tableOf: (path: string) => Promise<CyTable | null>;\n readonly report: ImportReportBuilder;\n}\n\n/**\n * Add the cells of a subnetwork's tables to its node, edge and network records.\n * @param prepared - the prepared import\n * @param choice - the subnetwork\n * @param doc - its network file\n * @param nodes - its node records by id\n * @param edges - its edge records by id\n * @returns the number of rows that name no element of the network\n */\nasync function applyTables(\n prepared: Prepared,\n choice: Choice3,\n doc: Parsed[\"doc\"],\n nodes: ReadonlyMap<string, NodeRec>,\n edges: ReadonlyMap<string, EdgeRec>,\n): Promise<number> {\n const { report, inner, session } = prepared;\n const { layout } = session;\n // each network reads its tables into its own report, so a shared table's issues, and a\n // table that fails the import, land in every network that reads it.\n // ponytail: a table shared by several networks is inflated and parsed once per network (the\n // byte budget is charged once); cache the parse and relay its issues if importAll gets slow\n const tables = new Map<string, Promise<CyTable | null>>();\n const tableOf = (path: string): Promise<CyTable | null> => {\n let pending = tables.get(path);\n if (pending === undefined) {\n const entry = layout.tables.find((t) => t.tablePath === path);\n pending =\n entry === undefined\n ? Promise.resolve(null)\n : session.read(entry, report).then((bytes) => readCyTable(bytes, path, entry.name, report, inner));\n tables.set(path, pending);\n }\n return pending;\n };\n const ctx: TableContext = {\n choice,\n graph: choice.graph,\n nodes,\n edges,\n // a row of an element the file declares outside this network (a collapsed group's member, a\n // meta-edge) is Cytoscape's bookkeeping, not a stale row\n declared: new Set<string>([\n ...doc.nodes.flatMap((n) => (n.id === null ? [] : [n.id])),\n ...doc.edges.flatMap((e) => (e.id === null ? [] : [e.id])),\n ]),\n virtuals: layout.cytables === null ? [] : await readVirtuals(session, layout.cytables, report, inner),\n tableOf,\n report,\n };\n let unmatched = 0;\n for (const entry of layout.tables.filter((t) => t.network === choice.graphId && t.element !== null)) {\n throwIfAborted(inner.signal);\n const table = await tableOf(entry.tablePath);\n if (table !== null) {\n unmatched += await applyTable(ctx, entry, table);\n }\n }\n return unmatched;\n}\n\n/**\n * Add the cells of one table, and of the shared columns that extend it, to the records.\n * @param ctx - the shared state\n * @param entry - the table's entry\n * @param table - the table\n * @returns the number of rows that name no element of the network\n */\nasync function applyTable(ctx: TableContext, entry: TableEntry, table: CyTable): Promise<number> {\n const local = entry.namespace === \"LOCAL_ATTRS\";\n const namespace = local ? null : entry.namespace;\n const hidden = !local && entry.namespace !== \"SHARED_ATTRS\";\n const target = (key: string): AttRec[] | undefined => {\n if (entry.element === \"network\") {\n return key === ctx.choice.graphId ? ctx.graph.atts : undefined;\n }\n return (entry.element === \"node\" ? ctx.nodes : ctx.edges).get(key)?.atts;\n };\n let unmatched = 0;\n for (const [key, cells] of table.rows) {\n const atts = target(key);\n if (atts !== undefined) {\n atts.push(...rowAtts(table, key, cells, namespace, hidden));\n } else if (!ctx.declared.has(key)) {\n unmatched++;\n }\n }\n for (const virtual of await virtualColumnsOf(table, ctx.virtuals, ctx.tableOf, ctx.report)) {\n // a shared column named like a local one is renamed; the local one keeps the name\n const owned = table.columns.some((c) => c.name === virtual.column.name);\n const ns = local ? sharedNamespace(owned) : namespace;\n for (const [key, text] of virtual.values) {\n const atts = target(key);\n if (atts !== undefined) {\n pushAtt(atts, cellAtt(virtual.column, text, table.lines.get(key) ?? 0, ns, hidden));\n }\n }\n }\n return unmatched;\n}\n\n/**\n * The attributes of one table row's cells (the first cell is the SUID key).\n * @param table - the table\n * @param key - the row's key\n * @param cells - the row's cells\n * @param namespace - the namespace the attributes are written in, or null\n * @param hidden - whether the table is one of Cytoscape's hidden ones\n * @returns the attributes of the cells that hold a value\n */\nfunction rowAtts(\n table: CyTable,\n key: string,\n cells: readonly string[],\n namespace: string | null,\n hidden: boolean,\n): AttRec[] {\n const line = table.lines.get(key) ?? 0;\n const out: AttRec[] = [];\n for (let i = 1; i < table.columns.length && i < cells.length; i++) {\n const quoted = table.quotedEmpty?.get(key)?.has(i) === true;\n pushAtt(out, cellAtt(table.columns[i], cells[i], line, namespace, hidden, quoted));\n }\n return out;\n}\n\n/**\n * The namespace of a shared column in a local table: renamed when a local column has its name.\n * @param owned - whether a local column has the shared column's name\n * @returns \"SHARED_ATTRS\", or null for none\n */\nfunction sharedNamespace(owned: boolean): string | null {\n return owned ? \"SHARED_ATTRS\" : null;\n}\n\n/**\n * Add an attribute to a record's list, unless there is none.\n * @param atts - the record's attributes\n * @param att - the attribute, or null\n */\nfunction pushAtt(atts: AttRec[], att: AttRec | null): void {\n if (att !== null) {\n atts.push(att);\n }\n}\n\n/**\n * Read a subnetwork's views: the first (the lowest view SUID, whatever the order of the entries)\n * fills the records' coordinates and graphics, each further one gives positions only. A view that\n * cannot be read is recorded and skipped.\n * @param prepared - the prepared import\n * @param choice - the subnetwork\n * @param nodes - its node records by id\n * @param edges - its edge records by id\n * @returns the first view's style, and the positions and SUIDs of the further views\n */\nasync function readViews(\n prepared: Prepared,\n choice: Choice3,\n nodes: ReadonlyMap<string, NodeRec>,\n edges: ReadonlyMap<string, EdgeRec>,\n): Promise<{\n visualStyle: string | null;\n extraViews: Map<string, [number, number, number]>[];\n extraIds: string[];\n}> {\n const { report, inner, session } = prepared;\n const views = session.layout.views\n .filter((v) => v.network === choice.graphId)\n .sort((a, b) => a.view.length - b.view.length || (a.view < b.view ? -1 : Number(a.view > b.view)));\n let visualStyle: string | null = null;\n const extraViews: Map<string, [number, number, number]>[] = [];\n const extraIds: string[] = [];\n let first = true;\n for (const view of views) {\n const viewDoc = (await parseOptionalEntry(session, view, report, inner, true))?.doc;\n if (viewDoc === undefined) {\n continue;\n }\n if (first) {\n first = false;\n visualStyle = viewDoc.root.attrs.get(\"cy:visualStyle\") ?? null;\n applyView(viewDoc, choice.graph, nodes, edges, report, view.name);\n } else {\n extraViews.push(viewPositions(viewDoc, prepared.zAs, nodes, report, view.name));\n extraIds.push(view.view);\n }\n }\n return { visualStyle, extraViews, extraIds };\n}\n\n/**\n * The virtual columns of `tables/cytables.xml`.\n * @param session - the session\n * @param entry - the cytables.xml entry\n * @param report - the report\n * @param inner - the options entries are read with\n * @returns the virtual columns in document order\n */\nasync function readVirtuals(\n session: Session,\n entry: SessionEntry,\n report: ImportReportBuilder,\n inner: ResolvedImportOptions,\n): Promise<VirtualColumn[]> {\n const tree = await parseXmlTree(await session.read(entry, report), entry.name, report, inner);\n if (typeof tree === \"string\") {\n // only the shared columns are lost: every table's own columns are still read\n report.error(\n \"parse-error\",\n CYS_ISSUE.TABLE,\n `${entryLabel(entry.name)}: ${tree}; its virtual columns are not read`,\n );\n return [];\n }\n const out: VirtualColumn[] = [];\n for (const node of elementsNamed(tree, \"virtualColumn\")) {\n const missing = [\"name\", \"targetTable\", \"sourceTable\", \"sourceColumn\"].filter((k) => !node.attrs.has(k));\n if (missing.length > 0) {\n const named = node.attrs.has(\"name\") ? ` \"${node.attrs.get(\"name\") ?? \"\"}\"` : \"\";\n report.error(\n \"parse-error\",\n CYS_ISSUE.TABLE,\n `${entryLabel(entry.name)}: a virtual column${named} has no ${missing.join(\", \")}; the column is not read`,\n );\n continue;\n }\n const a = (key: string): string => node.attrs.get(key) ?? \"\";\n out.push({\n name: a(\"name\"),\n targetTable: a(\"targetTable\"),\n sourceTable: a(\"sourceTable\"),\n sourceColumn: a(\"sourceColumn\"),\n sourceJoinKey: node.attrs.get(\"sourceJoinKey\") ?? \"SUID\",\n targetJoinKey: node.attrs.get(\"targetJoinKey\") ?? \"SUID\",\n });\n }\n return out;\n}\n\n/**\n * Records by id.\n * @param records - node or edge records\n * @returns the first record of each id\n */\nfunction byId<T extends NodeRec | EdgeRec>(records: readonly T[]): Map<string, T> {\n const out = new Map<string, T>();\n for (const record of records) {\n if (record.id !== null && !out.has(record.id)) {\n out.set(record.id, record);\n }\n }\n return out;\n}\n\n/**\n * Copy a view's coordinates and graphics onto the network's records (by `cy:nodeId` and\n * `cy:edgeId`), and its network graphics onto the graph. A view element naming nothing of the\n * network is counted in one W_DANGLING_REFERENCE.\n * @param view - the view document\n * @param graph - the subnetwork\n * @param nodes - its node records by id\n * @param edges - its edge records by id\n * @param report - the report\n * @param entry - the view entry name\n */\nfunction applyView(\n view: XgmmlDocument,\n graph: GraphRec,\n nodes: ReadonlyMap<string, NodeRec>,\n edges: ReadonlyMap<string, EdgeRec>,\n report: ImportReportBuilder,\n entry: string,\n): void {\n let dangling = 0;\n const seen = new Set<string>();\n for (const node of view.nodes) {\n const target = node.viewId === null ? undefined : nodes.get(node.viewId);\n if (target === undefined) {\n dangling++;\n continue;\n }\n duplicateViewNode(seen, node, report, entry);\n target.x = node.x;\n target.y = node.y;\n target.z = node.z;\n if (node.graphics !== null) {\n target.graphics = { ...target.graphics, ...node.graphics };\n }\n }\n for (const edge of view.edges) {\n const target = edge.viewId === null ? undefined : edges.get(edge.viewId);\n if (target === undefined) {\n dangling++;\n continue;\n }\n if (edge.graphics !== null) {\n target.graphics = { ...target.graphics, ...edge.graphics };\n }\n }\n if (view.root.graphics !== null) {\n graph.graphics = { ...graph.graphics, ...view.root.graphics };\n }\n if (dangling > 0) {\n report.warning(\n \"validation-error\",\n CYS_ISSUE.DANGLING_REFERENCE,\n `${entryLabel(entry)}: ${dangling} view element${plural(dangling)} ${agree(dangling, \"names\", \"name\")} no node or edge of the network; they are not read`,\n );\n }\n}\n\n/**\n * W_DUPLICATE_NODE for a view element that repeats a node an earlier one of the view gave.\n * @param seen - the model node ids seen so far in the view\n * @param node - the view element\n * @param report - the report\n * @param entry - the view entry name\n */\nfunction duplicateViewNode(seen: Set<string>, node: NodeRec, report: ImportReportBuilder, entry: string): void {\n const id = node.viewId as string;\n if (seen.has(id)) {\n report.warning(\n \"validation-error\",\n XGMML_ISSUE.DUPLICATE_NODE,\n `${entryLabel(entry)}: the view gives node \"${id}\" twice; the later element is used`,\n { line: node.line, element: id },\n );\n }\n seen.add(id);\n}\n\n/**\n * The positions of a further view, by model node id, read by the first view's rules: y flipped\n * to y-up, z in the position only under zAs \"position\", a coordinate that does not parse\n * E_BAD_VALUE (the position is unset; a bad z is 0), an element naming no node of the network\n * counted in one W_DANGLING_REFERENCE.\n * @param view - the view document\n * @param zAs - where z goes\n * @param nodes - the network's node records by id\n * @param report - the report\n * @param entry - the view entry name\n * @returns the positions\n */\nfunction viewPositions(\n view: XgmmlDocument,\n zAs: \"column\" | \"position\",\n nodes: ReadonlyMap<string, NodeRec>,\n report: ImportReportBuilder,\n entry: string,\n): Map<string, [number, number, number]> {\n const out = new Map<string, [number, number, number]>();\n const seen = new Set<string>();\n let dangling = 0;\n const coordinate = (text: string | null, node: NodeRec): number | null => {\n if (text === null) {\n return null;\n }\n const n = parseCoordinate(text);\n if (n === null) {\n report.error(\n \"validation-error\",\n XGMML_ISSUE.BAD_VALUE,\n `${entryLabel(entry)}: graphics coordinate \"${text}\" is not a number`,\n {\n line: node.line,\n element: node.viewId,\n },\n );\n }\n return n;\n };\n for (const node of view.nodes) {\n if (node.viewId === null || !nodes.has(node.viewId)) {\n dangling++;\n continue;\n }\n duplicateViewNode(seen, node, report, entry);\n const x = coordinate(node.x, node);\n const y = coordinate(node.y, node);\n const z = zAs === \"position\" ? coordinate(node.z, node) : null;\n if (x !== null && y !== null) {\n out.set(node.viewId, [x, y === 0 ? 0 : -y, z ?? 0]);\n } else {\n out.delete(node.viewId);\n }\n }\n if (dangling > 0) {\n report.warning(\n \"validation-error\",\n CYS_ISSUE.DANGLING_REFERENCE,\n `${entryLabel(entry)}: ${dangling} view element${plural(dangling)} ${agree(dangling, \"names\", \"name\")} no node of the network; they are not read`,\n );\n }\n return out;\n}\n\n/**\n * Write each further view's positions as a `position@<n>` column (n from 2), no role.\n * @param sink - the sink\n * @param views - the positions of each further view\n * @param viewIds - each view's SUID\n * @param report - the report\n * @param common - the id rule\n * @param restoredIds - the original ids of mangled nodes, by written id\n */\nfunction writeViewPositions(\n sink: GraphSink,\n views: readonly Map<string, [number, number, number]>[],\n viewIds: readonly string[],\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n restoredIds: ReadonlyMap<string, string>,\n): void {\n const coercer = new IdCoercer(common.ids);\n views.forEach((positions, i) => {\n const name = `${VIEW_POSITION_PREFIX}${i + 2}`;\n const { handle } = declareResolved(\n sink,\n \"node\",\n {\n name,\n dtype: \"f32\",\n components: 3,\n nullable: true,\n origin: {\n format: FORMAT,\n id: viewIds[i],\n title: null,\n type: \"graphics\",\n namespace: XGMML_ORIGIN_NAMESPACE,\n },\n extra: { sourceDims: 2, units: \"file\" },\n },\n report,\n { element: name },\n );\n for (const [id, xyz] of positions) {\n let index: number;\n try {\n index = sink.indexOf(coercer.text(restoredIds.get(id) ?? id));\n } catch {\n continue; // an id the id rule refuses was refused, and recorded, as a node already\n }\n if (index !== INVALID_INDEX) {\n sink.setNodeValue(handle, index, xyz);\n }\n }\n });\n}\n\n/**\n * The original ids an exporter's `sanitizeIds: \"mangle\"` kept in the node table's\n * `graphty:originalId` column; each such cell is taken out of the node's columns.\n * @param nodes - the node records, table cells merged in\n * @returns the original id by written id\n */\nfunction restoreIds(nodes: readonly NodeRec[]): Map<string, string> {\n const out = new Map<string, string>();\n for (const node of nodes) {\n const at = node.atts.findIndex(\n (a) =>\n a.name === ORIGINAL_ID_ATTRIBUTE &&\n (a.namespace ?? null) === null &&\n a.value !== null &&\n a.children.length === 0,\n );\n if (node.id !== null && at >= 0) {\n out.set(node.id, node.atts[at].value as string);\n node.atts.splice(at, 1);\n }\n }\n return out;\n}\n\n/**\n * The network's name from its own table (the LOCAL `name` att), else null.\n * @param graph - the subnetwork with its table atts\n * @returns the name\n */\nfunction localName(graph: GraphRec): string | null {\n const att = graph.atts.find((a) => a.name === \"name\" && (a.namespace ?? null) === null);\n return att?.value ?? null;\n}\n\n/**\n * The name of the network a subnetwork was made from: the hidden `__parentNetwork.SUID` (or the\n * pre-3.4 `Cy2 Parent Network.SUID`), named when the session holds it.\n * @param graph - the subnetwork with its table atts\n * @param choices - the session's networks\n * @returns the parent's name, its SUID when unnamed, or null\n */\nfunction parentNetwork(graph: GraphRec, choices: readonly Choice[]): string | null {\n const att = graph.atts.find((a) => a.name === \"__parentNetwork.SUID\" || a.name === \"Cy2 Parent Network.SUID\");\n if (att?.value === undefined || att.value === null || att.value.length === 0) {\n return null;\n }\n const suid = att.value;\n const named = choices.find((c) => c.era === \"3\" && c.graphId === suid);\n return named?.name ?? suid;\n}\n\n/**\n * The resolver of nested-network pointers into other network files of the session\n * (`207-Set+2.xgmml#223`): the target graph's label. Only the files a pointer names are read.\n * @param prepared - the prepared import\n * @param doc - the network file being read\n * @returns the resolver\n */\nfunction pointerResolver(prepared: Prepared, doc: XgmmlDocument): (href: string) => string | null {\n const names = new Map<string, string>();\n for (const graph of doc.graphs) {\n const { href } = graph;\n const hash = href?.indexOf(\"#\") ?? -1;\n if (href === null || hash <= 0 || names.has(href)) {\n continue;\n }\n const file = urlDecode(href.slice(0, hash));\n const id = href.slice(hash + 1);\n const network = prepared.session.layout.networks.find(\n (n) => urlDecode(n.path.slice(\"networks/\".length)) === file,\n );\n const parsed = network === undefined ? undefined : prepared.docs.get(network.name);\n const target = parsed?.doc.graphs.find((g) => g.id === id);\n if (target !== undefined) {\n names.set(href, target.label ?? id);\n }\n }\n return (href) => names.get(href) ?? null;\n}\n\n/**\n * W_XGMML_ROOT_ONLY_ELEMENTS for elements of a network file no registered subnetwork holds.\n * @param parsed - the network file\n * @param report - the report\n * @param entry - the entry name\n */\nfunction reportRootOnly(parsed: Parsed, report: ImportReportBuilder, entry: string): void {\n const held = new Set<unknown>();\n for (const graph of registeredGraphs(parsed)) {\n const members = membersOf(parsed.doc, graph);\n members.nodes.forEach((n) => held.add(n));\n members.edges.forEach((e) => held.add(e));\n }\n const nodes = parsed.doc.nodes.filter((n) => !held.has(n)).length;\n const edges = parsed.doc.edges.filter((e) => !held.has(e)).length;\n if (nodes + edges > 0) {\n report.warning(\n \"unsupported\",\n XGMML_ISSUE.ROOT_ONLY_ELEMENTS,\n `${entryLabel(entry)}: ${elementCount(nodes, edges)} ${agree(nodes + edges, \"belongs\", \"belong\")} to none of the session's networks (group meta-edges or collapsed group members) and ${agree(nodes + edges, \"was\", \"were\")} not read`,\n );\n }\n}\n\n// ---------------------------------------------------------------------------------------- 2.x\n\n/**\n * The networks of a 2.x session: every network of `cysession.xml`'s tree except `Network Root`,\n * in the order of their files in the archive.\n * @param session - the session\n * @param report - the report\n * @param inner - the options entries are read with\n * @returns the networks\n */\nasync function networks2(\n session: Session,\n report: ImportReportBuilder,\n inner: ResolvedImportOptions,\n): Promise<Choice2[]> {\n const { layout } = session;\n if (layout.cysession === null) {\n return report.fail(CYS_ISSUE.NOT_SESSION, \"the session has no cysession.xml\");\n }\n const tree = await readXmlTree(await session.read(layout.cysession, report), layout.cysession.name, report, inner);\n const documentVersion = tree.attrs.get(\"documentVersion\") ?? \"\";\n if (documentVersion.length > 0 && !/^\\d+(\\.\\d+)*$/.test(documentVersion.trim())) {\n report.warning(\n \"validation-error\",\n XGMML_ISSUE.DOCUMENT_VERSION,\n `${layout.cysession.name}: documentVersion \"${documentVersion}\" does not parse; the session is read as Cytoscape 2.x`,\n );\n }\n if (documentVersion.startsWith(\"3\")) {\n report.fail(\n CYS_ISSUE.VERSION,\n `cysession.xml has documentVersion ${documentVersion} and no version marker: the 2011 Cytoscape 3.0 pre-release layout, which no released Cytoscape reads`,\n );\n }\n const byDecoded = new Map<string, SessionEntry>();\n for (const [path, entry] of layout.files) {\n byDecoded.set(path, entry);\n byDecoded.set(urlDecode(path), entry);\n }\n const order = [...layout.files.values()];\n const choices: Choice2[] = [];\n const missing: string[] = [];\n const named = new Set<SessionEntry>();\n for (const record of elementsNamed(tree, \"network\")) {\n const given = record.attrs.get(\"id\");\n const filename = record.attrs.get(\"filename\") ?? (given === undefined ? undefined : `${given}.xgmml`);\n if (given === \"Network Root\") {\n continue;\n }\n if (filename === undefined) {\n sessionRecord(\n report,\n layout.cysession.name,\n \"a <network> has neither an id nor a filename; it is not read\",\n );\n continue;\n }\n const id = given ?? urlDecode(filename.replace(/\\.xgmml$/i, \"\"));\n if (given === undefined) {\n sessionRecord(\n report,\n layout.cysession.name,\n `a <network> for ${filename} has no id; it is named \"${id}\" after its file`,\n );\n }\n const file = byDecoded.get(filename);\n if (file === undefined) {\n missing.push(filename);\n continue;\n }\n if (named.has(file)) {\n sessionRecord(\n report,\n layout.cysession.name,\n `the <network> \"${id}\" names ${filename}, which an earlier record already names; it is not read a second time`,\n );\n continue;\n }\n named.add(file);\n const parent = record.children.find((c) => c.name === \"parent\")?.attrs.get(\"id\") ?? null;\n choices.push({\n era: \"2\",\n file,\n name: id,\n record,\n parent: parent === \"Network Root\" || parent === \"NULL\" ? null : parent,\n });\n }\n if (missing.length > 0) {\n report.warning(\n \"validation-error\",\n CYS_ISSUE.DANGLING_REFERENCE,\n `cysession.xml names ${missing.length} network file${plural(missing.length)} the session does not hold: ${listed(missing)}`,\n );\n }\n const unnamed = order.filter((e) => !named.has(e)).map((e) => e.name);\n if (unnamed.length > 0) {\n report.warning(\n \"unsupported\",\n CYS_ISSUE.ENTRY_SKIPPED,\n `${unnamed.length} network file${plural(unnamed.length)} ${agree(unnamed.length, \"is\", \"are\")} not in cysession.xml's network tree and were not read: ${listed(unnamed)}`,\n );\n }\n return choices.sort((a, b) => order.indexOf(a.file) - order.indexOf(b.file));\n}\n\n/**\n * W_CYS_SESSION_RECORD: a cysession.xml network record without an id, or one naming a file an\n * earlier record names.\n * @param report - the report\n * @param entry - the cysession.xml entry name\n * @param message - what is wrong and what is done\n */\nfunction sessionRecord(report: ImportReportBuilder, entry: string, message: string): void {\n report.warning(\"validation-error\", CYS_ISSUE.SESSION_RECORD, `${entryLabel(entry)}: ${message}`);\n}\n\n/**\n * Import one network of a 2.x session.\n * @param prepared - the prepared import\n * @param choice - the network\n * @param sink - the sink\n * @returns the style the network uses, or null\n */\nasync function import2(prepared: Prepared, choice: Choice2, sink: GraphSink): Promise<string | null> {\n const { report, inner, session } = prepared;\n const { doc, dialect } = await parseEntry(session, choice.file, report, inner);\n let unmatched = 0;\n for (const [list, column] of [\n [\"selectedNodes\", SELECTED_COLUMN],\n [\"hiddenNodes\", HIDDEN_COLUMN],\n ] as const) {\n unmatched += mark(doc.nodes, idsIn(choice.record, list), column);\n }\n for (const [list, column] of [\n [\"selectedEdges\", SELECTED_COLUMN],\n [\"hiddenEdges\", HIDDEN_COLUMN],\n ] as const) {\n unmatched += mark(doc.edges, idsIn(choice.record, list), column);\n }\n if (unmatched > 0) {\n report.warning(\n \"validation-error\",\n CYS_ISSUE.DANGLING_REFERENCE,\n `cysession.xml lists ${unmatched} selected or hidden name${plural(unmatched)} that ${choice.file.name} does not hold; they are not read`,\n );\n }\n const cyMeta = sessionMeta(prepared, {\n collection: null,\n network: choice.name,\n parentNetwork: choice.parent,\n visualStyle: choice.record.attrs.get(\"visualStyle\") ?? null,\n });\n const extras: EmitExtras = {\n sourceFormat: FORMAT,\n entry: choice.file.name,\n graphName: choice.name,\n metaExtra: { [META_KEY]: cyMeta },\n };\n const settings: XgmmlSettings = { labelAliases: true, cytoscapeEscapes: true, zAs: prepared.zAs };\n new XgmmlEmitter(doc, dialect, sink, report, inner, settings, extras).emit(null);\n return cyMeta.visualStyle;\n}\n\n/**\n * The element ids a `cysession.xml` network record lists under one key (`selectedNodes`, ...).\n * @param record - the network record\n * @param list - the list element's name\n * @returns the ids (2.x node names, edge identifiers)\n */\nfunction idsIn(record: XmlNode, list: string): Set<string> {\n const out = new Set<string>();\n for (const holder of record.children.filter((c) => c.name === list)) {\n for (const item of holder.children) {\n const id = item.attrs.get(\"id\");\n if (id !== undefined) {\n out.add(id);\n }\n }\n }\n return out;\n}\n\n/**\n * Give the records 2.x lists by name (a node's name is its label; an edge is named by its id or\n * label) a true cell in a bool column of the cytoscape namespace.\n * @param records - the node or edge records\n * @param ids - the listed names\n * @param column - the column\n * @returns how many listed names match no record\n */\nfunction mark(records: readonly (NodeRec | EdgeRec)[], ids: ReadonlySet<string>, column: string): number {\n if (ids.size === 0) {\n return 0;\n }\n const matched = new Set<string>();\n for (const record of records) {\n if (record.id !== null && ids.has(record.id)) {\n matched.add(record.id);\n }\n if (record.label !== null && ids.has(record.label)) {\n matched.add(record.label);\n }\n if ((record.id !== null && ids.has(record.id)) || (record.label !== null && ids.has(record.label))) {\n record.atts.push({\n name: column,\n type: null,\n cyType: \"Boolean\",\n elementType: null,\n value: \"true\",\n hidden: false,\n equation: false,\n children: [],\n extra: {},\n xml: null,\n hasGraph: false,\n text: \"\",\n line: record.line,\n namespace: CYTOSCAPE_NAMESPACE,\n });\n }\n }\n return ids.size - matched.size;\n}\n\n// ---------------------------------------------------------------------------------------- shared\n\n/** The session facts of `meta.extra.cytoscape`. */\ninterface SessionMeta {\n sessionVersion: string;\n collection: string | null;\n network: string;\n parentNetwork: string | null;\n visualStyle: string | null;\n skippedEntries: string[];\n groups?: { group: string; members: string[] }[];\n}\n\n/**\n * The session facts of one network, and the once-per-import warnings about what is not read\n * (styles, other entries).\n * @param prepared - the prepared import\n * @param facts - the network's facts\n * @param facts.collection - the root network's name (3.x)\n * @param facts.network - the network's id\n * @param facts.parentNetwork - the network it was made from\n * @param facts.visualStyle - the style its view uses\n * @returns the record\n */\nfunction sessionMeta(\n prepared: Prepared,\n facts: { collection: string | null; network: string; parentNetwork: string | null; visualStyle: string | null },\n): SessionMeta {\n const { layout } = prepared.session;\n const { report } = prepared;\n if (layout.styles.length > 0) {\n report.warning(\n \"unsupported\",\n CYS_ISSUE.STYLES_NOT_IMPORTED,\n `the session's styles (${layout.styles.map((s) => s.path).join(\", \")}) are not applied`,\n );\n }\n if (layout.skipped.length > 0) {\n report.warning(\n \"unsupported\",\n CYS_ISSUE.ENTRY_SKIPPED,\n `${layout.skipped.length} ${layout.skipped.length === 1 ? \"entry holds\" : \"entries hold\"} no graph data and ${agree(layout.skipped.length, \"was\", \"were\")} not read (apps, global tables, properties, images): ${listed(layout.skipped)}`,\n );\n }\n return {\n sessionVersion: layout.version,\n ...facts,\n skippedEntries: [...layout.skipped],\n };\n}\n\n/**\n * Import one network of a prepared session into a sink.\n * @param prepared - the prepared import\n * @param index - the network\n * @param sink - the sink\n * @returns the report\n */\nasync function importChoice(prepared: Prepared, index: number, sink: GraphSink): Promise<ImportReport> {\n const choice = prepared.choices[index];\n let visualStyle: string | null;\n if (choice.era === \"3\") {\n const parsed = prepared.docs.get(choice.network.name) as Parsed;\n visualStyle = await import3(prepared, choice, sink, parsed);\n } else {\n visualStyle = await import2(prepared, choice, sink);\n }\n await keepStyleSource(prepared, index, visualStyle);\n throwIfAborted(prepared.common.signal);\n return prepared.report.finish();\n}\n\n/**\n * Keep what the session's style reader needs (`styles()` gets it back as `context.kept`): the parsed\n * `session_vizmap.xml` of a 3.x session, the style the imported view names, and which network was imported.\n * Reading the styles never fails the import: a damaged entry is kept as the reason it cannot be read.\n * @param prepared - the prepared import\n * @param index - the network imported\n * @param visualStyle - the style its view names, or null\n */\nasync function keepStyleSource(prepared: Prepared, index: number, visualStyle: string | null): Promise<void> {\n const { layout } = prepared.session;\n const entry = layout.styles.find((e) => e.path.endsWith(\"session_vizmap.xml\"));\n let vizmap: XmlNode | null = null;\n let problem: string | null = null;\n if (layout.era === \"3\" && entry !== undefined) {\n const bytes = await entryBytes(prepared, entry);\n const tree =\n typeof bytes === \"string\"\n ? bytes\n : await parseXmlTree(bytes, entry.name, new ImportReportBuilder(FORMAT, 0), prepared.inner);\n if (typeof tree === \"string\") {\n problem = tree;\n } else {\n vizmap = tree;\n }\n }\n const source: SessionStyleSource = {\n era: layout.era,\n vizmap,\n problem,\n visualStyle,\n network: { index, name: prepared.choices[index].name },\n };\n prepared.report.keepForStyles(source);\n}\n\n/**\n * An entry's bytes for the styles, read outside the import's report: a damaged entry is the reason, never a failure.\n * @param prepared - the prepared import\n * @param entry - the entry\n * @returns the bytes, or why they cannot be read\n */\nasync function entryBytes(prepared: Prepared, entry: SessionEntry): Promise<Uint8Array | string> {\n try {\n return await prepared.session.read(entry, new ImportReportBuilder(FORMAT, 0));\n } catch (err) {\n if (err instanceof ImportError) {\n return err.message;\n }\n throw err;\n }\n}\n\n/**\n * An entry's text for the styles, or null when it cannot be read.\n * @param prepared - the prepared import\n * @param entry - the entry\n * @returns the text, or null\n */\nasync function entryText(prepared: Prepared, entry: SessionEntry): Promise<string | null> {\n const bytes = await entryBytes(prepared, entry);\n if (typeof bytes === \"string\") {\n return null;\n }\n try {\n return await readText(bytes, new ImportReportBuilder(FORMAT, 0), { signal: prepared.common.signal });\n } catch (err) {\n if (err instanceof ImportError) {\n return null;\n }\n throw err;\n }\n}\n\n/**\n * A text att of the network.\n * @param name - its name\n * @param value - its text\n * @returns the att\n */\nfunction textAtt(name: string, value: string): AttRec {\n return {\n name,\n type: \"string\",\n cyType: \"String\",\n elementType: null,\n value,\n hidden: false,\n equation: false,\n children: [],\n extra: {},\n xml: null,\n hasGraph: false,\n text: \"\",\n line: 0,\n namespace: null,\n };\n}\n\n/**\n * Import one network of a session.\n * @param input - the session bytes\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report; ImportError when the session cannot be read or the error limit is exceeded\n */\nasync function importCys(\n input: ImportInput,\n sink: GraphSink,\n options?: CysImportOptions & CommonImportOptions,\n): Promise<ImportReport> {\n const prepared = await prepare(input, sink, options);\n const index = chooseGraph(\n prepared.choices.map((c) => c.name),\n options,\n prepared.report,\n );\n if (prepared.choices.length > 1 && !graphChosen(options)) {\n prepared.report.warning(\n \"unsupported\",\n CYS_ISSUE.MULTIPLE_GRAPHS,\n `the session holds ${prepared.choices.length} networks; only the first is read (importAllGraphs() reads every one; graphIndex or graphName chooses one)`,\n );\n }\n const report = await importChoice(prepared, index, sink);\n prepared.session.done();\n return report;\n}\n\n/**\n * Import every network of a session, each into its own sink with its own report.\n * @param input - the session bytes\n * @param sinkFor - a sink per network\n * @param options - format-specific and common options\n * @returns one report per network\n */\nasync function importAllCys(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: CysImportOptions & CommonImportOptions,\n): Promise<ImportReport[]> {\n // the archive is opened and its network files parsed once: one byte budget, one progress,\n // and every network's report starts from what reading the session recorded\n const first = await prepare(input, null, options);\n const opened = first.report.fork();\n const reports: ImportReport[] = [];\n for (let i = 0; i < first.choices.length; i++) {\n const sink = sinkFor(i);\n const prepared = i === 0 ? first : { ...first, report: opened.fork() };\n reportSinkOptions(sink, options, prepared.report, true);\n reportUnusedOptions(options, prepared.report, USED_OPTIONS);\n reports.push(await importChoice(prepared, i, sink));\n }\n first.session.done();\n return reports;\n}\n\n/**\n * List the networks of a session from its network files, without reading tables or views.\n * @param input - the session bytes\n * @param options - the options\n * @returns one listing per network; node and edge counts for 3.x sessions only\n */\nasync function listCysGraphs(\n input: ImportInput,\n options?: CysImportOptions & CommonImportOptions,\n): Promise<readonly GraphListing[]> {\n const prepared = await prepare(input, null, options);\n return prepared.choices.map((choice, index) =>\n Object.freeze({\n index,\n name: choice.name,\n nodes: choice.era === \"3\" ? choice.nodes : null,\n edges: choice.era === \"3\" ? choice.edges : null,\n }),\n );\n}\n\n/**\n * A session's marker or folder name in the head of the archive, or an entry only a session has\n * (Cytoscape's app state, a network, view or table file), for a session whose folder was renamed.\n * The head is decoded whole, so a name can sit anywhere in it.\n */\nconst SESSION_NAMES: readonly RegExp[] = [\n /CytoscapeSession|cysession\\.xml/,\n /(?<!\\d)\\d+\\.\\d+\\.\\d+\\.version/,\n /(?:^|\\/)apps\\/org\\.cytoscape\\./,\n /(?:^|\\/)(?:networks|views)\\/\\d+-[^/]*\\.xgmml/,\n /(?:^|\\/)tables\\/\\d+-[^/]*\\/[^/]+\\.cytable/,\n];\n\n/**\n * Confidence that a head of bytes is a Cytoscape session: 0.95 for a zip whose head names the\n * session folder, its version marker or cysession.xml; 0 for any other zip, so an `.xlsx`, a\n * `.docx` or a zipped GraphML ranks as no format rather than as a broken session. The zip may\n * start after a short stub (a self-extracting archive) within the head.\n * @param head - the first bytes\n * @returns the confidence\n * @category Plugin helpers\n */\nexport function sniffCys(head: Uint8Array): number {\n for (let at = 0; at + 4 <= head.byteLength; at++) {\n if (startsLikeZip(head.subarray(at))) {\n return SESSION_NAMES.some((r) => r.test(decodeEntryName(head.subarray(at)))) ? 0.95 : 0;\n }\n }\n return 0;\n}\n\n/**\n * The Cytoscape session importer.\n * @category Built-in formats\n */\nexport const cysImporter: GraphImporter<CysImportOptions> = Object.freeze({\n format: FORMAT,\n options: Object.freeze([\"maxUncompressedBytes\", \"zAs\"]),\n extensions: EXTENSIONS,\n mimeTypes: MIME_TYPES,\n sniff: sniffCys,\n import: importCys,\n importAll: importAllCys,\n listGraphs: listCysGraphs,\n styles: readSessionStyles,\n});\n"],"names":["entries","localName","values","att"],"mappings":"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"}