@graphty/graph-io 0.3.48 → 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 (570) hide show
  1. package/dist/chunks/{approximations-C2riR4NT.js → approximations-Bzn3L-je.js} +2 -2
  2. package/dist/chunks/{approximations-C2riR4NT.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-Cu22ewuS.js → block-iptrlMBb.js} +906 -164
  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-CV_Bhcyi.js → codes-BE2xir2k.js} +6 -2
  10. package/dist/chunks/codes-BE2xir2k.js.map +1 -0
  11. package/dist/chunks/{constants-D0LqcsLJ.js → constants-CKkYLPtt.js} +2 -2
  12. package/dist/chunks/{constants-D0LqcsLJ.js.map → constants-CKkYLPtt.js.map} +1 -1
  13. package/dist/chunks/{context-cgmmOxZ2.js → context-C3p0RQxR.js} +5 -4
  14. package/dist/chunks/{context-cgmmOxZ2.js.map → context-C3p0RQxR.js.map} +1 -1
  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-BiQsnMTb.js → credentials-DXHx7nwR.js} +16 -14
  18. package/dist/chunks/credentials-DXHx7nwR.js.map +1 -0
  19. package/dist/chunks/{cx-export-BEeF6ymo.js → cx-export-Bt6NoqTQ.js} +3 -3
  20. package/dist/chunks/{cx-export-BEeF6ymo.js.map → cx-export-Bt6NoqTQ.js.map} +1 -1
  21. package/dist/chunks/descriptor-B28U25x4.js +60 -0
  22. package/dist/chunks/descriptor-B28U25x4.js.map +1 -0
  23. package/dist/chunks/{descriptor-BJ-W0Jd-.js → descriptor-DLA5kINx.js} +7 -2
  24. package/dist/chunks/descriptor-DLA5kINx.js.map +1 -0
  25. package/dist/chunks/{emit-CD8xnY8s.js → emit-BwHQkZle.js} +1660 -133
  26. package/dist/chunks/emit-BwHQkZle.js.map +1 -0
  27. package/dist/chunks/{escape-DH2Egt-l.js → escape-CuCIzNMB.js} +8 -8
  28. package/dist/chunks/{escape-DH2Egt-l.js.map → escape-CuCIzNMB.js.map} +1 -1
  29. package/dist/chunks/{export-CZ7VRm4I.js → export-Cha4dRFz.js} +45 -387
  30. package/dist/chunks/export-Cha4dRFz.js.map +1 -0
  31. package/dist/chunks/{exporter-Dcw7Ldtq.js → exporter-BP6otMO6.js} +6 -6
  32. package/dist/chunks/{exporter-Dcw7Ldtq.js.map → exporter-BP6otMO6.js.map} +1 -1
  33. package/dist/chunks/{exporter-bxxjOrDZ.js → exporter-D2CETOMK.js} +1222 -156
  34. package/dist/chunks/exporter-D2CETOMK.js.map +1 -0
  35. package/dist/chunks/{exporter-BIdaoIgh.js → exporter-D9yMtocA.js} +7 -7
  36. package/dist/chunks/{exporter-BIdaoIgh.js.map → exporter-D9yMtocA.js.map} +1 -1
  37. package/dist/chunks/{exporter-DtVU80Fa.js → exporter-_jrBTnos.js} +9 -8
  38. package/dist/chunks/{exporter-DtVU80Fa.js.map → exporter-_jrBTnos.js.map} +1 -1
  39. package/dist/chunks/{exporter-ChjL5fmP.js → exporter-nDfxIK5D.js} +9 -8
  40. package/dist/chunks/{exporter-ChjL5fmP.js.map → exporter-nDfxIK5D.js.map} +1 -1
  41. package/dist/chunks/format-BXiAb-1h.js +408 -0
  42. package/dist/chunks/format-BXiAb-1h.js.map +1 -0
  43. package/dist/chunks/{generic-CP6YD34u.js → generic-ymWCETAJ.js} +387 -31
  44. package/dist/chunks/generic-ymWCETAJ.js.map +1 -0
  45. package/dist/chunks/{importer-e3huMZbm.js → importer-B92x1xY5.js} +14 -10
  46. package/dist/chunks/importer-B92x1xY5.js.map +1 -0
  47. package/dist/chunks/{importer-B87_fmVx.js → importer-CT9mJ1nn.js} +326 -84
  48. package/dist/chunks/importer-CT9mJ1nn.js.map +1 -0
  49. package/dist/chunks/{importer-CB_zV5_L.js → importer-DaLTjbds.js} +116 -1102
  50. package/dist/chunks/importer-DaLTjbds.js.map +1 -0
  51. package/dist/chunks/{importer-DPZDN40-.js → importer-GREKMdIf.js} +25 -17
  52. package/dist/chunks/importer-GREKMdIf.js.map +1 -0
  53. package/dist/chunks/{importer-Bji2MeWr.js → importer-PqaaKKnY.js} +13 -10
  54. package/dist/chunks/{importer-Bji2MeWr.js.map → importer-PqaaKKnY.js.map} +1 -1
  55. package/dist/chunks/{importer-Cyy6UseH.js → importer-Vn5QvmmJ.js} +66 -13
  56. package/dist/chunks/importer-Vn5QvmmJ.js.map +1 -0
  57. package/dist/chunks/{importer-CVT-JyDE.js → importer-vRq4h3j5.js} +1469 -356
  58. package/dist/chunks/importer-vRq4h3j5.js.map +1 -0
  59. package/dist/chunks/{input-Ccg9I22A.js → input-CAxt_aV-.js} +4 -4
  60. package/dist/chunks/{input-Ccg9I22A.js.map → input-CAxt_aV-.js.map} +1 -1
  61. package/dist/chunks/{json-elements-By172SVq.js → json-elements-Cq76WjnZ.js} +4 -4
  62. package/dist/chunks/{json-elements-By172SVq.js.map → json-elements-Cq76WjnZ.js.map} +1 -1
  63. package/dist/chunks/{lexicon-u2SI5xcx.js → lexicon-Clf4QIyl.js} +282 -74
  64. package/dist/chunks/lexicon-Clf4QIyl.js.map +1 -0
  65. package/dist/chunks/{ontology-export-BwgMyuF0.js → ontology-export-OMo91mb0.js} +4 -4
  66. package/dist/chunks/{ontology-export-BwgMyuF0.js.map → ontology-export-OMo91mb0.js.map} +1 -1
  67. package/dist/chunks/{records-Cgvxz-Vx.js → records-NJiYvekn.js} +2 -2
  68. package/dist/chunks/{records-Cgvxz-Vx.js.map → records-NJiYvekn.js.map} +1 -1
  69. package/dist/chunks/{report-CgdsL9Hb.js → report-CwMfYa9J.js} +23 -23
  70. package/dist/chunks/{report-CgdsL9Hb.js.map → report-CwMfYa9J.js.map} +1 -1
  71. package/dist/chunks/round-trip-Zm3_ivgq.js +79 -0
  72. package/dist/chunks/round-trip-Zm3_ivgq.js.map +1 -0
  73. package/dist/chunks/{sigv4-LkAzsLAu.js → sigv4-EokFic1V.js} +5 -5
  74. package/dist/chunks/sigv4-EokFic1V.js.map +1 -0
  75. package/dist/chunks/{styles-CaABMoO1.js → styles-CCs214_3.js} +1237 -138
  76. package/dist/chunks/styles-CCs214_3.js.map +1 -0
  77. package/dist/chunks/styles-Cm62yyQX.js +2812 -0
  78. package/dist/chunks/styles-Cm62yyQX.js.map +1 -0
  79. package/dist/chunks/styles-DPQQIig4.js +1928 -0
  80. package/dist/chunks/styles-DPQQIig4.js.map +1 -0
  81. package/dist/chunks/{styles-yed-Cs1nmrjn.js → styles-yed-UMFdNqze.js} +503 -172
  82. package/dist/chunks/styles-yed-UMFdNqze.js.map +1 -0
  83. package/dist/chunks/{text-BuKQVMz2.js → text-ystE2bYi.js} +2 -2
  84. package/dist/chunks/{text-BuKQVMz2.js.map → text-ystE2bYi.js.map} +1 -1
  85. package/dist/csv.js +7 -7
  86. package/dist/cx.js +2 -2
  87. package/dist/cx2.js +2 -2
  88. package/dist/cys.js +1 -1
  89. package/dist/dot.js +5 -4
  90. package/dist/dot.js.map +1 -1
  91. package/dist/gexf.js +42 -12
  92. package/dist/gexf.js.map +1 -1
  93. package/dist/gml.js +847 -193
  94. package/dist/gml.js.map +1 -1
  95. package/dist/graph-io.js +232 -220
  96. package/dist/graph-io.js.map +1 -1
  97. package/dist/graphml.js +3 -3
  98. package/dist/json.js +3 -2
  99. package/dist/neo4j.js +6 -6
  100. package/dist/obo.js +1 -1
  101. package/dist/pajek.js +1 -1
  102. package/dist/positions.js +45 -3
  103. package/dist/positions.js.map +1 -1
  104. package/dist/sources-cypher.js +138 -23
  105. package/dist/sources-cypher.js.map +1 -1
  106. package/dist/sources-ndex.js +2 -2
  107. package/dist/sources-rest.js +16 -6
  108. package/dist/sources-rest.js.map +1 -1
  109. package/dist/sources-sparql.d.ts +1 -0
  110. package/dist/sources-sparql.js +405 -0
  111. package/dist/sources-sparql.js.map +1 -0
  112. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  113. package/dist/src/formats/cx/importer.js +5 -1
  114. package/dist/src/formats/cx/importer.js.map +1 -1
  115. package/dist/src/formats/cx/styles.d.ts +24 -1
  116. package/dist/src/formats/cx/styles.d.ts.map +1 -1
  117. package/dist/src/formats/cx/styles.js +117 -11
  118. package/dist/src/formats/cx/styles.js.map +1 -1
  119. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  120. package/dist/src/formats/cx2/importer.js +1 -0
  121. package/dist/src/formats/cx2/importer.js.map +1 -1
  122. package/dist/src/formats/cx2/styles.d.ts.map +1 -1
  123. package/dist/src/formats/cx2/styles.js +3 -1
  124. package/dist/src/formats/cx2/styles.js.map +1 -1
  125. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cys/importer.js +1 -0
  127. package/dist/src/formats/cys/importer.js.map +1 -1
  128. package/dist/src/formats/cys/styles.d.ts +2 -0
  129. package/dist/src/formats/cys/styles.d.ts.map +1 -1
  130. package/dist/src/formats/cys/styles.js +15 -7
  131. package/dist/src/formats/cys/styles.js.map +1 -1
  132. package/dist/src/formats/dot/drawing.d.ts +98 -0
  133. package/dist/src/formats/dot/drawing.d.ts.map +1 -0
  134. package/dist/src/formats/dot/drawing.js +734 -0
  135. package/dist/src/formats/dot/drawing.js.map +1 -0
  136. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  137. package/dist/src/formats/dot/importer.js +108 -31
  138. package/dist/src/formats/dot/importer.js.map +1 -1
  139. package/dist/src/formats/dot/label-places.d.ts +34 -0
  140. package/dist/src/formats/dot/label-places.d.ts.map +1 -0
  141. package/dist/src/formats/dot/label-places.js +179 -0
  142. package/dist/src/formats/dot/label-places.js.map +1 -0
  143. package/dist/src/formats/dot/record.d.ts +50 -0
  144. package/dist/src/formats/dot/record.d.ts.map +1 -0
  145. package/dist/src/formats/dot/record.js +275 -0
  146. package/dist/src/formats/dot/record.js.map +1 -0
  147. package/dist/src/formats/dot/styles.d.ts +62 -2
  148. package/dist/src/formats/dot/styles.d.ts.map +1 -1
  149. package/dist/src/formats/dot/styles.js +1454 -119
  150. package/dist/src/formats/dot/styles.js.map +1 -1
  151. package/dist/src/formats/gexf/dialog-metrics.d.ts +15 -0
  152. package/dist/src/formats/gexf/dialog-metrics.d.ts.map +1 -0
  153. package/dist/src/formats/gexf/dialog-metrics.js +59 -0
  154. package/dist/src/formats/gexf/dialog-metrics.js.map +1 -0
  155. package/dist/src/formats/gexf/importer.d.ts +7 -0
  156. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  157. package/dist/src/formats/gexf/importer.js +41 -5
  158. package/dist/src/formats/gexf/importer.js.map +1 -1
  159. package/dist/src/formats/gexf/preview.d.ts +77 -0
  160. package/dist/src/formats/gexf/preview.d.ts.map +1 -0
  161. package/dist/src/formats/gexf/preview.js +191 -0
  162. package/dist/src/formats/gexf/preview.js.map +1 -0
  163. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  164. package/dist/src/formats/gexf/schema.js +2 -1
  165. package/dist/src/formats/gexf/schema.js.map +1 -1
  166. package/dist/src/formats/gexf/styles.d.ts +58 -31
  167. package/dist/src/formats/gexf/styles.d.ts.map +1 -1
  168. package/dist/src/formats/gexf/styles.js +848 -225
  169. package/dist/src/formats/gexf/styles.js.map +1 -1
  170. package/dist/src/formats/gml/importer.d.ts +5 -2
  171. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  172. package/dist/src/formats/gml/importer.js +258 -71
  173. package/dist/src/formats/gml/importer.js.map +1 -1
  174. package/dist/src/formats/gml/index.d.ts +1 -1
  175. package/dist/src/formats/gml/index.d.ts.map +1 -1
  176. package/dist/src/formats/gml/index.js +1 -1
  177. package/dist/src/formats/gml/index.js.map +1 -1
  178. package/dist/src/formats/gml/positions.d.ts +7 -0
  179. package/dist/src/formats/gml/positions.d.ts.map +1 -1
  180. package/dist/src/formats/gml/positions.js +29 -7
  181. package/dist/src/formats/gml/positions.js.map +1 -1
  182. package/dist/src/formats/gml/styles.d.ts.map +1 -1
  183. package/dist/src/formats/gml/styles.js +753 -101
  184. package/dist/src/formats/gml/styles.js.map +1 -1
  185. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
  186. package/dist/src/formats/graphml/styles-plain.js +6 -10
  187. package/dist/src/formats/graphml/styles-plain.js.map +1 -1
  188. package/dist/src/formats/graphml/styles-yed.d.ts +21 -15
  189. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
  190. package/dist/src/formats/graphml/styles-yed.js +692 -161
  191. package/dist/src/formats/graphml/styles-yed.js.map +1 -1
  192. package/dist/src/formats/graphml/styles-yfiles3.d.ts +1 -1
  193. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -1
  194. package/dist/src/formats/graphml/styles-yfiles3.js +429 -64
  195. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -1
  196. package/dist/src/formats/graphml/yfiles.d.ts +3 -3
  197. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  198. package/dist/src/formats/graphml/yfiles.js +16 -6
  199. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  200. package/dist/src/formats/json/dialect.d.ts +3 -2
  201. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  202. package/dist/src/formats/json/dialect.js +39 -5
  203. package/dist/src/formats/json/dialect.js.map +1 -1
  204. package/dist/src/formats/json/importer.d.ts +13 -2
  205. package/dist/src/formats/json/importer.d.ts.map +1 -1
  206. package/dist/src/formats/json/importer.js +42 -6
  207. package/dist/src/formats/json/importer.js.map +1 -1
  208. package/dist/src/formats/json/index.d.ts +1 -1
  209. package/dist/src/formats/json/index.d.ts.map +1 -1
  210. package/dist/src/formats/json/index.js +1 -1
  211. package/dist/src/formats/json/index.js.map +1 -1
  212. package/dist/src/formats/json/positions.d.ts +5 -2
  213. package/dist/src/formats/json/positions.d.ts.map +1 -1
  214. package/dist/src/formats/json/positions.js +20 -4
  215. package/dist/src/formats/json/positions.js.map +1 -1
  216. package/dist/src/formats/json/styles.d.ts +12 -1
  217. package/dist/src/formats/json/styles.d.ts.map +1 -1
  218. package/dist/src/formats/json/styles.js +1755 -136
  219. package/dist/src/formats/json/styles.js.map +1 -1
  220. package/dist/src/formats/pajek/draw.d.ts +96 -0
  221. package/dist/src/formats/pajek/draw.d.ts.map +1 -0
  222. package/dist/src/formats/pajek/draw.js +372 -0
  223. package/dist/src/formats/pajek/draw.js.map +1 -0
  224. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  225. package/dist/src/formats/pajek/exporter.js +70 -51
  226. package/dist/src/formats/pajek/exporter.js.map +1 -1
  227. package/dist/src/formats/pajek/importer.d.ts +9 -0
  228. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  229. package/dist/src/formats/pajek/importer.js +233 -102
  230. package/dist/src/formats/pajek/importer.js.map +1 -1
  231. package/dist/src/formats/pajek/index.d.ts +1 -0
  232. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  233. package/dist/src/formats/pajek/index.js.map +1 -1
  234. package/dist/src/formats/pajek/styles.d.ts +15 -7
  235. package/dist/src/formats/pajek/styles.d.ts.map +1 -1
  236. package/dist/src/formats/pajek/styles.js +1278 -114
  237. package/dist/src/formats/pajek/styles.js.map +1 -1
  238. package/dist/src/formats/pajek/syntax.d.ts +10 -1
  239. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  240. package/dist/src/formats/pajek/syntax.js +26 -2
  241. package/dist/src/formats/pajek/syntax.js.map +1 -1
  242. package/dist/src/formats/xgmml/emit.d.ts +1 -0
  243. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  244. package/dist/src/formats/xgmml/emit.js +65 -5
  245. package/dist/src/formats/xgmml/emit.js.map +1 -1
  246. package/dist/src/formats/xgmml/styles.d.ts +23 -3
  247. package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
  248. package/dist/src/formats/xgmml/styles.js +277 -60
  249. package/dist/src/formats/xgmml/styles.js.map +1 -1
  250. package/dist/src/index.d.ts +4 -3
  251. package/dist/src/index.d.ts.map +1 -1
  252. package/dist/src/index.js +4 -3
  253. package/dist/src/index.js.map +1 -1
  254. package/dist/src/positions/convert.d.ts.map +1 -1
  255. package/dist/src/positions/convert.js +11 -1
  256. package/dist/src/positions/convert.js.map +1 -1
  257. package/dist/src/positions/extract.d.ts.map +1 -1
  258. package/dist/src/positions/extract.js +53 -1
  259. package/dist/src/positions/extract.js.map +1 -1
  260. package/dist/src/positions/index.d.ts +1 -1
  261. package/dist/src/positions/index.d.ts.map +1 -1
  262. package/dist/src/positions/types.d.ts +59 -0
  263. package/dist/src/positions/types.d.ts.map +1 -1
  264. package/dist/src/sources/builtins.d.ts +1 -1
  265. package/dist/src/sources/builtins.d.ts.map +1 -1
  266. package/dist/src/sources/builtins.js +8 -2
  267. package/dist/src/sources/builtins.js.map +1 -1
  268. package/dist/src/sources/context.d.ts.map +1 -1
  269. package/dist/src/sources/context.js +1 -0
  270. package/dist/src/sources/context.js.map +1 -1
  271. package/dist/src/sources/cypher/descriptor.d.ts.map +1 -1
  272. package/dist/src/sources/cypher/descriptor.js +5 -0
  273. package/dist/src/sources/cypher/descriptor.js.map +1 -1
  274. package/dist/src/sources/cypher/index.d.ts.map +1 -1
  275. package/dist/src/sources/cypher/index.js +124 -18
  276. package/dist/src/sources/cypher/index.js.map +1 -1
  277. package/dist/src/sources/cypher/params.d.ts +1 -1
  278. package/dist/src/sources/cypher/params.d.ts.map +1 -1
  279. package/dist/src/sources/cypher/query-builder.d.ts +17 -0
  280. package/dist/src/sources/cypher/query-builder.d.ts.map +1 -1
  281. package/dist/src/sources/cypher/query-builder.js +31 -0
  282. package/dist/src/sources/cypher/query-builder.js.map +1 -1
  283. package/dist/src/sources/ids.d.ts +5 -0
  284. package/dist/src/sources/ids.d.ts.map +1 -1
  285. package/dist/src/sources/ids.js +5 -0
  286. package/dist/src/sources/ids.js.map +1 -1
  287. package/dist/src/sources/params.d.ts +3 -0
  288. package/dist/src/sources/params.d.ts.map +1 -1
  289. package/dist/src/sources/rest/descriptor.d.ts.map +1 -1
  290. package/dist/src/sources/rest/descriptor.js +5 -0
  291. package/dist/src/sources/rest/descriptor.js.map +1 -1
  292. package/dist/src/sources/rest/source.d.ts.map +1 -1
  293. package/dist/src/sources/rest/source.js +15 -0
  294. package/dist/src/sources/rest/source.js.map +1 -1
  295. package/dist/src/sources/sigv4.d.ts +5 -3
  296. package/dist/src/sources/sigv4.d.ts.map +1 -1
  297. package/dist/src/sources/sigv4.js +6 -4
  298. package/dist/src/sources/sigv4.js.map +1 -1
  299. package/dist/src/sources/sparql/descriptor.d.ts +10 -0
  300. package/dist/src/sources/sparql/descriptor.d.ts.map +1 -0
  301. package/dist/src/sources/sparql/descriptor.js +64 -0
  302. package/dist/src/sources/sparql/descriptor.js.map +1 -0
  303. package/dist/src/sources/sparql/index.d.ts +28 -0
  304. package/dist/src/sources/sparql/index.d.ts.map +1 -0
  305. package/dist/src/sources/sparql/index.js +314 -0
  306. package/dist/src/sources/sparql/index.js.map +1 -0
  307. package/dist/src/sources/sparql/ntriples.d.ts +69 -0
  308. package/dist/src/sources/sparql/ntriples.d.ts.map +1 -0
  309. package/dist/src/sources/sparql/ntriples.js +180 -0
  310. package/dist/src/sources/sparql/ntriples.js.map +1 -0
  311. package/dist/src/sources/sparql/params.d.ts +27 -0
  312. package/dist/src/sources/sparql/params.d.ts.map +1 -0
  313. package/dist/src/sources/sparql/params.js +5 -0
  314. package/dist/src/sources/sparql/params.js.map +1 -0
  315. package/dist/src/sources/sparql/query.d.ts +72 -0
  316. package/dist/src/sources/sparql/query.d.ts.map +1 -0
  317. package/dist/src/sources/sparql/query.js +113 -0
  318. package/dist/src/sources/sparql/query.js.map +1 -0
  319. package/dist/src/sources/types.d.ts +31 -0
  320. package/dist/src/sources/types.d.ts.map +1 -1
  321. package/dist/src/styles/annotations.d.ts +61 -5
  322. package/dist/src/styles/annotations.d.ts.map +1 -1
  323. package/dist/src/styles/annotations.js +130 -22
  324. package/dist/src/styles/annotations.js.map +1 -1
  325. package/dist/src/styles/canon/bends.d.ts +46 -0
  326. package/dist/src/styles/canon/bends.d.ts.map +1 -1
  327. package/dist/src/styles/canon/bends.js +123 -0
  328. package/dist/src/styles/canon/bends.js.map +1 -1
  329. package/dist/src/styles/canon/color-tables.d.ts +6 -1
  330. package/dist/src/styles/canon/color-tables.d.ts.map +1 -1
  331. package/dist/src/styles/canon/color-tables.js +10 -4
  332. package/dist/src/styles/canon/color-tables.js.map +1 -1
  333. package/dist/src/styles/canon/color.d.ts +3 -1
  334. package/dist/src/styles/canon/color.d.ts.map +1 -1
  335. package/dist/src/styles/canon/color.js +103 -3
  336. package/dist/src/styles/canon/color.js.map +1 -1
  337. package/dist/src/styles/canon/enums.d.ts +2 -2
  338. package/dist/src/styles/canon/enums.d.ts.map +1 -1
  339. package/dist/src/styles/canon/enums.js +81 -7
  340. package/dist/src/styles/canon/enums.js.map +1 -1
  341. package/dist/src/styles/canon/graphviz.d.ts +12 -3
  342. package/dist/src/styles/canon/graphviz.d.ts.map +1 -1
  343. package/dist/src/styles/canon/graphviz.js +57 -9
  344. package/dist/src/styles/canon/graphviz.js.map +1 -1
  345. package/dist/src/styles/canon/number.d.ts +8 -0
  346. package/dist/src/styles/canon/number.d.ts.map +1 -1
  347. package/dist/src/styles/canon/number.js +18 -0
  348. package/dist/src/styles/canon/number.js.map +1 -1
  349. package/dist/src/styles/canon/text.d.ts +29 -2
  350. package/dist/src/styles/canon/text.d.ts.map +1 -1
  351. package/dist/src/styles/canon/text.js +156 -16
  352. package/dist/src/styles/canon/text.js.map +1 -1
  353. package/dist/src/styles/codes.d.ts +2 -0
  354. package/dist/src/styles/codes.d.ts.map +1 -1
  355. package/dist/src/styles/codes.js +2 -0
  356. package/dist/src/styles/codes.js.map +1 -1
  357. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
  358. package/dist/src/styles/cyjs/cascade.js +1015 -79
  359. package/dist/src/styles/cyjs/cascade.js.map +1 -1
  360. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
  361. package/dist/src/styles/cyjs/defaults-table.js +3 -0
  362. package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
  363. package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
  364. package/dist/src/styles/cyjs/emit.js +202 -9
  365. package/dist/src/styles/cyjs/emit.js.map +1 -1
  366. package/dist/src/styles/cyjs/face.d.ts +20 -0
  367. package/dist/src/styles/cyjs/face.d.ts.map +1 -0
  368. package/dist/src/styles/cyjs/face.js +332 -0
  369. package/dist/src/styles/cyjs/face.js.map +1 -0
  370. package/dist/src/styles/cyjs/mappers.d.ts +44 -1
  371. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
  372. package/dist/src/styles/cyjs/mappers.js +461 -26
  373. package/dist/src/styles/cyjs/mappers.js.map +1 -1
  374. package/dist/src/styles/cyjs/routes.d.ts +53 -0
  375. package/dist/src/styles/cyjs/routes.d.ts.map +1 -0
  376. package/dist/src/styles/cyjs/routes.js +360 -0
  377. package/dist/src/styles/cyjs/routes.js.map +1 -0
  378. package/dist/src/styles/cytoscape/charts.d.ts +23 -0
  379. package/dist/src/styles/cytoscape/charts.d.ts.map +1 -0
  380. package/dist/src/styles/cytoscape/charts.js +560 -0
  381. package/dist/src/styles/cytoscape/charts.js.map +1 -0
  382. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
  383. package/dist/src/styles/cytoscape/emit.js +156 -48
  384. package/dist/src/styles/cytoscape/emit.js.map +1 -1
  385. package/dist/src/styles/cytoscape/lexicon.d.ts +91 -3
  386. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
  387. package/dist/src/styles/cytoscape/lexicon.js +387 -77
  388. package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
  389. package/dist/src/styles/cytoscape/mappings.d.ts +30 -0
  390. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -1
  391. package/dist/src/styles/cytoscape/mappings.js +92 -0
  392. package/dist/src/styles/cytoscape/mappings.js.map +1 -1
  393. package/dist/src/styles/cytoscape/resolve.d.ts +42 -2
  394. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
  395. package/dist/src/styles/cytoscape/resolve.js +623 -17
  396. package/dist/src/styles/cytoscape/resolve.js.map +1 -1
  397. package/dist/src/styles/defaults.d.ts +46 -26
  398. package/dist/src/styles/defaults.d.ts.map +1 -1
  399. package/dist/src/styles/defaults.js +308 -71
  400. package/dist/src/styles/defaults.js.map +1 -1
  401. package/dist/src/styles/index.d.ts +4 -3
  402. package/dist/src/styles/index.d.ts.map +1 -1
  403. package/dist/src/styles/index.js +3 -2
  404. package/dist/src/styles/index.js.map +1 -1
  405. package/dist/src/styles/internal.d.ts +1 -0
  406. package/dist/src/styles/internal.d.ts.map +1 -1
  407. package/dist/src/styles/internal.js +1 -0
  408. package/dist/src/styles/internal.js.map +1 -1
  409. package/dist/src/styles/io/generic.d.ts.map +1 -1
  410. package/dist/src/styles/io/generic.js +56 -16
  411. package/dist/src/styles/io/generic.js.map +1 -1
  412. package/dist/src/styles/io/round-trip.d.ts +56 -0
  413. package/dist/src/styles/io/round-trip.d.ts.map +1 -0
  414. package/dist/src/styles/io/round-trip.js +138 -0
  415. package/dist/src/styles/io/round-trip.js.map +1 -0
  416. package/dist/src/styles/io/writer.d.ts.map +1 -1
  417. package/dist/src/styles/io/writer.js +6 -1
  418. package/dist/src/styles/io/writer.js.map +1 -1
  419. package/dist/src/styles/notes.d.ts.map +1 -1
  420. package/dist/src/styles/notes.js +1 -0
  421. package/dist/src/styles/notes.js.map +1 -1
  422. package/dist/src/styles/plan/features.d.ts +1 -1
  423. package/dist/src/styles/plan/features.d.ts.map +1 -1
  424. package/dist/src/styles/plan/features.js +22 -2
  425. package/dist/src/styles/plan/features.js.map +1 -1
  426. package/dist/src/styles/plan/index.d.ts +1 -1
  427. package/dist/src/styles/plan/index.d.ts.map +1 -1
  428. package/dist/src/styles/plan/index.js +1 -1
  429. package/dist/src/styles/plan/index.js.map +1 -1
  430. package/dist/src/styles/plan/plan.d.ts.map +1 -1
  431. package/dist/src/styles/plan/plan.js +61 -4
  432. package/dist/src/styles/plan/plan.js.map +1 -1
  433. package/dist/src/styles/plan/resolve.d.ts +11 -0
  434. package/dist/src/styles/plan/resolve.d.ts.map +1 -1
  435. package/dist/src/styles/plan/resolve.js +40 -4
  436. package/dist/src/styles/plan/resolve.js.map +1 -1
  437. package/dist/src/styles/slots.d.ts +14 -0
  438. package/dist/src/styles/slots.d.ts.map +1 -0
  439. package/dist/src/styles/slots.js +20 -0
  440. package/dist/src/styles/slots.js.map +1 -0
  441. package/dist/src/styles/types.d.ts +622 -6
  442. package/dist/src/styles/types.d.ts.map +1 -1
  443. package/dist/src/styles/vocabulary.d.ts +3 -2
  444. package/dist/src/styles/vocabulary.d.ts.map +1 -1
  445. package/dist/src/styles/vocabulary.js +203 -0
  446. package/dist/src/styles/vocabulary.js.map +1 -1
  447. package/dist/styles.js +30 -239
  448. package/dist/styles.js.map +1 -1
  449. package/dist/xgmml.js +3 -3
  450. package/package.json +27 -7
  451. package/src/formats/cx/importer.ts +6 -1
  452. package/src/formats/cx/styles.ts +143 -9
  453. package/src/formats/cx2/importer.ts +1 -0
  454. package/src/formats/cx2/styles.ts +3 -1
  455. package/src/formats/cys/importer.ts +1 -0
  456. package/src/formats/cys/styles.ts +27 -5
  457. package/src/formats/dot/drawing.ts +799 -0
  458. package/src/formats/dot/importer.ts +120 -35
  459. package/src/formats/dot/label-places.ts +228 -0
  460. package/src/formats/dot/record.ts +336 -0
  461. package/src/formats/dot/styles.ts +1654 -153
  462. package/src/formats/gexf/dialog-metrics.ts +61 -0
  463. package/src/formats/gexf/importer.ts +50 -5
  464. package/src/formats/gexf/preview.ts +217 -0
  465. package/src/formats/gexf/schema.ts +2 -1
  466. package/src/formats/gexf/styles.ts +1099 -245
  467. package/src/formats/gml/importer.ts +291 -76
  468. package/src/formats/gml/index.ts +1 -1
  469. package/src/formats/gml/positions.ts +29 -7
  470. package/src/formats/gml/styles.ts +851 -109
  471. package/src/formats/graphml/styles-plain.ts +6 -15
  472. package/src/formats/graphml/styles-yed.ts +762 -173
  473. package/src/formats/graphml/styles-yfiles3.ts +485 -63
  474. package/src/formats/graphml/yfiles.ts +19 -6
  475. package/src/formats/json/dialect.ts +41 -5
  476. package/src/formats/json/importer.ts +59 -7
  477. package/src/formats/json/index.ts +1 -0
  478. package/src/formats/json/positions.ts +22 -5
  479. package/src/formats/json/styles.ts +2041 -185
  480. package/src/formats/pajek/draw.ts +458 -0
  481. package/src/formats/pajek/exporter.ts +81 -49
  482. package/src/formats/pajek/importer.ts +278 -103
  483. package/src/formats/pajek/index.ts +1 -0
  484. package/src/formats/pajek/styles.ts +1381 -133
  485. package/src/formats/pajek/syntax.ts +27 -2
  486. package/src/formats/xgmml/emit.ts +73 -5
  487. package/src/formats/xgmml/styles.ts +330 -71
  488. package/src/index.ts +5 -1
  489. package/src/positions/convert.ts +12 -1
  490. package/src/positions/extract.ts +55 -1
  491. package/src/positions/index.ts +1 -0
  492. package/src/positions/types.ts +60 -0
  493. package/src/sources/builtins.ts +8 -1
  494. package/src/sources/context.ts +1 -0
  495. package/src/sources/cypher/descriptor.ts +7 -1
  496. package/src/sources/cypher/index.ts +148 -18
  497. package/src/sources/cypher/params.ts +1 -1
  498. package/src/sources/cypher/query-builder.ts +33 -0
  499. package/src/sources/ids.ts +6 -0
  500. package/src/sources/params.ts +3 -0
  501. package/src/sources/rest/descriptor.ts +5 -0
  502. package/src/sources/rest/source.ts +16 -0
  503. package/src/sources/sigv4.ts +6 -4
  504. package/src/sources/sparql/descriptor.ts +67 -0
  505. package/src/sources/sparql/index.ts +356 -0
  506. package/src/sources/sparql/ntriples.ts +219 -0
  507. package/src/sources/sparql/params.ts +28 -0
  508. package/src/sources/sparql/query.ts +162 -0
  509. package/src/sources/types.ts +35 -0
  510. package/src/styles/annotations.ts +201 -27
  511. package/src/styles/canon/bends.ts +137 -0
  512. package/src/styles/canon/color-tables.ts +10 -4
  513. package/src/styles/canon/color.ts +105 -3
  514. package/src/styles/canon/enums.ts +98 -8
  515. package/src/styles/canon/graphviz.ts +71 -10
  516. package/src/styles/canon/number.ts +19 -0
  517. package/src/styles/canon/text.ts +187 -16
  518. package/src/styles/codes.ts +2 -0
  519. package/src/styles/cyjs/cascade.ts +1160 -84
  520. package/src/styles/cyjs/defaults-table.ts +3 -0
  521. package/src/styles/cyjs/emit.ts +233 -13
  522. package/src/styles/cyjs/face.ts +372 -0
  523. package/src/styles/cyjs/mappers.ts +492 -27
  524. package/src/styles/cyjs/routes.ts +432 -0
  525. package/src/styles/cytoscape/charts.ts +684 -0
  526. package/src/styles/cytoscape/emit.ts +170 -48
  527. package/src/styles/cytoscape/lexicon.ts +431 -78
  528. package/src/styles/cytoscape/mappings.ts +108 -0
  529. package/src/styles/cytoscape/resolve.ts +741 -17
  530. package/src/styles/defaults.ts +417 -108
  531. package/src/styles/index.ts +5 -0
  532. package/src/styles/internal.ts +1 -0
  533. package/src/styles/io/generic.ts +79 -23
  534. package/src/styles/io/round-trip.ts +202 -0
  535. package/src/styles/io/writer.ts +6 -1
  536. package/src/styles/notes.ts +1 -0
  537. package/src/styles/plan/features.ts +23 -2
  538. package/src/styles/plan/index.ts +1 -1
  539. package/src/styles/plan/plan.ts +69 -5
  540. package/src/styles/plan/resolve.ts +47 -4
  541. package/src/styles/slots.ts +25 -0
  542. package/src/styles/types.ts +633 -5
  543. package/src/styles/vocabulary.ts +211 -2
  544. package/dist/chunks/block-Cu22ewuS.js.map +0 -1
  545. package/dist/chunks/choose-Cdx6Enl2.js +0 -57
  546. package/dist/chunks/choose-Cdx6Enl2.js.map +0 -1
  547. package/dist/chunks/codes-CV_Bhcyi.js.map +0 -1
  548. package/dist/chunks/convert-BcQ8_jMo.js.map +0 -1
  549. package/dist/chunks/credentials-BiQsnMTb.js.map +0 -1
  550. package/dist/chunks/descriptor-BJ-W0Jd-.js.map +0 -1
  551. package/dist/chunks/emit-CD8xnY8s.js.map +0 -1
  552. package/dist/chunks/export-CZ7VRm4I.js.map +0 -1
  553. package/dist/chunks/exporter-bxxjOrDZ.js.map +0 -1
  554. package/dist/chunks/format-BMS-1Nxb.js +0 -64
  555. package/dist/chunks/format-BMS-1Nxb.js.map +0 -1
  556. package/dist/chunks/generic-CP6YD34u.js.map +0 -1
  557. package/dist/chunks/importer-B87_fmVx.js.map +0 -1
  558. package/dist/chunks/importer-CB_zV5_L.js.map +0 -1
  559. package/dist/chunks/importer-CVT-JyDE.js.map +0 -1
  560. package/dist/chunks/importer-Cyy6UseH.js.map +0 -1
  561. package/dist/chunks/importer-DPZDN40-.js.map +0 -1
  562. package/dist/chunks/importer-e3huMZbm.js.map +0 -1
  563. package/dist/chunks/lexicon-u2SI5xcx.js.map +0 -1
  564. package/dist/chunks/sigv4-LkAzsLAu.js.map +0 -1
  565. package/dist/chunks/styles-CaABMoO1.js.map +0 -1
  566. package/dist/chunks/styles-P_gmFAOi.js +0 -770
  567. package/dist/chunks/styles-P_gmFAOi.js.map +0 -1
  568. package/dist/chunks/styles-yed-Cs1nmrjn.js.map +0 -1
  569. package/dist/chunks/writer-DvHTl36J.js +0 -449
  570. package/dist/chunks/writer-DvHTl36J.js.map +0 -1
@@ -39,6 +39,24 @@ const opacity255: CytoscapeValueParser = (raw, site) => {
39
39
  // CX2's 0..1 opacity.
40
40
  const opacity01: CytoscapeValueParser = (raw, site) => canonOpacity(raw, "css", site);
41
41
  const length: CytoscapeValueParser = (raw, site) => canonNumber(raw, site);
42
+ // An arrow size as the neutral factor: Cytoscape's normal arrow is size 6 (default_vizmap.xml).
43
+ export const arrowSizeParser: CytoscapeValueParser = (raw, site) => {
44
+ const v = canonNumber(raw, site);
45
+ return v === null ? null : num6(v / 6);
46
+ };
47
+
48
+ // Degrees, clockwise on screen as Cytoscape turns a label, folded into 0..360.
49
+ // ponytail: a continuous mapping across 0 (from -30 to 30) folds to 330..30 and interpolates the long way round;
50
+ // keep the sign when a file needs it.
51
+ const rotation: CytoscapeValueParser = (raw, site) => {
52
+ const v = typeof raw === "number" ? raw : Number(scalarText(raw, site)?.trim() ?? Number.NaN);
53
+ if (!Number.isFinite(v)) {
54
+ noteAt(site, STYLE_ISSUE.BAD_VALUE, String(raw));
55
+ return null;
56
+ }
57
+ return num6(((v % 360) + 360) % 360);
58
+ };
59
+
42
60
  // Cytoscape desktop holds a font size as a whole number, so every value read for one is drawn rounded.
43
61
  const fontSize: CytoscapeValueParser = (raw, site) => {
44
62
  const v = canonNumber(raw, site);
@@ -85,29 +103,34 @@ const shape: CytoscapeValueParser = (raw, site) => {
85
103
  const CY_ARROWS: ReadonlyMap<string, string> = new Map([
86
104
  ["none", "none"],
87
105
  ["delta", "triangle"],
88
- ["arrow", "vee"],
106
+ // a filled delta with a shallow notch in its back, as long and wide as DELTA (Cytoscape 3.10.5 SVG export)
107
+ ["arrow", "triangle"],
89
108
  ["diamond", "diamond"],
90
109
  ["circle", "circle"],
91
110
  ["t", "tee"],
92
111
  ["half_top", "half"],
93
- ["half_bottom", "half"],
112
+ // the half arrow on the line's other side from HALF_TOP's
113
+ ["half_bottom", "other:half-bottom"],
94
114
  ["square", "square"],
95
115
  ["delta_short_1", "triangle"],
96
116
  ["delta_short_2", "triangle"],
97
- ["arrow_short", "vee"],
117
+ // a short arrow whose notch is too shallow to show: drawn as the triangle it reads as
118
+ ["arrow_short", "triangle"],
98
119
  ["diamond_short_1", "diamond"],
99
120
  ["diamond_short_2", "diamond"],
100
121
  ["open_delta", "triangle-open"],
101
122
  ["open_circle", "circle-open"],
102
123
  ["open_diamond", "diamond-open"],
103
124
  ["open_square", "other:open-square"],
104
- ["cross_delta", "vee"],
105
- ["cross_open_delta", "triangle-open"],
125
+ // a delta with a bar across the line behind it
126
+ ["cross_delta", "other:cross-delta"],
127
+ ["cross_open_delta", "other:cross-open-delta"],
106
128
  ["open_half_circle", "other:open-half-circle"],
107
129
  ["half_circle", "other:half-circle"],
108
130
  ["triangle", "triangle"],
109
131
  ["triangle-tee", "tee"],
110
- ["triangle-cross", "vee"],
132
+ // CX2's spelling of CROSS_DELTA
133
+ ["triangle-cross", "other:cross-delta"],
111
134
  ["triangle-backcurve", "triangle"],
112
135
  ["tee", "tee"],
113
136
  ["vee", "vee"],
@@ -117,7 +140,44 @@ const CY_ARROWS: ReadonlyMap<string, string> = new Map([
117
140
  ["open-square", "other:open-square"],
118
141
  ["open-delta", "triangle-open"],
119
142
  ["half-top", "half"],
120
- ["half-bottom", "half"],
143
+ ["half-bottom", "other:half-bottom"],
144
+ ]);
145
+
146
+ /**
147
+ * How much longer and wider than the neutral shape it is read as each Cytoscape arrow is drawn: the short deltas and
148
+ * diamonds, the short arrow and the crossed deltas (a bar behind the delta), from the unit glyphs Cytoscape 3.10.5's
149
+ * SVG export draws (a DELTA is 2 long and 1 wide, DELTA_SHORT_1 1 by 1, ARROW_SHORT 1.2 by 0.8, CROSS_DELTA 3 by 1.5).
150
+ * Every other arrow is drawn in its shape's own proportions.
151
+ */
152
+ const CY_ARROW_PROPORTIONS: ReadonlyMap<string, { readonly length: number; readonly width: number }> = new Map([
153
+ ["delta_short_1", { length: 0.5, width: 1 }],
154
+ ["delta_short_2", { length: 0.25, width: 1 }],
155
+ ["arrow_short", { length: 0.6, width: 0.8 }],
156
+ ["diamond_short_1", { length: 0.5, width: 1 }],
157
+ ["diamond_short_2", { length: 0.25, width: 1 }],
158
+ ["cross_delta", { length: 1.5, width: 1.5 }],
159
+ ["cross_open_delta", { length: 1.5, width: 1.5 }],
160
+ ["triangle-cross", { length: 1.5, width: 1.5 }],
161
+ ]);
162
+
163
+ /**
164
+ * How far from its node Cytoscape draws each arrow that stands off the node's outline, as a multiple of the arrow's
165
+ * own length along its line, from the unit glyphs Cytoscape 3.10.5's SVG export draws back from the outline: T's bar
166
+ * from 0.8 to 1 (4 of its 0.2), a half circle from 0.5 to 1, HALF_TOP's barb from 0.3 to 1.435, a square from 0.25
167
+ * to 1.25. Every other arrow touches the outline.
168
+ */
169
+ const CY_ARROW_GAPS: ReadonlyMap<string, number> = new Map([
170
+ ["t", 4],
171
+ ["tee", 4],
172
+ ["half_circle", 1],
173
+ ["open_half_circle", 1],
174
+ ["half_top", 0.3 / 1.135],
175
+ ["half_bottom", 0.3 / 1.135],
176
+ ["half-top", 0.3 / 1.135],
177
+ ["half-bottom", 0.3 / 1.135],
178
+ ["square", 0.25],
179
+ ["open_square", 0.25],
180
+ ["open-square", 0.25],
121
181
  ]);
122
182
 
123
183
  /** Cytoscape 2.x numbered arrow codes. */
@@ -142,16 +202,55 @@ const LEGACY_ARROW: readonly string[] = [
142
202
  "half_bottom",
143
203
  ];
144
204
 
205
+ /**
206
+ * A Cytoscape arrow name, lowercase, with a 2.x numbered code read as its name.
207
+ * @param s - the raw name
208
+ * @returns the key
209
+ */
210
+ function arrowKey(s: string): string {
211
+ const key = s.trim().toLowerCase();
212
+ return /^\d{1,2}$/.test(key) ? (LEGACY_ARROW.at(Number(key)) ?? key) : key;
213
+ }
214
+
145
215
  const arrow: CytoscapeValueParser = (raw, site) => {
146
216
  const s = scalarText(raw, site);
147
217
  if (s === null) {
148
218
  return null;
149
219
  }
150
- let key = s.trim().toLowerCase();
151
- if (/^\d{1,2}$/.test(key)) {
152
- key = LEGACY_ARROW.at(Number(key)) ?? key;
220
+ return caseless(CY_ARROWS.get(arrowKey(s)) ?? canonEnum("arrow", s, "cytoscape", site));
221
+ };
222
+
223
+ /**
224
+ * The parser of an arrow's length or width as a fraction of its neutral shape's, from the arrow's name: 1 for every
225
+ * arrow Cytoscape draws in its shape's proportions, so a bypass over a short default draws the full shape again.
226
+ * @param side - which proportion
227
+ * @returns the parser; null for a name it does not know (the shape's parser notes it)
228
+ */
229
+ export function arrowProportion(side: "length" | "width"): CytoscapeValueParser {
230
+ return (raw, site) => {
231
+ const s = scalarText(raw, site);
232
+ if (s === null) {
233
+ return null;
234
+ }
235
+ const key = arrowKey(s);
236
+ return CY_ARROW_PROPORTIONS.get(key)?.[side] ?? (CY_ARROWS.has(key) ? 1 : null);
237
+ };
238
+ }
239
+
240
+ /**
241
+ * The parser of how far an arrow stands off its node, as a multiple of its own length (`CY_ARROW_GAPS`), from the
242
+ * arrow's name: 0 for an arrow that touches the node.
243
+ * @param raw - the arrow's name
244
+ * @param site - where it was read
245
+ * @returns the gap; null for a name it does not know (the shape's parser notes it)
246
+ */
247
+ export const arrowGap: CytoscapeValueParser = (raw, site) => {
248
+ const s = scalarText(raw, site);
249
+ if (s === null) {
250
+ return null;
153
251
  }
154
- return caseless(CY_ARROWS.get(key) ?? canonEnum("arrow", s, "cytoscape", site));
252
+ const key = arrowKey(s);
253
+ return CY_ARROW_GAPS.get(key) ?? (CY_ARROWS.has(key) ? 0 : null);
155
254
  };
156
255
 
157
256
  /** Cytoscape's line types, lowercase. */
@@ -199,8 +298,8 @@ function lineOf(kind: "lineStyle" | "borderStyle"): CytoscapeValueParser {
199
298
  if (v === null || isStyleValue("node", kind, v) || kind === "lineStyle") {
200
299
  return v;
201
300
  }
202
- // a line type a border does not have is kept as other:
203
- return `other:${key}`;
301
+ // a line type a border does not have is kept as other:, spelled as the line type's own (other:forward-slash)
302
+ return v.startsWith("other:") ? v : `other:${v}`;
204
303
  };
205
304
  }
206
305
 
@@ -211,10 +310,43 @@ interface FontFace {
211
310
  readonly italic: boolean;
212
311
  }
213
312
 
313
+ /**
314
+ * A Java font name's own style: `Dialog.bolditalic` is the bold italic face of `Dialog`, and Java draws it bold and
315
+ * italic whatever style the rest of the face states (`Dialog.bolditalic,plain,12` is drawn bold italic).
316
+ * @param name - the font name
317
+ * @returns the family without the suffix, and whether the suffix makes it bold or italic
318
+ */
319
+ function javaFace(name: string): FontFace {
320
+ const m = /\.(bold|italic|plain|bolditalic)$/i.exec(name);
321
+ const suffix = m?.[1].toLowerCase() ?? "";
322
+ return {
323
+ family: m === null ? name : name.slice(0, m.index),
324
+ weight: suffix.includes("bold") ? "bold" : "normal",
325
+ italic: suffix.includes("italic"),
326
+ };
327
+ }
328
+
329
+ /**
330
+ * A face whose family may carry a Java style suffix, its suffix's style added to the stated one.
331
+ * @param family - the family as written
332
+ * @param bold - whether the face states bold
333
+ * @param italic - whether the face states italic
334
+ * @returns the face
335
+ */
336
+ function withSuffix(family: string, bold: boolean, italic: boolean): FontFace {
337
+ const own = javaFace(family.trim());
338
+ return {
339
+ family: own.family,
340
+ weight: bold || own.weight === "bold" ? "bold" : "normal",
341
+ italic: italic || own.italic,
342
+ };
343
+ }
344
+
214
345
  /**
215
346
  * A font face: `SansSerif,plain,12`, `Dialog.bold,bold,12`, the legacy `SansSerif-0-12` (style bits 1 bold,
216
347
  * 2 italic) or CX2's `{ FONT_FAMILY, FONT_STYLE, FONT_WEIGHT }`, whose `FONT_NAME` (the font Cytoscape desktop
217
- * wrote it from, which its own import restores) wins over the CSS family when present.
348
+ * wrote it from, which its own import restores) wins over the CSS family when present. A Java style suffix on the
349
+ * name (`SansSerif.bold`) is drawn as well.
218
350
  * @param raw - the value
219
351
  * @param site - where it was read
220
352
  * @returns the face, or null
@@ -229,14 +361,12 @@ function fontFace(raw: unknown, site: CanonSite): FontFace | null {
229
361
  }
230
362
  const parts = s.split(",");
231
363
  if (parts.length >= 2) {
232
- const st = parts[1].trim().toLowerCase();
233
- return {
234
- family: parts[0].trim().replace(/\.(?:bold|italic|plain|bolditalic)$/i, ""),
235
- weight: st.includes("bold") ? "bold" : "normal",
236
- italic: st.includes("italic"),
237
- };
364
+ // desktop takes the face from the name alone (`FontVisualProperty.parseSerializableString`): its style word is
365
+ // what it writes, not what it reads, so a passthrough of `Serif,bold,12` is drawn plain (Cytoscape 3.10.5's
366
+ // SVG of specimen-mappings-bypass-p19, passthrough-font-face) and `SansSerif.bold,bold,10` bold by its suffix
367
+ return withSuffix(parts[0], false, false);
238
368
  }
239
- return legacyFontFace(s) ?? { family: s.trim(), weight: "normal", italic: false };
369
+ return legacyFontFace(s) ?? withSuffix(s, false, false);
240
370
  }
241
371
 
242
372
  /**
@@ -249,18 +379,14 @@ function cx2FontFace(o: Record<string, unknown>, site: CanonSite): FontFace | nu
249
379
  const name = Object.hasOwn(o, "FONT_NAME") ? scalarText(o.FONT_NAME, site) : null;
250
380
  let family = Object.hasOwn(o, "FONT_FAMILY") ? scalarText(o.FONT_FAMILY, site) : null;
251
381
  if (name !== null && name.trim() !== "") {
252
- family = name.trim().replace(/\.(?:bold|italic|plain|bolditalic)$/i, "");
382
+ family = name;
253
383
  }
254
384
  if (family === null) {
255
385
  return null;
256
386
  }
257
387
  const weight = Object.hasOwn(o, "FONT_WEIGHT") ? String(o.FONT_WEIGHT) : "";
258
388
  const style = Object.hasOwn(o, "FONT_STYLE") ? String(o.FONT_STYLE) : "";
259
- return {
260
- family: family.trim(),
261
- weight: /bold/i.test(weight.slice(0, 32)) ? "bold" : "normal",
262
- italic: /italic/i.test(style.slice(0, 32)),
263
- };
389
+ return withSuffix(family, /bold/i.test(weight.slice(0, 32)), /italic/i.test(style.slice(0, 32)));
264
390
  }
265
391
 
266
392
  /**
@@ -281,79 +407,254 @@ function legacyFontFace(s: string): FontFace | null {
281
407
  family = family.slice(0, -"-bold".length);
282
408
  bold = true;
283
409
  }
284
- return { family: family.replace(/\.bold$/i, ""), weight: bold ? "bold" : "normal", italic: (bits & 2) !== 0 };
410
+ return withSuffix(family, bold, (bits & 2) !== 0);
285
411
  }
286
412
 
287
- /** Java's logical font names, which Cytoscape desktop writes, as the CSS generic families they stand for. */
413
+ /**
414
+ * The faces Java draws its logical fonts in on Linux, where the oracles were drawn (the JDK's fontconfig maps
415
+ * SansSerif and Dialog to DejaVu Sans), each before the CSS generic family it stands for. A label wraps by its width
416
+ * in that face: a browser's own sans-serif (Liberation Sans) is 14 percent narrower, so its lines break later.
417
+ */
418
+ export const JAVA_SANS = "DejaVu Sans, sans-serif";
419
+ export const JAVA_SERIF = "DejaVu Serif, serif";
420
+ export const JAVA_MONO = "DejaVu Sans Mono, monospace";
421
+
288
422
  /** The family a Java logical font name is read as (`Dialog` is drawn as a sans-serif font). */
289
- export const JAVA_FONTS: ReadonlyMap<string, string> = new Map([
290
- ["sansserif", "sans-serif"],
291
- ["dialog", "sans-serif"],
292
- ["default", "sans-serif"],
293
- ["dialoginput", "monospace"],
294
- ["monospaced", "monospace"],
295
- ["serif", "serif"],
423
+ const JAVA_FONTS: ReadonlyMap<string, string> = new Map([
424
+ // CX2's CSS generic families too: Cytoscape desktop hands them to Java, which draws them as these
425
+ ["sans-serif", JAVA_SANS],
426
+ ["monospace", JAVA_MONO],
427
+ ["sansserif", JAVA_SANS],
428
+ ["dialog", JAVA_SANS],
429
+ ["default", JAVA_SANS],
430
+ ["dialoginput", JAVA_MONO],
431
+ ["monospaced", JAVA_MONO],
432
+ ["serif", JAVA_SERIF],
296
433
  ]);
297
434
 
298
435
  const fontFamily: CytoscapeValueParser = (raw, site) => {
299
436
  const family = fontFace(raw, site)?.family ?? null;
300
- return family === null ? null : (JAVA_FONTS.get(family.toLowerCase()) ?? family);
437
+ return family === null ? null : javaFamily(family);
301
438
  };
439
+
440
+ /** The CSS generic families. */
441
+ const CSS_GENERIC: ReadonlySet<string> = new Set([
442
+ "sans-serif",
443
+ "serif",
444
+ "monospace",
445
+ "cursive",
446
+ "fantasy",
447
+ "system-ui",
448
+ ]);
449
+
450
+ /**
451
+ * A Java font name as the CSS family Cytoscape draws it with: a logical name as its generic family, and any other
452
+ * with Dialog's face after it, because Java draws a font it does not have as Dialog
453
+ * (`Calibri-Bold` on a machine without Calibri is drawn in Dialog's face and measured so when a label wraps).
454
+ * @param family - the Java font name, without its style suffix
455
+ * @returns the CSS family
456
+ */
457
+ export function javaFamily(family: string): string {
458
+ const logical = JAVA_FONTS.get(family.toLowerCase());
459
+ if (logical !== undefined) {
460
+ return logical;
461
+ }
462
+ // a CSS generic family or family list (CX2 writes them) already says what stands in for a missing font
463
+ return family.includes(",") || CSS_GENERIC.has(family.toLowerCase()) ? family : `${family}, ${JAVA_SANS}`;
464
+ }
302
465
  const fontWeight: CytoscapeValueParser = (raw, site) => fontFace(raw, site)?.weight ?? null;
303
466
  const fontItalic: CytoscapeValueParser = (raw, site) => fontFace(raw, site)?.italic ?? null;
304
467
 
305
- /** The node anchor of a desktop label position `C,C,c,0.00,0.00`. */
306
- const ANCHOR: ReadonlyMap<string, string> = new Map([
307
- ["C", "center"],
308
- ["N", "top"],
309
- ["S", "bottom"],
310
- ["E", "right"],
311
- ["W", "left"],
312
- ["NE", "top-right"],
313
- ["NW", "top-left"],
314
- ["SE", "bottom-right"],
315
- ["SW", "bottom-left"],
316
- ["NONE", "center"],
468
+ /** A desktop anchor letter as a point of a box, x right and y down, each -1, 0 or 1. */
469
+ const ANCHOR: ReadonlyMap<string, readonly [number, number]> = new Map([
470
+ ["C", [0, 0]],
471
+ ["N", [0, -1]],
472
+ ["S", [0, 1]],
473
+ ["E", [1, 0]],
474
+ ["W", [-1, 0]],
475
+ ["NE", [1, -1]],
476
+ ["NW", [-1, -1]],
477
+ ["SE", [1, 1]],
478
+ ["SW", [-1, 1]],
479
+ ["NONE", [0, 0]],
317
480
  ]);
318
481
 
319
- /** CX2's `HORIZONTAL_ANCHOR,VERTICAL_ANCHOR`, lowercase. */
320
- const CX2_ANCHOR: ReadonlyMap<string, string> = new Map([
321
- ["center,center", "center"],
322
- ["center,top", "top"],
323
- ["center,bottom", "bottom"],
324
- ["right,center", "right"],
325
- ["left,center", "left"],
326
- ["right,top", "top-right"],
327
- ["left,top", "top-left"],
328
- ["right,bottom", "bottom-right"],
329
- ["left,bottom", "bottom-left"],
482
+ /** CX2's anchor and align words as a point of a box on one axis. */
483
+ const CX2_SIDE: ReadonlyMap<string, number> = new Map([
484
+ ["center", 0],
485
+ ["left", -1],
486
+ ["right", 1],
487
+ ["top", -1],
488
+ ["bottom", 1],
330
489
  ]);
331
490
 
332
- const labelPosition: CytoscapeValueParser = (raw, site) => {
333
- let key: string;
334
- let found: string | undefined;
491
+ /** A label justification as the neutral text alignment. */
492
+ const JUSTIFY: ReadonlyMap<string, string> = new Map([
493
+ ["l", "left"],
494
+ ["left", "left"],
495
+ ["c", "center"],
496
+ ["center", "center"],
497
+ ["r", "right"],
498
+ ["right", "right"],
499
+ ]);
500
+
501
+ /**
502
+ * A Cytoscape label position, read whole: the point of the node (or the edge's middle) `node` and the point of the
503
+ * label's box `label` it is pinned to, each `[x, y]` with x right and y down as -1, 0 or 1, the justification of its
504
+ * lines, and the offset `[x, y]` in px, y down.
505
+ * @category Styles
506
+ */
507
+ export interface CytoscapeLabelPlace {
508
+ readonly node: readonly [number, number];
509
+ readonly label: readonly [number, number];
510
+ readonly justify: string;
511
+ readonly offset: readonly [number, number];
512
+ }
513
+
514
+ /**
515
+ * The anchors of CX2's edge label position `{ EDGE_ANCHOR, LABEL_ANCHOR, ... }`, each a desktop anchor letter, as
516
+ * `[edge x, edge y, label x, label y]`; undefined where a letter is not one.
517
+ * @param o - the position
518
+ * @param site - where a bad value is noted
519
+ * @returns the four sides
520
+ */
521
+ function cx2EdgeAnchors(o: Record<string, unknown>, site: CanonSite): (number | undefined)[] {
522
+ const letter = (key: string): readonly [number, number] | undefined =>
523
+ ANCHOR.get((scalarText(Object.hasOwn(o, key) ? o[key] : "C", site) ?? "").trim().toUpperCase());
524
+ return [
525
+ ...(letter("EDGE_ANCHOR") ?? [undefined, undefined]),
526
+ ...(letter("LABEL_ANCHOR") ?? [undefined, undefined]),
527
+ ];
528
+ }
529
+
530
+ /**
531
+ * Reads a label position: desktop's `C,C,c,0.00,0.00` (node anchor, label anchor, justification, x and y offsets)
532
+ * or CX2's `{ HORIZONTAL_ANCHOR, VERTICAL_ANCHOR, HORIZONTAL_ALIGN, VERTICAL_ALIGN, JUSTIFICATION, MARGIN_X,
533
+ * MARGIN_Y }` (for an edge's label `{ EDGE_ANCHOR, LABEL_ANCHOR, JUSTIFICATION, MARGIN_X, MARGIN_Y }`, the anchors
534
+ * as desktop's letters).
535
+ * @param raw - the value
536
+ * @param site - where a bad value is noted
537
+ * @returns the place, or null
538
+ * @category Styles
539
+ */
540
+ export function cytoscapeLabelPlace(raw: unknown, site: CanonSite): CytoscapeLabelPlace | null {
335
541
  if (raw !== null && typeof raw === "object" && !Array.isArray(raw)) {
336
542
  const o = raw as Record<string, unknown>;
337
- const h = scalarText(Object.hasOwn(o, "HORIZONTAL_ANCHOR") ? o.HORIZONTAL_ANCHOR : "center", site);
338
- const v = scalarText(Object.hasOwn(o, "VERTICAL_ANCHOR") ? o.VERTICAL_ANCHOR : "center", site);
339
- if (h === null || v === null) {
340
- return null;
341
- }
342
- key = `${h.trim().toLowerCase()},${v.trim().toLowerCase()}`;
343
- found = CX2_ANCHOR.get(key);
344
- } else {
345
- const s = scalarText(raw, site);
346
- if (s === null) {
543
+ const word = (key: string): string => {
544
+ const v = Object.hasOwn(o, key) ? scalarText(o[key], site) : null;
545
+ return (v ?? "center").trim().toLowerCase();
546
+ };
547
+ const num = (key: string): number => {
548
+ const v = Object.hasOwn(o, key) ? Number(o[key]) : 0;
549
+ return Number.isFinite(v) ? v : 0;
550
+ };
551
+ const sides = Object.hasOwn(o, "EDGE_ANCHOR")
552
+ ? cx2EdgeAnchors(o, site)
553
+ : ["HORIZONTAL_ANCHOR", "VERTICAL_ANCHOR", "HORIZONTAL_ALIGN", "VERTICAL_ALIGN"].map((k) =>
554
+ CX2_SIDE.get(word(k)),
555
+ );
556
+ if (sides.includes(undefined)) {
557
+ noteAt(site, STYLE_ISSUE.UNKNOWN_VALUE, JSON.stringify(raw).slice(0, 64));
347
558
  return null;
348
559
  }
349
- key = s;
350
- found = ANCHOR.get(s.split(",")[0].trim().toUpperCase());
560
+ const [nx, ny, lx, ly] = sides as number[];
561
+ return {
562
+ node: [nx, ny],
563
+ label: [lx, ly],
564
+ justify: JUSTIFY.get(word("JUSTIFICATION")) ?? "center",
565
+ offset: [num("MARGIN_X"), num("MARGIN_Y")],
566
+ };
567
+ }
568
+ const s = scalarText(raw, site);
569
+ if (s === null) {
570
+ return null;
351
571
  }
352
- if (found === undefined) {
353
- noteAt(site, STYLE_ISSUE.UNKNOWN_VALUE, key);
572
+ const parts = s.split(",").map((p) => p.trim());
573
+ const node = ANCHOR.get(parts[0].toUpperCase());
574
+ // a position naming only the node's anchor pins the label's opposite point there, as Cytoscape 2.x did
575
+ const label = parts.length > 1 ? ANCHOR.get(parts[1].toUpperCase()) : node?.map((v) => -v);
576
+ if (node === undefined || label === undefined) {
577
+ noteAt(site, STYLE_ISSUE.UNKNOWN_VALUE, s);
354
578
  return null;
355
579
  }
356
- return found;
580
+ const at = (i: number): number => {
581
+ const v = Number(parts[i] ?? 0);
582
+ return Number.isFinite(v) ? v : 0;
583
+ };
584
+ return {
585
+ node,
586
+ label: [label[0], label[1]],
587
+ justify: JUSTIFY.get((parts[2] ?? "c").toLowerCase()) ?? "center",
588
+ offset: [at(3), at(4)],
589
+ };
590
+ }
591
+
592
+ /** The neutral position of a label inside its node against each side, by `[x, y]` of the side, y down. */
593
+ const INSIDE: ReadonlyMap<string, string> = new Map([
594
+ ["0,0", "center"],
595
+ ["0,-1", "inside-top"],
596
+ ["0,1", "inside-bottom"],
597
+ ["-1,0", "inside-left"],
598
+ ["1,0", "inside-right"],
599
+ ["-1,-1", "inside-top-left"],
600
+ ["1,-1", "inside-top-right"],
601
+ ["-1,1", "inside-bottom-left"],
602
+ ["1,1", "inside-bottom-right"],
603
+ ]);
604
+
605
+ /**
606
+ * The neutral `labelPosition` a Cytoscape label position starts from: where the label's point is the node's own
607
+ * point on both axes (its center, or inside against a side or a corner), that position; anywhere else `center`,
608
+ * with the rest said by `labelOffsetX`/`Y` and `labelShiftX`/`Y` (see `cytoscapeLabelMove()`).
609
+ * @param place - the label position
610
+ * @returns the neutral position
611
+ * @category Styles
612
+ */
613
+ export function cytoscapeLabelBase(place: CytoscapeLabelPlace): string {
614
+ const inside = place.node[0] === place.label[0] && place.node[1] === place.label[1];
615
+ return inside ? (INSIDE.get(`${place.node[0]},${place.node[1]}`) ?? "center") : "center";
616
+ }
617
+
618
+ /**
619
+ * How far a Cytoscape label is moved from its `cytoscapeLabelBase()` position: the offset in px (y down), with the
620
+ * node's anchor point added when the base is `center` and the anchors differ, and the shift by the label's own
621
+ * size that pins the label's anchor point there.
622
+ * @param place - the label position
623
+ * @param width - the node's width (0 for an edge's middle)
624
+ * @param height - the node's height (0 for an edge's middle)
625
+ * @returns the offset and the shift, each `[x, y]`
626
+ * @category Styles
627
+ */
628
+ export function cytoscapeLabelMove(
629
+ place: CytoscapeLabelPlace,
630
+ width: number,
631
+ height: number,
632
+ ): { readonly offset: readonly [number, number]; readonly shift: readonly [number, number] } {
633
+ if (
634
+ cytoscapeLabelBase(place) !== "center" ||
635
+ (place.node[0] === 0 && place.node[1] === 0 && place.label[0] === 0 && place.label[1] === 0)
636
+ ) {
637
+ return { offset: place.offset, shift: [0, 0] };
638
+ }
639
+ return {
640
+ offset: [(place.node[0] * width) / 2 + place.offset[0], (place.node[1] * height) / 2 + place.offset[1]],
641
+ shift: [halfBack(place.label[0]), halfBack(place.label[1])],
642
+ };
643
+ }
644
+
645
+ /**
646
+ * How far a label is shifted, as a fraction of its own size, to pin its point `side` (-1, 0 or 1) where its middle was.
647
+ * @param side - the label's point on one axis
648
+ * @returns the shift (0, never -0, for the middle)
649
+ * @category Styles
650
+ */
651
+ export function halfBack(side: number): number {
652
+ return side === 0 ? 0 : -side / 2;
653
+ }
654
+
655
+ const labelPosition: CytoscapeValueParser = (raw, site) => {
656
+ const place = cytoscapeLabelPlace(raw, site);
657
+ return place === null ? null : cytoscapeLabelBase(place);
357
658
  };
358
659
 
359
660
  /**
@@ -388,6 +689,13 @@ export const CYTOSCAPE_LEXICON: Readonly<
388
689
  ["NODE_BORDER_COLOR", color],
389
690
  ],
390
691
  ],
692
+ [
693
+ "borderOpacity",
694
+ [
695
+ ["NODE_BORDER_TRANSPARENCY", opacity255],
696
+ ["NODE_BORDER_OPACITY", opacity01],
697
+ ],
698
+ ],
391
699
  ["borderWidth", [["NODE_BORDER_WIDTH", length]]],
392
700
  [
393
701
  "borderStyle",
@@ -403,10 +711,25 @@ export const CYTOSCAPE_LEXICON: Readonly<
403
711
  ["label", [["NODE_LABEL", text]]],
404
712
  ["labelColor", [["NODE_LABEL_COLOR", color]]],
405
713
  ["labelSize", [["NODE_LABEL_FONT_SIZE", fontSize]]],
714
+ [
715
+ "labelWrapWidth",
716
+ [
717
+ ["NODE_LABEL_WIDTH", length],
718
+ ["NODE_LABEL_MAX_WIDTH", length],
719
+ ],
720
+ ],
406
721
  ["labelFont", [["NODE_LABEL_FONT_FACE", fontFamily]]],
407
722
  ["labelWeight", [["NODE_LABEL_FONT_FACE", fontWeight]]],
408
723
  ["labelItalic", [["NODE_LABEL_FONT_FACE", fontItalic]]],
409
724
  ["labelPosition", [["NODE_LABEL_POSITION", labelPosition]]],
725
+ ["labelRotation", [["NODE_LABEL_ROTATION", rotation]]],
726
+ [
727
+ "labelOpacity",
728
+ [
729
+ ["NODE_LABEL_TRANSPARENCY", opacity255],
730
+ ["NODE_LABEL_OPACITY", opacity01],
731
+ ],
732
+ ],
410
733
  ["tooltip", [["NODE_TOOLTIP", text]]],
411
734
  [
412
735
  "visible",
@@ -443,6 +766,14 @@ export const CYTOSCAPE_LEXICON: Readonly<
443
766
  ],
444
767
  ["sourceArrow", [["EDGE_SOURCE_ARROW_SHAPE", arrow]]],
445
768
  ["targetArrow", [["EDGE_TARGET_ARROW_SHAPE", arrow]]],
769
+ // One neutral size for both ends: the target's, else the source's.
770
+ [
771
+ "arrowSize",
772
+ [
773
+ ["EDGE_TARGET_ARROW_SIZE", arrowSizeParser],
774
+ ["EDGE_SOURCE_ARROW_SIZE", arrowSizeParser],
775
+ ],
776
+ ],
446
777
  [
447
778
  "sourceArrowColor",
448
779
  [
@@ -464,6 +795,21 @@ export const CYTOSCAPE_LEXICON: Readonly<
464
795
  ["labelFont", [["EDGE_LABEL_FONT_FACE", fontFamily]]],
465
796
  ["labelWeight", [["EDGE_LABEL_FONT_FACE", fontWeight]]],
466
797
  ["labelItalic", [["EDGE_LABEL_FONT_FACE", fontItalic]]],
798
+ [
799
+ "labelWrapWidth",
800
+ [
801
+ ["EDGE_LABEL_WIDTH", length],
802
+ ["EDGE_LABEL_MAX_WIDTH", length],
803
+ ],
804
+ ],
805
+ ["labelRotation", [["EDGE_LABEL_ROTATION", rotation]]],
806
+ [
807
+ "labelOpacity",
808
+ [
809
+ ["EDGE_LABEL_TRANSPARENCY", opacity255],
810
+ ["EDGE_LABEL_OPACITY", opacity01],
811
+ ],
812
+ ],
467
813
  ["tooltip", [["EDGE_TOOLTIP", text]]],
468
814
  [
469
815
  "visible",
@@ -484,6 +830,13 @@ export const sizeParser: CytoscapeValueParser = length;
484
830
  /** The parser of colors, for the network background and `arrowColorMatchesEdge`. */
485
831
  export const colorParser: CytoscapeValueParser = color;
486
832
 
833
+ /**
834
+ * The parser of 0..255 transparencies (desktop) and 0..1 opacities (CX2), by visual property.
835
+ * @param vp - the visual property (`*_TRANSPARENCY` or `*_OPACITY`)
836
+ * @returns its parser
837
+ */
838
+ export const opacityParser = (vp: string): CytoscapeValueParser => (vp.endsWith("_OPACITY") ? opacity01 : opacity255);
839
+
487
840
  /** Every visual property the lexicon reads. */
488
841
  const KNOWN_VPS: ReadonlySet<string> = new Set([
489
842
  NODE_SIZE_VP,