@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.
- package/dist/chunks/{approximations-C2riR4NT.js → approximations-BRXsll0T.js} +2 -2
- package/dist/chunks/{approximations-C2riR4NT.js.map → approximations-BRXsll0T.js.map} +1 -1
- package/dist/chunks/bends-BGXjv_U4.js +129 -0
- package/dist/chunks/bends-BGXjv_U4.js.map +1 -0
- package/dist/chunks/{block-Cu22ewuS.js → block-yl0f_qLO.js} +931 -164
- package/dist/chunks/block-yl0f_qLO.js.map +1 -0
- package/dist/chunks/choose-CczZJaX_.js +717 -0
- package/dist/chunks/choose-CczZJaX_.js.map +1 -0
- package/dist/chunks/{codes-CV_Bhcyi.js → codes-BE2xir2k.js} +6 -2
- package/dist/chunks/codes-BE2xir2k.js.map +1 -0
- package/dist/chunks/{constants-D0LqcsLJ.js → constants-CKkYLPtt.js} +2 -2
- package/dist/chunks/{constants-D0LqcsLJ.js.map → constants-CKkYLPtt.js.map} +1 -1
- package/dist/chunks/{context-cgmmOxZ2.js → context-DizmppHy.js} +5 -4
- package/dist/chunks/{context-cgmmOxZ2.js.map → context-DizmppHy.js.map} +1 -1
- package/dist/chunks/{convert-BcQ8_jMo.js → convert-Ct2zelbQ.js} +7 -2
- package/dist/chunks/convert-Ct2zelbQ.js.map +1 -0
- package/dist/chunks/{credentials-BiQsnMTb.js → credentials-CmvJXYeH.js} +67 -16
- package/dist/chunks/credentials-CmvJXYeH.js.map +1 -0
- package/dist/chunks/{cx-export-BEeF6ymo.js → cx-export-Bt6NoqTQ.js} +3 -3
- package/dist/chunks/{cx-export-BEeF6ymo.js.map → cx-export-Bt6NoqTQ.js.map} +1 -1
- package/dist/chunks/descriptor-B28U25x4.js +60 -0
- package/dist/chunks/descriptor-B28U25x4.js.map +1 -0
- package/dist/chunks/{descriptor-BJ-W0Jd-.js → descriptor-Dhez_Cew.js} +11 -2
- package/dist/chunks/descriptor-Dhez_Cew.js.map +1 -0
- package/dist/chunks/{emit-CD8xnY8s.js → emit-7Jkpg0yd.js} +1788 -133
- package/dist/chunks/emit-7Jkpg0yd.js.map +1 -0
- package/dist/chunks/{escape-DH2Egt-l.js → escape-CuCIzNMB.js} +8 -8
- package/dist/chunks/{escape-DH2Egt-l.js.map → escape-CuCIzNMB.js.map} +1 -1
- package/dist/chunks/{export-CZ7VRm4I.js → export-Cha4dRFz.js} +45 -387
- package/dist/chunks/export-Cha4dRFz.js.map +1 -0
- package/dist/chunks/{exporter-ChjL5fmP.js → exporter-1Ajud15J.js} +9 -8
- package/dist/chunks/{exporter-ChjL5fmP.js.map → exporter-1Ajud15J.js.map} +1 -1
- package/dist/chunks/{exporter-BIdaoIgh.js → exporter-B6yvL3wy.js} +7 -7
- package/dist/chunks/{exporter-BIdaoIgh.js.map → exporter-B6yvL3wy.js.map} +1 -1
- package/dist/chunks/{exporter-Dcw7Ldtq.js → exporter-BP6otMO6.js} +6 -6
- package/dist/chunks/{exporter-Dcw7Ldtq.js.map → exporter-BP6otMO6.js.map} +1 -1
- package/dist/chunks/{exporter-DtVU80Fa.js → exporter-CA5q8ROP.js} +9 -8
- package/dist/chunks/{exporter-DtVU80Fa.js.map → exporter-CA5q8ROP.js.map} +1 -1
- package/dist/chunks/{exporter-bxxjOrDZ.js → exporter-CQQZFJ2v.js} +1284 -156
- package/dist/chunks/exporter-CQQZFJ2v.js.map +1 -0
- package/dist/chunks/format-BXiAb-1h.js +408 -0
- package/dist/chunks/format-BXiAb-1h.js.map +1 -0
- package/dist/chunks/{generic-CP6YD34u.js → generic-Dc21MAdg.js} +387 -31
- package/dist/chunks/generic-Dc21MAdg.js.map +1 -0
- package/dist/chunks/{importer-B87_fmVx.js → importer-C6NVpCXp.js} +327 -84
- package/dist/chunks/importer-C6NVpCXp.js.map +1 -0
- package/dist/chunks/{importer-DPZDN40-.js → importer-CKFe4q54.js} +25 -17
- package/dist/chunks/importer-CKFe4q54.js.map +1 -0
- package/dist/chunks/{importer-Bji2MeWr.js → importer-CKbUbsJA.js} +13 -10
- package/dist/chunks/{importer-Bji2MeWr.js.map → importer-CKbUbsJA.js.map} +1 -1
- package/dist/chunks/{importer-CB_zV5_L.js → importer-ClCsdgTJ.js} +208 -1104
- package/dist/chunks/importer-ClCsdgTJ.js.map +1 -0
- package/dist/chunks/{importer-e3huMZbm.js → importer-CyVZTrf0.js} +14 -10
- package/dist/chunks/importer-CyVZTrf0.js.map +1 -0
- package/dist/chunks/{importer-CVT-JyDE.js → importer-DgG4v1Ms.js} +1537 -355
- package/dist/chunks/importer-DgG4v1Ms.js.map +1 -0
- package/dist/chunks/{importer-Cyy6UseH.js → importer-asFUrIsj.js} +66 -13
- package/dist/chunks/importer-asFUrIsj.js.map +1 -0
- package/dist/chunks/{input-Ccg9I22A.js → input-CAxt_aV-.js} +4 -4
- package/dist/chunks/{input-Ccg9I22A.js.map → input-CAxt_aV-.js.map} +1 -1
- package/dist/chunks/{json-elements-By172SVq.js → json-elements-Cq76WjnZ.js} +4 -4
- package/dist/chunks/{json-elements-By172SVq.js.map → json-elements-Cq76WjnZ.js.map} +1 -1
- package/dist/chunks/{lexicon-u2SI5xcx.js → lexicon-IVRq2Uoo.js} +282 -74
- package/dist/chunks/lexicon-IVRq2Uoo.js.map +1 -0
- package/dist/chunks/{ontology-export-BwgMyuF0.js → ontology-export-OMo91mb0.js} +4 -4
- package/dist/chunks/{ontology-export-BwgMyuF0.js.map → ontology-export-OMo91mb0.js.map} +1 -1
- package/dist/chunks/{records-Cgvxz-Vx.js → records-NJiYvekn.js} +2 -2
- package/dist/chunks/{records-Cgvxz-Vx.js.map → records-NJiYvekn.js.map} +1 -1
- package/dist/chunks/{report-CgdsL9Hb.js → report-CwMfYa9J.js} +23 -23
- package/dist/chunks/{report-CgdsL9Hb.js.map → report-CwMfYa9J.js.map} +1 -1
- package/dist/chunks/round-trip-Cy3_SHRZ.js +79 -0
- package/dist/chunks/round-trip-Cy3_SHRZ.js.map +1 -0
- package/dist/chunks/{sigv4-LkAzsLAu.js → sigv4-BXwVbza3.js} +5 -5
- package/dist/chunks/sigv4-BXwVbza3.js.map +1 -0
- package/dist/chunks/{styles-CaABMoO1.js → styles-CAVmBLgp.js} +1237 -138
- package/dist/chunks/styles-CAVmBLgp.js.map +1 -0
- package/dist/chunks/styles-CPczw1Jz.js +1928 -0
- package/dist/chunks/styles-CPczw1Jz.js.map +1 -0
- package/dist/chunks/styles-boK6Ln54.js +2847 -0
- package/dist/chunks/styles-boK6Ln54.js.map +1 -0
- package/dist/chunks/{styles-yed-Cs1nmrjn.js → styles-yed-XeFBQ6VS.js} +506 -175
- package/dist/chunks/styles-yed-XeFBQ6VS.js.map +1 -0
- package/dist/chunks/{text-BuKQVMz2.js → text-ystE2bYi.js} +2 -2
- package/dist/chunks/{text-BuKQVMz2.js.map → text-ystE2bYi.js.map} +1 -1
- package/dist/csv.js +7 -7
- package/dist/cx.js +2 -2
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +8 -4
- package/dist/dot.js.map +1 -1
- package/dist/gexf.js +42 -12
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +848 -194
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +230 -193
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +3 -3
- package/dist/json.js +3 -2
- package/dist/neo4j.js +6 -6
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/positions.js +45 -3
- package/dist/positions.js.map +1 -1
- package/dist/sources-cypher.js +141 -23
- package/dist/sources-cypher.js.map +1 -1
- package/dist/sources-ndex.js +2 -2
- package/dist/sources-rest.js +32 -6
- package/dist/sources-rest.js.map +1 -1
- package/dist/sources-sparql.d.ts +1 -0
- package/dist/sources-sparql.js +439 -0
- package/dist/sources-sparql.js.map +1 -0
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +5 -1
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx/styles.d.ts +24 -1
- package/dist/src/formats/cx/styles.d.ts.map +1 -1
- package/dist/src/formats/cx/styles.js +117 -11
- package/dist/src/formats/cx/styles.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +1 -0
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cx2/styles.d.ts.map +1 -1
- package/dist/src/formats/cx2/styles.js +3 -1
- package/dist/src/formats/cx2/styles.js.map +1 -1
- package/dist/src/formats/cys/importer.d.ts.map +1 -1
- package/dist/src/formats/cys/importer.js +1 -0
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/styles.d.ts +2 -0
- package/dist/src/formats/cys/styles.d.ts.map +1 -1
- package/dist/src/formats/cys/styles.js +15 -7
- package/dist/src/formats/cys/styles.js.map +1 -1
- package/dist/src/formats/dot/drawing.d.ts +98 -0
- package/dist/src/formats/dot/drawing.d.ts.map +1 -0
- package/dist/src/formats/dot/drawing.js +734 -0
- package/dist/src/formats/dot/drawing.js.map +1 -0
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +34 -2
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts +6 -1
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +170 -33
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/index.d.ts +3 -1
- package/dist/src/formats/dot/index.d.ts.map +1 -1
- package/dist/src/formats/dot/index.js +2 -1
- package/dist/src/formats/dot/index.js.map +1 -1
- package/dist/src/formats/dot/label-places.d.ts +41 -0
- package/dist/src/formats/dot/label-places.d.ts.map +1 -0
- package/dist/src/formats/dot/label-places.js +185 -0
- package/dist/src/formats/dot/label-places.js.map +1 -0
- package/dist/src/formats/dot/names.d.ts +13 -0
- package/dist/src/formats/dot/names.d.ts.map +1 -1
- package/dist/src/formats/dot/names.js +13 -0
- package/dist/src/formats/dot/names.js.map +1 -1
- package/dist/src/formats/dot/record.d.ts +50 -0
- package/dist/src/formats/dot/record.d.ts.map +1 -0
- package/dist/src/formats/dot/record.js +275 -0
- package/dist/src/formats/dot/record.js.map +1 -0
- package/dist/src/formats/dot/styles.d.ts +72 -2
- package/dist/src/formats/dot/styles.d.ts.map +1 -1
- package/dist/src/formats/dot/styles.js +1500 -119
- package/dist/src/formats/dot/styles.js.map +1 -1
- package/dist/src/formats/gexf/dialog-metrics.d.ts +15 -0
- package/dist/src/formats/gexf/dialog-metrics.d.ts.map +1 -0
- package/dist/src/formats/gexf/dialog-metrics.js +59 -0
- package/dist/src/formats/gexf/dialog-metrics.js.map +1 -0
- package/dist/src/formats/gexf/importer.d.ts +7 -0
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +41 -5
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/preview.d.ts +77 -0
- package/dist/src/formats/gexf/preview.d.ts.map +1 -0
- package/dist/src/formats/gexf/preview.js +191 -0
- package/dist/src/formats/gexf/preview.js.map +1 -0
- package/dist/src/formats/gexf/schema.d.ts.map +1 -1
- package/dist/src/formats/gexf/schema.js +2 -1
- package/dist/src/formats/gexf/schema.js.map +1 -1
- package/dist/src/formats/gexf/styles.d.ts +58 -31
- package/dist/src/formats/gexf/styles.d.ts.map +1 -1
- package/dist/src/formats/gexf/styles.js +848 -225
- package/dist/src/formats/gexf/styles.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts +5 -2
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +258 -71
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/index.d.ts +1 -1
- package/dist/src/formats/gml/index.d.ts.map +1 -1
- package/dist/src/formats/gml/index.js +1 -1
- package/dist/src/formats/gml/index.js.map +1 -1
- package/dist/src/formats/gml/positions.d.ts +7 -0
- package/dist/src/formats/gml/positions.d.ts.map +1 -1
- package/dist/src/formats/gml/positions.js +29 -7
- package/dist/src/formats/gml/positions.js.map +1 -1
- package/dist/src/formats/gml/styles.d.ts.map +1 -1
- package/dist/src/formats/gml/styles.js +754 -102
- package/dist/src/formats/gml/styles.js.map +1 -1
- package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-plain.js +6 -10
- package/dist/src/formats/graphml/styles-plain.js.map +1 -1
- package/dist/src/formats/graphml/styles-yed.d.ts +21 -15
- package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-yed.js +695 -164
- package/dist/src/formats/graphml/styles-yed.js.map +1 -1
- package/dist/src/formats/graphml/styles-yfiles3.d.ts +1 -1
- package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-yfiles3.js +431 -64
- package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts +3 -3
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +16 -6
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/dialect.d.ts +3 -2
- package/dist/src/formats/json/dialect.d.ts.map +1 -1
- package/dist/src/formats/json/dialect.js +39 -5
- package/dist/src/formats/json/dialect.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +13 -2
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +42 -6
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/index.d.ts +1 -1
- package/dist/src/formats/json/index.d.ts.map +1 -1
- package/dist/src/formats/json/index.js +1 -1
- package/dist/src/formats/json/index.js.map +1 -1
- package/dist/src/formats/json/positions.d.ts +5 -2
- package/dist/src/formats/json/positions.d.ts.map +1 -1
- package/dist/src/formats/json/positions.js +20 -4
- package/dist/src/formats/json/positions.js.map +1 -1
- package/dist/src/formats/json/styles.d.ts +12 -1
- package/dist/src/formats/json/styles.d.ts.map +1 -1
- package/dist/src/formats/json/styles.js +1843 -136
- package/dist/src/formats/json/styles.js.map +1 -1
- package/dist/src/formats/pajek/draw.d.ts +104 -0
- package/dist/src/formats/pajek/draw.d.ts.map +1 -0
- package/dist/src/formats/pajek/draw.js +382 -0
- package/dist/src/formats/pajek/draw.js.map +1 -0
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +70 -51
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts +9 -0
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +233 -102
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/index.d.ts +1 -0
- package/dist/src/formats/pajek/index.d.ts.map +1 -1
- package/dist/src/formats/pajek/index.js.map +1 -1
- package/dist/src/formats/pajek/styles.d.ts +15 -7
- package/dist/src/formats/pajek/styles.d.ts.map +1 -1
- package/dist/src/formats/pajek/styles.js +1395 -114
- package/dist/src/formats/pajek/styles.js.map +1 -1
- package/dist/src/formats/pajek/syntax.d.ts +10 -1
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +26 -2
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts +1 -0
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +65 -5
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/styles.d.ts +23 -3
- package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
- package/dist/src/formats/xgmml/styles.js +277 -60
- package/dist/src/formats/xgmml/styles.js.map +1 -1
- package/dist/src/index.d.ts +6 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/positions/convert.d.ts.map +1 -1
- package/dist/src/positions/convert.js +11 -1
- package/dist/src/positions/convert.js.map +1 -1
- package/dist/src/positions/extract.d.ts.map +1 -1
- package/dist/src/positions/extract.js +53 -1
- package/dist/src/positions/extract.js.map +1 -1
- package/dist/src/positions/index.d.ts +1 -1
- package/dist/src/positions/index.d.ts.map +1 -1
- package/dist/src/positions/types.d.ts +59 -0
- package/dist/src/positions/types.d.ts.map +1 -1
- package/dist/src/sources/builtins.d.ts +1 -1
- package/dist/src/sources/builtins.d.ts.map +1 -1
- package/dist/src/sources/builtins.js +8 -2
- package/dist/src/sources/builtins.js.map +1 -1
- package/dist/src/sources/context.d.ts.map +1 -1
- package/dist/src/sources/context.js +1 -0
- package/dist/src/sources/context.js.map +1 -1
- package/dist/src/sources/credentials.d.ts +50 -1
- package/dist/src/sources/credentials.d.ts.map +1 -1
- package/dist/src/sources/credentials.js +69 -0
- package/dist/src/sources/credentials.js.map +1 -1
- package/dist/src/sources/cypher/descriptor.d.ts.map +1 -1
- package/dist/src/sources/cypher/descriptor.js +5 -0
- package/dist/src/sources/cypher/descriptor.js.map +1 -1
- package/dist/src/sources/cypher/index.d.ts.map +1 -1
- package/dist/src/sources/cypher/index.js +125 -18
- package/dist/src/sources/cypher/index.js.map +1 -1
- package/dist/src/sources/cypher/params.d.ts +1 -1
- package/dist/src/sources/cypher/params.d.ts.map +1 -1
- package/dist/src/sources/cypher/query-builder.d.ts +17 -0
- package/dist/src/sources/cypher/query-builder.d.ts.map +1 -1
- package/dist/src/sources/cypher/query-builder.js +31 -0
- package/dist/src/sources/cypher/query-builder.js.map +1 -1
- package/dist/src/sources/ids.d.ts +5 -0
- package/dist/src/sources/ids.d.ts.map +1 -1
- package/dist/src/sources/ids.js +5 -0
- package/dist/src/sources/ids.js.map +1 -1
- package/dist/src/sources/params.d.ts +3 -0
- package/dist/src/sources/params.d.ts.map +1 -1
- package/dist/src/sources/rest/descriptor.d.ts.map +1 -1
- package/dist/src/sources/rest/descriptor.js +9 -0
- package/dist/src/sources/rest/descriptor.js.map +1 -1
- package/dist/src/sources/rest/openalex.d.ts +4 -2
- package/dist/src/sources/rest/openalex.d.ts.map +1 -1
- package/dist/src/sources/rest/openalex.js +4 -2
- package/dist/src/sources/rest/openalex.js.map +1 -1
- package/dist/src/sources/rest/source.d.ts.map +1 -1
- package/dist/src/sources/rest/source.js +38 -0
- package/dist/src/sources/rest/source.js.map +1 -1
- package/dist/src/sources/run.d.ts +2 -0
- package/dist/src/sources/run.d.ts.map +1 -1
- package/dist/src/sources/run.js +30 -3
- package/dist/src/sources/run.js.map +1 -1
- package/dist/src/sources/sigv4.d.ts +5 -3
- package/dist/src/sources/sigv4.d.ts.map +1 -1
- package/dist/src/sources/sigv4.js +6 -4
- package/dist/src/sources/sigv4.js.map +1 -1
- package/dist/src/sources/sparql/descriptor.d.ts +10 -0
- package/dist/src/sources/sparql/descriptor.d.ts.map +1 -0
- package/dist/src/sources/sparql/descriptor.js +64 -0
- package/dist/src/sources/sparql/descriptor.js.map +1 -0
- package/dist/src/sources/sparql/index.d.ts +28 -0
- package/dist/src/sources/sparql/index.d.ts.map +1 -0
- package/dist/src/sources/sparql/index.js +327 -0
- package/dist/src/sources/sparql/index.js.map +1 -0
- package/dist/src/sources/sparql/ntriples.d.ts +69 -0
- package/dist/src/sources/sparql/ntriples.d.ts.map +1 -0
- package/dist/src/sources/sparql/ntriples.js +180 -0
- package/dist/src/sources/sparql/ntriples.js.map +1 -0
- package/dist/src/sources/sparql/params.d.ts +27 -0
- package/dist/src/sources/sparql/params.d.ts.map +1 -0
- package/dist/src/sources/sparql/params.js +5 -0
- package/dist/src/sources/sparql/params.js.map +1 -0
- package/dist/src/sources/sparql/query.d.ts +73 -0
- package/dist/src/sources/sparql/query.d.ts.map +1 -0
- package/dist/src/sources/sparql/query.js +164 -0
- package/dist/src/sources/sparql/query.js.map +1 -0
- package/dist/src/sources/types.d.ts +60 -0
- package/dist/src/sources/types.d.ts.map +1 -1
- package/dist/src/styles/annotations.d.ts +61 -5
- package/dist/src/styles/annotations.d.ts.map +1 -1
- package/dist/src/styles/annotations.js +130 -22
- package/dist/src/styles/annotations.js.map +1 -1
- package/dist/src/styles/canon/bends.d.ts +46 -0
- package/dist/src/styles/canon/bends.d.ts.map +1 -1
- package/dist/src/styles/canon/bends.js +123 -0
- package/dist/src/styles/canon/bends.js.map +1 -1
- package/dist/src/styles/canon/color-tables.d.ts +6 -1
- package/dist/src/styles/canon/color-tables.d.ts.map +1 -1
- package/dist/src/styles/canon/color-tables.js +10 -4
- package/dist/src/styles/canon/color-tables.js.map +1 -1
- package/dist/src/styles/canon/color.d.ts +3 -1
- package/dist/src/styles/canon/color.d.ts.map +1 -1
- package/dist/src/styles/canon/color.js +103 -3
- package/dist/src/styles/canon/color.js.map +1 -1
- package/dist/src/styles/canon/enums.d.ts +2 -2
- package/dist/src/styles/canon/enums.d.ts.map +1 -1
- package/dist/src/styles/canon/enums.js +89 -7
- package/dist/src/styles/canon/enums.js.map +1 -1
- package/dist/src/styles/canon/graphviz.d.ts +12 -3
- package/dist/src/styles/canon/graphviz.d.ts.map +1 -1
- package/dist/src/styles/canon/graphviz.js +57 -9
- package/dist/src/styles/canon/graphviz.js.map +1 -1
- package/dist/src/styles/canon/number.d.ts +8 -0
- package/dist/src/styles/canon/number.d.ts.map +1 -1
- package/dist/src/styles/canon/number.js +18 -0
- package/dist/src/styles/canon/number.js.map +1 -1
- package/dist/src/styles/canon/text.d.ts +29 -2
- package/dist/src/styles/canon/text.d.ts.map +1 -1
- package/dist/src/styles/canon/text.js +156 -16
- package/dist/src/styles/canon/text.js.map +1 -1
- package/dist/src/styles/codes.d.ts +2 -0
- package/dist/src/styles/codes.d.ts.map +1 -1
- package/dist/src/styles/codes.js +2 -0
- package/dist/src/styles/codes.js.map +1 -1
- package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
- package/dist/src/styles/cyjs/cascade.js +1139 -79
- package/dist/src/styles/cyjs/cascade.js.map +1 -1
- package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
- package/dist/src/styles/cyjs/defaults-table.js +4 -0
- package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
- package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
- package/dist/src/styles/cyjs/emit.js +232 -10
- package/dist/src/styles/cyjs/emit.js.map +1 -1
- package/dist/src/styles/cyjs/face.d.ts +20 -0
- package/dist/src/styles/cyjs/face.d.ts.map +1 -0
- package/dist/src/styles/cyjs/face.js +332 -0
- package/dist/src/styles/cyjs/face.js.map +1 -0
- package/dist/src/styles/cyjs/mappers.d.ts +44 -1
- package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
- package/dist/src/styles/cyjs/mappers.js +475 -26
- package/dist/src/styles/cyjs/mappers.js.map +1 -1
- package/dist/src/styles/cyjs/routes.d.ts +53 -0
- package/dist/src/styles/cyjs/routes.d.ts.map +1 -0
- package/dist/src/styles/cyjs/routes.js +360 -0
- package/dist/src/styles/cyjs/routes.js.map +1 -0
- package/dist/src/styles/cytoscape/charts.d.ts +23 -0
- package/dist/src/styles/cytoscape/charts.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/charts.js +560 -0
- package/dist/src/styles/cytoscape/charts.js.map +1 -0
- package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/emit.js +156 -48
- package/dist/src/styles/cytoscape/emit.js.map +1 -1
- package/dist/src/styles/cytoscape/lexicon.d.ts +91 -3
- package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/lexicon.js +387 -77
- package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
- package/dist/src/styles/cytoscape/mappings.d.ts +30 -0
- package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/mappings.js +92 -0
- package/dist/src/styles/cytoscape/mappings.js.map +1 -1
- package/dist/src/styles/cytoscape/resolve.d.ts +42 -2
- package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/resolve.js +623 -17
- package/dist/src/styles/cytoscape/resolve.js.map +1 -1
- package/dist/src/styles/defaults.d.ts +46 -26
- package/dist/src/styles/defaults.d.ts.map +1 -1
- package/dist/src/styles/defaults.js +308 -71
- package/dist/src/styles/defaults.js.map +1 -1
- package/dist/src/styles/index.d.ts +4 -3
- package/dist/src/styles/index.d.ts.map +1 -1
- package/dist/src/styles/index.js +3 -2
- package/dist/src/styles/index.js.map +1 -1
- package/dist/src/styles/internal.d.ts +1 -0
- package/dist/src/styles/internal.d.ts.map +1 -1
- package/dist/src/styles/internal.js +1 -0
- package/dist/src/styles/internal.js.map +1 -1
- package/dist/src/styles/io/generic.d.ts.map +1 -1
- package/dist/src/styles/io/generic.js +56 -16
- package/dist/src/styles/io/generic.js.map +1 -1
- package/dist/src/styles/io/round-trip.d.ts +56 -0
- package/dist/src/styles/io/round-trip.d.ts.map +1 -0
- package/dist/src/styles/io/round-trip.js +138 -0
- package/dist/src/styles/io/round-trip.js.map +1 -0
- package/dist/src/styles/io/writer.d.ts.map +1 -1
- package/dist/src/styles/io/writer.js +6 -1
- package/dist/src/styles/io/writer.js.map +1 -1
- package/dist/src/styles/notes.d.ts.map +1 -1
- package/dist/src/styles/notes.js +1 -0
- package/dist/src/styles/notes.js.map +1 -1
- package/dist/src/styles/plan/features.d.ts +1 -1
- package/dist/src/styles/plan/features.d.ts.map +1 -1
- package/dist/src/styles/plan/features.js +22 -2
- package/dist/src/styles/plan/features.js.map +1 -1
- package/dist/src/styles/plan/index.d.ts +1 -1
- package/dist/src/styles/plan/index.d.ts.map +1 -1
- package/dist/src/styles/plan/index.js +1 -1
- package/dist/src/styles/plan/index.js.map +1 -1
- package/dist/src/styles/plan/plan.d.ts.map +1 -1
- package/dist/src/styles/plan/plan.js +61 -4
- package/dist/src/styles/plan/plan.js.map +1 -1
- package/dist/src/styles/plan/resolve.d.ts +11 -0
- package/dist/src/styles/plan/resolve.d.ts.map +1 -1
- package/dist/src/styles/plan/resolve.js +40 -4
- package/dist/src/styles/plan/resolve.js.map +1 -1
- package/dist/src/styles/slots.d.ts +14 -0
- package/dist/src/styles/slots.d.ts.map +1 -0
- package/dist/src/styles/slots.js +20 -0
- package/dist/src/styles/slots.js.map +1 -0
- package/dist/src/styles/types.d.ts +687 -6
- package/dist/src/styles/types.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.d.ts +3 -2
- package/dist/src/styles/vocabulary.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.js +224 -0
- package/dist/src/styles/vocabulary.js.map +1 -1
- package/dist/styles.js +30 -239
- package/dist/styles.js.map +1 -1
- package/dist/xgmml.js +3 -3
- package/package.json +27 -7
- package/src/formats/cx/importer.ts +6 -1
- package/src/formats/cx/styles.ts +143 -9
- package/src/formats/cx2/importer.ts +1 -0
- package/src/formats/cx2/styles.ts +3 -1
- package/src/formats/cys/importer.ts +1 -0
- package/src/formats/cys/styles.ts +27 -5
- package/src/formats/dot/drawing.ts +799 -0
- package/src/formats/dot/exporter.ts +37 -1
- package/src/formats/dot/importer.ts +192 -36
- package/src/formats/dot/index.ts +3 -1
- package/src/formats/dot/label-places.ts +241 -0
- package/src/formats/dot/names.ts +15 -0
- package/src/formats/dot/record.ts +336 -0
- package/src/formats/dot/styles.ts +1702 -149
- package/src/formats/gexf/dialog-metrics.ts +61 -0
- package/src/formats/gexf/importer.ts +50 -5
- package/src/formats/gexf/preview.ts +217 -0
- package/src/formats/gexf/schema.ts +2 -1
- package/src/formats/gexf/styles.ts +1099 -245
- package/src/formats/gml/importer.ts +291 -76
- package/src/formats/gml/index.ts +1 -1
- package/src/formats/gml/positions.ts +29 -7
- package/src/formats/gml/styles.ts +852 -110
- package/src/formats/graphml/styles-plain.ts +6 -15
- package/src/formats/graphml/styles-yed.ts +765 -176
- package/src/formats/graphml/styles-yfiles3.ts +487 -63
- package/src/formats/graphml/yfiles.ts +19 -6
- package/src/formats/json/dialect.ts +41 -5
- package/src/formats/json/importer.ts +59 -7
- package/src/formats/json/index.ts +1 -0
- package/src/formats/json/positions.ts +22 -5
- package/src/formats/json/styles.ts +2123 -171
- package/src/formats/pajek/draw.ts +469 -0
- package/src/formats/pajek/exporter.ts +81 -49
- package/src/formats/pajek/importer.ts +278 -103
- package/src/formats/pajek/index.ts +1 -0
- package/src/formats/pajek/styles.ts +1506 -133
- package/src/formats/pajek/syntax.ts +27 -2
- package/src/formats/xgmml/emit.ts +73 -5
- package/src/formats/xgmml/styles.ts +330 -71
- package/src/index.ts +12 -1
- package/src/positions/convert.ts +12 -1
- package/src/positions/extract.ts +55 -1
- package/src/positions/index.ts +1 -0
- package/src/positions/types.ts +60 -0
- package/src/sources/builtins.ts +8 -1
- package/src/sources/context.ts +1 -0
- package/src/sources/credentials.ts +90 -1
- package/src/sources/cypher/descriptor.ts +7 -1
- package/src/sources/cypher/index.ts +149 -18
- package/src/sources/cypher/params.ts +1 -1
- package/src/sources/cypher/query-builder.ts +33 -0
- package/src/sources/ids.ts +6 -0
- package/src/sources/params.ts +3 -0
- package/src/sources/rest/descriptor.ts +9 -0
- package/src/sources/rest/openalex.ts +4 -2
- package/src/sources/rest/source.ts +41 -0
- package/src/sources/run.ts +35 -3
- package/src/sources/sigv4.ts +6 -4
- package/src/sources/sparql/descriptor.ts +67 -0
- package/src/sources/sparql/index.ts +371 -0
- package/src/sources/sparql/ntriples.ts +219 -0
- package/src/sources/sparql/params.ts +28 -0
- package/src/sources/sparql/query.ts +216 -0
- package/src/sources/types.ts +68 -0
- package/src/styles/annotations.ts +201 -27
- package/src/styles/canon/bends.ts +137 -0
- package/src/styles/canon/color-tables.ts +10 -4
- package/src/styles/canon/color.ts +105 -3
- package/src/styles/canon/enums.ts +107 -8
- package/src/styles/canon/graphviz.ts +71 -10
- package/src/styles/canon/number.ts +19 -0
- package/src/styles/canon/text.ts +187 -16
- package/src/styles/codes.ts +2 -0
- package/src/styles/cyjs/cascade.ts +1303 -84
- package/src/styles/cyjs/defaults-table.ts +4 -0
- package/src/styles/cyjs/emit.ts +268 -14
- package/src/styles/cyjs/face.ts +372 -0
- package/src/styles/cyjs/mappers.ts +506 -27
- package/src/styles/cyjs/routes.ts +432 -0
- package/src/styles/cytoscape/charts.ts +684 -0
- package/src/styles/cytoscape/emit.ts +170 -48
- package/src/styles/cytoscape/lexicon.ts +431 -78
- package/src/styles/cytoscape/mappings.ts +108 -0
- package/src/styles/cytoscape/resolve.ts +741 -17
- package/src/styles/defaults.ts +417 -108
- package/src/styles/index.ts +5 -0
- package/src/styles/internal.ts +1 -0
- package/src/styles/io/generic.ts +79 -23
- package/src/styles/io/round-trip.ts +202 -0
- package/src/styles/io/writer.ts +6 -1
- package/src/styles/notes.ts +1 -0
- package/src/styles/plan/features.ts +23 -2
- package/src/styles/plan/index.ts +1 -1
- package/src/styles/plan/plan.ts +69 -5
- package/src/styles/plan/resolve.ts +47 -4
- package/src/styles/slots.ts +25 -0
- package/src/styles/types.ts +698 -5
- package/src/styles/vocabulary.ts +232 -2
- package/dist/chunks/block-Cu22ewuS.js.map +0 -1
- package/dist/chunks/choose-Cdx6Enl2.js +0 -57
- package/dist/chunks/choose-Cdx6Enl2.js.map +0 -1
- package/dist/chunks/codes-CV_Bhcyi.js.map +0 -1
- package/dist/chunks/convert-BcQ8_jMo.js.map +0 -1
- package/dist/chunks/credentials-BiQsnMTb.js.map +0 -1
- package/dist/chunks/descriptor-BJ-W0Jd-.js.map +0 -1
- package/dist/chunks/emit-CD8xnY8s.js.map +0 -1
- package/dist/chunks/export-CZ7VRm4I.js.map +0 -1
- package/dist/chunks/exporter-bxxjOrDZ.js.map +0 -1
- package/dist/chunks/format-BMS-1Nxb.js +0 -64
- package/dist/chunks/format-BMS-1Nxb.js.map +0 -1
- package/dist/chunks/generic-CP6YD34u.js.map +0 -1
- package/dist/chunks/importer-B87_fmVx.js.map +0 -1
- package/dist/chunks/importer-CB_zV5_L.js.map +0 -1
- package/dist/chunks/importer-CVT-JyDE.js.map +0 -1
- package/dist/chunks/importer-Cyy6UseH.js.map +0 -1
- package/dist/chunks/importer-DPZDN40-.js.map +0 -1
- package/dist/chunks/importer-e3huMZbm.js.map +0 -1
- package/dist/chunks/lexicon-u2SI5xcx.js.map +0 -1
- package/dist/chunks/sigv4-LkAzsLAu.js.map +0 -1
- package/dist/chunks/styles-CaABMoO1.js.map +0 -1
- package/dist/chunks/styles-P_gmFAOi.js +0 -770
- package/dist/chunks/styles-P_gmFAOi.js.map +0 -1
- package/dist/chunks/styles-yed-Cs1nmrjn.js.map +0 -1
- package/dist/chunks/writer-DvHTl36J.js +0 -449
- package/dist/chunks/writer-DvHTl36J.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles-CAVmBLgp.js","sources":["../../src/styles/cytoscape/mappings.ts","../../src/styles/cytoscape/emit.ts","../../src/styles/cytoscape/charts.ts","../../src/styles/cytoscape/resolve.ts","../../src/styles/cytoscape/translate.ts","../../src/formats/xgmml/constants.ts","../../src/formats/xgmml/styles.ts","../../src/formats/cx/styles.ts"],"sourcesContent":["/**\n * Cytoscape desktop's visual style model: per target the defaults, the one mapping per visual property and the\n * dependencies, read from CX version 1 (`cyVisualProperties`, mapping definitions as `COL=...,K=0=a` strings) and CX2\n * (`visualProperties`, `visualEditorProperties`). Every table keyed by file text is a `Map`.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport type { StyleNotes } from \"../notes.js\";\nimport type { StyleTarget } from \"../types.js\";\n\n/**\n * One Cytoscape mapping, with the file's raw values (they are read per property when resolved or translated). A\n * discrete table's keys are typed by the attribute's type (numbers for `integer`, `long` and `double`, booleans for\n * `boolean`), so a key compares with a value the way Cytoscape compares them.\n * @category Styles\n */\nexport type CytoscapeMapping =\n | {\n /** The column's value is the visual property's value. */\n readonly kind: \"passthrough\";\n /** The column read. */\n readonly column: string;\n /** The attribute type the file states, or null. */\n readonly type: string | null;\n }\n | {\n /** A table from the column's value to a raw visual property value. */\n readonly kind: \"discrete\";\n /** The column read. */\n readonly column: string;\n /** The attribute type the file states, or null. */\n readonly type: string | null;\n /** `[key, raw value]` in the file's order. */\n readonly table: readonly (readonly [key: string | number | boolean, value: unknown])[];\n }\n | {\n /** Points between which Cytoscape interpolates. */\n readonly kind: \"continuous\";\n /** The column read. */\n readonly column: string;\n /** The attribute type the file states, or null. */\n readonly type: string | null;\n /** The points, in the file's order, with raw values. */\n readonly points: readonly CytoscapeContinuousPoint[];\n };\n\n/**\n * One point of a Cytoscape continuous mapping, with raw values: `below` just below `at`, `value` exactly at it,\n * `above` just above it.\n * @category Styles\n */\nexport interface CytoscapeContinuousPoint {\n /** The attribute value. */\n readonly at: number;\n /** The raw value just below `at`. */\n readonly below: unknown;\n /** The raw value exactly at `at`. */\n readonly value: unknown;\n /** The raw value just above `at`. */\n readonly above: unknown;\n}\n\n/**\n * The style of one target: defaults and mappings by visual property name, and the dependencies\n * (`nodeSizeLocked`, `arrowColorMatchesEdge`).\n * @category Styles\n */\nexport interface CytoscapeTargetStyle {\n /** Visual property name to raw default value. */\n readonly defaults: Map<string, unknown>;\n /** Visual property name to its mapping. */\n readonly mappings: Map<string, CytoscapeMapping>;\n /** Dependency name to whether it is on. */\n readonly dependencies: Map<string, boolean>;\n /**\n * Bypass names read as another visual property when the element has none of that one (CX2's `NODE_WIDTH` bypass\n * drives a locked node size).\n */\n readonly bypassAliases: Map<string, string>;\n}\n\n/**\n * A Cytoscape visual style: the network defaults and the style of nodes and edges.\n * @category Styles\n */\nexport interface CytoscapeStyle {\n /** The network's defaults (`NETWORK_BACKGROUND_PAINT`). */\n readonly network: {\n /** The network's default values by visual property name. */\n readonly defaults: Map<string, unknown>;\n };\n /** Node style. */\n readonly node: CytoscapeTargetStyle;\n /** Edge style. */\n readonly edge: CytoscapeTargetStyle;\n}\n\n/**\n * An empty style.\n * @returns a style with no defaults, mappings or dependencies\n * @category Styles\n */\nexport function emptyCytoscapeStyle(): CytoscapeStyle {\n const target = (): CytoscapeTargetStyle => ({\n defaults: new Map(),\n mappings: new Map(),\n dependencies: new Map(),\n bypassAliases: new Map(),\n });\n return { network: { defaults: new Map() }, node: target(), edge: target() };\n}\n\n/** Cytoscape's network-collection columns and the plain columns it fills them from when a file holds only those. */\nconst SHARED_COLUMNS: ReadonlyMap<string, string> = new Map([\n [\"shared name\", \"name\"],\n [\"shared interaction\", \"interaction\"],\n]);\n\n/**\n * Points every mapping over `shared name` or `shared interaction` at `name` or `interaction` when the file holds only\n * the plain column: Cytoscape fills the shared column from it on import, so the mapping reads the same values.\n * @param style - the target's style, changed in place\n * @param has - whether the file holds a column\n * @category Styles\n */\nexport function sharedColumnFallback(style: CytoscapeTargetStyle, has: (column: string) => boolean): void {\n for (const [vp, m] of style.mappings) {\n const plain = SHARED_COLUMNS.get(m.column);\n if (plain !== undefined && !has(m.column) && has(plain)) {\n style.mappings.set(vp, { ...m, column: plain });\n }\n }\n}\n\n/**\n * Points every mapping over the attribute an import read as the edge weight at the column it is kept in\n * (`graphty.weight`, which `snapshot.edges.byRole(\"weight\")` finds): the importer takes that attribute out of the\n * plain columns, while Cytoscape keeps it as an ordinary column its mappings read.\n * @param style - the edge style, changed in place\n * @param weightFrom - the attribute read as the weight, or null when none was\n * @param table - the edge table\n * @category Styles\n */\nexport function weightColumnFallback(\n style: CytoscapeTargetStyle,\n weightFrom: string | null,\n table: GraphSnapshot[\"edges\"],\n): void {\n const kept = weightFrom === null || table.has(weightFrom) ? undefined : table.byRole(\"weight\")?.meta.name;\n if (kept === undefined) {\n return;\n }\n for (const [vp, m] of style.mappings) {\n if (m.column === weightFrom) {\n style.mappings.set(vp, { ...m, column: kept });\n }\n }\n}\n\n/**\n * Whether a numeric type name is integral (`integer`, `long`), floating (`double`, `real`) or neither.\n * @param type - the type name as a file gives it\n * @returns the family, or null\n */\nfunction numericFamily(type: string | null): \"integral\" | \"floating\" | null {\n const t = (type ?? \"\")\n .toLowerCase()\n .replace(/^list_of_/, \"\")\n .replace(/^java\\.lang\\./, \"\");\n if (t === \"integer\" || t === \"long\" || t === \"int\" || t === \"short\") {\n return \"integral\";\n }\n if (t === \"double\" || t === \"float\" || t === \"real\") {\n return \"floating\";\n }\n return null;\n}\n\n/**\n * Empties every discrete mapping whose keys are typed integral (`integer`, `long`) over a floating (`double`)\n * column, or the other way round. Cytoscape compares a Java Integer key with a Double value, which never match, so\n * the mapping sets nothing and the default shows (`4.0` does not match key `4`). Noted as `W_STYLE_BAD_MAPPING`.\n * @param style - the target's style, changed in place\n * @param typeOf - a column's declared type, or null when unknown\n * @param notes - where problems are noted\n * @param target - nodes or edges, for notes\n * @category Styles\n */\nexport function dropMismatchedKeys(\n style: CytoscapeTargetStyle,\n typeOf: (column: string) => string | null,\n notes: StyleNotes,\n target: StyleTarget,\n): void {\n for (const [vp, m] of style.mappings) {\n if (m.kind !== \"discrete\" || m.table.length === 0) {\n continue;\n }\n const key = numericFamily(m.type);\n const column = numericFamily(typeOf(m.column));\n if (key !== null && column !== null && key !== column) {\n style.mappings.set(vp, { ...m, table: [] });\n notes.add(STYLE_ISSUE.BAD_MAPPING, target, m.column, {\n sample: `${vp}: ${key} keys on a ${column} column`,\n });\n }\n }\n}\n\nconst NUMERIC_TYPES: ReadonlySet<string> = new Set([\"integer\", \"long\", \"double\", \"float\", \"int\", \"short\"]);\nconst DECIMAL = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/;\n\n/**\n * A discrete key typed by its attribute's type: a number for a numeric type, a boolean for `boolean`, else the key\n * as the file gives it. A list type (`list_of_integer`) types its items.\n * @param raw - the key as the file gives it\n * @param type - the attribute type, or null\n * @returns the typed key, or null when it is not a scalar\n * @category Styles\n */\nexport function typedKey(raw: unknown, type: string | null): string | number | boolean | null {\n if (typeof raw === \"number\") {\n return Number.isFinite(raw) ? raw : null;\n }\n if (typeof raw === \"boolean\") {\n return raw;\n }\n if (typeof raw !== \"string\") {\n return null;\n }\n const t = (type ?? \"\")\n .toLowerCase()\n .replace(/^list_of_/, \"\")\n .replace(/^java\\.lang\\./, \"\");\n if (NUMERIC_TYPES.has(t) && raw.length <= 64 && DECIMAL.test(raw.trim())) {\n return Number(raw.trim());\n }\n if (t === \"boolean\") {\n const b = raw.trim().toLowerCase();\n if (b === \"true\" || b === \"false\") {\n return b === \"true\";\n }\n }\n return raw;\n}\n\n/**\n * The tags of a CX version 1 mapping definition that are indexed.\n * @category Styles\n */\nexport type Cx1IndexedTag = \"K\" | \"V\" | \"L\" | \"E\" | \"G\" | \"OV\";\nconst INDEXED: ReadonlySet<string> = new Set<Cx1IndexedTag>([\"K\", \"V\", \"L\", \"E\", \"G\", \"OV\"]);\n\n/**\n * A parsed CX version 1 mapping definition.\n * @category Styles\n */\nexport interface Cx1Definition {\n /** The column (`COL=`), or null. */\n readonly column: string | null;\n /** The attribute type (`T=`), or null. */\n readonly type: string | null;\n /** Each indexed tag's entries by index: `K` keys, `V` values, `L`/`E`/`G` below/at/above, `OV` points. */\n readonly entries: ReadonlyMap<Cx1IndexedTag, ReadonlyMap<number, string>>;\n}\n\n/**\n * Splits a definition at single commas; `,,` is a literal comma.\n * @param def - the definition\n * @returns the tokens\n */\nfunction definitionTokens(def: string): string[] {\n const tokens: string[] = [];\n let parts: string[] = [];\n let start = 0;\n let i = def.indexOf(\",\");\n while (i >= 0) {\n parts.push(def.slice(start, i));\n if (def[i + 1] === \",\") {\n parts.push(\",\");\n i++;\n } else {\n tokens.push(parts.join(\"\"));\n parts = [];\n }\n start = i + 1;\n i = def.indexOf(\",\", start);\n }\n parts.push(def.slice(start));\n tokens.push(parts.join(\"\"));\n return tokens;\n}\n\n/**\n * One indexed entry of a definition: `TAG=index=value`.\n * @param t - the token\n * @returns the tag, the index and the value, or null when the token is no indexed entry\n */\nfunction indexedEntry(t: string): { tag: string; index: number; value: string } | null {\n const eq1 = t.indexOf(\"=\");\n const eq2 = eq1 < 0 ? -1 : t.indexOf(\"=\", eq1 + 1);\n const tag = t.slice(0, eq1);\n if (eq2 < 0 || !INDEXED.has(tag)) {\n return null;\n }\n const indexText = t.slice(eq1 + 1, eq2);\n return /^\\d{1,15}$/.test(indexText) ? { tag, index: Number(indexText), value: t.slice(eq2 + 1) } : null;\n}\n\n/**\n * Reads a CX version 1 mapping definition: `COL=a,T=string,K=0=x,V=0=y,...`, with `,,` a literal comma. Indexes are\n * collected into Maps and never used as array positions (`K=4294967294=a` is one entry, not four billion holes); an\n * index larger than the number of tokens is ignored and noted as `W_STYLE_BAD_MAPPING`.\n * @param def - the definition string\n * @param notes - where problems are noted\n * @param target - nodes or edges, for the note\n * @returns the definition\n * @category Styles\n */\nexport function parseCx1Definition(def: string, notes?: StyleNotes, target: StyleTarget | null = null): Cx1Definition {\n const tokens = definitionTokens(def);\n const entries = new Map<Cx1IndexedTag, Map<number, string>>();\n let column: string | null = null;\n let type: string | null = null;\n let beyond = 0;\n for (const t of tokens) {\n if (t.startsWith(\"COL=\")) {\n column = t.slice(4);\n continue;\n }\n if (t.startsWith(\"T=\")) {\n type = t.slice(2);\n continue;\n }\n const indexed = indexedEntry(t);\n if (indexed === null) {\n continue;\n }\n const { tag, index, value } = indexed;\n if (index > tokens.length) {\n beyond++;\n continue;\n }\n let byIndex = entries.get(tag as Cx1IndexedTag);\n if (byIndex === undefined) {\n byIndex = new Map();\n entries.set(tag as Cx1IndexedTag, byIndex);\n }\n byIndex.set(index, value);\n }\n if (beyond > 0) {\n notes?.add(STYLE_ISSUE.BAD_MAPPING, target, column ?? \"definition\", {\n sample: `${beyond} entries with an index beyond the definition`,\n count: beyond,\n });\n }\n return { column, type, entries };\n}\n\n/**\n * The indexes of a tag's entries, ascending.\n * @param d - the definition\n * @param tag - the tag\n * @returns the indexes\n */\nfunction indexesOf(d: Cx1Definition, tag: Cx1IndexedTag): number[] {\n return Array.from(d.entries.get(tag)?.keys() ?? []).sort((a, b) => a - b);\n}\n\n/**\n * A finite number from a number or decimal text.\n * @param v - the value\n * @returns the number, or null\n */\nfunction finiteOf(v: unknown): number | null {\n if (typeof v === \"number\") {\n return Number.isFinite(v) ? v : null;\n }\n if (typeof v === \"string\" && v.length <= 64 && DECIMAL.test(v.trim())) {\n return Number(v.trim());\n }\n return null;\n}\n\n/**\n * A CX version 1 mapping (`{ type: \"DISCRETE\", definition: \"COL=...\" }`) as a Cytoscape mapping.\n * @param m - the mapping object\n * @param notes - where problems are noted\n * @param target - nodes or edges, for notes\n * @returns the mapping, or null when it cannot be read\n * @category Styles\n */\nexport function mappingFromCx1(\n m: unknown,\n notes?: StyleNotes,\n target: StyleTarget | null = null,\n): CytoscapeMapping | null {\n if (m === null || typeof m !== \"object\" || typeof (m as { definition?: unknown }).definition !== \"string\") {\n return null;\n }\n const { type: kind, definition } = m as { type?: unknown; definition: string };\n const d = parseCx1Definition(definition, notes, target);\n if (d.column === null) {\n return null;\n }\n const at = (tag: Cx1IndexedTag, i: number): string | undefined => d.entries.get(tag)?.get(i);\n switch (String(kind).toUpperCase()) {\n case \"PASSTHROUGH\":\n return { kind: \"passthrough\", column: d.column, type: d.type };\n case \"DISCRETE\": {\n const table: [string | number | boolean, unknown][] = [];\n for (const i of indexesOf(d, \"K\")) {\n const key = typedKey(at(\"K\", i), d.type);\n const value = at(\"V\", i);\n if (key !== null && value !== undefined) {\n table.push([key, value]);\n }\n }\n return { kind: \"discrete\", column: d.column, type: d.type, table };\n }\n case \"CONTINUOUS\": {\n const points: CytoscapeContinuousPoint[] = [];\n for (const i of indexesOf(d, \"OV\")) {\n const x = finiteOf(at(\"OV\", i));\n if (x !== null) {\n points.push({ at: x, below: at(\"L\", i), value: at(\"E\", i), above: at(\"G\", i) });\n }\n }\n return { kind: \"continuous\", column: d.column, type: d.type, points };\n }\n default:\n return null;\n }\n}\n\n/**\n * A property of an object, read only when it is the object's own.\n * @param o - the object\n * @param k - the key\n * @returns the value, or undefined\n */\nfunction own(o: unknown, k: string): unknown {\n return o !== null && typeof o === \"object\" && Object.hasOwn(o, k) ? (o as Record<string, unknown>)[k] : undefined;\n}\n\n/** A continuous point being assembled from CX2 intervals. */\ninterface PointDraft {\n at: number;\n below?: unknown;\n value?: unknown;\n above?: unknown;\n}\n\n/**\n * A CX2 mapping (`{ type, definition: { attribute, map } }`) as a Cytoscape mapping. Continuous intervals\n * (`{ min, max, includeMin, includeMax, minVPValue, maxVPValue }`) become points: an interval's `minVPValue` is the\n * value just above its `min` (and at it when `includeMin`), its `maxVPValue` the value just below its `max` (and at\n * it when `includeMax` and the next interval does not include its `min`).\n * @param m - the mapping object\n * @returns the mapping, or null when it cannot be read\n * @category Styles\n */\nexport function mappingFromCx2(m: unknown): CytoscapeMapping | null {\n const def = own(m, \"definition\");\n const column = own(def, \"attribute\");\n if (typeof column !== \"string\") {\n return null;\n }\n const declared = own(def, \"type\");\n const type = typeof declared === \"string\" ? declared : null;\n const map = own(def, \"map\");\n const entries = Array.isArray(map) ? (map as unknown[]) : [];\n switch (String(own(m, \"type\")).toUpperCase()) {\n case \"PASSTHROUGH\":\n return { kind: \"passthrough\", column, type };\n case \"DISCRETE\": {\n const table: [string | number | boolean, unknown][] = [];\n for (const e of entries) {\n const key = typedKey(own(e, \"v\"), type);\n const value = own(e, \"vp\");\n if (key !== null && value !== undefined) {\n table.push([key, value]);\n }\n }\n return { kind: \"discrete\", column, type, table };\n }\n case \"CONTINUOUS\":\n return { kind: \"continuous\", column, type, points: cx2Points(entries) };\n default:\n return null;\n }\n}\n\n/**\n * The points of CX2's continuous intervals.\n * @param entries - the intervals\n * @returns the points, ascending\n */\nfunction cx2Points(entries: readonly unknown[]): CytoscapeContinuousPoint[] {\n const byAt = new Map<number, PointDraft>();\n const point = (x: number): PointDraft => {\n let p = byAt.get(x);\n if (p === undefined) {\n p = { at: x };\n byAt.set(x, p);\n }\n return p;\n };\n for (const iv of entries) {\n if (iv !== null && typeof iv === \"object\") {\n addInterval(iv, point);\n }\n }\n return Array.from(byAt.values())\n .sort((a, b) => a.at - b.at)\n .map((p): CytoscapeContinuousPoint => {\n const below = p.below ?? p.value ?? p.above;\n const above = p.above ?? p.value ?? below;\n return { at: p.at, below, value: p.value ?? below, above };\n });\n}\n\n/**\n * One CX2 interval into its points: its `minVPValue` is the value just above its `min` (and at it when\n * `includeMin`), its `maxVPValue` the value just below its `max` (and at it when `includeMax` and the next interval\n * does not include its `min`).\n * @param iv - the interval\n * @param point - the point at a position, made on first use\n */\nfunction addInterval(iv: object, point: (x: number) => PointDraft): void {\n const lo = finiteOf(own(iv, \"min\"));\n const hi = finiteOf(own(iv, \"max\"));\n const minValue = own(iv, \"minVPValue\") ?? own(iv, \"maxVPValue\");\n const maxValue = own(iv, \"maxVPValue\") ?? own(iv, \"minVPValue\");\n if (lo !== null) {\n const p = point(lo);\n p.above = minValue;\n if (own(iv, \"includeMin\") !== false) {\n p.value = minValue;\n }\n }\n if (hi !== null) {\n const p = point(hi);\n p.below = maxValue;\n if (own(iv, \"includeMax\") !== false && p.value === undefined) {\n p.value = maxValue;\n }\n }\n}\n\n/**\n * The element's own record of values, or an empty one.\n * @param x - the value\n * @returns the record\n */\nfunction record(x: unknown): Record<string, unknown> {\n return x !== null && typeof x === \"object\" && !Array.isArray(x) ? (x as Record<string, unknown>) : {};\n}\n\n/**\n * The style of a CX version 1 file from its `cyVisualProperties` aspect: the first view's `network`,\n * `nodes:default` and `edges:default` entries (defaults, mappings, dependencies). Other views are skipped with one\n * `W_STYLE_OTHER_VIEWS` note; a mapping that cannot be read is noted as `W_STYLE_BAD_MAPPING`.\n * @param entries - the aspect's entries\n * @param notes - where problems are noted\n * @returns the style\n * @category Styles\n */\nexport function cytoscapeStyleFromCx(entries: readonly unknown[], notes?: StyleNotes): CytoscapeStyle {\n const style = emptyCytoscapeStyle();\n const viewOf = (v: unknown): unknown => own(v, \"applies_to\") ?? own(v, \"view\") ?? null;\n const views: unknown[] = [];\n for (const v of entries) {\n if (/default|network/.test(String(own(v, \"properties_of\"))) && !views.includes(viewOf(v))) {\n views.push(viewOf(v));\n }\n }\n if (views.length > 1) {\n notes?.add(STYLE_ISSUE.OTHER_VIEWS, null, \"cyVisualProperties\", {\n sample: `${views.length - 1} more`,\n count: views.length - 1,\n });\n }\n for (const v of entries) {\n const target =\n v !== null && typeof v === \"object\" && viewOf(v) === views[0]\n ? CX_SECTIONS.get(String(own(v, \"properties_of\")))\n : undefined;\n if (target === undefined) {\n continue;\n }\n const props = record(own(v, \"properties\"));\n for (const k of Object.keys(props)) {\n style[target].defaults.set(k, props[k]);\n }\n if (target !== \"network\") {\n readCxMappings(style, target, v, notes);\n }\n }\n return style;\n}\n\n/** The style section each `properties_of` of a CX `cyVisualProperties` entry fills. */\nconst CX_SECTIONS: ReadonlyMap<string, StyleTarget | \"network\"> = new Map([\n [\"nodes:default\", \"node\"],\n [\"edges:default\", \"edge\"],\n [\"network\", \"network\"],\n]);\n\n/**\n * The mappings and dependencies of a CX `nodes:default` or `edges:default` entry, into the style.\n * @param style - the style, changed in place\n * @param target - nodes or edges\n * @param v - the entry\n * @param notes - where a mapping that cannot be read is noted\n */\nfunction readCxMappings(style: CytoscapeStyle, target: StyleTarget, v: unknown, notes: StyleNotes | undefined): void {\n const mappings = record(own(v, \"mappings\"));\n for (const vp of Object.keys(mappings)) {\n const m = mappingFromCx1(mappings[vp], notes, target);\n if (m === null) {\n notes?.add(STYLE_ISSUE.BAD_MAPPING, target, vp, { sample: mappings[vp] });\n } else {\n style[target].mappings.set(vp, m);\n }\n }\n const deps = record(own(v, \"dependencies\"));\n for (const d of Object.keys(deps)) {\n style[target].dependencies.set(d, String(deps[d]).toLowerCase() === \"true\");\n }\n}\n\n/**\n * The style of a CX2 file from its `visualProperties` and `visualEditorProperties` aspects (the first entry of\n * each). CX2 has no `NODE_SIZE`, so a locked node size follows `NODE_WIDTH` (its default, mapping and bypasses)\n * unless the file writes `NODE_SIZE` anyway.\n * @param visualProperties - the `visualProperties` aspect\n * @param visualEditorProperties - the `visualEditorProperties` aspect, or undefined\n * @param notes - where problems are noted\n * @returns the style\n * @category Styles\n */\nexport function cytoscapeStyleFromCx2(\n visualProperties: unknown,\n visualEditorProperties?: unknown,\n notes?: StyleNotes,\n): CytoscapeStyle {\n const style = emptyCytoscapeStyle();\n const first = (x: unknown): unknown => (Array.isArray(x) ? x[0] : x);\n const vp = record(first(visualProperties));\n const editor = record(own(record(first(visualEditorProperties)), \"properties\"));\n const defaults = record(own(vp, \"default\"));\n for (const target of [\"network\", \"node\", \"edge\"] as const) {\n const d = record(own(defaults, target));\n for (const k of Object.keys(d)) {\n style[target].defaults.set(k, d[k]);\n }\n }\n style.node.dependencies.set(\"nodeSizeLocked\", own(editor, \"nodeSizeLocked\") === true);\n style.edge.dependencies.set(\"arrowColorMatchesEdge\", own(editor, \"arrowColorMatchesEdge\") === true);\n // charts are fitted to their node unless the editor says otherwise\n style.node.dependencies.set(\"nodeCustomGraphicsSizeSync\", own(editor, \"nodeCustomGraphicsSizeSync\") !== false);\n for (const [target, key] of [\n [\"node\", \"nodeMapping\"],\n [\"edge\", \"edgeMapping\"],\n ] as const) {\n const mappings = record(own(vp, key));\n for (const name of Object.keys(mappings)) {\n const m = mappingFromCx2(mappings[name]);\n if (m === null) {\n notes?.add(STYLE_ISSUE.BAD_MAPPING, target, name, { sample: mappings[name] });\n } else {\n style[target].mappings.set(name, m);\n }\n }\n }\n lockedSizeFromWidth(style.node);\n // CX2 names an edge's bend handles EDGE_CONTROL_POINTS\n for (const part of [style.edge.defaults, style.edge.mappings] as Map<string, unknown>[]) {\n if (part.has(\"EDGE_CONTROL_POINTS\") && !part.has(\"EDGE_BEND\")) {\n part.set(\"EDGE_BEND\", part.get(\"EDGE_CONTROL_POINTS\"));\n }\n }\n style.edge.bypassAliases.set(\"EDGE_CONTROL_POINTS\", \"EDGE_BEND\");\n return style;\n}\n\n/**\n * CX2 has no `NODE_SIZE`: a locked node size follows `NODE_WIDTH` (its default, mapping and bypasses) unless the\n * file writes `NODE_SIZE` anyway.\n * @param node - the node section, changed in place\n */\nfunction lockedSizeFromWidth(node: CytoscapeStyle[\"node\"]): void {\n if (\n node.dependencies.get(\"nodeSizeLocked\") !== true ||\n node.defaults.has(\"NODE_SIZE\") ||\n node.mappings.has(\"NODE_SIZE\")\n ) {\n return;\n }\n if (node.defaults.has(\"NODE_WIDTH\")) {\n node.defaults.set(\"NODE_SIZE\", node.defaults.get(\"NODE_WIDTH\"));\n }\n const width = node.mappings.get(\"NODE_WIDTH\");\n if (width !== undefined) {\n node.mappings.set(\"NODE_SIZE\", width);\n }\n node.bypassAliases.set(\"NODE_WIDTH\", \"NODE_SIZE\");\n}\n","/**\n * Neutral style rules back to a Cytoscape visual style, for the CX, CX2 and session writers: rules over every element\n * become defaults and mappings, everything Cytoscape cannot say as a rule (a rule over a group of elements, a second\n * mapping of one property, a value written per element) becomes per-element bypasses, so what Cytoscape draws is\n * what the rules give. Every value the style cannot hold is a coded note.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { escapeXmlAttribute } from \"../../common/escape.js\";\nimport { num6 } from \"../canon/number.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport { StyleNotes } from \"../notes.js\";\nimport { canonicalFor, degreeValues, refSource, resolveRules } from \"../plan/resolve.js\";\nimport type {\n ColumnRef,\n ContinuousPoint,\n ExtractedStyles,\n Mapping,\n Scalar,\n StyleRule,\n StyleTarget,\n StyleValue,\n} from \"../types.js\";\nimport { STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { JAVA_MONO, JAVA_SANS, JAVA_SERIF, javaFamily, vpStep } from \"./lexicon.js\";\nimport {\n type CytoscapeContinuousPoint,\n type CytoscapeMapping,\n type CytoscapeStyle,\n emptyCytoscapeStyle,\n} from \"./mappings.js\";\n\n/**\n * The spelling a Cytoscape style is written in: `\"desktop\"` for CX version 1 and session files (text values,\n * `NODE_FILL_COLOR`, 0..255 transparency), `\"cx2\"` for CX2 (typed JSON values, `NODE_BACKGROUND_COLOR`, 0..1\n * opacity).\n * @category Styles\n */\nexport type CytoscapeDialect = \"desktop\" | \"cx2\";\n\n/**\n * Options of `emitCytoscapeStyle()`.\n * @category Styles\n */\nexport interface CytoscapeEmitOptions {\n /** The spelling to write. */\n readonly dialect: CytoscapeDialect;\n /** Where every loss is noted (`W_STYLE_NOT_WRITTEN`, `W_STYLE_APPROXIMATED`, `W_STYLE_LAYER_FLATTENED`). */\n readonly notes?: StyleNotes;\n /**\n * The name of the attribute column a mapping over a style column or a computed degree reads, which the writer\n * adds to the file; defaults to `graphty.style.<target>.<key>` (`<key>` is the style column's key or the degree's\n * name).\n */\n readonly columnName?: (target: StyleTarget, ref: ColumnRef) => string;\n}\n\n/**\n * A Cytoscape style made from neutral rules.\n * @category Styles\n */\nexport interface CytoscapeEmitted {\n /** The style: defaults, mappings and dependencies, values in the dialect's spelling. */\n readonly style: CytoscapeStyle;\n /** Each element's bypasses (visual property to value in the dialect's spelling), or null where it has none. */\n readonly bypasses: {\n /** Per node, by node index. */\n readonly node: (Map<string, unknown> | null)[];\n /** Per edge, by edge index. */\n readonly edge: (Map<string, unknown> | null)[];\n };\n /** Attribute columns the mappings read that the graph does not hold, by name, with each element's value. */\n readonly columns: {\n /** Node columns. */\n readonly node: Map<string, readonly (StyleValue | null)[]>;\n /** Edge columns. */\n readonly edge: Map<string, readonly (StyleValue | null)[]>;\n };\n}\n\n/** Writes one canonical value in a dialect's spelling; calls `approx` when the value is changed to fit. */\ntype Write = (v: StyleValue, approx: () => void) => unknown;\n\n/** A visual property and how a value is written into it. */\ninterface Writer {\n readonly vp: string;\n readonly write: Write;\n}\n\n/**\n * `#RRGGBB`.\n * @param v - a canonical color\n * @returns the color as Cytoscape writes it\n */\nconst colorOut: Write = (v) => String(v).toUpperCase();\n\n/**\n * A writer of an enumeration.\n * @param table - canonical value to the dialect's spelling\n * @param near - canonical value to the nearest spelling, for values the dialect does not have\n * @param upper - whether an `other:` value is written uppercase with underscores\n * @param cytoscape - the `other:` values (lowercase, hyphenated) that are Cytoscape's own names, written as they\n * are; any other `other:` value (another program's, such as Graphviz's `invtrapezium`) is no Cytoscape value and\n * is written as its nearest\n * @returns the writer\n */\nfunction enumOut(\n table: Readonly<Record<string, string>>,\n near: Readonly<Record<string, string>>,\n upper: boolean,\n cytoscape: ReadonlySet<string> = new Set(),\n): Write {\n return (v, approx) => {\n const s = String(v);\n if (Object.hasOwn(table, s)) {\n return table[s];\n }\n if (s.startsWith(\"other:\") && cytoscape.has(s.slice(\"other:\".length).toLowerCase().replaceAll(\"_\", \"-\"))) {\n const raw = s.slice(\"other:\".length);\n const out = upper ? raw.toUpperCase().replaceAll(\"-\", \"_\") : raw;\n if (out !== raw) {\n // read back in Cytoscape's spelling, which is another value\n approx();\n }\n return out;\n }\n approx();\n return Object.hasOwn(near, s) ? near[s] : Object.values(table)[0];\n };\n}\n\n/** Where a node's border sits: Cytoscape's own place for it is inside the node's size, which it always draws. */\nconst BORDER_POSITION = \"borderPosition\";\n\n/**\n * What Cytoscape always draws and no file can change, per target: where a border sits, how far its zigzag and\n * sine-wave strokes swing and how often they repeat (`ding-presentation-impl` `ZigzagStroke`, `SineWaveStroke`), and\n * a label's box round its words alone, its lines one font tall. Nothing is written for them, and any other value is\n * drawn as Cytoscape's.\n */\nconst FIXED: Readonly<Record<\"node\" | \"edge\", ReadonlyMap<string, string | number>>> = {\n node: new Map<string, string | number>([\n [BORDER_POSITION, \"inside\"],\n [\"borderWaveAmplitude\", 10],\n [\"borderWavePeriod\", 20],\n [\"labelPadding\", 0],\n [\"labelLineHeight\", 1],\n ]),\n edge: new Map<string, string | number>([\n [\"waveAmplitude\", 10],\n [\"wavePeriod\", 20],\n [\"labelPadding\", 0],\n [\"labelLineHeight\", 1],\n ]),\n};\n\nconst DESKTOP_SHAPES = {\n ellipse: \"ELLIPSE\",\n rectangle: \"RECTANGLE\",\n \"round-rectangle\": \"ROUND_RECTANGLE\",\n triangle: \"TRIANGLE\",\n diamond: \"DIAMOND\",\n hexagon: \"HEXAGON\",\n octagon: \"OCTAGON\",\n parallelogram: \"PARALLELOGRAM\",\n vee: \"V\",\n};\nconst NEAR_SHAPES = {\n pentagon: \"hexagon\",\n star: \"octagon\",\n trapezoid: \"parallelogram\",\n none: \"ellipse\",\n // Graphviz shapes no canonical shape names\n \"other:invtrapezium\": \"parallelogram\",\n \"other:house\": \"hexagon\",\n \"other:invhouse\": \"hexagon\",\n};\nconst lower = (t: Readonly<Record<string, string>>): Record<string, string> =>\n Object.fromEntries(Object.entries(t).map(([k, v]) => [k, v === \"V\" ? \"vee\" : v.toLowerCase()]));\nconst nearIn = (t: Readonly<Record<string, string>>, near: Readonly<Record<string, string>>): Record<string, string> =>\n Object.fromEntries(Object.entries(near).map(([k, v]) => [k, t[v]]));\n\nconst DESKTOP_BORDERS = {\n solid: \"SOLID\",\n dashed: \"EQUAL_DASH\",\n dotted: \"DOT\",\n \"dash-dot\": \"DASH_DOT\",\n double: \"PARALLEL_LINES\",\n};\n// LONG_DASH is read as dashed (CX2 has no long dash), so long-dash is written as its nearest, EQUAL_DASH\nconst DESKTOP_LINES = { ...DESKTOP_BORDERS, zigzag: \"ZIGZAG\", sinewave: \"SINEWAVE\" };\nconst CX2_LINES = { solid: \"solid\", dashed: \"dashed\", dotted: \"dotted\", double: \"double\" };\nconst NEAR_LINES = { \"dash-dot\": \"dashed\", \"long-dash\": \"dashed\", zigzag: \"solid\", sinewave: \"solid\" };\n\nconst DESKTOP_ARROWS = {\n none: \"NONE\",\n triangle: \"DELTA\",\n tee: \"T\",\n diamond: \"DIAMOND\",\n circle: \"CIRCLE\",\n square: \"SQUARE\",\n \"triangle-open\": \"OPEN_DELTA\",\n \"diamond-open\": \"OPEN_DIAMOND\",\n \"circle-open\": \"OPEN_CIRCLE\",\n half: \"HALF_TOP\",\n \"other:cross-delta\": \"CROSS_DELTA\",\n \"other:cross-open-delta\": \"CROSS_OPEN_DELTA\",\n};\nconst CX2_ARROWS = {\n none: \"none\",\n triangle: \"triangle\",\n vee: \"vee\",\n tee: \"tee\",\n diamond: \"diamond\",\n circle: \"circle\",\n square: \"square\",\n \"triangle-open\": \"open-triangle\",\n \"diamond-open\": \"open-diamond\",\n \"circle-open\": \"open-circle\",\n half: \"half-top\",\n // as Cytoscape 3.10.5 writes CROSS_DELTA and CROSS_OPEN_DELTA in CX2\n \"other:cross-delta\": \"triangle-cross\",\n \"other:cross-open-delta\": \"cross_open_delta\",\n};\nconst NEAR_ARROWS = { crow: \"vee\", inverted: \"triangle\" };\n// desktop has no open vee: its ARROW, the nearest, is drawn as a filled delta and read back as one\nconst DESKTOP_NEAR_ARROWS = { crow: \"ARROW\", inverted: \"DELTA\", vee: \"ARROW\" };\n\n/** The Cytoscape arrow names no canonical arrow names, which Cytoscape's readers keep as `other:` values. */\nconst CY_OTHER_ARROWS: ReadonlySet<string> = new Set([\"open-square\", \"open-half-circle\", \"half-circle\", \"half-bottom\"]);\n/** The Cytoscape line types no canonical line style names. */\nconst CY_OTHER_LINES: ReadonlySet<string> = new Set([\n \"backward-slash\",\n \"forward-slash\",\n \"vertical-slash\",\n \"separate-arrow\",\n \"contiguous-arrow\",\n]);\n/** The Cytoscape line types a border can take that no canonical border style names. */\nconst CY_OTHER_BORDERS: ReadonlySet<string> = new Set([...CY_OTHER_LINES, \"zigzag\", \"sinewave\"]);\n\n/**\n * A label position as the point of the node and the point of the label's box pinned to it, in desktop's anchor\n * letters: beside the node, the label's opposite point; inside it, the same point.\n */\nconst POSITION_ANCHORS: Readonly<Record<string, readonly [node: string, label: string]>> = {\n center: [\"C\", \"C\"],\n top: [\"N\", \"S\"],\n bottom: [\"S\", \"N\"],\n left: [\"W\", \"E\"],\n right: [\"E\", \"W\"],\n \"top-left\": [\"NW\", \"SE\"],\n \"top-right\": [\"NE\", \"SW\"],\n \"bottom-left\": [\"SW\", \"NE\"],\n \"bottom-right\": [\"SE\", \"NW\"],\n \"inside-top\": [\"N\", \"N\"],\n \"inside-bottom\": [\"S\", \"S\"],\n \"inside-left\": [\"W\", \"W\"],\n \"inside-right\": [\"E\", \"E\"],\n \"inside-top-left\": [\"NW\", \"NW\"],\n \"inside-top-right\": [\"NE\", \"NE\"],\n \"inside-bottom-left\": [\"SW\", \"SW\"],\n \"inside-bottom-right\": [\"SE\", \"SE\"],\n};\nconst DESKTOP_POSITIONS: Readonly<Record<string, string>> = Object.fromEntries(\n Object.entries(POSITION_ANCHORS).map(([k, [node, label]]) => [k, `${node},${label},c,0.00,0.00`]),\n);\n/** A desktop anchor letter as CX2's horizontal and vertical words. */\nconst CX2_WORDS: Readonly<Record<string, readonly [string, string]>> = {\n C: [\"center\", \"center\"],\n N: [\"center\", \"top\"],\n S: [\"center\", \"bottom\"],\n W: [\"left\", \"center\"],\n E: [\"right\", \"center\"],\n NW: [\"left\", \"top\"],\n NE: [\"right\", \"top\"],\n SW: [\"left\", \"bottom\"],\n SE: [\"right\", \"bottom\"],\n};\n\nconst desktopNumber: Write = String;\nconst cx2Number: Write = (v) => v;\n\n/**\n * A writer for a visual property Cytoscape holds as a whole number (a font size): the value is written as it is, and\n * a fraction is noted, since Cytoscape draws it rounded.\n * @param write - the dialect's number writer\n * @returns the writer\n */\nfunction whole(write: Write): Write {\n return (v, approx) => {\n if (typeof v === \"number\" && !Number.isInteger(v)) {\n approx();\n }\n return write(v, approx);\n };\n}\nconst textOut: Write = String;\nconst desktopBool: Write = (v) => String(v === true);\nconst opacity255: Write = (v, approx) => {\n const b = Math.round(Number(v) * 255);\n if (num6(b / 255) !== v) {\n approx();\n }\n return String(b);\n};\n\n/** The writers of each dialect, per target and property. */\nconst WRITERS: Readonly<Record<CytoscapeDialect, Readonly<Record<StyleTarget, ReadonlyMap<string, Writer>>>>> = {\n desktop: {\n node: new Map<string, Writer>([\n [\"fill\", { vp: \"NODE_FILL_COLOR\", write: colorOut }],\n [\"fillOpacity\", { vp: \"NODE_TRANSPARENCY\", write: opacity255 }],\n [\"borderColor\", { vp: \"NODE_BORDER_PAINT\", write: colorOut }],\n [\"borderOpacity\", { vp: \"NODE_BORDER_TRANSPARENCY\", write: opacity255 }],\n [\"borderWidth\", { vp: \"NODE_BORDER_WIDTH\", write: desktopNumber }],\n [\n \"borderStyle\",\n {\n vp: \"NODE_BORDER_LINE_TYPE\",\n write: enumOut(DESKTOP_BORDERS, nearIn(DESKTOP_BORDERS, NEAR_LINES), true, CY_OTHER_BORDERS),\n },\n ],\n [\"shape\", { vp: \"NODE_SHAPE\", write: enumOut(DESKTOP_SHAPES, nearIn(DESKTOP_SHAPES, NEAR_SHAPES), true) }],\n [\"width\", { vp: \"NODE_WIDTH\", write: desktopNumber }],\n [\"height\", { vp: \"NODE_HEIGHT\", write: desktopNumber }],\n [\"label\", { vp: \"NODE_LABEL\", write: textOut }],\n [\"labelColor\", { vp: \"NODE_LABEL_COLOR\", write: colorOut }],\n [\"labelSize\", { vp: \"NODE_LABEL_FONT_SIZE\", write: whole(desktopNumber) }],\n [\"labelWrapWidth\", { vp: \"NODE_LABEL_WIDTH\", write: desktopNumber }],\n [\"labelPosition\", { vp: \"NODE_LABEL_POSITION\", write: enumOut(DESKTOP_POSITIONS, {}, false) }],\n [\"labelRotation\", { vp: \"NODE_LABEL_ROTATION\", write: desktopNumber }],\n [\"tooltip\", { vp: \"NODE_TOOLTIP\", write: textOut }],\n [\"visible\", { vp: \"NODE_VISIBLE\", write: desktopBool }],\n ]),\n edge: new Map<string, Writer>([\n [\"color\", { vp: \"EDGE_STROKE_UNSELECTED_PAINT\", write: colorOut }],\n [\"opacity\", { vp: \"EDGE_TRANSPARENCY\", write: opacity255 }],\n [\"width\", { vp: \"EDGE_WIDTH\", write: desktopNumber }],\n [\n \"lineStyle\",\n {\n vp: \"EDGE_LINE_TYPE\",\n write: enumOut(DESKTOP_LINES, nearIn(DESKTOP_LINES, NEAR_LINES), true, CY_OTHER_LINES),\n },\n ],\n [\n \"sourceArrow\",\n {\n vp: \"EDGE_SOURCE_ARROW_SHAPE\",\n write: enumOut(DESKTOP_ARROWS, DESKTOP_NEAR_ARROWS, true, CY_OTHER_ARROWS),\n },\n ],\n [\n \"targetArrow\",\n {\n vp: \"EDGE_TARGET_ARROW_SHAPE\",\n write: enumOut(DESKTOP_ARROWS, DESKTOP_NEAR_ARROWS, true, CY_OTHER_ARROWS),\n },\n ],\n [\"sourceArrowColor\", { vp: \"EDGE_SOURCE_ARROW_UNSELECTED_PAINT\", write: colorOut }],\n [\"targetArrowColor\", { vp: \"EDGE_TARGET_ARROW_UNSELECTED_PAINT\", write: colorOut }],\n [\"curved\", { vp: \"EDGE_CURVED\", write: desktopBool }],\n [\"label\", { vp: \"EDGE_LABEL\", write: textOut }],\n [\"labelColor\", { vp: \"EDGE_LABEL_COLOR\", write: colorOut }],\n [\"labelSize\", { vp: \"EDGE_LABEL_FONT_SIZE\", write: whole(desktopNumber) }],\n [\"tooltip\", { vp: \"EDGE_TOOLTIP\", write: textOut }],\n [\"visible\", { vp: \"EDGE_VISIBLE\", write: desktopBool }],\n ]),\n },\n cx2: {\n node: new Map<string, Writer>([\n [\"fill\", { vp: \"NODE_BACKGROUND_COLOR\", write: colorOut }],\n [\"fillOpacity\", { vp: \"NODE_BACKGROUND_OPACITY\", write: cx2Number }],\n [\"borderColor\", { vp: \"NODE_BORDER_COLOR\", write: colorOut }],\n [\"borderOpacity\", { vp: \"NODE_BORDER_OPACITY\", write: cx2Number }],\n [\"borderWidth\", { vp: \"NODE_BORDER_WIDTH\", write: cx2Number }],\n [\n \"borderStyle\",\n {\n vp: \"NODE_BORDER_STYLE\",\n write: enumOut(CX2_LINES, nearIn(CX2_LINES, NEAR_LINES), false, CY_OTHER_BORDERS),\n },\n ],\n [\n \"shape\",\n {\n vp: \"NODE_SHAPE\",\n write: enumOut(lower(DESKTOP_SHAPES), nearIn(lower(DESKTOP_SHAPES), NEAR_SHAPES), false),\n },\n ],\n [\"width\", { vp: \"NODE_WIDTH\", write: cx2Number }],\n [\"height\", { vp: \"NODE_HEIGHT\", write: cx2Number }],\n [\"label\", { vp: \"NODE_LABEL\", write: textOut }],\n [\"labelColor\", { vp: \"NODE_LABEL_COLOR\", write: colorOut }],\n [\"labelSize\", { vp: \"NODE_LABEL_FONT_SIZE\", write: whole(cx2Number) }],\n [\"labelWrapWidth\", { vp: \"NODE_LABEL_MAX_WIDTH\", write: cx2Number }],\n [\"labelPosition\", { vp: \"NODE_LABEL_POSITION\", write: cx2Position }],\n [\"labelRotation\", { vp: \"NODE_LABEL_ROTATION\", write: cx2Number }],\n [\"visible\", { vp: \"NODE_VISIBILITY\", write: (v) => (v === true ? \"element\" : \"none\") }],\n ]),\n edge: new Map<string, Writer>([\n [\"color\", { vp: \"EDGE_LINE_COLOR\", write: colorOut }],\n [\"opacity\", { vp: \"EDGE_OPACITY\", write: cx2Number }],\n [\"width\", { vp: \"EDGE_WIDTH\", write: cx2Number }],\n [\n \"lineStyle\",\n {\n vp: \"EDGE_LINE_STYLE\",\n write: enumOut(CX2_LINES, nearIn(CX2_LINES, NEAR_LINES), false, CY_OTHER_LINES),\n },\n ],\n [\n \"sourceArrow\",\n {\n vp: \"EDGE_SOURCE_ARROW_SHAPE\",\n write: enumOut(CX2_ARROWS, nearIn(CX2_ARROWS, NEAR_ARROWS), false, CY_OTHER_ARROWS),\n },\n ],\n [\n \"targetArrow\",\n {\n vp: \"EDGE_TARGET_ARROW_SHAPE\",\n write: enumOut(CX2_ARROWS, nearIn(CX2_ARROWS, NEAR_ARROWS), false, CY_OTHER_ARROWS),\n },\n ],\n [\"sourceArrowColor\", { vp: \"EDGE_SOURCE_ARROW_COLOR\", write: colorOut }],\n [\"targetArrowColor\", { vp: \"EDGE_TARGET_ARROW_COLOR\", write: colorOut }],\n [\"curved\", { vp: \"EDGE_CURVED\", write: (v) => v === true }],\n [\"label\", { vp: \"EDGE_LABEL\", write: textOut }],\n [\"labelColor\", { vp: \"EDGE_LABEL_COLOR\", write: colorOut }],\n [\"labelSize\", { vp: \"EDGE_LABEL_FONT_SIZE\", write: whole(cx2Number) }],\n [\"visible\", { vp: \"EDGE_VISIBILITY\", write: (v) => (v === true ? \"element\" : \"none\") }],\n ]),\n },\n};\n\n/**\n * CX2's label position object.\n * @param v - a canonical position\n * @returns the object\n */\nfunction cx2Position(v: StyleValue): unknown {\n const [node, label] = Object.hasOwn(POSITION_ANCHORS, String(v)) ? POSITION_ANCHORS[String(v)] : [\"C\", \"C\"];\n const [h, vert] = CX2_WORDS[node];\n const [ha, va] = CX2_WORDS[label];\n return {\n HORIZONTAL_ALIGN: ha,\n VERTICAL_ALIGN: va,\n HORIZONTAL_ANCHOR: h,\n VERTICAL_ANCHOR: vert,\n MARGIN_X: 0,\n MARGIN_Y: 0,\n JUSTIFICATION: \"center\",\n };\n}\n\n/** The font properties, written together into one font face. */\nconst FONT_PROPS = [\"labelFont\", \"labelWeight\", \"labelItalic\"] as const;\nconst FONT_VP: Readonly<Record<StyleTarget, string>> = { node: \"NODE_LABEL_FONT_FACE\", edge: \"EDGE_LABEL_FONT_FACE\" };\n// A CSS generic family is written as it is: Java draws a name it does not know in Dialog, and reads it back the same.\nconst CSS_TO_JAVA: Readonly<Record<string, string>> = {\n // the families the reader gives Java's logical fonts\n [JAVA_SANS]: \"SansSerif\",\n [JAVA_SERIF]: \"Serif\",\n [JAVA_MONO]: \"Monospaced\",\n};\n\n/**\n * A font face in a dialect's spelling.\n * @param dialect - the dialect\n * @param family - the family, or null\n * @param weight - the weight, or null\n * @param italic - whether italic, or null\n * @param approx - called when the family had to be shortened\n * @returns the face\n */\nfunction fontOut(\n dialect: CytoscapeDialect,\n family: StyleValue | null,\n weight: StyleValue | null,\n italic: StyleValue | null,\n approx: () => void,\n): unknown {\n const bold = weight === \"bold\";\n const it = italic === true;\n const fam = family === null ? \"sans-serif\" : String(family);\n if (dialect === \"cx2\") {\n if (fontReadsAs(fam) !== fam) {\n approx();\n }\n return { FONT_FAMILY: fam, FONT_STYLE: it ? \"italic\" : \"normal\", FONT_WEIGHT: bold ? \"bold\" : \"normal\" };\n }\n const first = fam.includes(\",\") ? fam.split(\",\")[0].trim() : fam;\n const asWritten = Object.hasOwn(CSS_TO_JAVA, first) ? CSS_TO_JAVA[first] : first;\n const java = Object.hasOwn(CSS_TO_JAVA, fam) ? CSS_TO_JAVA[fam] : asWritten;\n if (fontReadsAs(java) !== fam) {\n approx();\n }\n // desktop reads the face from the name alone: bold and italic go on it as a Java face suffix, as desktop itself\n // writes them (`SansSerif.bold,bold,12`); the style word after it is not read (`FontVisualProperty`)\n const style = javaFontStyle(bold, it);\n const face = style === \"plain\" ? java : `${java}.${style}`;\n return `${face},${bold ? \"bold\" : \"plain\"},12`;\n}\n\n/**\n * The style part of a Java font face.\n * @param bold - whether bold\n * @param italic - whether italic\n * @returns `plain`, `bold`, `italic` or `bolditalic`\n */\nfunction javaFontStyle(bold: boolean, italic: boolean): string {\n if (!bold && !italic) {\n return \"plain\";\n }\n return (bold ? \"bold\" : \"\") + (italic ? \"italic\" : \"\");\n}\n\n/**\n * The family a font face reads back as: the reader drops a face suffix (Dialog.plain is Dialog) and reads a Java\n * logical name as the family Cytoscape draws it with (Dialog as sans-serif).\n * @param name - the face\n * @returns the family\n */\nfunction fontReadsAs(name: string): string {\n return javaFamily(name.replace(/\\.(?:bold|italic|plain|bolditalic)$/i, \"\"));\n}\n\n/**\n * The default name of the column a mapping over a non-data column reads.\n * @param target - nodes or edges\n * @param ref - the column\n * @returns the name\n */\nfunction defaultColumnName(target: StyleTarget, ref: ColumnRef): string {\n if (\"style\" in ref) {\n return `graphty.style.${target}.${ref.style}`;\n }\n return `graphty.style.${target}.${\"computed\" in ref ? ref.computed : (ref as { data: string }).data}`;\n}\n\n/** The kinds of value a Cytoscape passthrough reads the same way the neutral reading does. */\nconst PASSTHROUGH_SAFE: ReadonlySet<string> = new Set([\"color\", \"number\", \"text\", \"boolean\"]);\n\n/**\n * Turns neutral rules into a Cytoscape visual style. Rules over every element become defaults (a constant) and\n * mappings (one per visual property: the topmost wins); a passthrough of a value Cytoscape spells differently (an\n * opacity, a shape) becomes a discrete table over the values the graph holds. Every element whose value under the\n * rules differs from what that style gives gets a bypass, so Cytoscape draws exactly what the rules give; each rule\n * written that way is noted as `W_STYLE_LAYER_FLATTENED`. A property Cytoscape has no visual property for is noted as\n * `W_STYLE_NOT_WRITTEN`, a value changed to the nearest Cytoscape has as `W_STYLE_APPROXIMATED`.\n * @param extracted - the styles, for this graph\n * @param snapshot - the graph\n * @param options - the dialect, notes and column names\n * @returns the style, the bypasses and the columns the writer adds\n * @category Styles\n */\nexport function emitCytoscapeStyle(\n extracted: ExtractedStyles,\n snapshot: GraphSnapshot,\n options: CytoscapeEmitOptions,\n): CytoscapeEmitted {\n const notes = options.notes ?? new StyleNotes();\n const style = emptyCytoscapeStyle();\n const bypasses = {\n node: new Array<Map<string, unknown> | null>(snapshot.nodeCount).fill(null),\n edge: new Array<Map<string, unknown> | null>(snapshot.edgeCount).fill(null),\n };\n const columns = {\n node: new Map<string, readonly (StyleValue | null)[]>(),\n edge: new Map<string, readonly (StyleValue | null)[]>(),\n };\n for (const target of [\"node\", \"edge\"] as const) {\n emitTarget(targetEmit(target, extracted, snapshot, options, notes), style, bypasses[target], columns[target]);\n }\n const bg = extracted.styles.graph.background;\n if (bg !== undefined) {\n style.network.defaults.set(\n options.dialect === \"cx2\" ? \"NETWORK_BACKGROUND_COLOR\" : \"NETWORK_BACKGROUND_PAINT\",\n bg.toUpperCase(),\n );\n }\n return { style, bypasses, columns };\n}\n\n/** The neutral style one target's Cytoscape style gives, being built. */\ninterface Model {\n readonly set: Map<string, StyleValue>;\n readonly map: Map<string, Mapping>;\n readonly mappedBy: Map<string, string>;\n}\n\n/** What emitting one target reads. */\ninterface TargetEmit {\n readonly target: StyleTarget;\n readonly extracted: ExtractedStyles;\n readonly snapshot: GraphSnapshot;\n readonly options: CytoscapeEmitOptions;\n readonly notes: StyleNotes;\n /** The element count. */\n readonly n: number;\n readonly src: ReturnType<typeof refSource>;\n /** The target's rules. */\n readonly rules: readonly StyleRule[];\n /** Every element's value of each property the rules write. */\n readonly truth: ReadonlyMap<string, (StyleValue | null)[]>;\n /** The approximation note of a property. */\n readonly approx: (p: string) => () => void;\n /** The approximation note of a default, counted over the elements that draw it. */\n readonly approxDefault: (p: string, value: StyleValue) => () => void;\n}\n\n/**\n * What emitting one target reads, worked out once.\n * @param target - nodes or edges\n * @param extracted - the styles\n * @param snapshot - the graph\n * @param options - the options\n * @param notes - where losses are noted\n * @returns the target's emission\n */\nfunction targetEmit(\n target: StyleTarget,\n extracted: ExtractedStyles,\n snapshot: GraphSnapshot,\n options: CytoscapeEmitOptions,\n notes: StyleNotes,\n): TargetEmit {\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const src = refSource(target, n, extracted.columns[target], extracted.features[target], snapshot);\n const rules = extracted.styles.rules.filter((r) => r.target === target);\n const written = new Set(rules.flatMap((r) => [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})]));\n const truth = new Map(Array.from(written, (p) => [p, resolveRules(rules, target, p, src)] as const));\n return {\n target,\n extracted,\n snapshot,\n options,\n notes,\n n,\n src,\n rules,\n truth,\n approx: (p) => () => {\n notes.add(STYLE_ISSUE.APPROXIMATED, target, p);\n },\n // a default written as an approximation changes every element that draws it\n approxDefault: (p, value) => () => {\n const count = (truth.get(p) ?? []).filter((v) => v === value).length;\n notes.add(STYLE_ISSUE.APPROXIMATED, target, p, { count: Math.max(count, 1) });\n },\n };\n}\n\n/** The properties Cytoscape draws one way only, with that way: what is drawn so needs nothing written. */\nconst DRAWN_SO: ReadonlyMap<string, StyleValue> = new Map<string, StyleValue>([\n // it measures each word with a space after it when it wraps a label\n [\"labelWrapTrailingSpace\", true],\n // it curves an edge through its bends' midpoints\n [\"bendCurve\", \"midpoints\"],\n]);\n\n/**\n * Whether every element's value of a property is how Cytoscape draws it anyway, so there is nothing to write.\n * @param p - the property\n * @param values - each element's value\n * @returns true when nothing is lost by not writing it\n */\nfunction drawnSo(p: string, values: readonly (StyleValue | null)[]): boolean {\n const way = DRAWN_SO.get(p);\n return way !== undefined && values.every((v) => v === null || v === way);\n}\n\n/**\n * Emits one target.\n * @param e - the target's emission\n * @param style - the style being written\n * @param bypasses - the target's bypasses, filled in\n * @param columns - the target's added columns, filled in\n */\nfunction emitTarget(\n e: TargetEmit,\n style: CytoscapeStyle,\n bypasses: (Map<string, unknown> | null)[],\n columns: Map<string, readonly (StyleValue | null)[]>,\n): void {\n const { target, notes, truth } = e;\n const writers = WRITERS[e.options.dialect][target];\n for (const [p, values] of truth) {\n const fixed = FIXED[target].get(p);\n if (fixed !== undefined) {\n // Cytoscape draws every border inside its node's size and every wave alike: nothing to write, and any\n // other value is lost\n const other = values.filter((v) => v !== null && v !== fixed).length;\n if (other > 0) {\n notes.add(STYLE_ISSUE.APPROXIMATED, target, p, { count: other });\n }\n } else if (!writers.has(p) && !(FONT_PROPS as readonly string[]).includes(p) && !drawnSo(p, values)) {\n const count = values.filter((v) => v !== null).length;\n notes.add(STYLE_ISSUE.NOT_WRITTEN, target, p, { count: Math.max(count, 1) });\n }\n }\n\n // a rule written as per-element values is noted with the elements that carry one, once per property\n const counted = new Set<string>();\n const carrying = (p: string): number => {\n if (counted.has(p)) {\n return 0;\n }\n counted.add(p);\n return Math.max((truth.get(p) ?? []).filter((v) => v !== null).length, 1);\n };\n const model = buildModel(target, e.rules, writers, notes, carrying);\n const s = style[target];\n s.dependencies.set(target === \"node\" ? \"nodeSizeLocked\" : \"arrowColorMatchesEdge\", false);\n for (const [p, w] of writers) {\n if (truth.has(p)) {\n emitProperty(e, s, model, p, w, columns, carrying);\n }\n }\n addBypasses(e, model, writers, bypasses);\n emitFont(e, model, s, bypasses);\n}\n\n/**\n * Emits one property the rules write: its default, and its mapping, or the mapping noted as flattened when\n * Cytoscape cannot read the column it needs.\n * @param e - the target's emission\n * @param s - the target's style\n * @param model - the model; a mapping not written is removed\n * @param p - the property\n * @param w - its writer\n * @param columns - where added columns go\n * @param carrying - how many elements carry a value of a property, once\n */\nfunction emitProperty(\n e: TargetEmit,\n s: CytoscapeStyle[\"node\"],\n model: Model,\n p: string,\n w: Writer,\n columns: Map<string, readonly (StyleValue | null)[]>,\n carrying: (p: string) => number,\n): void {\n const set = model.set.get(p);\n if (set !== undefined) {\n s.defaults.set(w.vp, w.write(set, e.approxDefault(p, set)));\n }\n let m = model.map.get(p);\n if (m === undefined) {\n return;\n }\n if (e.options.dialect === \"cx2\" && m.kind === \"continuous\") {\n m = cx2Points(m, e.approx(p));\n model.map.set(p, m);\n }\n const cm = cytoscapeMapping(e, p, m, w, columns);\n if (cm === null) {\n e.notes.add(STYLE_ISSUE.LAYER_FLATTENED, e.target, p, { sample: model.mappedBy.get(p), count: carrying(p) });\n model.map.delete(p);\n } else {\n s.mappings.set(w.vp, cm);\n }\n}\n\n/**\n * A bypass for every element the written style draws differently from the rules.\n * @param e - the target's emission\n * @param model - the defaults and mappings written\n * @param writers - the dialect's writers\n * @param bypasses - the bypasses, filled in\n */\nfunction addBypasses(\n e: TargetEmit,\n model: Model,\n writers: ReadonlyMap<string, Writer>,\n bypasses: (Map<string, unknown> | null)[],\n): void {\n const { target } = e;\n const modelRules: StyleRule[] = [\n {\n id: \"defaults\",\n target,\n role: \"defaults\",\n origin: \"declared\",\n where: { all: true },\n set: Object.fromEntries(model.set),\n },\n {\n id: \"mappings\",\n target,\n role: \"mapping\",\n origin: \"declared\",\n where: { all: true },\n map: Object.fromEntries(model.map),\n },\n ];\n for (const [p, w] of writers) {\n const want = e.truth.get(p);\n if (want === undefined) {\n continue;\n }\n const drawn = resolveRules(modelRules, target, p, e.src);\n const step = drawnStep(model.map.get(p), w.vp, STYLE_PROPERTIES[target].get(p));\n let rounded = 0;\n for (let i = 0; i < e.n; i++) {\n const v = want[i];\n if (v !== null && v !== drawn[i]) {\n bypasses[i] ??= new Map();\n bypasses[i]?.set(w.vp, w.write(v, e.approx(p)));\n } else if (offStep(v, step)) {\n rounded++;\n }\n }\n if (rounded > 0) {\n e.notes.add(STYLE_ISSUE.APPROXIMATED, target, p, { count: rounded });\n }\n }\n}\n\n/**\n * The step Cytoscape rounds the values of a written mapping to: a continuous mapping, or a passthrough written as\n * one, on a visual property that holds whole numbers (a font size, a 0..255 transparency) is drawn rounded, unless\n * the mapping already rounds to it. A passthrough written as a table writes its values through the property's writer,\n * which notes them itself.\n * @param m - the mapping written, if any\n * @param vp - the visual property it sets\n * @param kind - the kind of value the property holds\n * @returns the step, or undefined when Cytoscape draws the mapping's values as they are\n */\nfunction drawnStep(m: Mapping | undefined, vp: string, kind: string | undefined): number | undefined {\n const ramp = m?.kind === \"continuous\" && m.step === undefined;\n const passthrough = m?.kind === \"passthrough\" && PASSTHROUGH_SAFE.has(kind ?? \"\");\n return ramp || passthrough ? vpStep(vp) : undefined;\n}\n\n/**\n * Whether a value is not a multiple of a step, so Cytoscape draws it rounded.\n * @param v - the value\n * @param step - the step, or undefined for none\n * @returns true when the value changes on rounding\n */\nfunction offStep(v: StyleValue | null | undefined, step: number | undefined): boolean {\n return step !== undefined && typeof v === \"number\" && num6(Math.round(v / step) * step) !== v;\n}\n\n/**\n * The defaults and mappings of one target: rules over every element, bottom to top. A constant over every element\n * hides everything beneath it; of two mappings of one property only the topmost is kept. Every rule that cannot be\n * kept whole is noted as `W_STYLE_LAYER_FLATTENED`.\n * @param target - nodes or edges\n * @param rules - the target's rules\n * @param writers - the dialect's writers\n * @param notes - where flattened rules are noted\n * @param carrying - how many elements carry a value of a property\n * @returns the model\n */\nfunction buildModel(\n target: StyleTarget,\n rules: readonly StyleRule[],\n writers: ReadonlyMap<string, Writer>,\n notes: StyleNotes,\n carrying: (p: string) => number,\n): Model {\n const model: Model = { set: new Map(), map: new Map(), mappedBy: new Map() };\n const flatten = (p: string, id: string): void => {\n notes.add(STYLE_ISSUE.LAYER_FLATTENED, target, p, { sample: id, count: carrying(p) });\n };\n const holds = (p: string): boolean => writers.has(p) || (FONT_PROPS as readonly string[]).includes(p);\n const applySet = (r: StyleRule, all: boolean): void => {\n for (const [p, v] of Object.entries(r.set ?? {})) {\n if (v === undefined || !holds(p)) {\n continue;\n }\n if (!all) {\n flatten(p, r.id);\n continue;\n }\n model.set.set(p, v);\n model.map.delete(p);\n model.mappedBy.delete(p);\n }\n };\n const applyMap = (r: StyleRule, all: boolean): void => {\n for (const [p, m] of Object.entries(r.map ?? {})) {\n if (m === undefined || !holds(p)) {\n continue;\n }\n if (!all || (FONT_PROPS as readonly string[]).includes(p)) {\n flatten(p, r.id);\n continue;\n }\n const below = model.mappedBy.get(p);\n if (below !== undefined) {\n flatten(p, below);\n }\n model.map.set(p, m);\n model.mappedBy.set(p, r.id);\n }\n };\n for (const r of rules) {\n const all = \"all\" in r.where && r.where.all;\n applySet(r, all);\n applyMap(r, all);\n }\n return model;\n}\n\n/**\n * One neutral mapping as a Cytoscape mapping.\n * @param e - the target's emission\n * @param p - the property\n * @param m - the mapping\n * @param w - the property's writer\n * @param columns - where added columns go\n * @returns the mapping, or null when Cytoscape cannot read the column it needs\n */\nfunction cytoscapeMapping(\n e: TargetEmit,\n p: string,\n m: Mapping,\n w: Writer,\n columns: Map<string, readonly (StyleValue | null)[]>,\n): CytoscapeMapping | null {\n const column = mappingColumn(e, m.by, columns);\n if (column === null) {\n return null;\n }\n const approx = e.approx(p);\n const write = (v: StyleValue): unknown => w.write(v, approx);\n if (m.kind === \"passthrough\") {\n return passthroughMapping(e, p, m.by, column, write);\n }\n if (m.kind === \"discrete\") {\n return {\n kind: \"discrete\",\n column,\n type: keyType(\n e,\n m.by,\n m.table.map(([k]) => k),\n ),\n table: m.table.map(([k, v]) => [k, write(v)]),\n };\n }\n if (m.kind === \"continuous\") {\n const points: CytoscapeContinuousPoint[] = m.points.map((pt: ContinuousPoint) => ({\n at: pt.at,\n below: write(pt.below),\n value: write(pt.value),\n above: write(pt.above),\n }));\n return { kind: \"continuous\", column, type: \"double\", points };\n }\n return null;\n}\n\n/**\n * The column a mapping reads, by its name in the file: a data column's own, else an added column of the style\n * column's or the degree's values.\n * @param e - the target's emission\n * @param ref - the column\n * @param columns - where added columns go\n * @returns the name, or null when the values cannot be written (a degree of an edge)\n */\nfunction mappingColumn(\n e: TargetEmit,\n ref: ColumnRef,\n columns: Map<string, readonly (StyleValue | null)[]>,\n): string | null {\n if (\"data\" in ref) {\n return ref.data;\n }\n const { target } = e;\n const column = (e.options.columnName ?? defaultColumnName)(target, ref);\n let values: readonly (StyleValue | null)[] | null = null;\n if (\"style\" in ref) {\n values = e.extracted.columns[target].get(ref.style) ?? null;\n } else if (\"computed\" in ref && target === \"node\") {\n values = degreeValues(e.snapshot, ref.computed);\n }\n if (values === null) {\n return null;\n }\n columns.set(column, values);\n return column;\n}\n\n/**\n * A passthrough as Cytoscape reads it: a passthrough where Cytoscape reads the values as the neutral reading does,\n * else a table over the values the graph holds, in Cytoscape's spelling.\n * @param e - the target's emission\n * @param p - the property\n * @param by - the column\n * @param column - its name in the file\n * @param write - a value in Cytoscape's spelling\n * @returns the mapping\n */\nfunction passthroughMapping(\n e: TargetEmit,\n p: string,\n by: ColumnRef,\n column: string,\n write: (v: StyleValue) => unknown,\n): CytoscapeMapping {\n const { target } = e;\n const kind = STYLE_PROPERTIES[target].get(p) ?? \"\";\n const cells = e.src.column(by) ?? [];\n if (PASSTHROUGH_SAFE.has(kind)) {\n return { kind: \"passthrough\", column, type: typeOf(Array.from(cells)) };\n }\n const read = \"style\" in by ? (v: unknown): StyleValue | null => (isScalar(v) ? v : null) : canonicalFor(target, p);\n const seen = new Map<Scalar, unknown>();\n for (let i = 0; i < cells.length; i++) {\n const raw = cells[i];\n const v = isScalar(raw) && !seen.has(raw) ? read(raw) : null;\n if (v !== null) {\n seen.set(raw as Scalar, write(v));\n }\n }\n const table = Array.from(seen);\n return {\n kind: \"discrete\",\n column,\n type: keyType(\n e,\n by,\n table.map(([k]) => k),\n ),\n table,\n };\n}\n\n/**\n * A continuous mapping as CX2 holds it: CX2's intervals give the value exactly at a point only as the value just\n * below or just above it, so a third value becomes the one below (noted; the elements exactly at it get bypasses).\n * @param m - the mapping\n * @param approx - called when a point changes\n * @returns the mapping CX2 reads back\n */\nfunction cx2Points(m: Extract<Mapping, { kind: \"continuous\" }>, approx: () => void): Mapping {\n let changed = false;\n const points = m.points.map((pt) => {\n if (pt.value === pt.below || pt.value === pt.above) {\n return pt;\n }\n changed = true;\n return { ...pt, value: pt.below };\n });\n if (!changed) {\n return m;\n }\n approx();\n return { ...m, points };\n}\n\n/**\n * Whether a value is a scalar.\n * @param v - the value\n * @returns true for a string, a finite number or a boolean\n */\nfunction isScalar(v: unknown): v is Scalar {\n return typeof v === \"string\" || typeof v === \"boolean\" || (typeof v === \"number\" && Number.isFinite(v));\n}\n\n/**\n * The type a discrete mapping's keys are written with: `double` over a column the exporter writes as Double\n * (Cytoscape compares an Integer key with a Double cell and finds no match), else the keys' own type.\n * @param e - the target's emission\n * @param by - the column the mapping reads\n * @param keys - the keys\n * @returns the type\n */\nfunction keyType(e: TargetEmit, by: ColumnRef, keys: readonly unknown[]): string {\n const type = typeOf(keys);\n if (type !== \"integer\") {\n return type;\n }\n if (!(\"data\" in by)) {\n // a column the exporter adds holds numbers as Double\n return \"double\";\n }\n const meta = (e.target === \"node\" ? e.snapshot.nodes : e.snapshot.edges).get(by.data)?.meta;\n const floating = (meta?.dtype === \"f32\" || meta?.dtype === \"f64\") && meta.origin?.type !== \"long\";\n return floating ? \"double\" : type;\n}\n\n/**\n * Cytoscape's attribute type of a set of values: `integer`, `double`, `boolean` or `string`.\n * @param values - the values\n * @returns the type\n */\nfunction typeOf(values: readonly unknown[]): string {\n let numbers = 0;\n let integers = 0;\n let booleans = 0;\n let all = 0;\n for (const v of values) {\n if (v === null || v === undefined) {\n continue;\n }\n all++;\n if (typeof v === \"number\") {\n numbers++;\n if (Number.isInteger(v)) {\n integers++;\n }\n } else if (typeof v === \"boolean\") {\n booleans++;\n }\n }\n if (all > 0 && numbers === all) {\n return integers === all ? \"integer\" : \"double\";\n }\n if (all > 0 && booleans === all) {\n return \"boolean\";\n }\n return \"string\";\n}\n\n/**\n * The font face: a default from the constant font properties, and a bypass for every element whose family, weight\n * or italic differs from it.\n * @param e - the target's emission\n * @param model - the model\n * @param s - the target's style\n * @param bypasses - the bypasses\n */\nfunction emitFont(\n e: TargetEmit,\n model: Model,\n s: CytoscapeStyle[\"node\"],\n bypasses: (Map<string, unknown> | null)[],\n): void {\n const { target, truth, n, approx, approxDefault } = e;\n const { dialect } = e.options;\n if (!FONT_PROPS.some((p) => truth.has(p))) {\n return;\n }\n const [fd, wd, id] = FONT_PROPS.map((p) => model.set.get(p) ?? null);\n const vp = FONT_VP[target];\n if (fd !== null || wd !== null || id !== null) {\n s.defaults.set(\n vp,\n fontOut(dialect, fd, wd, id, fd === null ? approx(\"labelFont\") : approxDefault(\"labelFont\", fd)),\n );\n }\n const [ft, wt, it] = FONT_PROPS.map((p) => truth.get(p) ?? null);\n for (let i = 0; i < n; i++) {\n const f = ft?.[i] ?? null;\n const w = wt?.[i] ?? null;\n const t = it?.[i] ?? null;\n const differs = (f !== null && f !== fd) || (w !== null && w !== wd) || (t !== null && t !== id);\n if (differs) {\n bypasses[i] ??= new Map();\n bypasses[i]?.set(vp, fontOut(dialect, f ?? fd, w ?? wd, t ?? id, approx(\"labelFont\")));\n }\n }\n}\n\n// ------------------------------------------------------------------ the file forms\n\n/**\n * A raw value as text: `,` doubled inside a CX version 1 definition.\n * @param v - the value\n * @returns the text\n */\nfunction defText(v: unknown): string {\n return String(v).replaceAll(\",\", \",,\");\n}\n\n/**\n * A mapping as a CX version 1 definition string.\n * @param m - the mapping\n * @returns the definition\n * @category Styles\n */\nexport function cx1Definition(m: CytoscapeMapping): string {\n const parts = [`COL=${defText(m.column)}`, `T=${m.type ?? \"string\"}`];\n if (m.kind === \"discrete\") {\n m.table.forEach(([k, v], i) => {\n parts.push(`K=${i}=${defText(k)}`, `V=${i}=${defText(v)}`);\n });\n } else if (m.kind === \"continuous\") {\n m.points.forEach((p, i) => {\n parts.push(\n `L=${i}=${defText(p.below)}`,\n `E=${i}=${defText(p.value)}`,\n `G=${i}=${defText(p.above)}`,\n `OV=${i}=${p.at}`,\n );\n });\n }\n return parts.join(\",\");\n}\n\n/**\n * A record of a Map with text keys.\n * @param map - the map\n * @param value - how each value is written\n * @returns the record\n */\nfunction recordOf<V>(map: ReadonlyMap<string, V>, value: (v: V) => unknown): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of map) {\n Object.defineProperty(out, k, { value: value(v), enumerable: true, writable: true, configurable: true });\n }\n return out;\n}\n\n/**\n * A style (in the desktop dialect) as the default entries of a CX version 1 `cyVisualProperties` aspect: `network`,\n * `nodes:default` and `edges:default`, with every value as text and every mapping as a definition string. The\n * writer adds each element's bypasses as `nodes` / `edges` entries.\n * @param style - the style\n * @returns the entries\n * @category Styles\n */\nexport function cytoscapeCxAspect(style: CytoscapeStyle): Record<string, unknown>[] {\n const entry = (of: string, t: CytoscapeStyle[\"node\"]): Record<string, unknown> => ({\n properties_of: of,\n properties: recordOf(t.defaults, String),\n dependencies: recordOf(t.dependencies, String),\n mappings: recordOf(t.mappings, (m) => ({ type: m.kind.toUpperCase(), definition: cx1Definition(m) })),\n });\n return [\n { properties_of: \"network\", properties: recordOf(style.network.defaults, String) },\n entry(\"nodes:default\", style.node),\n entry(\"edges:default\", style.edge),\n ];\n}\n\n/**\n * A continuous mapping's points as CX2 intervals: below the first point, between each two, above the last. The\n * value exactly at a point is the interval that includes it.\n * @param points - the points\n * @returns the intervals\n */\nfunction cx2Intervals(points: readonly CytoscapeContinuousPoint[]): Record<string, unknown>[] {\n const same = (a: unknown, b: unknown): boolean => JSON.stringify(a) === JSON.stringify(b);\n const out: Record<string, unknown>[] = [];\n for (let i = 0; i <= points.length; i++) {\n const lo = points.at(i - 1);\n const hi = points.at(i);\n const iv: Record<string, unknown> = {};\n if (i > 0 && lo !== undefined) {\n iv.min = lo.at;\n iv.minVPValue = lo.above;\n iv.includeMin = same(lo.value, lo.above);\n }\n if (i < points.length && hi !== undefined) {\n iv.max = hi.at;\n iv.maxVPValue = hi.below;\n iv.includeMax = !same(hi.value, hi.above) && same(hi.value, hi.below);\n }\n out.push(iv);\n }\n return out;\n}\n\n/**\n * A style (in the CX2 dialect) as CX2's `visualProperties` and `visualEditorProperties` aspects. The writer adds the\n * bypasses as `nodeBypasses` / `edgeBypasses`.\n * @param style - the style\n * @returns the two aspects\n * @category Styles\n */\nexport function cytoscapeCx2Aspects(style: CytoscapeStyle): {\n /** The `visualProperties` aspect. */\n visualProperties: Record<string, unknown>[];\n /** The `visualEditorProperties` aspect. */\n visualEditorProperties: Record<string, unknown>[];\n} {\n const mapping = (m: CytoscapeMapping): Record<string, unknown> => {\n if (m.kind === \"passthrough\") {\n return { type: \"PASSTHROUGH\", definition: { attribute: m.column } };\n }\n if (m.kind === \"discrete\") {\n return {\n type: \"DISCRETE\",\n definition: { attribute: m.column, map: m.table.map(([v, vp]) => ({ v, vp })) },\n };\n }\n return { type: \"CONTINUOUS\", definition: { attribute: m.column, map: cx2Intervals(m.points) } };\n };\n const id = (v: unknown): unknown => v;\n return {\n visualProperties: [\n {\n default: {\n network: recordOf(style.network.defaults, id),\n node: recordOf(style.node.defaults, id),\n edge: recordOf(style.edge.defaults, id),\n },\n nodeMapping: recordOf(style.node.mappings, mapping),\n edgeMapping: recordOf(style.edge.mappings, mapping),\n },\n ],\n visualEditorProperties: [\n {\n properties: {\n nodeSizeLocked: style.node.dependencies.get(\"nodeSizeLocked\") === true,\n arrowColorMatchesEdge: style.edge.dependencies.get(\"arrowColorMatchesEdge\") === true,\n },\n },\n ],\n };\n}\n\n/**\n * An attribute pair.\n * @param name - the attribute\n * @param value - its value\n * @returns ` name=\"value\"`, escaped\n */\nfunction attr(name: string, value: unknown): string {\n return ` ${name}=\"${escapeXmlAttribute(String(value))}\"`;\n}\n\n/**\n * A style (in the desktop dialect) as one `<visualStyle>` element of a session's `session_vizmap.xml`.\n * @param style - the style\n * @param name - the style's name\n * @returns the element's XML\n * @category Styles\n */\nexport function cytoscapeVizmapXml(style: CytoscapeStyle, name: string): string {\n const lines = [`<visualStyle${attr(\"name\", name)}>`];\n const section = (tag: string, defaults: ReadonlyMap<string, unknown>, t?: CytoscapeStyle[\"node\"]): void => {\n lines.push(` <${tag}>`);\n for (const [dep, on] of t?.dependencies ?? []) {\n lines.push(` <dependency${attr(\"name\", dep)}${attr(\"value\", on)}/>`);\n }\n const vps = new Set([...defaults.keys(), ...(t?.mappings.keys() ?? [])]);\n for (const vp of vps) {\n const d = defaults.has(vp) ? attr(\"default\", defaults.get(vp)) : \"\";\n const m = t?.mappings.get(vp);\n if (m === undefined) {\n lines.push(` <visualProperty${attr(\"name\", vp)}${d}/>`);\n } else {\n lines.push(` <visualProperty${attr(\"name\", vp)}${d}>`, ...mappingXml(m), \" </visualProperty>\");\n }\n }\n lines.push(` </${tag}>`);\n };\n section(\"network\", style.network.defaults);\n section(\"node\", style.node.defaults, style.node);\n section(\"edge\", style.edge.defaults, style.edge);\n lines.push(\"</visualStyle>\");\n return lines.join(\"\\n\");\n}\n\n/**\n * A mapping as the lines of its `session_vizmap.xml` element.\n * @param m - the mapping\n * @returns the lines\n */\nfunction mappingXml(m: CytoscapeMapping): string[] {\n const head = `${attr(\"attributeName\", m.column)}${attr(\"attributeType\", m.kind === \"continuous\" ? \"float\" : (m.type ?? \"string\"))}`;\n if (m.kind === \"passthrough\") {\n return [` <passthroughMapping${head}/>`];\n }\n if (m.kind === \"discrete\") {\n return [\n ` <discreteMapping${head}>`,\n ...m.table.map(\n ([k, v]) => ` <discreteMappingEntry${attr(\"attributeValue\", k)}${attr(\"value\", v)}/>`,\n ),\n \" </discreteMapping>\",\n ];\n }\n return [\n ` <continuousMapping${head}>`,\n ...m.points.map(\n (p) =>\n ` <continuousMappingPoint${attr(\"attrValue\", p.at)}${attr(\"lesserValue\", p.below)}${attr(\"equalValue\", p.value)}${attr(\"greaterValue\", p.above)}/>`,\n ),\n \" </continuousMapping>\",\n ];\n}\n\n// ------------------------------------------------------------------ per-element values\n\n/**\n * The neutral properties a Cytoscape dialect holds per element: what a writer of resolved per-element values (XGMML\n * graphics, a session view's bypasses) can write.\n * @param target - nodes or edges\n * @param dialect - the spelling\n * @returns the properties\n */\nexport function cytoscapeWritableProperties(target: StyleTarget, dialect: CytoscapeDialect): string[] {\n // a label wrapped as Cytoscape wraps it needs nothing written: emitTarget notes any other value\n return [\n ...WRITERS[dialect][target].keys(),\n ...FONT_PROPS,\n ...FIXED[target].keys(),\n ...(target === \"node\" ? [\"labelWrapTrailingSpace\"] : [\"bendCurve\"]),\n ];\n}\n\n/**\n * One element's values as Cytoscape visual properties in a dialect's spelling, for a writer of per-element values.\n * The label font, weight and italic are written together as one font face.\n * @param target - nodes or edges\n * @param value - the element's value of a neutral property, or null\n * @param dialect - the spelling\n * @param approx - called with the property when a value is written as its nearest\n * @returns visual property name to raw value\n */\nexport function cytoscapeElementProperties(\n target: StyleTarget,\n value: (property: string) => StyleValue | null,\n dialect: CytoscapeDialect,\n approx: (property: string) => void,\n): Map<string, unknown> {\n const out = new Map<string, unknown>();\n for (const [p, w] of WRITERS[dialect][target]) {\n const v = value(p);\n if (v !== null) {\n out.set(\n w.vp,\n w.write(v, () => {\n approx(p);\n }),\n );\n }\n }\n const [f, wt, it] = FONT_PROPS.map((p) => value(p));\n if (f !== null || wt !== null || it !== null) {\n out.set(\n FONT_VP[target],\n fontOut(dialect, f, wt, it, () => {\n approx(\"labelFont\");\n }),\n );\n }\n return out;\n}\n","/**\n * Cytoscape desktop's charts (`NODE_CUSTOMGRAPHICS_1` .. `_9` holding `org.cytoscape.PieChart:{...}`,\n * `org.cytoscape.RingChart:{...}`, `BarChart`, `LineChart`, `BoxChart` or `HeatMapChart`), read per node from the\n * node's own data as the neutral `pie*` properties (pie and ring) and `chart*` properties (the others)\n * (https://manual.cytoscape.org/en/stable/Styles.html#using-graphics-in-styles).\n *\n * As Cytoscape 3.10.5 draws them (measured from its own SVG export): each slice is its data column's share of the\n * node's values, the slices run counter-clockwise from `cy_startAngle` degrees counter-clockwise from 3 o'clock,\n * the disc is 0.9 of the node across (of `NODE_CUSTOMGRAPHICS_SIZE_<slot>` with `nodeCustomGraphicsSizeSync` off),\n * and a ring's hole is `cy_holeSize` (default 0.4) of its radius. The same pie\n * drawn clockwise is its slices in reverse order from where the last one ends.\n */\n\nimport { num6 } from \"../canon/number.js\";\nimport type { StyleColumn, StyleValue } from \"../types.js\";\n\n/** How far across the node Cytoscape draws a pie, measured from its SVG export. */\nconst CHART_ACROSS = 0.9;\n\n/** A ring chart's hole when its options name none (Cytoscape's `RingChart` default). */\nconst RING_HOLE = 0.4;\n\n/** The custom graphics slots, in the order Cytoscape stacks them. */\nconst SLOTS = Array.from({ length: 9 }, (_, k) => `NODE_CUSTOMGRAPHICS_${String(k + 1)}`);\n\n/** A chart's options as Cytoscape writes them. */\ninterface ChartOptions {\n readonly cy_colors?: unknown;\n readonly cy_dataColumns?: unknown;\n readonly cy_startAngle?: unknown;\n readonly cy_holeSize?: unknown;\n readonly cy_range?: unknown;\n readonly cy_globalRange?: unknown;\n readonly cy_type?: unknown;\n readonly cy_orientation?: unknown;\n readonly cy_separation?: unknown;\n readonly cy_borderWidth?: unknown;\n readonly cy_borderColor?: unknown;\n readonly cy_lineWidth?: unknown;\n readonly cy_showItemLabels?: unknown;\n readonly cy_itemLabels?: unknown;\n readonly cy_itemLabelsColumn?: unknown;\n readonly cy_itemLabelFontSize?: unknown;\n}\n\n/** The charts Cytoscape draws, by the name of their class. */\ntype ChartKind = \"PieChart\" | \"RingChart\" | \"BarChart\" | \"LineChart\" | \"BoxChart\" | \"HeatMapChart\";\n\n/** A Cytoscape chart class name, without its package. */\nconst CHART_CLASS = /^org\\.cytoscape\\.(PieChart|RingChart|BarChart|LineChart|BoxChart|HeatMapChart)$/;\n\n/**\n * The chart a custom graphics value holds, or null for anything else.\n * @param raw - the value\n * @returns the chart's kind and options\n */\nfunction chartOf(raw: unknown): { kind: ChartKind; ring: boolean; options: ChartOptions } | null {\n // CX2 writes the chart as an object, the desktop, CX and sessions as `<class>:<options as JSON>`\n if (typeof raw === \"object\" && raw !== null && !Array.isArray(raw)) {\n const o = raw as { type?: unknown; name?: unknown; properties?: unknown };\n const kind = CHART_CLASS.exec(typeof o.name === \"string\" ? o.name : \"\")?.[1] as ChartKind | undefined;\n return kind !== undefined && typeof o.properties === \"object\" && o.properties !== null\n ? { kind, ring: kind === \"RingChart\", options: o.properties }\n : null;\n }\n if (typeof raw !== \"string\") {\n return null;\n }\n const m = /^(org\\.cytoscape\\.\\w+):(\\{.*\\})\\s*$/s.exec(raw.trim());\n const kind = m === null ? undefined : (CHART_CLASS.exec(m[1])?.[1] as ChartKind | undefined);\n if (m === null || kind === undefined) {\n return null;\n }\n try {\n const options = JSON.parse(m[2]) as unknown;\n return typeof options === \"object\" && options !== null\n ? { kind, ring: kind === \"RingChart\", options: options }\n : null;\n } catch {\n return null;\n }\n}\n\n/** Where each of Cytoscape's anchors is on a box, as fractions of its half width and half height, y down. */\nconst ANCHORS: Readonly<Record<string, readonly [number, number]>> = {\n C: [0, 0],\n N: [0, -1],\n NE: [1, -1],\n E: [1, 0],\n SE: [1, 1],\n S: [0, 1],\n SW: [-1, 1],\n W: [-1, 0],\n NW: [-1, -1],\n};\n\n/**\n * A custom graphic's position: `NODE_CUSTOMGRAPHICS_POSITION_<slot>` as the desktop writes it\n * (`<node anchor>,<graphic anchor>,<justification>,<x offset>,<y offset>`) or as CX2 does (an object of\n * `ENTITY_ANCHOR`, `GRAPHICS_ANCHOR`, `MARGIN_X`, `MARGIN_Y`).\n * @param raw - the value\n * @returns the anchors and offsets, or null when it does not read\n */\nfunction positionOf(\n raw: unknown,\n): { node: readonly [number, number]; chart: readonly [number, number]; x: number; y: number } | null {\n let parts: [unknown, unknown, unknown, unknown];\n if (typeof raw === \"string\") {\n const p = raw.split(\",\");\n parts = [p[0], p[1], p[3], p[4]];\n } else if (typeof raw === \"object\" && raw !== null) {\n const o = raw as Record<string, unknown>;\n parts = [o.ENTITY_ANCHOR, o.GRAPHICS_ANCHOR, o.MARGIN_X, o.MARGIN_Y];\n } else {\n return null;\n }\n const anchor = (v: unknown): readonly [number, number] | undefined =>\n typeof v === \"string\" ? ANCHORS[v.trim().toUpperCase()] : undefined;\n const [node, chart] = [anchor(parts[0]), anchor(parts[1])];\n const [x, y] = [Number(parts[2] ?? 0), Number(parts[3] ?? 0)];\n return node === undefined || chart === undefined\n ? null\n : { node, chart, x: Number.isFinite(x) ? x : 0, y: Number.isFinite(y) ? y : 0 };\n}\n\n/**\n * A node's values for a chart's data columns: one per column, or the items of a single list column.\n * @param columns - the chart's data columns\n * @param value - reads the node's value of a column\n * @returns the values, NaN where one is not a number\n */\nfunction valuesOf(columns: readonly string[], value: (column: string) => unknown): number[] {\n const first = columns.length === 1 ? value(columns[0]) : undefined;\n const raw = Array.isArray(first) ? (first as unknown[]) : columns.map((c) => value(c));\n return raw.map((v) => (typeof v === \"number\" ? v : Number(v)));\n}\n\n/**\n * Sets each node's `pie*` properties from the first pie or ring chart among its custom graphics.\n * @param out - the node values per property, changed in place\n * @param n - the node count\n * @param graphicOf - a node's resolved value of a custom graphics slot\n * @param value - a node's value of a data column\n * @param sizeSync - whether charts are fitted to their node (`nodeCustomGraphicsSizeSync`, true by default)\n */\nexport function readCytoscapeCharts(\n out: Partial<Record<string, StyleColumn>>,\n n: number,\n graphicOf: (slot: string, i: number) => unknown,\n value: (column: string, i: number) => unknown,\n sizeSync: boolean,\n): void {\n const col = (property: string): (StyleValue | null)[] => {\n const existing = out[property];\n if (existing !== undefined) {\n return existing as (StyleValue | null)[];\n }\n const fresh = new Array<StyleValue | null>(n).fill(null);\n out[property] = fresh;\n return fresh;\n };\n for (let i = 0; i < n; i++) {\n const slot = SLOTS.findIndex((vp) => chartOf(graphicOf(vp, i)) !== null);\n const chart = slot < 0 ? null : chartOf(graphicOf(SLOTS[slot], i));\n if (chart === null) {\n continue;\n }\n const [w, h] = [out.width?.[i], out.height?.[i]];\n chartOnNode(\n chart,\n {\n put: (property, v) => {\n col(property)[i] = v;\n },\n get: (property) => out[property]?.[i],\n graphic: (name) => graphicOf(`${name}_${String(slot + 1)}`, i),\n value: (column) => value(column, i),\n w: typeof w === \"number\" ? w : null,\n h: typeof h === \"number\" ? h : null,\n },\n sizeSync,\n );\n }\n}\n\n/** A node with a chart: what it reads, and where its values go. */\ninterface ChartNode {\n /** sets one of the node's values */\n readonly put: (property: string, v: StyleValue) => void;\n /** one of the node's values as set so far */\n readonly get: (property: string) => StyleValue | null | undefined;\n /** the node's value of one of its chart slot's custom graphics properties, by name without the slot number */\n readonly graphic: (name: string) => unknown;\n /** the node's value of a data column */\n readonly value: (column: string) => unknown;\n /** the node's width, or null when it is not a number */\n readonly w: number | null;\n /** the node's height, or null when it is not a number */\n readonly h: number | null;\n}\n\n/**\n * A node's shorter side, when its width and height are known.\n * @param node - the node\n * @returns the side, or null\n */\nfunction shorterSide(node: ChartNode): number | null {\n return node.w !== null && node.h !== null ? Math.min(node.w, node.h) : null;\n}\n\n/**\n * Sets a node's `pie*` or `chart*` properties from its chart.\n * @param chart - the chart\n * @param chart.kind - its class\n * @param chart.ring - whether it is a ring\n * @param chart.options - its options\n * @param node - the node\n * @param sizeSync - whether charts are fitted to their node\n */\nfunction chartOnNode(\n chart: { kind: ChartKind; ring: boolean; options: ChartOptions },\n node: ChartNode,\n sizeSync: boolean,\n): void {\n const { options } = chart;\n const colors = Array.isArray(options.cy_colors) ? options.cy_colors.map(String) : [];\n const columns = Array.isArray(options.cy_dataColumns) ? options.cy_dataColumns.map(String) : [];\n const values = valuesOf(columns, node.value);\n if (chart.kind === \"PieChart\" || chart.kind === \"RingChart\") {\n pieOnNode(chart.ring, options, values, colors, node, sizeSync);\n return;\n }\n const own = Number(node.graphic(\"NODE_CUSTOMGRAPHICS_SIZE\"));\n const side = shorterSide(node);\n const ownSize = own > 0;\n const fitted = sizeSync || !ownSize;\n const box = side === null ? null : { disc: CHART_ACROSS * (fitted ? side : own), side };\n for (const [property, v] of Object.entries(plotChart(chart.kind, options, values, colors, box))) {\n node.put(property, v);\n }\n}\n\n/**\n * Each slice of a pie: a value above 0 with a color, its share of the values above 0.\n * @param values - the node's values\n * @param colors - the chart's colors\n * @returns the slices in order\n */\nfunction pieSlices(values: readonly number[], colors: readonly string[]): { color: string; size: number }[] {\n const total = values.reduce((sum, v) => sum + (Number.isFinite(v) && v > 0 ? v : 0), 0);\n return values.flatMap((v, k) =>\n Number.isFinite(v) && v > 0 && colors[k] !== undefined\n ? [{ color: colors[k].toLowerCase(), size: v / total }]\n : [],\n );\n}\n\n/**\n * Sets a node's `pie*` properties from a pie or ring chart.\n * @param ring - whether it is a ring\n * @param options - the chart's options\n * @param values - the node's values\n * @param colors - the chart's colors\n * @param node - the node\n * @param sizeSync - whether charts are fitted to their node\n */\nfunction pieOnNode(\n ring: boolean,\n options: ChartOptions,\n values: readonly number[],\n colors: readonly string[],\n node: ChartNode,\n sizeSync: boolean,\n): void {\n const slices = pieSlices(values, colors);\n if (slices.length === 0) {\n return;\n }\n const start = Number(options.cy_startAngle ?? 0);\n const from = Number.isFinite(start) ? start : 0;\n // counter-clockwise from `start` past 3 o'clock is clockwise from 12 o'clock at 90 - start, slices reversed\n const reversed = [...slices].reverse();\n node.put(\"pieColors\", reversed.map((s) => s.color).join(\" \"));\n node.put(\"pieSizes\", reversed.map((s) => String(num6(s.size))).join(\" \"));\n // fitted to the node, or with `nodeCustomGraphicsSizeSync` off at the slot's own size\n const own = Number(node.graphic(\"NODE_CUSTOMGRAPHICS_SIZE\"));\n const side = shorterSide(node);\n const ownSize = own > 0;\n const fitted = sizeSync || !ownSize || side === null || side <= 0;\n node.put(\"pieRadius\", fitted ? CHART_ACROSS : num6((CHART_ACROSS * own) / side));\n pieOffset(node, fitted, own);\n node.put(\"pieRotation\", num6((((90 - from) % 360) + 360) % 360));\n const texts = pieItemLabels(options, values, colors, node.value, {\n start: from,\n radius: (CHART_ACROSS * (fitted || side === null ? 1 : own / side) * (side ?? 0)) / 2,\n dx: Number(node.get(\"pieOffsetX\") ?? 0),\n dy: Number(node.get(\"pieOffsetY\") ?? 0),\n w: node.w,\n h: node.h,\n });\n if (texts !== null && (node.get(\"shapeTexts\") ?? null) === null) {\n node.put(\"shapeTexts\", texts);\n }\n if (ring) {\n const hole = Number(options.cy_holeSize ?? RING_HOLE);\n node.put(\"pieHole\", Number.isFinite(hole) ? Math.max(0, Math.min(1, hole)) : RING_HOLE);\n }\n}\n\n/**\n * A pie's offset from its node's center, as Cytoscape 3.10.5 draws a chart's position (measured from its SVG export\n * of the specimen sheets, every anchor pair they hold, fitted and at a size of its own): the node anchor scales by\n * the drawn disc and the chart anchor by the node, so on a 60 node NW,NW moves a fitted 54 disc 3 px down and right\n * and a 21.6 disc 19 px, C,NW puts either one's center 30 px down and right, and E,W puts a fitted disc 57 px right;\n * then the position's offsets (y down).\n * @param node - the node\n * @param fitted - whether the pie is fitted to the node\n * @param own - the slot's own size\n */\nfunction pieOffset(node: ChartNode, fitted: boolean, own: number): void {\n const at = positionOf(node.graphic(\"NODE_CUSTOMGRAPHICS_POSITION\"));\n const { w, h } = node;\n if (at === null || w === null || h === null) {\n return;\n }\n const disc = CHART_ACROSS * (fitted ? Math.min(w, h) : own);\n const dx = (at.node[0] * disc) / 2 - (at.chart[0] * w) / 2 + at.x;\n const dy = (at.node[1] * disc) / 2 - (at.chart[1] * h) / 2 + at.y;\n if (dx !== 0 || dy !== 0) {\n node.put(\"pieOffsetX\", num6(dx));\n node.put(\"pieOffsetY\", num6(dy));\n }\n}\n\n/**\n * Where Cytoscape's pie draws an item label: centered on its slice's middle, this share of the radius out (measured\n * from its SVG export of xgmml-specimen-images-charts-p5 and -p7: 16.4 to 17.3 px from the center of a 27.2 px disc,\n * at 1, 10 and 20 px).\n */\nconst ITEM_LABEL_RADIUS = 0.62;\n\n/**\n * The size of a chart's item labels, in the file's lengths, when its options name none: Cytoscape 3.10.5 draws them 1\n * px tall (xgmml-specimen-images-charts-p5 `pie-item-labels`).\n */\nconst ITEM_LABEL_FONT_SIZE = 1;\n\n/** The color JFreeChart draws Cytoscape's chart labels in. */\nconst CHART_LABEL_COLOR = \"#404040\";\n\n/**\n * A chart's item labels: `cy_itemLabels`, or the node's list in `cy_itemLabelsColumn`, one per data column; none\n * unless `cy_showItemLabels` is on.\n * @param options - the chart's options\n * @param value - reads the node's value of a column\n * @returns the labels, or null\n */\nfunction itemLabelsOf(options: ChartOptions, value: (column: string) => unknown): string[] | null {\n if (options.cy_showItemLabels !== true) {\n return null;\n }\n const column = typeof options.cy_itemLabelsColumn === \"string\" ? value(options.cy_itemLabelsColumn) : undefined;\n const list = Array.isArray(column) ? column : options.cy_itemLabels;\n return Array.isArray(list) ? list.map((v) => (v === null || v === undefined ? \"\" : String(v))) : null;\n}\n\n/**\n * A pie's or a ring's item labels as the node's further texts (`shapeTexts`), as Cytoscape 3.10.5 draws them\n * (measured from its SVG export of the specimen sheets): each slice's label centered on the middle of its slice, a\n * share of the disc's radius out from its center, in `cy_itemLabelFontSize` (the file's lengths) and JFreeChart's\n * dark gray.\n * @param options - the chart's options\n * @param values - the node's values, one per data column\n * @param colors - the chart's colors, one per data column\n * @param value - reads the node's value of a column\n * @param at - where the disc is: its start angle (degrees counter-clockwise from 3 o'clock), radius and offset from\n * the node's center (y down), and the node's width and height\n * @param at.start - start angle\n * @param at.radius - the disc's radius\n * @param at.dx - offset right\n * @param at.dy - offset down\n * @param at.w - the node's width\n * @param at.h - the node's height\n * @returns the texts as JSON, or null for none\n */\nfunction pieItemLabels(\n options: ChartOptions,\n values: readonly number[],\n colors: readonly string[],\n value: (column: string) => unknown,\n at: { start: number; radius: number; dx: number; dy: number; w: number | null; h: number | null },\n): string | null {\n const labels = itemLabelsOf(options, value);\n const { w, h } = at;\n if (labels === null || w === null || h === null) {\n return null;\n }\n // a size that is not a number, like one of 0, draws nothing\n const drawn = w > 0 && h > 0 && at.radius > 0;\n if (!drawn) {\n return null;\n }\n const shown = values.map((v, k) => Number.isFinite(v) && v > 0 && colors[k] !== undefined);\n const total = values.reduce((sum, v, k) => sum + (shown[k] ? v : 0), 0);\n const size = Number(options.cy_itemLabelFontSize ?? ITEM_LABEL_FONT_SIZE);\n const texts: [number, number, string, { size: number; color: string }][] = [];\n let from = at.start;\n values.forEach((v, k) => {\n if (!shown[k]) {\n return;\n }\n const sweep = (360 * v) / total;\n const mid = ((from + sweep / 2) * Math.PI) / 180;\n from += sweep;\n const text = labels[k] ?? \"\";\n if (text === \"\") {\n return;\n }\n // counter-clockwise from 3 o'clock, y up in the node's frame\n const x = at.dx + ITEM_LABEL_RADIUS * at.radius * Math.cos(mid);\n const y = -at.dy + ITEM_LABEL_RADIUS * at.radius * Math.sin(mid);\n texts.push([\n num6(x / (w / 2)),\n num6(y / (h / 2)),\n text,\n {\n size: num6((Number.isFinite(size) && size > 0 ? size : ITEM_LABEL_FONT_SIZE) / h),\n color: CHART_LABEL_COLOR,\n },\n ]);\n });\n return texts.length === 0 ? null : JSON.stringify(texts);\n}\n\n/** How many of the file's lengths one of Cytoscape's chart units is: it draws a chart at twice the node's scale. */\nconst CHART_UNIT = 0.5;\n\n/**\n * How far in from the disc a pie would fill Cytoscape draws a chart's plot, in the file's lengths, measured from its\n * SVG export of the specimen sheets (60 nodes): the chart's own box is 0.9 of the node less 0.9, its plot 1 less\n * again, a heat map's 2 less.\n */\nconst CHART_INSET = 0.9;\nconst PLOT_INSET = 1;\nconst HEAT_MAP_INSET = 2;\n\n/** The default outline Cytoscape draws round each bar and box, in chart units: JFreeChart's dark gray, a quarter wide. */\nconst BAR_OUTLINE = { color: \"#404040\", width: 0.25 };\n\n/** How much of the category side JFreeChart leaves at each end of a bar and a box chart, and of a line chart. */\nconst BAR_MARGIN = 0.025;\nconst LINE_MARGIN = -0.0125;\n\n/** The share of its range JFreeChart adds above a line chart's, and above an automatic range's top. */\nconst RANGE_HEADROOM = 0.1;\n\n/**\n * A color between two `#rrggbb` colors, each channel rounded, as Cytoscape interpolates a heat map's.\n * @param a - the color at 0\n * @param b - the color at 1\n * @param t - how far, 0..1\n * @returns the color\n */\nfunction mix(a: string, b: string, t: number): string {\n const rgb = (c: string): number[] => [1, 3, 5].map((k) => Number.parseInt(c.slice(k, k + 2), 16));\n const [x, y] = [rgb(a), rgb(b)];\n if ([...x, ...y].some((v) => !Number.isFinite(v))) {\n return a;\n }\n const u = Math.max(0, Math.min(1, t));\n return `#${x\n .map((v, k) =>\n Math.round(v + (y[k] - v) * u)\n .toString(16)\n .padStart(2, \"0\"),\n )\n .join(\"\")}`;\n}\n\n/**\n * A value's color on Cytoscape's three-color scale (`[up, zero, down]`): from the zero color toward the up color as\n * the value nears the top of the range, toward the down color as it nears the bottom (`cy-heat-map`: 5 of 0..10\n * half way from #F7F7F7 to #2166AC).\n * @param colors - the three colors\n * @param v - the value\n * @param range - the range\n * @returns the color\n */\nfunction scaleColor(colors: readonly string[], v: number, range: readonly [number, number]): string {\n const [up, zero, down] = [colors[0], colors[1] ?? colors[0], colors[2] ?? colors[0]];\n if (v >= 0) {\n return mix(zero, up, range[1] > 0 ? v / range[1] : 0);\n }\n return mix(zero, down, range[0] < 0 ? v / range[0] : 0);\n}\n\n/**\n * The quartiles, median and whiskers JFreeChart draws a box chart's values as (`BoxAndWhiskerCalculator`): the\n * quartiles are the medians of each half, the middle value in both halves of an odd count; each whisker reaches the\n * furthest value within 1.5 times the quartiles' spread.\n * @param values - the values\n * @returns low whisker, lower quartile, median, upper quartile, high whisker\n */\nfunction boxStats(values: readonly number[]): number[] {\n const v = [...values].sort((a, b) => a - b);\n const median = (list: readonly number[]): number => {\n const m = list.length / 2;\n return list.length % 2 === 1 ? list[Math.floor(m)] : (list[m - 1] + list[m]) / 2;\n };\n const half = Math.ceil(v.length / 2);\n const [q1, q3] = [median(v.slice(0, half)), median(v.slice(v.length - half))];\n const reach = 1.5 * (q3 - q1);\n const inside = v.filter((x) => x >= q1 - reach && x <= q3 + reach);\n // never empty: the middle values lie between the quartiles\n return [inside[0], q1, median(v), q3, inside.at(-1) ?? q3];\n}\n\n/**\n * How large a chart's plot is drawn: inside the disc a pie fills, as a share of the node.\n * @param kind - the chart's class\n * @param box - the pie's width and the node's shorter side, or null when the node's size is unknown\n * @returns `chartSize`, or nothing when the node's size is unknown\n */\nfunction plotSize(\n kind: Exclude<ChartKind, \"PieChart\" | \"RingChart\">,\n box: { disc: number; side: number } | null,\n): Record<string, StyleValue> {\n const sized = box !== null && box.side > 0;\n if (!sized) {\n return {};\n }\n // ponytail: the insets are measured on 60 nodes only; whether they scale with the node is not known\n const inset = CHART_INSET + (kind === \"HeatMapChart\" ? HEAT_MAP_INSET : PLOT_INSET);\n return { chartSize: num6(Math.max(0, box.disc - inset) / box.side) };\n}\n\n/**\n * The outline Cytoscape draws round each bar and box.\n * @param options - the chart's options\n * @returns `chartBorderColor` and `chartBorderWidth`\n */\nfunction chartOutline(options: ChartOptions): Record<string, StyleValue> {\n const color = typeof options.cy_borderColor === \"string\" ? options.cy_borderColor : BAR_OUTLINE.color;\n return {\n chartBorderColor: color.toLowerCase(),\n chartBorderWidth: num6(CHART_UNIT * (Number(options.cy_borderWidth ?? BAR_OUTLINE.width) || 0)),\n };\n}\n\n/**\n * A bar chart's own properties: grouped, stacked, up and down (the first color up, the last down) or heat strips\n * (each bar colored on the three-color scale).\n * @param options - its options\n * @param finite - the node's values that are numbers\n * @param colors - its colors\n * @param range - its range\n * @param horizontal - whether its orientation is horizontal\n * @returns the properties\n */\nfunction barChart(\n options: ChartOptions,\n finite: readonly number[],\n colors: readonly string[],\n range: readonly [number, number],\n horizontal: boolean,\n): Record<string, StyleValue> {\n const type = typeof options.cy_type === \"string\" ? options.cy_type : \"GROUPED\";\n const stacked = type === \"STACKED\";\n return {\n chartKind: stacked ? \"stacked-bar\" : \"bar\",\n chartValues: finite.join(\" \"),\n chartColors: finite.map((v, k) => barColor(type, colors, v, k, range)).join(\" \"),\n chartMin: range[0],\n chartMax: range[1],\n // Cytoscape lays a stacked bar's values across the node when its orientation says up\n chartHorizontal: stacked ? !horizontal : horizontal,\n chartMargin: BAR_MARGIN,\n chartGap: num6(Math.max(0, Math.min(1, Number(options.cy_separation ?? 0) || 0))),\n };\n}\n\n/**\n * One bar's color.\n * @param type - the bar chart's type\n * @param colors - its colors\n * @param v - the bar's value\n * @param k - the bar's place\n * @param range - the chart's range\n * @returns the color\n */\nfunction barColor(\n type: string,\n colors: readonly string[],\n v: number,\n k: number,\n range: readonly [number, number],\n): string {\n if (type === \"HEAT_STRIPS\") {\n return scaleColor(colors, v, range);\n }\n if (type === \"UP_DOWN\") {\n return colors[v >= 0 ? 0 : colors.length - 1].toLowerCase();\n }\n return colors[Math.min(k, colors.length - 1)].toLowerCase();\n}\n\n/**\n * A bar, line, box or heat map chart as the neutral `chart*` properties, as Cytoscape 3.10.5 draws it (measured from\n * its own SVG export of the specimen sheets: JFreeChart plots in a square box inset from the disc a pie fills).\n * @param kind - the chart's class\n * @param options - its options\n * @param values - the node's values for its data columns\n * @param colors - its colors\n * @param box - how far across a pie would be drawn on the node and the node's shorter side, in the file's lengths;\n * null when the node's size is unknown\n * @param box.disc - the pie's width\n * @param box.side - the node's shorter side\n * @returns the properties to set\n */\nfunction plotChart(\n kind: Exclude<ChartKind, \"PieChart\" | \"RingChart\">,\n options: ChartOptions,\n values: readonly number[],\n colors: readonly string[],\n box: { disc: number; side: number } | null,\n): Record<string, StyleValue> {\n const finite = values.filter((v) => Number.isFinite(v));\n if (finite.length === 0 || colors.length === 0) {\n // ponytail: a chart colored by a named scheme (cy_colorScheme) without its colors is not drawn\n return {};\n }\n const given = Array.isArray(options.cy_range) ? options.cy_range.map(Number) : [];\n const global = options.cy_globalRange !== false && given.length === 2 && given.every((v) => Number.isFinite(v));\n // an automatic range holds zero and the values, with headroom above\n const auto: [number, number] = [Math.min(0, ...finite), Math.max(0, ...finite)];\n auto[1] += RANGE_HEADROOM * (auto[1] - auto[0]);\n const range: [number, number] = global ? [given[0], given[1]] : auto;\n const horizontal = options.cy_orientation === \"HORIZONTAL\";\n const out: Record<string, StyleValue> = plotSize(kind, box);\n const outline = chartOutline(options);\n switch (kind) {\n case \"BarChart\":\n Object.assign(out, outline, barChart(options, finite, colors, range, horizontal));\n break;\n case \"LineChart\":\n // drawn up the node whatever its orientation, with headroom above its range\n Object.assign(out, {\n chartKind: \"line\",\n chartValues: finite.join(\" \"),\n chartColors: colors[0].toLowerCase(),\n chartMin: range[0],\n chartMax: num6(range[1] + (global ? RANGE_HEADROOM * (range[1] - range[0]) : 0)),\n chartMargin: LINE_MARGIN,\n chartLineWidth: num6(CHART_UNIT * (Number(options.cy_lineWidth ?? 1) || 0)),\n });\n break;\n case \"BoxChart\":\n Object.assign(out, outline, {\n chartKind: \"box\",\n chartValues: boxStats(finite).map(num6).join(\" \"),\n chartColors: `${colors[0].toLowerCase()} #000000`,\n chartMin: range[0],\n chartMax: range[1],\n chartHorizontal: horizontal,\n chartMargin: BAR_MARGIN,\n chartLineWidth: num6(CHART_UNIT * BAR_OUTLINE.width),\n });\n break;\n case \"HeatMapChart\": {\n // one cell per value, top to bottom; laid left to right, the last value first\n const cells = horizontal ? [...finite].reverse() : finite;\n Object.assign(out, {\n chartKind: \"cells\",\n chartValues: cells.join(\" \"),\n chartColors: cells.map((v) => scaleColor(colors, v, range)).join(\" \"),\n chartHorizontal: !horizontal,\n });\n break;\n }\n default:\n break;\n }\n return out;\n}\n","/**\n * Cytoscape's own resolution of a visual style, per element: a bypass over a mapping over a default, per visual\n * property, with the dependencies applied (`nodeSizeLocked` makes `NODE_SIZE` drive width and height,\n * `arrowColorMatchesEdge` makes the edge's paint drive the line and both arrows). Every pass is linear in the number\n * of elements plus the size of the style, and spends from the extraction's one budget.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { num6 } from \"../canon/number.js\";\nimport { type CanonSite, noteAt } from \"../canon/site.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport { toolDefaults } from \"../defaults.js\";\nimport { StyleNotes } from \"../notes.js\";\nimport { discreteLookup, evalContinuous, numberOf } from \"../plan/resolve.js\";\nimport type {\n ContinuousPoint,\n Scalar,\n StyleColor,\n StyleColumn,\n StyleTarget,\n StyleTool,\n StyleValue,\n StyleWorkBudget,\n} from \"../types.js\";\nimport { isStyleValue } from \"../vocabulary.js\";\nimport { readCytoscapeCharts } from \"./charts.js\";\nimport {\n arrowGap,\n arrowProportion,\n arrowSizeParser,\n colorParser,\n CYTOSCAPE_LEXICON,\n cytoscapeLabelBase,\n cytoscapeLabelMove,\n type CytoscapeLabelPlace,\n cytoscapeLabelPlace,\n type CytoscapeValueParser,\n halfBack,\n isUncarriedVp,\n NODE_SIZE_VP,\n opacityParser,\n sizeParser,\n vpStep,\n} from \"./lexicon.js\";\nimport {\n type CytoscapeContinuousPoint,\n type CytoscapeMapping,\n type CytoscapeStyle,\n type CytoscapeTargetStyle,\n emptyCytoscapeStyle,\n} from \"./mappings.js\";\n\n/**\n * One element's bypasses: visual property name to raw value; null or undefined when it has none.\n * @category Styles\n */\nexport type CytoscapeBypass = ReadonlyMap<string, unknown> | null | undefined;\n\n/**\n * The elements of one target a style is resolved over.\n * @category Styles\n */\nexport interface CytoscapeElements {\n /** How many elements there are. */\n readonly count: number;\n /**\n * An element's value of an attribute column (a list attribute as an array), or null.\n * @param column - the column's name\n * @param i - the element index\n * @returns the value\n */\n value(column: string, i: number): unknown;\n /** Each element's bypasses, by element index. */\n readonly bypasses?: readonly CytoscapeBypass[];\n /**\n * Edges only: each edge's source and target node index, in the order Cytoscape created the edges. With them,\n * the edges Cytoscape desktop fans apart (parallel edges without bends) are marked curved; with `nodeSize` too\n * (each node's larger drawn side, by node index, as `fanNodeSizes()` reads it), they are given the `fanSpacing`\n * desktop spaces them by. With `nodeBox` (each node's width, height and border width, by node index), each\n * self-loop without bends is given the two handles desktop draws it round.\n */\n readonly ends?: {\n readonly source: ArrayLike<number>;\n readonly target: ArrayLike<number>;\n readonly nodeSize?: ArrayLike<number | null>;\n readonly nodeBox?: ArrayLike<readonly [width: number, height: number, border: number] | null>;\n /** Each node's center on screen, x right and y down, by node index: what an edge's label is placed by. */\n readonly nodeAt?: ArrayLike<readonly [x: number, y: number] | null>;\n /**\n * The order Cytoscape desktop creates the file's nodes and edges in, when it is not the file's (its CX reader\n * creates them in hash order): each element's rank, lower first, by index. With it, `nodeAt` and `nodeSize`,\n * each fanned edge is given desktop's own anchor as its bend, so it bows to the side desktop draws it on.\n */\n readonly created?: { readonly node: ArrayLike<number>; readonly edge: ArrayLike<number> };\n };\n}\n\n/**\n * Options of `resolveCytoscape()`.\n * @category Styles\n */\nexport interface CytoscapeResolveOptions {\n /** Where problems are noted. */\n readonly notes?: StyleNotes;\n /** The counted work budget. */\n readonly budget?: StyleWorkBudget;\n /**\n * Whose defaults fill what the style leaves unset: `\"cytoscape\"` (the desktop's default visual style, for CX,\n * CX2 and XGMML), `\"cytoscape-fallbacks\"` (the renderer's fallbacks, for sessions) or null for none, so an\n * element the style says nothing about is null. Defaults to null.\n */\n readonly defaults?: StyleTool | null;\n /** `resolveCytoscapeBypasses()` only: the edges' ends, as `CytoscapeElements.ends`. */\n readonly ends?: CytoscapeElements[\"ends\"];\n /**\n * `resolveCytoscapeBypasses()` only: an element's value of an attribute column, as `CytoscapeElements.value`,\n * for what is drawn from the element's data (a chart's values); without it no element has any.\n */\n readonly value?: CytoscapeElements[\"value\"];\n}\n\n/** How closely desktop stacks the edges it fans, 0..1: its anchors are twice this times the node size apart. */\nconst EDGE_STACKING_DENSITY_VP = \"EDGE_STACKING_DENSITY\";\n/** How desktop draws parallel edges: AUTO_BEND (the default) fans them, HAYSTACK draws them straight. */\nconst EDGE_STACKING_VP = \"EDGE_STACKING\";\n/** Whether an edge's label is turned along its line. */\nconst AUTOROTATE_VP = \"EDGE_LABEL_AUTOROTATE\";\n\n/**\n * A map without one key.\n * @param m - the map\n * @param key - the key left out\n * @returns a copy without it\n */\nfunction withoutKey(m: ReadonlyMap<string, unknown>, key: string): ReadonlyMap<string, unknown> {\n return new Map([...m].filter(([k]) => k !== key));\n}\n/** Desktop's `EDGE_STACKING_DENSITY` default. */\nconst EDGE_STACKING_DENSITY_DEFAULT = 0.5;\n\n/**\n * A graph's edge ends for `CytoscapeElements.ends`, with each node's larger side from the nodes' resolved `width`\n * and `height`: what desktop spaces the edges it fans between two nodes by.\n * @param snapshot - the graph\n * @param nodes - the nodes' values per property\n * @returns the ends\n */\nexport function edgeEnds(\n snapshot: GraphSnapshot,\n nodes: Partial<Record<string, StyleColumn>>,\n): NonNullable<CytoscapeElements[\"ends\"]> {\n const nodeSize = Array.from({ length: snapshot.nodeCount }, (_, i) => {\n const sides = [nodes.width?.[i], nodes.height?.[i]].filter((v): v is number => typeof v === \"number\");\n return sides.length === 0 ? null : Math.max(...sides);\n });\n const nodeBox = Array.from({ length: snapshot.nodeCount }, (_, i) => {\n const [w, h, b] = [nodes.width?.[i], nodes.height?.[i], nodes.borderWidth?.[i]];\n return typeof w === \"number\" && typeof h === \"number\" ? ([w, h, typeof b === \"number\" ? b : 0] as const) : null;\n });\n const position = snapshot.nodes.byRole(\"position\");\n // stored y up unless the column says otherwise; the label places are worked out y down, as Cytoscape draws\n const down = (position?.meta.extra as { yAxis?: string } | undefined)?.yAxis === \"down\";\n const nodeAt = Array.from({ length: snapshot.nodeCount }, (_, i) => {\n const v = position?.isSet(i) === true ? (position.value(i) as ArrayLike<number>) : null;\n return v === null ? null : ([v[0], down ? v[1] : -v[1]] as const);\n });\n const { src, dst } = snapshot.edgeList();\n return { source: src, target: dst, nodeSize, nodeBox, nodeAt };\n}\n\n/** Locked node sizes with no `NODE_SIZE` anywhere draw at Cytoscape's lexicon default. */\nconst NODE_SIZE_FALLBACK = 50;\n\n/**\n * The visual property whose bypass each one takes when an element does not bypass it itself: Cytoscape desktop locks\n * a bypassed parent's children too, so a session's `NODE_PAINT` bypass paints the fill and the border, a `NODE_SIZE`\n * bypass sizes the node whatever `nodeSizeLocked` says, and an `EDGE_PAINT` or `EDGE_UNSELECTED_PAINT` bypass paints\n * the line and its arrows (Cytoscape 3.10.5's SVG of the session specimen sheets `node-fills-borders`,\n * `node-sizes-opacity` and `edges-lines`).\n */\nconst LOCK_PARENT: ReadonlyMap<string, string> = new Map([\n [\"NODE_FILL_COLOR\", \"NODE_PAINT\"],\n [\"NODE_BORDER_PAINT\", \"NODE_PAINT\"],\n [\"NODE_WIDTH\", \"NODE_SIZE\"],\n [\"NODE_HEIGHT\", \"NODE_SIZE\"],\n [\"EDGE_UNSELECTED_PAINT\", \"EDGE_PAINT\"],\n [\"EDGE_STROKE_UNSELECTED_PAINT\", \"EDGE_UNSELECTED_PAINT\"],\n [\"EDGE_SOURCE_ARROW_UNSELECTED_PAINT\", \"EDGE_UNSELECTED_PAINT\"],\n [\"EDGE_TARGET_ARROW_UNSELECTED_PAINT\", \"EDGE_UNSELECTED_PAINT\"],\n]);\n\n/**\n * An element's bypass of a visual property: its own, else the nearest bypassed parent's (`LOCK_PARENT`).\n * @param b - the element's bypasses\n * @param vp - the visual property\n * @returns the bypass value, or undefined\n */\nfunction lockedValue(b: NonNullable<CytoscapeBypass>, vp: string): unknown {\n for (let p: string | undefined = vp; p !== undefined; p = LOCK_PARENT.get(p)) {\n const v = b.get(p);\n if (v !== undefined && v !== null) {\n return v;\n }\n }\n return undefined;\n}\n\n/** A visual property and the parser that reads it for one neutral property. */\ntype VpChoice = readonly [vp: string, parse: CytoscapeValueParser];\n\n/**\n * Which visual properties a style or its bypasses mention.\n * @param style - the target's style\n * @param bypasses - the elements' bypasses\n * @returns the names used anywhere, and those used by a bypass\n */\nexport function vpUsage(\n style: CytoscapeTargetStyle,\n bypasses: readonly CytoscapeBypass[],\n): { used: Set<string>; bypassed: Set<string> } {\n const bypassed = new Set<string>();\n for (const b of bypasses) {\n if (b) {\n for (const k of b.keys()) {\n bypassed.add(k);\n }\n }\n }\n for (const [from, to] of style.bypassAliases) {\n if (bypassed.has(from)) {\n bypassed.add(to);\n }\n }\n // a bypassed parent bypasses its children (LOCK_PARENT lists a parent's own entry before its children's)\n for (const [child, parent] of LOCK_PARENT) {\n if (bypassed.has(parent)) {\n bypassed.add(child);\n }\n }\n const used = new Set([...style.defaults.keys(), ...style.mappings.keys(), ...bypassed]);\n return { used, bypassed };\n}\n\n/**\n * Which visual property sets each neutral property: the first of its lexicon list the style or any bypass\n * mentions, with the dependencies applied.\n * @param target - nodes or edges\n * @param style - the target's style\n * @param used - the visual properties used anywhere\n * @returns property to its visual property and parser\n */\nexport function chooseVps(\n target: StyleTarget,\n style: CytoscapeTargetStyle,\n used: ReadonlySet<string>,\n): Map<string, VpChoice> {\n const chosen = new Map<string, VpChoice>();\n for (const [prop, list] of CYTOSCAPE_LEXICON[target]) {\n const hit = list.find(([vp]) => used.has(vp));\n if (hit !== undefined) {\n chosen.set(prop, hit);\n }\n }\n if (target === \"node\" && style.dependencies.get(\"nodeSizeLocked\") === true) {\n chosen.delete(\"width\");\n chosen.delete(\"height\");\n }\n if (target === \"edge\" && style.dependencies.get(\"arrowColorMatchesEdge\") === true) {\n // the line is EDGE_UNSELECTED_PAINT's, not the stroke's, even where the style sets only the stroke\n if (used.has(\"EDGE_UNSELECTED_PAINT\") || used.has(\"EDGE_STROKE_UNSELECTED_PAINT\")) {\n chosen.set(\"color\", [\"EDGE_UNSELECTED_PAINT\", colorParser]);\n }\n chosen.delete(\"sourceArrowColor\");\n chosen.delete(\"targetArrowColor\");\n }\n return chosen;\n}\n\n/**\n * A mapping with its values read for one property.\n * @category Styles\n */\nexport type ParsedMapping =\n | { readonly kind: \"passthrough\"; readonly column: string }\n | { readonly kind: \"discrete\"; readonly column: string; readonly table: readonly (readonly [Scalar, StyleValue])[] }\n | {\n readonly kind: \"continuous\";\n readonly column: string;\n readonly points: readonly ContinuousPoint[];\n /** The step Cytoscape rounds a value to, for an integer visual property. */\n readonly step?: number;\n };\n\n/**\n * Reads a mapping's raw values with a property's parser: table entries and points whose values do not parse are\n * dropped (and noted), points are sorted, and of two points at the same value the later one wins.\n * @param m - the mapping\n * @param parse - the property's parser\n * @param site - where problems are noted\n * @param vp - the visual property it sets, whose type decides whether an interpolated value is rounded\n * @returns the mapping with canonical values\n */\nexport function parseMapping(\n m: CytoscapeMapping,\n parse: CytoscapeValueParser,\n site: CanonSite,\n vp: string,\n): ParsedMapping {\n switch (m.kind) {\n case \"passthrough\":\n return { kind: \"passthrough\", column: m.column };\n case \"discrete\": {\n const table: [Scalar, StyleValue][] = [];\n for (const [k, raw] of m.table) {\n const v = parse(raw, site);\n if (v !== null) {\n table.push([k, v]);\n }\n }\n return { kind: \"discrete\", column: m.column, table };\n }\n default: {\n const step = vpStep(vp);\n const points = parsePoints(m.points, parse, site);\n return { kind: \"continuous\", column: m.column, points, ...(step === undefined ? {} : { step }) };\n }\n }\n}\n\n/**\n * A continuous mapping's points with canonical values: points whose values do not parse are dropped (and noted),\n * points are sorted, and of two points at the same value the later one wins.\n * @param raw - the points\n * @param parse - the property's parser\n * @param site - where problems are noted\n * @returns the points\n */\nfunction parsePoints(\n raw: readonly CytoscapeContinuousPoint[],\n parse: CytoscapeValueParser,\n site: CanonSite,\n): ContinuousPoint[] {\n const parsed: ContinuousPoint[] = [];\n for (const p of raw) {\n const below = parse(p.below, site);\n const value = parse(p.value, site);\n const above = parse(p.above, site);\n if (below !== null && value !== null && above !== null) {\n parsed.push({ at: p.at, below, value, above });\n }\n }\n parsed.sort((a, b) => a.at - b.at);\n const points: ContinuousPoint[] = [];\n for (const p of parsed) {\n if (points.at(-1)?.at === p.at) {\n points[points.length - 1] = p;\n } else {\n points.push(p);\n }\n }\n return points;\n}\n\n/**\n * One mapping evaluated for one element's attribute value.\n * @param m - the parsed mapping\n * @param value - the element's value\n * @param parse - the property's parser, for a passthrough\n * @param site - where problems are noted\n * @returns the value, or null when the mapping gives none\n */\nfunction evalMapping(\n m: ParsedMapping,\n value: unknown,\n parse: CytoscapeValueParser,\n site: CanonSite,\n): StyleValue | null {\n if (value === null || value === undefined) {\n return null;\n }\n switch (m.kind) {\n case \"passthrough\":\n return Array.isArray(value) ? null : parse(value, site);\n case \"discrete\": {\n const j = discreteLookup(m.table)(value);\n return j < 0 ? null : m.table[j][1];\n }\n default:\n return evalContinuous(m.points, numberOf(value), m.step);\n }\n}\n\n/** The resolver of one target: reads one visual property for one element. */\ninterface Resolver {\n readonly bypass: (i: number, vp: string) => unknown;\n readonly one: (vp: string, parse: CytoscapeValueParser, property: string, i: number) => StyleValue | null;\n}\n\n/**\n * Builds the per-element reader of one target's style.\n * @param target - nodes or edges\n * @param style - the target's style\n * @param elements - the elements\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @returns the reader\n */\nfunction resolver(\n target: StyleTarget,\n style: CytoscapeTargetStyle,\n elements: CytoscapeElements,\n notes: StyleNotes,\n budget: StyleWorkBudget | undefined,\n): Resolver {\n const bypasses = elements.bypasses ?? [];\n const parsed = new Map<string, ParsedMapping>();\n const ruleSite = (property: string): CanonSite => ({ notes, target, property, budget });\n const bypass = (i: number, vp: string): unknown => {\n const b = bypasses[i];\n if (!b) {\n return undefined;\n }\n const v = b.get(vp);\n if (v !== undefined && v !== null) {\n return v;\n }\n for (const [from, to] of style.bypassAliases) {\n if (to === vp && !b.has(to)) {\n return b.get(from);\n }\n }\n return lockedValue(b, vp);\n };\n // a mapping parsed once per visual property and neutral property\n const mappingOf = (vp: string, parse: CytoscapeValueParser, property: string): ParsedMapping | undefined => {\n const raw = style.mappings.get(vp);\n if (raw === undefined) {\n return undefined;\n }\n const key = `${vp}\\u0000${property}`;\n let m = parsed.get(key);\n if (m === undefined) {\n const entries = raw.kind === \"discrete\" ? raw.table.length : 0;\n budget?.spend(target, 1 + entries + (raw.kind === \"continuous\" ? raw.points.length : 0));\n m = parseMapping(raw, parse, ruleSite(property), vp);\n parsed.set(key, m);\n }\n return m;\n };\n const one = (vp: string, parse: CytoscapeValueParser, property: string, i: number): StyleValue | null => {\n const site: CanonSite = { notes, target, property, element: i, budget };\n const b = bypass(i, vp);\n const fromBypass = b === undefined || b === null ? null : parse(b, site);\n if (fromBypass !== null) {\n return fromBypass;\n }\n const m = mappingOf(vp, parse, property);\n const mapped = m === undefined ? null : evalMapping(m, elements.value(m.column, i), parse, site);\n if (mapped !== null) {\n return mapped;\n }\n return style.defaults.has(vp) ? parse(style.defaults.get(vp), ruleSite(property)) : null;\n };\n return { bypass, one };\n}\n\n/**\n * Every element's value per neutral property under a Cytoscape style, the way Cytoscape draws it: per visual\n * property a bypass, else the mapping's value, else the default; `nodeSizeLocked` and `arrowColorMatchesEdge`\n * applied (under `nodeSizeLocked` a node's own `NODE_WIDTH` or `NODE_HEIGHT` bypass still sets that dimension). `EDGE_CURVED` only rounds an edge's bends, so an edge without bends is `curved: false` unless desktop fans it out of a bundle of parallel edges (given `elements.ends`). Visual properties\n * no neutral property carries are noted as `W_STYLE_NOT_CARRIED`.\n * @param target - nodes or edges\n * @param style - the style\n * @param elements - the elements, their attribute values and their bypasses\n * @param options - notes, the budget and whose defaults fill what the style leaves unset\n * @returns per property, each element's value (null where nothing gives one)\n * @category Styles\n */\nexport function resolveCytoscape(\n target: StyleTarget,\n style: CytoscapeStyle,\n elements: CytoscapeElements,\n options: CytoscapeResolveOptions = {},\n): Partial<Record<string, StyleColumn>> {\n const notes = options.notes ?? new StyleNotes();\n const s = style[target];\n const n = elements.count;\n const { used, bypassed } = vpUsage(s, elements.bypasses ?? []);\n const chosen = chooseVps(target, s, used);\n const { one, bypass } = resolver(target, s, elements, notes, options.budget);\n const out: Partial<Record<string, StyleColumn>> = {};\n const column = (vp: string, parse: CytoscapeValueParser, property: string): (StyleValue | null)[] => {\n options.budget?.spend(target, n);\n const values = new Array<StyleValue | null>(n);\n for (let i = 0; i < n; i++) {\n values[i] = one(vp, parse, property, i);\n }\n return values;\n };\n for (const [prop, [vp, parse]] of chosen) {\n out[prop] = column(vp, parse, prop);\n }\n if (target === \"node\" && s.dependencies.get(\"nodeSizeLocked\") === true) {\n // a node's own width or height still wins over the locked size: Cytoscape draws it\n const size = column(NODE_SIZE_VP, sizeParser, \"width\").map((v) => v ?? NODE_SIZE_FALLBACK);\n const own = (vp: string, property: string): StyleColumn =>\n size.map((v, i) => {\n const b = bypass(i, vp);\n const parsed =\n b === undefined || b === null ? null : sizeParser(b, { notes, target, property, element: i });\n return parsed ?? v;\n });\n out.width = own(\"NODE_WIDTH\", \"width\");\n out.height = own(\"NODE_HEIGHT\", \"height\");\n }\n labelDress(target, out, one, n, elements.ends);\n if (target === \"node\") {\n squashHexagons(out);\n // the value as written: a chart is text, or an object in CX2; a size a number or its text\n const raw: CytoscapeValueParser = (v) => {\n if (typeof v === \"string\" || typeof v === \"number\") {\n return String(v);\n }\n return typeof v === \"object\" && v !== null ? JSON.stringify(v) : null;\n };\n readCytoscapeCharts(\n out,\n n,\n (slot, i) => {\n const v = one(slot, raw, \"pieColors\", i);\n return typeof v === \"string\" && v.startsWith(\"{\") ? (JSON.parse(v) as unknown) : v;\n },\n (column, i) => elements.value(column, i),\n s.dependencies.get(\"nodeCustomGraphicsSizeSync\") !== false,\n );\n }\n if (\n target === \"edge\" &&\n s.dependencies.get(\"arrowColorMatchesEdge\") === true &&\n !used.has(\"EDGE_UNSELECTED_PAINT\") &&\n used.has(\"EDGE_STROKE_UNSELECTED_PAINT\")\n ) {\n // the dependency draws the line and the arrows in EDGE_UNSELECTED_PAINT, Cytoscape's own when the style has\n // none: the stroke's default and its mapping are not drawn, only an element's own bypass of the stroke (below;\n // Cytoscape 3.10.5 on specimen-mappings-bypass draws a passthrough of the stroke #404040, as its XGMML says)\n const paint = (toolDefaults(\"cytoscape-fallbacks\")?.edge.color?.value ?? null) as StyleValue | null;\n out.color = Array.from({ length: n }, (_, i) => one(\"EDGE_UNSELECTED_PAINT\", colorParser, \"color\", i) ?? paint);\n }\n if (target === \"edge\" && s.dependencies.get(\"arrowColorMatchesEdge\") === true && out.color !== undefined) {\n // CX2's EDGE_LINE_COLOR bypass is the stroke's alone (its writer spells a desktop EDGE_UNSELECTED_PAINT\n // bypass out as the line and both arrow colors): the arrows keep the style's line color (Cytoscape 3.10.5's\n // SVG of the CX2 specimen-mappings-bypass, bypass-over-edge-passthrough, draws its arrow #505050)\n const lineVp = chosen.get(\"color\")?.[0];\n const unbypassed = resolver(target, s, { ...elements, bypasses: [] }, notes, options.budget).one;\n const arrows =\n lineVp === \"EDGE_LINE_COLOR\"\n ? Array.from({ length: n }, (_, i) => unbypassed(lineVp, colorParser, \"color\", i))\n : out.color;\n out.sourceArrowColor = arrows.slice();\n out.targetArrowColor = arrows.slice();\n // the dependency sets the line and the arrows from EDGE_UNSELECTED_PAINT; an element's own bypass of one of\n // them still wins for that one (Cytoscape draws a bypassed EDGE_STROKE_UNSELECTED_PAINT line in its color)\n const own: readonly [string, string][] = [\n [\"color\", \"EDGE_STROKE_UNSELECTED_PAINT\"],\n [\"sourceArrowColor\", \"EDGE_SOURCE_ARROW_UNSELECTED_PAINT\"],\n [\"targetArrowColor\", \"EDGE_TARGET_ARROW_UNSELECTED_PAINT\"],\n [\"sourceArrowColor\", \"EDGE_SOURCE_ARROW_COLOR\"],\n [\"targetArrowColor\", \"EDGE_TARGET_ARROW_COLOR\"],\n ];\n for (const [prop, vp] of own) {\n out[prop] = (out[prop] ?? []).map((v, i) => {\n const b = bypass(i, vp);\n const site = { notes, target, property: prop, element: i };\n return (b === undefined || b === null ? null : colorParser(b, site)) ?? v;\n });\n }\n }\n noteUncarried(target, s, used, bypassed, notes);\n if (target === \"edge\") {\n const bends = column(EDGE_BEND_VP, bendsParser, \"bends\");\n if (bends.some((v) => v !== null)) {\n out.bends = bends;\n }\n // before the tool's defaults: an edge the style leaves unset is curved as Cytoscape's EDGE_CURVED default is\n const curvedAsSet = out.curved?.slice();\n straightenBendless(out, one, n, elements.ends);\n loopHandles(out, one, curvedAsSet, elements.ends);\n arrowProportions(out, column);\n }\n fillToolDefaults(target, out, n, options.defaults ?? null);\n return out;\n}\n\n/**\n * A visual property's value as written, a CX2 object as its JSON.\n * @param v - the value\n * @returns its text, or null\n */\nconst rawText: CytoscapeValueParser = (v) => {\n if (typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\") {\n return String(v);\n }\n return typeof v === \"object\" && v !== null ? JSON.stringify(v) : null;\n};\n\n/**\n * Reads what Cytoscape draws of each element's label beyond its words, font and color: the box behind it (drawn only\n * with a `*_LABEL_BACKGROUND_SHAPE` other than NONE, the default, in its color and transparency), where it is placed\n * (`*_LABEL_POSITION` read whole: which point of the label's box is pinned to which point of the node, or of the\n * edge's line, and the offset) and how its lines are justified. Each column is kept only where some element needs it;\n * an edge's place is kept whenever it has one, since Cytoscape centers an edge's label on its line.\n * @param target - nodes or edges\n * @param out - the values per property, changed in place\n * @param one - reads one visual property of one element\n * @param n - the element count\n * @param ends - the edges' ends and their nodes' centers, when known\n */\nfunction labelDress(\n target: StyleTarget,\n out: Partial<Record<string, StyleColumn>>,\n one: Resolver[\"one\"],\n n: number,\n ends: CytoscapeElements[\"ends\"],\n): void {\n const vp = (name: string): string => `${target === \"node\" ? \"NODE\" : \"EDGE\"}_LABEL_${name}`;\n const columns: Record<string, (StyleValue | null)[]> = {};\n const put = (property: string, i: number, v: StyleValue | null): void => {\n let column = columns[property];\n if (column === undefined) {\n column = new Array<StyleValue | null>(n).fill(null);\n columns[property] = column;\n }\n column[i] = v;\n };\n for (let i = 0; i < n; i++) {\n labelBox(vp, one, i, put);\n // read whole, quietly (the lexicon's reading of the same value notes a bad one), under a name of its own: a\n // mapping is parsed once per visual property and neutral property\n const placed = one(vp(\"POSITION\"), rawText, \"labelPlace\", i);\n const raw = typeof placed === \"string\" && placed.startsWith(\"{\") ? (JSON.parse(placed) as unknown) : placed;\n const place = cytoscapeLabelPlace(raw, { notes: new StyleNotes(), target, property: \"labelPosition\" });\n if (place !== null) {\n placeLabel(target, place, i, out, put, ends);\n }\n if (target === \"edge\") {\n autorotate(one, i, out, n, ends);\n }\n }\n const kept = (property: string, v: StyleValue | null): boolean =>\n v !== null && v !== 0 && (v !== \"center\" || (property === \"labelPosition\" && target === \"edge\"));\n for (const [property, values] of Object.entries(columns)) {\n if (values.some((v) => kept(property, v))) {\n out[property] = values;\n }\n }\n}\n\n/**\n * The box Cytoscape draws behind one label, when its shape is not NONE: its color (`#B6B6B6` unset, the lexicon's\n * default), its opacity, and for ROUND_RECTANGLE its corners, rounded an eighth of the box's height: 1.455 on the\n * 11.64-tall box of a 10 px label (xgmml-specimen-labels.svg, label-background-shape-round-rectangle), so 0.1455 of the\n * label's size. ponytail: one line's height; a box of several lines is rounded as one line's.\n * @param vp - names a label visual property of the target\n * @param one - reads one visual property of one element\n * @param i - the element\n * @param put - sets one element's value of a property\n */\nfunction labelBox(\n vp: (name: string) => string,\n one: Resolver[\"one\"],\n i: number,\n put: (property: string, i: number, v: StyleValue | null) => void,\n): void {\n const shape = one(vp(\"BACKGROUND_SHAPE\"), rawText, \"labelBackgroundShape\", i);\n if (typeof shape !== \"string\" || shape.trim().toUpperCase() === \"NONE\") {\n return;\n }\n put(\"labelBackground\", i, one(vp(\"BACKGROUND_COLOR\"), colorParser, \"labelBackground\", i) ?? \"#b6b6b6\");\n const [t, o] = [vp(\"BACKGROUND_TRANSPARENCY\"), vp(\"BACKGROUND_OPACITY\")];\n const opacity =\n one(t, opacityParser(t), \"labelBackgroundOpacity\", i) ?? one(o, opacityParser(o), \"labelBackgroundOpacity\", i);\n put(\"labelBackgroundOpacity\", i, opacity ?? 1);\n // CX2 spells it round-rectangle\n if (shape.trim().toUpperCase().replace(\"-\", \"_\") === \"ROUND_RECTANGLE\") {\n const size = one(vp(\"FONT_SIZE\"), sizeParser, \"labelSize\", i);\n // desktop's default label sizes: 12 on a node, 10 on an edge\n const defaultSize = vp(\"FONT_SIZE\").startsWith(\"EDGE\") ? 10 : 12;\n put(\"labelCornerRadius\", i, num6(LABEL_CORNER_PER_SIZE * (typeof size === \"number\" ? size : defaultSize)));\n }\n}\n\n/** How far Cytoscape rounds a ROUND_RECTANGLE label box's corners, as a fraction of the label's font size. */\nconst LABEL_CORNER_PER_SIZE = 0.1455;\n\n/**\n * Where one label is placed, from its Cytoscape label position: its neutral `labelPosition`, offsets, shifts and\n * line justification. A node's label is pinned against the node's box. An edge's is pinned to a point of its drawn\n * line, the middle unless the anchor's horizontal letter names an end (W the source's, E the target's; its vertical\n * letter changes nothing, measured on Cytoscape 3.10.5's SVG), from the line's middle, where it is centered.\n * @param target - nodes or edges\n * @param place - the label position\n * @param i - the element\n * @param out - the values per property (the node sizes are read)\n * @param put - sets one element's value of a property\n * @param ends - the edges' ends and their nodes' centers, when known\n */\nfunction placeLabel(\n target: StyleTarget,\n place: CytoscapeLabelPlace,\n i: number,\n out: Partial<Record<string, StyleColumn>>,\n put: (property: string, i: number, v: StyleValue | null) => void,\n ends: CytoscapeElements[\"ends\"],\n): void {\n let move: ReturnType<typeof cytoscapeLabelMove>;\n if (target === \"node\") {\n const [w, h] = [out.width?.[i], out.height?.[i]];\n move = cytoscapeLabelMove(place, typeof w === \"number\" ? w : 0, typeof h === \"number\" ? h : 0);\n put(\"labelPosition\", i, cytoscapeLabelBase(place));\n } else {\n const [ax, ay] = lineEnd(ends, i, place.node[0]);\n move = {\n offset: [ax + place.offset[0], ay + place.offset[1]],\n shift: [halfBack(place.label[0]), halfBack(place.label[1])],\n };\n put(\"labelPosition\", i, \"center\");\n }\n put(\"labelOffsetX\", i, num6(move.offset[0]));\n put(\"labelOffsetY\", i, num6(move.offset[1]));\n put(\"labelShiftX\", i, move.shift[0]);\n put(\"labelShiftY\", i, move.shift[1]);\n put(\"labelTextAlign\", i, place.justify);\n}\n\n/**\n * Turns an edge's label along its line under `EDGE_LABEL_AUTOROTATE`, as Cytoscape draws it: the line's angle from\n * its source's center to its target's (kept between -90 and 90 so the words read left to right), plus its\n * `EDGE_LABEL_ROTATION`.\n * ponytail: the angle is the file's node places at import; a layout that moves the nodes leaves it as it was, until\n * the neutral styles can say \"along the line\"\n * @param one - reads one visual property of one element\n * @param e - the edge\n * @param out - the values per property, changed in place\n * @param n - the edge count\n * @param ends - the edges' ends and their nodes' centers\n */\nfunction autorotate(\n one: Resolver[\"one\"],\n e: number,\n out: Partial<Record<string, StyleColumn>>,\n n: number,\n ends: CytoscapeElements[\"ends\"],\n): void {\n const on = one(AUTOROTATE_VP, rawText, \"labelRotation\", e);\n const [si, ti] = [ends?.source[e], ends?.target[e]];\n const [s, t] = [si === undefined ? null : ends?.nodeAt?.[si], ti === undefined ? null : ends?.nodeAt?.[ti]];\n if (String(on).toLowerCase() !== \"true\" || !s || !t || (s[0] === t[0] && s[1] === t[1])) {\n return;\n }\n const a = (Math.atan2(t[1] - s[1], t[0] - s[0]) * 180) / Math.PI;\n let upright = a;\n if (a > 90) {\n upright = a - 180;\n } else if (a <= -90) {\n upright = a + 180;\n }\n out.labelRotation ??= new Array<StyleValue | null>(n).fill(null);\n const column = out.labelRotation as (StyleValue | null)[];\n const own = column[e];\n column[e] = num6((((upright + (typeof own === \"number\" ? own : 0)) % 360) + 360) % 360);\n}\n\n/**\n * How far from the middle of an edge's drawn line one of its ends is, on screen (y down): the line between its two\n * nodes' centers, cut where it meets each node's ellipse; 0 for the middle, or where the centers are not known.\n * @param ends - the edges' ends, their nodes' centers and boxes\n * @param e - the edge\n * @param side - -1 for the source's end, 1 for the target's, 0 for the middle\n * @returns the offset from the line's middle\n */\nfunction lineEnd(ends: CytoscapeElements[\"ends\"], e: number, side: number): readonly [number, number] {\n const [si, ti] = [ends?.source[e], ends?.target[e]];\n const [s, t] = [si === undefined ? null : ends?.nodeAt?.[si], ti === undefined ? null : ends?.nodeAt?.[ti]];\n if (side === 0 || s === null || s === undefined || t === null || t === undefined) {\n return [0, 0];\n }\n const length = Math.hypot(t[0] - s[0], t[1] - s[1]);\n if (length === 0) {\n return [0, 0];\n }\n const [ux, uy] = [(t[0] - s[0]) / length, (t[1] - s[1]) / length];\n // where the line leaves a node's ellipse, along it from the center\n const reach = (node: number | undefined): number => {\n const box = node === undefined ? null : ends?.nodeBox?.[node];\n if (box === null || box === undefined) {\n return 0;\n }\n const [a, b] = [box[0] / 2, box[1] / 2];\n return a === 0 || b === 0 ? 0 : (a * b) / Math.hypot(b * ux, a * uy);\n };\n const from = reach(si);\n const to = length - reach(ti);\n // the drawn line's middle and the end asked for, both measured along the line from the source's center\n const along = (side < 0 ? from : to) - (from + to) / 2;\n return [ux * along, uy * along];\n}\n\n/** How tall a regular hexagon is for its width. */\nconst HEXAGON_ASPECT = Math.sqrt(3) / 2;\n\n/**\n * Gives every hexagon node the height Cytoscape desktop draws it at. Its HEXAGON is a regular hexagon squashed to\n * the node's box rather than one filling it: the corners reach the box's sides, the flat top and bottom only\n * `sqrt(3) / 2` of the way up and down, so a 40 x 40 node with a border of 1 is a 39 x 33.8 path (its border is\n * inside its size, `borderPosition` inside). The neutral hexagon fills its box, so the node is that much shorter.\n * @param out - the node values per property, changed in place\n */\nfunction squashHexagons(out: Partial<Record<string, StyleColumn>>): void {\n const { shape, height } = out;\n if (shape === undefined || height === undefined || !shape.includes(\"hexagon\")) {\n return;\n }\n const border = out.borderWidth;\n out.height = height.map((h, i) => {\n if (shape[i] !== \"hexagon\" || typeof h !== \"number\") {\n return h;\n }\n const b = border?.[i];\n const w = typeof b === \"number\" ? Math.min(b, h) : 0;\n return (h - w) * HEXAGON_ASPECT + w;\n });\n}\n\n/**\n * What Cytoscape draws of each end's arrow beyond its shape and the one neutral `arrowSize`: the source end's own\n * size where it differs from the target's (an unset size is Cytoscape's 6), and the length and width of the short and\n * crossed arrows against their neutral shape's, and how far off its node each arrow stands. Each is kept only where\n * some edge needs it.\n * @param out - the values per property, changed in place\n * @param column - reads one visual property of every element\n */\nfunction arrowProportions(\n out: Partial<Record<string, StyleColumn>>,\n column: (vp: string, parse: CytoscapeValueParser, property: string) => (StyleValue | null)[],\n): void {\n const size = out.arrowSize;\n const own = column(\"EDGE_SOURCE_ARROW_SIZE\", arrowSizeParser, \"sourceArrowSize\").map((v) => v ?? 1);\n if (own.some((v, i) => v !== (size?.[i] ?? 1))) {\n out.sourceArrowSize = own;\n }\n for (const [prop, vp, side] of [\n [\"sourceArrowLength\", \"EDGE_SOURCE_ARROW_SHAPE\", \"length\"],\n [\"targetArrowLength\", \"EDGE_TARGET_ARROW_SHAPE\", \"length\"],\n [\"sourceArrowWidth\", \"EDGE_SOURCE_ARROW_SHAPE\", \"width\"],\n [\"targetArrowWidth\", \"EDGE_TARGET_ARROW_SHAPE\", \"width\"],\n ] as const) {\n const values = column(vp, arrowProportion(side), prop).map((v) => (v === 1 ? null : v));\n if (values.some((v) => v !== null)) {\n out[prop] = values;\n }\n }\n // the arrows desktop draws standing off their node (T, the half circles, HALF_TOP, the squares)\n for (const [prop, vp] of [\n [\"sourceArrowGap\", \"EDGE_SOURCE_ARROW_SHAPE\"],\n [\"targetArrowGap\", \"EDGE_TARGET_ARROW_SHAPE\"],\n ] as const) {\n const values = column(vp, arrowGap, prop).map((v) => (v === 0 ? null : v));\n if (values.some((v) => v !== null)) {\n out[prop] = values;\n }\n }\n}\n\n/**\n * Marks straight every curved edge without bends, except where Cytoscape desktop fans it: `EDGE_CURVED` only\n * rounds the bends an edge has, and the bends Cytoscape adds itself. Among the edges joining the same two nodes\n * (either way round, not loops), it draws the last it created straight and bends each earlier one without bends\n * of its own round an anchor beside the line (`DEdgeDetails.getAnchors`, `EDGE_STACKING` `AUTO_BEND`, the default;\n * it walks the pair's edges newest first, measured on Cytoscape 3.10.5's SVG of edges joining two nodes both ways)\n * -- unless the last has bends, when every anchor falls on the line. Its anchors are the larger side of the two\n * nodes times twice `EDGE_STACKING_DENSITY` apart, so the curves' middles half that: each fanned edge's\n * `fanSpacing`, when the node sizes are known. A fanned edge is drawn curved even under `EDGE_CURVED` false, and an\n * edge whose `EDGE_STACKING` is HAYSTACK is neither fanned nor counted: desktop draws it straight (both measured on\n * Cytoscape 3.10.5's SVG of the edges-lines specimen sheet).\n * @param out - the values per property, changed in place\n * @param one - reads one visual property of one element\n * @param n - the edge count\n * @param ends - each edge's source and target node index, in creation order, when known\n */\nfunction straightenBendless(\n out: Partial<Record<string, StyleColumn>>,\n one: Resolver[\"one\"],\n n: number,\n ends: CytoscapeElements[\"ends\"],\n): void {\n // an edge the style leaves unset takes EDGE_CURVED's default, true\n const curved = out.curved ?? new Array<StyleValue | null>(n).fill(null);\n const bent = (i: number): boolean => one(EDGE_BEND_VP, bendParser, \"curved\", i) === true;\n const haystack = (i: number): boolean =>\n String(one(EDGE_STACKING_VP, rawText, \"fanned\", i) ?? \"\").toUpperCase() === \"HAYSTACK\";\n // each fanned edge's place in its pair's walk (1 for the first fanned)\n const place = ends === undefined ? new Map<number, number>() : fanPlaces(ends, curved.length, bent, haystack);\n const fanned = new Set(place.keys());\n const rounds = (i: number): boolean => fanned.has(i) || bent(i);\n const rounded = curved.map((c, i) => {\n if (c === null) {\n return rounds(i) ? true : null;\n }\n return c === true || fanned.has(i) ? rounds(i) : c;\n });\n if (out.curved !== undefined || rounded.includes(true)) {\n out.curved = rounded;\n }\n if (ends?.nodeSize === undefined || fanned.size === 0) {\n return;\n }\n const { source, target, nodeSize } = ends;\n out.fanSpacing = curved.map((_, i) => {\n const size = Math.max(nodeSize[source[i]] ?? Number.NaN, nodeSize[target[i]] ?? Number.NaN);\n if (out.curved?.[i] !== true || !fanned.has(i) || bent(i) || !Number.isFinite(size)) {\n return null;\n }\n const read = one(EDGE_STACKING_DENSITY_VP, sizeParser, \"fanSpacing\", i);\n const density = Math.min(1, typeof read === \"number\" ? read : EDGE_STACKING_DENSITY_DEFAULT);\n return size * density;\n });\n fanAnchors(out, ends, place);\n}\n\n/**\n * The edges desktop fans, each with its place in its node pair's walk (1 for the first fanned). Desktop walks a node\n * pair's edges newest first (its adjacency lists take each new edge at the head); the first it meets is drawn\n * straight, and each later one fanned unless that first one has bends. Loops and haystack edges are left out.\n * @param ends - each edge's source and target node index, and the order they were created in\n * @param count - the edge count\n * @param bent - whether an edge has bends of its own\n * @param haystack - whether an edge is a haystack edge\n * @returns each fanned edge's place, in walk order\n */\nfunction fanPlaces(\n ends: NonNullable<CytoscapeElements[\"ends\"]>,\n count: number,\n bent: (i: number) => boolean,\n haystack: (i: number) => boolean,\n): Map<number, number> {\n const place = new Map<number, number>();\n const first = new Map<string, { f: number; k: number }>();\n for (const i of newestFirst(count, ends.created?.edge)) {\n const [s, t] = [ends.source[i], ends.target[i]];\n if (s === t || haystack(i)) {\n continue;\n }\n const key = `${Math.min(s, t)},${Math.max(s, t)}`;\n const f = first.get(key);\n if (f === undefined) {\n first.set(key, { f: i, k: 0 });\n } else if (!bent(f.f)) {\n f.k++;\n place.set(i, f.k);\n }\n }\n return place;\n}\n\n/**\n * The edges newest first: by the order they were created in when it is known, else last index first.\n * @param count - the edge count\n * @param created - each edge's place in the creation order, when known\n * @returns the edge indices in that order\n */\nfunction newestFirst(count: number, created: ArrayLike<number> | undefined): number[] {\n const walk = Array.from({ length: count }, (_, i) => i);\n walk.sort(created === undefined ? (a, b) => b - a : (a, b) => created[b] - created[a]);\n return walk;\n}\n\n/**\n * Gives each fanned edge its place in desktop's fan as a bend, when the order desktop created the nodes in is known:\n * the fan's side is then desktop's, not graphty's. Desktop measures each pair's fan from the node whose view it made\n * first, and it makes views newest node first (`DEdgeDetails.getAnchors`: the pair's lower view SUID is its source;\n * `SimpleNetwork.getNodeList` lists the newest node first); the `k`-th fanned edge bows `ceil(k / 2)` fan spacings\n * off the middle of the line, to the right of the fan's direction (y down) for odd `k`, to the left for even. The\n * bend is the control point of a quadratic Bezier whose middle lies there, twice as far off.\n * @param out - the values per property, with `fanSpacing` set; changed in place\n * @param ends - the edges' ends, their nodes' centers and creation order\n * @param place - each fanned edge's place in its pair's walk, from 1\n */\nfunction fanAnchors(\n out: Partial<Record<string, StyleColumn>>,\n ends: NonNullable<CytoscapeElements[\"ends\"]>,\n place: ReadonlyMap<number, number>,\n): void {\n const { created, nodeAt, source, target } = ends;\n const spacing = out.fanSpacing?.slice();\n if (created === undefined || nodeAt === undefined || spacing === undefined) {\n return;\n }\n const bends = out.bends?.slice() ?? new Array<StyleValue | null>(source.length).fill(null);\n const bendCurve = out.bendCurve?.slice() ?? new Array<StyleValue | null>(source.length).fill(null);\n let changed = false;\n for (const [i, k] of place) {\n const [s, t] = [source[i], target[i]];\n const [ps, pt, f] = [nodeAt[s], nodeAt[t], spacing[i]];\n if (ps === null || ps === undefined || pt === null || pt === undefined || typeof f !== \"number\") {\n continue;\n }\n const len = Math.hypot(pt[0] - ps[0], pt[1] - ps[1]);\n if (len === 0) {\n continue;\n }\n // the fan's direction: from the node desktop made a view of first, the one created last\n const sign = created.node[s] > created.node[t] ? 1 : -1;\n const [nx, ny] = [(sign * (pt[0] - ps[0])) / len, (sign * (pt[1] - ps[1])) / len];\n const offset = Math.ceil(k / 2) * (k % 2 === 0 ? 1 : -1) * 2 * f;\n const [vx, vy] = [offset * ny, -offset * nx];\n // to the left of source -> target, y up, as a fraction of the length\n const across = (vx * (pt[1] - ps[1]) - vy * (pt[0] - ps[0])) / (len * len);\n bends[i] = `0.5,${String(Math.round(across * 1e6) / 1e6 || 0)}`;\n bendCurve[i] = \"bezier\";\n spacing[i] = null;\n changed = true;\n }\n if (changed) {\n out.bends = bends;\n out.bendCurve = bendCurve;\n out.fanSpacing = spacing;\n }\n}\n\n/**\n * Gives each self-loop without bends of its own the two handles Cytoscape desktop draws it round\n * (`DEdgeDetails.getAnchors`): one left of the node's center and one above it, each `(i + 3) / 2` of the node's\n * size times twice `EDGE_STACKING_DENSITY` away, where the size is the larger side of the node with its border\n * (its extents in desktop's spatial index) and `i` counts the node's earlier loops without bends, newest first as\n * desktop walks them. A loop is curved through them unless `EDGE_CURVED` says false. Measured on Cytoscape\n * 3.10.5's SVG of the edges-lines specimen sheet (within 0.3 px of its loops).\n * @param out - the values per property, changed in place\n * @param one - reads one visual property of one element\n * @param curvedAsSet - each edge's `curved` as the style set it, before bendless edges were straightened\n * @param ends - each edge's source and target node index, in creation order, and each node's box, when known\n */\nfunction loopHandles(\n out: Partial<Record<string, StyleColumn>>,\n one: Resolver[\"one\"],\n curvedAsSet: readonly (StyleValue | null)[] | undefined,\n ends: CytoscapeElements[\"ends\"],\n): void {\n const box = ends?.nodeBox;\n if (ends === undefined || box === undefined) {\n return;\n }\n const bends = out.bends?.slice() ?? new Array<StyleValue | null>(ends.source.length).fill(null);\n const curved = out.curved?.slice() ?? new Array<StyleValue | null>(ends.source.length).fill(null);\n const earlier = new Map<number, number>();\n const fraction = (v: number): string => String(Math.round(v * 1e4) / 1e4 || 0);\n let changed = false;\n for (let i = ends.source.length - 1; i >= 0; i--) {\n const node = ends.source[i];\n const b = box[node];\n if (node !== ends.target[i] || bends[i] !== null) {\n continue;\n }\n const rank = earlier.get(node) ?? 0;\n earlier.set(node, rank + 1);\n if (b === null || b === undefined || b[0] <= 0 || b[1] <= 0) {\n continue;\n }\n const read = one(EDGE_STACKING_DENSITY_VP, sizeParser, \"fanSpacing\", i);\n const density = Math.min(1, typeof read === \"number\" ? read : EDGE_STACKING_DENSITY_DEFAULT);\n const reach = (((rank + 3) * (Math.max(b[0], b[1]) + b[2])) / 2) * 2 * density;\n // as `x,y` fractions of the node's half width and half height, y up: left of the center, then above it\n bends[i] = `${fraction(-reach / (b[0] / 2))},0 0,${fraction(reach / (b[1] / 2))}`;\n curved[i] = curvedAsSet?.[i] !== false;\n changed = true;\n }\n if (changed) {\n out.bends = bends;\n out.curved = curved;\n }\n}\n\n/** An edge's bend handles. */\nexport const EDGE_BEND_VP = \"EDGE_BEND\";\n\n/**\n * Whether an `EDGE_BEND` value holds any handle: Cytoscape writes an edge without bends as an empty string.\n * @param raw - the value\n * @returns true when the edge bends\n */\nexport const bendParser: CytoscapeValueParser = (raw) => {\n if (typeof raw === \"string\") {\n const text = raw.trim();\n return text !== \"\" && text !== '\"\"';\n }\n return Array.isArray(raw) ? raw.length > 0 : raw !== null && raw !== undefined && typeof raw === \"object\";\n};\n\n/**\n * An `EDGE_BEND` value as the neutral `bends`: Cytoscape keeps each handle as `cos,sin,ratio`, the handle at the\n * source center plus `ratio` times the source-to-target vector turned by the angle (y down), handles separated by\n * `|`. Relative to the same line, y up, that is `ratio * cos` along it and `-ratio * sin` across it.\n * @param input - the value: an `EDGE_BEND` text, or CX2's `EDGE_CONTROL_POINTS` objects\n * @param site - where it was read\n * @returns the bends, or null for an edge without handles or a value that is not handles\n */\nconst bendsParser: CytoscapeValueParser = (input, site) => {\n // CX2's EDGE_CONTROL_POINTS: one object per handle, whose `sin` Cytoscape fills with EDGE_BEND's first number and\n // `cos` with its second (it reads them back the same way: specimen-edges-lines bend-one-handle bends)\n const raw = Array.isArray(input)\n ? input\n .map((h: unknown) => {\n const o = (h ?? {}) as Record<string, unknown>;\n return `${Number(o.sin)},${Number(o.cos)},${Number(o.ratio)}`;\n })\n .join(\"|\")\n : input;\n if (typeof raw !== \"string\" || !bendParser(raw, site)) {\n return null;\n }\n const points: string[] = [];\n for (const handle of raw.trim().split(\"|\")) {\n const [c, sin, ratio] = handle.split(\",\").map((t) => Number(t.trim()));\n if (![c, sin, ratio].every((v) => Number.isFinite(v))) {\n noteAt(site, STYLE_ISSUE.BAD_VALUE, raw.slice(0, 64));\n return null;\n }\n const fraction = (v: number): string => String(Math.round(v * 1e4) / 1e4 || 0);\n points.push(`${fraction(ratio * c)},${fraction(-ratio * sin)}`);\n }\n return points.join(\" \");\n};\n\n/** Default values that mean \"nothing drawn\": a VP left at one of these is not worth a note. */\nconst INERT_DEFAULT = /NullCustomGraphics|^255$|^0(?:\\.0+)?$|^$|^C,C,c,0\\.00,0\\.00$|^false$/;\n\n/**\n * Notes every visual property the style uses that no neutral property carries.\n * @param target - nodes or edges\n * @param s - the target's style\n * @param used - the visual properties used anywhere\n * @param bypassed - those used by a bypass\n * @param notes - where to note\n */\nfunction noteUncarried(\n target: StyleTarget,\n s: CytoscapeTargetStyle,\n used: ReadonlySet<string>,\n bypassed: ReadonlySet<string>,\n notes: StyleNotes,\n): void {\n for (const vp of used) {\n if (!isUncarriedVp(vp)) {\n continue;\n }\n const d = s.defaults.get(vp);\n const text = typeof d === \"string\" || typeof d === \"number\" || typeof d === \"boolean\" ? String(d) : \"\";\n if (INERT_DEFAULT.test(text.slice(0, 64)) && !s.mappings.has(vp) && !bypassed.has(vp)) {\n continue;\n }\n notes.add(STYLE_ISSUE.NOT_CARRIED, target, vp, { sample: text });\n }\n}\n\n/**\n * Fills what nothing gave with a tool's defaults.\n * @param target - nodes or edges\n * @param out - the values per property\n * @param n - the element count\n * @param tool - the tool, or null for none\n */\nfunction fillToolDefaults(\n target: StyleTarget,\n out: Partial<Record<string, StyleColumn>>,\n n: number,\n tool: StyleTool | null,\n): void {\n const d = tool === null ? null : toolDefaults(tool);\n if (d === null) {\n return;\n }\n for (const [prop, entry] of Object.entries(d[target]) as [string, { value: unknown } | undefined][]) {\n if (entry === undefined || !isStyleValue(target, prop, entry.value)) {\n continue;\n }\n const value = entry.value as StyleValue;\n const values = out[prop] === undefined ? new Array<StyleValue | null>(n).fill(null) : out[prop].slice();\n for (let i = 0; i < n; i++) {\n values[i] ??= value;\n }\n out[prop] = values;\n }\n}\n\n/**\n * The style's network background color (`NETWORK_BACKGROUND_PAINT`, CX2's `NETWORK_BACKGROUND_COLOR`).\n * @param style - the style\n * @param notes - where a bad value is noted\n * @returns the color, or null\n * @category Styles\n */\nexport function cytoscapeBackground(style: CytoscapeStyle, notes?: StyleNotes): StyleColor | null {\n const d = style.network.defaults;\n const raw = d.get(\"NETWORK_BACKGROUND_PAINT\") ?? d.get(\"NETWORK_BACKGROUND_COLOR\");\n if (raw === undefined) {\n return null;\n }\n const v = colorParser(raw, { notes: notes ?? new StyleNotes(), target: \"graph\", property: \"background\" });\n return typeof v === \"string\" ? (v as StyleColor) : null;\n}\n\n/**\n * Every element's values when each element carries its own resolved visual properties and no style (XGMML files\n * and Cytoscape 2.x sessions). Width and height are read from `NODE_SIZE` when no element states them; keys with no\n * visual property name (`?<key>` from `normalizeVisualProperties()`) are noted as `W_STYLE_NOT_CARRIED`.\n * @param target - nodes or edges\n * @param maps - each element's visual properties\n * @param options - notes, the budget and whose defaults fill what is unset\n * @returns per property, each element's value\n * @category Styles\n */\nexport function resolveCytoscapeBypasses(\n target: StyleTarget,\n maps: readonly CytoscapeBypass[],\n options: CytoscapeResolveOptions = {},\n): Partial<Record<string, StyleColumn>> {\n const notes = options.notes ?? new StyleNotes();\n const style = emptyCytoscapeStyle();\n const elements: CytoscapeElements = {\n count: maps.length,\n value: options.value ?? (() => null),\n // Cytoscape 3.10.5 draws an XGMML edge's EDGE_LABEL_AUTOROTATE true level, where it turns the same edge read\n // from CX, CX2 or a session along its line (the label-autorotate-true edge of the edge-labels and\n // mappings-bypass-p13 sheets in its SVG): its XGMML reader does not apply it, so neither does graph-io\n bypasses: maps.map((m) => (m?.has(AUTOROTATE_VP) === true ? withoutKey(m, AUTOROTATE_VP) : m)),\n ends: options.ends,\n };\n const out = resolveCytoscape(target, style, elements, { notes, budget: options.budget });\n if (target === \"node\" && out.width === undefined) {\n const size = maps.map((m) => {\n const raw = m?.get(NODE_SIZE_VP);\n return raw === undefined ? null : sizeParser(raw, { notes, target, property: \"width\" });\n });\n if (size.some((v) => v !== null)) {\n out.width = size;\n out.height = size.slice();\n }\n }\n for (const m of maps) {\n if (!m) {\n continue;\n }\n for (const [k, v] of m) {\n if (k.startsWith(\"?\")) {\n notes.add(STYLE_ISSUE.NOT_CARRIED, target, k.slice(1), { sample: v });\n }\n }\n }\n fillToolDefaults(target, out, maps.length, options.defaults ?? null);\n return out;\n}\n","/**\n * A Cytoscape visual style as neutral rules: the defaults as one rule, then one rule per mapped column and kind.\n * Cytoscape's precedence (a mapping over a default) becomes rule order. Bypasses are not rules: they are the\n * per-element exceptions the planner lays on top of these.\n */\n\nimport type { CanonSite } from \"../canon/site.js\";\nimport { StyleNotes } from \"../notes.js\";\nimport { canonicalFor } from \"../plan/resolve.js\";\nimport type { ColumnRef, Mapping, StyleColumn, StyleRule, StyleTarget, StyleValue, StyleWorkBudget } from \"../types.js\";\nimport { type CytoscapeValueParser, NODE_SIZE_VP, sizeParser } from \"./lexicon.js\";\nimport type { CytoscapeStyle } from \"./mappings.js\";\nimport {\n bendParser,\n chooseVps,\n type CytoscapeElements,\n EDGE_BEND_VP,\n type ParsedMapping,\n parseMapping,\n vpUsage,\n} from \"./resolve.js\";\n\n/**\n * Options of `cytoscapeRules()`.\n * @category Styles\n */\nexport interface CytoscapeTranslateOptions {\n /** Where problems are noted. */\n readonly notes?: StyleNotes;\n /** The counted work budget. */\n readonly budget?: StyleWorkBudget;\n /**\n * The column a mapping over a file column reads; defaults to `{ data: column }`. A writer's own tagged columns\n * map back to style columns here.\n */\n readonly columnRef?: (column: string) => ColumnRef;\n}\n\n/**\n * Neutral rules of a Cytoscape style, and the style columns they read.\n * @category Styles\n */\nexport interface CytoscapeRules {\n /** The rules, bottom to top. */\n readonly rules: StyleRule[];\n /**\n * Style columns by key: a passthrough whose file values Cytoscape reads differently from their plain reading\n * (a 0..255 transparency, `ROUND_RECTANGLE`) reads its values from `cytoscape.<property>` instead.\n */\n readonly columns: Map<string, StyleColumn>;\n}\n\n/** A rule being built from one column and mapping kind. */\ninterface MappingRule {\n readonly id: string;\n readonly map: Record<string, Mapping>;\n}\n\n/**\n * Translates one target's Cytoscape style into neutral rules: one `defaults` rule over every element, then one\n * `mapping` rule per mapped column and mapping kind (`node.discrete.Type`), with `nodeSizeLocked` and\n * `arrowColorMatchesEdge` applied. Discrete keys keep their attribute type.\n * @param target - nodes or edges\n * @param style - the style\n * @param elements - the elements (their bypasses decide which visual property a property is read from)\n * @param options - notes, the budget and how a file column is referenced\n * @returns the rules and the style columns they read\n * @category Styles\n */\nexport function cytoscapeRules(\n target: StyleTarget,\n style: CytoscapeStyle,\n elements: CytoscapeElements,\n options: CytoscapeTranslateOptions = {},\n): CytoscapeRules {\n const notes = options.notes ?? new StyleNotes();\n const refOf = options.columnRef ?? ((column: string): ColumnRef => ({ data: column }));\n const s = style[target];\n const { used } = vpUsage(s, elements.bypasses ?? []);\n const chosen = chooseVps(target, s, used);\n const site = (property: string): CanonSite => ({ notes, target, property, budget: options.budget });\n const locked = target === \"node\" && s.dependencies.get(\"nodeSizeLocked\") === true;\n const matched = target === \"edge\" && s.dependencies.get(\"arrowColorMatchesEdge\") === true;\n\n const set = defaultValues(s, chosen, site, { locked, matched });\n const columns = new Map<string, StyleColumn>();\n const byColumn = new Map<string, MappingRule>();\n const reading: MappingRead = { target, refOf, elements, columns, notes, budget: options.budget };\n const add = (props: readonly string[], vp: string, parse: CytoscapeValueParser): void => {\n const raw = s.mappings.get(vp);\n if (raw === undefined) {\n return;\n }\n const parsed = parseMapping(raw, parse, site(props[0]), vp);\n const mapping = neutralMapping(parsed, props[0], parse, reading);\n const key = `${raw.kind}\\u0000${raw.column}`;\n let rule = byColumn.get(key);\n if (rule === undefined) {\n rule = { id: `${target}.${raw.kind}.${raw.column}`, map: {} };\n byColumn.set(key, rule);\n }\n for (const p of props) {\n rule.map[p] = mapping;\n }\n };\n for (const [prop, [vp, parse]] of chosen) {\n add(matched && prop === \"color\" ? [\"color\", \"sourceArrowColor\", \"targetArrowColor\"] : [prop], vp, parse);\n }\n if (locked) {\n add([\"width\", \"height\"], NODE_SIZE_VP, sizeParser);\n }\n\n const rules: StyleRule[] = [];\n if (Object.keys(set).length > 0) {\n rules.push({\n id: `${target}.defaults`,\n target,\n role: \"defaults\",\n origin: \"declared\",\n where: { all: true },\n set,\n });\n }\n for (const r of byColumn.values()) {\n rules.push({ id: r.id, target, role: \"mapping\", origin: \"declared\", where: { all: true }, map: r.map });\n }\n return { rules, columns };\n}\n\n/**\n * The defaults rule's values: each chosen visual property's default, a locked node size as the width and height\n * (50 when unset), an edge color as both arrow colors when they match the edge, and `curved` only with default bends.\n * @param s - the target's style\n * @param chosen - the visual property and parser each neutral property is read from\n * @param site - where a value of a property is read\n * @param deps - the dependencies that apply\n * @param deps.locked - `nodeSizeLocked`\n * @param deps.matched - `arrowColorMatchesEdge`\n * @returns the values\n */\nfunction defaultValues(\n s: CytoscapeStyle[\"node\"],\n chosen: ReadonlyMap<string, readonly [string, CytoscapeValueParser]>,\n site: (property: string) => CanonSite,\n deps: { readonly locked: boolean; readonly matched: boolean },\n): Record<string, StyleValue> {\n const set: Record<string, StyleValue> = {};\n for (const [prop, [vp, parse]] of chosen) {\n const v = s.defaults.has(vp) ? parse(s.defaults.get(vp), site(prop)) : null;\n if (v !== null) {\n set[prop] = v;\n }\n }\n if (deps.locked) {\n const size = s.defaults.has(NODE_SIZE_VP) ? sizeParser(s.defaults.get(NODE_SIZE_VP), site(\"width\")) : null;\n set.width = size ?? 50;\n set.height = size ?? 50;\n }\n if (deps.matched && set.color !== undefined) {\n set.sourceArrowColor = set.color;\n set.targetArrowColor = set.color;\n }\n // EDGE_CURVED only rounds bends: with no default bends, the default edge is straight\n if (set.curved === true && bendParser(s.defaults.get(EDGE_BEND_VP), site(\"curved\")) !== true) {\n set.curved = false;\n }\n return set;\n}\n\n/** What turning one target's Cytoscape mappings into neutral ones reads. */\ninterface MappingRead {\n readonly target: StyleTarget;\n /** How a file column is referenced. */\n readonly refOf: (column: string) => ColumnRef;\n readonly elements: CytoscapeElements;\n /** Where a copied column is put. */\n readonly columns: Map<string, StyleColumn>;\n readonly notes: StyleNotes;\n readonly budget: StyleWorkBudget | undefined;\n}\n\n/**\n * A parsed Cytoscape mapping as a neutral mapping. A passthrough stays a passthrough over the file's column when\n * the planner's reading of every value equals Cytoscape's; otherwise Cytoscape's values are copied into the style\n * column `cytoscape.<property>`, which the passthrough reads.\n * @param m - the parsed mapping\n * @param property - the first property it sets\n * @param parse - Cytoscape's parser for the property\n * @param reading - the target, the elements and where copies go\n * @returns the neutral mapping\n */\nfunction neutralMapping(\n m: ParsedMapping,\n property: string,\n parse: CytoscapeValueParser,\n reading: MappingRead,\n): Mapping {\n const { target, elements, columns, notes, budget } = reading;\n const by = reading.refOf(m.column);\n if (m.kind === \"discrete\") {\n return { kind: \"discrete\", by, table: m.table };\n }\n if (m.kind === \"continuous\") {\n return { kind: \"continuous\", by, points: m.points, ...(m.step === undefined ? {} : { step: m.step }) };\n }\n const plain = \"style\" in by ? styleCell : canonicalFor(target, property);\n const n = elements.count;\n budget?.spend(target, n);\n const values = new Array<StyleValue | null>(n);\n let same = true;\n for (let i = 0; i < n; i++) {\n const raw = elements.value(m.column, i);\n const cy =\n raw === null || raw === undefined || Array.isArray(raw)\n ? null\n : parse(raw, { notes, target, property, element: i });\n values[i] = cy;\n if (same && cy !== (raw === null || raw === undefined || Array.isArray(raw) ? null : plain(raw))) {\n same = false;\n }\n }\n if (same) {\n return { kind: \"passthrough\", by };\n }\n const key = `cytoscape.${property}`;\n columns.set(key, values);\n return { kind: \"passthrough\", by: { style: key } };\n}\n\n/**\n * How the resolver reads a style column's cell: a scalar as it is.\n * @param raw - the cell\n * @returns the value, or null\n */\nfunction styleCell(raw: unknown): StyleValue | null {\n return typeof raw === \"string\" || typeof raw === \"number\" || typeof raw === \"boolean\" ? raw : null;\n}\n","/**\n * What the XGMML importer and exporter share: the namespaces, the format facts, the fixed column\n * names, the `meta.extra` key, and the issue and loss code tables.\n */\n\nimport {\n AMBIGUOUS_GRAPH_NAME_CODE,\n BAD_VALUE_CODE,\n COLUMN_RENAMED_CODE,\n COLUMN_RENAMED_LOSS_CODE,\n DANGLING_REFERENCE_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n DUPLICATE_ATTRIBUTE_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_NODE_CODE,\n ELEMENT_ISSUE,\n EMPTY_INPUT_CODE,\n ENCODING_CONFLICT_CODE,\n ENCODING_FALLBACK_CODE,\n EQUATION_AS_TEXT_CODE,\n GRAPH_NOT_FOUND_CODE,\n ID_MERGED_CODE,\n ID_TEXT_TYPE_CODE,\n INPUT_ISSUE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MIXED_DIRECTION_CODE,\n MULTIPLE_GRAPHS_CODE,\n MUTUAL_EXPANDED_CODE,\n NO_GRAPH_CODE,\n OPTION_IGNORED_CODE,\n PARENT_CYCLE_CODE,\n PARENTS_DROPPED_CODE,\n PRECISION_CODE,\n ROLE_ASSUMED_CODE,\n ROLE_DROPPED_CODE,\n ROLE_TAKEN_CODE,\n SINK_OPTION_CODE,\n STORAGE_CLASS_CODE,\n STRAY_TEXT_CODE,\n TEMPORAL_DROPPED_CODE,\n TEMPORAL_TEXT_DROPPED_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ELEMENT_CODE,\n UNKNOWN_ENCODING_CODE,\n UNKNOWN_PARENT_CODE,\n WEIGHT_KEY_CLASH_CODE,\n WIDENED_CODE,\n XML_ILLEGAL_CHAR_CODE,\n XML_NESTING_CODE,\n XML_SYNTAX_CODE,\n} from \"../../common/codes.js\";\n\n/**\n * The format name.\n * @category Plugin helpers\n */\nexport const FORMAT = \"xgmml\";\n\n/**\n * File extensions (never `.gr`, which DIMACS owns).\n * @category Plugin helpers\n */\nexport const EXTENSIONS: readonly string[] = Object.freeze([\".xgmml\", \".xml\"]);\n\n/**\n * MIME types: the draft's (appendix E) and Cytoscape's.\n * @category Plugin helpers\n */\nexport const MIME_TYPES: readonly string[] = Object.freeze([\"application/xgmml\", \"text/xgmml\", \"text/xgmml+xml\"]);\n\n/**\n * The XGMML namespace.\n * @category Plugin helpers\n */\nexport const XGMML_NAMESPACE = \"http://www.cs.rpi.edu/XGMML\";\n\n/**\n * Cytoscape's namespace, bound to the `cy` prefix.\n * @category Plugin helpers\n */\nexport const CY_NAMESPACE = \"http://www.cytoscape.org\";\n\n/**\n * The XLink namespace.\n * @category Plugin helpers\n */\nexport const XLINK_NAMESPACE = \"http://www.w3.org/1999/xlink\";\n\n/**\n * The `meta.extra` key the importer writes and the exporter reads.\n * @category Plugin helpers\n */\nexport const META_KEY = \"xgmml\";\n\n/**\n * The label column (role label) of node and edge `label` attributes.\n * @category Plugin helpers\n */\nexport const LABEL_COLUMN = \"label\";\n\n/**\n * The edge `id` column (role id, unique).\n * @category Plugin helpers\n */\nexport const EDGE_ID_COLUMN = \"id\";\n\n/**\n * The node position (f64 x3, role position, y up).\n * @category Plugin helpers\n */\nexport const POSITION_COLUMN = \"position\";\n\n/**\n * Cytoscape's stacking order (`NODE_Z_LOCATION`), kept out of the position.\n * @category Plugin helpers\n */\nexport const Z_COLUMN = \"z\";\n\n/**\n * The node, edge and graph json column of a `<graphics>` element's values as written.\n * @category Plugin helpers\n */\nexport const GRAPHICS_COLUMN = \"graphics\";\n\n/**\n * The containing group node (u32, role parent).\n * @category Plugin helpers\n */\nexport const PARENT_COLUMN = \"parent\";\n\n/**\n * Every containing group node of a node that is in several groups (list of u32, role parents).\n * @category Plugin helpers\n */\nexport const PARENTS_COLUMN = \"parents\";\n\n/**\n * The json node column of a group's nested graph id, label and atts.\n * @category Plugin helpers\n */\nexport const SUBGRAPH_COLUMN = \"xgmml.subgraph\";\n\n/**\n * The string node column naming the network a node's nested-network pointer points to.\n * @category Plugin helpers\n */\nexport const NESTED_NETWORK_COLUMN = \"cytoscape.nestedNetwork\";\n\n/**\n * The string node column of a nested-network pointer into another file (`file.xgmml#id`).\n * @category Plugin helpers\n */\nexport const NETWORK_POINTER_COLUMN = \"xgmml.networkPointer\";\n\n/**\n * The list node column of the root-level subgraphs a node belongs to, in a generic document.\n * @category Plugin helpers\n */\nexport const NETWORKS_COLUMN = \"xgmml.networks\";\n\n/**\n * The edge column of Cytoscape's interaction type.\n * @category Plugin helpers\n */\nexport const INTERACTION_COLUMN = \"interaction\";\n\n/**\n * The `origin.namespace` of the columns the importer derives from XGMML structure.\n * @category Plugin helpers\n */\nexport const XGMML_ORIGIN_NAMESPACE = \"xgmml\";\n\n/**\n * The `origin.namespace` of the columns that hold Cytoscape-only data (z, nested networks).\n * @category Plugin helpers\n */\nexport const CYTOSCAPE_ORIGIN_NAMESPACE = \"cytoscape\";\n\n/**\n * The issue codes the XGMML importer records, by name: the codes shared with\n * the other importers and the XGMML-specific ones. A key is the code without\n * its severity and format prefixes.\n * @category Built-in formats\n */\nexport const XGMML_ISSUE = Object.freeze({\n ...INPUT_ISSUE,\n ...ELEMENT_ISSUE,\n /** The input is not well-formed XML. The import stops. */\n XML_SYNTAX: XML_SYNTAX_CODE,\n /** Elements are nested more than 100,000 deep. The import stops. */\n XML_NESTING: XML_NESTING_CODE,\n /** The input is empty or whitespace only. The import stops. */\n EMPTY_INPUT: EMPTY_INPUT_CODE,\n /** The input is not valid UTF-8. The import stops. */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /**\n * Some bytes are not valid in the encoding that was chosen (by a byte order mark, the file's declaration or the\n * `encoding` option). The import stops.\n */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Undeclared non-UTF-8 bytes were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** A declared encoding the byte order mark contradicts (the mark wins). */\n ENCODING_CONFLICT: ENCODING_CONFLICT_CODE,\n /**\n * The root element is not `<graph>` (it may be an XHTML page with a graph inside, or a GraphML file). The import\n * stops.\n */\n NO_GRAPH: NO_GRAPH_CODE,\n /**\n * The file is a Cytoscape session view (`cy:view=\"1\"`), which holds only view settings and no nodes or edges. The\n * import stops.\n */\n VIEW_DOCUMENT: \"E_XGMML_VIEW_DOCUMENT\",\n /** A node with neither an id nor a label; it is skipped with its subtree. */\n MISSING_ID: MISSING_ID_CODE,\n /** A node without an id; its label is used as the id. */\n ID_FROM_LABEL: \"W_XGMML_ID_FROM_LABEL\",\n /** A node or edge with both an id and an `xlink:href`; it is read as the reference. */\n ID_AND_HREF: \"W_XGMML_ID_AND_HREF\",\n /** An edge without a source or a target that no label alias resolves. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** An edge endpoint that names no node (addMissingNodes false); the edge is skipped. */\n UNKNOWN_NODE: \"E_UNKNOWN_NODE\",\n /** Endpoints resolved through Cytoscape's `\"a (pp) b\"` label aliases; interactions filled from labels. */\n LABEL_ALIAS: \"W_XGMML_LABEL_ALIAS\",\n /** A node id declared twice; the declarations are merged. */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** An edge id used twice; the second edge is skipped. */\n DUPLICATE_EDGE_ID: DUPLICATE_EDGE_ID_CODE,\n /**\n * Cytoscape 2.x writes each edge of a group a second time, inside the group. The repeats are dropped, so every edge\n * is read once; nothing is lost.\n */\n GROUP_DUPLICATE_EDGE: \"W_XGMML_GROUP_DUPLICATE_EDGE\",\n /** A `directed` or `cy:directed` value other than 0 / 1. */\n BAD_DIRECTED: \"W_XGMML_BAD_DIRECTED\",\n /** A `documentVersion` that does not parse; the dialect is chosen from the content. */\n DOCUMENT_VERSION: \"W_XGMML_DOCUMENT_VERSION\",\n /** A root `<graph>` with neither the XGMML namespace nor an XGMML DOCTYPE. */\n NO_NAMESPACE: \"W_XGMML_NO_NAMESPACE\",\n /** A malformed `<att>`: a list with a value, a scalar with child atts, an att with no name. */\n BAD_ATT: \"W_XGMML_BAD_ATT\",\n /** A bare `&` read as `&` under repairBareAmpersands. */\n AMPERSAND_REPAIRED: \"W_XGMML_AMPERSAND_REPAIRED\",\n /** Two surrogate character references joined under pairSurrogateReferences. */\n SURROGATE_PAIRED: \"W_XGMML_SURROGATE_PAIRED\",\n /** An empty list whose element type nothing states; a list of strings is assumed. */\n EMPTY_LIST_TYPE: \"W_XGMML_EMPTY_LIST_TYPE\",\n /**\n * An attribute holds a structure a single column cannot (a list of records, a list of lists, a Cytoscape 2.x map\n * or XML from another tool). Its value is kept as a JSON value, which a save as XGMML writes back.\n */\n RECORD_LIST: \"W_XGMML_RECORD_LIST\",\n /** A pointer into another file (`file.xgmml#id`); kept as text. */\n CROSS_FILE_REFERENCE: \"W_XGMML_CROSS_FILE_REFERENCE\",\n /** A graph nested in an edge's att; there is no model for it. */\n EDGE_NESTED_GRAPH: \"W_XGMML_EDGE_NESTED_GRAPH\",\n /**\n * Some nodes or edges of a Cytoscape session belong to none of its networks (Cytoscape keeps group meta-edges and\n * the members of collapsed groups this way). They are not read; the message counts them.\n */\n ROOT_ONLY_ELEMENTS: \"W_XGMML_ROOT_ONLY_ELEMENTS\",\n /** A value that does not parse as its declared type; the cell is unset. */\n BAD_VALUE: BAD_VALUE_CODE,\n /**\n * An attribute's type was widened because a later value did not fit: an integer above 2^31 in an integer column,\n * or two declared types for one attribute.\n */\n WIDENED: WIDENED_CODE,\n /** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: \"string\"` to keep every digit. */\n PRECISION: PRECISION_CODE,\n /** A reference (xlink:href, nested-network pointer) that names nothing. */\n DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,\n /** The same attribute twice on one element; the later value wins. */\n DUPLICATE_ATTRIBUTE: DUPLICATE_ATTRIBUTE_CODE,\n /** A group membership naming no node. */\n UNKNOWN_PARENT: UNKNOWN_PARENT_CODE,\n /** A group membership that would close a parent cycle; that link is dropped. */\n PARENT_CYCLE: PARENT_CYCLE_CODE,\n /** A Cytoscape formula kept as its text. */\n EQUATION_AS_TEXT: EQUATION_AS_TEXT_CODE,\n /** An att type XGMML and Cytoscape do not define; kept as text. */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** An element XGMML does not define at that place; skipped with its subtree. */\n UNKNOWN_ELEMENT: UNKNOWN_ELEMENT_CODE,\n /** Character data where XGMML allows only elements, or inside an att. */\n STRAY_TEXT: STRAY_TEXT_CODE,\n /**\n * The file holds several graphs and only the first was read. It is not added when `graphIndex` or `graphName` chose the graph.\n * `importAllGraphs()` reads every one.\n */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** `graphIndex` or `graphName` matches no network in the session. The import stops. */\n GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,\n /** `graphName` matches several networks in the session. The import stops. */\n AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,\n /**\n * An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example\n * two attributes declared with the same name.\n */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /**\n * You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as\n * a plain attribute.\n */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** Two different id texts became the same number because `ids` is \"number\", so their nodes were merged. */\n ID_MERGED: ID_MERGED_CODE,\n /** You set an option this format does not use; it had no effect. The message names the option. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /**\n * You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,\n * `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.\n */\n SINK_OPTION: SINK_OPTION_CODE,\n /**\n * You read into a graph builder whose direction is already set, or which already holds edges, so the file is read\n * with the builder's direction instead of its own.\n */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges of the other direction were read with the direction `onMixedDirection` chose. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /**\n * The graph has both directed and undirected edges and `onMixedDirection` is \"error\". An import stops; a save to a\n * format that holds one direction per file fails with E_DIRECTED. Pass \"directed\" or \"undirected\" to read or write\n * it anyway.\n */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n});\n\n/**\n * Loss note codes of the XGMML exporter (check()): the XGMML ones and the shared ones its notes\n * can carry. The generic notes of `checkCapabilities()` (dtypes, components, temporal and visual\n * roles, extension tables) are those of `LOSS`.\n * @category Built-in formats\n */\nexport const XGMML_LOSS = Object.freeze({\n /** A json or nested-list column written as a string att. */\n JSON_AS_STRING: \"W_XGMML_JSON_AS_STRING\",\n /**\n * An attribute type Cytoscape does not have is written as a wider one (a 32-bit float as Double, a large unsigned\n * integer as Long, a byte as Integer, a dictionary as String).\n */\n WIDENED_TYPE: \"W_XGMML_WIDENED_TYPE\",\n /** A text value holds a character XML 1.0 forbids (most control characters); the save fails with E_COLUMN_TYPE. */\n XML_ILLEGAL_CHAR: XML_ILLEGAL_CHAR_CODE,\n /** A temporal column written as plain numbers. */\n TEMPORAL_DROPPED: TEMPORAL_DROPPED_CODE,\n /** A temporal text companion written as a plain string att. */\n TEMPORAL_TEXT_DROPPED: TEMPORAL_TEXT_DROPPED_CODE,\n /** An attribute with a role the format has no place for is written as a plain attribute; the role is lost. */\n ROLE_DROPPED: ROLE_DROPPED_CODE,\n /**\n * A `parents` attribute (several parents per node) is not written because the graph also has a `parent` attribute.\n */\n PARENTS_DROPPED: PARENTS_DROPPED_CODE,\n /** A mutual pair written as two directed edges. */\n MUTUAL_EXPANDED: MUTUAL_EXPANDED_CODE,\n /** Node ids whose text reads back as the other type. */\n ID_TEXT_TYPE: ID_TEXT_TYPE_CODE,\n /** Edge ids that are not text are written as text and read back as text. */\n EDGE_ID_TEXT: \"W_XGMML_EDGE_ID_TEXT\",\n /** Strings holding a literal backslash-n or backslash-t read back as newline / tab (Cytoscape's escapes). */\n BACKSLASH_ESCAPE: \"W_XGMML_BACKSLASH_ESCAPE\",\n /** A position that cannot be written as it is: another shape, a non-finite coordinate, a z read back in the z column. */\n POSITION: \"W_XGMML_POSITION\",\n /** Nodes whose parent chain never reaches a root are written at the top level. */\n PARENT_CYCLE: \"W_XGMML_PARENT_CYCLE\",\n /**\n * An attribute with a role (for example, the label) is written where the format keeps that role, and reads back under the\n * name the format's importer gives it.\n */\n COLUMN_NAME_CHANGED: COLUMN_RENAMED_LOSS_CODE,\n /**\n * An attribute without a role is written where the format keeps a role (for example, a `name` column as the label), and\n * reads back with that role.\n */\n ROLE_ASSUMED: ROLE_ASSUMED_CODE,\n /** An attribute named `weight` without the weight role reads back as the edge weight. */\n WEIGHT_KEY_CLASH: WEIGHT_KEY_CLASH_CODE,\n /**\n * A text attribute reads back as a dictionary attribute, or the reverse, because the importer chooses by how often\n * its values repeat. The values are the same.\n */\n STORAGE_CLASS_CHANGED: STORAGE_CLASS_CODE,\n /** Edge labels shaped `a (i) b` read back with an `interaction` column (Cytoscape's label alias). */\n INTERACTION_FROM_LABEL: \"W_XGMML_INTERACTION_FROM_LABEL\",\n});\n","/**\n * The styles of XGMML files and Cytoscape 2.x session networks: Cytoscape writes every element's RESOLVED visual\n * properties into its `<graphics>` (XML attributes in the old spelling, nested `<att>` elements named for the visual\n * property, and the locked ones under `lockedVisualProperties`), and no style. The reader turns those values into\n * the neutral vocabulary; the planner explains them. The writer does the reverse from what graphty draws.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { type BendPoint, canonBends } from \"../../styles/canon/bends.js\";\nimport { STYLE_ISSUE } from \"../../styles/codes.js\";\nimport {\n type CytoscapeDialect,\n cytoscapeElementProperties,\n cytoscapeWritableProperties,\n} from \"../../styles/cytoscape/emit.js\";\nimport { normalizeVisualProperties } from \"../../styles/cytoscape/lexicon.js\";\nimport { type CytoscapeStyle, emptyCytoscapeStyle } from \"../../styles/cytoscape/mappings.js\";\nimport {\n cytoscapeBackground,\n type CytoscapeBypass,\n type CytoscapeElements,\n edgeEnds,\n resolveCytoscapeBypasses,\n} from \"../../styles/cytoscape/resolve.js\";\nimport { STYLE_BLOCK_NAME } from \"../../styles/io/block.js\";\nimport { takeFromBlock } from \"../../styles/io/round-trip.js\";\nimport type { ExporterStyleInput } from \"../../styles/io/writer.js\";\nimport { StyleNotes } from \"../../styles/notes.js\";\nimport { plainCell } from \"../../styles/plan/resolve.js\";\nimport type {\n EdgeStyleProperty,\n GraphStyle,\n ImporterStyles,\n NodeStyleProperty,\n ReaderOutput,\n StyleColumn,\n StyleProperty,\n StyleReadContext,\n StyleTarget,\n StyleTool,\n StyleValue,\n StyleWriteCapabilities,\n} from \"../../styles/types.js\";\nimport type { LossNote } from \"../../types.js\";\nimport { lossOf } from \"../cx/styles.js\";\nimport { GRAPHICS_COLUMN, SUBGRAPH_COLUMN, XGMML_ORIGIN_NAMESPACE } from \"./constants.js\";\n\ntype Table = GraphSnapshot[\"nodes\"];\n\n/**\n * The name of a table's graphics column: the json column the XGMML reader keeps `<graphics>` in.\n * @param table - the node, edge or graph table\n * @returns the column's name, or null\n */\nfunction graphicsColumnOf(table: Table): string | null {\n for (const col of table) {\n const { origin } = col.meta;\n if (col.dtype === \"json\" && origin?.type === \"graphics\" && origin.namespace === XGMML_ORIGIN_NAMESPACE) {\n return col.meta.name;\n }\n }\n return table.get(GRAPHICS_COLUMN)?.dtype === \"json\" ? GRAPHICS_COLUMN : null;\n}\n\n/**\n * Each element's visual properties from its graphics: the graphics values normalized to visual property names, the\n * locked ones (`lockedVisualProperties`, a session view's bypasses) on top.\n * @param table - the node or edge table\n * @param target - nodes or edges\n * @param n - the element count\n * @param notes - where too-deep nesting is noted\n * @returns per element, its visual properties (null without graphics)\n */\nexport function graphicsBypasses(table: Table, target: StyleTarget, n: number, notes: StyleNotes): CytoscapeBypass[] {\n const out = new Array<CytoscapeBypass>(n).fill(null);\n const name = graphicsColumnOf(table);\n if (name === null) {\n return out;\n }\n for (let i = 0; i < n; i++) {\n const g = plainCell(table.value(name, i));\n if (g === null || typeof g !== \"object\" || Array.isArray(g)) {\n continue;\n }\n const map = normalizeVisualProperties(target, g, notes);\n const locked = Object.hasOwn(g, \"lockedVisualProperties\")\n ? (g as Record<string, unknown>).lockedVisualProperties\n : undefined;\n if (locked !== null && typeof locked === \"object\") {\n for (const [k, v] of normalizeVisualProperties(target, locked, notes)) {\n map.set(k, v);\n }\n }\n out[i] = map.size > 0 ? map : null;\n }\n return out;\n}\n\n/** What the XGMML style reader is told by its caller. */\ninterface XgmmlStyleSettings {\n /** Whose defaults fill what the file leaves unset. */\n readonly tool: StyleTool;\n /** A bool column marking hidden elements (a Cytoscape 2.x session's hidden state), or null. */\n readonly hiddenColumn?: string | null;\n}\n\n/**\n * The styles of a graph whose elements carry Cytoscape's resolved visual properties in their graphics.\n * @param snapshot - the graph\n * @param context - the budget and cancel signal\n * @param settings - the tool and the hidden-state column\n * @returns the styles (canonical values, no declared rules)\n */\nexport function readXgmmlStyles(\n snapshot: GraphSnapshot,\n context: StyleReadContext,\n settings: XgmmlStyleSettings,\n): ImporterStyles {\n const notes = new StyleNotes();\n const out: Record<StyleTarget, ReaderOutput> = { node: { values: {} }, edge: { values: {} } };\n for (const target of [\"node\", \"edge\"] as const) {\n context.signal?.throwIfAborted();\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const maps = graphicsBypasses(table, target, n, notes);\n const values = maps.some((m) => m !== null)\n ? resolveCytoscapeBypasses(target, maps, {\n notes,\n budget: context.budget,\n value: (column, i) => (table.has(column) ? plainCell(table.value(column, i)) : null),\n ...(target === \"edge\" ? { ends: edgeEnds(snapshot, out.node.values) } : {}),\n })\n : {};\n drawnAsDesktop(snapshot, target, out.node.values, values, settings);\n exactFromBlock(snapshot, target, values);\n out[target] = { values: nonEmpty(values) };\n }\n return {\n canonical: true,\n dialect: \"cytoscape\",\n tool: settings.tool,\n units: \"px\",\n node: out.node,\n edge: out.edge,\n graph: graphStyleOf(snapshot, notes),\n notes: notes.list(),\n };\n}\n\n/**\n * What Cytoscape desktop draws of an XGMML file's resolved values: hidden elements, the groups it hides and the\n * edges of every node it does not draw not visible, nodes with no label labeled by their names, and edge bends at the\n * network origin.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @param nodes - the node values per property (read for edges)\n * @param values - the values per property, changed in place\n * @param settings - the tool and the hidden-state column\n */\nfunction drawnAsDesktop(\n snapshot: GraphSnapshot,\n target: StyleTarget,\n nodes: Partial<Record<string, StyleColumn>>,\n values: Partial<Record<string, StyleColumn>>,\n settings: XgmmlStyleSettings,\n): void {\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const desktop = settings.tool === \"cytoscape\";\n if (target === \"edge\" && desktop) {\n bendsAtOrigin(snapshot, values);\n }\n hiddenToVisible(table, settings.hiddenColumn ?? null, n, values);\n hideWhatCytoscapeHides(snapshot, target, nodes, values);\n if (target === \"node\") {\n if (desktop && values.label === undefined && !snapshot.graph.has(STYLE_BLOCK_NAME)) {\n nameLabels(table, n, values);\n }\n }\n}\n\n/**\n * Every bend of an edge where Cytoscape desktop draws it from an XGMML file: at the network's origin. Its XGMML reader\n * turns each `EDGE_BEND` handle (`cos,sin,ratio`, relative to the line between the two nodes) into a point while\n * every node is still at the origin and keeps that point, so each handle of each edge is drawn at (0, 0) of the\n * network, wherever the nodes then go (measured on Cytoscape 3.10.5's own SVG of an XGMML file with handles; its CX\n * reader places the same handles along their lines). An edge whose nodes have no position keeps its handles.\n * @param snapshot - the graph\n * @param values - the edge values per property, changed in place\n */\nfunction bendsAtOrigin(snapshot: GraphSnapshot, values: Partial<Record<string, StyleColumn>>): void {\n const { bends } = values;\n const position = snapshot.nodes.byRole(\"position\");\n if (bends === undefined || position === null) {\n return;\n }\n const center = (i: number): BendPoint | null => {\n const v = position.isSet(i) ? (position.value(i) as ArrayLike<number>) : null;\n return v === null ? null : [v[0], v[1]];\n };\n const { src, dst } = snapshot.edgeList();\n values.bends = bends.map((v, e) => {\n const [s, t] = [center(src[e]), center(dst[e])];\n if (typeof v !== \"string\" || s === null || t === null) {\n return v;\n }\n const handles = v.trim().split(/\\s+/).length;\n return (\n canonBends(\n s,\n t,\n Array.from({ length: handles }, (): BendPoint => [0, 0]),\n false,\n ) ?? v\n );\n });\n}\n\n/**\n * The labels Cytoscape shows for nodes whose graphics state none: its default style labels a node by its name, and\n * a node with no `name` att is named by its `label=` (Cytoscape 2.x files often carry only that). Not for a file\n * graphty wrote: its block says what to draw.\n * @param table - the node table\n * @param n - the node count\n * @param values - the values per property, changed in place\n */\nfunction nameLabels(table: Table, n: number, values: Partial<Record<string, StyleColumn>>): void {\n const label = table.byRole(\"label\")?.meta.name ?? null;\n const text = (column: string | null, i: number): string | null => {\n const v = column !== null && table.has(column) ? plainCell(table.value(column, i)) : null;\n return typeof v === \"string\" || typeof v === \"number\" ? String(v) : null;\n };\n const labels = Array.from({ length: n }, (_v, i) => text(\"name\", i) ?? text(label, i));\n if (labels.some((v) => v !== null)) {\n values.label = labels;\n }\n}\n\n/**\n * The styles of an XGMML file: its elements' resolved values, with Cytoscape desktop's default style beneath.\n * @param snapshot - the graph\n * @param context - the budget and cancel signal\n * @returns the styles\n */\nexport function readXgmmlFileStyles(snapshot: GraphSnapshot, context: StyleReadContext): ImporterStyles {\n return readXgmmlStyles(snapshot, context, { tool: \"cytoscape\" });\n}\n\n/**\n * For a file graphty wrote: where an element's value is what the writer's nearest Cytoscape value of the\n * `graphty.styles` block's value reads back as (a font family list written as its first family, a shape Cytoscape\n * does not have), the block's exact value is the truth, so a re-import gives the same rules. A value that differs\n * from what graphty wrote (another program edited it) stays the truth.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @param values - the values per property, changed in place\n * @param dialect - the Cytoscape dialect the file's values are written in\n * @param created - the order desktop creates the elements in, when the file is read with it (CX version 1)\n */\nexport function exactFromBlock(\n snapshot: GraphSnapshot,\n target: StyleTarget,\n values: Partial<Record<string, StyleColumn>>,\n dialect: CytoscapeDialect = \"desktop\",\n created?: NonNullable<CytoscapeElements[\"ends\"]>[\"created\"],\n): void {\n const text = snapshot.graph.has(STYLE_BLOCK_NAME) ? plainCell(snapshot.graph.value(STYLE_BLOCK_NAME, 0)) : null;\n if (typeof text !== \"string\") {\n return;\n }\n takeFromBlock(snapshot, text, \"xgmml\", (t, block) => {\n if (t !== target) {\n return null;\n }\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n // What each element's exact values are written as, read back the way the file is read.\n const written = Array.from({ length: n }, (_v, i) =>\n cytoscapeElementProperties(\n target,\n (property) => block(target, property)[i] ?? null,\n dialect,\n () => undefined,\n ),\n );\n // Desktop fans the curved edges between the same two nodes by the nodes' size, as the file is read\n const ends =\n target === \"edge\"\n ? {\n ends: {\n ...edgeEnds(snapshot, {\n width: block(\"node\", \"width\"),\n height: block(\"node\", \"height\"),\n borderWidth: block(\"node\", \"borderWidth\"),\n }),\n ...(created === undefined ? {} : { created }),\n },\n }\n : {};\n const readBack = resolveCytoscapeBypasses(target, written, { notes: new StyleNotes(), ...ends });\n return {\n values,\n properties: Object.keys(values).filter((p) => values[p] !== undefined && readBack[p] !== undefined),\n readBack: (i) => (property) => readBack[property]?.[i] ?? null,\n // a fan spacing, a curve or a loop's handles only desktop's fanning and looping give (graphty wrote none:\n // EDGE_CURVED defaults to true there) is graphty's own default again, and so is a label's place beside its\n // node, which desktop's anchors spell as an offset and a shift\n take: (property, wanted) => wanted !== null || BLOCK_DEFAULTED.has(property),\n };\n });\n}\n\n/** What a file graphty wrote leaves unset where Cytoscape's reading of it gives a value. */\nconst BLOCK_DEFAULTED: ReadonlySet<string> = new Set([\n \"fanSpacing\",\n \"curved\",\n \"bends\",\n \"bendCurve\",\n \"labelOffsetX\",\n \"labelOffsetY\",\n \"labelShiftX\",\n \"labelShiftY\",\n]);\n\n/**\n * Marks the elements a hidden-state column holds true as not visible.\n * @param table - the node or edge table\n * @param column - the bool column, or null\n * @param n - the element count\n * @param values - the values per property, changed in place\n */\nexport function hiddenToVisible(\n table: Table,\n column: string | null,\n n: number,\n values: Partial<Record<string, StyleColumn>>,\n): void {\n if (column === null || !table.has(column)) {\n return;\n }\n let visible: (StyleValue | null)[] | null = null;\n for (let i = 0; i < n; i++) {\n if (plainCell(table.value(column, i)) === true) {\n visible ??= values.visible === undefined ? new Array<StyleValue | null>(n).fill(null) : [...values.visible];\n visible[i] = false;\n }\n }\n if (visible !== null) {\n values.visible = visible;\n }\n}\n\n/**\n * Marks not visible what Cytoscape does not draw of its groups: an expanded group's own node (its members are drawn\n * in its place), and every node inside a collapsed group (the group's node is drawn in their place). A group is\n * collapsed when its nested graph's `__groupCollapsed.SUID` names the network being read. A file graphty wrote is\n * left alone: its block says what to draw.\n * @param snapshot - the graph\n * @param values - the node values per property, changed in place\n */\nfunction hideGroupsCytoscapeHides(snapshot: GraphSnapshot, values: Partial<Record<string, StyleColumn>>): void {\n const parent = snapshot.nodes.byRole(\"parent\");\n if (parent === null || snapshot.graph.has(STYLE_BLOCK_NAME)) {\n return;\n }\n const n = snapshot.nodeCount;\n const members = membersOf(parent, n);\n if (members.size === 0) {\n return;\n }\n const network = (snapshot.meta.extra as { xgmml?: { graphId?: unknown } } | undefined)?.xgmml?.graphId;\n const visible = values.visible === undefined ? new Array<StyleValue | null>(n).fill(null) : [...values.visible];\n for (const [group, inside] of members) {\n if (!collapsedIn(snapshot, group, network)) {\n visible[group] = false;\n continue;\n }\n for (const i of insideAtAnyDepth(group, inside, members)) {\n visible[i] = false;\n }\n }\n values.visible = visible;\n}\n\n/**\n * Marks not visible what Cytoscape does not draw of its groups, and the edges of every node it does not draw.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @param nodes - the node values per property (read for edges)\n * @param values - the target's values per property, changed in place\n */\nexport function hideWhatCytoscapeHides(\n snapshot: GraphSnapshot,\n target: StyleTarget,\n nodes: Partial<Record<string, StyleColumn>>,\n values: Partial<Record<string, StyleColumn>>,\n): void {\n if (target === \"node\") {\n hideGroupsCytoscapeHides(snapshot, values);\n } else {\n hideEdgesOfHiddenNodes(snapshot, nodes, values);\n }\n}\n\n/**\n * Marks not visible every edge with an end Cytoscape does not draw: a collapsed group's members' own edges (the\n * group's meta-edges are drawn in their place), an expanded group node's meta-edges, and a hidden node's edges. A\n * file graphty wrote is left alone: its block says what to draw.\n * @param snapshot - the graph\n * @param nodes - the node values per property\n * @param values - the edge values per property, changed in place\n */\nfunction hideEdgesOfHiddenNodes(\n snapshot: GraphSnapshot,\n nodes: Partial<Record<string, StyleColumn>>,\n values: Partial<Record<string, StyleColumn>>,\n): void {\n const shown = nodes.visible;\n if (shown === undefined || !shown.includes(false) || snapshot.graph.has(STYLE_BLOCK_NAME)) {\n return;\n }\n const { src, dst } = snapshot.edgeList();\n const visible =\n values.visible === undefined ? new Array<StyleValue | null>(src.length).fill(null) : [...values.visible];\n for (let e = 0; e < src.length; e++) {\n if (shown[src[e]] === false || shown[dst[e]] === false) {\n visible[e] = false;\n }\n }\n values.visible = visible;\n}\n\n/**\n * Each group node's direct members.\n * @param parent - the node parent column\n * @param n - the node count\n * @returns group node to its members\n */\nfunction membersOf(\n parent: NonNullable<ReturnType<GraphSnapshot[\"nodes\"][\"byRole\"]>>,\n n: number,\n): Map<number, number[]> {\n const members = new Map<number, number[]>();\n for (let i = 0; i < n; i++) {\n const g = parent.isSet(i) ? plainCell(parent.value(i)) : null;\n if (typeof g === \"number\" && g !== i) {\n members.set(g, [...(members.get(g) ?? []), i]);\n }\n }\n return members;\n}\n\n/**\n * Every node inside a group, at any depth.\n * @param group - the group node\n * @param inside - its direct members\n * @param members - each group node's direct members\n * @returns the nodes inside\n */\nfunction insideAtAnyDepth(group: number, inside: readonly number[], members: Map<number, number[]>): Set<number> {\n const stack = [...inside];\n const seen = new Set<number>([group]);\n const out = new Set<number>();\n for (let i = stack.pop(); i !== undefined; i = stack.pop()) {\n if (!seen.has(i)) {\n seen.add(i);\n out.add(i);\n stack.push(...(members.get(i) ?? []));\n }\n }\n return out;\n}\n\n/**\n * Whether a group node's nested graph says the group is collapsed in a network (`__groupCollapsed.SUID` lists it).\n * @param snapshot - the graph\n * @param group - the group node\n * @param network - the id of the network being read, or anything else when unknown\n * @returns true when collapsed there\n */\nfunction collapsedIn(snapshot: GraphSnapshot, group: number, network: unknown): boolean {\n if (typeof network !== \"string\" || !snapshot.nodes.has(SUBGRAPH_COLUMN)) {\n return false;\n }\n const sub = plainCell(snapshot.nodes.value(SUBGRAPH_COLUMN, group));\n const atts = sub !== null && typeof sub === \"object\" ? (sub as { atts?: unknown }).atts : null;\n const collapsed =\n atts !== null && typeof atts === \"object\" ? (atts as Record<string, unknown>)[\"__groupCollapsed.SUID\"] : null;\n return Array.isArray(collapsed) && collapsed.some((v) => String(v) === network);\n}\n\n/**\n * The properties with at least one value.\n * @param values - per property, each element's value\n * @returns the same without all-null properties\n */\nexport function nonEmpty(values: Partial<Record<string, StyleColumn>>): Partial<Record<StyleProperty, StyleColumn>> {\n const out: Partial<Record<string, StyleColumn>> = {};\n for (const [p, col] of Object.entries(values)) {\n if (col?.some((v) => v !== null) === true) {\n out[p] = col;\n }\n }\n return out;\n}\n\n/**\n * The graph's background: its own graphics' `NETWORK_BACKGROUND_PAINT`, the locked one (`lockedVisualProperties`, a\n * session view's bypass) on top, over the style's own.\n * @param snapshot - the graph\n * @param notes - where a bad value is noted\n * @param style - the style whose network defaults the graph's graphics override, or none\n * @returns the graph style\n * @category Styles\n */\nexport function graphStyleOf(snapshot: GraphSnapshot, notes: StyleNotes, style?: CytoscapeStyle): GraphStyle {\n const merged = emptyCytoscapeStyle();\n for (const [k, v] of style?.network.defaults ?? []) {\n merged.network.defaults.set(k, v);\n }\n for (const [k, v] of networkBypasses(snapshot, notes)) {\n merged.network.defaults.set(k, v);\n }\n const background = cytoscapeBackground(merged, notes);\n return background === null ? {} : { background };\n}\n\n/**\n * The network visual properties a graph's own graphics set, the locked ones (`lockedVisualProperties`) last.\n * @param snapshot - the graph\n * @param notes - where too-deep nesting is noted\n * @returns visual property name to raw value, in the order they apply\n */\nfunction networkBypasses(snapshot: GraphSnapshot, notes: StyleNotes): [string, unknown][] {\n const name = graphicsColumnOf(snapshot.graph);\n const g = name === null ? null : plainCell(snapshot.graph.value(name, 0));\n if (g === null || typeof g !== \"object\" || Array.isArray(g)) {\n return [];\n }\n const locked = Object.hasOwn(g, \"lockedVisualProperties\")\n ? (g as Record<string, unknown>).lockedVisualProperties\n : undefined;\n return [g, locked].flatMap((layer) =>\n [...normalizeVisualProperties(\"node\", layer, notes)].filter(([k]) => k.startsWith(\"NETWORK_\")),\n );\n}\n\n// ------------------------------------------------------------------ writing\n\n/**\n * What the XGMML writer holds natively: every visual property Cytoscape keeps per element, and the graph's\n * background. The block and the tagged values go into graph and element `<att>`s.\n */\nexport const XGMML_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({\n tool: \"cytoscape\",\n node: Object.freeze(cytoscapeWritableProperties(\"node\", \"desktop\") as NodeStyleProperty[]),\n edge: Object.freeze(cytoscapeWritableProperties(\"edge\", \"desktop\") as EdgeStyleProperty[]),\n graph: Object.freeze([\"background\"] as const),\n block: \"attributes\",\n});\n\n/** The visual properties Cytoscape also writes as `<graphics>` XML attributes, in its old spelling. */\nconst XML_ATTRIBUTES: Readonly<Record<StyleTarget, readonly (readonly [vp: string, attribute: string])[]>> = {\n node: [\n [\"NODE_SHAPE\", \"type\"],\n [\"NODE_HEIGHT\", \"h\"],\n [\"NODE_WIDTH\", \"w\"],\n [\"NODE_FILL_COLOR\", \"fill\"],\n [\"NODE_BORDER_WIDTH\", \"width\"],\n [\"NODE_BORDER_PAINT\", \"outline\"],\n ],\n edge: [\n [\"EDGE_WIDTH\", \"width\"],\n [\"EDGE_STROKE_UNSELECTED_PAINT\", \"fill\"],\n ],\n};\n\n/**\n * One element's graphics record for a file written with styles: what graphty draws as Cytoscape visual properties,\n * the six classic ones also as XML attributes (the importer reads both alike), over the kept graphics' visual\n * properties no neutral property carries (custom graphics, label widths) and edge bends.\n * @param target - nodes or edges\n * @param styles - the exporter's style input\n * @param i - the element index\n * @param kept - the element's kept graphics record, or null\n * @returns the record, or null when there is nothing to write\n */\nexport function styledGraphics(\n target: StyleTarget,\n styles: ExporterStyleInput,\n i: number,\n kept: Record<string, unknown> | null,\n): Record<string, unknown> | null {\n const vps = cytoscapeElementProperties(\n target,\n (p) => styles.picture(target, p as StyleProperty)[i] ?? null,\n \"desktop\",\n () => undefined,\n );\n const out: Record<string, unknown> = {};\n for (const [vp, attribute] of XML_ATTRIBUTES[target]) {\n if (vps.has(vp)) {\n out[attribute] = String(vps.get(vp));\n }\n }\n for (const [k, v] of Object.entries(kept ?? {})) {\n // a kept visual property the picture does not write, or the edge's bends; old-spelling and nested keys\n // would be read before the picture's values and contradict them\n if (k === \"Line\" || (/^[A-Z][A-Z_0-9]+$/.test(k) && !vps.has(k))) {\n out[k] = v;\n }\n }\n for (const [vp, v] of vps) {\n out[vp] = String(v);\n }\n return Object.keys(out).length === 0 ? null : out;\n}\n\n/**\n * What writing every element's graphics with styles loses: each value written as the nearest one Cytoscape allows,\n * counted per element.\n * @param styles - the exporter's style input\n * @param snapshot - the graph\n * @returns the loss notes\n */\nexport function styledGraphicsNotes(styles: ExporterStyleInput, snapshot: GraphSnapshot): LossNote[] {\n const notes = new StyleNotes();\n for (const target of [\"node\", \"edge\"] as const) {\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n for (let i = 0; i < n; i++) {\n cytoscapeElementProperties(\n target,\n (p) => styles.picture(target, p as StyleProperty)[i] ?? null,\n \"desktop\",\n (p) => {\n notes.add(STYLE_ISSUE.APPROXIMATED, target, p, { element: i });\n },\n );\n }\n }\n return notes.list().map(lossOf);\n}\n\n/**\n * The graph's graphics record for a file written with styles: the kept record with the background replaced.\n * @param styles - the exporter's style input\n * @param kept - the kept graph graphics, or null\n * @returns the record, or null\n */\nexport function styledGraphGraphics(\n styles: ExporterStyleInput,\n kept: Record<string, unknown> | null,\n): Record<string, unknown> | null {\n const { background } = styles.rules.styles.graph;\n const out: Record<string, unknown> = { ...kept };\n if (background !== undefined) {\n out.NETWORK_BACKGROUND_PAINT = background.toUpperCase();\n }\n return Object.keys(out).length === 0 ? null : out;\n}\n","/**\n * The styles of CX version 1 and CX2 files. Both hold one Cytoscape visual style (defaults, mappings and\n * dependencies) and per-element bypasses. The readers resolve every element the way Cytoscape draws it (bypass over\n * mapping over default) and translate the style into neutral rules, with Cytoscape desktop's default style beneath\n * (Cytoscape starts every imported CX or CX2 style as a copy of it). The writers do the reverse: neutral rules\n * become Cytoscape defaults and mappings, everything else per-element bypasses, so Cytoscape draws what graphty\n * draws; the `graphty.styles` block is an aspect of its own and the style values its rules read are attributes.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { STYLE_ISSUE } from \"../../styles/codes.js\";\nimport {\n type CytoscapeDialect,\n type CytoscapeEmitted,\n cytoscapeWritableProperties,\n emitCytoscapeStyle,\n} from \"../../styles/cytoscape/emit.js\";\nimport {\n type CytoscapeStyle,\n cytoscapeStyleFromCx,\n dropMismatchedKeys,\n sharedColumnFallback,\n weightColumnFallback,\n} from \"../../styles/cytoscape/mappings.js\";\nimport {\n cytoscapeBackground,\n type CytoscapeBypass,\n type CytoscapeElements,\n edgeEnds,\n resolveCytoscape,\n} from \"../../styles/cytoscape/resolve.js\";\nimport { cytoscapeRules } from \"../../styles/cytoscape/translate.js\";\nimport { STYLE_BLOCK_NAME } from \"../../styles/io/block.js\";\nimport type { ExporterStyleInput } from \"../../styles/io/writer.js\";\nimport { StyleNotes } from \"../../styles/notes.js\";\nimport { plainCell } from \"../../styles/plan/resolve.js\";\nimport type {\n EdgeStyleProperty,\n ImporterStyles,\n NodeStyleProperty,\n ReaderOutput,\n StyleColumn,\n StyleNote,\n StyleReadContext,\n StyleTarget,\n StyleWriteCapabilities,\n} from \"../../styles/types.js\";\nimport type { LossNote } from \"../../types.js\";\nimport { exactFromBlock, nonEmpty } from \"../xgmml/styles.js\";\n\ntype Table = GraphSnapshot[\"nodes\"];\n\n/**\n * The block text of a `graphty.styles` aspect (`[{ \"block\": \"<json>\" }]`, the aspect a CX or CX2 file graphty wrote\n * keeps its block in), or null when it holds none.\n * @param elements - the aspect's elements\n * @returns the text\n */\nexport function blockOfAspect(elements: readonly unknown[] | undefined): string | null {\n const first: unknown = elements?.[0];\n if (first === null || typeof first !== \"object\" || !Object.hasOwn(first, \"block\")) {\n return null;\n }\n const text = (first as { block: unknown }).block;\n return typeof text === \"string\" ? text : null;\n}\n\n/**\n * The `graphty.styles` aspect's elements for a block.\n * @param block - the block's text\n * @returns the elements\n */\nexport function blockAspect(block: string): Record<string, unknown>[] {\n return [{ block }];\n}\n\n/**\n * The `graphty.styles` block a snapshot carries as a graph attribute (an import of a file graphty wrote, or the one\n * graph-io adds for a styled export), or null.\n * @param snapshot - the graph\n * @returns the block's text\n */\nexport function snapshotBlock(snapshot: GraphSnapshot): string | null {\n const column = snapshot.graph.get(STYLE_BLOCK_NAME);\n const value = column?.isSet(0) ? column.value(0) : null;\n return typeof value === \"string\" ? value : null;\n}\n\n/** What a CX version 1 import keeps for its styles: the `cyVisualProperties` entries of the imported view. */\nexport interface CxStyleSource {\n /** The entries, in file order. */\n readonly entries: readonly unknown[];\n /** How many other views the file styles, whose entries were left out. */\n readonly otherViews?: number;\n /** The edge attribute the import read as the weight (its `weightFrom`), or null. */\n readonly weightFrom?: string | null;\n /** Whether the file is a collection (it has `cySubNetworks`), whose elements desktop creates in list order. */\n readonly collection?: boolean;\n}\n\n/** What a CX2 import keeps for its styles. */\nexport interface Cx2StyleSource {\n /** The `visualProperties` aspect. */\n readonly visualProperties: unknown;\n /** The `visualEditorProperties` aspect. */\n readonly visualEditorProperties: unknown;\n /** The edge attribute the import read as the weight (its `weightFrom`), or null. */\n readonly weightFrom?: string | null;\n}\n\n/**\n * Each element's bypasses: the columns of an importer's bypass namespace, keyed by the visual property's own name.\n * @param table - the node or edge table\n * @param n - the element count\n * @param namespace - the bypass namespace\n * @returns per element, its bypasses, and the bypass columns' names\n */\nfunction bypassesOf(table: Table, n: number, namespace: string): { maps: CytoscapeBypass[]; names: string[] } {\n const columns = [...table].filter((c) => c.meta.origin?.namespace === namespace);\n const maps = new Array<CytoscapeBypass>(n).fill(null);\n for (let i = 0; i < n; i++) {\n let m: Map<string, unknown> | null = null;\n for (const c of columns) {\n const v = plainCell(c.isSet(i) ? c.value(i) : null);\n if (v !== null) {\n m ??= new Map();\n const id = c.meta.origin?.id;\n m.set(typeof id === \"string\" && id.length > 0 ? id : c.meta.name, v);\n }\n }\n maps[i] = m;\n }\n return { maps, names: columns.map((c) => c.meta.name) };\n}\n\n/**\n * Points a target's mappings at the columns the import keeps them in (a shared column's plain one, the edge weight\n * column), empties the CX version 1 mappings whose key type the column cannot match, and notes a mapping over a\n * column the graph does not have.\n * @param style - the style, changed in place\n * @param target - nodes or edges\n * @param table - the target's table\n * @param read - where problems are noted, the dialect, and the attribute the import read as the edge weight\n * @param read.notes - where problems are noted\n * @param read.dialect - the Cytoscape dialect the file is written in\n * @param read.weightFrom - the edge attribute the import read as the weight, or null\n * @param read.weights - the weights a mapping over that attribute reads when no column holds them, or null\n */\nfunction fitMappingsToColumns(\n style: CytoscapeStyle,\n target: StyleTarget,\n table: Table,\n read: {\n readonly notes: StyleNotes;\n readonly dialect: CytoscapeDialect;\n readonly weightFrom: string | null;\n readonly weights: ExplicitWeights | null;\n },\n): void {\n const { notes } = read;\n sharedColumnFallback(style[target], (column) => table.has(column));\n if (target === \"edge\") {\n weightColumnFallback(style.edge, read.weightFrom, table);\n }\n // CX2's reader types a mapping's keys by the column; CX version 1 keeps the mapping's own type\n if (read.dialect !== \"cx2\") {\n dropMismatchedKeys(style[target], (column) => table.get(column)?.meta.origin?.type ?? null, notes, target);\n }\n for (const m of style[target].mappings.values()) {\n if (!table.has(m.column) && !(target === \"edge\" && read.weights !== null && m.column === read.weightFrom)) {\n notes.add(STYLE_ISSUE.MAPPING_COLUMN_MISSING, target, m.column, { sample: m.kind });\n }\n }\n}\n\n/**\n * The edge weights a mapping over the attribute read as the weight reads, when the import kept them as the graph's\n * weights only: no column of that name and no weight column (a CX2 file's integer `weight`). Null otherwise, when\n * the mapping reads a column.\n * @param snapshot - the graph\n * @param weightFrom - the attribute read as the weight, or null\n * @returns the weights, or null\n */\nfunction keptWeights(snapshot: GraphSnapshot, weightFrom: string | null): ExplicitWeights | null {\n if (weightFrom === null || snapshot.edges.has(weightFrom) || snapshot.edges.byRole(\"weight\") !== null) {\n return null;\n }\n const weights = explicitWeights(snapshot);\n return weights.weighted ? weights : null;\n}\n\n/**\n * Where a Java `HashMap<Long, ...>` holding these keys (inserted in this order) iterates each, first at 0: its\n * buckets in order (the key's `Long.hashCode` spread by `HashMap.hash`, masked by a capacity grown from 16 until the\n * keys fill at most three quarters of it), each bucket in insertion order. Null when a key is not a non-negative\n * integer (or its digits).\n * @param ids - the keys, in insertion order\n * @returns each key's rank, by insertion index, or null\n */\nfunction javaHashOrder(ids: readonly unknown[]): number[] | null {\n // an id read as text under the `ids` option is still the file's integer\n const keys = ids.map((k) => (typeof k === \"string\" && /^\\d{1,15}$/.test(k) ? Number(k) : k));\n if (!keys.every((k) => typeof k === \"number\" && Number.isSafeInteger(k) && k >= 0)) {\n return null;\n }\n let capacity = 16;\n while (keys.length > 0.75 * capacity) {\n capacity *= 2;\n }\n const bucket = (k: number): number => {\n // (int) (v ^ (v >>> 32)), then h ^ (h >>> 16)\n const h = ((k % 2 ** 32) ^ Math.floor(k / 2 ** 32)) >>> 0;\n return (h ^ (h >>> 16)) & (capacity - 1);\n };\n const order = keys.map((_, i) => i).sort((a, b) => bucket(keys[a] as number) - bucket(keys[b] as number) || a - b);\n const rank = new Array<number>(keys.length);\n order.forEach((i, r) => {\n rank[i] = r;\n });\n return rank;\n}\n\n/**\n * The order Cytoscape desktop creates a CX graph's nodes and edges in when it creates them in hash order: its CX\n * reader files them in `HashMap`s keyed by their ids and creates them as those iterate (`NiceCyRootNetwork.handleNodes`,\n * `addElements`, cx-support 2.8.4), which decides the side it fans parallel edges to. Null when an id is not an\n * integer or an edge has no id.\n * @param snapshot - the graph\n * @returns each node's and edge's rank, or null\n */\nexport function hashCreationOrder(snapshot: GraphSnapshot): NonNullable<CytoscapeElements[\"ends\"]>[\"created\"] | null {\n const ids = snapshot.edges.byRole(\"id\");\n if (ids === null) {\n return null;\n }\n const node = javaHashOrder(Array.from({ length: snapshot.nodeCount }, (_, i) => snapshot.ids.idOf(i)));\n const edge = javaHashOrder(Array.from({ length: snapshot.edgeCount }, (_, i) => ids.value(i)));\n return node === null || edge === null ? null : { node, edge };\n}\n\n/**\n * The styles of a graph from its Cytoscape style and its bypass columns.\n * @param snapshot - the graph\n * @param context - the budget and cancel signal\n * @param style - the file's style\n * @param namespace - the importer's bypass namespace\n * @param notes - where problems are noted\n * @param dialect - the Cytoscape dialect the file is written in\n * @param read - what the import read: the edge attribute it read as the weight (`weightFrom`, or null), and whether\n * Cytoscape desktop creates the file's elements in hash order (`hashOrder`: a CX version 1 file without subnetworks)\n * @param read.weightFrom - the weight attribute, or null\n * @param read.hashOrder - whether desktop creates the elements in hash order\n * @returns the styles\n */\nexport function readDeclaredStyles(\n snapshot: GraphSnapshot,\n context: StyleReadContext,\n style: CytoscapeStyle,\n namespace: string,\n notes: StyleNotes,\n dialect: CytoscapeDialect = \"desktop\",\n read: { readonly weightFrom?: string | null; readonly hashOrder?: boolean } = {},\n): ImporterStyles {\n const weightFrom = read.weightFrom ?? null;\n const created = read.hashOrder === true ? (hashCreationOrder(snapshot) ?? undefined) : undefined;\n const out: Record<StyleTarget, ReaderOutput> = { node: { values: {} }, edge: { values: {} } };\n const readFrom: Record<StyleTarget, string[]> = { node: [], edge: [] };\n for (const target of [\"node\", \"edge\"] as const) {\n context.signal?.throwIfAborted();\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const weights = target === \"edge\" ? keptWeights(snapshot, weightFrom) : null;\n fitMappingsToColumns(style, target, table, { notes, dialect, weightFrom, weights });\n const { maps, names } = bypassesOf(table, n, namespace);\n readFrom[target] = names;\n const elements: CytoscapeElements = {\n count: n,\n value: (column, i) => {\n if (weights !== null && column === weightFrom) {\n return weights.isExplicit(i) ? weights.value(i) : null;\n }\n return table.has(column) ? plainCell(table.value(column, i)) : null;\n },\n bypasses: maps,\n ...(target === \"edge\"\n ? { ends: { ...edgeEnds(snapshot, out.node.values), ...(created === undefined ? {} : { created }) } }\n : {}),\n };\n const values = resolveCytoscape(target, style, elements, { notes, budget: context.budget });\n // a file graphty wrote: a value its style writes as the nearest Cytoscape value is the block's\n exactFromBlock(snapshot, target, values, dialect, created);\n const { rules, columns } = cytoscapeRules(target, style, elements, { notes, budget: context.budget });\n out[target] = { values: nonEmpty(values), rules, columns };\n }\n const background = cytoscapeBackground(style, notes);\n return {\n canonical: true,\n dialect: \"cytoscape\",\n tool: \"cytoscape\",\n units: \"px\",\n node: out.node,\n edge: out.edge,\n graph: background === null ? {} : { background },\n notes: notes.list(),\n readFrom,\n };\n}\n\n/**\n * The styles of an imported CX version 1 network: the first view's `cyVisualProperties` (other views noted and\n * skipped), its bypasses, and Cytoscape desktop's default style beneath.\n * @param snapshot - the network\n * @param context - what the import kept, the budget and the cancel signal\n * @returns the styles\n */\nexport function readCxStyles(snapshot: GraphSnapshot, context: StyleReadContext): ImporterStyles {\n const notes = new StyleNotes();\n const kept = context.kept as CxStyleSource | undefined;\n const style = cytoscapeStyleFromCx(kept?.entries ?? [], notes);\n const otherViews = kept?.otherViews ?? 0;\n if (otherViews > 0) {\n notes.add(STYLE_ISSUE.OTHER_VIEWS, null, \"cyVisualProperties\", {\n sample: `${otherViews} more`,\n count: otherViews,\n });\n }\n return readDeclaredStyles(snapshot, context, style, \"cx.bypass\", notes, \"desktop\", {\n weightFrom: kept?.weightFrom ?? null,\n hashOrder: kept?.collection !== true,\n });\n}\n\n/**\n * The neutral properties a Cytoscape dialect writes, and the graph's background, as writer capabilities.\n * @param dialect - the dialect\n * @returns the capabilities\n */\nexport function cytoscapeWriteCapabilities(dialect: CytoscapeDialect): StyleWriteCapabilities {\n return Object.freeze({\n tool: \"cytoscape\",\n node: Object.freeze(cytoscapeWritableProperties(\"node\", dialect) as NodeStyleProperty[]),\n edge: Object.freeze(cytoscapeWritableProperties(\"edge\", dialect) as EdgeStyleProperty[]),\n graph: Object.freeze([\"background\"] as const),\n // graph-io adds the block as a graph attribute (the writer moves it into an aspect of its own) and the style\n // values the rules read as element attributes\n block: \"attributes\",\n });\n}\n\n/** What the CX version 1 writer holds of a graph's styles. */\nexport const CX_STYLE_CAPABILITIES: StyleWriteCapabilities = cytoscapeWriteCapabilities(\"desktop\");\n\n/**\n * The dtype a column of written style values gets: numbers, booleans or text (a mixed column as text).\n * @param col - the values\n * @returns the dtype\n */\nfunction valuesDtype(col: StyleColumn): \"f64\" | \"bool\" | \"string\" {\n const kinds = new Set(col.filter((v) => v !== null).map((v) => typeof v));\n if (kinds.size === 1 && kinds.has(\"number\")) {\n return \"f64\";\n }\n return kinds.size === 1 && kinds.has(\"boolean\") ? \"bool\" : \"string\";\n}\n\n/** A CX or CX2 export with styles worked out. */\ninterface CytoscapeStyledExport {\n /** The graph to write: the columns the style's mappings read that the graph does not hold, added. */\n readonly snapshot: GraphSnapshot;\n /** The style, its bypasses (by element index) and the added columns. */\n readonly styled: CytoscapeEmitted;\n /** Every value written approximately or flattened into bypasses, as loss notes. */\n readonly notes: readonly LossNote[];\n}\n\n/**\n * A style note as a loss note.\n * @param n - the note\n * @returns the loss note\n */\nexport function lossOf(n: StyleNote): LossNote {\n return Object.freeze({\n code: n.code,\n message: n.message,\n column: null,\n count: n.params.count,\n style:\n n.params.target === null || n.params.property === null || n.params.target === \"graph\"\n ? undefined\n : Object.freeze({ target: n.params.target, property: n.params.property as never }),\n });\n}\n\n/**\n * Works out a CX or CX2 export with styles: the Cytoscape style of the rules, the bypasses that make Cytoscape draw\n * exactly what they give, and the snapshot with the columns its mappings read added.\n * @param snapshot - the graph handed to the exporter\n * @param input - the styles, or undefined when none are written\n * @param dialect - `\"desktop\"` for CX version 1, `\"cx2\"` for CX2\n * @returns the styled export, or null without styles\n */\nexport function cytoscapeStyledExport(\n snapshot: GraphSnapshot,\n input: ExporterStyleInput | undefined,\n dialect: CytoscapeDialect,\n): CytoscapeStyledExport | null {\n if (input === undefined) {\n return null;\n }\n const notes = new StyleNotes();\n const styled = emitCytoscapeStyle(input.rules, snapshot, { dialect, notes });\n return { snapshot: withMappedColumns(snapshot, styled), styled, notes: notes.list().map(lossOf) };\n}\n\n/**\n * The snapshot with the columns the emitted mappings read and it lacks added.\n * @param snapshot - the graph handed to the exporter\n * @param styled - the emitted style\n * @returns the snapshot itself when it lacks none\n */\nfunction withMappedColumns(snapshot: GraphSnapshot, styled: CytoscapeEmitted): GraphSnapshot {\n const missing = ([\"node\", \"edge\"] as const).flatMap((target) =>\n [...styled.columns[target]]\n .filter(([name]) => !(target === \"node\" ? snapshot.nodes : snapshot.edges).has(name))\n .map(([name, values]) => ({ target, name, values })),\n );\n if (missing.length === 0) {\n return snapshot;\n }\n const out = snapshot.withColumns();\n for (const { target, name, values } of missing) {\n const dtype = valuesDtype(values);\n const col = dtype === \"string\" ? values.map((v) => (v === null ? null : String(v))) : values;\n (target === \"node\" ? out.nodes : out.edges).set(name, col, { dtype });\n }\n return out;\n}\n"],"names":["typeOf","cx2Points","kind","own","column"],"mappings":"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"}
|