@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
@@ -42,18 +42,26 @@ import type {
42
42
  StyleWorkBudget,
43
43
  } from "../types.js";
44
44
  import { CYJS_DEFAULT_STYLESHEET, CYJS_PROPERTY_DEFAULTS } from "./defaults-table.js";
45
+ import { combineFace } from "./face.js";
45
46
  import {
46
47
  applyCyjsMapper,
48
+ CYJS_CURVE_STYLES,
47
49
  CYJS_THROWS,
50
+ cyjsAliasOf,
51
+ cyjsDashLook,
48
52
  type CyjsFlat,
49
53
  cyjsNeutral,
50
54
  type CyjsParsed,
55
+ cyjsPolygonShapes,
51
56
  cyjsProperties,
52
57
  cyjsPropertyName,
53
58
  type CyjsPropertySpec,
54
59
  cyjsRendered,
60
+ gradientStopColors,
61
+ gradientStops,
55
62
  parseCyjsValue,
56
63
  } from "./mappers.js";
64
+ import { cyjsRoute, type CyjsRouteEdge, type CyjsRouteNode } from "./routes.js";
57
65
  import { type CyjsCheck, type CyjsQuery, type CyjsSelector, parseCyjsSelector } from "./selector.js";
58
66
  import { type CyjsSheetEntry, parseCyjsStylesheetText } from "./stylesheet-text.js";
59
67
 
@@ -1136,6 +1144,18 @@ const POSITIONS: ReadonlyMap<string, string> = new Map([
1136
1144
  ["bottom,right", "bottom-right"],
1137
1145
  ]);
1138
1146
 
1147
+ /** The positions inside the node, by the sides the `-inside` alignments name (`center` for neither). */
1148
+ const INSIDE_POSITIONS: ReadonlyMap<string, string> = new Map([
1149
+ ["top,left", "inside-top-left"],
1150
+ ["top,center", "inside-top"],
1151
+ ["top,right", "inside-top-right"],
1152
+ ["center,left", "inside-left"],
1153
+ ["center,right", "inside-right"],
1154
+ ["bottom,left", "inside-bottom-left"],
1155
+ ["bottom,center", "inside-bottom"],
1156
+ ["bottom,right", "inside-bottom-right"],
1157
+ ]);
1158
+
1139
1159
  /**
1140
1160
  * Applies a Cytoscape.js stylesheet to its elements as Cytoscape.js 3.34 does.
1141
1161
  * @param input - the elements, the stylesheet, the graph and the options
@@ -1186,8 +1206,8 @@ export function evaluateCytoscapeJs(input: CyjsStyleInput): CyjsStyles {
1186
1206
  notes.add(STYLE_ISSUE.SELECTOR, null, "selector", { count: deep, sample: "nested too deep" });
1187
1207
  }
1188
1208
  const matcher = new Matcher(graph, notes);
1189
- const node = evaluateTarget("node", graph, sheet, matcher, input, notes, budget);
1190
- const edge = evaluateTarget("edge", graph, sheet, matcher, input, notes, budget);
1209
+ const node = evaluateTarget("node", graph, sheet, matcher, input, { notes, budget, nodes: null });
1210
+ const edge = evaluateTarget("edge", graph, sheet, matcher, input, { notes, budget, nodes: node });
1191
1211
  return { node, edge, graph };
1192
1212
  }
1193
1213
 
@@ -1289,8 +1309,10 @@ function cellsOf(cells: Cells, name: string, n: number): (Cell | undefined)[] {
1289
1309
  * @param sheet - the entries
1290
1310
  * @param matcher - the selector evaluator
1291
1311
  * @param input - the input
1292
- * @param notes - where problems are noted
1293
- * @param budget - the counted budget
1312
+ * @param env - where problems are noted, the counted budget, and for edges the nodes' values
1313
+ * @param env.notes - where problems are noted
1314
+ * @param env.budget - the counted budget
1315
+ * @param env.nodes - the nodes' values, which edge routes are measured against (null for nodes)
1294
1316
  * @returns the target's values and rules
1295
1317
  */
1296
1318
  function evaluateTarget(
@@ -1299,9 +1321,9 @@ function evaluateTarget(
1299
1321
  sheet: readonly Entry[],
1300
1322
  matcher: Matcher,
1301
1323
  input: CyjsStyleInput,
1302
- notes: StyleNotes,
1303
- budget: StyleWorkBudget,
1324
+ env: { readonly notes: StyleNotes; readonly budget: StyleWorkBudget; readonly nodes: CyjsTargetStyles | null },
1304
1325
  ): CyjsTargetStyles {
1326
+ const { notes, budget } = env;
1305
1327
  const els = kind === "node" ? graph.nodes : graph.edges;
1306
1328
  const spend = (ops: number): void => {
1307
1329
  budget.spend(kind, ops);
@@ -1319,6 +1341,21 @@ function evaluateTarget(
1319
1341
  forceLoopCurves(graph, cells.get("curve-style"));
1320
1342
  }
1321
1343
  const drawn = drawnValues(kind, els, cells, order, input.rendered, notes, spend);
1344
+ // a file read with Cytoscape.js's own defaults draws an edge no rule curves as a haystack (a file graphty wrote
1345
+ // is read with graphty's)
1346
+ if (kind === "edge" && input.toolDefaults !== false) {
1347
+ const read: DrawnRead = { kind, els, cells, order, rendered: input.rendered, notes };
1348
+ const curves = drawnColumn(read, "curve-style", CURVE_PART);
1349
+ noArrowsOnHaystacks(curves, drawn);
1350
+ if (env.nodes !== null) {
1351
+ edgeRoutes(graph, read, curves, env.nodes, drawn);
1352
+ }
1353
+ }
1354
+ if (kind === "node") {
1355
+ const read: DrawnRead = { kind, els, cells, order, rendered: input.rendered, notes };
1356
+ nodeSizes(graph, read, drawn);
1357
+ mixedLabelPlaces(graph, read, drawn);
1358
+ }
1322
1359
  if (kind === "edge") {
1323
1360
  straightenUnpairedBeziers(graph, curveStyles(graph, cells, input.rendered), coreToOut, drawn.curved);
1324
1361
  }
@@ -1501,7 +1538,7 @@ function drawnValues(
1501
1538
  if (spec.property.startsWith("_")) {
1502
1539
  words.set(
1503
1540
  spec.property,
1504
- col.map((v) => (typeof v === "string" ? v : null)),
1541
+ col.map((v) => (typeof v === "string" || typeof v === "number" ? String(v) : null)),
1505
1542
  );
1506
1543
  continue;
1507
1544
  }
@@ -1514,6 +1551,9 @@ function drawnValues(
1514
1551
  });
1515
1552
  }
1516
1553
  combineParts(kind, out, words, values, notes);
1554
+ if (kind === "node") {
1555
+ cyjsPolygonShapes(values);
1556
+ }
1517
1557
  const drawn: Record<string, (StyleValue | null)[]> = {};
1518
1558
  for (const [p, col] of Object.entries(values)) {
1519
1559
  if (col.some((v) => v !== null)) {
@@ -1695,7 +1735,7 @@ function entryProperties(
1695
1735
  ): EntryProperty[] {
1696
1736
  const out: EntryProperty[] = [];
1697
1737
  for (const [name0, value] of entry.properties) {
1698
- const name = entry.dashOnly ? dashOnlyName(name0) : cyjsPropertyName(name0);
1738
+ const name = entry.dashOnly ? cyjsAliasOf(name0) : cyjsPropertyName(name0);
1699
1739
  const spec = specs.get(name);
1700
1740
  if (spec === undefined) {
1701
1741
  if (kind === "node" && !CYJS_EDGE_ONLY.has(name) && !entry.tool) {
@@ -1716,27 +1756,37 @@ function entryProperties(
1716
1756
  return out;
1717
1757
  }
1718
1758
 
1719
- /**
1720
- * A property name of an entry Cytoscape.js reads in dash form only: `content` is `label`, any other name as it is.
1721
- * @param name - the name as written
1722
- * @returns the name
1723
- */
1724
- function dashOnlyName(name: string): string {
1725
- return name === "content" ? "label" : name;
1726
- }
1727
-
1728
1759
  /** Edge properties a node never carries: not noted as dropped on nodes. */
1729
1760
  const CYJS_EDGE_ONLY: ReadonlySet<string> = new Set([
1730
1761
  "line-color",
1731
1762
  "line-style",
1763
+ "line-outline-width",
1764
+ "line-outline-color",
1765
+ "line-fill",
1766
+ "line-gradient-stop-colors",
1767
+ "line-gradient-stop-positions",
1732
1768
  "target-arrow-shape",
1733
1769
  "source-arrow-shape",
1734
1770
  "target-arrow-color",
1735
1771
  "source-arrow-color",
1772
+ "mid-target-arrow-shape",
1773
+ "mid-source-arrow-shape",
1774
+ "mid-target-arrow-color",
1775
+ "mid-source-arrow-color",
1776
+ "target-arrow-fill",
1777
+ "source-arrow-fill",
1736
1778
  "curve-style",
1737
1779
  "arrow-scale",
1738
1780
  "source-label",
1739
1781
  "target-label",
1782
+ "source-text-offset",
1783
+ "target-text-offset",
1784
+ "source-text-margin-x",
1785
+ "source-text-margin-y",
1786
+ "target-text-margin-x",
1787
+ "target-text-margin-y",
1788
+ "source-text-rotation",
1789
+ "target-text-rotation",
1740
1790
  ]);
1741
1791
 
1742
1792
  /**
@@ -1860,7 +1910,8 @@ function neutralOfCell(spec: CyjsPropertySpec, name: string, c: Cell, site: Cano
1860
1910
  }
1861
1911
 
1862
1912
  /**
1863
- * Combines the label alignments into `labelPosition` and `visibility` with `display` into `visible`.
1913
+ * Combines the label alignments into `labelPosition`, `text-wrap` with `text-max-width` and `text-overflow-wrap` into
1914
+ * `labelWrapWidth`, `labelWrapEllipsis` and `labelWrapAnywhere`, and `visibility` with `display` into `visible`.
1864
1915
  * @param kind - the target
1865
1916
  * @param n - the element count
1866
1917
  * @param words - the parts by internal name
@@ -1874,47 +1925,1139 @@ function combineParts(
1874
1925
  values: Record<string, (StyleValue | null)[]>,
1875
1926
  notes: StyleNotes,
1876
1927
  ): void {
1928
+ // the element's own opacity, before an edge's line opacity is multiplied in: its label is drawn at it
1929
+ const whole = [...(values.opacity ?? new Array<StyleValue | null>(n).fill(null))];
1930
+ combineLabelOpacity(n, words, values);
1931
+ if (kind === "node") {
1932
+ combineNodeOpacity(n, words, values);
1933
+ }
1877
1934
  const va = words.get("_valign");
1878
1935
  const ha = words.get("_halign");
1879
1936
  if (kind === "node" && (va !== undefined || ha !== undefined)) {
1880
- values.labelPosition = Array.from({ length: n }, (_, i) =>
1881
- labelPosition(va?.[i] ?? null, ha?.[i] ?? null, (sample) => {
1882
- notes.add(STYLE_ISSUE.UNKNOWN_VALUE, kind, "labelPosition", { sample, element: i });
1883
- }),
1937
+ values.labelPosition = Array.from({ length: n }, (_, i) => labelPosition(va?.[i] ?? null, ha?.[i] ?? null));
1938
+ }
1939
+ // `text-max-width` wraps a label only under `text-wrap: wrap`; unset there, it is 9999 (cytoscape.js 3.34.3
1940
+ // dist/cytoscape.cjs.js line 18484), which wraps nothing but the label's own line breaks.
1941
+ // `text-wrap: ellipsis` cuts the label at the same width instead (3.34.3 line 25254), and
1942
+ // `text-overflow-wrap: anywhere` breaks a wrapped one between any two letters (line 25204).
1943
+ const wrap = words.get("_wrap");
1944
+ const maxWidth = words.get("_maxWidth");
1945
+ const overflow = words.get("_overflowWrap");
1946
+ if (wrap !== undefined) {
1947
+ const cut = (i: number): boolean => wrap[i] === "wrap" || wrap[i] === "ellipsis";
1948
+ values.labelWrapWidth = Array.from({ length: n }, (_, i) =>
1949
+ cut(i) && typeof maxWidth?.[i] === "string" ? Number(maxWidth[i]) : null,
1884
1950
  );
1951
+ if (wrap.includes("ellipsis")) {
1952
+ values.labelWrapEllipsis = wrap.map((w) => (w === "ellipsis" ? true : null));
1953
+ }
1954
+ if (overflow?.includes("anywhere") === true) {
1955
+ values.labelWrapAnywhere = wrap.map((w, i) => (w === "wrap" && overflow[i] === "anywhere" ? true : null));
1956
+ }
1957
+ }
1958
+ if (kind === "node") {
1959
+ combineFace(n, words, values);
1960
+ combineBackgroundGradient(n, words, values, notes);
1961
+ } else {
1962
+ combineArrowFills(n, words, values, notes);
1963
+ combineLineOpacity(n, words.get("_lineOpacity"), values);
1964
+ }
1965
+ combineDashes(kind, n, words, values);
1966
+ combineLabelText(kind, n, words, values);
1967
+ combineLabelDress(kind, n, words, values, notes, whole);
1968
+ combineVisibility(kind, n, words, values);
1969
+ }
1970
+
1971
+ /**
1972
+ * A label's opacity as Cytoscape.js draws it: its `text-opacity` times the element's `opacity` (cytoscape.js 3.34.3
1973
+ * `drawText`: `effectiveOpacity() * text-opacity`), which the label's box and its line round it are drawn at too.
1974
+ * ponytail: a compound parent's opacity, which Cytoscape.js multiplies in as well, is left out
1975
+ * @param n - the element count
1976
+ * @param words - the parts by internal name
1977
+ * @param values - the values, `opacity` still the element's own; changed in place
1978
+ */
1979
+ function combineLabelOpacity(
1980
+ n: number,
1981
+ words: ReadonlyMap<string, (string | null)[]>,
1982
+ values: Record<string, (StyleValue | null)[]>,
1983
+ ): void {
1984
+ const text = words.get("_textOpacity");
1985
+ const whole = values.opacity;
1986
+ if (text === undefined && whole === undefined) {
1987
+ return;
1988
+ }
1989
+ const col = new Array<StyleValue | null>(n).fill(null);
1990
+ for (let i = 0; i < n; i++) {
1991
+ const t = text?.[i] ?? null;
1992
+ const o = whole?.[i];
1993
+ const v = Math.round((t === null ? 1 : Number(t)) * (typeof o === "number" ? o : 1) * 1e6) / 1e6;
1994
+ // a label at full strength is left unset, as one no rule fades
1995
+ col[i] = v === 1 || !Number.isFinite(v) ? null : v;
1996
+ }
1997
+ values.labelOpacity = col;
1998
+ }
1999
+
2000
+ /**
2001
+ * A node's border and outline as Cytoscape.js draws them: at their own `border-opacity` / `outline-opacity` times the
2002
+ * node's `opacity` (cytoscape.js 3.34.3 `drawNode`: `parentOpacity * borderOpacity`). A ring at full strength is left
2003
+ * unset.
2004
+ * @param n - the element count
2005
+ * @param words - the parts by internal name
2006
+ * @param values - the values, `opacity` still the node's own; changed in place
2007
+ */
2008
+ function combineNodeOpacity(
2009
+ n: number,
2010
+ words: ReadonlyMap<string, (string | null)[]>,
2011
+ values: Record<string, (StyleValue | null)[]>,
2012
+ ): void {
2013
+ const whole = values.opacity;
2014
+ for (const [part, p] of [
2015
+ ["_ringOpacity", "borderOpacity"],
2016
+ ["_outlineRingOpacity", "outerBorderOpacity"],
2017
+ ] as const) {
2018
+ const own = words.get(part);
2019
+ if (own === undefined && whole === undefined) {
2020
+ continue;
2021
+ }
2022
+ values[p] = Array.from({ length: n }, (_, i) => {
2023
+ const a = own?.[i] ?? null;
2024
+ const o = whole?.[i];
2025
+ const v = Math.round((a === null ? 1 : Number(a)) * (typeof o === "number" ? o : 1) * 1e6) / 1e6;
2026
+ return v === 1 || !Number.isFinite(v) ? null : v;
2027
+ });
1885
2028
  }
2029
+ }
2030
+
2031
+ /**
2032
+ * A dashed line or border as the line it looks like. Cytoscape.js draws `dashed` with `line-dash-pattern` (6 3) or
2033
+ * `border-dash-pattern` (4 2) in pixels whatever the width, and `dotted` as 1 1 (cytoscape.js 3.34.3 `drawEdgePath`,
2034
+ * `drawNode`), so a wide dashed line shows dots and a pattern of long and short dashes a dash-dot. The class is read
2035
+ * from the dashes and gaps against the width, a round or square cap lengthening each dash by the width.
2036
+ * ponytail: the neutral line styles name a class, not a pattern; a dash pattern slot would carry the lengths exactly
2037
+ * @param kind - the target
2038
+ * @param n - the element count
2039
+ * @param words - the parts by internal name
2040
+ * @param values - the values; changed in place
2041
+ */
2042
+ function combineDashes(
2043
+ kind: StyleTarget,
2044
+ n: number,
2045
+ words: ReadonlyMap<string, (string | null)[]>,
2046
+ values: Record<string, (StyleValue | null)[]>,
2047
+ ): void {
2048
+ // the line or border, and a node's outline, which is always dashed 4 2 with butt ends (`drawOutline`)
2049
+ const lines: [string, string, number, string, boolean][] =
2050
+ kind === "edge"
2051
+ ? [["lineStyle", "width", 3, "6 3", true]]
2052
+ : [
2053
+ ["borderStyle", "borderWidth", 0, "4 2", true],
2054
+ ["outerBorderStyle", "outerBorderWidth", 0, "4 2", false],
2055
+ ];
2056
+ for (const [style, width, fallback, pattern, own] of lines) {
2057
+ const col = values[style];
2058
+ if (col !== undefined) {
2059
+ dashColumn(col, n, values[width], { fallback, pattern }, own ? words : null);
2060
+ }
2061
+ }
2062
+ }
2063
+
2064
+ /**
2065
+ * One line style's dashed lines as the lines they look like.
2066
+ * @param col - the line styles; changed in place
2067
+ * @param n - the element count
2068
+ * @param widths - the lines' widths, when set
2069
+ * @param drawn - what Cytoscape.js draws when they are not set: the width and the dash pattern
2070
+ * @param drawn.fallback - the width
2071
+ * @param drawn.pattern - the dash pattern
2072
+ * @param words - the parts by internal name, or null for an outline, which has no pattern or cap of its own
2073
+ */
2074
+ function dashColumn(
2075
+ col: (StyleValue | null)[],
2076
+ n: number,
2077
+ widths: readonly (StyleValue | null)[] | undefined,
2078
+ drawn: { fallback: number; pattern: string },
2079
+ words: ReadonlyMap<string, (string | null)[]> | null,
2080
+ ): void {
2081
+ for (let i = 0; i < n; i++) {
2082
+ if (col[i] !== "dashed") {
2083
+ continue;
2084
+ }
2085
+ const w = widths?.[i];
2086
+ const look = dashedLook(words, i, drawn.pattern, typeof w === "number" ? w : drawn.fallback);
2087
+ if (look !== null) {
2088
+ col[i] = look;
2089
+ }
2090
+ }
2091
+ }
2092
+
2093
+ /**
2094
+ * One dashed line's look, from its dash pattern (its own `line-dash-pattern` when it has one) and cap.
2095
+ * @param words - the parts by internal name, or null for an outline, which has no pattern or cap of its own
2096
+ * @param i - the element
2097
+ * @param pattern - the pattern Cytoscape.js draws when none is given
2098
+ * @param width - the line's width
2099
+ * @returns the line style, or null when the pattern is not a list of numbers
2100
+ */
2101
+ function dashedLook(
2102
+ words: ReadonlyMap<string, (string | null)[]> | null,
2103
+ i: number,
2104
+ pattern: string,
2105
+ width: number,
2106
+ ): string | null {
2107
+ const dashes = (words?.get("_dashPattern")?.[i] ?? pattern)
2108
+ .split(/[\s,[\]]+/)
2109
+ .filter((t) => t !== "")
2110
+ .map((t) => Number.parseFloat(t));
2111
+ if (dashes.length === 0 || !dashes.every((d) => Number.isFinite(d))) {
2112
+ return null;
2113
+ }
2114
+ return cyjsDashLook(dashes, width, words?.get("_dashCap")?.[i] ?? "butt");
2115
+ }
2116
+
2117
+ /**
2118
+ * A property's values, created (all null) when it has none yet.
2119
+ * @param values - the values by property; changed in place
2120
+ * @param property - the property
2121
+ * @param n - the element count
2122
+ * @returns its values
2123
+ */
2124
+ function columnOf(values: Record<string, (StyleValue | null)[]>, property: string, n: number): (StyleValue | null)[] {
2125
+ let column = values[property];
2126
+ if (column === undefined) {
2127
+ column = new Array<StyleValue | null>(n).fill(null);
2128
+ values[property] = column;
2129
+ }
2130
+ return column;
2131
+ }
2132
+
2133
+ /**
2134
+ * `visibility` with `display` into `visible`. Cytoscape.js leaves the edges of a node hidden with `visibility:
2135
+ * hidden` drawn (only `display: none` takes them away), so such a node is kept and drawn at opacity 0 (its border and
2136
+ * outline too), with no label.
2137
+ * @param kind - the target
2138
+ * @param n - the element count
2139
+ * @param words - the parts by internal name
2140
+ * @param values - the values; changed in place
2141
+ */
2142
+ function combineVisibility(
2143
+ kind: StyleTarget,
2144
+ n: number,
2145
+ words: ReadonlyMap<string, (string | null)[]>,
2146
+ values: Record<string, (StyleValue | null)[]>,
2147
+ ): void {
1886
2148
  const vis = words.get("_visibility");
1887
2149
  const disp = words.get("_display");
1888
- if (vis !== undefined || disp !== undefined) {
1889
- const col = new Array<StyleValue | null>(n).fill(null);
2150
+ if (vis === undefined && disp === undefined) {
2151
+ return;
2152
+ }
2153
+ const col = new Array<StyleValue | null>(n).fill(null);
2154
+ for (let i = 0; i < n; i++) {
2155
+ const a = vis?.[i] ?? null;
2156
+ const b = disp?.[i] ?? null;
2157
+ if (a === null && b === null) {
2158
+ continue;
2159
+ }
2160
+ const keptInvisible = kind === "node" && a === "hidden" && b !== "none";
2161
+ col[i] = keptInvisible || (a !== "hidden" && b !== "none");
2162
+ if (keptInvisible) {
2163
+ // nothing of it is drawn: its body, its border, its outline or its label
2164
+ for (const p of ["opacity", "borderOpacity", "outerBorderOpacity", "labelOpacity"]) {
2165
+ columnOf(values, p, n)[i] = 0;
2166
+ }
2167
+ columnOf(values, "label", n)[i] = "";
2168
+ }
2169
+ }
2170
+ values.visible = col;
2171
+ }
2172
+
2173
+ /**
2174
+ * The label's words as Cytoscape.js draws them: `text-transform`, `text-justification`, and `text-rotation` (an
2175
+ * edge's end labels' `source-` / `target-text-rotation` too) as `labelRotation`, `sourceLabelRotation` and
2176
+ * `targetLabelRotation`.
2177
+ * @param kind - the target
2178
+ * @param n - the element count
2179
+ * @param words - the parts by internal name
2180
+ * @param values - the values; changed in place
2181
+ */
2182
+ function combineLabelText(
2183
+ kind: StyleTarget,
2184
+ n: number,
2185
+ words: ReadonlyMap<string, (string | null)[]>,
2186
+ values: Record<string, (StyleValue | null)[]>,
2187
+ ): void {
2188
+ transformLabels(n, words.get("_transform"), values.label);
2189
+ // cytoscape.js 3.34.3 `labelJustification`: auto lines the lines up against the node, a label beside it on the
2190
+ // left to its right edge
2191
+ const justification = words.get("_justification");
2192
+ if (justification !== undefined && kind === "edge") {
2193
+ combineEdgeJustification(n, justification, words.get("_wrap"), values);
2194
+ } else if (justification !== undefined) {
2195
+ const halign = words.get("_halign");
2196
+ const AUTO: Readonly<Record<string, string>> = {
2197
+ left: "right",
2198
+ right: "left",
2199
+ "left-inside": "left",
2200
+ "right-inside": "right",
2201
+ };
2202
+ values.labelTextAlign = justification.map((j, i) => {
2203
+ if (j === null) {
2204
+ return null;
2205
+ }
2206
+ return j === "auto" ? (AUTO[halign?.[i] ?? "center"] ?? "center") : j;
2207
+ });
2208
+ }
2209
+ // an edge's `autorotate` follows its line, which the routes work out (`autorotateLabels`)
2210
+ const rotations: readonly (readonly [string, string])[] = [
2211
+ ["_rotation", "labelRotation"],
2212
+ ["_sourceRotation", "sourceLabelRotation"],
2213
+ ["_targetRotation", "targetLabelRotation"],
2214
+ ];
2215
+ for (const [part, property] of rotations) {
2216
+ const rotation = words.get(part);
2217
+ if (rotation !== undefined) {
2218
+ values[property] = rotation.map((r) => (r === null ? null : cyjsAngleDegrees(r)));
2219
+ }
2220
+ }
2221
+ }
2222
+
2223
+ /**
2224
+ * A label's `text-transform`: `uppercase` and `lowercase` change its words; anything else leaves them.
2225
+ * @param n - the element count
2226
+ * @param transform - each element's transform
2227
+ * @param label - each element's label; changed in place
2228
+ */
2229
+ function transformLabels(
2230
+ n: number,
2231
+ transform: readonly (string | null)[] | undefined,
2232
+ label: (StyleValue | null)[] | undefined,
2233
+ ): void {
2234
+ if (transform === undefined || label === undefined) {
2235
+ return;
2236
+ }
2237
+ for (let i = 0; i < n; i++) {
2238
+ const text = label[i];
2239
+ if (typeof text === "string" && transform[i] === "uppercase") {
2240
+ label[i] = text.toUpperCase();
2241
+ } else if (typeof text === "string" && transform[i] === "lowercase") {
2242
+ label[i] = text.toLowerCase();
2243
+ }
2244
+ }
2245
+ }
2246
+
2247
+ /**
2248
+ * An edge label's `text-justification` as Cytoscape.js draws it: every line centered (an edge's text is always
2249
+ * centered, cytoscape.js 3.34.3 `setupTextStyle`), the block moved half its width left for `left` and right for
2250
+ * `right`, and only for a wrapped label (`drawText`), as `labelShiftX`.
2251
+ * @param n - the element count
2252
+ * @param justification - each edge's justification
2253
+ * @param wrap - each edge's `text-wrap`
2254
+ * @param values - the values; changed in place
2255
+ */
2256
+ function combineEdgeJustification(
2257
+ n: number,
2258
+ justification: readonly (string | null)[],
2259
+ wrap: readonly (string | null)[] | undefined,
2260
+ values: Record<string, (StyleValue | null)[]>,
2261
+ ): void {
2262
+ const SHIFT: Readonly<Record<string, number>> = { left: -0.5, right: 0.5 };
2263
+ for (let i = 0; i < n; i++) {
2264
+ const shift = wrap?.[i] === "wrap" ? SHIFT[justification[i] ?? ""] : undefined;
2265
+ if (shift !== undefined) {
2266
+ columnOf(values, "labelShiftX", n)[i] = shift;
2267
+ }
2268
+ }
2269
+ }
2270
+
2271
+ /**
2272
+ * A label's outline and background box as Cytoscape.js draws them: the outline only with a `text-outline-width` and
2273
+ * a `text-outline-opacity` above 0, a stroke of twice that width centered on the letters' edges (cytoscape.js
2274
+ * 3.34.3 `drawText`: `lineWidth = 2 * text-outline-width`); the box only with a `text-background-opacity` above 0
2275
+ * (its default is 0), and the line round the box (`labelBorder`); the box and the line reach `text-background-padding`
2276
+ * past the words.
2277
+ * @param kind - the target
2278
+ * @param n - the element count
2279
+ * @param words - the parts by internal name
2280
+ * @param values - the values; changed in place
2281
+ * @param notes - where problems are noted
2282
+ * @param whole - each element's own opacity, which the box is drawn at too
2283
+ */
2284
+ function combineLabelDress(
2285
+ kind: StyleTarget,
2286
+ n: number,
2287
+ words: ReadonlyMap<string, (string | null)[]>,
2288
+ values: Record<string, (StyleValue | null)[]>,
2289
+ notes: StyleNotes,
2290
+ whole: readonly (StyleValue | null)[],
2291
+ ): void {
2292
+ const num = (part: string, i: number, fallback: number): number => {
2293
+ const v = words.get(part)?.[i];
2294
+ return v === null || v === undefined ? fallback : Number(v);
2295
+ };
2296
+ const col = (p: string): (StyleValue | null)[] => (values[p] ??= new Array<StyleValue | null>(n).fill(null));
2297
+ const outlined = words.has("_outlineWidth");
2298
+ const boxed = words.has("_backgroundOpacity");
2299
+ const bordered = words.has("_textBorderWidth") && words.has("_textBorderOpacity");
2300
+ // each part is drawn at its own opacity times the element's; the outline at the words' opacity too (drawText)
2301
+ const at = (v: StyleValue | null | undefined): number => (typeof v === "number" ? v : 1);
2302
+ const faded = (v: number): number | null => {
2303
+ const r = Math.round(v * 1e6) / 1e6;
2304
+ return r < 1 ? r : null;
2305
+ };
2306
+ for (let i = 0; i < n && (outlined || boxed || bordered); i++) {
2307
+ const width = num("_outlineWidth", i, 0);
2308
+ const outlineOpacity = num("_outlineOpacity", i, 1);
2309
+ if (outlined && width > 0 && outlineOpacity > 0) {
2310
+ col("labelOutlineColor")[i] = words.get("_outlineColor")?.[i] ?? "#000000";
2311
+ col("labelOutlineWidth")[i] = 2 * width;
2312
+ col("labelOutlineOpacity")[i] = faded(outlineOpacity * at(values.labelOpacity?.[i]));
2313
+ }
2314
+ const boxOpacity = num("_backgroundOpacity", i, 0);
2315
+ const box = boxed && boxOpacity > 0;
2316
+ if (box) {
2317
+ col("labelBackground")[i] = words.get("_backgroundColor")?.[i] ?? "#000000";
2318
+ col("labelBackgroundOpacity")[i] = faded(boxOpacity * at(whole[i]));
2319
+ }
2320
+ const border = bordered && labelBorder(kind, i, words, col, notes, at(whole[i]));
2321
+ if (box || border) {
2322
+ labelBoxShape(kind, i, words, col, notes);
2323
+ }
2324
+ }
2325
+ }
2326
+
2327
+ /**
2328
+ * A label's box or line round it, sized and shaped: it reaches `text-background-padding` past the words on every
2329
+ * side (0 unset), one font size tall a line (cytoscape.js 3.34.3 `calculateLabelDimensions`), its corners rounded
2330
+ * 2px for round-rectangle (`drawText`); a circle is noted.
2331
+ * @param kind - the target
2332
+ * @param i - the element
2333
+ * @param words - the parts by internal name
2334
+ * @param col - a property's values, created when absent
2335
+ * @param notes - where problems are noted
2336
+ */
2337
+ function labelBoxShape(
2338
+ kind: StyleTarget,
2339
+ i: number,
2340
+ words: ReadonlyMap<string, (string | null)[]>,
2341
+ col: (p: string) => (StyleValue | null)[],
2342
+ notes: StyleNotes,
2343
+ ): void {
2344
+ const padding = words.get("_backgroundPadding")?.[i];
2345
+ col("labelPadding")[i] = padding === null || padding === undefined ? 0 : Number(padding);
2346
+ col("labelLineHeight")[i] = 1;
2347
+ const shape = words.get("_backgroundShape")?.[i];
2348
+ if (shape === "round-rectangle" || shape === "roundrectangle") {
2349
+ col("labelCornerRadius")[i] = 2;
2350
+ } else if (shape === "circle") {
2351
+ // a disc as tall as the box, centered on it: no neutral box has that shape
2352
+ notes.add(STYLE_ISSUE.APPROXIMATED, kind, "labelBackground", { sample: "circle", element: i });
2353
+ }
2354
+ }
2355
+
2356
+ /**
2357
+ * The line Cytoscape.js draws round a label's box: only with a `text-border-width` and a `text-border-opacity` above
2358
+ * 0 (both default to 0), in `text-border-color` (black unset), at its opacity times the element's. A double one is
2359
+ * one line a quarter of the width, where `drawText` strokes two such lines half the width apart (cytoscape.js 3.34.3),
2360
+ * noted; dotted and dashed are drawn solid, noted.
2361
+ * @param kind - the target
2362
+ * @param i - the element
2363
+ * @param words - the parts by internal name
2364
+ * @param col - a property's values, created when absent
2365
+ * @param notes - where problems are noted
2366
+ * @param whole - the element's opacity
2367
+ * @returns whether a line is drawn
2368
+ */
2369
+ function labelBorder(
2370
+ kind: StyleTarget,
2371
+ i: number,
2372
+ words: ReadonlyMap<string, (string | null)[]>,
2373
+ col: (p: string) => (StyleValue | null)[],
2374
+ notes: StyleNotes,
2375
+ whole: number,
2376
+ ): boolean {
2377
+ const num = (part: string): number => Number(words.get(part)?.[i] ?? 0);
2378
+ const [width, opacity] = [num("_textBorderWidth"), num("_textBorderOpacity")];
2379
+ if (!(width > 0 && opacity > 0)) {
2380
+ return false;
2381
+ }
2382
+ const style = words.get("_textBorderStyle")?.[i] ?? "solid";
2383
+ col("labelBorderColor")[i] = words.get("_textBorderColor")?.[i] ?? "#000000";
2384
+ col("labelBorderWidth")[i] = style === "double" ? width / 4 : width;
2385
+ const drawn = Math.round(opacity * whole * 1e6) / 1e6;
2386
+ col("labelBorderOpacity")[i] = drawn < 1 ? drawn : null;
2387
+ if (style === "dotted" || style === "dashed" || style === "double") {
2388
+ notes.add(STYLE_ISSUE.APPROXIMATED, kind, "labelBorderColor", { sample: style, element: i });
2389
+ }
2390
+ return true;
2391
+ }
2392
+
2393
+ /**
2394
+ * An autorotated label's turn: along the line between two centers, kept upright (cytoscape.js 3.34.3
2395
+ * `lineAngleFromDelta`: atan(dy / dx), a vertical line turned to +90 whichever way it runs), from 0 up to 360.
2396
+ * @param a - the source's center
2397
+ * @param b - the target's center
2398
+ * @returns the degrees
2399
+ */
2400
+ function lineDegrees(a: readonly [number, number], b: readonly [number, number]): number {
2401
+ const dx = b[0] - a[0];
2402
+ const angle = Math.atan((b[1] - a[1]) / dx);
2403
+ const turn = ((dx === 0 ? Math.abs(angle) : angle) * 180) / Math.PI;
2404
+ return Number.isFinite(turn) ? Math.round((((turn % 360) + 360) % 360) * 1e6) / 1e6 + 0 : 0;
2405
+ }
2406
+
2407
+ /**
2408
+ * A Cytoscape.js angle (`30deg`, `0.5rad`, a number of radians) in degrees; `none` and `autorotate` (which turns
2409
+ * only an edge's label) are 0.
2410
+ * @param text - the value
2411
+ * @returns the degrees, or null when it is not an angle
2412
+ */
2413
+ function cyjsAngleDegrees(text: string): number | null {
2414
+ const t = text.trim();
2415
+ if (t === "none" || t === "autorotate") {
2416
+ return 0;
2417
+ }
2418
+ const m = /^(-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?)(deg|rad)?$/i.exec(t);
2419
+ if (m === null) {
2420
+ return null;
2421
+ }
2422
+ const x = Number(m[1]);
2423
+ const deg = m[2]?.toLowerCase() === "deg" ? x : (x * 180) / Math.PI;
2424
+ // the neutral rotation runs from 0 up to 360
2425
+ return Math.round((((deg % 360) + 360) % 360) * 1e6) / 1e6 + 0;
2426
+ }
2427
+
2428
+ /**
2429
+ * An edge's `line-opacity` times its `opacity`, which the line is drawn at (cytoscape.js 3.34.3 `drawEdge`:
2430
+ * `effectiveLineOpacity`).
2431
+ * @param n - the element count
2432
+ * @param line - the line opacities, as text
2433
+ * @param values - the values; changed in place
2434
+ */
2435
+ function combineLineOpacity(
2436
+ n: number,
2437
+ line: readonly (string | null)[] | undefined,
2438
+ values: Record<string, (StyleValue | null)[]>,
2439
+ ): void {
2440
+ if (line === undefined) {
2441
+ return;
2442
+ }
2443
+ const whole = values.opacity;
2444
+ values.opacity = Array.from({ length: n }, (_, i) => {
2445
+ const a = line[i] === null ? null : Number(line[i]);
2446
+ const b = whole?.[i];
2447
+ if (a === null || !Number.isFinite(a)) {
2448
+ return b ?? null;
2449
+ }
2450
+ return Math.round(a * (typeof b === "number" ? b : 1) * 1e6) / 1e6;
2451
+ });
2452
+ }
2453
+
2454
+ /** Where each `background-gradient-direction` runs, in the neutral `fillGradientAngle` degrees. */
2455
+ const GRADIENT_ANGLES: ReadonlyMap<string, number> = new Map([
2456
+ ["to-bottom", 90],
2457
+ ["to-top", 270],
2458
+ ["to-left", 180],
2459
+ ["to-right", 0],
2460
+ ["to-bottom-right", 45],
2461
+ ["to-right-bottom", 45],
2462
+ ["to-bottom-left", 135],
2463
+ ["to-left-bottom", 135],
2464
+ ["to-top-right", 315],
2465
+ ["to-right-top", 315],
2466
+ ["to-top-left", 225],
2467
+ ["to-left-top", 225],
2468
+ ]);
2469
+
2470
+ /**
2471
+ * A node's `background-fill: linear-gradient` or `radial-gradient` as `fill` (its first stop), `fillGradient` (its
2472
+ * last), `fillGradientAngle` (a linear one's direction), `fillGradientKind`, `fillGradientColors` (every stop, when
2473
+ * there are more than two) and `fillGradientStops` (`background-gradient-stop-positions`, when there is one per
2474
+ * color, as Cytoscape.js uses them).
2475
+ * @param n - the element count
2476
+ * @param words - the parts by internal name
2477
+ * @param values - the values; changed in place
2478
+ * @param notes - where problems are noted
2479
+ */
2480
+ function combineBackgroundGradient(
2481
+ n: number,
2482
+ words: ReadonlyMap<string, (string | null)[]>,
2483
+ values: Record<string, (StyleValue | null)[]>,
2484
+ notes: StyleNotes,
2485
+ ): void {
2486
+ const fill = words.get("_backgroundFill");
2487
+ if (fill === undefined) {
2488
+ return;
2489
+ }
2490
+ const stops = words.get("_backgroundStops");
2491
+ const positions = words.get("_backgroundPositions");
2492
+ const direction = words.get("_backgroundDirection");
2493
+ const col = (name: string): (StyleValue | null)[] => (values[name] ??= new Array<StyleValue | null>(n).fill(null));
2494
+ for (let i = 0; i < n; i++) {
2495
+ const radial = fill[i] === "radial-gradient";
2496
+ if (fill[i] !== "linear-gradient" && !radial) {
2497
+ continue;
2498
+ }
2499
+ // Cytoscape.js's default stop colors are one gray, which draws flat
2500
+ const colors = gradientStopColors(stops?.[i] ?? "#999", {
2501
+ notes,
2502
+ target: "node",
2503
+ property: "fill",
2504
+ element: i,
2505
+ });
2506
+ if (colors.length < 2) {
2507
+ continue;
2508
+ }
2509
+ col("fill")[i] = colors[0];
2510
+ col("fillGradient")[i] = colors.at(-1) ?? null;
2511
+ if (colors.length > 2) {
2512
+ col("fillGradientColors")[i] = colors.join(" ");
2513
+ }
2514
+ const placed = gradientStops(positions?.[i] ?? "");
2515
+ if (placed?.split(" ").length === colors.length) {
2516
+ col("fillGradientStops")[i] = placed;
2517
+ }
2518
+ if (radial) {
2519
+ col("fillGradientKind")[i] = "radial";
2520
+ } else {
2521
+ col("fillGradientAngle")[i] = GRADIENT_ANGLES.get(direction?.[i] ?? "to-bottom") ?? 90;
2522
+ }
2523
+ }
2524
+ }
2525
+
2526
+ /** An edge's routing settings, each read as Cytoscape.js spells it. */
2527
+ const ROUTE_PARTS: readonly (readonly [keyof CyjsRouteEdge, string, CyjsPropertySpec])[] = [
2528
+ ["segmentDistances", "segment-distances", { property: "_segmentDistances", type: "text" }],
2529
+ ["segmentWeights", "segment-weights", { property: "_segmentWeights", type: "text" }],
2530
+ ["controlPointDistances", "control-point-distances", { property: "_controlPointDistances", type: "text" }],
2531
+ ["controlPointWeights", "control-point-weights", { property: "_controlPointWeights", type: "text" }],
2532
+ ["controlPointStepSize", "control-point-step-size", { property: "_controlPointStepSize", type: "size" }],
2533
+ ["taxiDirection", "taxi-direction", { property: "_taxiDirection", type: "text" }],
2534
+ ["taxiTurn", "taxi-turn", { property: "_taxiTurn", type: "text" }],
2535
+ ["taxiTurnMinDistance", "taxi-turn-min-distance", { property: "_taxiTurnMinDistance", type: "size" }],
2536
+ ["edgeDistances", "edge-distances", { property: "_edgeDistances", type: "text" }],
2537
+ ["loopDirection", "loop-direction", { property: "_loopDirection", type: "text" }],
2538
+ ["loopSweep", "loop-sweep", { property: "_loopSweep", type: "text" }],
2539
+ ["segmentRadii", "segment-radii", { property: "_segmentRadii", type: "text" }],
2540
+ ["taxiRadius", "taxi-radius", { property: "_taxiRadius", type: "text" }],
2541
+ ["radiusType", "radius-type", { property: "_radiusType", type: "text" }],
2542
+ ];
2543
+
2544
+ /**
2545
+ * The routes of the edges Cytoscape.js does not draw straight (`segments`, `taxi`, an `unbundled-bezier` with
2546
+ * control points, a loop) as `bends`, drawn straight through them (`curved` false).
2547
+ * @param graph - the core's elements
2548
+ * @param read - the edges' cells
2549
+ * @param curves - each edge's curve style, in output order
2550
+ * @param nodes - the nodes' values
2551
+ * @param values - the edges' values; changed in place
2552
+ */
2553
+ function edgeRoutes(
2554
+ graph: CyjsGraph,
2555
+ read: DrawnRead,
2556
+ curves: readonly (StyleValue | null | undefined)[],
2557
+ nodes: CyjsTargetStyles,
2558
+ values: Record<string, (StyleValue | null)[]>,
2559
+ ): void {
2560
+ const words = new Map(ROUTE_PARTS.map(([key, name, spec]) => [key, drawnColumn(read, name, spec)] as const));
2561
+ const nodeAt = new Map<CyjsElement, number>();
2562
+ nodes.elements.forEach((el, k) => {
2563
+ if (el !== null) {
2564
+ nodeAt.set(el, k);
2565
+ }
2566
+ });
2567
+ const geometry = (core: number): CyjsRouteNode | null => routeNode(graph.nodes[core], nodeAt, nodes);
2568
+ // an end label's autorotate turns it as the main label's does (cytoscape.js 3.34.3 `calculateLabelAngle`)
2569
+ const turned: readonly (readonly [string, (StyleValue | null | undefined)[]])[] = [
2570
+ ["labelRotation", drawnColumn(read, "text-rotation", TEXT_PART)],
2571
+ ["sourceLabelRotation", drawnColumn(read, "source-text-rotation", TEXT_PART)],
2572
+ ["targetLabelRotation", drawnColumn(read, "target-text-rotation", TEXT_PART)],
2573
+ ];
2574
+ const ends = [drawnColumn(read, "source-endpoint", TEXT_PART), drawnColumn(read, "target-endpoint", TEXT_PART)];
2575
+ const loops = new Map<string, number>();
2576
+ const n = read.order.length;
2577
+ let routed: (StyleValue | null)[] | null = null;
2578
+ for (let k = 0; k < n; k++) {
2579
+ const e = read.order[k];
2580
+ const between = edgeNodes(graph, e, geometry);
2581
+ if (between === null) {
2582
+ continue;
2583
+ }
2584
+ const { src, tgt, loop } = between;
2585
+ if (!loop) {
2586
+ autorotateLabels(values, turned, k, n, lineDegrees(src.center, tgt.center));
2587
+ }
2588
+ const edge = routeSettings(words, k, curves[k]);
2589
+ const bends = cyjsRoute(edge, src, tgt, loop ? nextLoopIndex(loops, graph.source[e], edge) : 0);
2590
+ if (bends !== null) {
2591
+ routed ??= values.bends ?? new Array<StyleValue | null>(n).fill(null);
2592
+ routed[k] = bends;
2593
+ columnOf(values, "curved", n)[k] = false;
2594
+ }
2595
+ if (!loop) {
2596
+ edgePorts(edge.curveStyle, [ends[0][k], ends[1][k]], [src, tgt], (p, port) => {
2597
+ columnOf(values, p, n)[k] = port;
2598
+ });
2599
+ }
2600
+ }
2601
+ if (routed !== null) {
2602
+ values.bends = routed;
2603
+ }
2604
+ }
2605
+
2606
+ /**
2607
+ * A node's geometry as the routes measure it: its center, its outer size (its border taken in), its box and whether
2608
+ * it is an ellipse.
2609
+ * @param el - the node
2610
+ * @param nodeAt - each node's output index
2611
+ * @param nodes - the nodes' values
2612
+ * @returns the geometry, or null when the node has no position
2613
+ */
2614
+ function routeNode(
2615
+ el: CyjsElement,
2616
+ nodeAt: ReadonlyMap<CyjsElement, number>,
2617
+ nodes: CyjsTargetStyles,
2618
+ ): CyjsRouteNode | null {
2619
+ const k = nodeAt.get(el);
2620
+ const pos = el.json.position;
2621
+ if (k === undefined || !isObject(pos) || typeof pos.x !== "number" || typeof pos.y !== "number") {
2622
+ return null;
2623
+ }
2624
+ const num = (p: string, fallback: number): number => {
2625
+ const v = nodes.values[p]?.[k];
2626
+ return typeof v === "number" ? v : fallback;
2627
+ };
2628
+ const [w, h, bw] = [num("width", 30), num("height", 30), num("borderWidth", 0)];
2629
+ return {
2630
+ center: [pos.x, pos.y],
2631
+ size: [w + bw, h + bw],
2632
+ box: [w, h],
2633
+ ellipse: (nodes.values.shape?.[k] ?? "ellipse") === "ellipse",
2634
+ };
2635
+ }
2636
+
2637
+ /**
2638
+ * An edge's two nodes' geometry, and whether it is a loop.
2639
+ * @param graph - the core's elements
2640
+ * @param e - the edge's core index, below 0 for none
2641
+ * @param geometry - a node's geometry
2642
+ * @returns the source's and the target's geometry, or null when either is not known
2643
+ */
2644
+ function edgeNodes(
2645
+ graph: CyjsGraph,
2646
+ e: number,
2647
+ geometry: (core: number) => CyjsRouteNode | null,
2648
+ ): { src: CyjsRouteNode; tgt: CyjsRouteNode; loop: boolean } | null {
2649
+ if (e < 0) {
2650
+ return null;
2651
+ }
2652
+ const loop = graph.source[e] === graph.target[e];
2653
+ const src = geometry(graph.source[e]);
2654
+ const tgt = loop ? src : geometry(graph.target[e]);
2655
+ return src === null || tgt === null ? null : { src, tgt, loop };
2656
+ }
2657
+
2658
+ /**
2659
+ * Turns each of an edge's labels set to `autorotate` along its line.
2660
+ * @param values - the edges' values; changed in place
2661
+ * @param turned - each label's rotation property and its `text-rotation` words
2662
+ * @param k - the edge's output index
2663
+ * @param n - the edge count
2664
+ * @param degrees - the line's turn
2665
+ */
2666
+ function autorotateLabels(
2667
+ values: Record<string, (StyleValue | null)[]>,
2668
+ turned: readonly (readonly [string, (StyleValue | null | undefined)[]])[],
2669
+ k: number,
2670
+ n: number,
2671
+ degrees: number,
2672
+ ): void {
2673
+ for (const [property, column] of turned) {
2674
+ if (column[k] === "autorotate") {
2675
+ columnOf(values, property, n)[k] = degrees;
2676
+ }
2677
+ }
2678
+ }
2679
+
2680
+ /**
2681
+ * A loop's place among the loops drawn before it on the same node in the same direction and sweep, which fans them.
2682
+ * @param loops - how many loops each node, direction and sweep has so far; changed in place
2683
+ * @param source - the loop's node
2684
+ * @param edge - the loop's settings
2685
+ * @returns its place, from 0
2686
+ */
2687
+ function nextLoopIndex(loops: Map<string, number>, source: number, edge: CyjsRouteEdge): number {
2688
+ const key = `${String(source)} ${String(edge.loopDirection)} ${String(edge.loopSweep)}`;
2689
+ const index = loops.get(key) ?? 0;
2690
+ loops.set(key, index + 1);
2691
+ return index;
2692
+ }
2693
+
2694
+ /**
2695
+ * Where an edge's ends meet its nodes, when not where the line from the centers crosses the outlines (cytoscape.js
2696
+ * 3.34.3 `findEndpoints`, `manualEndptToPx`): `inside-to-node` at the center, `x y` offsets from the center (pixels,
2697
+ * or percentages of the node's outer size), an angle clockwise from 12 o'clock on the outline. A `haystack` edge
2698
+ * runs between points `haystack-radius` of the way from the centers to the outlines in a random direction
2699
+ * (`findHaystackPoints`), drawn from the centers, where a radius of 0 (the default) puts them; a taxi edge ignores its
2700
+ * endpoints.
2701
+ * ponytail: an angle meets a polygon's outline where it meets its box; per-shape outlines if a file angles one
2702
+ * @param curve - the curve style
2703
+ * @param words - the source endpoint and the target endpoint, as Cytoscape.js spells them
2704
+ * @param nodes - the source's and the target's geometry
2705
+ * @param put - sets `sourcePort` or `targetPort`
2706
+ */
2707
+ function edgePorts(
2708
+ curve: string,
2709
+ words: readonly (StyleValue | null | undefined)[],
2710
+ nodes: readonly [CyjsRouteNode, CyjsRouteNode],
2711
+ put: (property: string, port: string) => void,
2712
+ ): void {
2713
+ if (curve === "taxi" || curve === "round-taxi") {
2714
+ return;
2715
+ }
2716
+ (["sourcePort", "targetPort"] as const).forEach((p, a) => {
2717
+ const port = curve === "haystack" ? "0,0" : endpointPort(String(words[a] ?? ""), nodes[a]);
2718
+ if (port !== null) {
2719
+ put(p, port);
2720
+ }
2721
+ });
2722
+ }
2723
+
2724
+ /**
2725
+ * One `source-endpoint` / `target-endpoint` as a neutral port.
2726
+ * @param text - the value
2727
+ * @param node - the node's geometry
2728
+ * @returns the port, or null where the line meets the outline as it does by default
2729
+ */
2730
+ function endpointPort(text: string, node: CyjsRouteNode): string | null {
2731
+ const t = text.trim();
2732
+ if (t === "inside-to-node") {
2733
+ return "0,0";
2734
+ }
2735
+ const parts = t.split(/\s+/);
2736
+ const [w, h] = node.size;
2737
+ const r6 = (v: number): string => String(Math.round(v * 1e6) / 1e6 + 0);
2738
+ const fraction = (part: string, size: number): number | null => {
2739
+ const m = /^(-?(?:\d+(?:\.\d*)?|\.\d+))(%|px)?$/.exec(part);
2740
+ if (m === null || Number.isNaN(size) || size <= 0) {
2741
+ return null;
2742
+ }
2743
+ const px = m[2] === "%" ? (Number(m[1]) / 100) * size : Number(m[1]);
2744
+ return px / (size / 2);
2745
+ };
2746
+ if (parts.length === 2) {
2747
+ const [x, y] = [fraction(parts[0], w), fraction(parts[1], h)];
2748
+ return x === null || y === null ? null : `${r6(x)},${r6(-y)}`;
2749
+ }
2750
+ const m = /^(-?(?:\d+(?:\.\d*)?|\.\d+))(deg|rad)$/.exec(t);
2751
+ if (m === null) {
2752
+ return null;
2753
+ }
2754
+ const turn = m[2] === "deg" ? (Number(m[1]) * Math.PI) / 180 : Number(m[1]);
2755
+ // the direction in half sizes, y up, from 12 o'clock clockwise; scaled until it meets the outline
2756
+ const [dx, dy] = [Math.sin(turn) / (w / 2), Math.cos(turn) / (h / 2)];
2757
+ const reach = node.ellipse ? Math.hypot(dx, dy) : Math.max(Math.abs(dx), Math.abs(dy));
2758
+ return reach > 0 ? `${r6(dx / reach)},${r6(dy / reach)}` : null;
2759
+ }
2760
+
2761
+ /**
2762
+ * One edge's routing settings.
2763
+ * @param words - each setting's values, in output order
2764
+ * @param k - the edge's output index
2765
+ * @param curve - its curve style
2766
+ * @returns the settings
2767
+ */
2768
+ function routeSettings(
2769
+ words: ReadonlyMap<keyof CyjsRouteEdge, readonly (StyleValue | null | undefined)[]>,
2770
+ k: number,
2771
+ curve: StyleValue | null | undefined,
2772
+ ): CyjsRouteEdge {
2773
+ const text = (key: keyof CyjsRouteEdge): string | null => {
2774
+ const v = words.get(key)?.[k];
2775
+ return v === null || v === undefined ? null : String(v);
2776
+ };
2777
+ const num = (key: keyof CyjsRouteEdge): number | null => {
2778
+ const v = text(key);
2779
+ return v === null ? null : Number(v);
2780
+ };
2781
+ return {
2782
+ curveStyle: String(curve ?? "haystack"),
2783
+ segmentDistances: text("segmentDistances"),
2784
+ segmentWeights: text("segmentWeights"),
2785
+ controlPointDistances: text("controlPointDistances"),
2786
+ controlPointWeights: text("controlPointWeights"),
2787
+ controlPointStepSize: num("controlPointStepSize"),
2788
+ taxiDirection: text("taxiDirection"),
2789
+ taxiTurn: text("taxiTurn"),
2790
+ taxiTurnMinDistance: num("taxiTurnMinDistance"),
2791
+ edgeDistances: text("edgeDistances"),
2792
+ loopDirection: text("loopDirection"),
2793
+ loopSweep: text("loopSweep"),
2794
+ segmentRadii: text("segmentRadii"),
2795
+ taxiRadius: text("taxiRadius"),
2796
+ radiusType: text("radiusType"),
2797
+ };
2798
+ }
2799
+
2800
+ /** A padding read as Cytoscape.js spells it. */
2801
+ const TEXT_PART: CyjsPropertySpec = { property: "_text", type: "text" };
2802
+
2803
+ /**
2804
+ * A node's size as Cytoscape.js draws it: a node that is no compound parent is drawn `padding` larger on every side
2805
+ * (cytoscape.js 3.34.3 draws its shape `width() + 2 * padding()` across).
2806
+ * @param graph - the core's elements
2807
+ * @param read - the nodes' cells
2808
+ * @param values - the nodes' values; changed in place
2809
+ */
2810
+ function nodeSizes(graph: CyjsGraph, read: DrawnRead, values: Record<string, (StyleValue | null)[]>): void {
2811
+ const padding = drawnColumn(read, "padding", TEXT_PART);
2812
+ const toLabel = (["width", "height"] as const).map((p) => drawnColumn(read, p, SIZE_PART));
2813
+ const n = read.order.length;
2814
+ const col = (p: string): (StyleValue | null)[] => (values[p] ??= new Array<StyleValue | null>(n).fill(null));
2815
+ for (let k = 0; k < n; k++) {
2816
+ const core = read.order[k];
2817
+ const pad = core < 0 || graph.children[core].length > 0 ? 0 : paddingOf(padding[k]);
2818
+ const fitted = toLabel.map((c) => c[k] === "label");
2819
+ if (fitted[0] || fitted[1]) {
2820
+ // `width: label` sizes the node to its label's box (cytoscape.js 3.34.3 `width()` reads the label's
2821
+ // width), padding on each side: the label's side is a minimum of 0, the other keeps its own size
2822
+ col("labelFit")[k] = "bounds";
2823
+ col("labelPaddingX")[k] = pad;
2824
+ col("labelPaddingY")[k] = pad;
2825
+ ["width", "height"].forEach((p, a) => {
2826
+ const v = values[p]?.[k];
2827
+ const side = typeof v === "number" ? v : 30;
2828
+ col(p)[k] = fitted[a] ? 0 : side + 2 * pad;
2829
+ });
2830
+ continue;
2831
+ }
2832
+ if (pad <= 0) {
2833
+ continue;
2834
+ }
2835
+ for (const p of ["width", "height"]) {
2836
+ const v = values[p]?.[k];
2837
+ col(p)[k] = (typeof v === "number" ? v : 30) + 2 * pad;
2838
+ }
2839
+ }
2840
+ }
2841
+
2842
+ /** The label alignments read as Cytoscape.js's words. */
2843
+ const VALIGN_PART: CyjsPropertySpec = {
2844
+ property: "_valign",
2845
+ type: "enum",
2846
+ enums: ["top", "top-inside", "center", "bottom", "bottom-inside"],
2847
+ };
2848
+ const HALIGN_PART: CyjsPropertySpec = {
2849
+ property: "_halign",
2850
+ type: "enum",
2851
+ enums: ["left", "left-inside", "center", "right", "right-inside"],
2852
+ };
2853
+
2854
+ /**
2855
+ * Where Cytoscape.js pins a label on one axis (cytoscape.js 3.34.3 `recalculateNodeLabelProjection` and
2856
+ * `labelHalign` / `labelValign`): outside, `padding` past the node's side with the label's far edge there; inside,
2857
+ * `padding` short of it with the label's near edge there; centered, at the node's middle.
2858
+ * @param align - the alignment (`left`, `left-inside`, `top`, ...)
2859
+ * @param half - half the node's drawn size on that axis, `padding` included
2860
+ * @param pad - the node's padding
2861
+ * @returns the offset from the node's center and the shift by the label's own size
2862
+ */
2863
+ function pinnedAxis(align: string, half: number, pad: number): { offset: number; shift: number } {
2864
+ const near = /^(left|top)/.test(align);
2865
+ if (!near && !/^(right|bottom)/.test(align)) {
2866
+ return { offset: 0, shift: 0 };
2867
+ }
2868
+ const side = near ? -1 : 1;
2869
+ return align.endsWith("-inside")
2870
+ ? { offset: side * (half - 2 * pad), shift: -side / 2 }
2871
+ : { offset: side * half, shift: side / 2 };
2872
+ }
2873
+
2874
+ /**
2875
+ * A node label with one alignment inside the node and the other outside it (`text-valign: bottom-inside` with
2876
+ * `text-halign: left`): no neutral position says that, so the label is centered, moved to the point Cytoscape.js
2877
+ * puts it at by `labelOffsetX` / `labelOffsetY` (its `text-margin` added) and pinned there by `labelShiftX` /
2878
+ * `labelShiftY`. A node sized to its label keeps the outside side's position, noted.
2879
+ * @param graph - the core's elements
2880
+ * @param read - the nodes' cells
2881
+ * @param values - the nodes' values, sizes already drawn (`nodeSizes`); changed in place
2882
+ */
2883
+ function mixedLabelPlaces(graph: CyjsGraph, read: DrawnRead, values: Record<string, (StyleValue | null)[]>): void {
2884
+ const va = drawnColumn(read, "text-valign", VALIGN_PART);
2885
+ const ha = drawnColumn(read, "text-halign", HALIGN_PART);
2886
+ const padding = drawnColumn(read, "padding", TEXT_PART);
2887
+ const n = read.order.length;
2888
+ const col = (p: string): (StyleValue | null)[] => (values[p] ??= new Array<StyleValue | null>(n).fill(null));
2889
+ for (let k = 0; k < n; k++) {
2890
+ const v = typeof va[k] === "string" ? String(va[k]) : "top";
2891
+ const h = typeof ha[k] === "string" ? String(ha[k]) : "center";
2892
+ const inside = v.endsWith("-inside") || h.endsWith("-inside");
2893
+ const outside = v === "top" || v === "bottom" || h === "left" || h === "right";
2894
+ if (!inside || !outside) {
2895
+ continue;
2896
+ }
2897
+ if (values.labelFit?.[k] !== undefined && values.labelFit[k] !== null) {
2898
+ read.notes.add(STYLE_ISSUE.APPROXIMATED, "node", "labelPosition", { sample: `${v} ${h}`, element: k });
2899
+ continue;
2900
+ }
2901
+ const core = read.order[k];
2902
+ const pad = core < 0 || graph.children[core].length > 0 ? 0 : paddingOf(padding[k]);
2903
+ const size = (p: string): number => {
2904
+ const s = values[p]?.[k];
2905
+ return typeof s === "number" ? s : 30 + 2 * pad;
2906
+ };
2907
+ const x = pinnedAxis(h, size("width") / 2, pad);
2908
+ const y = pinnedAxis(v, size("height") / 2, pad);
2909
+ const add = (p: string, d: number): void => {
2910
+ const was = values[p]?.[k];
2911
+ col(p)[k] = (typeof was === "number" ? was : 0) + d;
2912
+ };
2913
+ col("labelPosition")[k] = "center";
2914
+ add("labelOffsetX", x.offset);
2915
+ add("labelOffsetY", y.offset);
2916
+ col("labelShiftX")[k] = x.shift;
2917
+ col("labelShiftY")[k] = y.shift;
2918
+ }
2919
+ }
2920
+
2921
+ /** A node size read as Cytoscape.js's word, so `label` is seen. */
2922
+ const SIZE_PART: CyjsPropertySpec = { property: "_size", type: "nodeSize" };
2923
+
2924
+ /**
2925
+ * A node's padding in pixels. A percentage is relative only on a compound parent; on any other node Cytoscape.js
2926
+ * draws its fraction as pixels (`padding()` returns the property's `pfValue`, 0.2 for `20%`).
2927
+ * @param text - the padding as Cytoscape.js spells it, or null
2928
+ * @returns the pixels, 0 for none
2929
+ */
2930
+ function paddingOf(text: StyleValue | null | undefined): number {
2931
+ if (typeof text !== "string") {
2932
+ return 0;
2933
+ }
2934
+ const x = Number.parseFloat(text);
2935
+ if (!Number.isFinite(x) || x <= 0) {
2936
+ return 0;
2937
+ }
2938
+ return text.trim().endsWith("%") ? x / 100 : x;
2939
+ }
2940
+
2941
+ /** The curve style read as Cytoscape.js's word. */
2942
+ const CURVE_PART: CyjsPropertySpec = { property: "_curve", type: "enum", enums: CYJS_CURVE_STYLES };
2943
+
2944
+ /**
2945
+ * Cytoscape.js draws no source or target arrow on a `haystack` edge, its default curve style (cytoscape.js 3.34.3
2946
+ * `drawArrowheads` skips them on haystacks, but still draws the mid arrows): each end arrow of one is `none`.
2947
+ * @param curves - each edge's curve style, null where no rule sets it
2948
+ * @param values - the values; changed in place
2949
+ */
2950
+ function noArrowsOnHaystacks(
2951
+ curves: readonly (StyleValue | null | undefined)[],
2952
+ values: Record<string, (StyleValue | null)[]>,
2953
+ ): void {
2954
+ const n = curves.length;
2955
+ for (const p of ["targetArrow", "sourceArrow"]) {
2956
+ const col = values[p];
2957
+ if (col === undefined) {
2958
+ continue;
2959
+ }
1890
2960
  for (let i = 0; i < n; i++) {
1891
- const a = vis?.[i] ?? null;
1892
- const b = disp?.[i] ?? null;
1893
- if (a === null && b === null) {
2961
+ if ((curves[i] ?? "haystack") === "haystack" && col[i] !== null) {
2962
+ col[i] = "none";
2963
+ }
2964
+ }
2965
+ }
2966
+ }
2967
+
2968
+ /**
2969
+ * The outline arrow a hollow `*-arrow-fill` draws for each filled shape that has one (cytoscape.js 3.34.3 strokes the
2970
+ * arrow's path instead of filling it). A hollow square has no outline cap of its own in the neutral vocabulary;
2971
+ * `other:open-square` is drawn as the nearest one.
2972
+ */
2973
+ const HOLLOW_ARROWS: ReadonlyMap<StyleValue, string> = new Map([
2974
+ ["triangle", "triangle-open"],
2975
+ ["diamond", "diamond-open"],
2976
+ ["circle", "circle-open"],
2977
+ ["square", "other:open-square"],
2978
+ ]);
2979
+
2980
+ /**
2981
+ * A rule that sets an arrow shape and makes it hollow sets the outline shape (`combineArrowFills` does the same per
2982
+ * element, for a fill and a shape set by different rules).
2983
+ * @param set - the rule's values; changed in place
2984
+ * @param all - every property of the rule
2985
+ */
2986
+ function hollowArrowsOfRule(set: Record<string, StyleValue>, all: readonly EntryProperty[]): void {
2987
+ for (const p of all) {
2988
+ const shapeProp = /^_(\w+Arrow)Fill$/.exec(p.spec.property)?.[1];
2989
+ const shape = shapeProp === undefined ? undefined : set[shapeProp];
2990
+ if (shapeProp === undefined || shape === undefined || p.parsed.kind !== "word") {
2991
+ continue;
2992
+ }
2993
+ const open = HOLLOW_ARROWS.get(shape);
2994
+ if (open !== undefined && p.parsed.value === "hollow") {
2995
+ set[shapeProp] = open;
2996
+ }
2997
+ }
2998
+ }
2999
+
3000
+ /**
3001
+ * Turns each arrow whose `*-arrow-fill` is `hollow` into its outline shape. A hollow arrow the vocabulary has no
3002
+ * outline shape for keeps its filled shape and is noted.
3003
+ * @param n - the element count
3004
+ * @param words - the parts by internal name
3005
+ * @param values - the values; changed in place
3006
+ * @param notes - where a hollow arrow drawn filled is noted
3007
+ */
3008
+ function combineArrowFills(
3009
+ n: number,
3010
+ words: ReadonlyMap<string, (string | null)[]>,
3011
+ values: Record<string, (StyleValue | null)[]>,
3012
+ notes: StyleNotes,
3013
+ ): void {
3014
+ for (const p of ["targetArrow", "sourceArrow", "midTargetArrow", "midSourceArrow"]) {
3015
+ const fill = words.get(`_${p}Fill`);
3016
+ const shapes = values[p];
3017
+ if (fill === undefined || shapes === undefined) {
3018
+ continue;
3019
+ }
3020
+ for (let i = 0; i < n; i++) {
3021
+ const shape = shapes[i];
3022
+ if (fill[i] !== "hollow" || shape === null || shape === "none") {
1894
3023
  continue;
1895
3024
  }
1896
- col[i] = a !== "hidden" && b !== "none";
3025
+ const open = HOLLOW_ARROWS.get(shape);
3026
+ if (open !== undefined) {
3027
+ shapes[i] = open;
3028
+ } else if (!String(shape).includes("open")) {
3029
+ const property = p.replaceAll(/[A-Z]/g, (c) => `-${c.toLowerCase()}`).replace("-arrow", "-arrow-fill");
3030
+ notes.add(STYLE_ISSUE.NOT_CARRIED, "edge", property, { sample: `hollow ${String(shape)}`, element: i });
3031
+ }
1897
3032
  }
1898
- values.visible = col;
1899
3033
  }
1900
3034
  }
1901
3035
 
1902
3036
  /**
1903
- * A node label's position from its vertical and horizontal alignments; an `-inside` alignment is read as its
1904
- * outside one, noted.
3037
+ * A node label's position from its vertical and horizontal alignments. Cytoscape.js 3.34 places an `-inside`
3038
+ * alignment against that side of the node, inside it (`recalculateNodeLabelProjection`): `top-inside` with
3039
+ * `center` is `inside-top`, `top-inside` with `left-inside` is `inside-top-left`. One inside and one outside
3040
+ * alignment have no neutral position of their own: the outside side here, its inside part read as centered, which
3041
+ * `mixedLabelPlaces()` replaces with the pinned place once the node's size is known.
1905
3042
  * @param v - the vertical alignment, or null
1906
3043
  * @param h - the horizontal alignment, or null
1907
- * @param note - notes an alignment read as another
1908
3044
  * @returns the position, or null
1909
3045
  */
1910
- function labelPosition(v: string | null, h: string | null, note: (sample: string) => void): StyleValue | null {
3046
+ function labelPosition(v: string | null, h: string | null): StyleValue | null {
1911
3047
  if (v === null && h === null) {
1912
3048
  return null;
1913
3049
  }
3050
+ const vIn = (v ?? "").endsWith("-inside");
3051
+ const hIn = (h ?? "").endsWith("-inside");
1914
3052
  const vv = (v ?? "top").replace("-inside", "");
1915
3053
  const hh = (h ?? "center").replace("-inside", "");
1916
- if ((v ?? "").endsWith("-inside") || (h ?? "").endsWith("-inside")) {
1917
- note(`${v ?? ""} ${h ?? ""}`);
3054
+ if (vIn || hIn) {
3055
+ const vOut = vv !== "center" && !vIn;
3056
+ const hOut = hh !== "center" && !hIn;
3057
+ if (!vOut && !hOut) {
3058
+ return INSIDE_POSITIONS.get(`${vv},${hh}`) ?? null;
3059
+ }
3060
+ return POSITIONS.get(`${vIn ? "center" : vv},${hIn ? "center" : hh}`) ?? null;
1918
3061
  }
1919
3062
  return POSITIONS.get(`${vv},${hh}`) ?? null;
1920
3063
  }
@@ -1973,7 +3116,7 @@ function buildRules(
1973
3116
  if (props.length === 0 || a.list.length === 0) {
1974
3117
  continue;
1975
3118
  }
1976
- drafts.push(draftOf(ctx, a.entry, a.list, props));
3119
+ drafts.push(draftOf(ctx, a.entry, a.list, props, a.props));
1977
3120
  }
1978
3121
  const rules = collapse(ctx, drafts);
1979
3122
  return { rules, columns, rawColumns: [...raw] };
@@ -2020,9 +3163,16 @@ interface Draft {
2020
3163
  * @param entry - the entry
2021
3164
  * @param list - the matched core elements
2022
3165
  * @param props - the carried properties
3166
+ * @param all - every property of the entry, the parts combined afterward too
2023
3167
  * @returns the draft
2024
3168
  */
2025
- function draftOf(ctx: RuleContext, entry: Entry, list: readonly number[], props: readonly EntryProperty[]): Draft {
3169
+ function draftOf(
3170
+ ctx: RuleContext,
3171
+ entry: Entry,
3172
+ list: readonly number[],
3173
+ props: readonly EntryProperty[],
3174
+ all: readonly EntryProperty[],
3175
+ ): Draft {
2026
3176
  const setting = new Map<string, StyleValue>();
2027
3177
  const mapping = new Map<string, Mapping>();
2028
3178
  let flattened = false;
@@ -2053,7 +3203,12 @@ function draftOf(ctx: RuleContext, entry: Entry, list: readonly number[], props:
2053
3203
  mapping.set(p.spec.property, mapperMapping(ctx, entry, list, p));
2054
3204
  }
2055
3205
  }
2056
- const set = Object.fromEntries(setting);
3206
+ const set: Record<string, StyleValue> = Object.fromEntries(setting);
3207
+ if (ctx.kind === "node") {
3208
+ cyjsPolygonShapes(set);
3209
+ } else {
3210
+ hollowArrowsOfRule(set, all);
3211
+ }
2057
3212
  const map = Object.fromEntries(mapping);
2058
3213
  const hasMap = mapping.size > 0;
2059
3214
  // the predicate is built only for a rule that is not collapsed into a run: a run's rules need no column each