@graphty/graph-io 0.3.47 → 0.3.49

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 (770) hide show
  1. package/dist/chunks/{approximations-wWjCRzKj.js → approximations-Bzn3L-je.js} +2 -2
  2. package/dist/chunks/{approximations-wWjCRzKj.js.map → approximations-Bzn3L-je.js.map} +1 -1
  3. package/dist/chunks/bends-BGXjv_U4.js +129 -0
  4. package/dist/chunks/bends-BGXjv_U4.js.map +1 -0
  5. package/dist/chunks/{block-DiGq58c3.js → block-iptrlMBb.js} +947 -134
  6. package/dist/chunks/block-iptrlMBb.js.map +1 -0
  7. package/dist/chunks/choose-CczZJaX_.js +717 -0
  8. package/dist/chunks/choose-CczZJaX_.js.map +1 -0
  9. package/dist/chunks/codes-BE2xir2k.js +157 -0
  10. package/dist/chunks/codes-BE2xir2k.js.map +1 -0
  11. package/dist/chunks/{constants-BKwqelYD.js → constants-CKkYLPtt.js} +2 -2
  12. package/dist/chunks/{constants-BKwqelYD.js.map → constants-CKkYLPtt.js.map} +1 -1
  13. package/dist/chunks/context-C3p0RQxR.js +664 -0
  14. package/dist/chunks/context-C3p0RQxR.js.map +1 -0
  15. package/dist/chunks/{convert-BcQ8_jMo.js → convert-Ct2zelbQ.js} +7 -2
  16. package/dist/chunks/convert-Ct2zelbQ.js.map +1 -0
  17. package/dist/chunks/credentials-DXHx7nwR.js +349 -0
  18. package/dist/chunks/credentials-DXHx7nwR.js.map +1 -0
  19. package/dist/chunks/cx-export-Bt6NoqTQ.js +259 -0
  20. package/dist/chunks/cx-export-Bt6NoqTQ.js.map +1 -0
  21. package/dist/chunks/descriptor-B28U25x4.js +60 -0
  22. package/dist/chunks/descriptor-B28U25x4.js.map +1 -0
  23. package/dist/chunks/descriptor-C-YDhtsn.js +48 -0
  24. package/dist/chunks/descriptor-C-YDhtsn.js.map +1 -0
  25. package/dist/chunks/descriptor-DLA5kINx.js +142 -0
  26. package/dist/chunks/descriptor-DLA5kINx.js.map +1 -0
  27. package/dist/chunks/{emit-CwU8cUmG.js → emit-BwHQkZle.js} +1690 -103
  28. package/dist/chunks/emit-BwHQkZle.js.map +1 -0
  29. package/dist/chunks/{escape-CgzxiYPg.js → escape-CuCIzNMB.js} +12 -12
  30. package/dist/chunks/{escape-CgzxiYPg.js.map → escape-CuCIzNMB.js.map} +1 -1
  31. package/dist/chunks/{export-BvqAXCKh.js → export-Cha4dRFz.js} +48 -1780
  32. package/dist/chunks/export-Cha4dRFz.js.map +1 -0
  33. package/dist/chunks/{exporter--Mk9gXCJ.js → exporter-BP6otMO6.js} +6 -4
  34. package/dist/chunks/{exporter--Mk9gXCJ.js.map → exporter-BP6otMO6.js.map} +1 -1
  35. package/dist/chunks/{exporter-CrDWIyiq.js → exporter-D2CETOMK.js} +1222 -154
  36. package/dist/chunks/exporter-D2CETOMK.js.map +1 -0
  37. package/dist/chunks/{exporter-DndFlGSa.js → exporter-D9yMtocA.js} +7 -6
  38. package/dist/chunks/{exporter-DndFlGSa.js.map → exporter-D9yMtocA.js.map} +1 -1
  39. package/dist/chunks/exporter-_jrBTnos.js +1009 -0
  40. package/dist/chunks/exporter-_jrBTnos.js.map +1 -0
  41. package/dist/chunks/{exporter-CJgfhF-l.js → exporter-nDfxIK5D.js} +9 -7
  42. package/dist/chunks/{exporter-CJgfhF-l.js.map → exporter-nDfxIK5D.js.map} +1 -1
  43. package/dist/chunks/format-BXiAb-1h.js +408 -0
  44. package/dist/chunks/format-BXiAb-1h.js.map +1 -0
  45. package/dist/chunks/{generic-Dq1ntt9q.js → generic-ymWCETAJ.js} +387 -31
  46. package/dist/chunks/generic-ymWCETAJ.js.map +1 -0
  47. package/dist/chunks/{importer-CMmeMWlC.js → importer-B92x1xY5.js} +15 -263
  48. package/dist/chunks/importer-B92x1xY5.js.map +1 -0
  49. package/dist/chunks/{importer-DiZRmOQG.js → importer-CT9mJ1nn.js} +328 -90
  50. package/dist/chunks/importer-CT9mJ1nn.js.map +1 -0
  51. package/dist/chunks/{importer-COTK9Tsl.js → importer-DaLTjbds.js} +116 -1099
  52. package/dist/chunks/importer-DaLTjbds.js.map +1 -0
  53. package/dist/chunks/{importer-iFYPEKaJ.js → importer-GREKMdIf.js} +28 -16
  54. package/dist/chunks/importer-GREKMdIf.js.map +1 -0
  55. package/dist/chunks/{importer-BSvfrX_h.js → importer-PqaaKKnY.js} +23 -1016
  56. package/dist/chunks/importer-PqaaKKnY.js.map +1 -0
  57. package/dist/chunks/{importer-yh_aBCU6.js → importer-Vn5QvmmJ.js} +66 -12
  58. package/dist/chunks/importer-Vn5QvmmJ.js.map +1 -0
  59. package/dist/chunks/{importer-e6LGpqHB.js → importer-vRq4h3j5.js} +1470 -354
  60. package/dist/chunks/importer-vRq4h3j5.js.map +1 -0
  61. package/dist/chunks/input-CAxt_aV-.js +1397 -0
  62. package/dist/chunks/input-CAxt_aV-.js.map +1 -0
  63. package/dist/chunks/{json-elements-DJZRZ6jd.js → json-elements-Cq76WjnZ.js} +4 -4
  64. package/dist/chunks/{json-elements-DJZRZ6jd.js.map → json-elements-Cq76WjnZ.js.map} +1 -1
  65. package/dist/chunks/{lexicon-CT69Kd87.js → lexicon-Clf4QIyl.js} +299 -77
  66. package/dist/chunks/lexicon-Clf4QIyl.js.map +1 -0
  67. package/dist/chunks/{ontology-export-G4MqRdux.js → ontology-export-OMo91mb0.js} +4 -3
  68. package/dist/chunks/{ontology-export-G4MqRdux.js.map → ontology-export-OMo91mb0.js.map} +1 -1
  69. package/dist/chunks/{records-CiaWZrFH.js → records-NJiYvekn.js} +2 -2
  70. package/dist/chunks/{records-CiaWZrFH.js.map → records-NJiYvekn.js.map} +1 -1
  71. package/dist/chunks/{format-BpQBx8MZ.js → report-CwMfYa9J.js} +70 -127
  72. package/dist/chunks/report-CwMfYa9J.js.map +1 -0
  73. package/dist/chunks/round-trip-Zm3_ivgq.js +79 -0
  74. package/dist/chunks/round-trip-Zm3_ivgq.js.map +1 -0
  75. package/dist/chunks/sigv4-EokFic1V.js +247 -0
  76. package/dist/chunks/sigv4-EokFic1V.js.map +1 -0
  77. package/dist/chunks/{styles-BQnsga7p.js → styles-CCs214_3.js} +1300 -168
  78. package/dist/chunks/styles-CCs214_3.js.map +1 -0
  79. package/dist/chunks/styles-Cm62yyQX.js +2812 -0
  80. package/dist/chunks/styles-Cm62yyQX.js.map +1 -0
  81. package/dist/chunks/styles-DPQQIig4.js +1928 -0
  82. package/dist/chunks/styles-DPQQIig4.js.map +1 -0
  83. package/dist/chunks/styles-yed-UMFdNqze.js +1213 -0
  84. package/dist/chunks/styles-yed-UMFdNqze.js.map +1 -0
  85. package/dist/chunks/{text-CzJNFOS9.js → text-ystE2bYi.js} +2 -2
  86. package/dist/chunks/{text-CzJNFOS9.js.map → text-ystE2bYi.js.map} +1 -1
  87. package/dist/csv.js +7 -5
  88. package/dist/csv.js.map +1 -1
  89. package/dist/cx.js +5 -4
  90. package/dist/cx.js.map +1 -1
  91. package/dist/cx2.js +2 -2
  92. package/dist/cys.js +1 -1
  93. package/dist/dot.js +5 -4
  94. package/dist/dot.js.map +1 -1
  95. package/dist/gexf.js +42 -10
  96. package/dist/gexf.js.map +1 -1
  97. package/dist/gml.js +850 -193
  98. package/dist/gml.js.map +1 -1
  99. package/dist/graph-io.js +1189 -220
  100. package/dist/graph-io.js.map +1 -1
  101. package/dist/graphml.js +3 -3
  102. package/dist/json.js +3 -2
  103. package/dist/neo4j.js +6 -4
  104. package/dist/neo4j.js.map +1 -1
  105. package/dist/obo.js +1 -1
  106. package/dist/pajek.js +1 -1
  107. package/dist/positions.js +45 -3
  108. package/dist/positions.js.map +1 -1
  109. package/dist/sources-cypher.d.ts +1 -0
  110. package/dist/sources-cypher.js +1351 -0
  111. package/dist/sources-cypher.js.map +1 -0
  112. package/dist/sources-ndex.d.ts +1 -0
  113. package/dist/sources-ndex.js +278 -0
  114. package/dist/sources-ndex.js.map +1 -0
  115. package/dist/sources-rest.d.ts +1 -0
  116. package/dist/sources-rest.js +1377 -0
  117. package/dist/sources-rest.js.map +1 -0
  118. package/dist/sources-sparql.d.ts +1 -0
  119. package/dist/sources-sparql.js +405 -0
  120. package/dist/sources-sparql.js.map +1 -0
  121. package/dist/src/common/report.d.ts +6 -3
  122. package/dist/src/common/report.d.ts.map +1 -1
  123. package/dist/src/common/report.js +15 -9
  124. package/dist/src/common/report.js.map +1 -1
  125. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cx/importer.js +5 -1
  127. package/dist/src/formats/cx/importer.js.map +1 -1
  128. package/dist/src/formats/cx/styles.d.ts +24 -1
  129. package/dist/src/formats/cx/styles.d.ts.map +1 -1
  130. package/dist/src/formats/cx/styles.js +118 -11
  131. package/dist/src/formats/cx/styles.js.map +1 -1
  132. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  133. package/dist/src/formats/cx2/importer.js +1 -0
  134. package/dist/src/formats/cx2/importer.js.map +1 -1
  135. package/dist/src/formats/cx2/styles.d.ts.map +1 -1
  136. package/dist/src/formats/cx2/styles.js +3 -1
  137. package/dist/src/formats/cx2/styles.js.map +1 -1
  138. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  139. package/dist/src/formats/cys/importer.js +1 -0
  140. package/dist/src/formats/cys/importer.js.map +1 -1
  141. package/dist/src/formats/cys/styles.d.ts +2 -0
  142. package/dist/src/formats/cys/styles.d.ts.map +1 -1
  143. package/dist/src/formats/cys/styles.js +15 -7
  144. package/dist/src/formats/cys/styles.js.map +1 -1
  145. package/dist/src/formats/dot/drawing.d.ts +98 -0
  146. package/dist/src/formats/dot/drawing.d.ts.map +1 -0
  147. package/dist/src/formats/dot/drawing.js +734 -0
  148. package/dist/src/formats/dot/drawing.js.map +1 -0
  149. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  150. package/dist/src/formats/dot/importer.js +108 -31
  151. package/dist/src/formats/dot/importer.js.map +1 -1
  152. package/dist/src/formats/dot/label-places.d.ts +34 -0
  153. package/dist/src/formats/dot/label-places.d.ts.map +1 -0
  154. package/dist/src/formats/dot/label-places.js +179 -0
  155. package/dist/src/formats/dot/label-places.js.map +1 -0
  156. package/dist/src/formats/dot/record.d.ts +50 -0
  157. package/dist/src/formats/dot/record.d.ts.map +1 -0
  158. package/dist/src/formats/dot/record.js +275 -0
  159. package/dist/src/formats/dot/record.js.map +1 -0
  160. package/dist/src/formats/dot/styles.d.ts +62 -2
  161. package/dist/src/formats/dot/styles.d.ts.map +1 -1
  162. package/dist/src/formats/dot/styles.js +1457 -120
  163. package/dist/src/formats/dot/styles.js.map +1 -1
  164. package/dist/src/formats/gexf/dialog-metrics.d.ts +15 -0
  165. package/dist/src/formats/gexf/dialog-metrics.d.ts.map +1 -0
  166. package/dist/src/formats/gexf/dialog-metrics.js +59 -0
  167. package/dist/src/formats/gexf/dialog-metrics.js.map +1 -0
  168. package/dist/src/formats/gexf/importer.d.ts +7 -0
  169. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  170. package/dist/src/formats/gexf/importer.js +41 -5
  171. package/dist/src/formats/gexf/importer.js.map +1 -1
  172. package/dist/src/formats/gexf/preview.d.ts +77 -0
  173. package/dist/src/formats/gexf/preview.d.ts.map +1 -0
  174. package/dist/src/formats/gexf/preview.js +191 -0
  175. package/dist/src/formats/gexf/preview.js.map +1 -0
  176. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  177. package/dist/src/formats/gexf/schema.js +2 -1
  178. package/dist/src/formats/gexf/schema.js.map +1 -1
  179. package/dist/src/formats/gexf/styles.d.ts +60 -16
  180. package/dist/src/formats/gexf/styles.d.ts.map +1 -1
  181. package/dist/src/formats/gexf/styles.js +883 -131
  182. package/dist/src/formats/gexf/styles.js.map +1 -1
  183. package/dist/src/formats/gml/importer.d.ts +5 -2
  184. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  185. package/dist/src/formats/gml/importer.js +258 -71
  186. package/dist/src/formats/gml/importer.js.map +1 -1
  187. package/dist/src/formats/gml/index.d.ts +1 -1
  188. package/dist/src/formats/gml/index.d.ts.map +1 -1
  189. package/dist/src/formats/gml/index.js +1 -1
  190. package/dist/src/formats/gml/index.js.map +1 -1
  191. package/dist/src/formats/gml/positions.d.ts +7 -0
  192. package/dist/src/formats/gml/positions.d.ts.map +1 -1
  193. package/dist/src/formats/gml/positions.js +29 -7
  194. package/dist/src/formats/gml/positions.js.map +1 -1
  195. package/dist/src/formats/gml/styles.d.ts.map +1 -1
  196. package/dist/src/formats/gml/styles.js +756 -103
  197. package/dist/src/formats/gml/styles.js.map +1 -1
  198. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
  199. package/dist/src/formats/graphml/styles-plain.js +8 -12
  200. package/dist/src/formats/graphml/styles-plain.js.map +1 -1
  201. package/dist/src/formats/graphml/styles-yed.d.ts +21 -15
  202. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
  203. package/dist/src/formats/graphml/styles-yed.js +749 -148
  204. package/dist/src/formats/graphml/styles-yed.js.map +1 -1
  205. package/dist/src/formats/graphml/styles-yfiles3.d.ts +1 -1
  206. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -1
  207. package/dist/src/formats/graphml/styles-yfiles3.js +429 -64
  208. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -1
  209. package/dist/src/formats/graphml/yfiles.d.ts +3 -3
  210. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  211. package/dist/src/formats/graphml/yfiles.js +16 -6
  212. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  213. package/dist/src/formats/json/dialect.d.ts +3 -2
  214. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  215. package/dist/src/formats/json/dialect.js +39 -5
  216. package/dist/src/formats/json/dialect.js.map +1 -1
  217. package/dist/src/formats/json/importer.d.ts +13 -2
  218. package/dist/src/formats/json/importer.d.ts.map +1 -1
  219. package/dist/src/formats/json/importer.js +42 -6
  220. package/dist/src/formats/json/importer.js.map +1 -1
  221. package/dist/src/formats/json/index.d.ts +1 -1
  222. package/dist/src/formats/json/index.d.ts.map +1 -1
  223. package/dist/src/formats/json/index.js +1 -1
  224. package/dist/src/formats/json/index.js.map +1 -1
  225. package/dist/src/formats/json/positions.d.ts +5 -2
  226. package/dist/src/formats/json/positions.d.ts.map +1 -1
  227. package/dist/src/formats/json/positions.js +20 -4
  228. package/dist/src/formats/json/positions.js.map +1 -1
  229. package/dist/src/formats/json/styles.d.ts +12 -1
  230. package/dist/src/formats/json/styles.d.ts.map +1 -1
  231. package/dist/src/formats/json/styles.js +1755 -136
  232. package/dist/src/formats/json/styles.js.map +1 -1
  233. package/dist/src/formats/pajek/draw.d.ts +96 -0
  234. package/dist/src/formats/pajek/draw.d.ts.map +1 -0
  235. package/dist/src/formats/pajek/draw.js +372 -0
  236. package/dist/src/formats/pajek/draw.js.map +1 -0
  237. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  238. package/dist/src/formats/pajek/exporter.js +70 -51
  239. package/dist/src/formats/pajek/exporter.js.map +1 -1
  240. package/dist/src/formats/pajek/importer.d.ts +9 -0
  241. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  242. package/dist/src/formats/pajek/importer.js +233 -102
  243. package/dist/src/formats/pajek/importer.js.map +1 -1
  244. package/dist/src/formats/pajek/index.d.ts +1 -0
  245. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  246. package/dist/src/formats/pajek/index.js.map +1 -1
  247. package/dist/src/formats/pajek/styles.d.ts +15 -7
  248. package/dist/src/formats/pajek/styles.d.ts.map +1 -1
  249. package/dist/src/formats/pajek/styles.js +1279 -114
  250. package/dist/src/formats/pajek/styles.js.map +1 -1
  251. package/dist/src/formats/pajek/syntax.d.ts +10 -1
  252. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  253. package/dist/src/formats/pajek/syntax.js +26 -2
  254. package/dist/src/formats/pajek/syntax.js.map +1 -1
  255. package/dist/src/formats/xgmml/emit.d.ts +1 -0
  256. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  257. package/dist/src/formats/xgmml/emit.js +65 -5
  258. package/dist/src/formats/xgmml/emit.js.map +1 -1
  259. package/dist/src/formats/xgmml/styles.d.ts +23 -3
  260. package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
  261. package/dist/src/formats/xgmml/styles.js +278 -60
  262. package/dist/src/formats/xgmml/styles.js.map +1 -1
  263. package/dist/src/index.d.ts +10 -2
  264. package/dist/src/index.d.ts.map +1 -1
  265. package/dist/src/index.js +11 -2
  266. package/dist/src/index.js.map +1 -1
  267. package/dist/src/positions/convert.d.ts.map +1 -1
  268. package/dist/src/positions/convert.js +11 -1
  269. package/dist/src/positions/convert.js.map +1 -1
  270. package/dist/src/positions/extract.d.ts.map +1 -1
  271. package/dist/src/positions/extract.js +53 -1
  272. package/dist/src/positions/extract.js.map +1 -1
  273. package/dist/src/positions/index.d.ts +1 -1
  274. package/dist/src/positions/index.d.ts.map +1 -1
  275. package/dist/src/positions/types.d.ts +59 -0
  276. package/dist/src/positions/types.d.ts.map +1 -1
  277. package/dist/src/registry.d.ts +173 -1
  278. package/dist/src/registry.d.ts.map +1 -1
  279. package/dist/src/registry.js +196 -1
  280. package/dist/src/registry.js.map +1 -1
  281. package/dist/src/sources/builtins.d.ts +11 -0
  282. package/dist/src/sources/builtins.d.ts.map +1 -0
  283. package/dist/src/sources/builtins.js +53 -0
  284. package/dist/src/sources/builtins.js.map +1 -0
  285. package/dist/src/sources/codes.d.ts +230 -0
  286. package/dist/src/sources/codes.d.ts.map +1 -0
  287. package/dist/src/sources/codes.js +58 -0
  288. package/dist/src/sources/codes.js.map +1 -0
  289. package/dist/src/sources/context.d.ts +112 -0
  290. package/dist/src/sources/context.d.ts.map +1 -0
  291. package/dist/src/sources/context.js +740 -0
  292. package/dist/src/sources/context.js.map +1 -0
  293. package/dist/src/sources/credentials.d.ts +179 -0
  294. package/dist/src/sources/credentials.d.ts.map +1 -0
  295. package/dist/src/sources/credentials.js +301 -0
  296. package/dist/src/sources/credentials.js.map +1 -0
  297. package/dist/src/sources/cypher/descriptor.d.ts +21 -0
  298. package/dist/src/sources/cypher/descriptor.d.ts.map +1 -0
  299. package/dist/src/sources/cypher/descriptor.js +124 -0
  300. package/dist/src/sources/cypher/descriptor.js.map +1 -0
  301. package/dist/src/sources/cypher/flatten.d.ts +72 -0
  302. package/dist/src/sources/cypher/flatten.d.ts.map +1 -0
  303. package/dist/src/sources/cypher/flatten.js +279 -0
  304. package/dist/src/sources/cypher/flatten.js.map +1 -0
  305. package/dist/src/sources/cypher/index.d.ts +33 -0
  306. package/dist/src/sources/cypher/index.d.ts.map +1 -0
  307. package/dist/src/sources/cypher/index.js +511 -0
  308. package/dist/src/sources/cypher/index.js.map +1 -0
  309. package/dist/src/sources/cypher/params.d.ts +40 -0
  310. package/dist/src/sources/cypher/params.d.ts.map +1 -0
  311. package/dist/src/sources/cypher/params.js +6 -0
  312. package/dist/src/sources/cypher/params.js.map +1 -0
  313. package/dist/src/sources/cypher/profiles.d.ts +44 -0
  314. package/dist/src/sources/cypher/profiles.d.ts.map +1 -0
  315. package/dist/src/sources/cypher/profiles.js +61 -0
  316. package/dist/src/sources/cypher/profiles.js.map +1 -0
  317. package/dist/src/sources/cypher/query-builder.d.ts +123 -0
  318. package/dist/src/sources/cypher/query-builder.d.ts.map +1 -0
  319. package/dist/src/sources/cypher/query-builder.js +267 -0
  320. package/dist/src/sources/cypher/query-builder.js.map +1 -0
  321. package/dist/src/sources/cypher/transports/bolt.d.ts +21 -0
  322. package/dist/src/sources/cypher/transports/bolt.d.ts.map +1 -0
  323. package/dist/src/sources/cypher/transports/bolt.js +185 -0
  324. package/dist/src/sources/cypher/transports/bolt.js.map +1 -0
  325. package/dist/src/sources/cypher/transports/neptune-analytics.d.ts +15 -0
  326. package/dist/src/sources/cypher/transports/neptune-analytics.d.ts.map +1 -0
  327. package/dist/src/sources/cypher/transports/neptune-analytics.js +38 -0
  328. package/dist/src/sources/cypher/transports/neptune-analytics.js.map +1 -0
  329. package/dist/src/sources/cypher/transports/neptune-https.d.ts +31 -0
  330. package/dist/src/sources/cypher/transports/neptune-https.d.ts.map +1 -0
  331. package/dist/src/sources/cypher/transports/neptune-https.js +104 -0
  332. package/dist/src/sources/cypher/transports/neptune-https.js.map +1 -0
  333. package/dist/src/sources/cypher/transports/query-api.d.ts +14 -0
  334. package/dist/src/sources/cypher/transports/query-api.d.ts.map +1 -0
  335. package/dist/src/sources/cypher/transports/query-api.js +80 -0
  336. package/dist/src/sources/cypher/transports/query-api.js.map +1 -0
  337. package/dist/src/sources/cypher/transports/transport.d.ts +78 -0
  338. package/dist/src/sources/cypher/transports/transport.d.ts.map +1 -0
  339. package/dist/src/sources/cypher/transports/transport.js +77 -0
  340. package/dist/src/sources/cypher/transports/transport.js.map +1 -0
  341. package/dist/src/sources/cypher/types-map.d.ts +91 -0
  342. package/dist/src/sources/cypher/types-map.d.ts.map +1 -0
  343. package/dist/src/sources/cypher/types-map.js +306 -0
  344. package/dist/src/sources/cypher/types-map.js.map +1 -0
  345. package/dist/src/sources/define.d.ts +47 -0
  346. package/dist/src/sources/define.d.ts.map +1 -0
  347. package/dist/src/sources/define.js +173 -0
  348. package/dist/src/sources/define.js.map +1 -0
  349. package/dist/src/sources/fail.d.ts +33 -0
  350. package/dist/src/sources/fail.d.ts.map +1 -0
  351. package/dist/src/sources/fail.js +49 -0
  352. package/dist/src/sources/fail.js.map +1 -0
  353. package/dist/src/sources/ids.d.ts +69 -0
  354. package/dist/src/sources/ids.d.ts.map +1 -0
  355. package/dist/src/sources/ids.js +69 -0
  356. package/dist/src/sources/ids.js.map +1 -0
  357. package/dist/src/sources/ndex/client.d.ts +31 -0
  358. package/dist/src/sources/ndex/client.d.ts.map +1 -0
  359. package/dist/src/sources/ndex/client.js +90 -0
  360. package/dist/src/sources/ndex/client.js.map +1 -0
  361. package/dist/src/sources/ndex/descriptor.d.ts +10 -0
  362. package/dist/src/sources/ndex/descriptor.d.ts.map +1 -0
  363. package/dist/src/sources/ndex/descriptor.js +55 -0
  364. package/dist/src/sources/ndex/descriptor.js.map +1 -0
  365. package/dist/src/sources/ndex/expand.d.ts +20 -0
  366. package/dist/src/sources/ndex/expand.d.ts.map +1 -0
  367. package/dist/src/sources/ndex/expand.js +87 -0
  368. package/dist/src/sources/ndex/expand.js.map +1 -0
  369. package/dist/src/sources/ndex/index.d.ts +25 -0
  370. package/dist/src/sources/ndex/index.d.ts.map +1 -0
  371. package/dist/src/sources/ndex/index.js +191 -0
  372. package/dist/src/sources/ndex/index.js.map +1 -0
  373. package/dist/src/sources/ndex/params.d.ts +17 -0
  374. package/dist/src/sources/ndex/params.d.ts.map +1 -0
  375. package/dist/src/sources/ndex/params.js +6 -0
  376. package/dist/src/sources/ndex/params.js.map +1 -0
  377. package/dist/src/sources/ndex/share-url.d.ts +40 -0
  378. package/dist/src/sources/ndex/share-url.d.ts.map +1 -0
  379. package/dist/src/sources/ndex/share-url.js +64 -0
  380. package/dist/src/sources/ndex/share-url.js.map +1 -0
  381. package/dist/src/sources/params.d.ts +31 -0
  382. package/dist/src/sources/params.d.ts.map +1 -0
  383. package/dist/src/sources/params.js +6 -0
  384. package/dist/src/sources/params.js.map +1 -0
  385. package/dist/src/sources/registry.d.ts +118 -0
  386. package/dist/src/sources/registry.d.ts.map +1 -0
  387. package/dist/src/sources/registry.js +193 -0
  388. package/dist/src/sources/registry.js.map +1 -0
  389. package/dist/src/sources/rest/descriptor.d.ts +16 -0
  390. package/dist/src/sources/rest/descriptor.d.ts.map +1 -0
  391. package/dist/src/sources/rest/descriptor.js +76 -0
  392. package/dist/src/sources/rest/descriptor.js.map +1 -0
  393. package/dist/src/sources/rest/index.d.ts +14 -0
  394. package/dist/src/sources/rest/index.d.ts.map +1 -0
  395. package/dist/src/sources/rest/index.js +13 -0
  396. package/dist/src/sources/rest/index.js.map +1 -0
  397. package/dist/src/sources/rest/mapping.d.ts +30 -0
  398. package/dist/src/sources/rest/mapping.d.ts.map +1 -0
  399. package/dist/src/sources/rest/mapping.js +362 -0
  400. package/dist/src/sources/rest/mapping.js.map +1 -0
  401. package/dist/src/sources/rest/openalex.d.ts +27 -0
  402. package/dist/src/sources/rest/openalex.d.ts.map +1 -0
  403. package/dist/src/sources/rest/openalex.js +269 -0
  404. package/dist/src/sources/rest/openalex.js.map +1 -0
  405. package/dist/src/sources/rest/paging.d.ts +53 -0
  406. package/dist/src/sources/rest/paging.d.ts.map +1 -0
  407. package/dist/src/sources/rest/paging.js +138 -0
  408. package/dist/src/sources/rest/paging.js.map +1 -0
  409. package/dist/src/sources/rest/params.d.ts +216 -0
  410. package/dist/src/sources/rest/params.d.ts.map +1 -0
  411. package/dist/src/sources/rest/params.js +7 -0
  412. package/dist/src/sources/rest/params.js.map +1 -0
  413. package/dist/src/sources/rest/records.d.ts +41 -0
  414. package/dist/src/sources/rest/records.d.ts.map +1 -0
  415. package/dist/src/sources/rest/records.js +240 -0
  416. package/dist/src/sources/rest/records.js.map +1 -0
  417. package/dist/src/sources/rest/samples/deps-dev.d.ts +10 -0
  418. package/dist/src/sources/rest/samples/deps-dev.d.ts.map +1 -0
  419. package/dist/src/sources/rest/samples/deps-dev.js +47 -0
  420. package/dist/src/sources/rest/samples/deps-dev.js.map +1 -0
  421. package/dist/src/sources/rest/samples/string.d.ts +9 -0
  422. package/dist/src/sources/rest/samples/string.d.ts.map +1 -0
  423. package/dist/src/sources/rest/samples/string.js +42 -0
  424. package/dist/src/sources/rest/samples/string.js.map +1 -0
  425. package/dist/src/sources/rest/selectors.d.ts +41 -0
  426. package/dist/src/sources/rest/selectors.d.ts.map +1 -0
  427. package/dist/src/sources/rest/selectors.js +81 -0
  428. package/dist/src/sources/rest/selectors.js.map +1 -0
  429. package/dist/src/sources/rest/source.d.ts +67 -0
  430. package/dist/src/sources/rest/source.d.ts.map +1 -0
  431. package/dist/src/sources/rest/source.js +650 -0
  432. package/dist/src/sources/rest/source.js.map +1 -0
  433. package/dist/src/sources/rest/templates.d.ts +38 -0
  434. package/dist/src/sources/rest/templates.d.ts.map +1 -0
  435. package/dist/src/sources/rest/templates.js +125 -0
  436. package/dist/src/sources/rest/templates.js.map +1 -0
  437. package/dist/src/sources/run.d.ts +93 -0
  438. package/dist/src/sources/run.d.ts.map +1 -0
  439. package/dist/src/sources/run.js +673 -0
  440. package/dist/src/sources/run.js.map +1 -0
  441. package/dist/src/sources/sha256.d.ts +12 -0
  442. package/dist/src/sources/sha256.d.ts.map +1 -0
  443. package/dist/src/sources/sha256.js +95 -0
  444. package/dist/src/sources/sha256.js.map +1 -0
  445. package/dist/src/sources/sigv4.d.ts +26 -0
  446. package/dist/src/sources/sigv4.d.ts.map +1 -0
  447. package/dist/src/sources/sigv4.js +184 -0
  448. package/dist/src/sources/sigv4.js.map +1 -0
  449. package/dist/src/sources/sparql/descriptor.d.ts +10 -0
  450. package/dist/src/sources/sparql/descriptor.d.ts.map +1 -0
  451. package/dist/src/sources/sparql/descriptor.js +64 -0
  452. package/dist/src/sources/sparql/descriptor.js.map +1 -0
  453. package/dist/src/sources/sparql/index.d.ts +28 -0
  454. package/dist/src/sources/sparql/index.d.ts.map +1 -0
  455. package/dist/src/sources/sparql/index.js +314 -0
  456. package/dist/src/sources/sparql/index.js.map +1 -0
  457. package/dist/src/sources/sparql/ntriples.d.ts +69 -0
  458. package/dist/src/sources/sparql/ntriples.d.ts.map +1 -0
  459. package/dist/src/sources/sparql/ntriples.js +180 -0
  460. package/dist/src/sources/sparql/ntriples.js.map +1 -0
  461. package/dist/src/sources/sparql/params.d.ts +27 -0
  462. package/dist/src/sources/sparql/params.d.ts.map +1 -0
  463. package/dist/src/sources/sparql/params.js +5 -0
  464. package/dist/src/sources/sparql/params.js.map +1 -0
  465. package/dist/src/sources/sparql/query.d.ts +72 -0
  466. package/dist/src/sources/sparql/query.d.ts.map +1 -0
  467. package/dist/src/sources/sparql/query.js +113 -0
  468. package/dist/src/sources/sparql/query.js.map +1 -0
  469. package/dist/src/sources/testing.d.ts +96 -0
  470. package/dist/src/sources/testing.d.ts.map +1 -0
  471. package/dist/src/sources/testing.js +138 -0
  472. package/dist/src/sources/testing.js.map +1 -0
  473. package/dist/src/sources/types.d.ts +696 -0
  474. package/dist/src/sources/types.d.ts.map +1 -0
  475. package/dist/src/sources/types.js +10 -0
  476. package/dist/src/sources/types.js.map +1 -0
  477. package/dist/src/styles/annotations.d.ts +61 -5
  478. package/dist/src/styles/annotations.d.ts.map +1 -1
  479. package/dist/src/styles/annotations.js +130 -22
  480. package/dist/src/styles/annotations.js.map +1 -1
  481. package/dist/src/styles/canon/bends.d.ts +46 -0
  482. package/dist/src/styles/canon/bends.d.ts.map +1 -1
  483. package/dist/src/styles/canon/bends.js +123 -0
  484. package/dist/src/styles/canon/bends.js.map +1 -1
  485. package/dist/src/styles/canon/color-tables.d.ts +6 -1
  486. package/dist/src/styles/canon/color-tables.d.ts.map +1 -1
  487. package/dist/src/styles/canon/color-tables.js +10 -4
  488. package/dist/src/styles/canon/color-tables.js.map +1 -1
  489. package/dist/src/styles/canon/color.d.ts +3 -1
  490. package/dist/src/styles/canon/color.d.ts.map +1 -1
  491. package/dist/src/styles/canon/color.js +103 -3
  492. package/dist/src/styles/canon/color.js.map +1 -1
  493. package/dist/src/styles/canon/enums.d.ts +2 -2
  494. package/dist/src/styles/canon/enums.d.ts.map +1 -1
  495. package/dist/src/styles/canon/enums.js +82 -7
  496. package/dist/src/styles/canon/enums.js.map +1 -1
  497. package/dist/src/styles/canon/graphviz.d.ts +12 -3
  498. package/dist/src/styles/canon/graphviz.d.ts.map +1 -1
  499. package/dist/src/styles/canon/graphviz.js +57 -9
  500. package/dist/src/styles/canon/graphviz.js.map +1 -1
  501. package/dist/src/styles/canon/number.d.ts +8 -0
  502. package/dist/src/styles/canon/number.d.ts.map +1 -1
  503. package/dist/src/styles/canon/number.js +18 -0
  504. package/dist/src/styles/canon/number.js.map +1 -1
  505. package/dist/src/styles/canon/text.d.ts +29 -2
  506. package/dist/src/styles/canon/text.d.ts.map +1 -1
  507. package/dist/src/styles/canon/text.js +156 -16
  508. package/dist/src/styles/canon/text.js.map +1 -1
  509. package/dist/src/styles/codes.d.ts +2 -0
  510. package/dist/src/styles/codes.d.ts.map +1 -1
  511. package/dist/src/styles/codes.js +2 -0
  512. package/dist/src/styles/codes.js.map +1 -1
  513. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
  514. package/dist/src/styles/cyjs/cascade.js +1037 -35
  515. package/dist/src/styles/cyjs/cascade.js.map +1 -1
  516. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
  517. package/dist/src/styles/cyjs/defaults-table.js +5 -0
  518. package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
  519. package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
  520. package/dist/src/styles/cyjs/emit.js +216 -12
  521. package/dist/src/styles/cyjs/emit.js.map +1 -1
  522. package/dist/src/styles/cyjs/face.d.ts +20 -0
  523. package/dist/src/styles/cyjs/face.d.ts.map +1 -0
  524. package/dist/src/styles/cyjs/face.js +332 -0
  525. package/dist/src/styles/cyjs/face.js.map +1 -0
  526. package/dist/src/styles/cyjs/mappers.d.ts +48 -2
  527. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
  528. package/dist/src/styles/cyjs/mappers.js +463 -26
  529. package/dist/src/styles/cyjs/mappers.js.map +1 -1
  530. package/dist/src/styles/cyjs/routes.d.ts +53 -0
  531. package/dist/src/styles/cyjs/routes.d.ts.map +1 -0
  532. package/dist/src/styles/cyjs/routes.js +360 -0
  533. package/dist/src/styles/cyjs/routes.js.map +1 -0
  534. package/dist/src/styles/cytoscape/charts.d.ts +23 -0
  535. package/dist/src/styles/cytoscape/charts.d.ts.map +1 -0
  536. package/dist/src/styles/cytoscape/charts.js +560 -0
  537. package/dist/src/styles/cytoscape/charts.js.map +1 -0
  538. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
  539. package/dist/src/styles/cytoscape/emit.js +204 -44
  540. package/dist/src/styles/cytoscape/emit.js.map +1 -1
  541. package/dist/src/styles/cytoscape/lexicon.d.ts +97 -3
  542. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
  543. package/dist/src/styles/cytoscape/lexicon.js +413 -79
  544. package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
  545. package/dist/src/styles/cytoscape/mappings.d.ts +30 -0
  546. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -1
  547. package/dist/src/styles/cytoscape/mappings.js +92 -0
  548. package/dist/src/styles/cytoscape/mappings.js.map +1 -1
  549. package/dist/src/styles/cytoscape/resolve.d.ts +46 -3
  550. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
  551. package/dist/src/styles/cytoscape/resolve.js +632 -22
  552. package/dist/src/styles/cytoscape/resolve.js.map +1 -1
  553. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -1
  554. package/dist/src/styles/cytoscape/translate.js +10 -10
  555. package/dist/src/styles/cytoscape/translate.js.map +1 -1
  556. package/dist/src/styles/defaults.d.ts +50 -0
  557. package/dist/src/styles/defaults.d.ts.map +1 -1
  558. package/dist/src/styles/defaults.js +315 -37
  559. package/dist/src/styles/defaults.js.map +1 -1
  560. package/dist/src/styles/index.d.ts +4 -3
  561. package/dist/src/styles/index.d.ts.map +1 -1
  562. package/dist/src/styles/index.js +3 -2
  563. package/dist/src/styles/index.js.map +1 -1
  564. package/dist/src/styles/internal.d.ts +1 -0
  565. package/dist/src/styles/internal.d.ts.map +1 -1
  566. package/dist/src/styles/internal.js +1 -0
  567. package/dist/src/styles/internal.js.map +1 -1
  568. package/dist/src/styles/io/block.d.ts.map +1 -1
  569. package/dist/src/styles/io/block.js +9 -0
  570. package/dist/src/styles/io/block.js.map +1 -1
  571. package/dist/src/styles/io/generic.d.ts.map +1 -1
  572. package/dist/src/styles/io/generic.js +56 -16
  573. package/dist/src/styles/io/generic.js.map +1 -1
  574. package/dist/src/styles/io/round-trip.d.ts +56 -0
  575. package/dist/src/styles/io/round-trip.d.ts.map +1 -0
  576. package/dist/src/styles/io/round-trip.js +138 -0
  577. package/dist/src/styles/io/round-trip.js.map +1 -0
  578. package/dist/src/styles/io/writer.d.ts.map +1 -1
  579. package/dist/src/styles/io/writer.js +13 -4
  580. package/dist/src/styles/io/writer.js.map +1 -1
  581. package/dist/src/styles/notes.d.ts.map +1 -1
  582. package/dist/src/styles/notes.js +1 -0
  583. package/dist/src/styles/notes.js.map +1 -1
  584. package/dist/src/styles/plan/features.d.ts +1 -1
  585. package/dist/src/styles/plan/features.d.ts.map +1 -1
  586. package/dist/src/styles/plan/features.js +22 -2
  587. package/dist/src/styles/plan/features.js.map +1 -1
  588. package/dist/src/styles/plan/index.d.ts +1 -1
  589. package/dist/src/styles/plan/index.d.ts.map +1 -1
  590. package/dist/src/styles/plan/index.js +1 -1
  591. package/dist/src/styles/plan/index.js.map +1 -1
  592. package/dist/src/styles/plan/plan.d.ts.map +1 -1
  593. package/dist/src/styles/plan/plan.js +61 -4
  594. package/dist/src/styles/plan/plan.js.map +1 -1
  595. package/dist/src/styles/plan/resolve.d.ts +13 -1
  596. package/dist/src/styles/plan/resolve.d.ts.map +1 -1
  597. package/dist/src/styles/plan/resolve.js +53 -6
  598. package/dist/src/styles/plan/resolve.js.map +1 -1
  599. package/dist/src/styles/slots.d.ts +14 -0
  600. package/dist/src/styles/slots.d.ts.map +1 -0
  601. package/dist/src/styles/slots.js +20 -0
  602. package/dist/src/styles/slots.js.map +1 -0
  603. package/dist/src/styles/types.d.ts +638 -5
  604. package/dist/src/styles/types.d.ts.map +1 -1
  605. package/dist/src/styles/vocabulary.d.ts +3 -2
  606. package/dist/src/styles/vocabulary.d.ts.map +1 -1
  607. package/dist/src/styles/vocabulary.js +218 -1
  608. package/dist/src/styles/vocabulary.js.map +1 -1
  609. package/dist/src/types.d.ts +19 -5
  610. package/dist/src/types.d.ts.map +1 -1
  611. package/dist/src/types.js.map +1 -1
  612. package/dist/styles.js +29 -238
  613. package/dist/styles.js.map +1 -1
  614. package/dist/xgmml.js +3 -3
  615. package/docs/samples/people.json +6 -0
  616. package/package.json +53 -8
  617. package/src/common/report.ts +27 -7
  618. package/src/formats/cx/importer.ts +6 -1
  619. package/src/formats/cx/styles.ts +144 -9
  620. package/src/formats/cx2/importer.ts +1 -0
  621. package/src/formats/cx2/styles.ts +3 -1
  622. package/src/formats/cys/importer.ts +1 -0
  623. package/src/formats/cys/styles.ts +27 -5
  624. package/src/formats/dot/drawing.ts +799 -0
  625. package/src/formats/dot/importer.ts +120 -35
  626. package/src/formats/dot/label-places.ts +228 -0
  627. package/src/formats/dot/record.ts +336 -0
  628. package/src/formats/dot/styles.ts +1657 -154
  629. package/src/formats/gexf/dialog-metrics.ts +61 -0
  630. package/src/formats/gexf/importer.ts +50 -5
  631. package/src/formats/gexf/preview.ts +217 -0
  632. package/src/formats/gexf/schema.ts +2 -1
  633. package/src/formats/gexf/styles.ts +1144 -142
  634. package/src/formats/gml/importer.ts +291 -76
  635. package/src/formats/gml/index.ts +1 -1
  636. package/src/formats/gml/positions.ts +29 -7
  637. package/src/formats/gml/styles.ts +854 -111
  638. package/src/formats/graphml/styles-plain.ts +8 -23
  639. package/src/formats/graphml/styles-yed.ts +821 -159
  640. package/src/formats/graphml/styles-yfiles3.ts +485 -63
  641. package/src/formats/graphml/yfiles.ts +19 -6
  642. package/src/formats/json/dialect.ts +41 -5
  643. package/src/formats/json/importer.ts +59 -7
  644. package/src/formats/json/index.ts +1 -0
  645. package/src/formats/json/positions.ts +22 -5
  646. package/src/formats/json/styles.ts +2041 -185
  647. package/src/formats/pajek/draw.ts +458 -0
  648. package/src/formats/pajek/exporter.ts +81 -49
  649. package/src/formats/pajek/importer.ts +278 -103
  650. package/src/formats/pajek/index.ts +1 -0
  651. package/src/formats/pajek/styles.ts +1382 -133
  652. package/src/formats/pajek/syntax.ts +27 -2
  653. package/src/formats/xgmml/emit.ts +73 -5
  654. package/src/formats/xgmml/styles.ts +331 -71
  655. package/src/index.ts +94 -0
  656. package/src/positions/convert.ts +12 -1
  657. package/src/positions/extract.ts +55 -1
  658. package/src/positions/index.ts +1 -0
  659. package/src/positions/types.ts +60 -0
  660. package/src/registry.ts +326 -1
  661. package/src/sources/builtins.ts +63 -0
  662. package/src/sources/codes.ts +235 -0
  663. package/src/sources/context.ts +894 -0
  664. package/src/sources/credentials.ts +409 -0
  665. package/src/sources/cypher/descriptor.ts +131 -0
  666. package/src/sources/cypher/flatten.ts +323 -0
  667. package/src/sources/cypher/index.ts +628 -0
  668. package/src/sources/cypher/params.ts +41 -0
  669. package/src/sources/cypher/profiles.ts +78 -0
  670. package/src/sources/cypher/query-builder.ts +327 -0
  671. package/src/sources/cypher/transports/bolt.ts +228 -0
  672. package/src/sources/cypher/transports/neptune-analytics.ts +41 -0
  673. package/src/sources/cypher/transports/neptune-https.ts +122 -0
  674. package/src/sources/cypher/transports/query-api.ts +100 -0
  675. package/src/sources/cypher/transports/transport.ts +139 -0
  676. package/src/sources/cypher/types-map.ts +418 -0
  677. package/src/sources/define.ts +195 -0
  678. package/src/sources/fail.ts +70 -0
  679. package/src/sources/ids.ts +80 -0
  680. package/src/sources/ndex/client.ts +102 -0
  681. package/src/sources/ndex/descriptor.ts +64 -0
  682. package/src/sources/ndex/expand.ts +100 -0
  683. package/src/sources/ndex/index.ts +235 -0
  684. package/src/sources/ndex/params.ts +17 -0
  685. package/src/sources/ndex/share-url.ts +84 -0
  686. package/src/sources/params.ts +32 -0
  687. package/src/sources/registry.ts +325 -0
  688. package/src/sources/rest/descriptor.ts +79 -0
  689. package/src/sources/rest/index.ts +22 -0
  690. package/src/sources/rest/mapping.ts +401 -0
  691. package/src/sources/rest/openalex.ts +288 -0
  692. package/src/sources/rest/paging.ts +180 -0
  693. package/src/sources/rest/params.ts +243 -0
  694. package/src/sources/rest/records.ts +289 -0
  695. package/src/sources/rest/samples/deps-dev.ts +49 -0
  696. package/src/sources/rest/samples/string.ts +44 -0
  697. package/src/sources/rest/selectors.ts +91 -0
  698. package/src/sources/rest/source.ts +776 -0
  699. package/src/sources/rest/templates.ts +151 -0
  700. package/src/sources/run.ts +793 -0
  701. package/src/sources/sha256.ts +99 -0
  702. package/src/sources/sigv4.ts +209 -0
  703. package/src/sources/sparql/descriptor.ts +67 -0
  704. package/src/sources/sparql/index.ts +356 -0
  705. package/src/sources/sparql/ntriples.ts +219 -0
  706. package/src/sources/sparql/params.ts +28 -0
  707. package/src/sources/sparql/query.ts +162 -0
  708. package/src/sources/testing.ts +210 -0
  709. package/src/sources/types.ts +776 -0
  710. package/src/styles/annotations.ts +201 -27
  711. package/src/styles/canon/bends.ts +137 -0
  712. package/src/styles/canon/color-tables.ts +10 -4
  713. package/src/styles/canon/color.ts +105 -3
  714. package/src/styles/canon/enums.ts +99 -8
  715. package/src/styles/canon/graphviz.ts +71 -10
  716. package/src/styles/canon/number.ts +19 -0
  717. package/src/styles/canon/text.ts +187 -16
  718. package/src/styles/codes.ts +2 -0
  719. package/src/styles/cyjs/cascade.ts +1193 -38
  720. package/src/styles/cyjs/defaults-table.ts +5 -0
  721. package/src/styles/cyjs/emit.ts +247 -16
  722. package/src/styles/cyjs/face.ts +372 -0
  723. package/src/styles/cyjs/mappers.ts +498 -28
  724. package/src/styles/cyjs/routes.ts +432 -0
  725. package/src/styles/cytoscape/charts.ts +684 -0
  726. package/src/styles/cytoscape/emit.ts +220 -44
  727. package/src/styles/cytoscape/lexicon.ts +459 -80
  728. package/src/styles/cytoscape/mappings.ts +108 -0
  729. package/src/styles/cytoscape/resolve.ts +763 -23
  730. package/src/styles/cytoscape/translate.ts +11 -11
  731. package/src/styles/defaults.ts +436 -38
  732. package/src/styles/index.ts +5 -0
  733. package/src/styles/internal.ts +1 -0
  734. package/src/styles/io/block.ts +10 -0
  735. package/src/styles/io/generic.ts +79 -23
  736. package/src/styles/io/round-trip.ts +202 -0
  737. package/src/styles/io/writer.ts +14 -4
  738. package/src/styles/notes.ts +1 -0
  739. package/src/styles/plan/features.ts +23 -2
  740. package/src/styles/plan/index.ts +1 -1
  741. package/src/styles/plan/plan.ts +69 -5
  742. package/src/styles/plan/resolve.ts +61 -6
  743. package/src/styles/slots.ts +25 -0
  744. package/src/styles/types.ts +658 -4
  745. package/src/styles/vocabulary.ts +226 -3
  746. package/src/types.ts +19 -5
  747. package/dist/chunks/block-DiGq58c3.js.map +0 -1
  748. package/dist/chunks/choose--jM0yYCo.js +0 -57
  749. package/dist/chunks/choose--jM0yYCo.js.map +0 -1
  750. package/dist/chunks/convert-BcQ8_jMo.js.map +0 -1
  751. package/dist/chunks/emit-CwU8cUmG.js.map +0 -1
  752. package/dist/chunks/export-BvqAXCKh.js.map +0 -1
  753. package/dist/chunks/exporter-CrDWIyiq.js.map +0 -1
  754. package/dist/chunks/format-BpQBx8MZ.js.map +0 -1
  755. package/dist/chunks/generic-Dq1ntt9q.js.map +0 -1
  756. package/dist/chunks/importer-BSvfrX_h.js.map +0 -1
  757. package/dist/chunks/importer-CMmeMWlC.js.map +0 -1
  758. package/dist/chunks/importer-COTK9Tsl.js.map +0 -1
  759. package/dist/chunks/importer-DiZRmOQG.js.map +0 -1
  760. package/dist/chunks/importer-e6LGpqHB.js.map +0 -1
  761. package/dist/chunks/importer-iFYPEKaJ.js.map +0 -1
  762. package/dist/chunks/importer-yh_aBCU6.js.map +0 -1
  763. package/dist/chunks/lexicon-CT69Kd87.js.map +0 -1
  764. package/dist/chunks/styles-BQnsga7p.js.map +0 -1
  765. package/dist/chunks/styles-D3fRphrO.js +0 -690
  766. package/dist/chunks/styles-D3fRphrO.js.map +0 -1
  767. package/dist/chunks/styles-yed-BF5x3_Y5.js +0 -842
  768. package/dist/chunks/styles-yed-BF5x3_Y5.js.map +0 -1
  769. package/dist/chunks/writer-DMKvthQE.js +0 -448
  770. package/dist/chunks/writer-DMKvthQE.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"format-BpQBx8MZ.js","sources":["../../src/common/codes.ts","../../src/common/plural.ts","../../src/types.ts","../../src/common/report.ts","../../src/common/format.ts"],"sourcesContent":["/**\n * The issue and loss codes shared by more than one format: one constant per condition, aliased by every format's\n * `<FMT>_ISSUE` / `<FMT>_LOSS` table, so a consumer can switch on a condition without knowing the\n * format and two importers never spell the same condition differently. A condition specific to one\n * format keeps that format's own `E_<FMT>_` / `W_<FMT>_` code next to its importer or exporter.\n *\n * Naming scheme: `E_` for an issue recorded with severity \"error\" (or a loss note whose export()\n * throws), `W_` for a warning; a table key is the code without the severity prefix and without the\n * format prefix.\n */\n\nimport type { GraphFormatErrorCode } from \"@graphty/graph-format\";\n\n// ============================================================ importer issues\n\n/**\n * The URL could not be fetched (network failure, CORS refusal or a non-2xx status).\n * @category Issue and loss codes\n */\nexport const FETCH_CODE = \"E_FETCH\";\n\n/**\n * The element (node, attribute, key, ...) has no id where the format requires one.\n * @category Issue and loss codes\n */\nexport const MISSING_ID_CODE = \"E_MISSING_ID\";\n\n/**\n * An edge has no source or no target.\n * @category Issue and loss codes\n */\nexport const MISSING_ENDPOINT_CODE = \"E_MISSING_ENDPOINT\";\n\n/**\n * A node id declared twice; the second declaration merges into the first.\n * @category Issue and loss codes\n */\nexport const DUPLICATE_NODE_CODE = \"W_DUPLICATE_NODE\";\n\n/**\n * The file declares no graph at all. The import stops.\n * @category Issue and loss codes\n */\nexport const NO_GRAPH_CODE = \"E_NO_GRAPH\";\n\n/**\n * The file holds several graphs and only the first was read (GraphML and GEXF merge them into one graph instead). It is not added when `graphIndex` or `graphName` chose the graph.\n * `importAllGraphs()` reads every one.\n * @category Issue and loss codes\n */\nexport const MULTIPLE_GRAPHS_CODE = \"W_MULTIPLE_GRAPHS\";\n\n/**\n * The input is empty. The import stops.\n * @category Issue and loss codes\n */\nexport const EMPTY_INPUT_CODE = \"E_EMPTY_INPUT\";\n\n/**\n * The text breaks the format's syntax; the message says where and how. The import stops.\n * @category Issue and loss codes\n */\nexport const SYNTAX_CODE = \"E_SYNTAX\";\n\n/**\n * The XML is not well-formed; the message says where. The import stops.\n * @category Issue and loss codes\n */\nexport const XML_SYNTAX_CODE = \"E_XML_SYNTAX\";\n\n/**\n * Elements are nested deeper than graph-io reads (`MAX_XML_DEPTH`, 100,000 levels); the message says where. The import\n * stops.\n * @category Issue and loss codes\n */\nexport const XML_NESTING_CODE = \"E_XML_NESTING\";\n\n/**\n * An element the format does not define at that place was skipped.\n * @category Issue and loss codes\n */\nexport const UNKNOWN_ELEMENT_CODE = \"W_UNKNOWN_ELEMENT\";\n\n/**\n * Text where the format allows only elements was ignored.\n * @category Issue and loss codes\n */\nexport const STRAY_TEXT_CODE = \"W_STRAY_TEXT\";\n\n/**\n * A `pid` / parent reference names a node the document never declares.\n * @category Issue and loss codes\n */\nexport const UNKNOWN_PARENT_CODE = \"E_UNKNOWN_PARENT\";\n\n/**\n * A hyperedge (an edge with more than two ends) while `hyperedges` is \"error\". The import stops.\n * @category Issue and loss codes\n */\nexport const HYPEREDGE_CODE = \"E_HYPEREDGE\";\n\n/**\n * A declaration's key / attribute id is declared twice.\n * @category Issue and loss codes\n */\nexport const DUPLICATE_KEY_CODE = \"E_DUPLICATE_KEY\";\n\n/**\n * An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example a repeated\n * column header.\n * @category Issue and loss codes\n */\nexport const COLUMN_RENAMED_CODE = \"W_COLUMN_RENAMED\";\n\n/**\n * A node or edge attribute is not written, because the format has nowhere to put it.\n * @category Issue and loss codes\n */\nexport const COLUMN_DROPPED_CODE = \"W_COLUMN_DROPPED\";\n\n/**\n * You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as a\n * plain attribute.\n * @category Issue and loss codes\n */\nexport const ROLE_TAKEN_CODE = \"W_ROLE_TAKEN\";\n\n/**\n * An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: \"string\"` to keep every digit.\n * @category Issue and loss codes\n */\nexport const PRECISION_CODE = \"W_PRECISION\";\n\n/**\n * Two different id texts became the same number because `ids` is \"number\" (for example, \"042\" and \"42\"), so their nodes were\n * merged.\n * @category Issue and loss codes\n */\nexport const ID_MERGED_CODE = \"W_ID_MERGED\";\n\n/**\n * You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,\n * `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.\n * @category Issue and loss codes\n */\nexport const SINK_OPTION_CODE = \"W_SINK_OPTION\";\n\n/**\n * You set an option this format does not use; it had no effect. The message names the option.\n * @category Issue and loss codes\n */\nexport const OPTION_IGNORED_CODE = \"W_OPTION_IGNORED\";\n\n/**\n * The input is not valid UTF-8. The import stops.\n * @category Issue and loss codes\n */\nexport const INVALID_UTF8_CODE = \"E_INVALID_UTF8\";\n\n/**\n * Some bytes are not valid in the encoding that was chosen (by a byte order mark, the file's own declaration or the\n * `encoding` option). The import stops.\n * @category Issue and loss codes\n */\nexport const INVALID_ENCODING_CODE = \"E_INVALID_ENCODING\";\n\n/**\n * Bytes that are not valid UTF-8 (and declare no other encoding) were read as windows-1252.\n * @category Issue and loss codes\n */\nexport const ENCODING_FALLBACK_CODE = \"W_ENCODING_FALLBACK\";\n\n/**\n * The file declares an encoding the platform's TextDecoder does not know; the declaration is ignored.\n * @category Issue and loss codes\n */\nexport const UNKNOWN_ENCODING_CODE = \"W_UNKNOWN_ENCODING\";\n\n/**\n * A byte order mark, the `encoding` option and the encoding the file declares disagree, or the file\n * declares UTF-16 over bytes that are not UTF-16; the message names which one applied (a BOM wins\n * over the option and the declaration, the option over the declaration).\n * @category Issue and loss codes\n */\nexport const ENCODING_CONFLICT_CODE = \"W_ENCODING_CONFLICT\";\n\n/**\n * The text holds a control character, such as a NUL byte or an escape character, which is kept in the id or value it\n * is part of; or it ends with a Ctrl-Z end-of-file marker, which was ignored. Reported once per import.\n * @category Issue and loss codes\n */\nexport const CONTROL_CHARACTER_CODE = \"W_CONTROL_CHARACTER\";\n\n/**\n * The input is a known kind of file that is not a graph: an HTML page, a PDF, compressed or zip data, or an image. The\n * import stops.\n * @category Issue and loss codes\n */\nexport const FOREIGN_FORMAT_CODE = \"E_FOREIGN_FORMAT\";\n\n/**\n * More warnings of one code than a report keeps: the first ones are kept and this one warning (the\n * suppressed code as its element) counts the rest.\n * @category Issue and loss codes\n */\nexport const ISSUES_SUPPRESSED_CODE = \"W_ISSUES_SUPPRESSED\";\n\n/**\n * An XML attribute the format does not define (or does not keep) on that element; it is not kept.\n * @category Issue and loss codes\n */\nexport const UNKNOWN_XML_ATTRIBUTE_CODE = \"W_UNKNOWN_XML_ATTRIBUTE\";\n\n/**\n * You read into a graph builder that already holds edges (or whose direction is locked), and its direction differs\n * from the file's, so the file is read with the builder's direction. A builder without edges takes the file's\n * direction.\n * @category Issue and loss codes\n */\nexport const DIRECTION_REFUSED_CODE = \"W_DIRECTION_REFUSED\";\n\n/**\n * `onMixedDirection` (\"directed\" or \"undirected\") made edges take a direction the file did not give them. It can\n * appear twice in one report: once for the direction the file declares and once for the edges that declared\n * their own.\n * @category Issue and loss codes\n */\nexport const DIRECTION_FORCED_CODE = \"W_DIRECTION_FORCED\";\n\n/**\n * The graph has both directed and undirected edges and `onMixedDirection` is \"error\". An import stops; a save to a\n * format that holds one direction per file fails with E_DIRECTED. Pass \"directed\" or \"undirected\" to read or write it\n * anyway.\n * @category Issue and loss codes\n */\nexport const MIXED_DIRECTION_CODE = \"E_MIXED_DIRECTION\";\n\n/**\n * A node or edge count the file announces is too large to reserve room for; it is ignored and the elements are read as\n * they come.\n * @category Issue and loss codes\n */\nexport const COUNT_HINT_CODE = \"W_COUNT_HINT\";\n\n/**\n * The declared type is not one the format defines; the column is kept as string.\n * @category Issue and loss codes\n */\nexport const UNKNOWN_ATTR_TYPE_CODE = \"W_UNKNOWN_ATTR_TYPE\";\n\n/**\n * The declared default does not parse as the declared type; the column has no default.\n * @category Issue and loss codes\n */\nexport const BAD_DEFAULT_CODE = \"W_BAD_DEFAULT\";\n\n/**\n * A declared option does not parse as the declared type; the options are dropped.\n * @category Issue and loss codes\n */\nexport const BAD_OPTIONS_CODE = \"W_BAD_OPTIONS\";\n\n/**\n * A repeated edge id in a format whose edge ids are unique; the second edge is skipped.\n * @category Issue and loss codes\n */\nexport const DUPLICATE_EDGE_ID_CODE = \"E_DUPLICATE_EDGE_ID\";\n\n/**\n * A value does not parse as its declared type; the cell is left unset.\n * @category Issue and loss codes\n */\nexport const BAD_VALUE_CODE = \"E_BAD_VALUE\";\n\n/**\n * An attribute's type was widened because a later value did not fit: an integer above 2^31 in an integer column, or\n * two declared types for one attribute.\n * @category Issue and loss codes\n */\nexport const WIDENED_CODE = \"W_WIDENED\";\n\n/**\n * A reference that is not a containment link (an attribute's element id, a layout or bypass\n * entry, a subnetwork member, a view's network, an undeclared target) names nothing; reported\n * once per kind with the count.\n * @category Issue and loss codes\n */\nexport const DANGLING_REFERENCE_CODE = \"W_DANGLING_REFERENCE\";\n\n/**\n * The same attribute twice on one element; one value is kept (the later, unless the format's specification says the first).\n * @category Issue and loss codes\n */\nexport const DUPLICATE_ATTRIBUTE_CODE = \"W_DUPLICATE_ATTRIBUTE\";\n\n/**\n * A containment link would close a parent cycle; that one link is dropped.\n * @category Issue and loss codes\n */\nexport const PARENT_CYCLE_CODE = \"E_PARENT_CYCLE\";\n\n/**\n * A formula (Cytoscape's `=ABS($x)`) is kept as its text; it is never evaluated.\n * @category Issue and loss codes\n */\nexport const EQUATION_AS_TEXT_CODE = \"W_EQUATION_AS_TEXT\";\n\n/**\n * The file's style rules (default styles, mappings, visual properties) are not applied to the graph. Reported once per\n * import; the message names what was not applied.\n * @category Issue and loss codes\n */\nexport const STYLES_NOT_IMPORTED_CODE = \"W_STYLES_NOT_IMPORTED\";\n\n/**\n * A CX file is an array of blocks, each an object with one key (`{\"nodes\": [...]}`). A member of that array\n * that is not such a block cannot be read and is skipped; the rest of the file is read.\n * @category Issue and loss codes\n */\nexport const BAD_ASPECT_BLOCK_CODE = \"E_BAD_ASPECT_BLOCK\";\n\n/**\n * A CX array member holding several aspects (`{\"nodes\": [...], \"edges\": [...]}`); each array-valued key is read as its own fragment.\n * @category Issue and loss codes\n */\nexport const MULTI_ASPECT_FRAGMENT_CODE = \"W_MULTI_ASPECT_FRAGMENT\";\n\n/**\n * A CX aspect, an array of elements, written as one object (`{\"nodes\": {\"@id\": 1}}`); read as one element.\n * @category Issue and loss codes\n */\nexport const SINGLE_OBJECT_ASPECT_CODE = \"W_SINGLE_OBJECT_ASPECT\";\n\n/**\n * The document uses the bare tokens NaN, Infinity or -Infinity (Python's json writes them), which\n * strict JSON does not allow; read as the numbers.\n * @category Issue and loss codes\n */\nexport const JSON_NONSTANDARD_NUMBER_CODE = \"W_JSON_NONSTANDARD_NUMBER\";\n\n/**\n * A CX aspect out of its place (after the post-metadata, a status that is not last, a block buffered for what it depends on).\n * @category Issue and loss codes\n */\nexport const ASPECT_ORDER_CODE = \"W_ASPECT_ORDER\";\n\n/**\n * A declared element count disagrees with what was read.\n * @category Issue and loss codes\n */\nexport const COUNT_MISMATCH_CODE = \"W_COUNT_MISMATCH\";\n\n/**\n * The program that wrote the file marked it as failed (CX `status.success: false`), so it is incomplete. The import\n * stops.\n * @category Issue and loss codes\n */\nexport const STATUS_FAILED_CODE = \"E_STATUS_FAILED\";\n\n/**\n * The producer marked the document as successful but attached an error text.\n * @category Issue and loss codes\n */\nexport const STATUS_WARNING_CODE = \"W_STATUS_WARNING\";\n\n/**\n * The input is beyond a size limit (a zip's uncompressed total or ratio, a document longer than\n * one string); the same string as graph-format's E_TOO_LARGE, recorded with category \"unsupported\".\n * @category Issue and loss codes\n */\nexport const TOO_LARGE_CODE = \"E_TOO_LARGE\";\n\n/**\n * A value that does not fit its attribute's type. An import records it for a value that does not parse as the\n * type the file declares for it (\"x\" in an integer attribute): GraphML and GEXF leave that value unset, Neo4j CSV\n * skips the row. A save throws it when an attribute value cannot be written in the format; `checkExport()` returns\n * the `E_` note that names the attribute.\n * @category Issue and loss codes\n */\nexport const COLUMN_TYPE_CODE = \"E_COLUMN_TYPE\";\n\n/**\n * `graphIndex` is past the last graph in the file, or `graphName` matches none of them. The import stops, and\n * the message lists the index and name of each graph the file holds.\n * @category Issue and loss codes\n */\nexport const GRAPH_NOT_FOUND_CODE = \"E_GRAPH_NOT_FOUND\";\n\n/**\n * `graphName` matches more than one graph; the message lists their positions. The import stops.\n * @category Issue and loss codes\n */\nexport const AMBIGUOUS_GRAPH_NAME_CODE = \"E_AMBIGUOUS_GRAPH_NAME\";\n\n/**\n * A second edge between the same two nodes under `duplicateEdges: \"error\"`; the import stops.\n * @category Issue and loss codes\n */\nexport const DUPLICATE_EDGE_CODE = \"E_DUPLICATE_EDGE\" satisfies GraphFormatErrorCode;\n\n/**\n * An edge from a node to itself under `selfLoops: \"error\"`; the import stops.\n * @category Issue and loss codes\n */\nexport const SELF_LOOP_CODE = \"E_SELF_LOOP\" satisfies GraphFormatErrorCode;\n\n/**\n * The `duplicateEdges` option merged parallel edges into one edge per pair, so whatever told them apart (an OBO\n * relation, a label) is lost. Recorded once, with the number merged.\n * @category Issue and loss codes\n */\nexport const EDGES_MERGED_CODE = \"W_EDGES_MERGED\";\n\n/**\n * Self-loops were removed by the `selfLoops: \"drop\"` option. Recorded once by importGraph() with the\n * number removed.\n * @category Issue and loss codes\n */\nexport const SELF_LOOPS_DROPPED_CODE = \"W_SELF_LOOPS_DROPPED\";\n\n/**\n * An option name that no format and no load or save function takes, most often a misspelling (`delimeter`). The\n * option has no effect. A load records it as a warning, and `checkExport()` returns it as a note. Reported only while\n * every registered format lists its options, as the built-in formats do.\n * @category Issue and loss codes\n */\nexport const UNKNOWN_OPTION_CODE = \"W_UNKNOWN_OPTION\";\n\n/**\n * A line the `parseLine` function of a format made with defineLineFormat() could not read (it threw). The line is\n * skipped; the message is the one the function threw with.\n * @category Issue and loss codes\n */\nexport const BAD_LINE_CODE = \"E_BAD_LINE\";\n\n/**\n * The `weightFrom` option names an attribute no edge has a value for, so the graph has no weights. The usual cause\n * is one options object shared between formats: GML and Pajek keep their weights in `value`, not `weight`. Recorded\n * once by importGraph().\n * @category Issue and loss codes\n */\nexport const WEIGHT_NOT_FOUND_CODE = \"W_WEIGHT_NOT_FOUND\";\n\n// ============================================================ exporter loss notes\n\n/**\n * An attribute with a role the format has no place for is written as a plain attribute; the role is lost.\n * @category Issue and loss codes\n */\nexport const ROLE_DROPPED_CODE = \"W_ROLE_DROPPED\";\n\n/**\n * A parents (multi-parent) column in a format with single containment only.\n * @category Issue and loss codes\n */\nexport const PARENTS_DROPPED_CODE = \"W_PARENTS_DROPPED\";\n\n/**\n * A start / end / timestamp column in a format without temporal support.\n * @category Issue and loss codes\n */\nexport const TEMPORAL_DROPPED_CODE = \"W_TEMPORAL_DROPPED\";\n\n/**\n * A mutual pair is written as two directed edges without the mutual mark.\n * @category Issue and loss codes\n */\nexport const MUTUAL_EXPANDED_CODE = \"W_MUTUAL_EXPANDED\";\n\n/**\n * A mutual pair is written as one undirected edge; the pair reads back undirected, the mark is lost.\n * @category Issue and loss codes\n */\nexport const MUTUAL_AS_UNDIRECTED_CODE = \"W_MUTUAL_AS_UNDIRECTED\";\n\n/**\n * Node ids whose written text reads back as the other type under the importer's id rule.\n * @category Issue and loss codes\n */\nexport const ID_TEXT_TYPE_CODE = \"W_ID_TEXT_TYPE\";\n\n/**\n * Two node ids would be written as the same text (the number 5 and the text \"5\"); the save fails with E_INVALID_ID.\n * @category Issue and loss codes\n */\nexport const ID_TEXT_COLLISION_CODE = \"E_ID_TEXT_COLLISION\";\n\n/**\n * A `<column>.text` companion the format cannot carry.\n * @category Issue and loss codes\n */\nexport const TEMPORAL_TEXT_DROPPED_CODE = \"W_TEMPORAL_TEXT_DROPPED\";\n\n/**\n * The graph has edge weights and the file does not keep them: every edge reads back with the default weight 1.\n * @category Issue and loss codes\n */\nexport const WEIGHTS_DROPPED_CODE = \"W_WEIGHTS_DROPPED\";\n\n/**\n * An attribute without the weight role is named like the attribute graph-io reads weights from (for example, `weight`), so it\n * reads back as the edge weight.\n * @category Issue and loss codes\n */\nexport const WEIGHT_KEY_CLASH_CODE = \"W_WEIGHT_KEY_CLASH\";\n\n/**\n * An attribute without a role is written where the format keeps a role (for example, a `name` column as the label), and reads\n * back with that role.\n * @category Issue and loss codes\n */\nexport const ROLE_ASSUMED_CODE = \"W_ROLE_ASSUMED\";\n\n/**\n * An attribute with a role (for example, the label) is written where the format keeps that role, and reads back under the name\n * the format's importer gives it.\n * @category Issue and loss codes\n */\nexport const COLUMN_RENAMED_LOSS_CODE = \"W_COLUMN_NAME_CHANGED\";\n\n/**\n * A declared column whose every row is unset is not written by a format without declarations.\n * @category Issue and loss codes\n */\nexport const EMPTY_COLUMN_DROPPED_CODE = \"W_EMPTY_COLUMN_DROPPED\";\n\n/**\n * A text attribute reads back as a dictionary attribute, or the reverse, because the importer chooses by how often its\n * values repeat. The values are the same.\n * @category Issue and loss codes\n */\nexport const STORAGE_CLASS_CODE = \"W_STORAGE_CLASS_CHANGED\";\n\n/**\n * A number attribute whose values are all whole numbers reads back as integers, because the format does not record the\n * type.\n * @category Issue and loss codes\n */\nexport const INTEGRAL_F64_CODE = \"W_INTEGRAL_F64_AS_I32\";\n\n/**\n * A text value that reads back as a number or a boolean, because the format does not record that it was text (the text\n * \"42\" reads back as the number 42).\n * @category Issue and loss codes\n */\nexport const TEXT_INFERRED_CODE = \"W_TEXT_INFERRED\";\n\n/**\n * A text value holds a character XML 1.0 forbids (most control characters); the save fails with E_COLUMN_TYPE.\n * @category Issue and loss codes\n */\nexport const XML_ILLEGAL_CHAR_CODE = \"E_XML_ILLEGAL_CHAR\";\n\n/**\n * An ontology exporter (OBO, OBO Graphs) writes a node column outside its vocabulary as property values; it reads back inside the `property_value` column.\n * @category Issue and loss codes\n */\nexport const COLUMN_AS_PROPERTY_VALUE_CODE = \"W_COLUMN_AS_PROPERTY_VALUE\";\n\n/**\n * An ontology exporter writes an edge without a relation as `is_a` (or the relation the caller chose).\n * @category Issue and loss codes\n */\nexport const RELATION_ASSUMED_CODE = \"W_RELATION_ASSUMED\";\n\n/**\n * An ontology exporter writes Typedef (property) nodes; they read back as nodes only under the importer's `typedefs: \"nodes\"`.\n * @category Issue and loss codes\n */\nexport const TYPEDEF_NODES_CODE = \"W_TYPEDEF_NODES\";\n\n/**\n * A graph attribute is written into the file's metadata and reads back in `snapshot.meta.extra`, not as a graph\n * attribute.\n * @category Issue and loss codes\n */\nexport const GRAPH_COLUMN_AS_METADATA_CODE = \"W_GRAPH_COLUMN_AS_METADATA\";\n\n/**\n * The file cannot record direction: an undirected graph's edges read back as directed, or the whole graph reads back\n * with the importer's default direction.\n * @category Issue and loss codes\n */\nexport const DIRECTION_DROPPED_CODE = \"W_DIRECTION_DROPPED\";\n\n/**\n * NaN and the infinities cannot be written; they are written as null and read back unset.\n * @category Issue and loss codes\n */\nexport const NONFINITE_AS_NULL_CODE = \"W_NONFINITE_AS_NULL\";\n\n/**\n * The nodes read back in a different order.\n * @category Issue and loss codes\n */\nexport const NODE_ORDER_CODE = \"W_NODE_ORDER\";\n\n/**\n * A text attribute stored as a dictionary, without a declared list of allowed values, reads back with its distinct\n * values as that list.\n * @category Issue and loss codes\n */\nexport const OPTIONS_GAINED_CODE = \"W_OPTIONS_GAINED\";\n\n// ============================================================ the graph builder\n\n/**\n * The issue codes every importer can record when the graph refuses an element, by name; every\n * format's `<FMT>_ISSUE` table includes them. Each one skips that element and counts toward\n * `errorLimit`.\n * @category Issue and loss codes\n */\nexport const ELEMENT_ISSUE = Object.freeze({\n /** A node id of a type the graph cannot hold (an empty id, a non-finite number, an object). The node is skipped. */\n INVALID_ID: \"E_INVALID_ID\",\n /** An edge names a node the file never declares, while `addMissingNodes` is false. The edge is skipped. */\n UNKNOWN_NODE: \"E_UNKNOWN_NODE\",\n /**\n * An edge weight that is not a number (text such as \"2,5\" with a decimal comma, NaN, a boolean). The whole edge is\n * skipped, not only its weight.\n */\n INVALID_WEIGHT: \"E_INVALID_WEIGHT\",\n /** A second edge between the same two nodes, while `duplicateEdges` is \"error\". The edge is skipped. */\n DUPLICATE_EDGE: DUPLICATE_EDGE_CODE,\n /** An edge from a node to itself, while `selfLoops` is \"error\". The edge is skipped. */\n SELF_LOOP: SELF_LOOP_CODE,\n /** An edge id declared twice. The second edge is skipped. */\n DUPLICATE_EDGE_ID: DUPLICATE_EDGE_ID_CODE,\n});\n\n// ============================================================ the input layer\n\n/**\n * The issue codes every importer can record for input it cannot read (empty, too large, invalid\n * bytes, not a graph file), by name; every format's `<FMT>_ISSUE` table includes them.\n * @category Issue and loss codes\n */\nexport const INPUT_ISSUE = Object.freeze({\n /** The input is empty or holds only whitespace. The import stops. */\n EMPTY_INPUT: EMPTY_INPUT_CODE,\n /** The input, or one of its lines, is longer than a JavaScript string can hold. The import stops. */\n TOO_LARGE: TOO_LARGE_CODE,\n /** A byte order mark, the encoding option and the declared encoding disagree. */\n ENCODING_CONFLICT: ENCODING_CONFLICT_CODE,\n /** A control character or a stray U+FEFF in the text, or an ignored trailing Ctrl-Z. */\n CONTROL_CHARACTER: CONTROL_CHARACTER_CODE,\n /** The input is an HTML page, a PDF, compressed or zip data, or an image. The import stops. */\n FOREIGN_FORMAT: FOREIGN_FORMAT_CODE,\n /** Warnings of one code beyond the number a report keeps, counted in one warning. */\n ISSUES_SUPPRESSED: ISSUES_SUPPRESSED_CODE,\n});\n","/**\n * Count agreement for messages, so a report says \"1 node is\" and \"3 nodes are\", never \"1 node(s) are\".\n */\n\n/**\n * The plural ending of a regular noun after a count.\n * @param n - the count\n * @returns \"\" for 1, \"s\" otherwise\n */\nexport function plural(n: number): string {\n return n === 1 ? \"\" : \"s\";\n}\n\n/**\n * The form of a verb that agrees with a count.\n * @param n - the count\n * @param one - the form for 1 (\"is\", \"was\", \"holds\")\n * @param many - the form for any other count (\"are\", \"were\", \"hold\")\n * @returns `one` or `many`\n */\nexport function agree(n: number, one: string, many: string): string {\n return n === 1 ? one : many;\n}\n\n/**\n * A count of nodes and edges, leaving out a zero: \"2 nodes and 1 edge\", \"1 edge\".\n * @param nodes - the node count\n * @param edges - the edge count\n * @returns the text\n */\nexport function elementCount(nodes: number, edges: number): string {\n const parts = [];\n if (nodes > 0 || edges === 0) {\n parts.push(`${nodes} node${plural(nodes)}`);\n }\n if (edges > 0) {\n parts.push(`${edges} edge${plural(edges)}`);\n }\n return parts.join(\" and \");\n}\n\n/**\n * A word with its indefinite article, chosen by its first letter: \"an integer\", \"a double\".\n * @param word - the word\n * @returns \"a word\" or \"an word\"\n */\nexport function withArticle(word: string): string {\n return `${/^[aeiou]/i.test(word) ? \"an\" : \"a\"} ${word}`;\n}\n","/**\n * The io contract types of @graphty/graph-io: what every importer\n * and exporter implements and what every caller of one programs against. They are declared here\n * rather than in the core because ImportInput and CommonImportOptions reference ReadableStream and\n * AbortSignal, which need the DOM lib (or @types/node >= 18); the core's public types reference only\n * ES2020 globals (decision D-IO-TYPES). Every declaration is transcribed verbatim from the design;\n * the behavior behind each option is specified in sections 8.4 (import), 8.5 (export) and 8.6\n * (report and error aggregation).\n */\n\nimport {\n type Dtype,\n type DuplicatePolicy,\n GraphFormatError,\n type GraphSink,\n type GraphSnapshot,\n type IdCoercion,\n} from \"@graphty/graph-format\";\n\nimport type { ImporterPositions, PositionReadContext } from \"./positions/types.js\";\nimport type {\n EdgeStyleProperty,\n GraphStyleProperty,\n ImporterStyles,\n NodeStyleProperty,\n StyleReadContext,\n StyleWriteCapabilities,\n} from \"./styles/types.js\";\n\n/**\n * What an importer reads: whole text, whole bytes, a byte stream (a browser\n * `File.stream()`, a fetch body) or an async iterable of text or byte chunks. Bytes are decoded\n * strictly in the encoding the `encoding` option, a byte order mark or the file's own declaration\n * names, else as UTF-8 (undeclared bytes that are not UTF-8 are read as windows-1252 with a\n * warning), so an invalid sequence is a parse-error and never a silent U+FFFD that could alias two ids.\n * @category Loading\n */\nexport type ImportInput = string | Uint8Array | ReadableStream<Uint8Array> | AsyncIterable<string | Uint8Array>;\n\n/**\n * The options every importer accepts next to its format-specific ones. The\n * builder-policy fields (`addMissingNodes`, `duplicateEdges`, `selfLoops`, `weightDtype`) seed the\n * registry's builder; on a caller's sink they are read back from `sink.options` and every option the\n * sink cannot honor is reported.\n * @category Loading\n */\nexport interface CommonImportOptions {\n /**\n * How id text becomes a node id. \"canonical\": integer text such as \"42\" becomes the number 42\n * and everything else (\"042\", \"4.2\", \"a\") stays text. \"string\": every id stays text. \"number\":\n * every id is read as a number, so \"042\" and \"42\" become one node (with a warning) and text that\n * is not a number is an error. \"keep\": ids keep the type the file gives them. The default is\n * \"keep\" for JSON, OBO, XGMML, CX, CX2 and Cytoscape sessions, and \"canonical\" for the other\n * formats.\n * @defaultValue per format\n */\n ids?: IdCoercion | undefined;\n /**\n * Which value becomes the node id: the file's own id (\"id\"), the node's label (\"label\"), or its\n * position among the nodes, counting from 0 (\"index\"). Use it when a file's ids are meaningless\n * numbers and the labels are the real names. In d3 JSON, \"index\" also reads edges whose ends are\n * node positions. In GML and Pajek it only renames: every node still needs its id key or vertex\n * number, because edges refer to nodes by it, and a GML node without an `id` key is skipped\n * with E_MISSING_ID. CSV reads this option only when there is a node table, and it does not\n * just rename: with \"label\" the node table's label column (`label`, or the `labelColumn`\n * option) gives the ids, so the edge table must name its nodes by those labels.\n * @defaultValue \"id\"\n */\n nodeIdFrom?: \"id\" | \"label\" | \"index\" | undefined;\n /**\n * Whether an edge may name a node the file never declares; that node is then created. When\n * false, such an edge is skipped as an error. The default is false for GEXF, XGMML, CX, CX2 and\n * Cytoscape sessions, whose files must declare every node, and true for the other formats.\n * @defaultValue per format\n */\n addMissingNodes?: boolean | undefined;\n /**\n * What to do with a second edge between the same two nodes: \"keep\" keeps both, \"first\" / \"last\"\n * keep one, \"sum\" / \"min\" / \"max\" keep one with the weights combined, and \"error\" stops the\n * import. Merged edges are reported once as W_EDGES_MERGED.\n * @defaultValue \"keep\"\n */\n duplicateEdges?: DuplicatePolicy | undefined;\n /**\n * What to do with an edge from a node to itself: \"keep\", \"drop\" (reported once as\n * W_SELF_LOOPS_DROPPED with the number removed), or \"error\" to stop the import.\n * @defaultValue \"keep\"\n */\n selfLoops?: \"keep\" | \"drop\" | \"error\" | undefined;\n /**\n * How edge direction is read. \"expand\" (the default) keeps the file's direction, and for a file\n * that has both directed and undirected edges makes a directed graph in which each undirected\n * edge is two edges, marked so an export can write them back as one. \"directed\" / \"undirected\"\n * read every edge of any file that way, including a file whose edges all have the other\n * direction, with a W_DIRECTION_FORCED warning. \"error\" stops the import at the first edge whose\n * direction differs from the file's.\n * @defaultValue \"expand\"\n */\n onMixedDirection?: \"expand\" | \"directed\" | \"undirected\" | \"error\" | undefined;\n /**\n * Whether the graph is directed when the file does not say. The default is undirected for\n * GraphML, GEXF, GML, JSON and XGMML, and directed for CSV, Pajek and Cytoscape sessions. DOT,\n * Neo4j, CX, CX2 and OBO files always settle the direction themselves (DOT by `graph` or\n * `digraph`; the others are always directed), so those formats do not read this option and\n * report it as W_OPTION_IGNORED.\n * @defaultValue per format\n */\n defaultDirected?: boolean | undefined;\n /**\n * The edge attribute read as the edge weight. The default is \"weight\", except \"value\" for GML\n * and Pajek and none for OBO. Pass null to read every attribute as a plain attribute and leave\n * the graph unweighted. A name no edge has leaves the graph unweighted, with a W_WEIGHT_NOT_FOUND\n * warning: one options object with `weightFrom: \"weight\"` shared across formats reads GML and\n * Pajek files, which keep their weights in `value`, without weights. An edge whose weight cell is\n * empty or missing gets the default weight 1, and an export writes no weight for it.\n * @defaultValue per format\n */\n weightFrom?: string | null | undefined;\n /**\n * Whether weights a 32-bit float cannot hold exactly are also kept exactly. \"f64\" keeps them in\n * an edge column that `snapshot.edges.byRole(\"weight\")` finds, so 0.1 and 16777217\n * stay exact. \"f32\" keeps no such column and uses less memory: the 32-bit weight arrays\n * `snapshot.weights` and `snapshot.edgeList().weights`, which every import fills, are then the\n * only weights.\n * @defaultValue \"f64\"\n */\n weightDtype?: \"f32\" | \"f64\" | undefined;\n /**\n * How a column the file declares as a 64-bit integer is stored: \"f64\" (a number, exact up to\n * 2^53) or \"string\" (every digit kept, as text). GML declares no types, so there it applies to a\n * key whose integer values go beyond 2^53.\n * @defaultValue \"f64\"\n */\n long?: \"f64\" | \"string\" | undefined;\n /**\n * Whether to give back the original ids that an export with `sanitizeIds: \"mangle\"` had to\n * rewrite. The export writes them to the file in an attribute whose name each format page\n * gives. When false, the rewritten ids stay the ids and the originals are an ordinary node\n * attribute, named after the format's spelling: `graphty.originalId` in GraphML,\n * `graphty_originalId` in GML and Pajek, `graphty:originalId` in CX, CX2 and Cytoscape sessions,\n * and a `graphty:originalId` entry of the `property_value` attribute in OBO.\n * @defaultValue true\n */\n restoreMangledIds?: boolean | undefined;\n /**\n * What to do with a GraphML or JGF hyperedge (an edge with more than two ends): \"skip\" leaves it\n * out with a warning, \"error\" stops the import, and \"star\" and \"clique\" turn it into ordinary\n * edges. \"clique\" joins every pair of ends. \"star\" works differently per format: GraphML adds a\n * new hub node joined to every end, while JGF makes the hyperedge's first node the hub, so no\n * node is added. A directed JGF hyperedge (`source` and `target` arrays) becomes one edge from\n * every source to every target under both. In JGF every edge made from a hyperedge carries the\n * hyperedge's id, label, relation and metadata; GraphML drops a hyperedge's `<data>` and its\n * `<desc>`, with a warning.\n * @defaultValue \"skip\"\n */\n hyperedges?: \"error\" | \"skip\" | \"star\" | \"clique\" | undefined;\n /**\n * How many errors an import tolerates. Each error skips one node, edge or value and is listed in\n * the report; one error more than this stops the import with an ImportError. Pass 0 to stop at\n * the first error.\n * @defaultValue 100\n */\n errorLimit?: number | undefined;\n /**\n * Cancels the import. When it aborts, the import stops and rejects with the signal's reason\n * (an AbortError, or a TimeoutError from `AbortSignal.timeout()`).\n */\n signal?: AbortSignal | undefined;\n /**\n * Called as the input is read, with the bytes read so far and the total. For a string or a\n * Uint8Array the total is known from the first call. For a stream (which includes loadFromUrl()\n * and loadFromFile()) it is undefined until the last call, which always has\n * `bytesDone === bytesTotal`. Text counts its UTF-8 length.\n */\n onProgress?: ((bytesDone: number, bytesTotal?: number) => void) | undefined;\n /**\n * The character encoding of byte input, as a label such as \"utf-8\", \"windows-1252\" or\n * \"utf-16le\". Without it graph-io uses a byte order mark, then the encoding the file declares\n * (an XML declaration, DOT's `charset`), then UTF-8, and reads bytes that are not UTF-8 as\n * windows-1252 with a warning. A byte order mark wins over this option. A string input is\n * already text: setting this option for one adds a W_OPTION_IGNORED warning, once per input (a\n * CSV import with a `nodes` table has two inputs).\n */\n encoding?: string | undefined;\n}\n\n/**\n * Which graph to read from a file that holds several: by position or by name, never both. Without\n * either, the first graph is read.\n * @category Loading\n */\nexport interface GraphChoiceOptions {\n /**\n * The 0-based position of the graph to read from a file that holds several (`listGraphs()`\n * gives each graph's `index`). A position past the last graph stops the import with an\n * ImportError whose `issue.code` is E_GRAPH_NOT_FOUND; its message lists the file's graphs.\n * @defaultValue 0\n */\n graphIndex?: number | undefined;\n /**\n * The name of the graph to read from a file that holds several (`listGraphs()` gives each\n * graph's `name`). A name no graph has stops the import with an ImportError whose `issue.code`\n * is E_GRAPH_NOT_FOUND, and a name two graphs share with one whose `issue.code` is\n * E_AMBIGUOUS_GRAPH_NAME.\n */\n graphName?: string | undefined;\n}\n\n/**\n * One graph of an input that can hold several, as an importer's listGraphs() describes it.\n * @category Loading\n */\nexport interface GraphListing {\n /** The value graphIndex takes to read it. */\n readonly index: number;\n /** The value graphName takes to read it, or null when the graph has no name. */\n readonly name: string | null;\n /** The node count when the input states it cheaply, else null. */\n readonly nodes: number | null;\n /** The edge count when the input states it cheaply, else null. */\n readonly edges: number | null;\n}\n\n/**\n * A format's reader. It reads the input once, from start to end, and adds each node, edge and\n * attribute to a graph builder (`GraphSink`, which `GraphBuilder` from @graphty/graph-format\n * implements); importGraph() then builds the snapshot. Register one with\n * `registry.registerImporter()` to teach graph-io a new format. `Opts` is the type of the format's\n * own options.\n * @category Writing a format\n */\nexport interface GraphImporter<Opts = unknown> {\n /** The name callers pass as `format`, such as \"graphml\" or \"csv\"; lowercase, unique in a registry. */\n readonly format: string;\n /** File extensions with the leading dot, most common first; used to detect the format from a file name. */\n readonly extensions: readonly string[];\n /** MIME types the format is served as, most specific first; used to detect the format from a Content-Type. */\n readonly mimeTypes: readonly string[];\n /**\n * The names of this format's own options (`[\"separator\"]`), when you want misspelled options\n * reported. While every registered importer lists its options, a load warns `W_UNKNOWN_OPTION` for\n * a name that no format and no load function takes. Leave it out to report nothing.\n */\n readonly options?: readonly string[] | undefined;\n /**\n * How sure you are that `head`, the first bytes of a file (up to SNIFF_HEAD_BYTES), is this\n * format: 0 for no, up to 1 for certain. Below 0.5 counts as a weak guess, which loses to a\n * file extension another format claims. Without this method the format is detected only by\n * file name and MIME type.\n * @param head - the first bytes of the input\n * @returns a confidence in 0..1\n */\n sniff?(head: Uint8Array): number;\n /**\n * Read `input` into `sink`. Record each problem in an ImportReportBuilder and skip the element;\n * the builder throws ImportError once there are more errors than `errorLimit`.\n * @param input - the text, bytes or stream to read\n * @param sink - the graph builder to add nodes, edges and attributes to\n * @param options - the format's own options and the options every importer takes\n * @returns the import report (`report.finish()`)\n */\n import(input: ImportInput, sink: GraphSink, options?: Opts & CommonImportOptions): Promise<ImportReport>;\n /**\n * Optional, for a format whose files can hold several graphs: read every graph, each into its\n * own sink. importAllGraphs() calls it; with it, importGraph() also honors `graphIndex` and\n * `graphName` by reading every graph and returning the chosen one. `import()` should read the\n * first graph and warn W_MULTIPLE_GRAPHS with the number skipped.\n * @param input - the text, bytes or stream to read\n * @param sinkFor - called once per graph, in document order, before that graph's first push\n * @param options - format-specific and common options\n * @returns one report per graph, in document order\n */\n importAll?(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: Opts & CommonImportOptions,\n ): Promise<ImportReport[]>;\n /**\n * Optional: list the graphs of a file without importing them, so a caller can offer a choice.\n * listGraphs() calls it. An importer that has it must also honor `graphIndex` and `graphName`\n * in `import()` itself (`chooseGraph()` resolves them); one without it lists nothing and the\n * registry makes the choice through `importAll()`.\n * @param input - the text, bytes or stream to read\n * @param options - format-specific and common options\n * @returns one listing per graph, in document order\n */\n listGraphs?(input: ImportInput, options?: Opts & CommonImportOptions): Promise<readonly GraphListing[]>;\n /**\n * Optional: the file's styles, read after the import from the snapshot it built. Called only when a caller asks\n * for styles (`importGraph(input, { styles: true })`). The simple path names the snapshot columns that hold\n * each style and the dialect they are spelled in, and graph-io does the rest:\n * `styles: () => ({ dialect: \"css\", node: { fill: { data: \"color\" } } })`. The advanced path returns canonical\n * values and the rules the file declares (`{ canonical: true, ... }`). Style data that is not per element\n * reaches it as `context.kept`: whatever this import's `import()` passed to `report.keepForStyles()`. Without\n * this member, graph-io reads the columns whose role is `color`, `size`, `shape`, `thickness` or `hidden`.\n * @param snapshot - the graph this import built\n * @param context - the cancel signal, the work budget and what `import()` kept\n * @returns the styles, or null when the file has none\n */\n styles?(snapshot: GraphSnapshot, context: StyleReadContext): ImporterStyles | null;\n /**\n * Optional: where this format's stored node coordinates are and how they are spelled, for\n * `extractPositions()` (`@graphty/graph-io/positions`). Without it, the role-`position` column\n * is read as its `meta.extra` declares (y up, center, file units when it says nothing). With it,\n * the answer wins over the column's `meta.extra`; null falls back to the column.\n *\n * The simple form names plain numeric columns: `() => ({ x: \"x\", y: \"y\", yAxis: \"down\", units: \"px\" })`.\n * The advanced form names a 3-component `column` and may add `anchor`, `width` / `height` size\n * columns, `groups` (container boxes), `medianNodeSize` and `tool`.\n * @param snapshot - the graph this importer read\n * @param ctx - `signal` to abort\n * @returns the spelling, or null to read the role-`position` column as declared\n */\n positions?(snapshot: GraphSnapshot, ctx: PositionReadContext): ImporterPositions | null;\n}\n\n/**\n * What a format can store exactly. checkCapabilities() compares a graph against it and returns a\n * loss note for everything the graph has that the format cannot store.\n * @category Saving\n */\nexport interface ExportCapabilities {\n /**\n * Whether one file can hold directed and undirected edges together. When false, a graph with both\n * needs `onMixedDirection` (\"directed\" or \"undirected\") to be saved.\n */\n readonly mixedDirection: boolean;\n /**\n * Whether the file can hold two edges between the same pair of nodes. When false, the extra\n * edges are not kept as separate edges.\n */\n readonly multiEdges: boolean;\n /** Whether the file can hold an edge from a node to itself. When false, such edges are lost. */\n readonly selfLoops: boolean;\n /**\n * Whether edges carry ids. \"required\": every edge has one, and ids are made up (e0, e1, ...)\n * for a graph without them. \"optional\": edge ids are written when the graph has them. \"none\":\n * edge ids are lost.\n */\n readonly edgeIds: \"required\" | \"optional\" | \"none\";\n /**\n * Which node ids the format can write as they are: \"any\"; \"nmtoken\" (XML name tokens: letters,\n * digits and `. - _ :`, no spaces); \"integer\"; or \"dense-1-based\" (the nodes are always numbered\n * 1 to N). Other ids need `sanitizeIds: \"mangle\"`, which writes the original ids too.\n */\n readonly idCharset: \"any\" | \"nmtoken\" | \"integer\" | \"dense-1-based\";\n /**\n * The attribute types the format keeps exactly: \"bool\", \"i32\" (32-bit integer), \"u32\" (unsigned\n * 32-bit integer), \"u8\" (byte), \"f32\" (32-bit float), \"f64\" (64-bit float, a JavaScript number),\n * \"string\" (text), \"dict\" (text stored as a dictionary of repeated values), \"list\" and \"json\".\n * An attribute of another type is written as the nearest one the format has, with a\n * W_DTYPE_UNSUPPORTED note.\n */\n readonly dtypes: readonly Dtype[];\n /**\n * Whether an attribute other than the node position can hold several numbers per node or edge\n * (a vector). When false, such an attribute does not read back as one attribute. Positions\n * are covered by `positions`.\n */\n readonly components: boolean;\n /** Whether an attribute can hold a list per node or edge. When false, list attributes are lost or flattened. */\n readonly lists: boolean;\n /**\n * Whether an attribute can hold nested JSON objects and arrays. When false, such attributes are\n * written as text or lost.\n */\n readonly json: boolean;\n /** Whether the file can declare a default value for an attribute. When false, declared defaults are lost. */\n readonly defaults: boolean;\n /**\n * Whether the file can declare the allowed values of an attribute (GEXF `options`). When false,\n * those declarations are lost; the values themselves are kept.\n */\n readonly options: boolean;\n /** Whether nodes can sit inside other nodes (groups or clusters). When false, the nesting is lost. */\n readonly hierarchy: boolean;\n /**\n * What the file can say about time: \"none\" (time attributes are lost), \"intervals\" (one start\n * and end per element), \"spells\" (several intervals per element), or \"dynamic-values\"\n * (attribute values that change over time, as well).\n */\n readonly temporal: \"none\" | \"intervals\" | \"spells\" | \"dynamic-values\";\n /** Whether the file can hold attributes of the graph itself. When false, graph attributes are lost. */\n readonly graphAttributes: boolean;\n /** Whether the file can hold node positions. When false, the layout is lost. */\n readonly positions: boolean;\n /**\n * Whether the file can hold node and edge color, size, shape and thickness. When false, they are lost.\n * @deprecated This describes the `color`, `size`, `shape` and `thickness` role columns, the old way styles\n * reached a file. Use {@link ExportCapabilities.styles}, what the format's style writer can hold. Removed in\n * the next major version.\n */\n readonly viz: boolean;\n /**\n * What the format's writer can hold of a graph's styles (the exporter's `styles.capabilities`): per target the\n * properties written natively, and where the `graphty.styles` block goes. Absent for a format that writes no\n * styles: every style is then reported as W_STYLE_NOT_WRITTEN and W_STYLE_RULES_NOT_KEPT.\n */\n readonly styles?: StyleWriteCapabilities | undefined;\n}\n\n/**\n * One thing a format cannot store, returned by checkExport() before anything is written.\n * @category Saving\n */\nexport interface LossNote {\n /**\n * A stable code. Codes starting with \"E_\" mean the export refuses to write under these options:\n * the exportGraph*() functions throw a GraphFormatError. Codes starting with \"W_\" mean the file\n * is written, but this part will not read back the same.\n */\n readonly code: string;\n /** A plain-English explanation. */\n readonly message: string;\n /** The attribute column involved, or null. */\n readonly column: string | null;\n /** How many nodes, edges or values are affected, or null when not counted. */\n readonly count: number | null;\n /**\n * Every column the note is about, when it is about several and `column` is null: the graph\n * attributes a format has no place for, or the node columns a CSV edge table leaves for the node\n * table. Absent on a note about one column or none.\n */\n readonly columns?: readonly string[];\n /**\n * The style a W_STYLE_ note is about: nodes, edges or the graph, and the neutral property (`fill`, `width`).\n * Absent on every other note.\n */\n readonly style?:\n | {\n /** Nodes, edges or the graph. */\n readonly target: \"node\" | \"edge\" | \"graph\";\n /** The neutral property. */\n readonly property: NodeStyleProperty | EdgeStyleProperty | GraphStyleProperty;\n }\n | undefined;\n}\n\n/**\n * The options every exporter accepts next to its format-specific ones.\n * @category Saving\n */\nexport interface CommonExportOptions {\n /**\n * What to do with node ids the format cannot hold. \"error\": the export throws (E_INVALID_ID) and\n * no node is renamed. \"mangle\": such ids are rewritten and the originals are written to the\n * file too, so an import with `restoreMangledIds` (on by default) reads the original ids back.\n * Pajek is the exception: it always numbers nodes 1 to N and keeps the old ids as labels.\n * @defaultValue \"error\"\n */\n sanitizeIds?: \"error\" | \"mangle\" | undefined;\n /**\n * What a format with one direction per file does with a graph that has both directed and\n * undirected edges: \"error\" throws (E_DIRECTED), \"directed\" writes every edge as directed (an\n * undirected edge once, as one directed edge), \"undirected\" writes the whole graph undirected.\n * A format that keeps each edge's own direction (GraphML, GEXF, CSV, Pajek, XGMML, Cytoscape\n * sessions, and the JGF and graphology JSON dialects) ignores it and writes both kinds; to make\n * such a graph all one direction, read it with the import option `onMixedDirection`.\n * @defaultValue \"error\"\n */\n onMixedDirection?: \"error\" | \"directed\" | \"undirected\" | undefined;\n}\n\n/**\n * A format's writer. Register one with `registry.registerExporter()` to make a format writable by\n * every save function. `Opts` is the type of the format's own options.\n * @category Writing a format\n */\nexport interface GraphExporter<Opts = unknown> {\n /** The name callers pass as `format`; the same as the importer's when the format has both. */\n readonly format: string;\n /** What the format can store exactly; build it with `capabilities()`. */\n readonly capabilities: ExportCapabilities;\n /**\n * File extensions with the leading dot, most common first. Optional; listFormats() uses them\n * when no importer is registered for the format (an export-only format).\n */\n readonly extensions?: readonly string[] | undefined;\n /** MIME types, most specific first. Optional; used the same way as `extensions`. */\n readonly mimeTypes?: readonly string[] | undefined;\n /**\n * The names of this format's own save options, when you want misspelled options reported. While\n * every registered exporter lists its options, `checkExport()` returns a `W_UNKNOWN_OPTION` note for\n * a name that no format and no save function takes. Leave it out to report nothing.\n */\n readonly options?: readonly string[] | undefined;\n /**\n * What a save would lose, without writing anything; checkExport(snapshot, format, options) calls\n * it. Start from `checkCapabilities(snapshot, capabilities, resolveExportOptions(options))` and\n * add a note for anything else your format changes. Every difference a re-import would show\n * needs a note.\n * @param snapshot - the graph to check\n * @param options - the format's own options and the options every exporter takes\n * @returns the loss notes, empty when the save is exact\n */\n check(snapshot: GraphSnapshot, options?: Opts & CommonExportOptions): readonly LossNote[];\n /**\n * Write the graph as byte chunks: UTF-8 text for a text format (`encodeChunks()` turns string\n * parts into them), the raw bytes for a binary one. Throw a GraphFormatError before writing for\n * every \"E_\" note `check()` returns.\n * @param snapshot - the graph to write\n * @param options - the format's own options and the options every exporter takes\n * @returns the file's bytes, chunk by chunk\n */\n export(snapshot: GraphSnapshot, options?: Opts & CommonExportOptions): AsyncIterable<Uint8Array>;\n /**\n * Write the graph as one string (`joinText()` joins string parts). A binary format rejects with\n * a GraphFormatError E_UNSUPPORTED (`details.reason` \"binary\") instead.\n * @param snapshot - the graph to write\n * @param options - the format's own options and the options every exporter takes\n * @returns the whole file\n */\n exportToString(snapshot: GraphSnapshot, options?: Opts & CommonExportOptions): Promise<string>;\n /**\n * Optional: the styles this format can write. With it, `exportGraph(snapshot, format, { styles })` hands\n * `export()`, `exportToString()` and `check()` an `options.styles` (`ExporterStyleInput`): each element's value\n * per property (`picture()`), the `graphty.styles` block, the tagged per-element values and the rules. With\n * `block: \"attributes\"` graph-io adds the block and the tagged values to the snapshot as a graph attribute and\n * element attributes, so a format that writes attributes keeps every style for graphty with no code:\n * `styles: { capabilities: { node: [], edge: [], block: \"attributes\" } }`. Every property not listed natively\n * is reported as W_STYLE_NOT_WRITTEN, and a format without this member loses every style, reported the same way.\n */\n readonly styles?:\n | {\n /** What the writer holds natively, and where the block goes. */\n readonly capabilities: StyleWriteCapabilities;\n }\n | undefined;\n}\n\n/**\n * What an ImportIssue is about, for errors and warnings alike: \"parse-error\" (the text is not valid\n * in the format), \"missing-value\" (something required is absent), \"validation-error\" (a value\n * breaks a rule of the format or of an option; an error skips it, a warning keeps it as written,\n * such as an id with spaces around it), \"unsupported\" (the file uses something graph-io does not\n * read), \"precision\" (a value was rounded), \"coercion\" (a value or id changed type) and \"merged\"\n * (elements were combined). Sort by `severity` first: the category says what kind of problem it\n * is, not how serious.\n * @category Reports and errors\n */\nexport type IssueCategory =\n \"parse-error\" | \"missing-value\" | \"validation-error\" | \"unsupported\" | \"precision\" | \"coercion\" | \"merged\";\n\n/**\n * One problem found while importing.\n * @category Reports and errors\n */\nexport interface ImportIssue {\n /** The category. */\n readonly category: IssueCategory;\n /**\n * \"error\": the element was skipped and counts toward `errorLimit`. \"warning\": the element was\n * kept, possibly changed.\n */\n readonly severity: \"error\" | \"warning\";\n /** A stable code; E_ for errors, W_ for warnings (\"E_UNKNOWN_NODE\", \"W_WIDENED\"). */\n readonly code: string;\n /** A plain-English message. */\n readonly message: string;\n /** The 1-based line in the input, or null when the format has no lines or it is unknown. */\n readonly line: number | null;\n /** The node id, edge id or attribute name involved, or null. */\n readonly element: string | null;\n}\n\n/**\n * What happened while a file was read.\n * @category Reports and errors\n */\nexport interface ImportReport {\n /** The format the file was read as. */\n readonly format: string;\n /**\n * What was read from the file, counted before the graph was built: `duplicateEdges` and\n * `selfLoops: \"drop\"` can leave fewer edges in the snapshot (each reported as a warning).\n */\n readonly counts: {\n /** Nodes read. */\n readonly nodes: number;\n /** Edges read (an undirected edge expanded into two by onMixedDirection \"expand\" counts twice). */\n readonly edges: number;\n /** Nodes skipped after an error. */\n readonly skippedNodes: number;\n /** Edges skipped after an error. */\n readonly skippedEdges: number;\n /** Undirected edges expanded into two by onMixedDirection \"expand\". */\n readonly expandedMixed: number;\n };\n /** Every issue recorded, in order. */\n readonly issues: readonly ImportIssue[];\n /** Issues with severity \"error\". */\n readonly errorCount: number;\n /** Issues with severity \"warning\". */\n readonly warningCount: number;\n /** Whether the error limit was reached and the import aborted. */\n readonly truncated: boolean;\n /** What the importer could not represent. */\n readonly lossy: readonly LossNote[];\n /** How long reading the file took, in milliseconds. */\n readonly durationMs: number;\n}\n\n/**\n * What a load function throws when the input cannot be read: the URL failed, the format was not\n * recognized, the file could not be parsed, or there were more errors than `errorLimit`. It is a\n * GraphFormatError with code \"E_IMPORT\"; `issue` says what stopped the import and `report` holds\n * everything recorded until then.\n * @category Reports and errors\n */\nexport class ImportError extends GraphFormatError {\n /**\n * Everything recorded up to the point the import stopped. It is not an enumerable property, so an\n * uncaught ImportError prints its message and issue, not every issue of the report.\n */\n declare readonly report: ImportReport;\n\n /**\n * The issue that stopped the import: its `code` (\"E_FETCH\", \"E_UNKNOWN_FORMAT\", \"E_CSV_UNCLOSED_QUOTE\", ...),\n * `message`, `line` and `element`. This is the value to branch on; `code` is always \"E_IMPORT\".\n * Null only for an ImportError constructed by hand without a matching issue.\n * @example\n * ```ts\n * if (err instanceof ImportError) {\n * switch (err.issue?.code) {\n * case \"E_FETCH\":\n * console.error(`download failed with status ${String(err.details.status)}`);\n * break;\n * case \"E_UNKNOWN_FORMAT\":\n * console.error(\"not a graph file this library can read; pass `format`\");\n * break;\n * default:\n * console.error(err.message);\n * }\n * }\n * ```\n */\n readonly issue: ImportIssue | null;\n\n /**\n * Create an ImportError.\n * @param message - a plain-ASCII human-readable message\n * @param report - the partial report\n * @param details - optional machine-readable context; its `code` names the issue that stopped the import\n */\n constructor(message: string, report: ImportReport, details?: Readonly<Record<string, unknown>>) {\n super(\"E_IMPORT\", message, details);\n this.name = \"ImportError\";\n Object.defineProperty(this, \"report\", { value: report, enumerable: false });\n this.issue = stoppingIssue(report.issues, details?.code);\n }\n}\n\n/**\n * The issue that stopped an import: the last one with the code the abort named, else the last error.\n * @param issues - the report's issues\n * @param code - the code the abort named, if any\n * @returns the issue, or null\n */\nfunction stoppingIssue(issues: readonly ImportIssue[], code: unknown): ImportIssue | null {\n let lastError: ImportIssue | null = null;\n for (let i = issues.length - 1; i >= 0; i--) {\n if (issues[i].code === code) {\n return issues[i];\n }\n if (lastError === null && issues[i].severity === \"error\") {\n lastError = issues[i];\n }\n }\n return lastError;\n}\n","/**\n * The ImportReport builder shared by every importer (design section 8.6): issues by category and\n * severity, the element counts, loss notes, the error limit with truncation, and the ImportError\n * that carries the partial report when the importer aborts.\n *\n * Layering (design section 8.6): the builder throws on the first hard error; the importer catches\n * per element, records an ImportIssue through this class, skips the element and continues until the\n * error limit, then aborts with E_IMPORT. `recordError()` is that catch: it turns a thrown\n * GraphFormatError into an issue with the category its code implies and re-throws everything else\n * (an ImportError, an abort reason, a programming error) unchanged.\n */\n\nimport { GraphFormatError, type GraphFormatErrorCode } from \"@graphty/graph-format\";\n\nimport { ImportError, type ImportIssue, type ImportReport, type IssueCategory, type LossNote } from \"../types.js\";\nimport { ISSUES_SUPPRESSED_CODE } from \"./codes.js\";\nimport { agree, plural } from \"./plural.js\";\n\n/**\n * The most warnings of one code a report keeps; later ones are counted in one W_ISSUES_SUPPRESSED\n * warning, so a per-row warning on a large file cannot grow the report without bound.\n * @category Issue and loss codes\n */\nexport const MAX_WARNINGS_PER_CODE = 1000;\n\n/** What each finished report's import kept for its styles: per report object, so imports running at once never mix. */\nconst KEPT_FOR_STYLES = new WeakMap<ImportReport, unknown>();\n\n/** The value of a builder that kept nothing. */\nconst NOTHING_KEPT: unique symbol = Symbol(\"nothing kept\");\n\n/**\n * What the import that produced a report passed to `ImportReportBuilder.keepForStyles()`, or undefined when it kept\n * nothing. graph-io passes it to the same importer's `styles()` as `context.kept`.\n * @param report - a report an importer's `import()` returned\n * @returns the kept value\n * @category Writing a format\n */\nexport function keptForStyles(report: ImportReport): unknown {\n return KEPT_FOR_STYLES.get(report);\n}\n\n/**\n * Where an issue was found: the 1-based line and the element (id or attribute name) when known.\n * @public\n * @category Writing a format\n */\nexport interface IssueLocation {\n /** The 1-based source line, when known. */\n readonly line?: number | null | undefined;\n /** The element the issue is about, when known. */\n readonly element?: string | null | undefined;\n}\n\n/**\n * The mutable element counters of a report in progress; importers increment them directly in hot loops.\n * @public\n * @category Plugin helpers\n */\nexport interface MutableCounts {\n /** Nodes pushed. */\n nodes: number;\n /** Logical edges pushed (both halves of an expanded edge count). */\n edges: number;\n /** Nodes skipped after an error. */\n skippedNodes: number;\n /** Edges skipped after an error. */\n skippedEdges: number;\n /** Source edges expanded into two logical edges. */\n expandedMixed: number;\n}\n\n/**\n * The category a thrown GraphFormatError maps to when an importer catches it per element: the codes\n * that mean \"the file referenced something it never declared\" are missing values, a refused\n * direction change is a coercion, size and feature limits are unsupported, everything else is a\n * validation error of the element.\n */\nconst CATEGORY_BY_CODE: Readonly<Partial<Record<GraphFormatErrorCode, IssueCategory>>> = {\n E_UNKNOWN_NODE: \"missing-value\",\n E_UNKNOWN_COLUMN: \"missing-value\",\n E_DIRECTED: \"coercion\",\n E_TOO_LARGE: \"unsupported\",\n E_UNSUPPORTED: \"unsupported\",\n E_GPU_INELIGIBLE: \"unsupported\",\n};\n\n/**\n * No longer recorded; kept so code that switches on older reports still compiles.\n * @category Issue and loss codes\n */\nexport const PARSE_ERROR_CODE = \"E_PARSE\";\n\n/**\n * An issue message as the ImportError shows it: prefixed with its line when the issue has one and the\n * message does not already name it.\n * @param message - the issue message\n * @param where - the issue location\n * @returns the message for the error\n */\nfunction withLine(message: string, where: IssueLocation | undefined): string {\n const line = where?.line;\n return line === undefined || line === null || message.includes(`line ${line}`)\n ? message\n : `line ${line}: ${message}`;\n}\n\n/**\n * Accumulates an ImportReport while an importer runs. Errors count toward the error limit; the\n * error that takes the count beyond the limit is still recorded, `truncated` is set, and an\n * ImportError carrying the report so far is thrown. Warnings never abort.\n * @category Writing a format\n */\nexport class ImportReportBuilder {\n /** The importer's format name. */\n readonly format: string;\n\n /** The error limit the report was created with. */\n readonly errorLimit: number;\n\n /** The element counters; importers increment them directly. */\n readonly counts: MutableCounts = { nodes: 0, edges: 0, skippedNodes: 0, skippedEdges: 0, expandedMixed: 0 };\n\n private readonly issueList: ImportIssue[] = [];\n\n private readonly lossList: LossNote[] = [];\n\n private readonly onceCodes = new Set<string>();\n\n /** Warnings recorded per code, kept or not. */\n private readonly warningsByCode = new Map<string, number>();\n\n private errors = 0;\n\n private warnings = 0;\n\n private truncatedFlag = false;\n\n private kept: unknown = NOTHING_KEPT;\n\n private readonly startedAt: number;\n\n /**\n * Create a builder for one import call.\n * @param format - the importer's format name\n * @param errorLimit - errors tolerated before the import aborts; Infinity for no limit\n */\n constructor(format: string, errorLimit: number) {\n this.format = format;\n this.errorLimit = errorLimit;\n this.startedAt = now();\n }\n\n /**\n * Issues recorded so far, in order.\n * @returns the live list (not copied; finish() copies)\n */\n get issues(): readonly ImportIssue[] {\n return this.issueList;\n }\n\n /**\n * Issues with severity \"error\".\n * @returns the count\n */\n get errorCount(): number {\n return this.errors;\n }\n\n /**\n * Issues with severity \"warning\".\n * @returns the count\n */\n get warningCount(): number {\n return this.warnings;\n }\n\n /**\n * Whether the error limit was exceeded.\n * @returns true once an error beyond the limit was recorded\n */\n get truncated(): boolean {\n return this.truncatedFlag;\n }\n\n /**\n * Loss notes recorded so far.\n * @returns the live list\n */\n get lossy(): readonly LossNote[] {\n return this.lossList;\n }\n\n /**\n * Record an error. When the count goes beyond the error limit the report is marked truncated\n * and an ImportError carrying it is thrown; the importer does not catch that.\n * @param category - the issue category\n * @param code - a stable code such as \"E_UNKNOWN_NODE\"\n * @param message - a plain-ASCII message\n * @param where - the line and element, when known\n * @returns the recorded issue\n */\n error(category: IssueCategory, code: string, message: string, where?: IssueLocation): ImportIssue {\n const issue = makeIssue(category, \"error\", code, message, where);\n this.issueList.push(issue);\n this.errors++;\n if (this.errors > this.errorLimit) {\n this.truncatedFlag = true;\n throw this.abort(`error limit of ${this.errorLimit} exceeded: ${withLine(message, where)}`, {\n code,\n limit: this.errorLimit,\n });\n }\n return issue;\n }\n\n /**\n * Record a warning; warnings never count toward the limit. Beyond MAX_WARNINGS_PER_CODE\n * warnings of one code the warning is counted, not kept: finish() adds one W_ISSUES_SUPPRESSED\n * warning per such code with the number dropped.\n * @param category - the issue category\n * @param code - a stable code such as \"W_WIDENED\"\n * @param message - a plain-ASCII message\n * @param where - the line and element, when known\n * @returns the recorded issue\n */\n warning(category: IssueCategory, code: string, message: string, where?: IssueLocation): ImportIssue {\n const issue = makeIssue(category, \"warning\", code, message, where);\n const seen = (this.warningsByCode.get(code) ?? 0) + 1;\n this.warningsByCode.set(code, seen);\n if (seen <= MAX_WARNINGS_PER_CODE) {\n this.issueList.push(issue);\n this.warnings++;\n }\n return issue;\n }\n\n /**\n * Record a warning the first time its key is seen and ignore later repeats, for conditions\n * that would otherwise produce one warning per row.\n * @param category - the issue category\n * @param code - the stable code\n * @param message - a plain-ASCII message\n * @param where - the line and element, when known\n * @param key - what repeats are deduplicated on; the code itself by default (pass `code:column`\n * to warn once per column)\n * @returns the recorded issue, or null when the key was already recorded\n */\n warnOnce(\n category: IssueCategory,\n code: string,\n message: string,\n where?: IssueLocation,\n key: string = code,\n ): ImportIssue | null {\n if (this.onceCodes.has(key)) {\n return null;\n }\n this.onceCodes.add(key);\n return this.warning(category, code, message, where);\n }\n\n /**\n * Record something the importer could not represent.\n * @param code - a stable code\n * @param message - a plain-ASCII message\n * @param column - the affected column, or null\n * @param count - the affected count, or null\n * @returns the recorded note\n */\n loss(code: string, message: string, column: string | null = null, count: number | null = null): LossNote {\n const note: LossNote = Object.freeze({ code, message, column, count });\n this.lossList.push(note);\n return note;\n }\n\n /**\n * The per-element catch: record a thrown GraphFormatError as an error\n * issue with its code and the category the code implies. Anything else is re-thrown unchanged:\n * an ImportError (the import already aborted), an abort reason, and any other thrown value (a\n * TypeError or RangeError is a programming error in the importer or the sink, never a defect of\n * the input, so it must surface as an exception rather than as an issue blamed on the file).\n * @param err - the thrown value\n * @param where - the line and element, when known\n * @returns the recorded issue\n */\n recordError(err: unknown, where?: IssueLocation): ImportIssue {\n if (err instanceof GraphFormatError && !(err instanceof ImportError)) {\n const category = CATEGORY_BY_CODE[err.code] ?? \"validation-error\";\n if (err.code === \"E_TOO_LARGE\") {\n // the sink is full: every later element would fail the same way, so the import stops\n return this.failWith(category, err.code, err.message, where);\n }\n return this.error(category, err.code, err.message, where);\n }\n throw err;\n }\n\n /**\n * Keep style data that is not per element (a stylesheet, a groups object, a legend, the file's default styles)\n * for this import's `styles()`: graph-io passes it back as `context.kept` when styles are requested. Kept per\n * report, never on the importer object, so imports running at once each get their own. A later call replaces\n * the value.\n * @param value - anything the importer's `styles()` needs\n * @returns this builder\n */\n keepForStyles(value: unknown): this {\n this.kept = value;\n return this;\n }\n\n /**\n * A builder that starts from everything this one recorded so far: issues, counts, loss notes,\n * the warnOnce keys, the error and warning counts and the truncation flag. For an importer that\n * reads its input once and emits several graphs, each with its own report.\n * @returns the copy; later records to either builder do not reach the other\n */\n fork(): ImportReportBuilder {\n const copy = new ImportReportBuilder(this.format, this.errorLimit);\n Object.assign(copy.counts, this.counts);\n copy.issueList.push(...this.issueList);\n copy.lossList.push(...this.lossList);\n for (const key of this.onceCodes) {\n copy.onceCodes.add(key);\n }\n for (const [code, count] of this.warningsByCode) {\n copy.warningsByCode.set(code, count);\n }\n copy.errors = this.errors;\n copy.warnings = this.warnings;\n copy.truncatedFlag = this.truncatedFlag;\n copy.kept = this.kept;\n return copy;\n }\n\n /**\n * Build the ImportError that aborts the import, carrying the report so far. The caller throws\n * it; this method only constructs it so it can be used in expression position.\n * @param message - a plain-ASCII message\n * @param details - optional machine-readable context\n * @returns the error to throw\n */\n abort(message: string, details?: Readonly<Record<string, unknown>>): ImportError {\n return new ImportError(message, this.finish(), details);\n }\n\n /**\n * Record a fatal parse error and abort: the issue is recorded (even beyond the error limit)\n * and an ImportError carrying the report is thrown.\n * @param code - a stable code such as \"E_INVALID_UTF8\"\n * @param message - a plain-ASCII message\n * @param where - the line and element, when known\n * @param details - optional machine-readable context for the ImportError\n */\n fail(code: string, message: string, where?: IssueLocation, details?: Readonly<Record<string, unknown>>): never {\n this.failWith(\"parse-error\", code, message, where, details);\n }\n\n /**\n * Record a fatal error of any category and abort, as fail() does for a parse error: a size\n * limit (E_TOO_LARGE, category \"unsupported\") stops an import without being a defect of the\n * syntax. A fatal error is not the error limit: `truncated` stays as it was.\n * @param category - the issue category\n * @param code - a stable code\n * @param message - a plain-ASCII message\n * @param where - the line and element, when known\n * @param details - optional machine-readable context for the ImportError\n */\n failWith(\n category: IssueCategory,\n code: string,\n message: string,\n where?: IssueLocation,\n details?: Readonly<Record<string, unknown>>,\n ): never {\n this.issueList.push(makeIssue(category, \"error\", code, message, where));\n this.errors++;\n throw this.abort(withLine(message, where), { code, ...details });\n }\n\n /**\n * Add a finished report to this one: its issues after the ones recorded so far, its counts, its\n * loss notes and its truncated flag. Use it when an importer hands part of the work to another\n * importer (for example, a wrapper around the CSV importer) and returns one report for both. The issues\n * keep their codes; errors added this way do not count toward this report's error limit, since\n * the other importer applied its own.\n * @param report - the report the other importer returned\n * @returns this builder\n * @example\n * ```ts\n * const report = new ImportReportBuilder(\"netscope\", opts.errorLimit);\n * const text = await readText(input, report, opts);\n * report.include(await csvImporter.import(text, sink, options));\n * return report.finish();\n * ```\n */\n include(report: ImportReport): this {\n for (const issue of report.issues) {\n this.issueList.push(issue);\n if (issue.severity === \"error\") {\n this.errors++;\n } else {\n this.warnings++;\n }\n }\n const { counts } = report;\n this.counts.nodes += counts.nodes;\n this.counts.edges += counts.edges;\n this.counts.skippedNodes += counts.skippedNodes;\n this.counts.skippedEdges += counts.skippedEdges;\n this.counts.expandedMixed += counts.expandedMixed;\n this.lossList.push(...report.lossy);\n this.truncatedFlag ||= report.truncated;\n if (this.kept === NOTHING_KEPT && KEPT_FOR_STYLES.has(report)) {\n this.kept = KEPT_FOR_STYLES.get(report);\n }\n return this;\n }\n\n /**\n * The report as it stands: a frozen snapshot with the parse duration so far. Can be called more\n * than once; each call reflects everything recorded up to that point.\n * @returns the report\n */\n finish(): ImportReport {\n const { nodes, edges, skippedNodes, skippedEdges, expandedMixed } = this.counts;\n const suppressed: ImportIssue[] = [];\n for (const [code, seen] of this.warningsByCode) {\n if (seen > MAX_WARNINGS_PER_CODE) {\n const more = seen - MAX_WARNINGS_PER_CODE;\n suppressed.push(\n makeIssue(\n \"unsupported\",\n \"warning\",\n ISSUES_SUPPRESSED_CODE,\n `${more} more ${code} warning${plural(more)} ${agree(more, \"was\", \"were\")} not kept (the report keeps the first ${MAX_WARNINGS_PER_CODE})`,\n { element: code },\n ),\n );\n }\n }\n const report: ImportReport = Object.freeze({\n format: this.format,\n counts: Object.freeze({ nodes, edges, skippedNodes, skippedEdges, expandedMixed }),\n issues: Object.freeze([...this.issueList, ...suppressed]),\n errorCount: this.errors,\n warningCount: this.warnings + suppressed.length,\n truncated: this.truncatedFlag,\n lossy: Object.freeze([...this.lossList]),\n durationMs: now() - this.startedAt,\n });\n if (this.kept !== NOTHING_KEPT) {\n KEPT_FOR_STYLES.set(report, this.kept);\n }\n return report;\n }\n}\n\n/**\n * Build a frozen ImportIssue.\n * @param category - the category\n * @param severity - error or warning\n * @param code - the stable code\n * @param message - the message\n * @param where - the location, when known\n * @returns the issue\n */\nfunction makeIssue(\n category: IssueCategory,\n severity: \"error\" | \"warning\",\n code: string,\n message: string,\n where: IssueLocation | undefined,\n): ImportIssue {\n return Object.freeze({\n category,\n severity,\n code,\n message,\n line: where?.line ?? null,\n element: where?.element ?? null,\n });\n}\n\n/**\n * Whether a thrown value means the load was cancelled rather than failed: the DOMException or Error\n * named \"AbortError\" that an aborted signal throws, or the \"TimeoutError\" of AbortSignal.timeout().\n * Use it in a `catch` block to say nothing to the user when they cancelled. A custom reason passed\n * to `abort(reason)` is not recognized: compare it with `signal.reason`. A format plugin uses it to\n * let a cancellation through untouched.\n * @param err - the thrown value\n * @returns true for an AbortError or a TimeoutError\n * @example\n * ```ts\n * try {\n * await loadFromUrl(url, { signal });\n * } catch (err) {\n * if (!isAbortError(err)) {\n * showError(err);\n * }\n * }\n * ```\n * @category Reports and errors\n */\nexport function isAbortError(err: unknown): boolean {\n if (typeof err !== \"object\" || err === null) {\n return false;\n }\n const { name } = err as { name?: unknown };\n return name === \"AbortError\" || name === \"TimeoutError\";\n}\n\n/**\n * The message of a thrown value: an Error's message, a string as is, anything else described by type.\n * @param err - the thrown value\n * @returns a plain message\n * @category Plugin helpers\n */\nexport function messageOf(err: unknown): string {\n if (err instanceof Error) {\n return err.message;\n }\n if (typeof err === \"string\") {\n return err;\n }\n return `non-error thrown (${typeof err})`;\n}\n\n/**\n * A monotonic millisecond clock: performance.now() where it exists, Date.now() otherwise.\n * @returns milliseconds\n */\nfunction now(): number {\n return typeof performance === \"object\" ? performance.now() : Date.now();\n}\n","/**\n * Number formatting for exporters (design section 3.7): an f32 weight is written as the shortest\n * decimal that round-trips through Math.fround (never `String(x)`, which prints\n * 0.10000000149011612 for a stored 0.1); an f64 value as its shortest JS text; a GML real always\n * with a decimal point so the dtype survives (design section 8.5); non-finite values as the\n * spelling the target syntax accepts.\n */\n\nimport type { NodeId } from \"@graphty/graph-format\";\n\n/**\n * The shortest decimal text that reads back to the same f32 value through Math.fround.\n * @param value - an f32 value (a JS number holding one)\n * @returns the text; \"Infinity\" / \"-Infinity\" / \"NaN\" for the non-finite values, \"-0\" for negative zero\n * @category Plugin helpers\n */\nexport function formatF32(value: number): string {\n if (!Number.isFinite(value)) {\n return String(value);\n }\n if (value === 0) {\n return Object.is(value, -0) ? \"-0\" : \"0\";\n }\n for (let digits = 1; digits <= 9; digits++) {\n const text = value.toPrecision(digits);\n if (Math.fround(Number(text)) === value) {\n return String(Number(text));\n }\n }\n return String(value);\n}\n\n/**\n * The shortest text of an f64 value: `String(x)`, which is already the shortest round-tripping\n * decimal in JS, except for negative zero, which `String()` writes as \"0\".\n * @param value - the value\n * @returns the text; \"Infinity\" / \"-Infinity\" / \"NaN\" for the non-finite values, \"-0\" for negative zero\n * @category Plugin helpers\n */\nexport function formatF64(value: number): string {\n return Object.is(value, -0) ? \"-0\" : String(value);\n}\n\n/**\n * The text of a node id for the text formats that write ids bare (DOT, Pajek, XGMML): the string\n * itself, or the shortest decimal of a number (formatF64).\n * @param id - the id\n * @returns the text\n */\nexport function idText(id: NodeId): string {\n return typeof id === \"number\" ? formatF64(id) : id;\n}\n\n/**\n * A decimal text with a decimal point or an exponent guaranteed for a finite value (`2.0`,\n * `1e+21`, `1.5e-7`), so an\n * untyped re-import keeps the column f64 rather than i32; negative zero is\n * written `-0.0` so it reads back as -0; non-finite values are the JS spellings (`Infinity`,\n * `-Infinity`, `NaN`), which the CSV / DOT / Pajek importers read back as text. The one\n * implementation of the \"decimal point guaranteed\" rule for every text format; GML has its own\n * spellings of the non-finite values in formatGmlReal().\n * @param value - the value\n * @param dtype - the column dtype the value comes from; f32 values use the shortest fround-round-trip text\n * @returns the text\n * @category Plugin helpers\n */\nexport function formatDecimal(value: number, dtype: \"f32\" | \"f64\" | \"i32\" | \"u32\" | \"u8\" = \"f64\"): string {\n if (!Number.isFinite(value)) {\n return String(value);\n }\n if (Object.is(value, -0)) {\n return \"-0.0\";\n }\n const text = formatNumber(value, dtype);\n // an exponent form (`1e+21`, `1.5e-7`) is already f64 text under the 5.1 grammar\n return text.includes(\".\") || text.includes(\"e\") ? text : `${text}.0`;\n}\n\n/**\n * A GML real: the shortest text with a decimal point guaranteed (`2.0`, `1.0e-7`), so a re-import\n * keeps the column real rather than int. Non-finite values have no GML spelling and are written\n * as the texts NetworkX's writer emits and its reader accepts, `+INF`, `-INF` and `NAN` (the\n * lowercase `inf` / `nan` would lex as keys there).\n * @param value - the value\n * @param dtype - the column dtype the value comes from; f32 values use the shortest fround-round-trip text\n * @returns the text\n * @category Plugin helpers\n */\nexport function formatGmlReal(value: number, dtype: \"f32\" | \"f64\" | \"i32\" | \"u32\" | \"u8\" = \"f64\"): string {\n if (Number.isNaN(value)) {\n return \"NAN\";\n }\n if (!Number.isFinite(value)) {\n return value > 0 ? \"+INF\" : \"-INF\";\n }\n const text = formatDecimal(value, dtype);\n if (text.includes(\".\")) {\n return text;\n }\n // NetworkX's real pattern requires a decimal point even in the exponent form (`1.0e-7`)\n const e = text.indexOf(\"e\");\n return `${text.slice(0, e)}.0${text.slice(e)}`;\n}\n\n/**\n * An integer text for a value known to be integral (an i32 / u32 / u8 cell, an f64 that holds an\n * integer), avoiding the exponent form `String()` uses above 1e21.\n * @param value - an integral value\n * @returns the digits\n * @category Plugin helpers\n */\nexport function formatInteger(value: number): string {\n if (Number.isSafeInteger(value) || !Number.isFinite(value)) {\n return String(value);\n }\n return BigInt(value).toString();\n}\n\n/**\n * The text of a numeric cell of any numeric dtype, dispatching on the dtype: f32 through\n * formatF32, everything else through formatF64.\n * @param value - the value\n * @param dtype - the column dtype the value came from\n * @returns the text\n * @category Plugin helpers\n */\nexport function formatNumber(value: number, dtype: \"f32\" | \"f64\" | \"i32\" | \"u32\" | \"u8\"): string {\n return dtype === \"f32\" ? formatF32(value) : formatF64(value);\n}\n"],"names":[],"mappings":";AAmBO,MAAM,aAAa;AAMnB,MAAM,kBAAkB;AAMxB,MAAM,wBAAwB;AAM9B,MAAM,sBAAsB;AAM5B,MAAM,gBAAgB;AAOtB,MAAM,uBAAuB;AAM7B,MAAM,mBAAmB;AAMzB,MAAM,cAAc;AAMpB,MAAM,kBAAkB;AAOxB,MAAM,mBAAmB;AAMzB,MAAM,uBAAuB;AAM7B,MAAM,kBAAkB;AAMxB,MAAM,sBAAsB;AAM5B,MAAM,iBAAiB;AAMvB,MAAM,qBAAqB;AAO3B,MAAM,sBAAsB;AAM5B,MAAM,sBAAsB;AAO5B,MAAM,kBAAkB;AAMxB,MAAM,iBAAiB;AAOvB,MAAM,iBAAiB;AAOvB,MAAM,mBAAmB;AAMzB,MAAM,sBAAsB;AAM5B,MAAM,oBAAoB;AAO1B,MAAM,wBAAwB;AAM9B,MAAM,yBAAyB;AAM/B,MAAM,wBAAwB;AAQ9B,MAAM,yBAAyB;AAO/B,MAAM,yBAAyB;AAO/B,MAAM,sBAAsB;AAO5B,MAAM,yBAAyB;AAM/B,MAAM,6BAA6B;AAQnC,MAAM,yBAAyB;AAQ/B,MAAM,wBAAwB;AAQ9B,MAAM,uBAAuB;AAO7B,MAAM,kBAAkB;AAMxB,MAAM,yBAAyB;AAM/B,MAAM,mBAAmB;AAMzB,MAAM,mBAAmB;AAMzB,MAAM,yBAAyB;AAM/B,MAAM,iBAAiB;AAOvB,MAAM,eAAe;AAQrB,MAAM,0BAA0B;AAMhC,MAAM,2BAA2B;AAMjC,MAAM,oBAAoB;AAM1B,MAAM,wBAAwB;AAO9B,MAAM,2BAA2B;AAOjC,MAAM,wBAAwB;AAM9B,MAAM,6BAA6B;AAMnC,MAAM,4BAA4B;AAOlC,MAAM,+BAA+B;AAMrC,MAAM,oBAAoB;AAM1B,MAAM,sBAAsB;AAO5B,MAAM,qBAAqB;AAM3B,MAAM,sBAAsB;AAO5B,MAAM,iBAAiB;AASvB,MAAM,mBAAmB;AAOzB,MAAM,uBAAuB;AAM7B,MAAM,4BAA4B;AAMlC,MAAM,sBAAsB;AAM5B,MAAM,iBAAiB;AAOvB,MAAM,oBAAoB;AAO1B,MAAM,0BAA0B;AAQhC,MAAM,sBAAsB;AAO5B,MAAM,gBAAgB;AAQtB,MAAM,wBAAwB;AAQ9B,MAAM,oBAAoB;AAM1B,MAAM,uBAAuB;AAM7B,MAAM,wBAAwB;AAM9B,MAAM,uBAAuB;AAM7B,MAAM,4BAA4B;AAMlC,MAAM,oBAAoB;AAM1B,MAAM,yBAAyB;AAM/B,MAAM,6BAA6B;AAMnC,MAAM,uBAAuB;AAO7B,MAAM,wBAAwB;AAO9B,MAAM,oBAAoB;AAO1B,MAAM,2BAA2B;AAMjC,MAAM,4BAA4B;AAOlC,MAAM,qBAAqB;AAO3B,MAAM,oBAAoB;AAO1B,MAAM,qBAAqB;AAM3B,MAAM,wBAAwB;AAM9B,MAAM,gCAAgC;AAMtC,MAAM,wBAAwB;AAM9B,MAAM,qBAAqB;AAO3B,MAAM,gCAAgC;AAOtC,MAAM,yBAAyB;AAM/B,MAAM,yBAAyB;AAM/B,MAAM,kBAAkB;AAOxB,MAAM,sBAAsB;AAU5B,MAAM,gBAAgB,OAAO,OAAO;AAAA;AAAA,EAEvC,YAAY;AAAA;AAAA,EAEZ,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA,EAKd,gBAAgB;AAAA;AAAA,EAEhB,gBAAgB;AAAA;AAAA,EAEhB,WAAW;AAAA;AAAA,EAEX,mBAAmB;AACvB,CAAC;AASM,MAAM,cAAc,OAAO,OAAO;AAAA;AAAA,EAErC,aAAa;AAAA;AAAA,EAEb,WAAW;AAAA;AAAA,EAEX,mBAAmB;AAAA;AAAA,EAEnB,mBAAmB;AAAA;AAAA,EAEnB,gBAAgB;AAAA;AAAA,EAEhB,mBAAmB;AACvB,CAAC;ACjoBM,SAAS,OAAO,GAAmB;AACtC,SAAO,MAAM,IAAI,KAAK;AAC1B;AASO,SAAS,MAAM,GAAW,KAAa,MAAsB;AAChE,SAAO,MAAM,IAAI,MAAM;AAC3B;AAQO,SAAS,aAAa,OAAe,OAAuB;AAC/D,QAAM,QAAQ,CAAA;AACd,MAAI,QAAQ,KAAK,UAAU,GAAG;AAC1B,UAAM,KAAK,GAAG,KAAK,QAAQ,OAAO,KAAK,CAAC,EAAE;AAAA,EAC9C;AACA,MAAI,QAAQ,GAAG;AACX,UAAM,KAAK,GAAG,KAAK,QAAQ,OAAO,KAAK,CAAC,EAAE;AAAA,EAC9C;AACA,SAAO,MAAM,KAAK,OAAO;AAC7B;AAOO,SAAS,YAAY,MAAsB;AAC9C,SAAO,GAAG,YAAY,KAAK,IAAI,IAAI,OAAO,GAAG,IAAI,IAAI;AACzD;ACijBO,MAAM,oBAAoB,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmC9C,YAAY,SAAiB,QAAsB,SAA6C;AAC5F,UAAM,YAAY,SAAS,OAAO;AAClC,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,UAAU,EAAE,OAAO,QAAQ,YAAY,OAAO;AAC1E,SAAK,QAAQ,cAAc,OAAO,QAAQ,SAAS,IAAI;AAAA,EAC3D;AACJ;AAQA,SAAS,cAAc,QAAgC,MAAmC;AACtF,MAAI,YAAgC;AACpC,WAAS,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AACzC,QAAI,OAAO,CAAC,EAAE,SAAS,MAAM;AACzB,aAAO,OAAO,CAAC;AAAA,IACnB;AACA,QAAI,cAAc,QAAQ,OAAO,CAAC,EAAE,aAAa,SAAS;AACtD,kBAAY,OAAO,CAAC;AAAA,IACxB;AAAA,EACJ;AACA,SAAO;AACX;ACtoBO,MAAM,wBAAwB;AAGrC,MAAM,sCAAsB,QAAA;AAG5B,MAAM,sCAAqC,cAAc;AASlD,SAAS,cAAc,QAA+B;AACzD,SAAO,gBAAgB,IAAI,MAAM;AACrC;AAsCA,MAAM,mBAAmF;AAAA,EACrF,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,eAAe;AAAA,EACf,kBAAkB;AACtB;AAMO,MAAM,mBAAmB;AAShC,SAAS,SAAS,SAAiB,OAA0C;AACzE,QAAM,OAAO,OAAO;AACpB,SAAO,SAAS,UAAa,SAAS,QAAQ,QAAQ,SAAS,QAAQ,IAAI,EAAE,IACvE,UACA,QAAQ,IAAI,KAAK,OAAO;AAClC;AAQO,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkC7B,YAAY,QAAgB,YAAoB;AA1BhD,SAAS,SAAwB,EAAE,OAAO,GAAG,OAAO,GAAG,cAAc,GAAG,cAAc,GAAG,eAAe,EAAA;AAExG,SAAiB,YAA2B,CAAA;AAE5C,SAAiB,WAAuB,CAAA;AAExC,SAAiB,gCAAgB,IAAA;AAGjC,SAAiB,qCAAqB,IAAA;AAEtC,SAAQ,SAAS;AAEjB,SAAQ,WAAW;AAEnB,SAAQ,gBAAgB;AAExB,SAAQ,OAAgB;AAUpB,SAAK,SAAS;AACd,SAAK,aAAa;AAClB,SAAK,YAAY,IAAA;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,SAAiC;AACjC,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,aAAqB;AACrB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,eAAuB;AACvB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,YAAqB;AACrB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,QAA6B;AAC7B,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,UAAyB,MAAc,SAAiB,OAAoC;AAC9F,UAAM,QAAQ,UAAU,UAAU,SAAS,MAAM,SAAS,KAAK;AAC/D,SAAK,UAAU,KAAK,KAAK;AACzB,SAAK;AACL,QAAI,KAAK,SAAS,KAAK,YAAY;AAC/B,WAAK,gBAAgB;AACrB,YAAM,KAAK,MAAM,kBAAkB,KAAK,UAAU,cAAc,SAAS,SAAS,KAAK,CAAC,IAAI;AAAA,QACxF;AAAA,QACA,OAAO,KAAK;AAAA,MAAA,CACf;AAAA,IACL;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,QAAQ,UAAyB,MAAc,SAAiB,OAAoC;AAChG,UAAM,QAAQ,UAAU,UAAU,WAAW,MAAM,SAAS,KAAK;AACjE,UAAM,QAAQ,KAAK,eAAe,IAAI,IAAI,KAAK,KAAK;AACpD,SAAK,eAAe,IAAI,MAAM,IAAI;AAClC,QAAI,QAAQ,uBAAuB;AAC/B,WAAK,UAAU,KAAK,KAAK;AACzB,WAAK;AAAA,IACT;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,SACI,UACA,MACA,SACA,OACA,MAAc,MACI;AAClB,QAAI,KAAK,UAAU,IAAI,GAAG,GAAG;AACzB,aAAO;AAAA,IACX;AACA,SAAK,UAAU,IAAI,GAAG;AACtB,WAAO,KAAK,QAAQ,UAAU,MAAM,SAAS,KAAK;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,KAAK,MAAc,SAAiB,SAAwB,MAAM,QAAuB,MAAgB;AACrG,UAAM,OAAiB,OAAO,OAAO,EAAE,MAAM,SAAS,QAAQ,OAAO;AACrE,SAAK,SAAS,KAAK,IAAI;AACvB,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAY,KAAc,OAAoC;AAC1D,QAAI,eAAe,oBAAoB,EAAE,eAAe,cAAc;AAClE,YAAM,WAAW,iBAAiB,IAAI,IAAI,KAAK;AAC/C,UAAI,IAAI,SAAS,eAAe;AAE5B,eAAO,KAAK,SAAS,UAAU,IAAI,MAAM,IAAI,SAAS,KAAK;AAAA,MAC/D;AACA,aAAO,KAAK,MAAM,UAAU,IAAI,MAAM,IAAI,SAAS,KAAK;AAAA,IAC5D;AACA,UAAM;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,cAAc,OAAsB;AAChC,SAAK,OAAO;AACZ,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAA4B;AACxB,UAAM,OAAO,IAAI,oBAAoB,KAAK,QAAQ,KAAK,UAAU;AACjE,WAAO,OAAO,KAAK,QAAQ,KAAK,MAAM;AACtC,SAAK,UAAU,KAAK,GAAG,KAAK,SAAS;AACrC,SAAK,SAAS,KAAK,GAAG,KAAK,QAAQ;AACnC,eAAW,OAAO,KAAK,WAAW;AAC9B,WAAK,UAAU,IAAI,GAAG;AAAA,IAC1B;AACA,eAAW,CAAC,MAAM,KAAK,KAAK,KAAK,gBAAgB;AAC7C,WAAK,eAAe,IAAI,MAAM,KAAK;AAAA,IACvC;AACA,SAAK,SAAS,KAAK;AACnB,SAAK,WAAW,KAAK;AACrB,SAAK,gBAAgB,KAAK;AAC1B,SAAK,OAAO,KAAK;AACjB,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAiB,SAA0D;AAC7E,WAAO,IAAI,YAAY,SAAS,KAAK,OAAA,GAAU,OAAO;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,KAAK,MAAc,SAAiB,OAAuB,SAAoD;AAC3G,SAAK,SAAS,eAAe,MAAM,SAAS,OAAO,OAAO;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,SACI,UACA,MACA,SACA,OACA,SACK;AACL,SAAK,UAAU,KAAK,UAAU,UAAU,SAAS,MAAM,SAAS,KAAK,CAAC;AACtE,SAAK;AACL,UAAM,KAAK,MAAM,SAAS,SAAS,KAAK,GAAG,EAAE,MAAM,GAAG,SAAS;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,QAAQ,QAA4B;AAChC,eAAW,SAAS,OAAO,QAAQ;AAC/B,WAAK,UAAU,KAAK,KAAK;AACzB,UAAI,MAAM,aAAa,SAAS;AAC5B,aAAK;AAAA,MACT,OAAO;AACH,aAAK;AAAA,MACT;AAAA,IACJ;AACA,UAAM,EAAE,WAAW;AACnB,SAAK,OAAO,SAAS,OAAO;AAC5B,SAAK,OAAO,SAAS,OAAO;AAC5B,SAAK,OAAO,gBAAgB,OAAO;AACnC,SAAK,OAAO,gBAAgB,OAAO;AACnC,SAAK,OAAO,iBAAiB,OAAO;AACpC,SAAK,SAAS,KAAK,GAAG,OAAO,KAAK;AAClC,SAAK,kBAAkB,OAAO;AAC9B,QAAI,KAAK,SAAS,gBAAgB,gBAAgB,IAAI,MAAM,GAAG;AAC3D,WAAK,OAAO,gBAAgB,IAAI,MAAM;AAAA,IAC1C;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAuB;AACnB,UAAM,EAAE,OAAO,OAAO,cAAc,cAAc,cAAA,IAAkB,KAAK;AACzE,UAAM,aAA4B,CAAA;AAClC,eAAW,CAAC,MAAM,IAAI,KAAK,KAAK,gBAAgB;AAC5C,UAAI,OAAO,uBAAuB;AAC9B,cAAM,OAAO,OAAO;AACpB,mBAAW;AAAA,UACP;AAAA,YACI;AAAA,YACA;AAAA,YACA;AAAA,YACA,GAAG,IAAI,SAAS,IAAI,WAAW,OAAO,IAAI,CAAC,IAAI,MAAM,MAAM,OAAO,MAAM,CAAC,yCAAyC,qBAAqB;AAAA,YACvI,EAAE,SAAS,KAAA;AAAA,UAAK;AAAA,QACpB;AAAA,MAER;AAAA,IACJ;AACA,UAAM,SAAuB,OAAO,OAAO;AAAA,MACvC,QAAQ,KAAK;AAAA,MACb,QAAQ,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,cAAc,eAAe;AAAA,MACjF,QAAQ,OAAO,OAAO,CAAC,GAAG,KAAK,WAAW,GAAG,UAAU,CAAC;AAAA,MACxD,YAAY,KAAK;AAAA,MACjB,cAAc,KAAK,WAAW,WAAW;AAAA,MACzC,WAAW,KAAK;AAAA,MAChB,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC;AAAA,MACvC,YAAY,IAAA,IAAQ,KAAK;AAAA,IAAA,CAC5B;AACD,QAAI,KAAK,SAAS,cAAc;AAC5B,sBAAgB,IAAI,QAAQ,KAAK,IAAI;AAAA,IACzC;AACA,WAAO;AAAA,EACX;AACJ;AAWA,SAAS,UACL,UACA,UACA,MACA,SACA,OACW;AACX,SAAO,OAAO,OAAO;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,OAAO,QAAQ;AAAA,IACrB,SAAS,OAAO,WAAW;AAAA,EAAA,CAC9B;AACL;AAsBO,SAAS,aAAa,KAAuB;AAChD,MAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AACzC,WAAO;AAAA,EACX;AACA,QAAM,EAAE,SAAS;AACjB,SAAO,SAAS,gBAAgB,SAAS;AAC7C;AAQO,SAAS,UAAU,KAAsB;AAC5C,MAAI,eAAe,OAAO;AACtB,WAAO,IAAI;AAAA,EACf;AACA,MAAI,OAAO,QAAQ,UAAU;AACzB,WAAO;AAAA,EACX;AACA,SAAO,qBAAqB,OAAO,GAAG;AAC1C;AAMA,SAAS,MAAc;AACnB,SAAO,OAAO,gBAAgB,WAAW,YAAY,IAAA,IAAQ,KAAK,IAAA;AACtE;ACtgBO,SAAS,UAAU,OAAuB;AAC7C,MAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AACzB,WAAO,OAAO,KAAK;AAAA,EACvB;AACA,MAAI,UAAU,GAAG;AACb,WAAO,OAAO,GAAG,OAAO,EAAE,IAAI,OAAO;AAAA,EACzC;AACA,WAAS,SAAS,GAAG,UAAU,GAAG,UAAU;AACxC,UAAM,OAAO,MAAM,YAAY,MAAM;AACrC,QAAI,KAAK,OAAO,OAAO,IAAI,CAAC,MAAM,OAAO;AACrC,aAAO,OAAO,OAAO,IAAI,CAAC;AAAA,IAC9B;AAAA,EACJ;AACA,SAAO,OAAO,KAAK;AACvB;AASO,SAAS,UAAU,OAAuB;AAC7C,SAAO,OAAO,GAAG,OAAO,EAAE,IAAI,OAAO,OAAO,KAAK;AACrD;AAQO,SAAS,OAAO,IAAoB;AACvC,SAAO,OAAO,OAAO,WAAW,UAAU,EAAE,IAAI;AACpD;AAeO,SAAS,cAAc,OAAe,QAA8C,OAAe;AACtG,MAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AACzB,WAAO,OAAO,KAAK;AAAA,EACvB;AACA,MAAI,OAAO,GAAG,OAAO,EAAE,GAAG;AACtB,WAAO;AAAA,EACX;AACA,QAAM,OAAO,aAAa,OAAO,KAAK;AAEtC,SAAO,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG,IAAI,OAAO,GAAG,IAAI;AACpE;AAYO,SAAS,cAAc,OAAe,QAA8C,OAAe;AACtG,MAAI,OAAO,MAAM,KAAK,GAAG;AACrB,WAAO;AAAA,EACX;AACA,MAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AACzB,WAAO,QAAQ,IAAI,SAAS;AAAA,EAChC;AACA,QAAM,OAAO,cAAc,OAAO,KAAK;AACvC,MAAI,KAAK,SAAS,GAAG,GAAG;AACpB,WAAO;AAAA,EACX;AAEA,QAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,SAAO,GAAG,KAAK,MAAM,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;AAChD;AASO,SAAS,cAAc,OAAuB;AACjD,MAAI,OAAO,cAAc,KAAK,KAAK,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,WAAO,OAAO,KAAK;AAAA,EACvB;AACA,SAAO,OAAO,KAAK,EAAE,SAAA;AACzB;AAUO,SAAS,aAAa,OAAe,OAAqD;AAC7F,SAAO,UAAU,QAAQ,UAAU,KAAK,IAAI,UAAU,KAAK;AAC/D;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"generic-Dq1ntt9q.js","sources":["../../src/styles/plan/families.ts","../../src/styles/plan/discrete.ts","../../src/styles/plan/classes.ts","../../src/styles/plan/continuous.ts","../../src/styles/plan/plan.ts","../../src/styles/io/generic.ts"],"sourcesContent":["/**\n * Exact equivalence classes: every property's values partition the elements (null is a block of its own), and\n * properties with identical partitions form one family, explained once.\n */\n\nimport type { StyleValue } from \"../types.js\";\n\n/**\n * A group of properties that partition the elements the same way.\n */\nexport interface Family {\n /** The properties, in the order they were given. */\n readonly props: string[];\n /** Each element's block: 0 for null, 1.. by first appearance. */\n readonly blocks: Int32Array;\n /** The number of non-null blocks. */\n readonly k: number;\n /** The elements with a value (block above 0), ascending. */\n readonly styled: number[];\n}\n\n/**\n * The text a value is compared by.\n * @param v - the value\n * @returns a key unique per value and type\n */\nexport function valueKey(v: string | number | boolean | null | undefined): string {\n return v === null || v === undefined ? \"\\u0000null\" : `${typeof v}:${String(v)}`;\n}\n\n/**\n * The partition of the elements by a property's values.\n * @param values - the values by element\n * @returns each element's block (0 for null, then by first appearance) and the number of non-null blocks\n */\nfunction partition(values: readonly (StyleValue | null)[]): { blocks: Int32Array; k: number } {\n const ids = new Map<string, number>();\n const blocks = new Int32Array(values.length);\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (v === null) {\n continue;\n }\n const key = valueKey(v);\n let id = ids.get(key);\n if (id === undefined) {\n id = ids.size + 1;\n ids.set(key, id);\n }\n blocks[i] = id;\n }\n return { blocks, k: ids.size };\n}\n\n/**\n * A hash of a block array.\n * @param blocks - the blocks\n * @returns its hash\n */\nfunction hashBlocks(blocks: Int32Array): number {\n let h = 0x811c9dc5;\n for (const b of blocks) {\n h = Math.imul(h ^ b, 0x01000193);\n }\n return h >>> 0;\n}\n\n/**\n * Whether two block arrays are equal.\n * @param a - one\n * @param b - the other\n * @returns true when equal\n */\nfunction sameBlocks(a: Int32Array, b: Int32Array): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Groups properties by identical partitions.\n * @param props - the properties, each with its values\n * @returns the families, in the order of their first property\n */\nexport function familiesOf(props: readonly (readonly [string, readonly (StyleValue | null)[]])[]): Family[] {\n const byHash = new Map<number, Family[]>();\n const out: Family[] = [];\n for (const [p, values] of props) {\n const { blocks, k } = partition(values);\n const h = hashBlocks(blocks);\n const list = byHash.get(h) ?? [];\n const hit = list.find((f) => sameBlocks(f.blocks, blocks));\n if (hit !== undefined) {\n hit.props.push(p);\n continue;\n }\n const styled: number[] = [];\n for (let i = 0; i < blocks.length; i++) {\n if (blocks[i] !== 0) {\n styled.push(i);\n }\n }\n const fam: Family = { props: [p], blocks, k, styled };\n list.push(fam);\n byHash.set(h, list);\n out.push(fam);\n }\n return out;\n}\n","/**\n * A discrete mapping on one categorical feature: the feature's values fall inside the family's blocks, up to 20% of\n * the styled elements excepted, and the elements missing the feature may form their own group.\n */\n\nimport { type Family, valueKey } from \"./families.js\";\nimport type { FeatureInfo } from \"./features.js\";\n\n/** Below this many styled elements anything explains anything: no mapping is tried. */\nexport const MIN_MAPPED = 8;\n/** The most keys a discrete table may hold. */\nconst MAX_KEYS = 256;\n/** The share of styled elements a mapping may get wrong; the replay moves them into the exceptions. */\nconst MAX_EXCEPTION_SHARE = 0.2;\n\n/** A key of a discrete table, as the feature holds it. */\ntype KeyValue = string | number | boolean;\n\n/**\n * A discrete mapping that explains a family.\n */\nexport interface DiscreteCandidate {\n /** The kind of candidate. */\n readonly type: \"discrete\";\n /** The feature the table reads. */\n readonly info: FeatureInfo;\n /** Each key (by its value key) with its raw value and the block it maps to. */\n readonly table: Map<string, { readonly raw: KeyValue; readonly block: number }>;\n /** The block the elements missing the feature share, or null. */\n readonly bucket: number | null;\n /** The description cost. */\n readonly cost: number;\n}\n\n/**\n * Tests a discrete mapping on one feature.\n * @param fam - the family\n * @param info - the feature\n * @param n - the element count\n * @param spend - spends work from the budget\n * @returns the candidate, or null when the feature does not explain the family\n */\nexport function discreteCandidate(\n fam: Family,\n info: FeatureInfo,\n n: number,\n spend: (ops: number) => void,\n): DiscreteCandidate | null {\n const nF = fam.styled.length;\n if (!info.categorical || info.raw || nF < MIN_MAPPED) {\n return null;\n }\n if (info.distinct < 2 || info.distinct > Math.min(MAX_KEYS, nF / 2) || info.distinct >= 0.9 * n) {\n return null;\n }\n spend(n);\n const { values } = info.feature;\n const { votes, nullBlocks } = votesOf(fam, values);\n const { table, exceptions: wrong } = tableOf(votes);\n let exceptions = wrong;\n // never paint an element the file left unstyled\n const unstyledMissing = unstyledOf(fam, values, table, n);\n if (unstyledMissing === null) {\n return null;\n }\n // the elements missing the key form one group when they share one style (Gephi's \"null\" partition)\n let bucket: number | null = null;\n if (nullBlocks.size === 1 && !unstyledMissing) {\n bucket = nullBlocks.keys().next().value ?? null;\n } else {\n for (const c of nullBlocks.values()) {\n exceptions += c;\n }\n }\n if (exceptions > Math.max(2, MAX_EXCEPTION_SHARE * nF)) {\n return null;\n }\n const cost =\n 50 + table.size * fam.props.length + (exceptions > 0 ? 50 + exceptions : 0) + (bucket === null ? 0 : 50);\n return { type: \"discrete\", info, table, bucket, cost };\n}\n\n/** How the styled elements of each key fall into the family's blocks. */\ntype Votes = Map<string, { raw: KeyValue; counts: Map<number, number> }>;\n\n/**\n * Counts, per key of the feature, the styled elements in each block; and per block, those missing the feature.\n * @param fam - the family\n * @param values - the feature's values\n * @returns the votes, and the blocks of the elements missing the feature\n */\nfunction votesOf(fam: Family, values: readonly (KeyValue | null)[]): { votes: Votes; nullBlocks: Map<number, number> } {\n const votes: Votes = new Map();\n const nullBlocks = new Map<number, number>();\n for (const i of fam.styled) {\n const b = fam.blocks[i];\n const kv = values[i];\n if (kv === null) {\n nullBlocks.set(b, (nullBlocks.get(b) ?? 0) + 1);\n continue;\n }\n const key = valueKey(kv);\n let vote = votes.get(key);\n if (vote === undefined) {\n vote = { raw: kv, counts: new Map() };\n votes.set(key, vote);\n }\n vote.counts.set(b, (vote.counts.get(b) ?? 0) + 1);\n }\n return { votes, nullBlocks };\n}\n\n/**\n * The table: each key maps to the block most of its elements are in; the others are exceptions.\n * @param votes - the votes\n * @returns the table and how many elements it gets wrong\n */\nfunction tableOf(votes: Votes): { table: Map<string, { raw: KeyValue; block: number }>; exceptions: number } {\n const table = new Map<string, { raw: KeyValue; block: number }>();\n let exceptions = 0;\n for (const [key, { raw, counts }] of votes) {\n let best = -1;\n let bestCount = -1;\n let total = 0;\n for (const [b, c] of counts) {\n total += c;\n if (c > bestCount) {\n bestCount = c;\n best = b;\n }\n }\n table.set(key, { raw, block: best });\n exceptions += total - bestCount;\n }\n return { table, exceptions };\n}\n\n/**\n * Whether an element the file left unstyled misses the feature (or holds false, which a missing-key group's \"not has\"\n * also matches).\n * @param fam - the family\n * @param values - the feature's values\n * @param table - the table\n * @param n - the element count\n * @returns the answer, or null when the table would paint an unstyled element\n */\nfunction unstyledOf(\n fam: Family,\n values: readonly (KeyValue | null)[],\n table: ReadonlyMap<string, unknown>,\n n: number,\n): boolean | null {\n let missing = false;\n for (let i = 0; i < n; i++) {\n const v = values[i];\n if (fam.blocks[i] !== 0) {\n continue;\n }\n if (v !== null && table.has(valueKey(v))) {\n return null;\n }\n missing ||= v === null || v === false;\n }\n return missing;\n}\n","/**\n * The opaque pool: the families nothing explains. Over their non-text, non-size properties each distinct joint tuple\n * of values is a style class, numbered 1..k by frequency in the style column `class`; a few classes become one group\n * rule each, more become one table keyed by the class. What is left is copied per element.\n */\n\nimport type { StyleRule, StyleTarget, StyleValue } from \"../types.js\";\nimport { STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { MIN_MAPPED } from \"./discrete.js\";\nimport { valueKey } from \"./families.js\";\n\n/** The most style classes; more distinct tuples are copied per element. */\nconst MAX_CLASSES = 64;\n/** At most this many classes become one group rule each. */\nconst MAX_CLASS_RULES = 4;\n/** Sizes vary per element by nature and are never joined into a class. */\nconst SIZES: ReadonlySet<string> = new Set([\"width\", \"height\"]);\n/** The style column holding each element's class. */\nexport const CLASS_COLUMN = \"class\";\n\n/**\n * The style classes of an opaque pool.\n */\ninterface StyleClasses {\n /** The properties the classes explain. */\n readonly classed: readonly string[];\n /** The class of each element, 1..k, or null. */\n readonly column: (number | null)[];\n /** One group rule per class, or one mapping rule keyed by the class. */\n readonly rules: StyleRule[];\n}\n\n/**\n * Whether a property's values have few enough distinct values to be part of a class.\n * @param values - the values\n * @returns true when they do\n */\nfunction fewValues(values: readonly (StyleValue | null)[]): boolean {\n const seen = new Set<string>();\n for (const v of values) {\n seen.add(valueKey(v));\n if (seen.size > MAX_CLASSES + 1) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * One element's combination of values of the classable properties, as a key; null when it has none.\n * @param classable - the properties\n * @param truth - the values per property\n * @param i - the element\n * @returns the key\n */\nfunction tupleKey(\n classable: readonly string[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n i: number,\n): string | null {\n let key = \"\";\n let any = false;\n for (const p of classable) {\n const v = (truth.get(p) ?? [])[i] ?? null;\n any ||= v !== null;\n key += `${valueKey(v)}\\u0001`;\n }\n return any ? key : null;\n}\n\n/**\n * Finds the style classes of the opaque properties.\n * @param target - nodes or edges\n * @param props - the opaque properties\n * @param truth - the values per property\n * @param n - the element count\n * @param spend - spends work from the budget\n * @returns the classes, or null when the values have too many combinations\n */\nexport function styleClasses(\n target: StyleTarget,\n props: readonly string[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n n: number,\n spend: (ops: number) => void,\n): StyleClasses | null {\n const classable = props.filter(\n (p) => STYLE_PROPERTIES[target].get(p) !== \"text\" && !SIZES.has(p) && fewValues(truth.get(p) ?? []),\n );\n if (classable.length === 0) {\n return null;\n }\n spend(n * (classable.length + 1));\n const counts = new Map<string, { count: number; rep: number }>();\n const tupleOf = new Array<string | null>(n).fill(null);\n let withTuple = 0;\n for (let i = 0; i < n; i++) {\n const key = tupleKey(classable, truth, i);\n if (key === null) {\n continue;\n }\n withTuple++;\n tupleOf[i] = key;\n const c = counts.get(key);\n if (c === undefined) {\n counts.set(key, { count: 1, rep: i });\n if (counts.size > MAX_CLASSES) {\n return null;\n }\n } else {\n c.count++;\n }\n }\n if (counts.size === 0 || withTuple < MIN_MAPPED || counts.size * 2 > withTuple) {\n return null;\n }\n // classes by frequency, ties by first appearance (a stable sort)\n const order = Array.from(counts.entries()).sort((a, b) => b[1].count - a[1].count);\n const rank = new Map(order.map(([key], j) => [key, j + 1]));\n const column = tupleOf.map((t) => (t === null ? null : (rank.get(t) ?? null)));\n const ref = { style: CLASS_COLUMN };\n const valueOf = (p: string, rep: number): StyleValue | null => (truth.get(p) ?? [])[rep] ?? null;\n const rules: StyleRule[] = [];\n if (order.length <= Math.min(MAX_CLASS_RULES, Math.floor(withTuple / 4))) {\n order.forEach(([, { count, rep }], j) => {\n const set: Record<string, StyleValue> = {};\n for (const p of classable) {\n const v = valueOf(p, rep);\n if (v !== null) {\n set[p] = v;\n }\n }\n rules.push({\n id: `${target}.class.${String(j + 1)}`,\n target,\n role: \"group\",\n origin: \"inferred\",\n where: { eq: [ref, j + 1] },\n set,\n facts: { elements: count, reason: \"STYLE_CLASS\" },\n });\n });\n } else {\n const map: Record<string, { kind: \"discrete\"; by: { style: string }; table: [number, StyleValue][] }> = {};\n for (const p of classable) {\n const table: [number, StyleValue][] = [];\n order.forEach(([, { rep }], j) => {\n const v = valueOf(p, rep);\n if (v !== null) {\n table.push([j + 1, v]);\n }\n });\n map[p] = { kind: \"discrete\", by: ref, table };\n }\n rules.push({\n id: `${target}.classes`,\n target,\n role: \"mapping\",\n origin: \"inferred\",\n where: { all: true },\n map,\n facts: { classes: order.length, elements: withTuple, reason: \"STYLE_CLASS\" },\n });\n }\n return { classed: classable, column, rules };\n}\n","/**\n * A continuous mapping on one numeric feature: the fewest linear pieces (at most 8, each explaining at least 3\n * distinct inputs), exact first, else within the rounding the writing tool did per element.\n */\n\nimport type { ContinuousPoint, StyleValue } from \"../types.js\";\nimport { MIN_MAPPED } from \"./discrete.js\";\nimport type { Family } from \"./families.js\";\nimport type { FeatureInfo } from \"./features.js\";\nimport { interpolate, within } from \"./resolve.js\";\n\n/** The most linear pieces a ramp may have. */\nconst MAX_PIECES = 8;\n/** The most distinct inputs a ramp is fitted over. */\nconst MAX_DISTINCT_X = 4096;\nconst HEX6 = /^#[0-9a-f]{6}$/;\n\n/**\n * A continuous mapping that explains a family.\n */\nexport interface ContinuousCandidate {\n /** The kind of candidate. */\n readonly type: \"continuous\";\n /** The feature the ramp reads. */\n readonly info: FeatureInfo;\n /** The points per property. */\n readonly points: ReadonlyMap<string, ContinuousPoint[]>;\n /** Whether the ramp matches only within the tool's rounding. */\n readonly tolerant: boolean;\n /** The description cost. */\n readonly cost: number;\n}\n\n/**\n * Whether a value can be interpolated: a number or a canonical color.\n * @param v - the value\n * @returns true when it can\n */\nfunction interpolable(v: StyleValue | null): v is number | string {\n return typeof v === \"number\" || (typeof v === \"string\" && HEX6.test(v));\n}\n\n/**\n * The fewest linear pieces over sorted distinct points, or null when more than `MAX_PIECES` are needed.\n * @param xs - the inputs, ascending\n * @param ys - the outputs\n * @param tolerant - whether a piece may miss a point by the tool's rounding\n * @param spend - spends work from the budget\n * @returns each piece's first and last point index, or null\n */\nfunction fitPieces(\n xs: readonly number[],\n ys: readonly StyleValue[],\n tolerant: boolean,\n spend: (ops: number) => void,\n): [number, number][] | null {\n const pieces: [number, number][] = [];\n let a = 0;\n while (a < xs.length) {\n let b = a;\n // extend while the line from a to b + 1 reproduces every point between\n while (b + 1 < xs.length) {\n const ok = lineFits(xs, ys, a, b + 1, tolerant);\n spend(b + 1 - a);\n if (!ok) {\n break;\n }\n b++;\n }\n pieces.push([a, b]);\n if (pieces.length > MAX_PIECES) {\n return null;\n }\n a = b + 1;\n }\n return pieces;\n}\n\n/**\n * Whether the line from point a to point c reproduces every point between.\n * @param xs - the inputs, ascending\n * @param ys - the outputs\n * @param a - the first point\n * @param c - the last point\n * @param tolerant - whether the line may miss a point by the tool's rounding\n * @returns true when it does\n */\nfunction lineFits(xs: readonly number[], ys: readonly StyleValue[], a: number, c: number, tolerant: boolean): boolean {\n for (let j = a + 1; j < c; j++) {\n const v = interpolate(ys[a], ys[c], (xs[j] - xs[a]) / (xs[c] - xs[a]));\n if (tolerant ? !within(v, ys[j]) : v !== ys[j]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * The points of a fitted ramp.\n * @param xs - the inputs\n * @param ys - the outputs\n * @param pieces - the pieces\n * @returns the points, ascending\n */\nfunction piecesToPoints(\n xs: readonly number[],\n ys: readonly StyleValue[],\n pieces: [number, number][],\n): ContinuousPoint[] {\n const out: ContinuousPoint[] = [];\n for (const [a, b] of pieces) {\n out.push({ at: xs[a], below: ys[a], value: ys[a], above: ys[a] });\n if (b !== a) {\n out.push({ at: xs[b], below: ys[b], value: ys[b], above: ys[b] });\n }\n }\n return out;\n}\n\n/**\n * Tests a continuous mapping on one feature.\n * @param fam - the family\n * @param info - the feature\n * @param truth - the values per property\n * @param spend - spends work from the budget\n * @returns the candidate, or null when the feature does not explain the family\n */\nexport function continuousCandidate(\n fam: Family,\n info: FeatureInfo,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n spend: (ops: number) => void,\n): ContinuousCandidate | null {\n if (!info.numeric || info.raw || fam.styled.length < MIN_MAPPED) {\n return null;\n }\n const { values } = info.feature;\n spend(values.length);\n // the feature must be a number exactly where the family has a value\n if (values.some((v, i) => (fam.blocks[i] === 0) === (typeof v === \"number\"))) {\n return null;\n }\n for (const tolerant of [false, true]) {\n const points = rampsOf(fam, values, truth, tolerant, spend);\n if (points !== null) {\n const entries = Array.from(points.values()).reduce((sum, pts) => sum + pts.length, 0);\n return { type: \"continuous\", info, points, tolerant, cost: 50 + entries + (tolerant ? 10 : 0) };\n }\n }\n return null;\n}\n\n/**\n * The ramp of every property of the family over the feature, or null when one has none.\n * @param fam - the family\n * @param values - the feature's values\n * @param truth - the values per property\n * @param tolerant - whether a ramp may miss a value by the tool's rounding\n * @param spend - spends work from the budget\n * @returns the points per property, or null\n */\nfunction rampsOf(\n fam: Family,\n values: readonly unknown[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n tolerant: boolean,\n spend: (ops: number) => void,\n): Map<string, ContinuousPoint[]> | null {\n const points = new Map<string, ContinuousPoint[]>();\n for (const p of fam.props) {\n const pts = rampOf(fam, values, truth.get(p) ?? [], tolerant, spend);\n if (pts === null) {\n return null;\n }\n points.set(p, pts);\n }\n return points;\n}\n\n/**\n * The ramp of one property over the feature, or null when none explains it.\n * @param fam - the family\n * @param values - the feature's values\n * @param ys0 - the property's values\n * @param tolerant - whether the ramp may miss a value by the tool's rounding\n * @param spend - spends work from the budget\n * @returns the points, or null\n */\nfunction rampOf(\n fam: Family,\n values: readonly unknown[],\n ys0: readonly (StyleValue | null)[],\n tolerant: boolean,\n spend: (ops: number) => void,\n): ContinuousPoint[] | null {\n const byX = new Map<number, StyleValue>();\n let good = true;\n for (const i of fam.styled) {\n const y = ys0[i];\n const x = values[i] as number;\n const seen = byX.get(x);\n if (!interpolable(y) || (seen !== undefined && seen !== y)) {\n good = false;\n break;\n }\n byX.set(x, y);\n }\n spend(fam.styled.length);\n // a ramp needs at least 3 distinct outputs: two values over a number are a threshold, not a mapping\n if (!good || byX.size < 2 || byX.size > MAX_DISTINCT_X || new Set(byX.values()).size < 3) {\n return null;\n }\n const xs = Array.from(byX.keys()).sort((a, b) => a - b);\n const ys = xs.map((x) => byX.get(x) as StyleValue);\n const pieces = fitPieces(xs, ys, tolerant, spend);\n // every piece must explain at least 3 distinct inputs, or a few points fit anything\n return pieces === null || pieces.length * 3 > xs.length ? null : piecesToPoints(xs, ys, pieces);\n}\n","/**\n * The planner: turns a file's per-element style values into a few readable rules that reproduce them exactly. It\n * groups properties into families, explains each family by a discrete or continuous mapping on one feature, a\n * passthrough on an existing column, style classes or a copy, orders the rules, caps them at 15 per target and\n * replays them: every element whose resolved value differs from the file's goes into one sparse exceptions column\n * per property on top. One counted budget bounds the work; when it runs out the rest is copied.\n */\n\nimport { StyleBudget } from \"../budget.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport { toolDefaults } from \"../defaults.js\";\nimport { StyleNotes } from \"../notes.js\";\nimport type {\n ExtractedStyles,\n GraphStyle,\n Mapping,\n ReaderOutput,\n StyleColumn,\n StyleDialect,\n StyleFeature,\n StyleFeatures,\n StyleFingerprint,\n StyleRule,\n StyleRuleFacts,\n StyleTarget,\n StyleTool,\n StyleValue,\n StyleWorkBudget,\n} from \"../types.js\";\nimport { isStyleValue, STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { CLASS_COLUMN, styleClasses } from \"./classes.js\";\nimport { type ContinuousCandidate, continuousCandidate } from \"./continuous.js\";\nimport { type DiscreteCandidate, discreteCandidate } from \"./discrete.js\";\nimport { familiesOf, type Family } from \"./families.js\";\nimport { describeFeature, type FeatureInfo } from \"./features.js\";\nimport {\n canonicalFor,\n evalContinuous,\n isShortPredicate,\n matches,\n numberOf,\n refSource,\n resolveRules,\n within,\n} from \"./resolve.js\";\n\n/**\n * The most rules per target: the planner keeps at most 15 plus the exceptions rule.\n * @category Styles\n */\nexport const MAX_STYLE_RULES = 16;\n/** The most candidate features tested per target, fewest distinct values first. */\nconst MAX_FEATURES = 64;\n/** Lengths a tool states in its own unit; they are left out when the file's unit differs. */\nconst LENGTHS: ReadonlySet<string> = new Set([\"width\", \"height\", \"borderWidth\", \"labelSize\"]);\n\n/**\n * What the planner is given: the canonical per-element values a style reader produced, the rules the file declares,\n * and the graph they belong to.\n * @category Styles\n */\nexport interface StyleValues {\n /** The graph-io format id. */\n readonly format: string;\n /** How the file spelled its values. */\n readonly dialect?: StyleDialect | null;\n /** The program that wrote the file, whose defaults fill in what the file leaves unset; null when unknown. */\n readonly tool?: StyleTool | null;\n /** The unit of every length; defaults to pixels. */\n readonly units?: \"px\" | \"relative\";\n /** The graph's own style. */\n readonly graph?: GraphStyle;\n /** Node values, declared rules, reader columns and extra features. */\n readonly node?: ReaderOutput;\n /** Edge values, declared rules, reader columns and extra features. */\n readonly edge?: ReaderOutput;\n /** The graph the values belong to; its counts give the number of elements. */\n readonly fingerprint: StyleFingerprint;\n}\n\n/**\n * Options of `planStyles()`.\n * @category Styles\n */\nexport interface PlanOptions {\n /** Whether to add the writing tool's defaults as a rule at the bottom; defaults to true. */\n readonly toolDefaults?: boolean;\n /** The counted work budget; defaults to a fresh `StyleBudget`. */\n readonly budget?: StyleWorkBudget;\n /**\n * Where notes are collected; the reader's notes, when it used the same collector, are kept.\n * @internal\n */\n readonly notes?: StyleNotes;\n /** Data columns the reader read the values from: they are never offered as explanations of themselves. */\n readonly rawColumns?: {\n /** Node columns. */\n readonly node?: readonly string[];\n /** Edge columns. */\n readonly edge?: readonly string[];\n };\n /** Cancels the planning. */\n readonly signal?: AbortSignal;\n}\n\n/** A rule being built. */\ninterface Draft {\n id: string;\n readonly target: StyleTarget;\n readonly role: string;\n readonly origin: string;\n where: StyleRule[\"where\"];\n set?: Record<string, StyleValue>;\n map?: Record<string, Mapping>;\n facts?: StyleRuleFacts;\n readonly ext?: Readonly<Record<string, unknown>>;\n}\n\n/** The planning state of one target. */\ninterface TargetPlan {\n readonly target: StyleTarget;\n readonly n: number;\n readonly notes: StyleNotes;\n readonly budget: StyleWorkBudget;\n readonly spend: (ops: number) => void;\n readonly columns: Map<string, StyleColumn>;\n readonly ids: Set<string>;\n}\n\n/**\n * Plans a file's styles: the rules that reproduce its per-element values, with the columns they read.\n * @param values - the canonical values, the declared rules and the graph they belong to\n * @param features - the candidate explaining columns per target (`featuresOf()` of the snapshot)\n * @param options - tool defaults, the budget, the notes collector, the raw columns and a cancel signal\n * @returns the styles, exact for every element\n * @category Styles\n */\nexport function planStyles(values: StyleValues, features: StyleFeatures, options: PlanOptions = {}): ExtractedStyles {\n const notes = options.notes ?? new StyleNotes();\n const budget = options.budget ?? new StyleBudget();\n const defaults =\n options.toolDefaults !== false && values.tool !== undefined && values.tool !== null\n ? toolDefaults(values.tool)\n : null;\n const units = values.units ?? \"px\";\n const rules: StyleRule[] = [];\n const columns = { node: new Map<string, StyleColumn>(), edge: new Map<string, StyleColumn>() };\n const allFeatures = { node: [] as StyleFeature[], edge: [] as StyleFeature[] };\n for (const target of [\"node\", \"edge\"] as const) {\n const given = values[target];\n // a reader's own tool-default rules (Gephi's arrows on directed edges) go with the tool's constants\n const out =\n options.toolDefaults === false && given?.rules !== undefined\n ? { ...given, rules: given.rules.filter((r) => r.origin !== \"tool\") }\n : given;\n allFeatures[target] = [...features[target], ...(out?.features ?? [])];\n const toolSet = defaults === null ? null : toolSetOf(defaults, target, units);\n const plan: TargetPlan = {\n target,\n n: target === \"node\" ? values.fingerprint.nodes : values.fingerprint.edges,\n notes,\n budget,\n spend: (ops) => {\n budget.spend(target, ops);\n },\n columns: columns[target],\n ids: new Set(),\n };\n rules.push(\n ...planTarget(\n plan,\n out,\n allFeatures[target],\n new Set(options.rawColumns?.[target] ?? []),\n toolSet,\n options.signal,\n ),\n );\n }\n const graph = graphStyles(defaults, values.graph ?? {});\n return {\n styles: {\n version: 1,\n source: {\n format: values.format,\n dialect: values.dialect ?? null,\n tool: defaults === null ? null : defaults.tool,\n },\n units: { length: units },\n graph: graph,\n rules,\n notes: notes.list(),\n },\n columns,\n features: allFeatures,\n fingerprint: values.fingerprint,\n };\n}\n\n/**\n * The tool's default values of a target, as one defaults rule sets them; a length in other units than the file's is\n * left out.\n * @param defaults - the tool's defaults\n * @param target - nodes or edges\n * @param units - the file's length units\n * @returns the values, or null when none applies\n */\nfunction toolSetOf(\n defaults: NonNullable<ReturnType<typeof toolDefaults>>,\n target: StyleTarget,\n units: string,\n): Record<string, StyleValue> | null {\n const toolSet: Record<string, StyleValue> = {};\n for (const [p, d] of Object.entries(defaults[target]) as [string, { value: unknown } | undefined][]) {\n const fits = d !== undefined && isStyleValue(target, p, d.value);\n if (fits && !(LENGTHS.has(p) && defaults.units !== units)) {\n toolSet[p] = d.value as StyleValue;\n }\n }\n return Object.keys(toolSet).length === 0 ? null : toolSet;\n}\n\n/**\n * The graph's styles: the tool's defaults, then the file's own values over them.\n * @param defaults - the tool's defaults, or null\n * @param given - the file's graph values\n * @returns the values\n */\nfunction graphStyles(\n defaults: ReturnType<typeof toolDefaults> | null,\n given: Readonly<Record<string, unknown>>,\n): Record<string, StyleValue> {\n const graph: Record<string, StyleValue> = {};\n const own = Object.entries(defaults?.graph ?? {}) as [string, { value: unknown } | undefined][];\n for (const [p, d] of own) {\n if (d !== undefined && isStyleValue(\"graph\", p, d.value)) {\n graph[p] = d.value as StyleValue;\n }\n }\n for (const [p, v] of Object.entries(given)) {\n if (isStyleValue(\"graph\", p, v)) {\n graph[p] = v as StyleValue;\n }\n }\n return graph;\n}\n\n/**\n * A rule id not used yet in this target.\n * @param plan - the target's state\n * @param base - the wanted id\n * @returns the id, suffixed when taken\n */\nfunction uniqueId(plan: TargetPlan, base: string): string {\n let id = base;\n let k = 2;\n while (plan.ids.has(id)) {\n id = `${base}#${String(k)}`;\n k++;\n }\n plan.ids.add(id);\n return id;\n}\n\n/**\n * Sets one property's mapping of a rule, making the rule's mappings on first use.\n * @param rule - the rule, changed in place\n * @param property - the property\n * @param mapping - the mapping\n */\nfunction setMapping(rule: Draft, property: string, mapping: Mapping): void {\n rule.map ??= {};\n rule.map[property] = mapping;\n}\n\n/**\n * The type-checked per-element values of a target: a value of the wrong kind is noted and dropped.\n * @param plan - the target's state\n * @param out - the reader's output\n * @returns the values per property that have at least one value\n */\nfunction checkedTruth(plan: TargetPlan, out: ReaderOutput | undefined): Map<string, (StyleValue | null)[]> {\n const truth = new Map<string, (StyleValue | null)[]>();\n for (const [p, arr] of Object.entries<StyleColumn | undefined>(out?.values ?? {})) {\n if (arr === undefined) {\n continue;\n }\n if (!STYLE_PROPERTIES[plan.target].has(p) && !p.startsWith(\"graphty:\")) {\n plan.notes.add(STYLE_ISSUE.NOT_CARRIED, plan.target, p, { sample: p });\n continue;\n }\n const vals = checkedValues(plan, p, arr);\n plan.spend(plan.n);\n if (vals.some((v) => v !== null)) {\n truth.set(p, vals);\n }\n }\n return truth;\n}\n\n/**\n * One property's values, a value of the wrong kind noted and dropped.\n * @param plan - the target's state\n * @param p - the property\n * @param arr - the reader's values\n * @returns the values, one per element\n */\nfunction checkedValues(plan: TargetPlan, p: string, arr: StyleColumn): (StyleValue | null)[] {\n const vals = new Array<StyleValue | null>(plan.n).fill(null);\n for (let i = 0; i < plan.n && i < arr.length; i++) {\n const v = arr[i] ?? null;\n if (v !== null && isStyleValue(plan.target, p, v)) {\n vals[i] = v;\n } else if (v !== null) {\n plan.notes.add(STYLE_ISSUE.BAD_VALUE, plan.target, p, { sample: v, element: i });\n }\n }\n return vals;\n}\n\n/**\n * A copy of a property record without its undefined entries.\n * @param o - the record\n * @returns the copy, or undefined\n */\nfunction defined<T>(o: Readonly<Record<string, T | undefined>> | undefined): Record<string, T> | undefined {\n if (o === undefined) {\n return undefined;\n }\n const out: Record<string, T> = {};\n for (const [k, v] of Object.entries(o)) {\n if (v !== undefined) {\n out[k] = v;\n }\n }\n return out;\n}\n\n/**\n * The properties a rule writes.\n * @param r - the rule\n * @returns the property names\n */\nfunction writes(r: Draft | StyleRule): string[] {\n return [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})];\n}\n\n/**\n * The declared rules, with every predicate longer than a short one evaluated into a membership style column and\n * runs of rules that set values on every element merged into one defaults rule.\n * @param plan - the target's state\n * @param declared - the reader's rules\n * @param features - the features, for evaluating predicates over data columns\n * @returns the rules to keep\n */\nfunction prepareDeclared(plan: TargetPlan, declared: readonly StyleRule[], features: readonly StyleFeature[]): Draft[] {\n const src = refSource(plan.target, plan.n, plan.columns, features);\n const drafts: Draft[] = [];\n for (const r of declared.filter((x) => x.target === plan.target)) {\n const d: Draft = { ...r, set: defined(r.set), map: defined(r.map) };\n if (d.set === undefined) {\n delete d.set;\n }\n if (d.map === undefined) {\n delete d.map;\n }\n if (!isShortPredicate(r.where)) {\n asMembership(plan, d, r, src);\n }\n drafts.push(d);\n }\n const merged = mergedDefaults(plan.target, drafts);\n for (const d of merged) {\n d.id = uniqueId(plan, d.id);\n }\n return merged;\n}\n\n/**\n * Evaluates a long predicate into a membership style column the rule selects instead.\n * @param plan - the target's state\n * @param d - the rule's draft, changed in place\n * @param r - the declared rule\n * @param src - the reference source\n */\nfunction asMembership(plan: TargetPlan, d: Draft, r: StyleRule, src: ReturnType<typeof refSource>): void {\n let member = 1;\n while (plan.columns.has(`member.${String(member)}`)) {\n member++;\n }\n const key = `member.${String(member)}`;\n const col = new Array<StyleValue | null>(plan.n).fill(null);\n let count = 0;\n for (let i = 0; i < plan.n; i++) {\n if (matches(r.where, src, i)) {\n col[i] = true;\n count++;\n }\n }\n plan.spend(plan.n * 8);\n plan.columns.set(key, col);\n d.where = { has: { style: key } };\n d.facts = { ...r.facts, elements: count, reason: r.facts?.reason ?? \"SELECTOR\" };\n plan.notes.add(STYLE_ISSUE.SELECTOR_AS_COLUMN, plan.target, r.id, { count });\n}\n\n/**\n * Consecutive declared rules that select everything and only set values, as one defaults rule (later wins).\n * @param target - nodes or edges\n * @param drafts - the declared rules\n * @returns the rules, runs merged\n */\nfunction mergedDefaults(target: StyleTarget, drafts: readonly Draft[]): Draft[] {\n const merged: Draft[] = [];\n const plain = (x: Draft): boolean => \"all\" in x.where && x.set !== undefined && x.map === undefined;\n let i = 0;\n while (i < drafts.length) {\n let j = i + 1;\n while (plain(drafts[i]) && j < drafts.length && plain(drafts[j])) {\n j++;\n }\n if (j - i >= 2) {\n merged.push({\n id: drafts[i].id,\n target,\n role: \"defaults\",\n origin: \"declared\",\n where: { all: true },\n set: Object.assign({}, ...drafts.slice(i, j).map((x) => x.set)) as Record<string, StyleValue>,\n });\n } else {\n merged.push(drafts[i]);\n }\n i = j;\n }\n return merged;\n}\n\n/** A passthrough on existing columns that explains a family. */\ninterface PassCandidate {\n readonly type: \"passdata\";\n readonly cols: ReadonlyMap<string, FeatureInfo>;\n readonly raw: boolean;\n readonly cost: number;\n}\n\n/** The floor: classes or a copy. */\ninterface OpaqueCandidate {\n readonly type: \"opaque\";\n readonly cost: number;\n}\n\ntype Candidate = DiscreteCandidate | ContinuousCandidate | PassCandidate | OpaqueCandidate;\nconst ORDER = [\"passdata\", \"discrete\", \"continuous\", \"opaque\"];\n\n/**\n * Tests a passthrough on existing data columns: one column per property whose canonical value equals the style on\n * every element.\n * @param plan - the target's state\n * @param fam - the family\n * @param truth - the values per property\n * @param infos - the features\n * @returns the candidate, or null\n */\nfunction passCandidate(\n plan: TargetPlan,\n fam: Family,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n infos: readonly FeatureInfo[],\n): PassCandidate | null {\n const cols = new Map<string, FeatureInfo>();\n for (const p of fam.props) {\n const canon = canonicalFor(plan.target, p);\n const isColor = STYLE_PROPERTIES[plan.target].get(p) === \"color\";\n const t = truth.get(p) ?? [];\n const hit = infos.find((f) => {\n if (!(\"data\" in f.feature.ref)) {\n return false;\n }\n plan.spend(plan.n);\n for (let i = 0; i < plan.n; i++) {\n const raw = f.feature.values[i];\n // a color column is reused only when it already holds \"#rrggbb\": other spellings read differently\n if (isColor && raw !== null && !(typeof raw === \"string\" && /^#[0-9a-fA-F]{6}$/.test(raw))) {\n return false;\n }\n if ((raw === null ? null : canon(raw)) !== t[i]) {\n return false;\n }\n }\n return true;\n });\n if (hit === undefined) {\n return null;\n }\n cols.set(p, hit);\n }\n const raw = Array.from(cols.values()).some((f) => f.raw);\n // a passthrough on the raw style column itself recovers nothing: nearly as opaque as a copy\n return { type: \"passdata\", cols, raw, cost: raw ? 240 : 50 };\n}\n\n/**\n * Plans one target.\n * @param plan - the target's state\n * @param out - the reader's output\n * @param features - the candidate features\n * @param rawNames - the data columns the values were read from\n * @param toolSet - the tool's default values, or null\n * @param signal - cancels the planning\n * @returns the target's rules, bottom to top\n */\nfunction planTarget(\n plan: TargetPlan,\n out: ReaderOutput | undefined,\n features: readonly StyleFeature[],\n rawNames: ReadonlySet<string>,\n toolSet: Record<string, StyleValue> | null,\n signal: AbortSignal | undefined,\n): StyleRule[] {\n const { target, n } = plan;\n for (const [k, v] of out?.columns ?? []) {\n plan.columns.set(k, v);\n }\n const truth = checkedTruth(plan, out);\n const toolRule: Draft[] =\n toolSet === null\n ? []\n : [\n {\n id: uniqueId(plan, `${target}.tool`),\n target,\n role: \"defaults\",\n origin: \"tool\",\n where: { all: true },\n set: toolSet,\n },\n ];\n const declared = prepareDeclared(plan, out?.rules ?? [], features);\n const declaredProps = new Set(declared.flatMap(writes));\n\n const { defaults, rest } = splitDefaults(n, truth, declaredProps);\n plan.spend(n * truth.size);\n const inferred: Draft[] = [];\n if (Object.keys(defaults).length > 0) {\n inferred.push({\n id: uniqueId(plan, `${target}.defaults`),\n target,\n role: \"defaults\",\n origin: \"inferred\",\n where: { all: true },\n set: defaults,\n });\n }\n\n const families = familiesOf(rest);\n plan.spend(n * rest.length);\n const infos = features\n .map((f) => describeFeature(f, \"data\" in f.ref && rawNames.has(f.ref.data)))\n .sort((a, b) => a.distinct - b.distinct);\n plan.spend(n * features.length);\n const testable = infos.filter((f) => f.categorical || f.numeric).slice(0, MAX_FEATURES);\n\n const groups: Draft[] = [];\n const mappings = new Map<string, Draft>();\n const passData: Draft = {\n id: `${target}.passthrough`,\n target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n };\n const passRaw: Draft = {\n id: `${target}.passthrough.raw`,\n target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n facts: { reason: \"NO_EXPLANATION\" },\n };\n const copy: Draft = {\n id: `${target}.copy`,\n target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n facts: { reason: \"NO_EXPLANATION\" },\n };\n const opaque: { fam: Family; raw: ReadonlyMap<string, FeatureInfo> | null }[] = [];\n const tolerated = new Map<string, Set<number>>();\n let budgetHit = 0;\n\n const st: Inference = { groups, mappings, passData, passRaw, copy, opaque, tolerated };\n for (const fam of families) {\n signal?.throwIfAborted();\n if (plan.budget.exhausted(target)) {\n budgetHit++;\n opaque.push({ fam, raw: null });\n continue;\n }\n applyChoice(plan, st, fam, chooseCandidate(plan, fam, testable, infos, truth), truth);\n }\n if (budgetHit > 0) {\n plan.notes.add(STYLE_ISSUE.BUDGET, target, null, { count: budgetHit });\n }\n poolOpaque(plan, st, budgetHit, truth);\n\n const nonEmpty = (r: Draft): boolean => Object.keys(r.map ?? {}).length > 0;\n const sortedMappings = Array.from(mappings.values()).sort((a, b) => compareText(a.id, b.id));\n const drafts: Draft[] = [\n ...toolRule,\n ...declared,\n ...inferred,\n ...groups,\n ...sortedMappings,\n ...[passData, passRaw, copy].filter(nonEmpty),\n ];\n for (const d of drafts.slice(toolRule.length + declared.length + inferred.length)) {\n d.id = uniqueId(plan, d.id);\n }\n\n const src = refSource(target, n, plan.columns, features);\n enforceCap(plan, drafts, truth, src);\n const exceptions = replay(plan, drafts, truth, toolSet, tolerated, src);\n if (exceptions !== null) {\n drafts.push(exceptions);\n }\n return drafts.map(finish);\n}\n\n/**\n * The inferred defaults: each property non-null and equal on every element; the others are left to explain. A\n * property a declared rule writes is the declared rule's.\n * @param n - the element count\n * @param truth - the values per property\n * @param declaredProps - the properties the declared rules write\n * @returns the defaults, and the properties left\n */\nfunction splitDefaults(\n n: number,\n truth: ReadonlyMap<string, (StyleValue | null)[]>,\n declaredProps: ReadonlySet<string>,\n): { defaults: Record<string, StyleValue>; rest: [string, (StyleValue | null)[]][] } {\n const defaults: Record<string, StyleValue> = {};\n const rest: [string, (StyleValue | null)[]][] = [];\n for (const [p, a] of truth) {\n const first = a[0];\n if (declaredProps.has(p)) {\n continue;\n }\n if (n > 0 && first !== null && a.every((v) => v === first)) {\n defaults[p] = first;\n } else {\n rest.push([p, a]);\n }\n }\n return { defaults, rest };\n}\n\n/** What the inference of one target collects. */\ninterface Inference {\n readonly groups: Draft[];\n readonly mappings: Map<string, Draft>;\n readonly passData: Draft;\n readonly passRaw: Draft;\n readonly copy: Draft;\n readonly opaque: { fam: Family; raw: ReadonlyMap<string, FeatureInfo> | null }[];\n readonly tolerated: Map<string, Set<number>>;\n}\n\n/**\n * The cheapest explanation of one family: a discrete or continuous mapping over a feature, a passthrough over existing\n * columns, or the opaque floor.\n * @param plan - the target's state\n * @param fam - the family\n * @param testable - the features worth testing\n * @param infos - every feature\n * @param truth - the values per property\n * @returns the chosen candidate\n */\nfunction chooseCandidate(\n plan: TargetPlan,\n fam: Family,\n testable: readonly FeatureInfo[],\n infos: readonly FeatureInfo[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): Candidate {\n const { target, n } = plan;\n const cands: Candidate[] = [];\n // text is per element by nature: a label is never explained by another column's table\n const textual = fam.props.some((p) => STYLE_PROPERTIES[target].get(p) === \"text\");\n if (!textual) {\n for (const f of testable) {\n const d = discreteCandidate(fam, f, n, plan.spend);\n if (d !== null) {\n cands.push(d);\n }\n const c = continuousCandidate(fam, f, truth, plan.spend);\n if (c !== null) {\n cands.push(c);\n }\n if (plan.budget.exhausted(target)) {\n break;\n }\n }\n }\n const pass = passCandidate(plan, fam, truth, infos);\n if (pass !== null) {\n cands.push(pass);\n }\n cands.push({ type: \"opaque\", cost: 250 });\n cands.sort((a, b) => a.cost - b.cost || ORDER.indexOf(a.type) - ORDER.indexOf(b.type));\n return cands[0];\n}\n\n/**\n * Records a family's chosen explanation in the target's inference.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param fam - the family\n * @param c - the chosen candidate\n * @param truth - the values per property\n */\nfunction applyChoice(\n plan: TargetPlan,\n st: Inference,\n fam: Family,\n c: Candidate,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n if (c.type === \"discrete\") {\n applyDiscrete(plan, st, fam, c, truth);\n } else if (c.type === \"continuous\") {\n applyContinuous(plan, st, fam, c, truth);\n } else if (c.type === \"passdata\" && !c.raw) {\n for (const p of fam.props) {\n setMapping(st.passData, p, { kind: \"passthrough\", by: (c.cols.get(p) as FeatureInfo).feature.ref });\n }\n } else {\n // the raw style column recovers nothing: the family joins the opaque pool, where it may become part\n // of a style class, and otherwise reads the raw column\n st.opaque.push({ fam, raw: c.type === \"passdata\" ? c.cols : null });\n }\n}\n\n/**\n * The mapping rule of a feature, made on first use; one rule holds every family the feature explains.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param key - the rule's key among the mappings\n * @param id - its id\n * @returns the rule\n */\nfunction mappingRule(plan: TargetPlan, st: Inference, key: string, id: string): Draft {\n let r = st.mappings.get(key);\n if (r === undefined) {\n r = { id, target: plan.target, role: \"mapping\", origin: \"inferred\", where: { all: true }, map: {} };\n st.mappings.set(key, r);\n }\n return r;\n}\n\n/**\n * Makes a feature computed for the inference (a style column) a column of the styles.\n * @param plan - the target's state\n * @param info - the feature\n */\nfunction materialize(plan: TargetPlan, info: FeatureInfo): void {\n if (\"style\" in info.feature.ref) {\n plan.columns.set(info.feature.ref.style, info.feature.values);\n }\n}\n\n/**\n * Records a discrete mapping: one table per property, and a group for the elements the feature gives no value.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param fam - the family\n * @param c - the candidate\n * @param truth - the values per property\n */\nfunction applyDiscrete(\n plan: TargetPlan,\n st: Inference,\n fam: Family,\n c: DiscreteCandidate,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n const { target } = plan;\n materialize(plan, c.info);\n const rule = mappingRule(plan, st, `discrete|${c.info.name}`, `${target}.by.${c.info.name}`);\n // the first element of each block stands for the block\n const rep = new Map<number, number>();\n for (const i of fam.styled) {\n if (!rep.has(fam.blocks[i])) {\n rep.set(fam.blocks[i], i);\n }\n }\n for (const p of fam.props) {\n const t = truth.get(p) ?? [];\n const table = Array.from(c.table.values(), ({ raw, block }): [string | number | boolean, StyleValue] => [\n raw,\n t[rep.get(block) ?? -1] as StyleValue,\n ]);\n setMapping(rule, p, { kind: \"discrete\", by: c.info.feature.ref, table });\n }\n if (c.bucket === null) {\n return;\n }\n const set: Record<string, StyleValue> = {};\n for (const p of fam.props) {\n set[p] = (truth.get(p) ?? [])[rep.get(c.bucket) ?? -1] as StyleValue;\n }\n st.groups.push({\n id: `${target}.missing.${c.info.name}`,\n target,\n role: \"group\",\n origin: \"inferred\",\n where: { not: { has: c.info.feature.ref } },\n set,\n });\n}\n\n/**\n * Records a continuous mapping: one ramp per property; a ramp that matches only within the tool's rounding tolerates\n * those elements, noted.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param fam - the family\n * @param c - the candidate\n * @param truth - the values per property\n */\nfunction applyContinuous(\n plan: TargetPlan,\n st: Inference,\n fam: Family,\n c: ContinuousCandidate,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n const { target } = plan;\n materialize(plan, c.info);\n const rule = mappingRule(plan, st, `continuous|${c.info.name}`, `${target}.ramp.${c.info.name}`);\n for (const p of fam.props) {\n const points = c.points.get(p) ?? [];\n setMapping(rule, p, { kind: \"continuous\", by: c.info.feature.ref, points });\n if (!c.tolerant) {\n continue;\n }\n const t = truth.get(p) ?? [];\n const set = new Set<number>();\n for (const i of fam.styled) {\n if (evalContinuous(points, numberOf(c.info.feature.values[i])) !== t[i]) {\n set.add(i);\n plan.notes.add(STYLE_ISSUE.RAMP_ROUNDED, target, p, { element: i, sample: t[i] });\n }\n }\n st.tolerated.set(p, set);\n }\n}\n\n/**\n * The opaque pool: style classes when the file uses few combinations, else one copy per property.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param budgetHit - how many families the budget sent to the pool\n * @param truth - the values per property\n */\nfunction poolOpaque(\n plan: TargetPlan,\n st: Inference,\n budgetHit: number,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n const { target, n } = plan;\n if (st.opaque.length === 0) {\n return;\n }\n const props = st.opaque.flatMap((o) => o.fam.props);\n const classes = budgetHit > 0 ? null : styleClasses(target, props, truth, n, plan.spend);\n const classed = new Set(classes?.classed ?? []);\n if (classes !== null) {\n addClassRules(plan, st, classes);\n }\n let distinct = 0;\n for (const { fam, raw } of st.opaque) {\n for (const p of fam.props.filter((x) => !classed.has(x))) {\n const viaRaw = raw?.get(p);\n if (viaRaw === undefined) {\n distinct = Math.max(distinct, copyProperty(plan, st.copy, p, truth.get(p) ?? []));\n } else {\n setMapping(st.passRaw, p, { kind: \"passthrough\", by: viaRaw.feature.ref });\n }\n }\n }\n st.copy.facts = { reason: budgetHit > 0 ? \"BUDGET\" : \"NO_EXPLANATION\", distinctValues: distinct };\n}\n\n/**\n * Adds the style classes' column and rules.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param classes - the style classes\n */\nfunction addClassRules(plan: TargetPlan, st: Inference, classes: NonNullable<ReturnType<typeof styleClasses>>): void {\n plan.columns.set(CLASS_COLUMN, classes.column);\n for (const r of classes.rules) {\n if (r.role === \"group\") {\n st.groups.push({ ...r, id: r.id, set: { ...r.set } } as Draft);\n } else {\n st.mappings.set(r.id, { ...r, map: { ...r.map } } as Draft);\n }\n }\n}\n\n/**\n * Copies a property's values into a style column the copy rule passes through.\n * @param plan - the target's state\n * @param copy - the copy rule, changed in place\n * @param p - the property\n * @param t - its values\n * @returns how many distinct values it holds\n */\nfunction copyProperty(plan: TargetPlan, copy: Draft, p: string, t: readonly (StyleValue | null)[]): number {\n plan.columns.set(`copy.${p}`, t.slice());\n setMapping(copy, p, { kind: \"passthrough\", by: { style: `copy.${p}` } });\n plan.spend(plan.n);\n return new Set(t.filter((v) => v !== null)).size;\n}\n\n/**\n * The rule as a plain JSON-stable object.\n * @param d - the draft\n * @returns the rule\n */\nfunction finish(d: Draft): StyleRule {\n const r: Record<string, unknown> = { id: d.id, target: d.target, role: d.role, origin: d.origin, where: d.where };\n if (d.set !== undefined && Object.keys(d.set).length > 0) {\n r.set = d.set;\n }\n if (d.map !== undefined && Object.keys(d.map).length > 0) {\n r.map = d.map;\n }\n if (d.facts !== undefined) {\n r.facts = Object.fromEntries(Object.entries(d.facts).filter(([, v]) => v !== undefined));\n }\n if (d.ext !== undefined) {\n r.ext = d.ext;\n }\n return r as unknown as StyleRule;\n}\n\n/**\n * Compares two texts by code unit, the same everywhere.\n * @param a - one text\n * @param b - the other\n * @returns negative, zero or positive\n */\nfunction compareText(a: string, b: string): number {\n if (a === b) {\n return 0;\n }\n return a < b ? -1 : 1;\n}\n\n/**\n * The entries a person would edit in a rule.\n * @param r - the rule\n * @returns its size\n */\nfunction ruleSize(r: Draft): number {\n let size = Object.keys(r.set ?? {}).length;\n for (const m of Object.values(r.map ?? {})) {\n if (m.kind === \"discrete\") {\n size += m.table.length;\n } else if (m.kind === \"continuous\") {\n size += m.points.length;\n } else {\n size += 1;\n }\n }\n return size;\n}\n\n/** The order in which rules are folded into the copy: inferred first, the tool's defaults last. */\nconst FOLD_ORDER: Readonly<Record<string, number>> = { inferred: 0, declared: 1, tool: 2 };\n\n/**\n * Keeps at most 15 rules (the exceptions rule makes 16) by moving the least readable rules into the copy, with each\n * property's values as they resolved: exact, never a silent delete.\n * @param plan - the target's state\n * @param drafts - the rules, bottom to top; changed in place\n * @param truth - the file's values per property\n * @param src - the reference source\n */\nfunction enforceCap(\n plan: TargetPlan,\n drafts: Draft[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n src: ReturnType<typeof refSource>,\n): void {\n const cap = MAX_STYLE_RULES - 1;\n const copyId = `${plan.target}.copy`;\n let folded = 0;\n while (drafts.length > cap) {\n const cands = drafts.filter((r) => r.id !== copyId);\n if (cands.length === 0) {\n break;\n }\n cands.sort((a, b) => {\n const pa = a.role === \"passthrough\" ? 1 : 0;\n const pb = b.role === \"passthrough\" ? 1 : 0;\n return (\n pa - pb ||\n (FOLD_ORDER[a.origin] ?? 1) - (FOLD_ORDER[b.origin] ?? 1) ||\n ruleSize(b) - ruleSize(a) ||\n drafts.indexOf(b) - drafts.indexOf(a)\n );\n });\n const victim = cands[0];\n const before = drafts.map(finish);\n drafts.splice(drafts.indexOf(victim), 1);\n let copy = drafts.find((r) => r.id === copyId);\n if (copy === undefined) {\n copy = {\n id: copyId,\n target: plan.target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n };\n plan.ids.add(copyId);\n } else {\n drafts.splice(drafts.indexOf(copy), 1);\n }\n for (const p of new Set(writes(victim))) {\n // the property's values as the whole stack resolved them, supplied on top for every element\n const t = truth.get(p);\n const vals = t === undefined ? resolveRules(before, plan.target, p, src, plan.budget) : t.slice();\n plan.columns.set(`copy.${p}`, vals);\n setMapping(copy, p, { kind: \"passthrough\", by: { style: `copy.${p}` } });\n }\n copy.facts = { ...copy.facts, reason: \"LAYER_CAP\" };\n drafts.push(copy);\n folded++;\n }\n if (folded > 0) {\n plan.notes.add(STYLE_ISSUE.LAYER_CAP, plan.target, null, { count: folded });\n }\n}\n\n/**\n * The elements whose resolved value is not the one wanted, with the wanted value; none where nothing is wanted, and\n * none where a ramp is tolerated within the tool's rounding.\n * @param n - the element count\n * @param got - the resolved values\n * @param want - the value wanted for an element, or null for none\n * @param tolerated - the elements a ramp matches only within the tool's rounding\n * @returns the wanted values where they differ, or null when none does\n */\nfunction differences(\n n: number,\n got: readonly (StyleValue | null)[],\n want: (i: number) => StyleValue | null,\n tolerated: ReadonlySet<number> | undefined,\n): (StyleValue | null)[] | null {\n let col: (StyleValue | null)[] | null = null;\n for (let i = 0; i < n; i++) {\n const w = want(i);\n const differs = w !== null && got[i] !== w && !(tolerated?.has(i) === true && within(got[i], w));\n if (differs) {\n col ??= new Array<StyleValue | null>(n).fill(null);\n col[i] = w;\n }\n }\n return col;\n}\n\n/**\n * The replay: resolves every property the file gives and compares it with the file's value, or the tool's default\n * where the file gives none. Each difference goes into one sparse exceptions column per property.\n * @param plan - the target's state\n * @param drafts - the rules, bottom to top\n * @param truth - the file's values per property\n * @param toolSet - the tool's default values, or null\n * @param tolerated - per property, the elements a ramp matches only within the tool's rounding\n * @param src - the reference source\n * @returns the exceptions rule, or null when nothing differs\n */\nfunction replay(\n plan: TargetPlan,\n drafts: readonly Draft[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n toolSet: Record<string, StyleValue> | null,\n tolerated: ReadonlyMap<string, ReadonlySet<number>>,\n src: ReturnType<typeof refSource>,\n): Draft | null {\n const rules = drafts.map(finish);\n // where the file gives no value, the tool draws its default: its constants, and where a reader adds tool rules\n // of its own (Graphviz's target arrow on directed edges), what those rules give over the constants\n const toolRules = rules.filter((r) => r.origin === \"tool\");\n const ownToolRules = toolRules.length > (toolSet === null ? 0 : 1);\n const map: Record<string, Mapping> = {};\n for (const [p, t] of truth) {\n const got = resolveRules(rules, plan.target, p, src, plan.budget);\n const perElement = ownToolRules ? resolveRules(toolRules, plan.target, p, src, plan.budget) : null;\n const constant = toolSet?.[p] ?? null;\n const want = (i: number): StyleValue | null => t[i] ?? (perElement === null ? constant : perElement[i]);\n const col = differences(plan.n, got, want, tolerated.get(p));\n if (col !== null) {\n plan.columns.set(`exceptions.${p}`, col);\n map[p] = { kind: \"passthrough\", by: { style: `exceptions.${p}` } };\n }\n }\n if (Object.keys(map).length === 0) {\n return null;\n }\n return {\n id: uniqueId(plan, `${plan.target}.exceptions`),\n target: plan.target,\n role: \"exceptions\",\n origin: \"inferred\",\n where: { all: true },\n map,\n };\n}\n","/**\n * Reading a file's styles after an import: the importer's own `styles()` (the simple path, canonicalized and planned\n * here, or the advanced path), the generic reader of the style roles (`color`, `size`, `shape`, `thickness`,\n * `hidden`) for an importer without one, and the `graphty.styles` block when a file graphty wrote carries it as a\n * graph attribute.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { keptForStyles } from \"../../common/report.js\";\nimport type { GraphImporter, ImportReport } from \"../../types.js\";\nimport { StyleBudget } from \"../budget.js\";\nimport { canonColor, colorOpacity } from \"../canon/color.js\";\nimport { canonEnum, type StyleEnumKind } from \"../canon/enums.js\";\nimport { canonBoolean, canonNumber, canonOpacity, DOT_POINTS_PER_INCH, styleLengthUnit } from \"../canon/number.js\";\nimport type { CanonSite } from \"../canon/site.js\";\nimport { canonText } from \"../canon/text.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport { StyleNotes } from \"../notes.js\";\nimport { featuresOf, styleFingerprint } from \"../plan/features.js\";\nimport { planStyles } from \"../plan/plan.js\";\nimport { plainCell } from \"../plan/resolve.js\";\nimport type {\n ExtractedStyles,\n GraphStyle,\n ImporterStyles,\n ReaderOutput,\n StyleColumn,\n StyleDialect,\n StyleNote,\n StyleProperty,\n StyleTarget,\n StyleTool,\n StyleValue,\n} from \"../types.js\";\nimport { STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { blockStyles, parseStyleBlock, STYLE_BLOCK_NAME } from \"./block.js\";\n\n/**\n * The `styles` option of `importGraph()` given as an object.\n * @category Styles\n */\nexport interface StyleImportOptions {\n /**\n * Whether a property the file leaves to its writing program's default gets that program's default (Cytoscape's,\n * Graphviz's, Gephi's ...), so the graph looks as it does there. Defaults to true.\n */\n readonly toolDefaults?: boolean;\n}\n\n/**\n * Options of `extractStyles()`.\n * @category Styles\n */\nexport interface ExtractStylesOptions extends StyleImportOptions {\n /** Cancels the extraction. */\n readonly signal?: AbortSignal | null;\n /**\n * The counted work budget to spend (and read back after: `budget.used(\"node\")`); a new one of\n * `STYLE_WORK_BUDGET` operations per target when absent.\n * @internal\n */\n readonly budget?: StyleBudget;\n}\n\nconst TARGETS: readonly StyleTarget[] = [\"node\", \"edge\"];\nconst ENUM_KINDS: ReadonlySet<string> = new Set([\"shape\", \"borderStyle\", \"lineStyle\", \"arrow\", \"weight\", \"position\"]);\n\n/** What the readers here produce before planning: canonical values and the data columns they came from. */\ninterface StyleTruth {\n readonly dialect: StyleDialect | null;\n readonly tool: StyleTool | null;\n readonly units: \"px\" | \"relative\";\n readonly graph: GraphStyle;\n readonly node: ReaderOutput;\n readonly edge: ReaderOutput;\n readonly raw: { readonly node: readonly string[]; readonly edge: readonly string[] };\n readonly notes: readonly StyleNote[];\n /** A `graphty.styles` block the importer found outside the graph attributes, or null. */\n readonly block?: string | null;\n /** Whether the format writes an opacity as its color's alpha (see `ImporterStyles`). */\n readonly opacityInColor?: boolean;\n}\n\n/**\n * Reads the styles of a file after its import: the reading importer's own `styles()` (with what its `import()` kept\n * for it), or the columns whose role is a style role when it has none; a `graphty.styles` block carried as a graph\n * attribute gives the rules, with the importer's values as the truth. Called by `importGraph()` when styles are\n * requested; a caller that drives an importer itself (into its own builder) calls it with the report `import()`\n * returned.\n * @param importer - the importer that read the file\n * @param snapshot - the graph it built\n * @param report - the report its `import()` returned\n * @param options - tool defaults and a cancel signal\n * @returns the styles, or null when the file has none\n * @category Styles\n */\nexport function extractStyles(\n importer: GraphImporter,\n snapshot: GraphSnapshot,\n report: ImportReport,\n options: ExtractStylesOptions = {},\n): ExtractedStyles | null {\n const signal = options.signal ?? undefined;\n const notes = new StyleNotes();\n const budget = options.budget ?? new StyleBudget();\n const canonical = readStyleValues(importer, snapshot, report, { notes, budget, signal });\n const fingerprint = styleFingerprint(snapshot);\n const blockText = canonical?.block ?? graphValue(snapshot, STYLE_BLOCK_NAME);\n if (blockText !== undefined) {\n const parsed = parseStyleBlock(blockText, fingerprint);\n if (parsed.ok) {\n const truth = canonical === null ? {} : { node: canonical.node.values, edge: canonical.edge.values };\n const fromBlock = blockStyles(\n parsed.block,\n snapshot,\n importer.format,\n truth,\n canonical?.notes ?? [],\n canonical?.tool ?? null,\n canonical?.opacityInColor === true,\n );\n if (fromBlock !== null) {\n return fromBlock;\n }\n notes.add(STYLE_ISSUE.BLOCK_IGNORED, null, null, { sample: \"INVALID\" });\n } else {\n notes.add(STYLE_ISSUE.BLOCK_IGNORED, null, null, { sample: parsed.reason });\n }\n }\n if (canonical === null) {\n const list = notes.list();\n return list.length === 0 ? null : emptyStyles(importer.format, list, snapshot, fingerprint);\n }\n const raw = { node: new Set(canonical.raw.node), edge: new Set(canonical.raw.edge) };\n const features = {\n node: featuresOf(snapshot, \"node\").filter((f) => !(\"data\" in f.ref && raw.node.has(f.ref.data))),\n edge: featuresOf(snapshot, \"edge\").filter((f) => !(\"data\" in f.ref && raw.edge.has(f.ref.data))),\n };\n const planned = planStyles(\n {\n format: importer.format,\n dialect: canonical.dialect,\n tool: canonical.tool,\n units: canonical.units,\n graph: canonical.graph,\n node: canonical.node,\n edge: canonical.edge,\n fingerprint,\n },\n features,\n {\n toolDefaults: options.toolDefaults,\n budget,\n notes,\n rawColumns: { node: canonical.raw.node, edge: canonical.raw.edge },\n signal,\n },\n );\n if (canonical.notes.length === 0) {\n return planned;\n }\n return { ...planned, styles: { ...planned.styles, notes: [...canonical.notes, ...planned.styles.notes] } };\n}\n\n/**\n * What a file's styles are before planning: each element's canonical value per property, as the importer's own\n * `styles()` gives them (the simple path canonicalized) or, for an importer without one, as the generic reader reads\n * the columns with a style role. The truth the planned rules must reproduce; not part of the published entry.\n * @param importer - the importer that read the file\n * @param snapshot - the graph it built\n * @param report - the report its `import()` returned\n * @param context - where problems are noted, the work budget and a cancel signal\n * @param context.notes - where problems are noted\n * @param context.budget - the work budget\n * @param context.signal - cancels the work\n * @returns the canonical values, or null when the file has no styles\n */\nexport function readStyleValues(\n importer: GraphImporter,\n snapshot: GraphSnapshot,\n report: ImportReport,\n context: { readonly notes: StyleNotes; readonly budget: StyleBudget; readonly signal?: AbortSignal | undefined },\n): StyleTruth | null {\n const { notes, budget, signal } = context;\n signal?.throwIfAborted();\n let canonical: StyleTruth | null;\n if (importer.styles === undefined) {\n canonical = roleStyles(snapshot, importer.format, notes, budget);\n } else {\n const got = importer.styles(snapshot, { signal, budget, kept: keptForStyles(report) });\n canonical = got === null ? null : canonicalOf(got, snapshot, notes, budget, signal);\n }\n signal?.throwIfAborted();\n return canonical === null ? null : withPairedHalves(canonical, snapshot);\n}\n\n/**\n * The values with the second half of each undirected edge of a directed graph given its first half's value: the file\n * holds the edge once, its program draws it once, and the import read the element's values onto the first half.\n * @param truth - the values read\n * @param snapshot - the graph\n * @returns the values\n */\nfunction withPairedHalves(truth: StyleTruth, snapshot: GraphSnapshot): StyleTruth {\n const pair = snapshot.edges.byRole(\"pair\");\n if (pair === null) {\n return truth;\n }\n const values: Partial<Record<StyleProperty, StyleColumn>> = {};\n for (const [property, col] of Object.entries(truth.edge.values) as [StyleProperty, StyleColumn | undefined][]) {\n if (col === undefined) {\n continue;\n }\n const out = [...col];\n for (let e = 0; e < out.length; e++) {\n const first = pair.isSet(e) ? (pair.value(e) as number) : e;\n if (first < e) {\n out[e] = col[first] ?? null;\n }\n }\n values[property] = out;\n }\n return { ...truth, edge: { ...truth.edge, values } };\n}\n\n/**\n * A graph attribute's value, or undefined.\n * @param snapshot - the graph\n * @param name - the attribute\n * @returns its value\n */\nfunction graphValue(snapshot: GraphSnapshot, name: string): unknown {\n return snapshot.graph.has(name) ? plainCell(snapshot.graph.value(name, 0)) : undefined;\n}\n\n/**\n * Styles holding nothing but notes.\n * @param format - the format\n * @param notes - the notes\n * @param snapshot - the graph\n * @param fingerprint - its fingerprint\n * @returns the styles\n */\nfunction emptyStyles(\n format: string,\n notes: readonly StyleNote[],\n snapshot: GraphSnapshot,\n fingerprint: ExtractedStyles[\"fingerprint\"],\n): ExtractedStyles {\n return {\n styles: {\n version: 1,\n source: { format, dialect: null, tool: null },\n units: { length: \"px\" },\n graph: {},\n rules: [],\n notes,\n },\n columns: { node: new Map(), edge: new Map() },\n features: { node: featuresOf(snapshot, \"node\"), edge: featuresOf(snapshot, \"edge\") },\n fingerprint,\n };\n}\n\n/**\n * An importer's styles as canonical values: the advanced path as it is, the simple path read and canonicalized.\n * @param got - what the importer's `styles()` returned\n * @param snapshot - the graph\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @param signal - cancels the work\n * @returns the canonical values\n */\nfunction canonicalOf(\n got: ImporterStyles,\n snapshot: GraphSnapshot,\n notes: StyleNotes,\n budget: StyleBudget,\n signal: AbortSignal | undefined,\n): StyleTruth {\n if (\"canonical\" in got) {\n return {\n dialect: got.dialect ?? null,\n tool: got.tool ?? null,\n units: got.units ?? \"px\",\n graph: got.graph ?? {},\n node: got.node ?? { values: {} },\n edge: got.edge ?? { values: {} },\n raw: { node: got.readFrom?.node ?? [], edge: got.readFrom?.edge ?? [] },\n notes: got.notes ?? [],\n block: got.block ?? null,\n opacityInColor: got.opacityInColor === true,\n };\n }\n const { dialect } = got;\n const raw = { node: [] as string[], edge: [] as string[] };\n const out = { node: { values: {} } as ReaderOutput, edge: { values: {} } as ReaderOutput };\n for (const target of TARGETS) {\n const given = got[target];\n if (given === undefined) {\n continue;\n }\n const columns = new Map<string, readonly unknown[]>();\n for (const [property, source] of Object.entries(given)) {\n signal?.throwIfAborted();\n const values = rawValues(snapshot, target, property, source, notes, raw[target]);\n if (values !== null) {\n columns.set(property, values);\n }\n }\n out[target] = { values: canonicalize(target, columns, dialect, count(snapshot, target), notes, budget) };\n }\n return {\n dialect,\n tool: null,\n units: styleLengthUnit(dialect),\n graph: {},\n node: out.node,\n edge: out.edge,\n raw,\n notes: [],\n };\n}\n\n/**\n * The element count of a target.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @returns the count\n */\nfunction count(snapshot: GraphSnapshot, target: StyleTarget): number {\n return target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n}\n\n/**\n * The raw values of one property on the simple path: a snapshot column by name, or an array by element index.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @param property - the property\n * @param source - `{ data: \"<column>\" }` or an array\n * @param notes - where a missing column is noted\n * @param raw - collects the names of the columns read\n * @returns the values, or null\n */\nfunction rawValues(\n snapshot: GraphSnapshot,\n target: StyleTarget,\n property: string,\n source: unknown,\n notes: StyleNotes,\n raw: string[],\n): readonly unknown[] | null {\n if (Array.isArray(source)) {\n return source as unknown[];\n }\n if (source === null || typeof source !== \"object\" || typeof (source as { data?: unknown }).data !== \"string\") {\n notes.add(STYLE_ISSUE.BAD_MAPPING, target, property, { sample: source });\n return null;\n }\n const name = (source as { data: string }).data;\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n if (!table.has(name)) {\n notes.add(STYLE_ISSUE.MAPPING_COLUMN_MISSING, target, property, { sample: name });\n return null;\n }\n raw.push(name);\n const n = count(snapshot, target);\n const out = new Array<unknown>(n);\n for (let i = 0; i < n; i++) {\n out[i] = plainCell(table.value(name, i));\n }\n return out;\n}\n\n/**\n * Canonical values of every property of one target. A list value is read as its first item. A color's alpha moves\n * into the fill's or the edge's opacity (multiplied with an opacity the file also states) or is dropped with a note.\n * @param target - nodes or edges\n * @param columns - the raw values per property\n * @param dialect - how they are spelled\n * @param n - the element count\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @returns the canonical values per property\n */\nfunction canonicalize(\n target: StyleTarget,\n columns: ReadonlyMap<string, readonly unknown[]>,\n dialect: StyleDialect,\n n: number,\n notes: StyleNotes,\n budget: StyleBudget,\n): Record<string, StyleColumn> {\n const cx: CanonContext = { target, dialect, n, notes, budget };\n // keyed by the importer's property names: no prototype, so `__proto__` is a property like any other\n const out: Record<string, (StyleValue | null)[]> = Object.create(null) as Record<string, (StyleValue | null)[]>;\n const alphas = new Map<string, (number | null)[]>();\n for (const [property, raws] of columns) {\n const { col, alpha } = canonicalColumn(cx, property, raws);\n out[property] = col;\n if (alpha !== null) {\n alphas.set(property, alpha);\n }\n }\n for (const [property, alpha] of alphas) {\n moveAlpha(cx, out, property, alpha);\n }\n return out;\n}\n\n/** What canonicalize() reads one target's values with. */\ninterface CanonContext {\n readonly target: StyleTarget;\n readonly dialect: StyleDialect;\n /** The element count. */\n readonly n: number;\n readonly notes: StyleNotes;\n readonly budget: StyleBudget;\n}\n\n/**\n * Canonical values of one property; a color's alpha below 1 is kept apart.\n * @param cx - the target being read\n * @param property - the property\n * @param raws - its raw values\n * @returns the values, and the alphas (null when every color is opaque)\n */\nfunction canonicalColumn(\n cx: CanonContext,\n property: string,\n raws: readonly unknown[],\n): { col: (StyleValue | null)[]; alpha: (number | null)[] | null } {\n const { target, dialect, n, notes, budget } = cx;\n const kind = STYLE_PROPERTIES[target].get(property);\n const col = new Array<StyleValue | null>(n).fill(null);\n let alpha: (number | null)[] | null = null;\n for (let i = 0; i < n && i < raws.length; i++) {\n const site: CanonSite = { notes, target, property, element: i, budget };\n const v = firstItem(raws[i], site);\n if (v === null || v === undefined) {\n continue;\n }\n if (kind !== \"color\") {\n col[i] = canonValue(kind, property, v, dialect, site);\n continue;\n }\n const c = canonColor(v, dialect, site, { use: colorUse(target, property) });\n col[i] = c?.color ?? null;\n if (c !== null && c.alpha < 1) {\n alpha ??= new Array<number | null>(n).fill(null);\n alpha[i] = c.alpha;\n }\n }\n return { col, alpha };\n}\n\n/**\n * A raw value, a list read as its first item (a longer list noted).\n * @param v - the raw value\n * @param site - where it was read\n * @returns the value\n */\nfunction firstItem(v: unknown, site: CanonSite): unknown {\n if (!Array.isArray(v)) {\n return v;\n }\n if (v.length > 1) {\n site.notes.add(STYLE_ISSUE.BAD_VALUE, site.target, site.property, { sample: v, element: site.element });\n }\n return v.length === 0 ? null : v[0];\n}\n\n/**\n * Moves a color property's alphas into its opacity (multiplied with an opacity the file also states), or drops them\n * with a note where the property has none.\n * @param cx - the target being read\n * @param out - the canonical values, changed in place\n * @param property - the color property\n * @param alpha - its alphas\n */\nfunction moveAlpha(\n cx: CanonContext,\n out: Record<string, (StyleValue | null)[]>,\n property: string,\n alpha: readonly (number | null)[],\n): void {\n const { target, n, notes, budget } = cx;\n const carrier = OPACITY_OF.get(`${target}.${property}`) ?? null;\n let opacity: (StyleValue | null)[] | null = null;\n if (carrier !== null) {\n out[carrier] ??= new Array<StyleValue | null>(n).fill(null);\n opacity = out[carrier];\n }\n for (let i = 0; i < n; i++) {\n const a = alpha[i];\n if (a === null) {\n continue;\n }\n const site: CanonSite = { notes, target, property, element: i, budget };\n const stated = opacity === null ? null : (opacity[i] as number | null);\n const merged = colorOpacity(\n { color: out[property][i] as `#${string}`, alpha: a },\n stated,\n site,\n opacity !== null,\n );\n if (opacity !== null) {\n opacity[i] = merged;\n }\n }\n}\n\n/** The opacity property that carries a color's alpha: a node's fill and an edge's line. */\nconst OPACITY_OF: ReadonlyMap<string, string> = new Map([\n [\"node.fill\", \"fillOpacity\"],\n [\"edge.color\", \"opacity\"],\n]);\n\n/**\n * How a color is drawn, which decides how a Graphviz color list is read.\n * @param target - nodes or edges\n * @param property - the property\n * @returns the use\n */\nfunction colorUse(target: StyleTarget, property: string): \"fill\" | \"edge\" | \"line\" {\n if (property === \"fill\") {\n return \"fill\";\n }\n return target === \"edge\" && property === \"color\" ? \"edge\" : \"line\";\n}\n\n/**\n * The canonical value of a property that is not a color.\n * @param kind - the property's value kind, or undefined for a property outside the vocabulary\n * @param property - the property\n * @param raw - the raw value\n * @param dialect - how it is spelled\n * @param site - where it was read\n * @returns the value, or null\n */\nfunction canonValue(\n kind: string | undefined,\n property: string,\n raw: unknown,\n dialect: StyleDialect,\n site: CanonSite,\n): StyleValue | null {\n switch (kind) {\n case \"number\":\n return canonNumber(\n raw,\n site,\n dialect === \"graphviz\" && (property === \"width\" || property === \"height\") ? DOT_POINTS_PER_INCH : 1,\n );\n case \"opacity\":\n return canonOpacity(raw, dialect, site);\n case \"boolean\":\n return canonBoolean(raw, site);\n case \"text\":\n return canonText(raw, site);\n case undefined:\n // a property only one consumer draws (graphty:<channel>) is carried as it is\n return typeof raw === \"string\" ||\n typeof raw === \"boolean\" ||\n (typeof raw === \"number\" && Number.isFinite(raw))\n ? raw\n : null;\n default:\n return ENUM_KINDS.has(kind) ? canonEnum(kind as StyleEnumKind, raw, dialect, site) : null;\n }\n}\n\n/** The style roles and the property each sets, per target; `size` sets a node's width and height. */\nconst ROLE_PROPERTIES: Readonly<Record<StyleTarget, readonly (readonly [string, readonly string[]])[]>> = {\n node: [\n [\"color\", [\"fill\"]],\n [\"size\", [\"width\", \"height\"]],\n [\"shape\", [\"shape\"]],\n [\"hidden\", [\"visible\"]],\n ],\n edge: [\n [\"color\", [\"color\"]],\n [\"thickness\", [\"width\"]],\n [\"shape\", [\"lineStyle\"]],\n [\"hidden\", [\"visible\"]],\n ],\n};\n\n/**\n * The generic reader: the styles of the columns whose role is `color`, `size`, `shape`, `thickness` or `hidden`, so a\n * format that tags its style columns needs no reader of its own. A color column holds CSS text or channel numbers\n * (0..1 in a float column, 0..255 otherwise, with an optional alpha); a hidden column holds booleans.\n * @param snapshot - the graph\n * @param dialect - how text values are spelled (the format's name; CSS for a format with no dialect of its own)\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @returns the canonical values, or null when no column has a style role\n */\nfunction roleStyles(\n snapshot: GraphSnapshot,\n dialect: StyleDialect,\n notes: StyleNotes,\n budget: StyleBudget,\n): StyleTruth | null {\n const raw = { node: [] as string[], edge: [] as string[] };\n const out = { node: { values: {} } as ReaderOutput, edge: { values: {} } as ReaderOutput };\n for (const target of TARGETS) {\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = count(snapshot, target);\n const columns = new Map<string, readonly unknown[]>();\n for (const [role, properties] of ROLE_PROPERTIES[target]) {\n const col = table.byRole(role);\n if (col === null) {\n continue;\n }\n raw[target].push(col.meta.name);\n const vals = roleValues(table, col.meta, role, n);\n for (const p of properties) {\n columns.set(p, vals);\n }\n }\n out[target] = { values: canonicalize(target, columns, dialect, n, notes, budget) };\n }\n if (raw.node.length === 0 && raw.edge.length === 0) {\n return null;\n }\n return {\n dialect,\n tool: null,\n units: styleLengthUnit(dialect),\n graph: {},\n node: out.node,\n edge: out.edge,\n raw,\n notes: [],\n };\n}\n\n/**\n * A role column's raw values: a color as text, a hidden flag as the visibility it says the opposite of.\n * @param table - the node or edge table\n * @param meta - the column's name and dtype\n * @param meta.name - the column's name\n * @param meta.dtype - its dtype\n * @param role - its role\n * @param n - the element count\n * @returns the values\n */\nfunction roleValues(\n table: GraphSnapshot[\"nodes\"],\n meta: { readonly name: string; readonly dtype: string },\n role: string,\n n: number,\n): unknown[] {\n return Array.from({ length: n }, (_, i) => {\n const v = plainCell(table.value(meta.name, i));\n if (role === \"color\") {\n return channelsColor(v, meta.dtype);\n }\n if (role === \"hidden\") {\n return typeof v === \"boolean\" ? !v : null;\n }\n return v;\n });\n}\n\n/**\n * A color cell as text: channel numbers become `rgba()` (floats 0..1, integers 0..255); text stays as it is.\n * @param v - the cell\n * @param dtype - the column's dtype\n * @returns the color's text, or the cell unchanged\n */\nfunction channelsColor(v: unknown, dtype: string): unknown {\n if (\n !Array.isArray(v) ||\n (v.length !== 3 && v.length !== 4) ||\n !v.every((x) => typeof x === \"number\" && Number.isFinite(x))\n ) {\n return v;\n }\n const scale = dtype === \"f32\" || dtype === \"f64\" ? 255 : 1;\n const [r, g, b] = (v as number[]).map((x) => Math.round(x * scale));\n const alphaScale = scale === 255 ? 1 : 255;\n const a = v.length === 4 ? (v[3] as number) / alphaScale : 1;\n return `rgba(${String(r)}, ${String(g)}, ${String(b)}, ${String(a)})`;\n}\n"],"names":["count","raw"],"mappings":"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"}