@graphty/graph-io 0.3.48 → 0.3.50

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 (600) hide show
  1. package/dist/chunks/{approximations-C2riR4NT.js → approximations-BRXsll0T.js} +2 -2
  2. package/dist/chunks/{approximations-C2riR4NT.js.map → approximations-BRXsll0T.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-yl0f_qLO.js} +931 -164
  6. package/dist/chunks/block-yl0f_qLO.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-DizmppHy.js} +5 -4
  14. package/dist/chunks/{context-cgmmOxZ2.js.map → context-DizmppHy.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-CmvJXYeH.js} +67 -16
  18. package/dist/chunks/credentials-CmvJXYeH.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-Dhez_Cew.js} +11 -2
  24. package/dist/chunks/descriptor-Dhez_Cew.js.map +1 -0
  25. package/dist/chunks/{emit-CD8xnY8s.js → emit-7Jkpg0yd.js} +1788 -133
  26. package/dist/chunks/emit-7Jkpg0yd.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-ChjL5fmP.js → exporter-1Ajud15J.js} +9 -8
  32. package/dist/chunks/{exporter-ChjL5fmP.js.map → exporter-1Ajud15J.js.map} +1 -1
  33. package/dist/chunks/{exporter-BIdaoIgh.js → exporter-B6yvL3wy.js} +7 -7
  34. package/dist/chunks/{exporter-BIdaoIgh.js.map → exporter-B6yvL3wy.js.map} +1 -1
  35. package/dist/chunks/{exporter-Dcw7Ldtq.js → exporter-BP6otMO6.js} +6 -6
  36. package/dist/chunks/{exporter-Dcw7Ldtq.js.map → exporter-BP6otMO6.js.map} +1 -1
  37. package/dist/chunks/{exporter-DtVU80Fa.js → exporter-CA5q8ROP.js} +9 -8
  38. package/dist/chunks/{exporter-DtVU80Fa.js.map → exporter-CA5q8ROP.js.map} +1 -1
  39. package/dist/chunks/{exporter-bxxjOrDZ.js → exporter-CQQZFJ2v.js} +1284 -156
  40. package/dist/chunks/exporter-CQQZFJ2v.js.map +1 -0
  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-Dc21MAdg.js} +387 -31
  44. package/dist/chunks/generic-Dc21MAdg.js.map +1 -0
  45. package/dist/chunks/{importer-B87_fmVx.js → importer-C6NVpCXp.js} +327 -84
  46. package/dist/chunks/importer-C6NVpCXp.js.map +1 -0
  47. package/dist/chunks/{importer-DPZDN40-.js → importer-CKFe4q54.js} +25 -17
  48. package/dist/chunks/importer-CKFe4q54.js.map +1 -0
  49. package/dist/chunks/{importer-Bji2MeWr.js → importer-CKbUbsJA.js} +13 -10
  50. package/dist/chunks/{importer-Bji2MeWr.js.map → importer-CKbUbsJA.js.map} +1 -1
  51. package/dist/chunks/{importer-CB_zV5_L.js → importer-ClCsdgTJ.js} +208 -1104
  52. package/dist/chunks/importer-ClCsdgTJ.js.map +1 -0
  53. package/dist/chunks/{importer-e3huMZbm.js → importer-CyVZTrf0.js} +14 -10
  54. package/dist/chunks/importer-CyVZTrf0.js.map +1 -0
  55. package/dist/chunks/{importer-CVT-JyDE.js → importer-DgG4v1Ms.js} +1537 -355
  56. package/dist/chunks/importer-DgG4v1Ms.js.map +1 -0
  57. package/dist/chunks/{importer-Cyy6UseH.js → importer-asFUrIsj.js} +66 -13
  58. package/dist/chunks/importer-asFUrIsj.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-IVRq2Uoo.js} +282 -74
  64. package/dist/chunks/lexicon-IVRq2Uoo.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-Cy3_SHRZ.js +79 -0
  72. package/dist/chunks/round-trip-Cy3_SHRZ.js.map +1 -0
  73. package/dist/chunks/{sigv4-LkAzsLAu.js → sigv4-BXwVbza3.js} +5 -5
  74. package/dist/chunks/sigv4-BXwVbza3.js.map +1 -0
  75. package/dist/chunks/{styles-CaABMoO1.js → styles-CAVmBLgp.js} +1237 -138
  76. package/dist/chunks/styles-CAVmBLgp.js.map +1 -0
  77. package/dist/chunks/styles-CPczw1Jz.js +1928 -0
  78. package/dist/chunks/styles-CPczw1Jz.js.map +1 -0
  79. package/dist/chunks/styles-boK6Ln54.js +2847 -0
  80. package/dist/chunks/styles-boK6Ln54.js.map +1 -0
  81. package/dist/chunks/{styles-yed-Cs1nmrjn.js → styles-yed-XeFBQ6VS.js} +506 -175
  82. package/dist/chunks/styles-yed-XeFBQ6VS.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 +8 -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 +848 -194
  94. package/dist/gml.js.map +1 -1
  95. package/dist/graph-io.js +230 -193
  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 +141 -23
  105. package/dist/sources-cypher.js.map +1 -1
  106. package/dist/sources-ndex.js +2 -2
  107. package/dist/sources-rest.js +32 -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 +439 -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/exporter.d.ts.map +1 -1
  137. package/dist/src/formats/dot/exporter.js +34 -2
  138. package/dist/src/formats/dot/exporter.js.map +1 -1
  139. package/dist/src/formats/dot/importer.d.ts +6 -1
  140. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  141. package/dist/src/formats/dot/importer.js +170 -33
  142. package/dist/src/formats/dot/importer.js.map +1 -1
  143. package/dist/src/formats/dot/index.d.ts +3 -1
  144. package/dist/src/formats/dot/index.d.ts.map +1 -1
  145. package/dist/src/formats/dot/index.js +2 -1
  146. package/dist/src/formats/dot/index.js.map +1 -1
  147. package/dist/src/formats/dot/label-places.d.ts +41 -0
  148. package/dist/src/formats/dot/label-places.d.ts.map +1 -0
  149. package/dist/src/formats/dot/label-places.js +185 -0
  150. package/dist/src/formats/dot/label-places.js.map +1 -0
  151. package/dist/src/formats/dot/names.d.ts +13 -0
  152. package/dist/src/formats/dot/names.d.ts.map +1 -1
  153. package/dist/src/formats/dot/names.js +13 -0
  154. package/dist/src/formats/dot/names.js.map +1 -1
  155. package/dist/src/formats/dot/record.d.ts +50 -0
  156. package/dist/src/formats/dot/record.d.ts.map +1 -0
  157. package/dist/src/formats/dot/record.js +275 -0
  158. package/dist/src/formats/dot/record.js.map +1 -0
  159. package/dist/src/formats/dot/styles.d.ts +72 -2
  160. package/dist/src/formats/dot/styles.d.ts.map +1 -1
  161. package/dist/src/formats/dot/styles.js +1500 -119
  162. package/dist/src/formats/dot/styles.js.map +1 -1
  163. package/dist/src/formats/gexf/dialog-metrics.d.ts +15 -0
  164. package/dist/src/formats/gexf/dialog-metrics.d.ts.map +1 -0
  165. package/dist/src/formats/gexf/dialog-metrics.js +59 -0
  166. package/dist/src/formats/gexf/dialog-metrics.js.map +1 -0
  167. package/dist/src/formats/gexf/importer.d.ts +7 -0
  168. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  169. package/dist/src/formats/gexf/importer.js +41 -5
  170. package/dist/src/formats/gexf/importer.js.map +1 -1
  171. package/dist/src/formats/gexf/preview.d.ts +77 -0
  172. package/dist/src/formats/gexf/preview.d.ts.map +1 -0
  173. package/dist/src/formats/gexf/preview.js +191 -0
  174. package/dist/src/formats/gexf/preview.js.map +1 -0
  175. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  176. package/dist/src/formats/gexf/schema.js +2 -1
  177. package/dist/src/formats/gexf/schema.js.map +1 -1
  178. package/dist/src/formats/gexf/styles.d.ts +58 -31
  179. package/dist/src/formats/gexf/styles.d.ts.map +1 -1
  180. package/dist/src/formats/gexf/styles.js +848 -225
  181. package/dist/src/formats/gexf/styles.js.map +1 -1
  182. package/dist/src/formats/gml/importer.d.ts +5 -2
  183. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  184. package/dist/src/formats/gml/importer.js +258 -71
  185. package/dist/src/formats/gml/importer.js.map +1 -1
  186. package/dist/src/formats/gml/index.d.ts +1 -1
  187. package/dist/src/formats/gml/index.d.ts.map +1 -1
  188. package/dist/src/formats/gml/index.js +1 -1
  189. package/dist/src/formats/gml/index.js.map +1 -1
  190. package/dist/src/formats/gml/positions.d.ts +7 -0
  191. package/dist/src/formats/gml/positions.d.ts.map +1 -1
  192. package/dist/src/formats/gml/positions.js +29 -7
  193. package/dist/src/formats/gml/positions.js.map +1 -1
  194. package/dist/src/formats/gml/styles.d.ts.map +1 -1
  195. package/dist/src/formats/gml/styles.js +754 -102
  196. package/dist/src/formats/gml/styles.js.map +1 -1
  197. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
  198. package/dist/src/formats/graphml/styles-plain.js +6 -10
  199. package/dist/src/formats/graphml/styles-plain.js.map +1 -1
  200. package/dist/src/formats/graphml/styles-yed.d.ts +21 -15
  201. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
  202. package/dist/src/formats/graphml/styles-yed.js +695 -164
  203. package/dist/src/formats/graphml/styles-yed.js.map +1 -1
  204. package/dist/src/formats/graphml/styles-yfiles3.d.ts +1 -1
  205. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -1
  206. package/dist/src/formats/graphml/styles-yfiles3.js +431 -64
  207. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -1
  208. package/dist/src/formats/graphml/yfiles.d.ts +3 -3
  209. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  210. package/dist/src/formats/graphml/yfiles.js +16 -6
  211. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  212. package/dist/src/formats/json/dialect.d.ts +3 -2
  213. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  214. package/dist/src/formats/json/dialect.js +39 -5
  215. package/dist/src/formats/json/dialect.js.map +1 -1
  216. package/dist/src/formats/json/importer.d.ts +13 -2
  217. package/dist/src/formats/json/importer.d.ts.map +1 -1
  218. package/dist/src/formats/json/importer.js +42 -6
  219. package/dist/src/formats/json/importer.js.map +1 -1
  220. package/dist/src/formats/json/index.d.ts +1 -1
  221. package/dist/src/formats/json/index.d.ts.map +1 -1
  222. package/dist/src/formats/json/index.js +1 -1
  223. package/dist/src/formats/json/index.js.map +1 -1
  224. package/dist/src/formats/json/positions.d.ts +5 -2
  225. package/dist/src/formats/json/positions.d.ts.map +1 -1
  226. package/dist/src/formats/json/positions.js +20 -4
  227. package/dist/src/formats/json/positions.js.map +1 -1
  228. package/dist/src/formats/json/styles.d.ts +12 -1
  229. package/dist/src/formats/json/styles.d.ts.map +1 -1
  230. package/dist/src/formats/json/styles.js +1843 -136
  231. package/dist/src/formats/json/styles.js.map +1 -1
  232. package/dist/src/formats/pajek/draw.d.ts +104 -0
  233. package/dist/src/formats/pajek/draw.d.ts.map +1 -0
  234. package/dist/src/formats/pajek/draw.js +382 -0
  235. package/dist/src/formats/pajek/draw.js.map +1 -0
  236. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  237. package/dist/src/formats/pajek/exporter.js +70 -51
  238. package/dist/src/formats/pajek/exporter.js.map +1 -1
  239. package/dist/src/formats/pajek/importer.d.ts +9 -0
  240. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  241. package/dist/src/formats/pajek/importer.js +233 -102
  242. package/dist/src/formats/pajek/importer.js.map +1 -1
  243. package/dist/src/formats/pajek/index.d.ts +1 -0
  244. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  245. package/dist/src/formats/pajek/index.js.map +1 -1
  246. package/dist/src/formats/pajek/styles.d.ts +15 -7
  247. package/dist/src/formats/pajek/styles.d.ts.map +1 -1
  248. package/dist/src/formats/pajek/styles.js +1395 -114
  249. package/dist/src/formats/pajek/styles.js.map +1 -1
  250. package/dist/src/formats/pajek/syntax.d.ts +10 -1
  251. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  252. package/dist/src/formats/pajek/syntax.js +26 -2
  253. package/dist/src/formats/pajek/syntax.js.map +1 -1
  254. package/dist/src/formats/xgmml/emit.d.ts +1 -0
  255. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  256. package/dist/src/formats/xgmml/emit.js +65 -5
  257. package/dist/src/formats/xgmml/emit.js.map +1 -1
  258. package/dist/src/formats/xgmml/styles.d.ts +23 -3
  259. package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
  260. package/dist/src/formats/xgmml/styles.js +277 -60
  261. package/dist/src/formats/xgmml/styles.js.map +1 -1
  262. package/dist/src/index.d.ts +6 -5
  263. package/dist/src/index.d.ts.map +1 -1
  264. package/dist/src/index.js +6 -5
  265. package/dist/src/index.js.map +1 -1
  266. package/dist/src/positions/convert.d.ts.map +1 -1
  267. package/dist/src/positions/convert.js +11 -1
  268. package/dist/src/positions/convert.js.map +1 -1
  269. package/dist/src/positions/extract.d.ts.map +1 -1
  270. package/dist/src/positions/extract.js +53 -1
  271. package/dist/src/positions/extract.js.map +1 -1
  272. package/dist/src/positions/index.d.ts +1 -1
  273. package/dist/src/positions/index.d.ts.map +1 -1
  274. package/dist/src/positions/types.d.ts +59 -0
  275. package/dist/src/positions/types.d.ts.map +1 -1
  276. package/dist/src/sources/builtins.d.ts +1 -1
  277. package/dist/src/sources/builtins.d.ts.map +1 -1
  278. package/dist/src/sources/builtins.js +8 -2
  279. package/dist/src/sources/builtins.js.map +1 -1
  280. package/dist/src/sources/context.d.ts.map +1 -1
  281. package/dist/src/sources/context.js +1 -0
  282. package/dist/src/sources/context.js.map +1 -1
  283. package/dist/src/sources/credentials.d.ts +50 -1
  284. package/dist/src/sources/credentials.d.ts.map +1 -1
  285. package/dist/src/sources/credentials.js +69 -0
  286. package/dist/src/sources/credentials.js.map +1 -1
  287. package/dist/src/sources/cypher/descriptor.d.ts.map +1 -1
  288. package/dist/src/sources/cypher/descriptor.js +5 -0
  289. package/dist/src/sources/cypher/descriptor.js.map +1 -1
  290. package/dist/src/sources/cypher/index.d.ts.map +1 -1
  291. package/dist/src/sources/cypher/index.js +125 -18
  292. package/dist/src/sources/cypher/index.js.map +1 -1
  293. package/dist/src/sources/cypher/params.d.ts +1 -1
  294. package/dist/src/sources/cypher/params.d.ts.map +1 -1
  295. package/dist/src/sources/cypher/query-builder.d.ts +17 -0
  296. package/dist/src/sources/cypher/query-builder.d.ts.map +1 -1
  297. package/dist/src/sources/cypher/query-builder.js +31 -0
  298. package/dist/src/sources/cypher/query-builder.js.map +1 -1
  299. package/dist/src/sources/ids.d.ts +5 -0
  300. package/dist/src/sources/ids.d.ts.map +1 -1
  301. package/dist/src/sources/ids.js +5 -0
  302. package/dist/src/sources/ids.js.map +1 -1
  303. package/dist/src/sources/params.d.ts +3 -0
  304. package/dist/src/sources/params.d.ts.map +1 -1
  305. package/dist/src/sources/rest/descriptor.d.ts.map +1 -1
  306. package/dist/src/sources/rest/descriptor.js +9 -0
  307. package/dist/src/sources/rest/descriptor.js.map +1 -1
  308. package/dist/src/sources/rest/openalex.d.ts +4 -2
  309. package/dist/src/sources/rest/openalex.d.ts.map +1 -1
  310. package/dist/src/sources/rest/openalex.js +4 -2
  311. package/dist/src/sources/rest/openalex.js.map +1 -1
  312. package/dist/src/sources/rest/source.d.ts.map +1 -1
  313. package/dist/src/sources/rest/source.js +38 -0
  314. package/dist/src/sources/rest/source.js.map +1 -1
  315. package/dist/src/sources/run.d.ts +2 -0
  316. package/dist/src/sources/run.d.ts.map +1 -1
  317. package/dist/src/sources/run.js +30 -3
  318. package/dist/src/sources/run.js.map +1 -1
  319. package/dist/src/sources/sigv4.d.ts +5 -3
  320. package/dist/src/sources/sigv4.d.ts.map +1 -1
  321. package/dist/src/sources/sigv4.js +6 -4
  322. package/dist/src/sources/sigv4.js.map +1 -1
  323. package/dist/src/sources/sparql/descriptor.d.ts +10 -0
  324. package/dist/src/sources/sparql/descriptor.d.ts.map +1 -0
  325. package/dist/src/sources/sparql/descriptor.js +64 -0
  326. package/dist/src/sources/sparql/descriptor.js.map +1 -0
  327. package/dist/src/sources/sparql/index.d.ts +28 -0
  328. package/dist/src/sources/sparql/index.d.ts.map +1 -0
  329. package/dist/src/sources/sparql/index.js +327 -0
  330. package/dist/src/sources/sparql/index.js.map +1 -0
  331. package/dist/src/sources/sparql/ntriples.d.ts +69 -0
  332. package/dist/src/sources/sparql/ntriples.d.ts.map +1 -0
  333. package/dist/src/sources/sparql/ntriples.js +180 -0
  334. package/dist/src/sources/sparql/ntriples.js.map +1 -0
  335. package/dist/src/sources/sparql/params.d.ts +27 -0
  336. package/dist/src/sources/sparql/params.d.ts.map +1 -0
  337. package/dist/src/sources/sparql/params.js +5 -0
  338. package/dist/src/sources/sparql/params.js.map +1 -0
  339. package/dist/src/sources/sparql/query.d.ts +73 -0
  340. package/dist/src/sources/sparql/query.d.ts.map +1 -0
  341. package/dist/src/sources/sparql/query.js +164 -0
  342. package/dist/src/sources/sparql/query.js.map +1 -0
  343. package/dist/src/sources/types.d.ts +60 -0
  344. package/dist/src/sources/types.d.ts.map +1 -1
  345. package/dist/src/styles/annotations.d.ts +61 -5
  346. package/dist/src/styles/annotations.d.ts.map +1 -1
  347. package/dist/src/styles/annotations.js +130 -22
  348. package/dist/src/styles/annotations.js.map +1 -1
  349. package/dist/src/styles/canon/bends.d.ts +46 -0
  350. package/dist/src/styles/canon/bends.d.ts.map +1 -1
  351. package/dist/src/styles/canon/bends.js +123 -0
  352. package/dist/src/styles/canon/bends.js.map +1 -1
  353. package/dist/src/styles/canon/color-tables.d.ts +6 -1
  354. package/dist/src/styles/canon/color-tables.d.ts.map +1 -1
  355. package/dist/src/styles/canon/color-tables.js +10 -4
  356. package/dist/src/styles/canon/color-tables.js.map +1 -1
  357. package/dist/src/styles/canon/color.d.ts +3 -1
  358. package/dist/src/styles/canon/color.d.ts.map +1 -1
  359. package/dist/src/styles/canon/color.js +103 -3
  360. package/dist/src/styles/canon/color.js.map +1 -1
  361. package/dist/src/styles/canon/enums.d.ts +2 -2
  362. package/dist/src/styles/canon/enums.d.ts.map +1 -1
  363. package/dist/src/styles/canon/enums.js +89 -7
  364. package/dist/src/styles/canon/enums.js.map +1 -1
  365. package/dist/src/styles/canon/graphviz.d.ts +12 -3
  366. package/dist/src/styles/canon/graphviz.d.ts.map +1 -1
  367. package/dist/src/styles/canon/graphviz.js +57 -9
  368. package/dist/src/styles/canon/graphviz.js.map +1 -1
  369. package/dist/src/styles/canon/number.d.ts +8 -0
  370. package/dist/src/styles/canon/number.d.ts.map +1 -1
  371. package/dist/src/styles/canon/number.js +18 -0
  372. package/dist/src/styles/canon/number.js.map +1 -1
  373. package/dist/src/styles/canon/text.d.ts +29 -2
  374. package/dist/src/styles/canon/text.d.ts.map +1 -1
  375. package/dist/src/styles/canon/text.js +156 -16
  376. package/dist/src/styles/canon/text.js.map +1 -1
  377. package/dist/src/styles/codes.d.ts +2 -0
  378. package/dist/src/styles/codes.d.ts.map +1 -1
  379. package/dist/src/styles/codes.js +2 -0
  380. package/dist/src/styles/codes.js.map +1 -1
  381. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
  382. package/dist/src/styles/cyjs/cascade.js +1139 -79
  383. package/dist/src/styles/cyjs/cascade.js.map +1 -1
  384. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
  385. package/dist/src/styles/cyjs/defaults-table.js +4 -0
  386. package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
  387. package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
  388. package/dist/src/styles/cyjs/emit.js +232 -10
  389. package/dist/src/styles/cyjs/emit.js.map +1 -1
  390. package/dist/src/styles/cyjs/face.d.ts +20 -0
  391. package/dist/src/styles/cyjs/face.d.ts.map +1 -0
  392. package/dist/src/styles/cyjs/face.js +332 -0
  393. package/dist/src/styles/cyjs/face.js.map +1 -0
  394. package/dist/src/styles/cyjs/mappers.d.ts +44 -1
  395. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
  396. package/dist/src/styles/cyjs/mappers.js +475 -26
  397. package/dist/src/styles/cyjs/mappers.js.map +1 -1
  398. package/dist/src/styles/cyjs/routes.d.ts +53 -0
  399. package/dist/src/styles/cyjs/routes.d.ts.map +1 -0
  400. package/dist/src/styles/cyjs/routes.js +360 -0
  401. package/dist/src/styles/cyjs/routes.js.map +1 -0
  402. package/dist/src/styles/cytoscape/charts.d.ts +23 -0
  403. package/dist/src/styles/cytoscape/charts.d.ts.map +1 -0
  404. package/dist/src/styles/cytoscape/charts.js +560 -0
  405. package/dist/src/styles/cytoscape/charts.js.map +1 -0
  406. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
  407. package/dist/src/styles/cytoscape/emit.js +156 -48
  408. package/dist/src/styles/cytoscape/emit.js.map +1 -1
  409. package/dist/src/styles/cytoscape/lexicon.d.ts +91 -3
  410. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
  411. package/dist/src/styles/cytoscape/lexicon.js +387 -77
  412. package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
  413. package/dist/src/styles/cytoscape/mappings.d.ts +30 -0
  414. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -1
  415. package/dist/src/styles/cytoscape/mappings.js +92 -0
  416. package/dist/src/styles/cytoscape/mappings.js.map +1 -1
  417. package/dist/src/styles/cytoscape/resolve.d.ts +42 -2
  418. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
  419. package/dist/src/styles/cytoscape/resolve.js +623 -17
  420. package/dist/src/styles/cytoscape/resolve.js.map +1 -1
  421. package/dist/src/styles/defaults.d.ts +46 -26
  422. package/dist/src/styles/defaults.d.ts.map +1 -1
  423. package/dist/src/styles/defaults.js +308 -71
  424. package/dist/src/styles/defaults.js.map +1 -1
  425. package/dist/src/styles/index.d.ts +4 -3
  426. package/dist/src/styles/index.d.ts.map +1 -1
  427. package/dist/src/styles/index.js +3 -2
  428. package/dist/src/styles/index.js.map +1 -1
  429. package/dist/src/styles/internal.d.ts +1 -0
  430. package/dist/src/styles/internal.d.ts.map +1 -1
  431. package/dist/src/styles/internal.js +1 -0
  432. package/dist/src/styles/internal.js.map +1 -1
  433. package/dist/src/styles/io/generic.d.ts.map +1 -1
  434. package/dist/src/styles/io/generic.js +56 -16
  435. package/dist/src/styles/io/generic.js.map +1 -1
  436. package/dist/src/styles/io/round-trip.d.ts +56 -0
  437. package/dist/src/styles/io/round-trip.d.ts.map +1 -0
  438. package/dist/src/styles/io/round-trip.js +138 -0
  439. package/dist/src/styles/io/round-trip.js.map +1 -0
  440. package/dist/src/styles/io/writer.d.ts.map +1 -1
  441. package/dist/src/styles/io/writer.js +6 -1
  442. package/dist/src/styles/io/writer.js.map +1 -1
  443. package/dist/src/styles/notes.d.ts.map +1 -1
  444. package/dist/src/styles/notes.js +1 -0
  445. package/dist/src/styles/notes.js.map +1 -1
  446. package/dist/src/styles/plan/features.d.ts +1 -1
  447. package/dist/src/styles/plan/features.d.ts.map +1 -1
  448. package/dist/src/styles/plan/features.js +22 -2
  449. package/dist/src/styles/plan/features.js.map +1 -1
  450. package/dist/src/styles/plan/index.d.ts +1 -1
  451. package/dist/src/styles/plan/index.d.ts.map +1 -1
  452. package/dist/src/styles/plan/index.js +1 -1
  453. package/dist/src/styles/plan/index.js.map +1 -1
  454. package/dist/src/styles/plan/plan.d.ts.map +1 -1
  455. package/dist/src/styles/plan/plan.js +61 -4
  456. package/dist/src/styles/plan/plan.js.map +1 -1
  457. package/dist/src/styles/plan/resolve.d.ts +11 -0
  458. package/dist/src/styles/plan/resolve.d.ts.map +1 -1
  459. package/dist/src/styles/plan/resolve.js +40 -4
  460. package/dist/src/styles/plan/resolve.js.map +1 -1
  461. package/dist/src/styles/slots.d.ts +14 -0
  462. package/dist/src/styles/slots.d.ts.map +1 -0
  463. package/dist/src/styles/slots.js +20 -0
  464. package/dist/src/styles/slots.js.map +1 -0
  465. package/dist/src/styles/types.d.ts +687 -6
  466. package/dist/src/styles/types.d.ts.map +1 -1
  467. package/dist/src/styles/vocabulary.d.ts +3 -2
  468. package/dist/src/styles/vocabulary.d.ts.map +1 -1
  469. package/dist/src/styles/vocabulary.js +224 -0
  470. package/dist/src/styles/vocabulary.js.map +1 -1
  471. package/dist/styles.js +30 -239
  472. package/dist/styles.js.map +1 -1
  473. package/dist/xgmml.js +3 -3
  474. package/package.json +27 -7
  475. package/src/formats/cx/importer.ts +6 -1
  476. package/src/formats/cx/styles.ts +143 -9
  477. package/src/formats/cx2/importer.ts +1 -0
  478. package/src/formats/cx2/styles.ts +3 -1
  479. package/src/formats/cys/importer.ts +1 -0
  480. package/src/formats/cys/styles.ts +27 -5
  481. package/src/formats/dot/drawing.ts +799 -0
  482. package/src/formats/dot/exporter.ts +37 -1
  483. package/src/formats/dot/importer.ts +192 -36
  484. package/src/formats/dot/index.ts +3 -1
  485. package/src/formats/dot/label-places.ts +241 -0
  486. package/src/formats/dot/names.ts +15 -0
  487. package/src/formats/dot/record.ts +336 -0
  488. package/src/formats/dot/styles.ts +1702 -149
  489. package/src/formats/gexf/dialog-metrics.ts +61 -0
  490. package/src/formats/gexf/importer.ts +50 -5
  491. package/src/formats/gexf/preview.ts +217 -0
  492. package/src/formats/gexf/schema.ts +2 -1
  493. package/src/formats/gexf/styles.ts +1099 -245
  494. package/src/formats/gml/importer.ts +291 -76
  495. package/src/formats/gml/index.ts +1 -1
  496. package/src/formats/gml/positions.ts +29 -7
  497. package/src/formats/gml/styles.ts +852 -110
  498. package/src/formats/graphml/styles-plain.ts +6 -15
  499. package/src/formats/graphml/styles-yed.ts +765 -176
  500. package/src/formats/graphml/styles-yfiles3.ts +487 -63
  501. package/src/formats/graphml/yfiles.ts +19 -6
  502. package/src/formats/json/dialect.ts +41 -5
  503. package/src/formats/json/importer.ts +59 -7
  504. package/src/formats/json/index.ts +1 -0
  505. package/src/formats/json/positions.ts +22 -5
  506. package/src/formats/json/styles.ts +2123 -171
  507. package/src/formats/pajek/draw.ts +469 -0
  508. package/src/formats/pajek/exporter.ts +81 -49
  509. package/src/formats/pajek/importer.ts +278 -103
  510. package/src/formats/pajek/index.ts +1 -0
  511. package/src/formats/pajek/styles.ts +1506 -133
  512. package/src/formats/pajek/syntax.ts +27 -2
  513. package/src/formats/xgmml/emit.ts +73 -5
  514. package/src/formats/xgmml/styles.ts +330 -71
  515. package/src/index.ts +12 -1
  516. package/src/positions/convert.ts +12 -1
  517. package/src/positions/extract.ts +55 -1
  518. package/src/positions/index.ts +1 -0
  519. package/src/positions/types.ts +60 -0
  520. package/src/sources/builtins.ts +8 -1
  521. package/src/sources/context.ts +1 -0
  522. package/src/sources/credentials.ts +90 -1
  523. package/src/sources/cypher/descriptor.ts +7 -1
  524. package/src/sources/cypher/index.ts +149 -18
  525. package/src/sources/cypher/params.ts +1 -1
  526. package/src/sources/cypher/query-builder.ts +33 -0
  527. package/src/sources/ids.ts +6 -0
  528. package/src/sources/params.ts +3 -0
  529. package/src/sources/rest/descriptor.ts +9 -0
  530. package/src/sources/rest/openalex.ts +4 -2
  531. package/src/sources/rest/source.ts +41 -0
  532. package/src/sources/run.ts +35 -3
  533. package/src/sources/sigv4.ts +6 -4
  534. package/src/sources/sparql/descriptor.ts +67 -0
  535. package/src/sources/sparql/index.ts +371 -0
  536. package/src/sources/sparql/ntriples.ts +219 -0
  537. package/src/sources/sparql/params.ts +28 -0
  538. package/src/sources/sparql/query.ts +216 -0
  539. package/src/sources/types.ts +68 -0
  540. package/src/styles/annotations.ts +201 -27
  541. package/src/styles/canon/bends.ts +137 -0
  542. package/src/styles/canon/color-tables.ts +10 -4
  543. package/src/styles/canon/color.ts +105 -3
  544. package/src/styles/canon/enums.ts +107 -8
  545. package/src/styles/canon/graphviz.ts +71 -10
  546. package/src/styles/canon/number.ts +19 -0
  547. package/src/styles/canon/text.ts +187 -16
  548. package/src/styles/codes.ts +2 -0
  549. package/src/styles/cyjs/cascade.ts +1303 -84
  550. package/src/styles/cyjs/defaults-table.ts +4 -0
  551. package/src/styles/cyjs/emit.ts +268 -14
  552. package/src/styles/cyjs/face.ts +372 -0
  553. package/src/styles/cyjs/mappers.ts +506 -27
  554. package/src/styles/cyjs/routes.ts +432 -0
  555. package/src/styles/cytoscape/charts.ts +684 -0
  556. package/src/styles/cytoscape/emit.ts +170 -48
  557. package/src/styles/cytoscape/lexicon.ts +431 -78
  558. package/src/styles/cytoscape/mappings.ts +108 -0
  559. package/src/styles/cytoscape/resolve.ts +741 -17
  560. package/src/styles/defaults.ts +417 -108
  561. package/src/styles/index.ts +5 -0
  562. package/src/styles/internal.ts +1 -0
  563. package/src/styles/io/generic.ts +79 -23
  564. package/src/styles/io/round-trip.ts +202 -0
  565. package/src/styles/io/writer.ts +6 -1
  566. package/src/styles/notes.ts +1 -0
  567. package/src/styles/plan/features.ts +23 -2
  568. package/src/styles/plan/index.ts +1 -1
  569. package/src/styles/plan/plan.ts +69 -5
  570. package/src/styles/plan/resolve.ts +47 -4
  571. package/src/styles/slots.ts +25 -0
  572. package/src/styles/types.ts +698 -5
  573. package/src/styles/vocabulary.ts +232 -2
  574. package/dist/chunks/block-Cu22ewuS.js.map +0 -1
  575. package/dist/chunks/choose-Cdx6Enl2.js +0 -57
  576. package/dist/chunks/choose-Cdx6Enl2.js.map +0 -1
  577. package/dist/chunks/codes-CV_Bhcyi.js.map +0 -1
  578. package/dist/chunks/convert-BcQ8_jMo.js.map +0 -1
  579. package/dist/chunks/credentials-BiQsnMTb.js.map +0 -1
  580. package/dist/chunks/descriptor-BJ-W0Jd-.js.map +0 -1
  581. package/dist/chunks/emit-CD8xnY8s.js.map +0 -1
  582. package/dist/chunks/export-CZ7VRm4I.js.map +0 -1
  583. package/dist/chunks/exporter-bxxjOrDZ.js.map +0 -1
  584. package/dist/chunks/format-BMS-1Nxb.js +0 -64
  585. package/dist/chunks/format-BMS-1Nxb.js.map +0 -1
  586. package/dist/chunks/generic-CP6YD34u.js.map +0 -1
  587. package/dist/chunks/importer-B87_fmVx.js.map +0 -1
  588. package/dist/chunks/importer-CB_zV5_L.js.map +0 -1
  589. package/dist/chunks/importer-CVT-JyDE.js.map +0 -1
  590. package/dist/chunks/importer-Cyy6UseH.js.map +0 -1
  591. package/dist/chunks/importer-DPZDN40-.js.map +0 -1
  592. package/dist/chunks/importer-e3huMZbm.js.map +0 -1
  593. package/dist/chunks/lexicon-u2SI5xcx.js.map +0 -1
  594. package/dist/chunks/sigv4-LkAzsLAu.js.map +0 -1
  595. package/dist/chunks/styles-CaABMoO1.js.map +0 -1
  596. package/dist/chunks/styles-P_gmFAOi.js +0 -770
  597. package/dist/chunks/styles-P_gmFAOi.js.map +0 -1
  598. package/dist/chunks/styles-yed-Cs1nmrjn.js.map +0 -1
  599. package/dist/chunks/writer-DvHTl36J.js +0 -449
  600. package/dist/chunks/writer-DvHTl36J.js.map +0 -1
@@ -1,4 +1,5 @@
1
- import { a as STYLE_ISSUE, i as num6, l as canonEnum, W as CSS_COLORS, u as StyleNotes, d as canonicalFor, p as plainCell, Q as evalContinuous, R as numberOf, e as degreeValues, L as refSource, C as STYLE_PROPERTIES, O as resolveRules, P as matches } from "./block-Cu22ewuS.js";
1
+ import { i as num6, a as canonEnum, b as STYLE_ISSUE, d as canonColor, _ as CSS_COLORS, h as StyleNotes, C as canonicalFor, p as plainCell, W as evalContinuous, X as numberOf, D as degreeValues, Q as refSource, w as STYLE_PROPERTIES, U as resolveRules, V as matches } from "./block-yl0f_qLO.js";
2
+ import { d as canonBends, c as canonNodeOffsets, a as flattenQuadSpline } from "./bends-BGXjv_U4.js";
2
3
  const STYLE_WORK_BUDGET = 2e8;
3
4
  class StyleBudget {
4
5
  #used = { node: 0, edge: 0 };
@@ -41,6 +42,7 @@ const CYJS_PROPERTY_DEFAULTS = /* @__PURE__ */ new Map([
41
42
  ["background-opacity", "1"],
42
43
  ["opacity", "1"],
43
44
  ["border-color", "rgb(0,0,0)"],
45
+ ["border-opacity", "1"],
44
46
  ["border-width", "0px"],
45
47
  ["border-style", "solid"],
46
48
  ["shape", "ellipse"],
@@ -56,6 +58,8 @@ const CYJS_PROPERTY_DEFAULTS = /* @__PURE__ */ new Map([
56
58
  ["display", "element"],
57
59
  ["text-valign", "top"],
58
60
  ["text-halign", "center"],
61
+ ["text-wrap", "none"],
62
+ ["text-max-width", "9999px"],
59
63
  ["line-color", "rgb(153,153,153)"],
60
64
  ["line-style", "solid"],
61
65
  ["target-arrow-shape", "none"],
@@ -74,6 +78,7 @@ const CYJS_DEFAULT_STYLESHEET = [
74
78
  selector: ":parent",
75
79
  style: {
76
80
  shape: "rectangle",
81
+ padding: "10px",
77
82
  "background-color": "rgb(238,238,238)",
78
83
  "border-color": "rgb(204,204,204)",
79
84
  "border-width": "1px"
@@ -96,6 +101,239 @@ const CYJS_DEFAULT_STYLESHEET = [
96
101
  style: { "background-color": "rgb(204,225,249)", "border-color": "rgb(174,200,229)" }
97
102
  }
98
103
  ];
104
+ const PIECES = 16;
105
+ const text = (property) => ({ property, type: "text" });
106
+ const color = (property) => ({ property, type: "color" });
107
+ const CYJS_FACE_PROPERTIES = [
108
+ ["background-image", text("_bgImage")],
109
+ ["background-fit", text("_bgFit")],
110
+ ["background-width", text("_bgWidth")],
111
+ ["background-height", text("_bgHeight")],
112
+ ["background-width-relative-to", text("_bgWidthRel")],
113
+ ["background-height-relative-to", text("_bgHeightRel")],
114
+ ["background-position-x", text("_bgPosX")],
115
+ ["background-position-y", text("_bgPosY")],
116
+ ["background-offset-x", text("_bgOffX")],
117
+ ["background-offset-y", text("_bgOffY")],
118
+ ["background-repeat", text("_bgRepeat")],
119
+ ["background-clip", text("_bgClip")],
120
+ ["background-image-smoothing", text("_bgSmooth")],
121
+ ["background-image-opacity", text("_bgOpacity")],
122
+ ["pie-size", text("_pieSize")],
123
+ ["pie-hole", text("_pieHole")],
124
+ ["pie-start-angle", text("_pieStart")],
125
+ ["stripe-size", text("_stripeSize")],
126
+ ["stripe-direction", text("_stripeDir")],
127
+ ...Array.from({ length: PIECES }, (_, k) => [
128
+ [`pie-${String(k + 1)}-background-color`, color(`_pieC${String(k + 1)}`)],
129
+ [`pie-${String(k + 1)}-background-size`, text(`_pieS${String(k + 1)}`)],
130
+ [`pie-${String(k + 1)}-background-opacity`, text(`_pieO${String(k + 1)}`)],
131
+ [`stripe-${String(k + 1)}-background-color`, color(`_stripeC${String(k + 1)}`)],
132
+ [`stripe-${String(k + 1)}-background-size`, text(`_stripeS${String(k + 1)}`)],
133
+ [`stripe-${String(k + 1)}-background-opacity`, text(`_stripeO${String(k + 1)}`)]
134
+ ]).flat()
135
+ ];
136
+ function measure(word) {
137
+ const m = /^(-?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)\s*([a-z%]*)$/i.exec((word ?? "").trim());
138
+ return m === null ? null : [Number(m[1]), m[2].toLowerCase()];
139
+ }
140
+ const r6 = (v) => Math.round(v * 1e6) / 1e6;
141
+ function length(word, of) {
142
+ const m = measure(word);
143
+ if (m === null) {
144
+ return null;
145
+ }
146
+ let out = null;
147
+ if (m[1] === "%") {
148
+ out = of === null ? null : m[0] / 100 * of;
149
+ } else if (m[1] === "px" || m[1] === "") {
150
+ out = m[0];
151
+ }
152
+ return out === null || out < 0 ? null : r6(out);
153
+ }
154
+ function paddingPixels(word) {
155
+ const x = Number.parseFloat(word ?? "");
156
+ if (!Number.isFinite(x) || x <= 0) {
157
+ return 0;
158
+ }
159
+ return (word ?? "").trim().endsWith("%") ? x / 100 : x;
160
+ }
161
+ function fraction(word) {
162
+ const m = measure(word);
163
+ if (m === null) {
164
+ return null;
165
+ }
166
+ if (m[1] === "%") {
167
+ return r6(m[0] / 100);
168
+ }
169
+ return m[1] === "" ? r6(m[0]) : null;
170
+ }
171
+ function firstImage(word) {
172
+ const first = (word ?? "").trim().split(/\s+/)[0] ?? "";
173
+ const unwrapped = /^url\((['"]?)(.*)\1\)$/.exec(first)?.[2] ?? first;
174
+ return unwrapped === "" || unwrapped === "none" ? null : unwrapped;
175
+ }
176
+ function degrees(word) {
177
+ const m = measure(word);
178
+ if (m === null) {
179
+ return null;
180
+ }
181
+ if (m[1] !== "rad" && m[1] !== "deg" && m[1] !== "") {
182
+ return null;
183
+ }
184
+ const deg = m[1] === "rad" ? m[0] * 180 / Math.PI : m[0];
185
+ return r6((deg % 360 + 360) % 360);
186
+ }
187
+ function pieces(words, prefix, i) {
188
+ const colors = [];
189
+ const sizes = [];
190
+ const opacities = [];
191
+ for (let k = 1; k <= PIECES; k++) {
192
+ const m = measure(words.get(`${prefix}S${String(k)}`)?.[i]);
193
+ const size = m !== null && (m[1] === "%" || m[1] === "") ? r6(m[0] / 100) : null;
194
+ if (size === null || size <= 0) {
195
+ continue;
196
+ }
197
+ colors.push(words.get(`${prefix}C${String(k)}`)?.[i] ?? "#000000");
198
+ sizes.push(String(size));
199
+ const o = Number(words.get(`${prefix}O${String(k)}`)?.[i] ?? "1");
200
+ opacities.push(String(Number.isFinite(o) ? Math.max(0, Math.min(1, o)) : 1));
201
+ }
202
+ if (colors.length === 0) {
203
+ return null;
204
+ }
205
+ return {
206
+ colors: colors.join(" "),
207
+ sizes: sizes.join(" "),
208
+ opacities: opacities.every((o) => o === "1") ? null : opacities.join(" ")
209
+ };
210
+ }
211
+ function combineFace(n, words, values) {
212
+ const col = (property) => values[property] ??= new Array(n).fill(null);
213
+ const num = (property, i) => {
214
+ const v = values[property]?.[i];
215
+ return typeof v === "number" ? v : null;
216
+ };
217
+ for (let i = 0; i < n; i++) {
218
+ const el = {
219
+ word: (part) => words.get(part)?.[i] ?? null,
220
+ put: (property, value) => {
221
+ col(property)[i] = value;
222
+ },
223
+ // Cytoscape.js's default node is 30 x 30
224
+ w: num("width", i) ?? 30,
225
+ h: num("height", i) ?? 30
226
+ };
227
+ faceImage(el);
228
+ const pie = pieces(words, "_pie", i);
229
+ if (pie !== null) {
230
+ facePie(el, pie);
231
+ }
232
+ const stripe = pieces(words, "_stripe", i);
233
+ if (stripe !== null) {
234
+ faceStripes(el, stripe);
235
+ }
236
+ }
237
+ }
238
+ function faceImage(el) {
239
+ const image = firstImage(el.word("_bgImage"));
240
+ if (image === null) {
241
+ return;
242
+ }
243
+ el.put("image", image);
244
+ const fit = el.word("_bgFit") ?? "none";
245
+ el.put("imageFit", ["none", "contain", "cover"].includes(fit) ? fit : "none");
246
+ imageSize(el);
247
+ imagePlace(el);
248
+ imageLook(el);
249
+ }
250
+ function imageSize(el) {
251
+ const pad = paddingPixels(el.word("_padding"));
252
+ const of = (rel, side) => rel === "inner" ? side : side + 2 * pad;
253
+ const tiled = ["repeat", "repeat-x", "repeat-y"].includes(el.word("_bgRepeat") ?? "");
254
+ const bw = tiled ? null : length(el.word("_bgWidth"), of(el.word("_bgWidthRel"), el.w));
255
+ const bh = tiled ? null : length(el.word("_bgHeight"), of(el.word("_bgHeightRel"), el.h));
256
+ if (bw !== null) {
257
+ el.put("imageWidth", bw);
258
+ }
259
+ if (bh !== null) {
260
+ el.put("imageHeight", bh);
261
+ }
262
+ if (bw === null !== (bh === null)) {
263
+ el.put("imageAutoSize", "natural");
264
+ }
265
+ }
266
+ function imagePlace(el) {
267
+ const px = fraction(el.word("_bgPosX"));
268
+ const py = fraction(el.word("_bgPosY"));
269
+ if (px !== null && px >= 0) {
270
+ el.put("imagePositionX", px);
271
+ }
272
+ if (py !== null && py >= 0) {
273
+ el.put("imagePositionY", py);
274
+ }
275
+ const ox = length(el.word("_bgOffX"), el.w);
276
+ const oy = length(el.word("_bgOffY"), el.h);
277
+ if (ox !== null) {
278
+ el.put("imageOffsetX", ox);
279
+ }
280
+ if (oy !== null) {
281
+ el.put("imageOffsetY", oy);
282
+ }
283
+ }
284
+ function imageLook(el) {
285
+ const repeat = el.word("_bgRepeat");
286
+ if (repeat !== null && ["repeat", "repeat-x", "repeat-y", "no-repeat"].includes(repeat)) {
287
+ el.put("imageRepeat", repeat);
288
+ }
289
+ const clip = el.word("_bgClip");
290
+ if (clip !== null) {
291
+ el.put("imageClip", clip === "none" ? "none" : "node");
292
+ }
293
+ const smooth = el.word("_bgSmooth");
294
+ if (smooth === "yes" || smooth === "no") {
295
+ el.put("imageSmoothing", smooth === "yes");
296
+ }
297
+ const opacity = Number(el.word("_bgOpacity") ?? Number.NaN);
298
+ if (Number.isFinite(opacity)) {
299
+ el.put("imageOpacity", Math.max(0, Math.min(1, opacity)));
300
+ }
301
+ }
302
+ function facePie(el, pie) {
303
+ el.put("pieColors", pie.colors);
304
+ el.put("pieSizes", pie.sizes);
305
+ if (pie.opacities !== null) {
306
+ el.put("pieOpacities", pie.opacities);
307
+ }
308
+ const size = el.word("_pieSize");
309
+ const px = measure(size)?.[1] === "px" ? length(size, null) : null;
310
+ const r = px === null ? fraction(size) : px / Math.min(el.w, el.h);
311
+ if (r !== null) {
312
+ el.put("pieRadius", r6(r));
313
+ }
314
+ const hole = fraction(el.word("_pieHole"));
315
+ if (hole !== null && hole >= 0 && hole <= 1) {
316
+ el.put("pieHole", hole);
317
+ }
318
+ const start = degrees(el.word("_pieStart"));
319
+ if (start !== null) {
320
+ el.put("pieRotation", start);
321
+ }
322
+ }
323
+ function faceStripes(el, stripe) {
324
+ el.put("stripeColors", stripe.colors);
325
+ el.put("stripeSizes", stripe.sizes);
326
+ if (stripe.opacities !== null) {
327
+ el.put("stripeOpacities", stripe.opacities);
328
+ }
329
+ if (el.word("_stripeDir") === "righward") {
330
+ el.put("stripeDirection", "right");
331
+ }
332
+ const size = fraction(el.word("_stripeSize"));
333
+ if (size !== null && size >= 0) {
334
+ el.put("stripeSize", size);
335
+ }
336
+ }
99
337
  const NODE_SHAPES = [
100
338
  "rectangle",
101
339
  "roundrectangle",
@@ -166,7 +404,7 @@ const FONT_WEIGHTS = [
166
404
  800,
167
405
  900
168
406
  ];
169
- const CURVES = [
407
+ const CYJS_CURVE_STYLES = [
170
408
  "bezier",
171
409
  "unbundled-bezier",
172
410
  "haystack",
@@ -195,18 +433,230 @@ const LABEL = [
195
433
  ["font-style", { property: "labelItalic", type: "enum", enums: ["italic", "normal", "oblique"] }],
196
434
  ["visibility", { property: "_visibility", type: "enum", enums: ["hidden", "visible"] }],
197
435
  ["display", { property: "_display", type: "enum", enums: ["element", "none"] }],
198
- ["opacity", { property: "opacity", type: "zeroOne" }]
436
+ ["opacity", { property: "opacity", type: "zeroOne" }],
437
+ ["text-transform", { property: "_transform", type: "enum", enums: ["none", "uppercase", "lowercase"] }],
438
+ ["text-wrap", { property: "_wrap", type: "enum", enums: ["none", "wrap", "ellipsis"] }],
439
+ ["text-overflow-wrap", { property: "_overflowWrap", type: "enum", enums: ["whitespace", "anywhere"] }],
440
+ // how the lines line up; `auto` follows the horizontal alignment (`combineLabelText`)
441
+ ["text-justification", { property: "_justification", type: "enum", enums: ["auto", "left", "center", "right"] }],
442
+ // a width only `text-wrap: wrap` wraps at, so it is combined with the wrap afterward (`combineParts`)
443
+ ["text-max-width", { property: "_maxWidth", type: "size" }],
444
+ // the outline and the background box draw only with a width and an opacity (`combineLabelDress`)
445
+ ["text-outline-color", { property: "_outlineColor", type: "color" }],
446
+ ["text-outline-width", { property: "_outlineWidth", type: "size" }],
447
+ ["text-outline-opacity", { property: "_outlineOpacity", type: "zeroOne" }],
448
+ ["text-background-color", { property: "_backgroundColor", type: "color" }],
449
+ ["text-background-opacity", { property: "_backgroundOpacity", type: "zeroOne" }],
450
+ ["text-background-padding", { property: "_backgroundPadding", type: "size" }],
451
+ [
452
+ "text-background-shape",
453
+ {
454
+ property: "_backgroundShape",
455
+ type: "enum",
456
+ enums: ["rectangle", "round-rectangle", "roundrectangle", "circle"]
457
+ }
458
+ ],
459
+ ["text-rotation", { property: "_rotation", type: "text" }],
460
+ // the words' own opacity, drawn times the element's (`combineLabelOpacity`)
461
+ ["text-opacity", { property: "_textOpacity", type: "zeroOne" }],
462
+ // the label moved right and down by this many pixels from where its alignment puts it, a node's and an edge's
463
+ ["text-margin-x", { property: "labelOffsetX", type: "signedSize" }],
464
+ ["text-margin-y", { property: "labelOffsetY", type: "signedSize" }],
465
+ // the line round the label's box draws only with a width and an opacity above 0 (`combineLabelDress`)
466
+ ["text-border-color", { property: "_textBorderColor", type: "color" }],
467
+ ["text-border-width", { property: "_textBorderWidth", type: "size" }],
468
+ ["text-border-opacity", { property: "_textBorderOpacity", type: "zeroOne" }],
469
+ [
470
+ "text-border-style",
471
+ { property: "_textBorderStyle", type: "enum", enums: ["solid", "dotted", "dashed", "double"] }
472
+ ]
473
+ ];
474
+ const GRADIENT_DIRECTIONS = [
475
+ "to-bottom",
476
+ "to-top",
477
+ "to-left",
478
+ "to-right",
479
+ "to-bottom-right",
480
+ "to-bottom-left",
481
+ "to-top-right",
482
+ "to-top-left",
483
+ "to-right-bottom",
484
+ "to-left-bottom",
485
+ "to-right-top",
486
+ "to-left-top"
199
487
  ];
488
+ const EM_PX = 16;
489
+ function cyjsPointsToNeutral(text2) {
490
+ const n = text2.trim().split(/[\s,]+/).map(Number);
491
+ if (n.length < 6 || n.length % 2 !== 0 || !n.every((v) => Number.isFinite(v))) {
492
+ return null;
493
+ }
494
+ const pairs = [];
495
+ for (let i = 0; i < n.length; i += 2) {
496
+ pairs.push(`${String(round6(n[i]))},${String(round6(-n[i + 1]))}`);
497
+ }
498
+ return pairs.join(" ");
499
+ }
500
+ function neutralPointsToCyjs(points) {
501
+ const n = points.trim().split(/[\s,]+/).map(Number);
502
+ if (n.length < 6 || n.length % 2 !== 0 || !n.every((v) => Number.isFinite(v))) {
503
+ return null;
504
+ }
505
+ const pairs = [];
506
+ for (let i = 0; i < n.length; i += 2) {
507
+ pairs.push(`${String(round6(n[i]))} ${String(round6(-n[i + 1]))}`);
508
+ }
509
+ return pairs.join(" ");
510
+ }
511
+ const round6 = (v) => Math.round(v * 1e6) / 1e6 + 0;
512
+ function fittedHeptagon() {
513
+ const corners = Array.from({ length: 7 }, (_, i) => {
514
+ const angle = Math.PI / 2 + 2 * Math.PI * i / 7;
515
+ return [Math.cos(angle), Math.sin(angle)];
516
+ });
517
+ const [x0, x1] = [Math.min(...corners.map(([x]) => x)), Math.max(...corners.map(([x]) => x))];
518
+ const [y0, y1] = [Math.min(...corners.map(([, y]) => y)), Math.max(...corners.map(([, y]) => y))];
519
+ return corners.map(([x, y]) => `${round6(2 * (x - x0) / (x1 - x0) - 1)},${round6(2 * (y - y0) / (y1 - y0) - 1)}`).join(" ");
520
+ }
521
+ const CYJS_POLYGON_SHAPES = /* @__PURE__ */ new Map([
522
+ ["heptagon", fittedHeptagon()],
523
+ ["round-heptagon", fittedHeptagon()],
524
+ ["tag", "-1,-1 0.25,-1 1,0 0.25,1 -1,1"],
525
+ ["round-tag", "-1,-1 0.25,-1 1,0 0.25,1 -1,1"]
526
+ ]);
527
+ const CYJS_ROUND_SHAPES = /* @__PURE__ */ new Set([
528
+ "round-triangle",
529
+ "round-diamond",
530
+ "round-pentagon",
531
+ "round-hexagon",
532
+ "round-octagon"
533
+ ]);
534
+ function cyjsPolygonShapes(values) {
535
+ const { shape } = values;
536
+ const pointsOf = (v) => typeof v === "string" && v.startsWith("other:") ? CYJS_POLYGON_SHAPES.get(v.slice("other:".length)) : void 0;
537
+ if (Array.isArray(shape)) {
538
+ const col = shape;
539
+ if (!col.some((v) => pointsOf(v) !== void 0)) {
540
+ return;
541
+ }
542
+ const points = Array.isArray(values.shapePoints) ? [...values.shapePoints] : new Array(col.length).fill(null);
543
+ values.shape = col.map((v, i) => {
544
+ const p2 = pointsOf(v);
545
+ if (p2 === void 0) {
546
+ return v;
547
+ }
548
+ points[i] = p2;
549
+ return polygonOf(v);
550
+ });
551
+ values.shapePoints = points;
552
+ return;
553
+ }
554
+ const p = pointsOf(shape);
555
+ if (p !== void 0) {
556
+ values.shape = polygonOf(shape);
557
+ values.shapePoints = p;
558
+ }
559
+ }
560
+ function polygonOf(shape) {
561
+ return typeof shape === "string" && shape.startsWith("other:round-") ? "other:round-polygon" : "polygon";
562
+ }
563
+ const GRADIENT_KINDS = /* @__PURE__ */ new Map([
564
+ ["solid", "none"],
565
+ ["linear-gradient", "linear"],
566
+ ["radial-gradient", "radial"]
567
+ ]);
568
+ function wordsOutsideParens(text2) {
569
+ const closes = new Array(text2.length + 1).fill(false);
570
+ for (let i2 = text2.length - 1; i2 >= 0; i2--) {
571
+ closes[i2] = text2[i2] === ")" || text2[i2] !== "(" && closes[i2 + 1];
572
+ }
573
+ const words = [];
574
+ let start = 0;
575
+ let i = 0;
576
+ while (i < text2.length) {
577
+ if (!/\s/.test(text2[i])) {
578
+ i++;
579
+ continue;
580
+ }
581
+ let end = i + 1;
582
+ while (end < text2.length && /\s/.test(text2[end])) {
583
+ end++;
584
+ }
585
+ if (!closes[end]) {
586
+ words.push(text2.slice(start, i));
587
+ start = end;
588
+ }
589
+ i = end;
590
+ }
591
+ words.push(text2.slice(start));
592
+ return words;
593
+ }
594
+ function gradientColors(text2, site) {
595
+ const hexes = [];
596
+ for (const token of wordsOutsideParens(text2.trim())) {
597
+ const c = token === "" ? null : canonColor(token, "css", site);
598
+ if (c === null) {
599
+ return void 0;
600
+ }
601
+ hexes.push(c.color);
602
+ }
603
+ return hexes.join(" ");
604
+ }
605
+ function gradientStopColors(text2, site) {
606
+ return gradientColors(text2, site)?.split(" ") ?? [];
607
+ }
608
+ function gradientStops(text2) {
609
+ const stops = text2.trim().split(/\s+/).map((t) => t.endsWith("%") ? Number.parseFloat(t) / 100 : Number.parseFloat(t));
610
+ return stops.every((n) => Number.isFinite(n)) ? stops.map((n) => num6(n)).join(" ") : void 0;
611
+ }
612
+ const HALVED = /* @__PURE__ */ new Set(["fanSpacing", "outerBorderOffset"]);
200
613
  const CYJS_NODE_PROPERTIES = new Map([
201
614
  ["background-color", { property: "fill", type: "color" }],
202
615
  ["background-opacity", { property: "fillOpacity", type: "zeroOne" }],
203
616
  ["border-color", { property: "borderColor", type: "color" }],
617
+ // the rings are drawn at their own opacity times the node's (`combineNodeOpacity`)
618
+ ["border-opacity", { property: "_ringOpacity", type: "zeroOne" }],
204
619
  ["border-width", { property: "borderWidth", type: "size" }],
205
620
  ["border-style", { property: "borderStyle", type: "enum", enums: ["solid", "dotted", "dashed", "double"] }],
621
+ // the dashes a dashed border is drawn with and their ends, which decide how it looks (`combineDashes`)
622
+ ["border-dash-pattern", { property: "_dashPattern", type: "text" }],
623
+ ["border-cap", { property: "_dashCap", type: "enum", enums: ["butt", "round", "square"] }],
624
+ // where the border sits against the node's outline: across it, inside it or outside it
625
+ ["border-position", { property: "borderPosition", type: "enum", enums: ["center", "inside", "outside"] }],
626
+ ["outline-color", { property: "outerBorderColor", type: "color" }],
627
+ ["outline-opacity", { property: "_outlineRingOpacity", type: "zeroOne" }],
628
+ ["outline-width", { property: "outerBorderWidth", type: "size" }],
629
+ ["outline-style", { property: "outerBorderStyle", type: "enum", enums: ["solid", "dotted", "dashed", "double"] }],
630
+ ["outline-offset", { property: "outerBorderOffset", type: "size" }],
631
+ ["underlay-color", { property: "underlayColor", type: "color" }],
632
+ ["underlay-opacity", { property: "underlayOpacity", type: "zeroOne" }],
633
+ ["underlay-padding", { property: "underlayPadding", type: "size" }],
634
+ ["underlay-shape", { property: "underlayShape", type: "enum", enums: NODE_SHAPES }],
635
+ ["underlay-corner-radius", { property: "underlayCornerRadius", type: "size" }],
636
+ ["overlay-color", { property: "overlayColor", type: "color" }],
637
+ ["overlay-opacity", { property: "overlayOpacity", type: "zeroOne" }],
638
+ ["overlay-padding", { property: "overlayPadding", type: "size" }],
639
+ ["overlay-shape", { property: "overlayShape", type: "enum", enums: NODE_SHAPES }],
640
+ ["overlay-corner-radius", { property: "overlayCornerRadius", type: "size" }],
206
641
  ["shape", { property: "shape", type: "enum", enums: NODE_SHAPES }],
642
+ ["shape-polygon-points", { property: "shapePoints", type: "text" }],
207
643
  ["corner-radius", { property: "cornerRadius", type: "size" }],
208
644
  ["width", { property: "width", type: "nodeSize" }],
209
645
  ["height", { property: "height", type: "nodeSize" }],
646
+ // a node is drawn this much larger on every side (`nodeSizes`)
647
+ ["padding", { property: "_padding", type: "text" }],
648
+ // how a compound parent is sized round its children (`groupBoxes`)
649
+ [
650
+ "padding-relative-to",
651
+ { property: "_paddingOf", type: "enum", enums: ["width", "height", "average", "min", "max"] }
652
+ ],
653
+ ["min-width", { property: "_minWidth", type: "text" }],
654
+ ["min-height", { property: "_minHeight", type: "text" }],
655
+ ["min-width-bias-left", { property: "_biasLeft", type: "text" }],
656
+ ["min-width-bias-right", { property: "_biasRight", type: "text" }],
657
+ ["min-height-bias-top", { property: "_biasTop", type: "text" }],
658
+ ["min-height-bias-bottom", { property: "_biasBottom", type: "text" }],
659
+ ["compound-sizing-wrt-labels", { property: "_compoundLabels", type: "enum", enums: ["include", "exclude"] }],
210
660
  [
211
661
  "text-valign",
212
662
  { property: "_valign", type: "enum", enums: ["top", "top-inside", "center", "bottom", "bottom-inside"] }
@@ -215,30 +665,108 @@ const CYJS_NODE_PROPERTIES = new Map([
215
665
  "text-halign",
216
666
  { property: "_halign", type: "enum", enums: ["left", "left-inside", "center", "right", "right-inside"] }
217
667
  ],
668
+ // the fill's gradient, combined afterward into `fill`, `fillGradient`, `fillGradientAngle` and the other
669
+ // `fillGradient*` properties
670
+ [
671
+ "background-fill",
672
+ { property: "_backgroundFill", type: "enum", enums: ["solid", "linear-gradient", "radial-gradient"] }
673
+ ],
674
+ ["background-gradient-stop-colors", { property: "_backgroundStops", type: "text" }],
675
+ ["background-gradient-stop-positions", { property: "_backgroundPositions", type: "text" }],
676
+ ["background-gradient-direction", { property: "_backgroundDirection", type: "enum", enums: GRADIENT_DIRECTIONS }],
677
+ ...CYJS_FACE_PROPERTIES,
218
678
  ...LABEL
219
679
  ]);
220
680
  const CYJS_EDGE_PROPERTIES = new Map([
221
681
  ["line-color", { property: "color", type: "color" }],
222
682
  ["width", { property: "width", type: "nodeSize" }],
223
683
  ["line-style", { property: "lineStyle", type: "enum", enums: ["solid", "dotted", "dashed"] }],
684
+ // the dashes a dashed line is drawn with and their ends, which decide how it looks (`combineDashes`)
685
+ ["line-dash-pattern", { property: "_dashPattern", type: "text" }],
686
+ ["line-cap", { property: "_dashCap", type: "enum", enums: ["butt", "round", "square"] }],
687
+ // the line's own opacity, combined afterward into `opacity`, which the line is drawn at
688
+ ["line-opacity", { property: "_lineOpacity", type: "zeroOne" }],
689
+ ["line-outline-width", { property: "outlineWidth", type: "size" }],
690
+ ["line-fill", { property: "gradientKind", type: "enum", enums: ["solid", "linear-gradient", "radial-gradient"] }],
691
+ ["line-gradient-stop-colors", { property: "gradientColors", type: "text" }],
692
+ ["line-gradient-stop-positions", { property: "gradientStops", type: "text" }],
693
+ ["line-outline-color", { property: "outlineColor", type: "color" }],
694
+ ["underlay-color", { property: "underlayColor", type: "color" }],
695
+ ["underlay-opacity", { property: "underlayOpacity", type: "zeroOne" }],
696
+ ["underlay-padding", { property: "underlayPadding", type: "size" }],
697
+ ["overlay-color", { property: "overlayColor", type: "color" }],
698
+ ["overlay-opacity", { property: "overlayOpacity", type: "zeroOne" }],
699
+ ["overlay-padding", { property: "overlayPadding", type: "size" }],
224
700
  ["target-arrow-shape", { property: "targetArrow", type: "enum", enums: ARROWS }],
225
701
  ["source-arrow-shape", { property: "sourceArrow", type: "enum", enums: ARROWS }],
226
702
  ["target-arrow-color", { property: "targetArrowColor", type: "color" }],
227
703
  ["source-arrow-color", { property: "sourceArrowColor", type: "color" }],
704
+ ["mid-target-arrow-shape", { property: "midTargetArrow", type: "enum", enums: ARROWS }],
705
+ ["mid-source-arrow-shape", { property: "midSourceArrow", type: "enum", enums: ARROWS }],
706
+ ["mid-target-arrow-color", { property: "midTargetArrowColor", type: "color" }],
707
+ ["mid-source-arrow-color", { property: "midSourceArrowColor", type: "color" }],
708
+ // filled or hollow: combined with the shape afterward (`combineParts`), a hollow triangle being `triangle-open`
228
709
  ["target-arrow-fill", { property: "_targetArrowFill", type: "enum", enums: ["filled", "hollow"] }],
229
710
  ["source-arrow-fill", { property: "_sourceArrowFill", type: "enum", enums: ["filled", "hollow"] }],
230
- ["curve-style", { property: "curved", type: "enum", enums: CURVES }],
711
+ ["mid-target-arrow-fill", { property: "_midTargetArrowFill", type: "enum", enums: ["filled", "hollow"] }],
712
+ ["mid-source-arrow-fill", { property: "_midSourceArrowFill", type: "enum", enums: ["filled", "hollow"] }],
713
+ ["curve-style", { property: "curved", type: "enum", enums: CYJS_CURVE_STYLES }],
714
+ // a route's settings, read by the routes (`edgeRoutes`) as Cytoscape.js spells them
715
+ ["segment-distances", { property: "_segmentDistances", type: "text" }],
716
+ ["segment-weights", { property: "_segmentWeights", type: "text" }],
717
+ ["control-point-distances", { property: "_controlPointDistances", type: "text" }],
718
+ ["control-point-weights", { property: "_controlPointWeights", type: "text" }],
719
+ ["taxi-direction", { property: "_taxiDirection", type: "text" }],
720
+ ["taxi-turn", { property: "_taxiTurn", type: "text" }],
721
+ ["taxi-turn-min-distance", { property: "_taxiTurnMinDistance", type: "size" }],
722
+ ["edge-distances", { property: "_edgeDistances", type: "text" }],
723
+ ["loop-direction", { property: "_loopDirection", type: "text" }],
724
+ ["loop-sweep", { property: "_loopSweep", type: "text" }],
725
+ ["segment-radii", { property: "_segmentRadii", type: "text" }],
726
+ ["taxi-radius", { property: "_taxiRadius", type: "text" }],
727
+ ["radius-type", { property: "_radiusType", type: "text" }],
728
+ // where the ends meet the nodes, read with the routes (`edgePorts`)
729
+ ["source-endpoint", { property: "_sourceEndpoint", type: "text" }],
730
+ ["target-endpoint", { property: "_targetEndpoint", type: "text" }],
731
+ ["source-distance-from-node", { property: "sourceNodeGap", type: "size" }],
732
+ ["target-distance-from-node", { property: "targetNodeGap", type: "size" }],
733
+ // a bundle's control points are this far apart, so the curves' middles half of it (see cyjsNeutral)
734
+ ["control-point-step-size", { property: "fanSpacing", type: "size" }],
231
735
  ["arrow-scale", { property: "arrowSize", type: "positive" }],
232
736
  ["source-label", { property: "sourceLabel", type: "text" }],
233
737
  ["target-label", { property: "targetLabel", type: "text" }],
738
+ ["source-text-offset", { property: "sourceLabelOffset", type: "size" }],
739
+ ["target-text-offset", { property: "targetLabelOffset", type: "size" }],
740
+ ["source-text-margin-x", { property: "sourceLabelOffsetX", type: "signedSize" }],
741
+ ["source-text-margin-y", { property: "sourceLabelOffsetY", type: "signedSize" }],
742
+ ["target-text-margin-x", { property: "targetLabelOffsetX", type: "signedSize" }],
743
+ ["target-text-margin-y", { property: "targetLabelOffsetY", type: "signedSize" }],
744
+ // an angle, or autorotate along the line, which the routes work out (`autorotateLabels`)
745
+ ["source-text-rotation", { property: "_sourceRotation", type: "text" }],
746
+ ["target-text-rotation", { property: "_targetRotation", type: "text" }],
234
747
  ...LABEL
235
748
  ]);
236
749
  function cyjsProperties(target) {
237
750
  return target === "node" ? CYJS_NODE_PROPERTIES : CYJS_EDGE_PROPERTIES;
238
751
  }
752
+ const CYJS_ALIASES = /* @__PURE__ */ new Map([
753
+ ["content", "label"],
754
+ ["control-point-distance", "control-point-distances"],
755
+ ["control-point-weight", "control-point-weights"],
756
+ ["segment-distance", "segment-distances"],
757
+ ["segment-weight", "segment-weights"],
758
+ ["segment-radius", "segment-radii"],
759
+ ["edge-text-rotation", "text-rotation"],
760
+ ["padding-left", "padding"],
761
+ ["padding-right", "padding"],
762
+ ["padding-top", "padding"],
763
+ ["padding-bottom", "padding"]
764
+ ]);
765
+ function cyjsAliasOf(dashed) {
766
+ return CYJS_ALIASES.get(dashed) ?? dashed;
767
+ }
239
768
  function cyjsPropertyName(name) {
240
- const dashed = name.replaceAll(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
241
- return dashed === "content" ? "label" : dashed;
769
+ return cyjsAliasOf(name.replaceAll(/[A-Z]/g, (c) => `-${c.toLowerCase()}`));
242
770
  }
243
771
  const CYJS_THROWS = "throws";
244
772
  const NUM = String.raw`[-+]?(?:(?:\d+|\d*\.\d+)(?:[Ee][+-]?\d+)?)`;
@@ -361,8 +889,8 @@ function isFontChar(c) {
361
889
  function isSpace$1(c) {
362
890
  return /\s/.test(c);
363
891
  }
364
- function allOf(text, test) {
365
- return Array.from(text).every(test);
892
+ function allOf(text2, test) {
893
+ return Array.from(text2).every(test);
366
894
  }
367
895
  function firstFontPart(part) {
368
896
  let a = 0;
@@ -401,13 +929,14 @@ function parseFlat(spec, raw, rendered = false) {
401
929
  return ok ? { kind: "number", value: x, units: null, str: String(x) } : null;
402
930
  }
403
931
  case "size":
932
+ case "signedSize":
404
933
  case "nodeSize":
405
934
  return parseSizeValue(spec, value, raw);
406
935
  case "text":
407
936
  return { kind: "word", value: String(value), str: String(value) };
408
937
  case "fontFamily": {
409
- const text = String(value);
410
- return isFontFamily(text) ? { kind: "word", value: text, str: text } : null;
938
+ const text2 = String(value);
939
+ return isFontFamily(text2) ? { kind: "word", value: text2, str: text2 } : null;
411
940
  }
412
941
  case "fontWeight":
413
942
  case "enum": {
@@ -433,21 +962,21 @@ function parseColorValue(value) {
433
962
  }
434
963
  function parseSizeValue(spec, value, raw) {
435
964
  let units = "px";
436
- let text = value;
965
+ let text2 = value;
437
966
  if (typeof value === "string") {
438
967
  const m = NUMBER_UNITS.exec(value);
439
968
  if (m === null) {
440
969
  units = null;
441
970
  } else {
442
- text = m[1];
971
+ text2 = m[1];
443
972
  units = m.at(2) === "em" ? "em" : "px";
444
973
  }
445
974
  }
446
- const x = Number.parseFloat(String(text));
975
+ const x = Number.parseFloat(String(text2));
447
976
  if (Number.isNaN(x)) {
448
977
  return spec.type === "nodeSize" && raw === "label" ? { kind: "word", value: "label", str: "label" } : null;
449
978
  }
450
- return x < 0 ? null : { kind: "number", value: x, units, str: `${String(x)}${units ?? ""}` };
979
+ return x < 0 && spec.type !== "signedSize" ? null : { kind: "number", value: x, units, str: `${String(x)}${units ?? ""}` };
451
980
  }
452
981
  function splitArgs(inner) {
453
982
  const out = [];
@@ -518,7 +1047,7 @@ function parseMapData(spec, value, mode) {
518
1047
  if (mode === "bypass") {
519
1048
  return null;
520
1049
  }
521
- const numeric = spec.type === "zeroOne" || spec.type === "positive" || spec.type === "size" || spec.type === "nodeSize";
1050
+ const numeric = spec.type === "zeroOne" || spec.type === "positive" || spec.type === "size" || spec.type === "signedSize" || spec.type === "nodeSize";
522
1051
  if (spec.type !== "color" && !numeric) {
523
1052
  return null;
524
1053
  }
@@ -579,51 +1108,71 @@ function applyCyjsMapper(spec, m, data) {
579
1108
  }
580
1109
  return null;
581
1110
  }
1111
+ function colorNeutral(v, site) {
1112
+ if (v.rgb.some((c) => !Number.isFinite(c) || c < 0 || c > 255)) {
1113
+ site.notes.add(STYLE_ISSUE.BAD_VALUE, site.target, site.property, {
1114
+ sample: v.str,
1115
+ element: site.element
1116
+ });
1117
+ return void 0;
1118
+ }
1119
+ return `#${v.rgb.map((c) => Math.round(c).toString(16).padStart(2, "0")).join("")}`;
1120
+ }
582
1121
  function cyjsNeutral(spec, v, site) {
583
1122
  switch (v.kind) {
584
- case "color": {
585
- if (v.rgb.some((c) => !Number.isFinite(c) || c < 0 || c > 255)) {
586
- site.notes.add(STYLE_ISSUE.BAD_VALUE, site.target, site.property, {
587
- sample: v.str,
588
- element: site.element
589
- });
590
- return void 0;
591
- }
592
- return `#${v.rgb.map((c) => Math.round(c).toString(16).padStart(2, "0")).join("")}`;
593
- }
1123
+ case "color":
1124
+ return colorNeutral(v, site);
594
1125
  case "number":
595
- if (v.units === "em") {
596
- site.notes.add(STYLE_ISSUE.BAD_VALUE, site.target, site.property, {
597
- sample: v.str,
598
- element: site.element
599
- });
600
- return void 0;
601
- }
602
- return num6(v.value);
1126
+ return num6((HALVED.has(spec.property) ? v.value / 2 : v.value) * (v.units === "em" ? EM_PX : 1));
603
1127
  }
604
1128
  const word = v.value;
605
1129
  switch (spec.property) {
606
1130
  case "width":
607
1131
  case "height":
608
- site.notes.add(STYLE_ISSUE.BAD_VALUE, site.target, site.property, { sample: v.str, element: site.element });
1132
+ if (site.target === "edge") {
1133
+ site.notes.add(STYLE_ISSUE.BAD_VALUE, site.target, site.property, {
1134
+ sample: v.str,
1135
+ element: site.element
1136
+ });
1137
+ }
609
1138
  return void 0;
610
1139
  case "label":
611
1140
  case "sourceLabel":
612
1141
  case "targetLabel":
613
1142
  case "labelFont":
614
1143
  return String(word);
1144
+ case "gradientKind":
1145
+ return GRADIENT_KINDS.get(String(word)) ?? void 0;
1146
+ case "gradientColors":
1147
+ return gradientColors(String(word), site);
1148
+ case "gradientStops":
1149
+ return gradientStops(String(word));
615
1150
  case "labelItalic":
616
1151
  return word === "italic" || word === "oblique";
617
1152
  case "curved":
618
1153
  return !STRAIGHT.has(String(word));
619
- case "shape":
1154
+ case "shapePoints":
1155
+ return cyjsPointsToNeutral(String(word)) ?? void 0;
1156
+ case "underlayShape":
1157
+ case "overlayShape":
620
1158
  return canonEnum("shape", String(word), "cytoscape-js", site) ?? void 0;
1159
+ case "shape": {
1160
+ const polygon = String(word).toLowerCase();
1161
+ if (polygon === "polygon") {
1162
+ return "polygon";
1163
+ }
1164
+ return CYJS_POLYGON_SHAPES.has(polygon) || CYJS_ROUND_SHAPES.has(polygon) ? `other:${polygon}` : canonEnum("shape", String(word), "cytoscape-js", site) ?? void 0;
1165
+ }
621
1166
  case "borderStyle":
622
1167
  return canonEnum("borderStyle", String(word), "cytoscape-js", site) ?? void 0;
1168
+ case "outerBorderStyle":
1169
+ return word === "double" ? "solid" : canonEnum("borderStyle", String(word), "cytoscape-js", site) ?? void 0;
623
1170
  case "lineStyle":
624
1171
  return canonEnum("lineStyle", String(word), "cytoscape-js", site) ?? void 0;
625
1172
  case "sourceArrow":
626
1173
  case "targetArrow":
1174
+ case "midSourceArrow":
1175
+ case "midTargetArrow":
627
1176
  return canonEnum("arrow", String(word), "cytoscape-js", site) ?? void 0;
628
1177
  case "labelWeight":
629
1178
  return canonEnum("weight", String(word), "cytoscape-js", site) ?? void 0;
@@ -642,6 +1191,236 @@ function cyjsRendered(target, name, str, site) {
642
1191
  }
643
1192
  return cyjsNeutral(spec, v, site);
644
1193
  }
1194
+ function cyjsDashLook(dash, width, cap) {
1195
+ const pairs = dash.length % 2 === 1 ? [...dash, ...dash] : [...dash];
1196
+ const grow = cap === "butt" ? 0 : width;
1197
+ const on = pairs.filter((_, i) => i % 2 === 0).map((d) => Math.max(0, d) + grow);
1198
+ const off = pairs.filter((_, i) => i % 2 === 1).map((d) => Math.max(0, d - grow));
1199
+ const sum = (xs) => xs.reduce((a, b) => a + b, 0);
1200
+ if (sum(off) <= 0.1 * (sum(on) + sum(off))) {
1201
+ return "solid";
1202
+ }
1203
+ if (on.every((d) => d <= Math.max(1, width) * 1.5)) {
1204
+ return "dotted";
1205
+ }
1206
+ return Math.max(...on) >= 2 * Math.min(...on) ? "dash-dot" : "dashed";
1207
+ }
1208
+ function lengths(text2) {
1209
+ const out = text2.trim().split(/\s+/).map((t) => Number.parseFloat(t));
1210
+ return out.every((n) => Number.isFinite(n)) ? out : [];
1211
+ }
1212
+ function radians(text2) {
1213
+ const t = text2.trim();
1214
+ const x = Number.parseFloat(t);
1215
+ return t.endsWith("deg") ? x * Math.PI / 180 : x;
1216
+ }
1217
+ function outlinePoint(node, toward) {
1218
+ const [cx, cy] = node.center;
1219
+ const dx = toward[0] - cx;
1220
+ const dy = toward[1] - cy;
1221
+ const [hw, hh] = [node.size[0] / 2, node.size[1] / 2];
1222
+ if (dx === 0 && dy === 0 || hw <= 0 || hh <= 0) {
1223
+ return node.center;
1224
+ }
1225
+ const t = node.ellipse ? 1 / Math.hypot(dx / hw, dy / hh) : Math.min(axisReach(dx, hw), axisReach(dy, hh));
1226
+ return [cx + dx * t, cy + dy * t];
1227
+ }
1228
+ function axisReach(d, half) {
1229
+ return d === 0 ? Infinity : half / Math.abs(d);
1230
+ }
1231
+ function measureLine(edge, src, tgt) {
1232
+ const a0 = outlinePoint(src, tgt.center);
1233
+ const b0 = outlinePoint(tgt, src.center);
1234
+ const dx = b0[0] - a0[0];
1235
+ const dy = b0[1] - a0[1];
1236
+ const l = Math.hypot(dx, dy) || 1;
1237
+ const normal = [-dy / l, dx / l];
1238
+ return edge.edgeDistances === "node-position" ? { a: src.center, b: tgt.center, normal } : { a: a0, b: b0, normal };
1239
+ }
1240
+ function offsetPoints(line, weights, distances) {
1241
+ const n = Math.min(weights.length, distances.length);
1242
+ return Array.from({ length: n }, (_, s) => {
1243
+ const w = weights[s];
1244
+ const d = distances[s];
1245
+ return [
1246
+ line.a[0] * (1 - w) + line.b[0] * w + line.normal[0] * d,
1247
+ line.a[1] * (1 - w) + line.b[1] * w + line.normal[1] * d
1248
+ ];
1249
+ });
1250
+ }
1251
+ function taxiPoints(edge, src, tgt) {
1252
+ const body = edge.edgeDistances !== "node-position";
1253
+ const [x1, y1] = src.center;
1254
+ const [x2, y2] = tgt.center;
1255
+ const [srcW, srcH] = src.size;
1256
+ const [tgtW, tgtH] = tgt.size;
1257
+ const pdx = x2 - x1;
1258
+ const pdy = y2 - y1;
1259
+ const dx = towardZero(pdx, body ? (srcW + tgtW) / 2 : 0);
1260
+ const dy = towardZero(pdy, body ? (srcH + tgtH) / 2 : 0);
1261
+ const raw = edge.taxiDirection ?? "auto";
1262
+ const vertical = raw === "auto" ? Math.abs(dx) <= Math.abs(dy) : raw === "vertical" || raw === "upward" || raw === "downward";
1263
+ const [along, pl] = vertical ? [dy, pdy] : [dx, pdx];
1264
+ const { d, l, sgn, forced } = taxiTurn(edge, raw, along, pl);
1265
+ const minD = edge.taxiTurnMinDistance ?? 10;
1266
+ const tooClose = (v) => Math.abs(v) < minD || Math.abs(v) >= Math.abs(l);
1267
+ if ((tooClose(d) || tooClose(Math.abs(l) - Math.abs(d))) && !forced) {
1268
+ return taxiFallback(vertical, { x1, y1, x2, y2, pl, pdx, pdy }, src.size, tgt.size);
1269
+ }
1270
+ const srcAlong = vertical ? srcH : srcW;
1271
+ const out = body ? srcAlong / 2 * sgn : 0;
1272
+ if (vertical) {
1273
+ const y = y1 + d + out;
1274
+ return [
1275
+ [x1, y],
1276
+ [x2, y]
1277
+ ];
1278
+ }
1279
+ const x = x1 + d + out;
1280
+ return [
1281
+ [x, y1],
1282
+ [x, y2]
1283
+ ];
1284
+ }
1285
+ function towardZero(v, gap) {
1286
+ return v > 0 ? Math.max(v - gap, 0) : Math.min(v + gap, 0);
1287
+ }
1288
+ function taxiTurn(edge, raw, along, pl) {
1289
+ const explicit = raw !== "auto" && raw !== "vertical" && raw !== "horizontal";
1290
+ const turnText = (edge.taxiTurn ?? "50%").trim();
1291
+ const percent = turnText.endsWith("%");
1292
+ const turn = percent ? Number.parseFloat(turnText) / 100 : Number.parseFloat(turnText);
1293
+ const forced = !(explicit && (percent || turn < 0)) && runsAgainst(raw, pl);
1294
+ const sgn = forced ? -Math.sign(pl) : Math.sign(pl);
1295
+ const l = forced ? sgn * Math.abs(along) : along;
1296
+ if (percent) {
1297
+ return { d: (turn < 0 ? 1 + turn : turn) * l, l, sgn, forced };
1298
+ }
1299
+ return { d: (turn < 0 ? l : 0) + turn * sgn, l, sgn, forced };
1300
+ }
1301
+ function runsAgainst(raw, pl) {
1302
+ return raw === "downward" && pl < 0 || raw === "upward" && pl > 0 || raw === "leftward" && pl > 0 || raw === "rightward" && pl < 0;
1303
+ }
1304
+ function taxiFallback(vertical, p, srcSize, tgtSize) {
1305
+ const { x1, y1, x2, y2, pl, pdx, pdy } = p;
1306
+ const midX = (x1 + x2) / 2;
1307
+ const midY = (y1 + y2) / 2;
1308
+ if (vertical) {
1309
+ if (Math.abs(pl) <= srcSize[1] / 2) {
1310
+ return [
1311
+ [midX, y1],
1312
+ [midX, y2]
1313
+ ];
1314
+ }
1315
+ if (Math.abs(pdx) <= tgtSize[0] / 2) {
1316
+ return [
1317
+ [x1, midY],
1318
+ [x2, midY]
1319
+ ];
1320
+ }
1321
+ return [[x1, y2]];
1322
+ }
1323
+ if (Math.abs(pl) <= srcSize[0] / 2) {
1324
+ return [
1325
+ [x1, midY],
1326
+ [x2, midY]
1327
+ ];
1328
+ }
1329
+ if (Math.abs(pdy) <= tgtSize[1] / 2) {
1330
+ return [
1331
+ [midX, y1],
1332
+ [midX, y2]
1333
+ ];
1334
+ }
1335
+ return [[x2, y1]];
1336
+ }
1337
+ function splinePoints(src, tgt, controls) {
1338
+ const start = outlinePoint(src, controls[0]);
1339
+ const end = outlinePoint(tgt, controls.at(-1) ?? tgt.center);
1340
+ return flattenQuadSpline([start, ...controls, end], 0).slice(1, -1);
1341
+ }
1342
+ function cyjsRoute(edge, src, tgt, loopIndex) {
1343
+ const style = edge.curveStyle;
1344
+ if (style === "haystack") {
1345
+ return null;
1346
+ }
1347
+ if (src === tgt) {
1348
+ return loopRoute(edge, src, loopIndex);
1349
+ }
1350
+ let points = [];
1351
+ if (style.endsWith("segments")) {
1352
+ const distances = lengths(edge.segmentDistances ?? "20");
1353
+ const weights = lengths(edge.segmentWeights ?? "0.5");
1354
+ points = offsetPoints(measureLine(edge, src, tgt), weights, distances);
1355
+ } else if (style.endsWith("taxi")) {
1356
+ points = taxiPoints(edge, src, tgt);
1357
+ } else if (style === "unbundled-bezier") {
1358
+ const distances = lengths(edge.controlPointDistances ?? String(edge.controlPointStepSize ?? 40));
1359
+ const weights = lengths(edge.controlPointWeights ?? "0.5");
1360
+ const controls = offsetPoints(measureLine(edge, src, tgt), weights, distances);
1361
+ points = controls.length === 0 ? [] : splinePoints(src, tgt, controls);
1362
+ }
1363
+ if (points.length > 0 && style.startsWith("round-")) {
1364
+ const radii = lengths((style === "round-taxi" ? edge.taxiRadius : edge.segmentRadii) ?? "15");
1365
+ const types = (edge.radiusType ?? "arc-radius").trim().split(/\s+/);
1366
+ const start = outlinePoint(src, points[0]);
1367
+ const end = outlinePoint(tgt, points.at(-1) ?? tgt.center);
1368
+ points = roundedCorners([start, ...points, end], radii, types).slice(1, -1);
1369
+ }
1370
+ return points.length === 0 ? null : canonBends(src.center, tgt.center, points, true);
1371
+ }
1372
+ const ARC_STEPS = 8;
1373
+ function roundedCorners(line, radii, types) {
1374
+ const out = [line[0]];
1375
+ for (let i = 1; i < line.length - 1; i++) {
1376
+ const [p, a, b] = [line[i], line[i - 1], line[i + 1]];
1377
+ const r = radii[Math.min(i - 1, radii.length - 1)] ?? 15;
1378
+ const arc = (types[Math.min(i - 1, types.length - 1)] ?? "arc-radius") !== "influence-radius";
1379
+ const l1 = Math.hypot(a[0] - p[0], a[1] - p[1]);
1380
+ const l2 = Math.hypot(b[0] - p[0], b[1] - p[1]);
1381
+ const u1 = [(a[0] - p[0]) / l1, (a[1] - p[1]) / l1];
1382
+ const u2 = [(b[0] - p[0]) / l2, (b[1] - p[1]) / l2];
1383
+ const angle = Math.acos(Math.max(-1, Math.min(1, u1[0] * u2[0] + u1[1] * u2[1])));
1384
+ const half = angle / 2;
1385
+ const rounds = r > 0 && l1 > 0 && l2 > 0;
1386
+ if (!rounds || Math.abs(Math.PI - angle) < 1e-6) {
1387
+ out.push(p);
1388
+ continue;
1389
+ }
1390
+ const limit = Math.min(l1 / 2, l2 / 2);
1391
+ const back = Math.min(limit, arc ? r / Math.tan(half) : r);
1392
+ const radius = back * Math.tan(half);
1393
+ const bis = [u1[0] + u2[0], u1[1] + u2[1]];
1394
+ const bl = Math.hypot(bis[0], bis[1]);
1395
+ const reach = Math.hypot(back, radius);
1396
+ const c = [p[0] + bis[0] / bl * reach, p[1] + bis[1] / bl * reach];
1397
+ const from = Math.atan2(p[1] + u1[1] * back - c[1], p[0] + u1[0] * back - c[0]);
1398
+ const to = Math.atan2(p[1] + u2[1] * back - c[1], p[0] + u2[0] * back - c[0]);
1399
+ let sweep = to - from;
1400
+ sweep -= 2 * Math.PI * Math.round(sweep / (2 * Math.PI));
1401
+ for (let k = 0; k <= ARC_STEPS; k++) {
1402
+ const t = from + sweep * k / ARC_STEPS;
1403
+ out.push([c[0] + Math.cos(t) * radius, c[1] + Math.sin(t) * radius]);
1404
+ }
1405
+ }
1406
+ out.push(line.at(-1) ?? line[0]);
1407
+ return out;
1408
+ }
1409
+ function loopRoute(edge, node, loopIndex) {
1410
+ const unbundled = edge.curveStyle === "unbundled-bezier";
1411
+ const dist = unbundled ? lengths(edge.controlPointDistances ?? "").at(0) ?? Number.NaN : edge.controlPointStepSize ?? 40;
1412
+ const dir = radians(edge.loopDirection ?? "-45deg");
1413
+ const sweep = radians(edge.loopSweep ?? "-90deg");
1414
+ if (!Number.isFinite(dist + dir + sweep)) {
1415
+ return null;
1416
+ }
1417
+ const angle = dir - Math.PI / 2;
1418
+ const reach = 1.4 * dist * (loopIndex / 3 + 1);
1419
+ const [cx, cy] = node.center;
1420
+ const at = (a) => [cx + Math.cos(a) * reach, cy + Math.sin(a) * reach];
1421
+ const points = splinePoints(node, node, [at(angle - sweep / 2), at(angle + sweep / 2)]);
1422
+ return canonNodeOffsets(node.center, node.box, points, true);
1423
+ }
645
1424
  const CYJS_STATES = /* @__PURE__ */ new Set([
646
1425
  "selected",
647
1426
  "unselected",
@@ -688,8 +1467,8 @@ function isSpace(c) {
688
1467
  return c !== void 0 && /\s/.test(c);
689
1468
  }
690
1469
  class Cursor {
691
- constructor(text) {
692
- this.text = text;
1470
+ constructor(text2) {
1471
+ this.text = text2;
693
1472
  this.pos = 0;
694
1473
  }
695
1474
  /**
@@ -832,8 +1611,8 @@ function cleanMeta(raw) {
832
1611
  }
833
1612
  return out;
834
1613
  }
835
- function splitOp(text) {
836
- let op = text;
1614
+ function splitOp(text2) {
1615
+ let op = text2;
837
1616
  let not = false;
838
1617
  let ci = false;
839
1618
  if (op.includes("!")) {
@@ -1070,17 +1849,17 @@ function metaToken(c, i) {
1070
1849
  const { op: base, not, ci } = splitOp(op.text);
1071
1850
  return checkToken(c.spaceEnd(end) + 2, { type: "meta", field, op: base, not, ci, value });
1072
1851
  }
1073
- function isBlank(text) {
1074
- return /^\s*$/.test(text.length > 1024 ? text.slice(0, 1024) : text) && text.trim() === "";
1852
+ function isBlank(text2) {
1853
+ return /^\s*$/.test(text2.length > 1024 ? text2.slice(0, 1024) : text2) && text2.trim() === "";
1075
1854
  }
1076
- function parseCyjsSelector(text) {
1077
- if (typeof text !== "string" || isBlank(text)) {
1855
+ function parseCyjsSelector(text2) {
1856
+ if (typeof text2 !== "string" || isBlank(text2)) {
1078
1857
  return { queries: [], invalid: false };
1079
1858
  }
1080
- if (text.length > MAX_SELECTOR_LENGTH) {
1859
+ if (text2.length > MAX_SELECTOR_LENGTH) {
1081
1860
  return { queries: [], invalid: true };
1082
1861
  }
1083
- const c = new Cursor(text);
1862
+ const c = new Cursor(text2);
1084
1863
  const first = { checks: [] };
1085
1864
  const b = { queries: [first], subject: null, edgeCount: 0, compoundCount: 0, counts: [] };
1086
1865
  let current = first;
@@ -1098,7 +1877,7 @@ function parseCyjsSelector(text) {
1098
1877
  current = next;
1099
1878
  }
1100
1879
  c.pos = tok.end;
1101
- if (c.spaceEnd(c.pos) >= text.length) {
1880
+ if (c.spaceEnd(c.pos) >= text2.length) {
1102
1881
  break;
1103
1882
  }
1104
1883
  }
@@ -1108,22 +1887,22 @@ function parseCyjsSelector(text) {
1108
1887
  }
1109
1888
  const LINE = /[\n\r\u2028\u2029]/;
1110
1889
  const SPACE = /\s/;
1111
- function stripComments(text) {
1890
+ function stripComments(text2) {
1112
1891
  let out = "";
1113
1892
  let from = 0;
1114
1893
  for (; ; ) {
1115
- const open = text.indexOf("/*", from);
1894
+ const open = text2.indexOf("/*", from);
1116
1895
  if (open < 0) {
1117
1896
  break;
1118
1897
  }
1119
- const close = text.indexOf("*/", open + 3);
1898
+ const close = text2.indexOf("*/", open + 3);
1120
1899
  if (close < 0) {
1121
1900
  break;
1122
1901
  }
1123
- out += text.slice(from, open);
1902
+ out += text2.slice(from, open);
1124
1903
  from = close + 2;
1125
1904
  }
1126
- return out + text.slice(from);
1905
+ return out + text2.slice(from);
1127
1906
  }
1128
1907
  function skipSpace(s, i) {
1129
1908
  let j = i;
@@ -1180,8 +1959,8 @@ function nextNonSpace(s) {
1180
1959
  }
1181
1960
  return next;
1182
1961
  }
1183
- function parseCyjsStylesheetText(text) {
1184
- const s = stripComments(text);
1962
+ function parseCyjsStylesheetText(text2) {
1963
+ const s = stripComments(text2);
1185
1964
  const entries = [];
1186
1965
  let pos = 0;
1187
1966
  while (skipSpace(s, pos) < s.length) {
@@ -1282,14 +2061,14 @@ function parentsOf(nodes, ids) {
1282
2061
  if (raw === void 0 || raw === null) {
1283
2062
  continue;
1284
2063
  }
1285
- const text = typeof raw === "number" && !Number.isNaN(raw) ? String(raw) : raw;
1286
- const p = typeof text === "string" ? ids.get(text) : void 0;
2064
+ const text2 = typeof raw === "number" && !Number.isNaN(raw) ? String(raw) : raw;
2065
+ const p = typeof text2 === "string" ? ids.get(text2) : void 0;
1287
2066
  if (p === void 0 || p < 0) {
1288
2067
  nodes[i].overrides.set("parent", void 0);
1289
2068
  continue;
1290
2069
  }
1291
2070
  if (typeof raw === "number") {
1292
- nodes[i].overrides.set("parent", text);
2071
+ nodes[i].overrides.set("parent", text2);
1293
2072
  }
1294
2073
  if (rootOf(p) === i) {
1295
2074
  nodes[i].overrides.set("parent", void 0);
@@ -1413,11 +2192,11 @@ function edgeEnds(e, ids, overrides) {
1413
2192
  const ends = [];
1414
2193
  for (const field of ["source", "target"]) {
1415
2194
  const raw = e.data[field];
1416
- const text = typeof raw === "number" && !Number.isNaN(raw) ? String(raw) : raw;
2195
+ const text2 = typeof raw === "number" && !Number.isNaN(raw) ? String(raw) : raw;
1417
2196
  if (typeof raw === "number") {
1418
- overrides.set(field, text);
2197
+ overrides.set(field, text2);
1419
2198
  }
1420
- const at = typeof text === "string" ? ids.get(text) : void 0;
2199
+ const at = typeof text2 === "string" ? ids.get(text2) : void 0;
1421
2200
  if (at !== void 0) {
1422
2201
  ends.push(at);
1423
2202
  }
@@ -1971,6 +2750,16 @@ const POSITIONS = /* @__PURE__ */ new Map([
1971
2750
  ["bottom,center", "bottom"],
1972
2751
  ["bottom,right", "bottom-right"]
1973
2752
  ]);
2753
+ const INSIDE_POSITIONS = /* @__PURE__ */ new Map([
2754
+ ["top,left", "inside-top-left"],
2755
+ ["top,center", "inside-top"],
2756
+ ["top,right", "inside-top-right"],
2757
+ ["center,left", "inside-left"],
2758
+ ["center,right", "inside-right"],
2759
+ ["bottom,left", "inside-bottom-left"],
2760
+ ["bottom,center", "inside-bottom"],
2761
+ ["bottom,right", "inside-bottom-right"]
2762
+ ]);
1974
2763
  function evaluateCytoscapeJs(input) {
1975
2764
  const notes = input.notes ?? new StyleNotes();
1976
2765
  const budget = input.budget ?? new StyleBudget();
@@ -2016,8 +2805,8 @@ function evaluateCytoscapeJs(input) {
2016
2805
  notes.add(STYLE_ISSUE.SELECTOR, null, "selector", { count: deep, sample: "nested too deep" });
2017
2806
  }
2018
2807
  const matcher = new Matcher(graph, notes);
2019
- const node = evaluateTarget("node", graph, sheet, matcher, input, notes, budget);
2020
- const edge = evaluateTarget("edge", graph, sheet, matcher, input, notes, budget);
2808
+ const node = evaluateTarget("node", graph, sheet, matcher, input, { notes, budget, nodes: null });
2809
+ const edge = evaluateTarget("edge", graph, sheet, matcher, input, { notes, budget, nodes: node });
2021
2810
  return { node, edge, graph };
2022
2811
  }
2023
2812
  function outputOrder(kind, graph, snapshot, notes) {
@@ -2069,7 +2858,8 @@ function cellsOf(cells, name, n) {
2069
2858
  }
2070
2859
  return c;
2071
2860
  }
2072
- function evaluateTarget(kind, graph, sheet, matcher, input, notes, budget) {
2861
+ function evaluateTarget(kind, graph, sheet, matcher, input, env) {
2862
+ const { notes, budget } = env;
2073
2863
  const els = kind === "node" ? graph.nodes : graph.edges;
2074
2864
  const spend = (ops) => {
2075
2865
  budget.spend(kind, ops);
@@ -2087,6 +2877,20 @@ function evaluateTarget(kind, graph, sheet, matcher, input, notes, budget) {
2087
2877
  forceLoopCurves(graph, cells.get("curve-style"));
2088
2878
  }
2089
2879
  const drawn = drawnValues(kind, els, cells, order, input.rendered, notes, spend);
2880
+ if (kind === "edge" && input.toolDefaults !== false) {
2881
+ const read = { kind, els, cells, order, rendered: input.rendered, notes };
2882
+ const curves = drawnColumn(read, "curve-style", CURVE_PART);
2883
+ noArrowsOnHaystacks(curves, drawn);
2884
+ if (env.nodes !== null) {
2885
+ edgeRoutes(graph, read, curves, env.nodes, drawn);
2886
+ }
2887
+ }
2888
+ if (kind === "node") {
2889
+ const read = { kind, els, cells, order, rendered: input.rendered, notes };
2890
+ nodeSizes(graph, read, drawn);
2891
+ groupBoxes(graph, read, drawn);
2892
+ mixedLabelPlaces(graph, read, drawn);
2893
+ }
2090
2894
  if (kind === "edge") {
2091
2895
  straightenUnpairedBeziers(graph, curveStyles(graph, cells, input.rendered), coreToOut, drawn.curved);
2092
2896
  }
@@ -2191,7 +2995,7 @@ function drawnValues(kind, els, cells, order, rendered, notes, spend) {
2191
2995
  if (spec.property.startsWith("_")) {
2192
2996
  words.set(
2193
2997
  spec.property,
2194
- col.map((v) => typeof v === "string" ? v : null)
2998
+ col.map((v) => typeof v === "string" || typeof v === "number" ? String(v) : null)
2195
2999
  );
2196
3000
  continue;
2197
3001
  }
@@ -2204,6 +3008,9 @@ function drawnValues(kind, els, cells, order, rendered, notes, spend) {
2204
3008
  });
2205
3009
  }
2206
3010
  combineParts(kind, out, words, values, notes);
3011
+ if (kind === "node") {
3012
+ cyjsPolygonShapes(values);
3013
+ }
2207
3014
  const drawn = {};
2208
3015
  for (const [p, col] of Object.entries(values)) {
2209
3016
  if (col.some((v) => v !== null)) {
@@ -2293,7 +3100,7 @@ function forceLoopCurves(graph, col) {
2293
3100
  function entryProperties(entry, kind, specs, notes, notCarried) {
2294
3101
  const out = [];
2295
3102
  for (const [name0, value] of entry.properties) {
2296
- const name = entry.dashOnly ? dashOnlyName(name0) : cyjsPropertyName(name0);
3103
+ const name = entry.dashOnly ? cyjsAliasOf(name0) : cyjsPropertyName(name0);
2297
3104
  const spec = specs.get(name);
2298
3105
  if (spec === void 0) {
2299
3106
  if (kind === "node" && !CYJS_EDGE_ONLY.has(name) && !entry.tool) {
@@ -2312,22 +3119,38 @@ function entryProperties(entry, kind, specs, notes, notCarried) {
2312
3119
  }
2313
3120
  return out;
2314
3121
  }
2315
- function dashOnlyName(name) {
2316
- return name === "content" ? "label" : name;
2317
- }
2318
3122
  const CYJS_EDGE_ONLY = /* @__PURE__ */ new Set([
2319
3123
  "line-color",
2320
3124
  "line-style",
3125
+ "line-outline-width",
3126
+ "line-outline-color",
3127
+ "line-fill",
3128
+ "line-gradient-stop-colors",
3129
+ "line-gradient-stop-positions",
2321
3130
  "target-arrow-shape",
2322
3131
  "source-arrow-shape",
2323
3132
  "target-arrow-color",
2324
3133
  "source-arrow-color",
3134
+ "mid-target-arrow-shape",
3135
+ "mid-source-arrow-shape",
3136
+ "mid-target-arrow-color",
3137
+ "mid-source-arrow-color",
2325
3138
  "target-arrow-fill",
2326
3139
  "source-arrow-fill",
2327
3140
  "curve-style",
2328
3141
  "arrow-scale",
2329
3142
  "source-label",
2330
- "target-label"
3143
+ "target-label",
3144
+ "source-text-offset",
3145
+ "target-text-offset",
3146
+ "source-text-margin-x",
3147
+ "source-text-margin-y",
3148
+ "target-text-margin-x",
3149
+ "target-text-margin-y",
3150
+ "source-text-rotation",
3151
+ "target-text-rotation",
3152
+ "source-distance-from-node",
3153
+ "target-distance-from-node"
2331
3154
  ]);
2332
3155
  function matchList(sel, kind, n, matcher, ix) {
2333
3156
  if (sel.queries.length === 0) {
@@ -2408,84 +3231,757 @@ function neutralOfCell(spec, name, c, site) {
2408
3231
  return cyjsNeutral(spec, flat, site);
2409
3232
  }
2410
3233
  function combineParts(kind, n, words, values, notes) {
3234
+ const whole = [...values.opacity ?? new Array(n).fill(null)];
3235
+ combineLabelOpacity(n, words, values);
3236
+ if (kind === "node") {
3237
+ combineNodeOpacity(n, words, values);
3238
+ }
2411
3239
  const va = words.get("_valign");
2412
3240
  const ha = words.get("_halign");
2413
3241
  if (kind === "node" && (va !== void 0 || ha !== void 0)) {
2414
- values.labelPosition = Array.from(
3242
+ values.labelPosition = Array.from({ length: n }, (_, i) => labelPosition(va?.[i] ?? null, ha?.[i] ?? null));
3243
+ }
3244
+ const wrap = words.get("_wrap");
3245
+ const maxWidth = words.get("_maxWidth");
3246
+ const overflow = words.get("_overflowWrap");
3247
+ if (wrap !== void 0) {
3248
+ const cut = (i) => wrap[i] === "wrap" || wrap[i] === "ellipsis";
3249
+ values.labelWrapWidth = Array.from(
2415
3250
  { length: n },
2416
- (_, i) => labelPosition(va?.[i] ?? null, ha?.[i] ?? null, (sample) => {
2417
- notes.add(STYLE_ISSUE.UNKNOWN_VALUE, kind, "labelPosition", { sample, element: i });
2418
- })
3251
+ (_, i) => cut(i) && typeof maxWidth?.[i] === "string" ? Number(maxWidth[i]) : null
2419
3252
  );
3253
+ if (wrap.includes("ellipsis")) {
3254
+ values.labelWrapEllipsis = wrap.map((w) => w === "ellipsis" ? true : null);
3255
+ }
3256
+ if (overflow?.includes("anywhere") === true) {
3257
+ values.labelWrapAnywhere = wrap.map((w, i) => w === "wrap" && overflow[i] === "anywhere" ? true : null);
3258
+ }
2420
3259
  }
3260
+ if (kind === "node") {
3261
+ combineFace(n, words, values);
3262
+ combineBackgroundGradient(n, words, values, notes);
3263
+ } else {
3264
+ combineArrowFills(n, words, values, notes);
3265
+ combineLineOpacity(n, words.get("_lineOpacity"), values);
3266
+ }
3267
+ combineDashes(kind, n, words, values);
3268
+ combineLabelText(kind, n, words, values);
3269
+ combineLabelDress(kind, n, words, values, notes, whole);
3270
+ combineVisibility(kind, n, words, values);
3271
+ }
3272
+ function combineLabelOpacity(n, words, values) {
3273
+ const text2 = words.get("_textOpacity");
3274
+ const whole = values.opacity;
3275
+ if (text2 === void 0 && whole === void 0) {
3276
+ return;
3277
+ }
3278
+ const col = new Array(n).fill(null);
3279
+ for (let i = 0; i < n; i++) {
3280
+ const t = text2?.[i] ?? null;
3281
+ const o = whole?.[i];
3282
+ const v = Math.round((t === null ? 1 : Number(t)) * (typeof o === "number" ? o : 1) * 1e6) / 1e6;
3283
+ col[i] = v === 1 || !Number.isFinite(v) ? null : v;
3284
+ }
3285
+ values.labelOpacity = col;
3286
+ }
3287
+ function combineNodeOpacity(n, words, values) {
3288
+ const whole = values.opacity;
3289
+ for (const [part, p] of [
3290
+ ["_ringOpacity", "borderOpacity"],
3291
+ ["_outlineRingOpacity", "outerBorderOpacity"]
3292
+ ]) {
3293
+ const own = words.get(part);
3294
+ if (own === void 0 && whole === void 0) {
3295
+ continue;
3296
+ }
3297
+ values[p] = Array.from({ length: n }, (_, i) => {
3298
+ const a = own?.[i] ?? null;
3299
+ const o = whole?.[i];
3300
+ const v = Math.round((a === null ? 1 : Number(a)) * (typeof o === "number" ? o : 1) * 1e6) / 1e6;
3301
+ return v === 1 || !Number.isFinite(v) ? null : v;
3302
+ });
3303
+ }
3304
+ }
3305
+ function combineDashes(kind, n, words, values) {
3306
+ const lines = kind === "edge" ? [["lineStyle", "width", 3, "6 3", true]] : [
3307
+ ["borderStyle", "borderWidth", 0, "4 2", true],
3308
+ ["outerBorderStyle", "outerBorderWidth", 0, "4 2", false]
3309
+ ];
3310
+ for (const [style, width, fallback, pattern, own] of lines) {
3311
+ const col = values[style];
3312
+ if (col !== void 0) {
3313
+ dashColumn(col, n, values[width], { fallback, pattern }, own ? words : null);
3314
+ }
3315
+ }
3316
+ }
3317
+ function dashColumn(col, n, widths, drawn, words) {
3318
+ for (let i = 0; i < n; i++) {
3319
+ if (col[i] !== "dashed") {
3320
+ continue;
3321
+ }
3322
+ const w = widths?.[i];
3323
+ const look = dashedLook(words, i, drawn.pattern, typeof w === "number" ? w : drawn.fallback);
3324
+ if (look !== null) {
3325
+ col[i] = look;
3326
+ }
3327
+ }
3328
+ }
3329
+ function dashedLook(words, i, pattern, width) {
3330
+ const dashes = (words?.get("_dashPattern")?.[i] ?? pattern).split(/[\s,[\]]+/).filter((t) => t !== "").map((t) => Number.parseFloat(t));
3331
+ if (dashes.length === 0 || !dashes.every((d) => Number.isFinite(d))) {
3332
+ return null;
3333
+ }
3334
+ return cyjsDashLook(dashes, width, words?.get("_dashCap")?.[i] ?? "butt");
3335
+ }
3336
+ function columnOf(values, property, n) {
3337
+ let column = values[property];
3338
+ if (column === void 0) {
3339
+ column = new Array(n).fill(null);
3340
+ values[property] = column;
3341
+ }
3342
+ return column;
3343
+ }
3344
+ function combineVisibility(kind, n, words, values) {
2421
3345
  const vis = words.get("_visibility");
2422
3346
  const disp = words.get("_display");
2423
- if (vis !== void 0 || disp !== void 0) {
2424
- const col = new Array(n).fill(null);
2425
- for (let i = 0; i < n; i++) {
2426
- const a = vis?.[i] ?? null;
2427
- const b = disp?.[i] ?? null;
2428
- if (a === null && b === null) {
2429
- continue;
3347
+ if (vis === void 0 && disp === void 0) {
3348
+ return;
3349
+ }
3350
+ const col = new Array(n).fill(null);
3351
+ for (let i = 0; i < n; i++) {
3352
+ const a = vis?.[i] ?? null;
3353
+ const b = disp?.[i] ?? null;
3354
+ if (a === null && b === null) {
3355
+ continue;
3356
+ }
3357
+ const keptInvisible = kind === "node" && a === "hidden" && b !== "none";
3358
+ col[i] = keptInvisible || a !== "hidden" && b !== "none";
3359
+ if (keptInvisible) {
3360
+ for (const p of ["opacity", "borderOpacity", "outerBorderOpacity", "labelOpacity"]) {
3361
+ columnOf(values, p, n)[i] = 0;
3362
+ }
3363
+ columnOf(values, "label", n)[i] = "";
3364
+ }
3365
+ }
3366
+ values.visible = col;
3367
+ }
3368
+ function combineLabelText(kind, n, words, values) {
3369
+ transformLabels(n, words.get("_transform"), values.label);
3370
+ const justification = words.get("_justification");
3371
+ if (justification !== void 0 && kind === "edge") {
3372
+ combineEdgeJustification(n, justification, words.get("_wrap"), values);
3373
+ } else if (justification !== void 0) {
3374
+ const halign = words.get("_halign");
3375
+ const AUTO = {
3376
+ left: "right",
3377
+ right: "left",
3378
+ "left-inside": "left",
3379
+ "right-inside": "right"
3380
+ };
3381
+ values.labelTextAlign = justification.map((j, i) => {
3382
+ if (j === null) {
3383
+ return null;
2430
3384
  }
2431
- col[i] = a !== "hidden" && b !== "none";
3385
+ return j === "auto" ? AUTO[halign?.[i] ?? "center"] ?? "center" : j;
3386
+ });
3387
+ }
3388
+ const rotations = [
3389
+ ["_rotation", "labelRotation"],
3390
+ ["_sourceRotation", "sourceLabelRotation"],
3391
+ ["_targetRotation", "targetLabelRotation"]
3392
+ ];
3393
+ for (const [part, property] of rotations) {
3394
+ const rotation = words.get(part);
3395
+ if (rotation !== void 0) {
3396
+ values[property] = rotation.map((r) => r === null ? null : cyjsAngleDegrees(r));
2432
3397
  }
2433
- values.visible = col;
2434
3398
  }
2435
- if (kind === "edge") {
2436
- hollowArrows("target", words.get("_targetArrowFill"), values, notes);
2437
- hollowArrows("source", words.get("_sourceArrowFill"), values, notes);
3399
+ }
3400
+ function transformLabels(n, transform, label) {
3401
+ if (transform === void 0 || label === void 0) {
3402
+ return;
3403
+ }
3404
+ for (let i = 0; i < n; i++) {
3405
+ const text2 = label[i];
3406
+ if (typeof text2 === "string" && transform[i] === "uppercase") {
3407
+ label[i] = text2.toUpperCase();
3408
+ } else if (typeof text2 === "string" && transform[i] === "lowercase") {
3409
+ label[i] = text2.toLowerCase();
3410
+ }
3411
+ }
3412
+ }
3413
+ function combineEdgeJustification(n, justification, wrap, values) {
3414
+ const SHIFT = { left: -0.5, right: 0.5 };
3415
+ for (let i = 0; i < n; i++) {
3416
+ const shift = wrap?.[i] === "wrap" ? SHIFT[justification[i] ?? ""] : void 0;
3417
+ if (shift !== void 0) {
3418
+ columnOf(values, "labelShiftX", n)[i] = shift;
3419
+ }
2438
3420
  }
2439
3421
  }
2440
- function openArrows(setting, parts) {
2441
- for (const end of ["target", "source"]) {
2442
- let fill;
2443
- for (const p of parts) {
2444
- if (p.spec.property === `_${end}ArrowFill`) {
2445
- fill = p.parsed;
3422
+ function combineLabelDress(kind, n, words, values, notes, whole) {
3423
+ const num = (part, i, fallback) => {
3424
+ const v = words.get(part)?.[i];
3425
+ return v === null || v === void 0 ? fallback : Number(v);
3426
+ };
3427
+ const col = (p) => values[p] ??= new Array(n).fill(null);
3428
+ const outlined = words.has("_outlineWidth");
3429
+ const boxed = words.has("_backgroundOpacity");
3430
+ const bordered = words.has("_textBorderWidth") && words.has("_textBorderOpacity");
3431
+ const at = (v) => typeof v === "number" ? v : 1;
3432
+ const faded = (v) => {
3433
+ const r = Math.round(v * 1e6) / 1e6;
3434
+ return r < 1 ? r : null;
3435
+ };
3436
+ for (let i = 0; i < n && (outlined || boxed || bordered); i++) {
3437
+ const width = num("_outlineWidth", i, 0);
3438
+ const outlineOpacity = num("_outlineOpacity", i, 1);
3439
+ if (outlined && width > 0 && outlineOpacity > 0) {
3440
+ col("labelOutlineColor")[i] = words.get("_outlineColor")?.[i] ?? "#000000";
3441
+ col("labelOutlineWidth")[i] = 2 * width;
3442
+ col("labelOutlineOpacity")[i] = faded(outlineOpacity * at(values.labelOpacity?.[i]));
3443
+ }
3444
+ const boxOpacity = num("_backgroundOpacity", i, 0);
3445
+ const box = boxed && boxOpacity > 0;
3446
+ if (box) {
3447
+ col("labelBackground")[i] = words.get("_backgroundColor")?.[i] ?? "#000000";
3448
+ col("labelBackgroundOpacity")[i] = faded(boxOpacity * at(whole[i]));
3449
+ }
3450
+ const border = bordered && labelBorder(kind, i, words, col, notes, at(whole[i]));
3451
+ if (box || border) {
3452
+ labelBoxShape(kind, i, words, col, notes);
3453
+ }
3454
+ }
3455
+ }
3456
+ function labelBoxShape(kind, i, words, col, notes) {
3457
+ const padding = words.get("_backgroundPadding")?.[i];
3458
+ col("labelPadding")[i] = padding === null || padding === void 0 ? 0 : Number(padding);
3459
+ col("labelLineHeight")[i] = 1;
3460
+ const shape = words.get("_backgroundShape")?.[i];
3461
+ if (shape === "round-rectangle" || shape === "roundrectangle") {
3462
+ col("labelCornerRadius")[i] = 2;
3463
+ } else if (shape === "circle") {
3464
+ notes.add(STYLE_ISSUE.APPROXIMATED, kind, "labelBackground", { sample: "circle", element: i });
3465
+ }
3466
+ }
3467
+ function labelBorder(kind, i, words, col, notes, whole) {
3468
+ const num = (part) => Number(words.get(part)?.[i] ?? 0);
3469
+ const [width, opacity] = [num("_textBorderWidth"), num("_textBorderOpacity")];
3470
+ if (!(width > 0 && opacity > 0)) {
3471
+ return false;
3472
+ }
3473
+ const style = words.get("_textBorderStyle")?.[i] ?? "solid";
3474
+ col("labelBorderColor")[i] = words.get("_textBorderColor")?.[i] ?? "#000000";
3475
+ col("labelBorderWidth")[i] = style === "double" ? width / 4 : width;
3476
+ const drawn = Math.round(opacity * whole * 1e6) / 1e6;
3477
+ col("labelBorderOpacity")[i] = drawn < 1 ? drawn : null;
3478
+ if (style === "dotted" || style === "dashed" || style === "double") {
3479
+ notes.add(STYLE_ISSUE.APPROXIMATED, kind, "labelBorderColor", { sample: style, element: i });
3480
+ }
3481
+ return true;
3482
+ }
3483
+ function lineDegrees(a, b) {
3484
+ const dx = b[0] - a[0];
3485
+ const angle = Math.atan((b[1] - a[1]) / dx);
3486
+ const turn = (dx === 0 ? Math.abs(angle) : angle) * 180 / Math.PI;
3487
+ return Number.isFinite(turn) ? Math.round((turn % 360 + 360) % 360 * 1e6) / 1e6 + 0 : 0;
3488
+ }
3489
+ function cyjsAngleDegrees(text2) {
3490
+ const t = text2.trim();
3491
+ if (t === "none" || t === "autorotate") {
3492
+ return 0;
3493
+ }
3494
+ const m = /^(-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?)(deg|rad)?$/i.exec(t);
3495
+ if (m === null) {
3496
+ return null;
3497
+ }
3498
+ const x = Number(m[1]);
3499
+ const deg = m[2]?.toLowerCase() === "deg" ? x : x * 180 / Math.PI;
3500
+ return Math.round((deg % 360 + 360) % 360 * 1e6) / 1e6 + 0;
3501
+ }
3502
+ function combineLineOpacity(n, line, values) {
3503
+ if (line === void 0) {
3504
+ return;
3505
+ }
3506
+ const whole = values.opacity;
3507
+ values.opacity = Array.from({ length: n }, (_, i) => {
3508
+ const a = line[i] === null ? null : Number(line[i]);
3509
+ const b = whole?.[i];
3510
+ if (a === null || !Number.isFinite(a)) {
3511
+ return b ?? null;
3512
+ }
3513
+ return Math.round(a * (typeof b === "number" ? b : 1) * 1e6) / 1e6;
3514
+ });
3515
+ }
3516
+ const GRADIENT_ANGLES = /* @__PURE__ */ new Map([
3517
+ ["to-bottom", 90],
3518
+ ["to-top", 270],
3519
+ ["to-left", 180],
3520
+ ["to-right", 0],
3521
+ ["to-bottom-right", 45],
3522
+ ["to-right-bottom", 45],
3523
+ ["to-bottom-left", 135],
3524
+ ["to-left-bottom", 135],
3525
+ ["to-top-right", 315],
3526
+ ["to-right-top", 315],
3527
+ ["to-top-left", 225],
3528
+ ["to-left-top", 225]
3529
+ ]);
3530
+ function combineBackgroundGradient(n, words, values, notes) {
3531
+ const fill = words.get("_backgroundFill");
3532
+ if (fill === void 0) {
3533
+ return;
3534
+ }
3535
+ const stops = words.get("_backgroundStops");
3536
+ const positions = words.get("_backgroundPositions");
3537
+ const direction = words.get("_backgroundDirection");
3538
+ const col = (name) => values[name] ??= new Array(n).fill(null);
3539
+ for (let i = 0; i < n; i++) {
3540
+ const radial = fill[i] === "radial-gradient";
3541
+ if (fill[i] !== "linear-gradient" && !radial) {
3542
+ continue;
3543
+ }
3544
+ const colors = gradientStopColors(stops?.[i] ?? "#999", {
3545
+ notes,
3546
+ target: "node",
3547
+ property: "fill",
3548
+ element: i
3549
+ });
3550
+ if (colors.length < 2) {
3551
+ continue;
3552
+ }
3553
+ col("fill")[i] = colors[0];
3554
+ col("fillGradient")[i] = colors.at(-1) ?? null;
3555
+ if (colors.length > 2) {
3556
+ col("fillGradientColors")[i] = colors.join(" ");
3557
+ }
3558
+ const placed = gradientStops(positions?.[i] ?? "");
3559
+ if (placed?.split(" ").length === colors.length) {
3560
+ col("fillGradientStops")[i] = placed;
3561
+ }
3562
+ if (radial) {
3563
+ col("fillGradientKind")[i] = "radial";
3564
+ } else {
3565
+ col("fillGradientAngle")[i] = GRADIENT_ANGLES.get(direction?.[i] ?? "to-bottom") ?? 90;
3566
+ }
3567
+ }
3568
+ }
3569
+ const ROUTE_PARTS = [
3570
+ ["segmentDistances", "segment-distances", { property: "_segmentDistances", type: "text" }],
3571
+ ["segmentWeights", "segment-weights", { property: "_segmentWeights", type: "text" }],
3572
+ ["controlPointDistances", "control-point-distances", { property: "_controlPointDistances", type: "text" }],
3573
+ ["controlPointWeights", "control-point-weights", { property: "_controlPointWeights", type: "text" }],
3574
+ ["controlPointStepSize", "control-point-step-size", { property: "_controlPointStepSize", type: "size" }],
3575
+ ["taxiDirection", "taxi-direction", { property: "_taxiDirection", type: "text" }],
3576
+ ["taxiTurn", "taxi-turn", { property: "_taxiTurn", type: "text" }],
3577
+ ["taxiTurnMinDistance", "taxi-turn-min-distance", { property: "_taxiTurnMinDistance", type: "size" }],
3578
+ ["edgeDistances", "edge-distances", { property: "_edgeDistances", type: "text" }],
3579
+ ["loopDirection", "loop-direction", { property: "_loopDirection", type: "text" }],
3580
+ ["loopSweep", "loop-sweep", { property: "_loopSweep", type: "text" }],
3581
+ ["segmentRadii", "segment-radii", { property: "_segmentRadii", type: "text" }],
3582
+ ["taxiRadius", "taxi-radius", { property: "_taxiRadius", type: "text" }],
3583
+ ["radiusType", "radius-type", { property: "_radiusType", type: "text" }]
3584
+ ];
3585
+ function edgeRoutes(graph, read, curves, nodes, values) {
3586
+ const words = new Map(ROUTE_PARTS.map(([key, name, spec]) => [key, drawnColumn(read, name, spec)]));
3587
+ const nodeAt = /* @__PURE__ */ new Map();
3588
+ nodes.elements.forEach((el, k) => {
3589
+ if (el !== null) {
3590
+ nodeAt.set(el, k);
3591
+ }
3592
+ });
3593
+ const geometry = (core) => routeNode(graph.nodes[core], nodeAt, nodes);
3594
+ const turned = [
3595
+ ["labelRotation", drawnColumn(read, "text-rotation", TEXT_PART)],
3596
+ ["sourceLabelRotation", drawnColumn(read, "source-text-rotation", TEXT_PART)],
3597
+ ["targetLabelRotation", drawnColumn(read, "target-text-rotation", TEXT_PART)]
3598
+ ];
3599
+ const ends = [drawnColumn(read, "source-endpoint", TEXT_PART), drawnColumn(read, "target-endpoint", TEXT_PART)];
3600
+ const loops = /* @__PURE__ */ new Map();
3601
+ const n = read.order.length;
3602
+ let routed = null;
3603
+ for (let k = 0; k < n; k++) {
3604
+ const e = read.order[k];
3605
+ const between = edgeNodes(graph, e, geometry);
3606
+ if (between === null) {
3607
+ continue;
3608
+ }
3609
+ const { src, tgt, loop } = between;
3610
+ if (!loop) {
3611
+ autorotateLabels(values, turned, k, n, lineDegrees(src.center, tgt.center));
3612
+ }
3613
+ const edge = routeSettings(words, k, curves[k]);
3614
+ const bends = cyjsRoute(edge, src, tgt, loop ? nextLoopIndex(loops, graph.source[e], edge) : 0);
3615
+ if (bends !== null) {
3616
+ routed ??= values.bends ?? new Array(n).fill(null);
3617
+ routed[k] = bends;
3618
+ columnOf(values, "curved", n)[k] = false;
3619
+ }
3620
+ if (!loop) {
3621
+ edgePorts(edge.curveStyle, [ends[0][k], ends[1][k]], [src, tgt], (p, port) => {
3622
+ columnOf(values, p, n)[k] = port;
3623
+ });
3624
+ }
3625
+ }
3626
+ if (routed !== null) {
3627
+ values.bends = routed;
3628
+ }
3629
+ }
3630
+ function routeNode(el, nodeAt, nodes) {
3631
+ const k = nodeAt.get(el);
3632
+ const pos = el.json.position;
3633
+ if (k === void 0 || !isObject(pos) || typeof pos.x !== "number" || typeof pos.y !== "number") {
3634
+ return null;
3635
+ }
3636
+ const num = (p, fallback) => {
3637
+ const v = nodes.values[p]?.[k];
3638
+ return typeof v === "number" ? v : fallback;
3639
+ };
3640
+ const [w, h, bw] = [num("width", 30), num("height", 30), num("borderWidth", 0)];
3641
+ return {
3642
+ center: [pos.x, pos.y],
3643
+ size: [w + bw, h + bw],
3644
+ box: [w, h],
3645
+ ellipse: (nodes.values.shape?.[k] ?? "ellipse") === "ellipse"
3646
+ };
3647
+ }
3648
+ function edgeNodes(graph, e, geometry) {
3649
+ if (e < 0) {
3650
+ return null;
3651
+ }
3652
+ const loop = graph.source[e] === graph.target[e];
3653
+ const src = geometry(graph.source[e]);
3654
+ const tgt = loop ? src : geometry(graph.target[e]);
3655
+ return src === null || tgt === null ? null : { src, tgt, loop };
3656
+ }
3657
+ function autorotateLabels(values, turned, k, n, degrees2) {
3658
+ for (const [property, column] of turned) {
3659
+ if (column[k] === "autorotate") {
3660
+ columnOf(values, property, n)[k] = degrees2;
3661
+ }
3662
+ }
3663
+ }
3664
+ function nextLoopIndex(loops, source, edge) {
3665
+ const key = `${String(source)} ${String(edge.loopDirection)} ${String(edge.loopSweep)}`;
3666
+ const index = loops.get(key) ?? 0;
3667
+ loops.set(key, index + 1);
3668
+ return index;
3669
+ }
3670
+ function edgePorts(curve, words, nodes, put) {
3671
+ if (curve === "taxi" || curve === "round-taxi") {
3672
+ return;
3673
+ }
3674
+ ["sourcePort", "targetPort"].forEach((p, a) => {
3675
+ const port = curve === "haystack" ? "0,0" : endpointPort(String(words[a] ?? ""), nodes[a]);
3676
+ if (port !== null) {
3677
+ put(p, port);
3678
+ }
3679
+ });
3680
+ }
3681
+ function endpointPort(text2, node) {
3682
+ const t = text2.trim();
3683
+ if (t === "inside-to-node") {
3684
+ return "0,0";
3685
+ }
3686
+ const parts = t.split(/\s+/);
3687
+ const [w, h] = node.size;
3688
+ const r62 = (v) => String(Math.round(v * 1e6) / 1e6 + 0);
3689
+ const fraction2 = (part, size) => {
3690
+ const m2 = /^(-?(?:\d+(?:\.\d*)?|\.\d+))(%|px)?$/.exec(part);
3691
+ if (m2 === null || Number.isNaN(size) || size <= 0) {
3692
+ return null;
3693
+ }
3694
+ const px = m2[2] === "%" ? Number(m2[1]) / 100 * size : Number(m2[1]);
3695
+ return px / (size / 2);
3696
+ };
3697
+ if (parts.length === 2) {
3698
+ const [x, y] = [fraction2(parts[0], w), fraction2(parts[1], h)];
3699
+ return x === null || y === null ? null : `${r62(x)},${r62(-y)}`;
3700
+ }
3701
+ const m = /^(-?(?:\d+(?:\.\d*)?|\.\d+))(deg|rad)$/.exec(t);
3702
+ if (m === null) {
3703
+ return null;
3704
+ }
3705
+ const turn = m[2] === "deg" ? Number(m[1]) * Math.PI / 180 : Number(m[1]);
3706
+ const [dx, dy] = [Math.sin(turn) / (w / 2), Math.cos(turn) / (h / 2)];
3707
+ const reach = node.ellipse ? Math.hypot(dx, dy) : Math.max(Math.abs(dx), Math.abs(dy));
3708
+ return reach > 0 ? `${r62(dx / reach)},${r62(dy / reach)}` : null;
3709
+ }
3710
+ function routeSettings(words, k, curve) {
3711
+ const text2 = (key) => {
3712
+ const v = words.get(key)?.[k];
3713
+ return v === null || v === void 0 ? null : String(v);
3714
+ };
3715
+ const num = (key) => {
3716
+ const v = text2(key);
3717
+ return v === null ? null : Number(v);
3718
+ };
3719
+ return {
3720
+ curveStyle: String(curve ?? "haystack"),
3721
+ segmentDistances: text2("segmentDistances"),
3722
+ segmentWeights: text2("segmentWeights"),
3723
+ controlPointDistances: text2("controlPointDistances"),
3724
+ controlPointWeights: text2("controlPointWeights"),
3725
+ controlPointStepSize: num("controlPointStepSize"),
3726
+ taxiDirection: text2("taxiDirection"),
3727
+ taxiTurn: text2("taxiTurn"),
3728
+ taxiTurnMinDistance: num("taxiTurnMinDistance"),
3729
+ edgeDistances: text2("edgeDistances"),
3730
+ loopDirection: text2("loopDirection"),
3731
+ loopSweep: text2("loopSweep"),
3732
+ segmentRadii: text2("segmentRadii"),
3733
+ taxiRadius: text2("taxiRadius"),
3734
+ radiusType: text2("radiusType")
3735
+ };
3736
+ }
3737
+ const TEXT_PART = { property: "_text", type: "text" };
3738
+ function nodeSizes(graph, read, values) {
3739
+ const padding = drawnColumn(read, "padding", TEXT_PART);
3740
+ const toLabel = ["width", "height"].map((p) => drawnColumn(read, p, SIZE_PART));
3741
+ const n = read.order.length;
3742
+ const col = (p) => values[p] ??= new Array(n).fill(null);
3743
+ for (let k = 0; k < n; k++) {
3744
+ const core = read.order[k];
3745
+ const pad = core < 0 || graph.children[core].length > 0 ? 0 : paddingOf(padding[k]);
3746
+ const fitted = toLabel.map((c) => c[k] === "label");
3747
+ if (fitted[0] || fitted[1]) {
3748
+ col("labelFit")[k] = "bounds";
3749
+ col("labelPaddingX")[k] = pad;
3750
+ col("labelPaddingY")[k] = pad;
3751
+ ["width", "height"].forEach((p, a) => {
3752
+ const v = values[p]?.[k];
3753
+ const side = typeof v === "number" ? v : 30;
3754
+ col(p)[k] = fitted[a] ? 0 : side + 2 * pad;
3755
+ });
3756
+ continue;
3757
+ }
3758
+ if (pad <= 0) {
3759
+ continue;
3760
+ }
3761
+ for (const p of ["width", "height"]) {
3762
+ const v = values[p]?.[k];
3763
+ col(p)[k] = (typeof v === "number" ? v : 30) + 2 * pad;
3764
+ }
3765
+ }
3766
+ }
3767
+ const PADDING_OF_PART = {
3768
+ property: "_paddingOf",
3769
+ type: "enum",
3770
+ enums: ["width", "height", "average", "min", "max"]
3771
+ };
3772
+ const LABELS_PART = { property: "_compoundLabels", type: "enum", enums: ["include", "exclude"] };
3773
+ function measureOf(text2) {
3774
+ if (typeof text2 !== "string" && typeof text2 !== "number") {
3775
+ return null;
3776
+ }
3777
+ const value = Number.parseFloat(String(text2));
3778
+ return Number.isFinite(value) ? { value, percent: String(text2).trim().endsWith("%") } : null;
3779
+ }
3780
+ function biasShare(near2, far, min) {
3781
+ const percent = (text2) => {
3782
+ const m = measureOf(text2);
3783
+ if (m === null || m.value <= 0) {
3784
+ return 0;
3785
+ }
3786
+ return m.percent ? m.value : m.value * 100 / min;
3787
+ };
3788
+ const a = percent(near2);
3789
+ const total = a + percent(far);
3790
+ return total > 0 ? a / total : null;
3791
+ }
3792
+ function groupBoxes(graph, read, values) {
3793
+ const word = (name, spec = TEXT_PART) => drawnColumn(read, name, spec);
3794
+ const padding = word("padding");
3795
+ const paddingOf2 = word("padding-relative-to", PADDING_OF_PART);
3796
+ const labels = word("compound-sizing-wrt-labels", LABELS_PART);
3797
+ const axes = [
3798
+ { min: word("min-width"), near: word("min-width-bias-left"), far: word("min-width-bias-right") },
3799
+ { min: word("min-height"), near: word("min-height-bias-top"), far: word("min-height-bias-bottom") }
3800
+ ];
3801
+ const names = [
3802
+ ["groupMinWidth", "groupMinWidthBiasLeft"],
3803
+ ["groupMinHeight", "groupMinHeightBiasTop"]
3804
+ ];
3805
+ const n = read.order.length;
3806
+ const put = (p, k, v) => {
3807
+ const column = values[p] ?? new Array(n).fill(null);
3808
+ values[p] = column;
3809
+ column[k] = v;
3810
+ };
3811
+ for (let k = 0; k < n; k++) {
3812
+ const core = read.order[k];
3813
+ if (core < 0 || graph.children[core].length === 0) {
3814
+ continue;
3815
+ }
3816
+ for (const [p, v] of groupPaddingValues(padding[k], paddingOf2[k])) {
3817
+ put(p, k, v);
3818
+ }
3819
+ put("groupIncludeLabels", k, labels[k] !== "exclude");
3820
+ axes.forEach((axis, a) => {
3821
+ for (const [p, v] of groupMinValues(axis.min[k], axis.near[k], axis.far[k], names[a])) {
3822
+ put(p, k, v);
2446
3823
  }
3824
+ });
3825
+ }
3826
+ }
3827
+ function groupPaddingValues(padding, of) {
3828
+ const pad = measureOf(padding);
3829
+ if (pad?.percent !== true) {
3830
+ return [["groupPadding", Math.max(0, pad?.value ?? 0)]];
3831
+ }
3832
+ return [
3833
+ ["groupPaddingRatio", Math.max(0, pad.value / 100)],
3834
+ ["groupPaddingOf", typeof of === "string" ? of : "width"]
3835
+ ];
3836
+ }
3837
+ function groupMinValues(min, near2, far, names) {
3838
+ const m = measureOf(min);
3839
+ if (m === null || m.percent || m.value <= 0) {
3840
+ return [];
3841
+ }
3842
+ const share = biasShare(near2, far, m.value);
3843
+ return share === null ? [[names[0], m.value]] : [
3844
+ [names[0], m.value],
3845
+ [names[1], share]
3846
+ ];
3847
+ }
3848
+ const VALIGN_PART = {
3849
+ property: "_valign",
3850
+ type: "enum",
3851
+ enums: ["top", "top-inside", "center", "bottom", "bottom-inside"]
3852
+ };
3853
+ const HALIGN_PART = {
3854
+ property: "_halign",
3855
+ type: "enum",
3856
+ enums: ["left", "left-inside", "center", "right", "right-inside"]
3857
+ };
3858
+ function pinnedAxis(align, half, pad) {
3859
+ const near2 = /^(left|top)/.test(align);
3860
+ if (!near2 && !/^(right|bottom)/.test(align)) {
3861
+ return { offset: 0, shift: 0 };
3862
+ }
3863
+ const side = near2 ? -1 : 1;
3864
+ return align.endsWith("-inside") ? { offset: side * (half - 2 * pad), shift: -side / 2 } : { offset: side * half, shift: side / 2 };
3865
+ }
3866
+ function mixedLabelPlaces(graph, read, values) {
3867
+ const va = drawnColumn(read, "text-valign", VALIGN_PART);
3868
+ const ha = drawnColumn(read, "text-halign", HALIGN_PART);
3869
+ const padding = drawnColumn(read, "padding", TEXT_PART);
3870
+ const n = read.order.length;
3871
+ const col = (p) => values[p] ??= new Array(n).fill(null);
3872
+ for (let k = 0; k < n; k++) {
3873
+ const v = typeof va[k] === "string" ? String(va[k]) : "top";
3874
+ const h = typeof ha[k] === "string" ? String(ha[k]) : "center";
3875
+ const inside = v.endsWith("-inside") || h.endsWith("-inside");
3876
+ const outside = v === "top" || v === "bottom" || h === "left" || h === "right";
3877
+ if (!inside || !outside) {
3878
+ continue;
2447
3879
  }
2448
- const shape = setting.get(`${end}Arrow`);
2449
- const open = shape === void 0 ? void 0 : OPEN_ARROWS.get(shape);
2450
- if (fill?.kind === "word" && fill.value === "hollow" && open !== void 0) {
2451
- setting.set(`${end}Arrow`, open);
3880
+ if (values.labelFit?.[k] !== void 0 && values.labelFit[k] !== null) {
3881
+ read.notes.add(STYLE_ISSUE.APPROXIMATED, "node", "labelPosition", { sample: `${v} ${h}`, element: k });
3882
+ continue;
2452
3883
  }
3884
+ const core = read.order[k];
3885
+ const pad = core < 0 || graph.children[core].length > 0 ? 0 : paddingOf(padding[k]);
3886
+ const size = (p) => {
3887
+ const s = values[p]?.[k];
3888
+ return typeof s === "number" ? s : 30 + 2 * pad;
3889
+ };
3890
+ const x = pinnedAxis(h, size("width") / 2, pad);
3891
+ const y = pinnedAxis(v, size("height") / 2, pad);
3892
+ const add = (p, d) => {
3893
+ const was = values[p]?.[k];
3894
+ col(p)[k] = (typeof was === "number" ? was : 0) + d;
3895
+ };
3896
+ col("labelPosition")[k] = "center";
3897
+ add("labelOffsetX", x.offset);
3898
+ add("labelOffsetY", y.offset);
3899
+ col("labelShiftX")[k] = x.shift;
3900
+ col("labelShiftY")[k] = y.shift;
3901
+ }
3902
+ }
3903
+ const SIZE_PART = { property: "_size", type: "nodeSize" };
3904
+ function paddingOf(text2) {
3905
+ if (typeof text2 !== "string") {
3906
+ return 0;
3907
+ }
3908
+ const x = Number.parseFloat(text2);
3909
+ if (!Number.isFinite(x) || x <= 0) {
3910
+ return 0;
2453
3911
  }
3912
+ return text2.trim().endsWith("%") ? x / 100 : x;
2454
3913
  }
2455
- const OPEN_ARROWS = /* @__PURE__ */ new Map([
3914
+ const CURVE_PART = { property: "_curve", type: "enum", enums: CYJS_CURVE_STYLES };
3915
+ function noArrowsOnHaystacks(curves, values) {
3916
+ const n = curves.length;
3917
+ for (const p of ["targetArrow", "sourceArrow"]) {
3918
+ const col = values[p];
3919
+ if (col === void 0) {
3920
+ continue;
3921
+ }
3922
+ for (let i = 0; i < n; i++) {
3923
+ if ((curves[i] ?? "haystack") === "haystack" && col[i] !== null) {
3924
+ col[i] = "none";
3925
+ }
3926
+ }
3927
+ }
3928
+ }
3929
+ const HOLLOW_ARROWS = /* @__PURE__ */ new Map([
2456
3930
  ["triangle", "triangle-open"],
3931
+ ["diamond", "diamond-open"],
2457
3932
  ["circle", "circle-open"],
2458
- ["diamond", "diamond-open"]
3933
+ ["square", "other:open-square"]
2459
3934
  ]);
2460
- function hollowArrows(end, fill, values, notes) {
2461
- const shapes = values[`${end}Arrow`];
2462
- if (fill === void 0 || shapes === void 0) {
2463
- return;
3935
+ function hollowArrowsOfRule(set, all) {
3936
+ for (const p of all) {
3937
+ const shapeProp = /^_(\w+Arrow)Fill$/.exec(p.spec.property)?.[1];
3938
+ const shape = shapeProp === void 0 ? void 0 : set[shapeProp];
3939
+ if (shapeProp === void 0 || shape === void 0 || p.parsed.kind !== "word") {
3940
+ continue;
3941
+ }
3942
+ const open = HOLLOW_ARROWS.get(shape);
3943
+ if (open !== void 0 && p.parsed.value === "hollow") {
3944
+ set[shapeProp] = open;
3945
+ }
2464
3946
  }
2465
- for (let i = 0; i < shapes.length; i++) {
2466
- const shape = shapes[i];
2467
- if (fill[i] !== "hollow" || shape === null || shape === "none") {
3947
+ }
3948
+ function combineArrowFills(n, words, values, notes) {
3949
+ for (const p of ["targetArrow", "sourceArrow", "midTargetArrow", "midSourceArrow"]) {
3950
+ const fill = words.get(`_${p}Fill`);
3951
+ const shapes = values[p];
3952
+ if (fill === void 0 || shapes === void 0) {
2468
3953
  continue;
2469
3954
  }
2470
- const open = OPEN_ARROWS.get(shape);
2471
- if (open === void 0) {
2472
- notes.add(STYLE_ISSUE.NOT_CARRIED, "edge", `${end}-arrow-fill`, {
2473
- sample: `hollow ${String(shape)}`,
2474
- element: i
2475
- });
2476
- } else {
2477
- shapes[i] = open;
3955
+ for (let i = 0; i < n; i++) {
3956
+ const shape = shapes[i];
3957
+ if (fill[i] !== "hollow" || shape === null || shape === "none") {
3958
+ continue;
3959
+ }
3960
+ const open = HOLLOW_ARROWS.get(shape);
3961
+ if (open !== void 0) {
3962
+ shapes[i] = open;
3963
+ } else if (!String(shape).includes("open")) {
3964
+ const property = p.replaceAll(/[A-Z]/g, (c) => `-${c.toLowerCase()}`).replace("-arrow", "-arrow-fill");
3965
+ notes.add(STYLE_ISSUE.NOT_CARRIED, "edge", property, { sample: `hollow ${String(shape)}`, element: i });
3966
+ }
2478
3967
  }
2479
3968
  }
2480
3969
  }
2481
- function labelPosition(v, h, note) {
3970
+ function labelPosition(v, h) {
2482
3971
  if (v === null && h === null) {
2483
3972
  return null;
2484
3973
  }
3974
+ const vIn = (v ?? "").endsWith("-inside");
3975
+ const hIn = (h ?? "").endsWith("-inside");
2485
3976
  const vv = (v ?? "top").replace("-inside", "");
2486
3977
  const hh = (h ?? "center").replace("-inside", "");
2487
- if ((v ?? "").endsWith("-inside") || (h ?? "").endsWith("-inside")) {
2488
- note(`${v ?? ""} ${h ?? ""}`);
3978
+ if (vIn || hIn) {
3979
+ const vOut = vv !== "center" && !vIn;
3980
+ const hOut = hh !== "center" && !hIn;
3981
+ if (!vOut && !hOut) {
3982
+ return INSIDE_POSITIONS.get(`${vv},${hh}`) ?? null;
3983
+ }
3984
+ return POSITIONS.get(`${vIn ? "center" : vv},${hIn ? "center" : hh}`) ?? null;
2489
3985
  }
2490
3986
  return POSITIONS.get(`${vv},${hh}`) ?? null;
2491
3987
  }
@@ -2522,7 +4018,7 @@ function buildRules(kind, applied, core, input, truth, env) {
2522
4018
  const rules = collapse(ctx, drafts);
2523
4019
  return { rules, columns, rawColumns: [...raw] };
2524
4020
  }
2525
- function draftOf(ctx, entry, list, props, parts) {
4021
+ function draftOf(ctx, entry, list, props, all) {
2526
4022
  const setting = /* @__PURE__ */ new Map();
2527
4023
  const mapping = /* @__PURE__ */ new Map();
2528
4024
  let flattened = false;
@@ -2550,8 +4046,12 @@ function draftOf(ctx, entry, list, props, parts) {
2550
4046
  mapping.set(p.spec.property, mapperMapping(ctx, entry, list, p));
2551
4047
  }
2552
4048
  }
2553
- openArrows(setting, parts);
2554
4049
  const set = Object.fromEntries(setting);
4050
+ if (ctx.kind === "node") {
4051
+ cyjsPolygonShapes(set);
4052
+ } else {
4053
+ hollowArrowsOfRule(set, all);
4054
+ }
2555
4055
  const map = Object.fromEntries(mapping);
2556
4056
  const hasMap = mapping.size > 0;
2557
4057
  const rule = () => {
@@ -2982,7 +4482,8 @@ const SHAPES_TO_CYJS = /* @__PURE__ */ new Map([
2982
4482
  ["octagon", "octagon"],
2983
4483
  ["parallelogram", "rhomboid"],
2984
4484
  ["star", "star"],
2985
- ["vee", "vee"]
4485
+ ["vee", "vee"],
4486
+ ["polygon", "polygon"]
2986
4487
  ]);
2987
4488
  const ARROWS_TO_CYJS = /* @__PURE__ */ new Map([
2988
4489
  ["none", "none"],
@@ -2993,6 +4494,17 @@ const ARROWS_TO_CYJS = /* @__PURE__ */ new Map([
2993
4494
  ["circle", "circle"],
2994
4495
  ["square", "square"]
2995
4496
  ]);
4497
+ const LINE_FILLS = /* @__PURE__ */ new Map([
4498
+ ["none", "solid"],
4499
+ ["linear", "linear-gradient"],
4500
+ ["radial", "radial-gradient"]
4501
+ ]);
4502
+ const ARROW_PROPERTY = {
4503
+ sourceArrow: "source-arrow-shape",
4504
+ targetArrow: "target-arrow-shape",
4505
+ midSourceArrow: "mid-source-arrow-shape",
4506
+ midTargetArrow: "mid-target-arrow-shape"
4507
+ };
2996
4508
  const ARROWS_OPEN = /* @__PURE__ */ new Map([
2997
4509
  ["triangle-open", "triangle"],
2998
4510
  ["diamond-open", "diamond"],
@@ -3008,12 +4520,27 @@ function toCyjs(target, property, value) {
3008
4520
  switch (property) {
3009
4521
  case "visible":
3010
4522
  return exact({ display: value === false ? "none" : "element" });
4523
+ case "shapePoints":
4524
+ return pointsToCyjs(String(value));
3011
4525
  case "labelItalic":
3012
4526
  return exact({ "font-style": value === true ? "italic" : "normal" });
3013
4527
  case "curved":
3014
4528
  return exact({ "curve-style": value === true ? "unbundled-bezier" : "straight" });
3015
4529
  case "labelPosition":
3016
4530
  return labelPositionToCyjs(String(value));
4531
+ case "fanSpacing":
4532
+ case "labelWrapWidth":
4533
+ return ifNumber(value, (v) => numberToCyjs(property, v));
4534
+ case "gradientKind":
4535
+ return gradientKindToCyjs(String(value));
4536
+ case "gradientStops":
4537
+ return exact({
4538
+ "line-gradient-stop-positions": String(value).trim().split(/\s+/).map((s) => `${num6(Number(s) * 100)}%`).join(" ")
4539
+ });
4540
+ case "outerBorderOffset":
4541
+ return ifNumber(value, (v) => exact({ "outline-offset": num6(v * 2) }));
4542
+ case "outerBorderStyle":
4543
+ return outerBorderStyleToCyjs(String(value));
3017
4544
  case "shape":
3018
4545
  return enumToCyjs("shape", String(value), SHAPES_TO_CYJS, specs);
3019
4546
  case "borderStyle":
@@ -3022,30 +4549,90 @@ function toCyjs(target, property, value) {
3022
4549
  return lineStyleToCyjs(String(value));
3023
4550
  case "sourceArrow":
3024
4551
  case "targetArrow":
3025
- return arrowToCyjs(
3026
- property === "sourceArrow" ? "source-arrow-shape" : "target-arrow-shape",
3027
- String(value),
3028
- specs
3029
- );
4552
+ case "midSourceArrow":
4553
+ case "midTargetArrow":
4554
+ return arrowToCyjs(ARROW_PROPERTY[property], String(value), specs);
3030
4555
  case "labelFont":
3031
4556
  return isFontFamily(String(value)) ? exact({ "font-family": String(value) }) : null;
4557
+ // a label's box draws only at an opacity above 0, which is 0 unset
4558
+ case "labelBackground":
4559
+ return exact({ "text-background-color": String(value), "text-background-opacity": 1 });
4560
+ // the outline is drawn as a stroke twice text-outline-width (see the reader)
4561
+ case "labelOutlineColor":
4562
+ return exact({ "text-outline-color": String(value) });
4563
+ case "labelOutlineWidth":
4564
+ return ifNumber(value, (v) => exact({ "text-outline-width": num6(v / 2) }));
4565
+ case "labelPadding":
4566
+ return ifNumber(value, (v) => exact({ "text-background-padding": v }));
4567
+ // the line round a label's box draws only at an opacity above 0, which is 0 unset
4568
+ case "labelBorderColor":
4569
+ return exact({ "text-border-color": String(value), "text-border-opacity": 1 });
4570
+ case "labelBorderWidth":
4571
+ return ifNumber(value, (v) => exact({ "text-border-width": v, "text-border-opacity": 1 }));
4572
+ default:
4573
+ return groupToCyjs(property, value) ?? propertyToCyjs(property, value, specs);
4574
+ }
4575
+ }
4576
+ function groupToCyjs(property, value) {
4577
+ const percent = (v) => `${num6(v * 100)}%`;
4578
+ switch (property) {
4579
+ case "groupPadding":
4580
+ return ifNumber(value, (v) => exact({ padding: `${num6(v)}px` }));
4581
+ case "groupPaddingRatio":
4582
+ return ifNumber(value, (v) => exact({ padding: percent(v) }));
4583
+ case "groupPaddingOf":
4584
+ return exact({ "padding-relative-to": String(value) });
4585
+ case "groupMinWidth":
4586
+ return ifNumber(value, (v) => exact({ "min-width": `${num6(v)}px` }));
4587
+ case "groupMinHeight":
4588
+ return ifNumber(value, (v) => exact({ "min-height": `${num6(v)}px` }));
4589
+ case "groupMinWidthBiasLeft":
4590
+ return ifNumber(
4591
+ value,
4592
+ (v) => exact({ "min-width-bias-left": percent(v), "min-width-bias-right": percent(1 - v) })
4593
+ );
4594
+ case "groupMinHeightBiasTop":
4595
+ return ifNumber(
4596
+ value,
4597
+ (v) => exact({ "min-height-bias-top": percent(v), "min-height-bias-bottom": percent(1 - v) })
4598
+ );
4599
+ case "groupIncludeLabels":
4600
+ return exact({ "compound-sizing-wrt-labels": value === false ? "exclude" : "include" });
3032
4601
  default:
3033
- return propertyToCyjs(property, value, specs);
4602
+ return null;
3034
4603
  }
3035
4604
  }
4605
+ function ifNumber(value, write) {
4606
+ return typeof value === "number" ? write(value) : null;
4607
+ }
4608
+ function gradientKindToCyjs(kind) {
4609
+ const fill = LINE_FILLS.get(kind);
4610
+ return fill === void 0 ? null : exact({ "line-fill": fill });
4611
+ }
4612
+ function outerBorderStyleToCyjs(style) {
4613
+ const written2 = borderStyleToCyjs(style);
4614
+ return written2 === null ? null : { ...written2, props: { "outline-style": written2.props["border-style"] } };
4615
+ }
4616
+ function pointsToCyjs(points) {
4617
+ const written2 = neutralPointsToCyjs(points);
4618
+ return written2 === null ? null : exact({ "shape-polygon-points": written2 });
4619
+ }
4620
+ function numberToCyjs(property, value) {
4621
+ return property === "fanSpacing" ? exact({ "control-point-step-size": num6(value * 2) }) : exact({ "text-wrap": "wrap", "text-max-width": value });
4622
+ }
3036
4623
  function exact(props) {
3037
4624
  return { props, approximate: false };
3038
4625
  }
3039
4626
  function near(props) {
3040
4627
  return { props, approximate: true };
3041
4628
  }
3042
- function labelPositionToCyjs(text) {
3043
- if (text === "inside-top") {
3044
- return near({ "text-valign": "top", "text-halign": "center" });
3045
- }
3046
- const v = ["top", "bottom"].find((x) => text.startsWith(x)) ?? "center";
3047
- const h = ["left", "right"].find((x) => text.endsWith(x)) ?? "center";
3048
- return exact({ "text-valign": v, "text-halign": h });
4629
+ function labelPositionToCyjs(text2) {
4630
+ const inside = text2.startsWith("inside-");
4631
+ const side = inside ? text2.slice("inside-".length) : text2;
4632
+ const v = ["top", "bottom"].find((x) => side.startsWith(x)) ?? "center";
4633
+ const h = ["left", "right"].find((x) => side.endsWith(x)) ?? "center";
4634
+ const of = (a) => inside && a !== "center" ? `${a}-inside` : a;
4635
+ return exact({ "text-valign": of(v), "text-halign": of(h) });
3049
4636
  }
3050
4637
  function enumToCyjs(name, value, table, specs) {
3051
4638
  const cy = table.get(value);
@@ -3475,13 +5062,81 @@ function exactness(e, rules) {
3475
5062
  const src = refSource(target, n, extracted.columns[target], extracted.features[target]);
3476
5063
  const rows = new Array(n).fill(null);
3477
5064
  for (const property of STYLE_PROPERTIES[target].keys()) {
3478
- const want = resolveRules(rules, target, property, src);
3479
- addBypasses(rows, target, property, want, drawn[target].values[property]);
5065
+ const want2 = resolveRules(rules, target, property, src);
5066
+ addBypasses(rows, target, property, want2, drawn[target].values[property]);
5067
+ }
5068
+ const want = (p) => resolveRules(rules, target, p, src);
5069
+ if (target === "node") {
5070
+ labelSizedBypasses(rows, want, drawn.node.values);
5071
+ }
5072
+ labelOpacityBypasses(rows, want, drawn[target].values);
5073
+ const parts = [
5074
+ ["labelBackgroundOpacity", "text-background-opacity", "opacity", "labelBackground"],
5075
+ ["labelBorderOpacity", "text-border-opacity", "opacity", "labelBorderWidth"],
5076
+ ["labelOutlineOpacity", "text-outline-opacity", "labelOpacity", "labelOutlineWidth"]
5077
+ ];
5078
+ if (target === "node") {
5079
+ parts.push(
5080
+ ["borderOpacity", "border-opacity", "opacity", null],
5081
+ ["outerBorderOpacity", "outline-opacity", "opacity", null]
5082
+ );
5083
+ }
5084
+ for (const part of parts) {
5085
+ partOpacityBypasses(rows, want, drawn[target].values, part);
3480
5086
  }
3481
5087
  out[target] = rows;
3482
5088
  }
3483
5089
  return out;
3484
5090
  }
5091
+ function labelOpacityBypasses(rows, want, got) {
5092
+ const label = want("labelOpacity");
5093
+ const whole = want("opacity");
5094
+ const at = (v) => typeof v === "number" ? v : 1;
5095
+ for (let i = 0; i < rows.length; i++) {
5096
+ const [l, o] = [at(label[i]), at(whole[i])];
5097
+ const rewritten = rows[i]?.opacity !== void 0;
5098
+ if (l === at(got.labelOpacity?.[i]) && !rewritten || Number.isNaN(o) || o <= 0) {
5099
+ continue;
5100
+ }
5101
+ if (l === o && rewritten) {
5102
+ continue;
5103
+ }
5104
+ if (l <= o) {
5105
+ rows[i] = { ...rows[i], "text-opacity": num6(l / o) };
5106
+ } else if (l > 0) {
5107
+ rows[i] = { ...rows[i], opacity: num6(l), "line-opacity": num6(o / l), "text-opacity": 1 };
5108
+ }
5109
+ }
5110
+ }
5111
+ function partOpacityBypasses(rows, want, got, part) {
5112
+ const [property, name, by, drawnBy] = part;
5113
+ const own = want(property);
5114
+ const whole = want(by);
5115
+ const shown = drawnBy === null ? null : want(drawnBy);
5116
+ const at = (v) => typeof v === "number" ? v : 1;
5117
+ for (let i = 0; i < rows.length; i++) {
5118
+ if (shown !== null && shown[i] === null) {
5119
+ continue;
5120
+ }
5121
+ const [r, o] = [at(own[i]), at(whole[i])];
5122
+ const rewritten = rows[i]?.opacity !== void 0 || rows[i]?.["text-opacity"] !== void 0;
5123
+ if (r === at(got[property]?.[i]) && !rewritten || Number.isNaN(o) || o <= 0 || r > o) {
5124
+ continue;
5125
+ }
5126
+ rows[i] = { ...rows[i], [name]: num6(r / o) };
5127
+ }
5128
+ }
5129
+ function labelSizedBypasses(rows, want, got) {
5130
+ const fit = want("labelFit");
5131
+ for (const p of ["width", "height"]) {
5132
+ const size = want(p);
5133
+ for (let i = 0; i < rows.length; i++) {
5134
+ if (fit[i] === "bounds" && size[i] === 0 && !(got.labelFit?.[i] === "bounds" && got[p]?.[i] === 0)) {
5135
+ rows[i] = { ...rows[i], [p]: "label" };
5136
+ }
5137
+ }
5138
+ }
5139
+ }
3485
5140
  function addBypasses(rows, target, property, want, got) {
3486
5141
  for (let i = 0; i < rows.length; i++) {
3487
5142
  const w = want[i];
@@ -3513,4 +5168,4 @@ export {
3513
5168
  evaluateCytoscapeJs as e,
3514
5169
  toCytoscapeStylesheet as t
3515
5170
  };
3516
- //# sourceMappingURL=emit-CD8xnY8s.js.map
5171
+ //# sourceMappingURL=emit-7Jkpg0yd.js.map