@graphty/graph-io 0.3.43 → 0.3.45
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-DJMHdDvv.js +40 -0
- package/dist/chunks/approximations-DJMHdDvv.js.map +1 -0
- package/dist/chunks/block-CPCHkX42.js +2777 -0
- package/dist/chunks/block-CPCHkX42.js.map +1 -0
- package/dist/chunks/{choose-DvpbdRuz.js → choose--jM0yYCo.js} +3 -2
- package/dist/chunks/{choose-DvpbdRuz.js.map → choose--jM0yYCo.js.map} +1 -1
- package/dist/chunks/{constants-fT3E8JYY.js → constants-BKwqelYD.js} +6 -2
- package/dist/chunks/constants-BKwqelYD.js.map +1 -0
- package/dist/chunks/convert-BcQ8_jMo.js +59 -0
- package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
- package/dist/chunks/emit-DZy6JgdA.js +3456 -0
- package/dist/chunks/emit-DZy6JgdA.js.map +1 -0
- package/dist/chunks/{escape-B62ZGM_a.js → escape-CgzxiYPg.js} +44 -21
- package/dist/chunks/escape-CgzxiYPg.js.map +1 -0
- package/dist/chunks/{export-rKLeGQMo.js → export-BvqAXCKh.js} +196 -792
- package/dist/chunks/export-BvqAXCKh.js.map +1 -0
- package/dist/chunks/{exporter-yLxKBvLE.js → exporter--Mk9gXCJ.js} +4 -3
- package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter--Mk9gXCJ.js.map} +1 -1
- package/dist/chunks/{exporter-RVtXVetw.js → exporter-C-9cgZKa.js} +1805 -287
- package/dist/chunks/exporter-C-9cgZKa.js.map +1 -0
- package/dist/chunks/{exporter-8hLNemFk.js → exporter-DFqJhBnj.js} +133 -74
- package/dist/chunks/exporter-DFqJhBnj.js.map +1 -0
- package/dist/chunks/{exporter-BWwEuOPT.js → exporter-DteVeJki.js} +22 -12
- package/dist/chunks/exporter-DteVeJki.js.map +1 -0
- package/dist/chunks/format-BpQBx8MZ.js +676 -0
- package/dist/chunks/format-BpQBx8MZ.js.map +1 -0
- package/dist/chunks/generic-BGO71QBv.js +1347 -0
- package/dist/chunks/generic-BGO71QBv.js.map +1 -0
- package/dist/chunks/{importer-C98dpSH4.js → importer-B-9Rc1zO.js} +141 -82
- package/dist/chunks/importer-B-9Rc1zO.js.map +1 -0
- package/dist/chunks/{importer-D794XUTe.js → importer-BVVR740x.js} +31 -8
- package/dist/chunks/importer-BVVR740x.js.map +1 -0
- package/dist/chunks/{importer-WrGRZb0N.js → importer-C0AjA3Ax.js} +449 -102
- package/dist/chunks/importer-C0AjA3Ax.js.map +1 -0
- package/dist/chunks/{importer-BbNb7eNg.js → importer-C7pvJe1L.js} +1398 -129
- package/dist/chunks/importer-C7pvJe1L.js.map +1 -0
- package/dist/chunks/{importer-xZ-3suY1.js → importer-ClwoVx3O.js} +791 -135
- package/dist/chunks/importer-ClwoVx3O.js.map +1 -0
- package/dist/chunks/{importer-Ht7LNg8L.js → importer-D0sC_6bO.js} +116 -296
- package/dist/chunks/importer-D0sC_6bO.js.map +1 -0
- package/dist/chunks/{importer-Dz7tI8Sa.js → importer-EHQk1jbM.js} +617 -115
- package/dist/chunks/importer-EHQk1jbM.js.map +1 -0
- package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-DJZRZ6jd.js} +123 -32
- package/dist/chunks/json-elements-DJZRZ6jd.js.map +1 -0
- package/dist/chunks/lexicon-WMsNddyU.js +509 -0
- package/dist/chunks/lexicon-WMsNddyU.js.map +1 -0
- package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-G4MqRdux.js} +3 -2
- package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-G4MqRdux.js.map} +1 -1
- package/dist/chunks/{records-Cu4bxYOm.js → records-CiaWZrFH.js} +2 -2
- package/dist/chunks/{records-Cu4bxYOm.js.map → records-CiaWZrFH.js.map} +1 -1
- package/dist/chunks/styles-DvoFBKCK.js +690 -0
- package/dist/chunks/styles-DvoFBKCK.js.map +1 -0
- package/dist/chunks/styles-yed-Cz9rLBCP.js +842 -0
- package/dist/chunks/styles-yed-Cz9rLBCP.js.map +1 -0
- package/dist/chunks/styles-zNTmz5R7.js +2102 -0
- package/dist/chunks/styles-zNTmz5R7.js.map +1 -0
- package/dist/chunks/{text-DHOJXnED.js → text-CzJNFOS9.js} +2 -2
- package/dist/chunks/{text-DHOJXnED.js.map → text-CzJNFOS9.js.map} +1 -1
- package/dist/chunks/units-XMZFIFe1.js +19 -0
- package/dist/chunks/units-XMZFIFe1.js.map +1 -0
- package/dist/chunks/writer-gQ8kx99H.js +448 -0
- package/dist/chunks/writer-gQ8kx99H.js.map +1 -0
- package/dist/csv.js +5 -4
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +5 -2
- package/dist/dot.js.map +1 -1
- package/dist/gexf.js +292 -412
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +927 -74
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +351 -236
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +4 -2
- package/dist/graphml.js.map +1 -1
- package/dist/json.js +1 -1
- package/dist/neo4j.js +4 -3
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +4 -2
- package/dist/positions.d.ts +1 -0
- package/dist/positions.js +427 -0
- package/dist/positions.js.map +1 -0
- package/dist/src/common/codes.d.ts +6 -0
- package/dist/src/common/codes.d.ts.map +1 -1
- package/dist/src/common/codes.js +6 -0
- package/dist/src/common/codes.js.map +1 -1
- package/dist/src/common/escape.d.ts.map +1 -1
- package/dist/src/common/escape.js +4 -2
- package/dist/src/common/escape.js.map +1 -1
- package/dist/src/common/export.d.ts +10 -0
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +123 -100
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +8 -1
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/json-elements.d.ts +12 -9
- package/dist/src/common/json-elements.d.ts.map +1 -1
- package/dist/src/common/json-elements.js +160 -37
- package/dist/src/common/json-elements.js.map +1 -1
- package/dist/src/common/notes.d.ts +42 -0
- package/dist/src/common/notes.d.ts.map +1 -0
- package/dist/src/common/notes.js +72 -0
- package/dist/src/common/notes.js.map +1 -0
- package/dist/src/common/report.d.ts +18 -0
- package/dist/src/common/report.d.ts.map +1 -1
- package/dist/src/common/report.js +36 -1
- package/dist/src/common/report.js.map +1 -1
- package/dist/src/common/units.d.ts +24 -0
- package/dist/src/common/units.d.ts.map +1 -0
- package/dist/src/common/units.js +26 -0
- package/dist/src/common/units.js.map +1 -0
- package/dist/src/common/xml.d.ts +18 -0
- package/dist/src/common/xml.d.ts.map +1 -1
- package/dist/src/common/xml.js +42 -5
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/formats/cx/exporter.d.ts +6 -0
- package/dist/src/formats/cx/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx/exporter.js +71 -8
- package/dist/src/formats/cx/exporter.js.map +1 -1
- package/dist/src/formats/cx/importer.d.ts +5 -2
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +102 -72
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx/styles.d.ts +102 -0
- package/dist/src/formats/cx/styles.d.ts.map +1 -0
- package/dist/src/formats/cx/styles.js +225 -0
- package/dist/src/formats/cx/styles.js.map +1 -0
- package/dist/src/formats/cx2/exporter.d.ts +5 -0
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +181 -71
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts +4 -1
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +19 -1
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cx2/styles.d.ts +18 -0
- package/dist/src/formats/cx2/styles.d.ts.map +1 -0
- package/dist/src/formats/cx2/styles.js +24 -0
- package/dist/src/formats/cx2/styles.js.map +1 -0
- package/dist/src/formats/cys/constants.d.ts +2 -0
- package/dist/src/formats/cys/constants.d.ts.map +1 -1
- package/dist/src/formats/cys/constants.js +2 -0
- package/dist/src/formats/cys/constants.js.map +1 -1
- package/dist/src/formats/cys/exporter.d.ts +6 -2
- package/dist/src/formats/cys/exporter.d.ts.map +1 -1
- package/dist/src/formats/cys/exporter.js +215 -53
- package/dist/src/formats/cys/exporter.js.map +1 -1
- package/dist/src/formats/cys/importer.d.ts +2 -1
- package/dist/src/formats/cys/importer.d.ts.map +1 -1
- package/dist/src/formats/cys/importer.js +119 -6
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/session.d.ts +2 -0
- package/dist/src/formats/cys/session.d.ts.map +1 -1
- package/dist/src/formats/cys/session.js +5 -0
- package/dist/src/formats/cys/session.js.map +1 -1
- package/dist/src/formats/cys/styles.d.ts +38 -0
- package/dist/src/formats/cys/styles.d.ts.map +1 -0
- package/dist/src/formats/cys/styles.js +213 -0
- package/dist/src/formats/cys/styles.js.map +1 -0
- package/dist/src/formats/cys/tables.d.ts +8 -3
- package/dist/src/formats/cys/tables.d.ts.map +1 -1
- package/dist/src/formats/cys/tables.js +88 -34
- package/dist/src/formats/cys/tables.js.map +1 -1
- package/dist/src/formats/dot/exporter.d.ts +2 -0
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +195 -81
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +100 -20
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/index.d.ts +1 -0
- package/dist/src/formats/dot/index.d.ts.map +1 -1
- package/dist/src/formats/dot/index.js +1 -0
- package/dist/src/formats/dot/index.js.map +1 -1
- package/dist/src/formats/dot/positions.d.ts +14 -0
- package/dist/src/formats/dot/positions.d.ts.map +1 -0
- package/dist/src/formats/dot/positions.js +70 -0
- package/dist/src/formats/dot/positions.js.map +1 -0
- package/dist/src/formats/dot/styles.d.ts +82 -0
- package/dist/src/formats/dot/styles.d.ts.map +1 -0
- package/dist/src/formats/dot/styles.js +1496 -0
- package/dist/src/formats/dot/styles.js.map +1 -0
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +20 -5
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +8 -1
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +251 -131
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/index.d.ts +8 -0
- package/dist/src/formats/gexf/index.d.ts.map +1 -1
- package/dist/src/formats/gexf/index.js +10 -2
- package/dist/src/formats/gexf/index.js.map +1 -1
- package/dist/src/formats/gexf/schema.d.ts +5 -0
- package/dist/src/formats/gexf/schema.d.ts.map +1 -1
- package/dist/src/formats/gexf/schema.js +5 -0
- package/dist/src/formats/gexf/schema.js.map +1 -1
- package/dist/src/formats/gexf/styles.d.ts +74 -0
- package/dist/src/formats/gexf/styles.d.ts.map +1 -0
- package/dist/src/formats/gexf/styles.js +604 -0
- package/dist/src/formats/gexf/styles.js.map +1 -0
- package/dist/src/formats/gml/exporter.d.ts +1 -5
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +19 -8
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +4 -0
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/index.d.ts +2 -1
- package/dist/src/formats/gml/index.d.ts.map +1 -1
- package/dist/src/formats/gml/index.js +2 -1
- package/dist/src/formats/gml/index.js.map +1 -1
- package/dist/src/formats/gml/positions.d.ts +14 -0
- package/dist/src/formats/gml/positions.d.ts.map +1 -0
- package/dist/src/formats/gml/positions.js +46 -0
- package/dist/src/formats/gml/positions.js.map +1 -0
- package/dist/src/formats/gml/styles.d.ts +59 -0
- package/dist/src/formats/gml/styles.d.ts.map +1 -0
- package/dist/src/formats/gml/styles.js +1056 -0
- package/dist/src/formats/gml/styles.js.map +1 -0
- package/dist/src/formats/gml/syntax.d.ts +11 -0
- package/dist/src/formats/gml/syntax.d.ts.map +1 -1
- package/dist/src/formats/gml/syntax.js +151 -62
- package/dist/src/formats/gml/syntax.js.map +1 -1
- package/dist/src/formats/graphml/constants.d.ts +4 -0
- package/dist/src/formats/graphml/constants.d.ts.map +1 -1
- package/dist/src/formats/graphml/constants.js +5 -1
- package/dist/src/formats/graphml/constants.js.map +1 -1
- package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
- package/dist/src/formats/graphml/exporter.js +133 -65
- package/dist/src/formats/graphml/exporter.js.map +1 -1
- package/dist/src/formats/graphml/importer.d.ts +4 -1
- package/dist/src/formats/graphml/importer.d.ts.map +1 -1
- package/dist/src/formats/graphml/importer.js +100 -44
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/graphml/index.d.ts +1 -0
- package/dist/src/formats/graphml/index.d.ts.map +1 -1
- package/dist/src/formats/graphml/index.js +1 -0
- package/dist/src/formats/graphml/index.js.map +1 -1
- package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
- package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-plain.js +187 -0
- package/dist/src/formats/graphml/styles-plain.js.map +1 -0
- package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
- package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-yed.js +1086 -0
- package/dist/src/formats/graphml/styles-yed.js.map +1 -0
- package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
- package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
- package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
- package/dist/src/formats/graphml/tree.d.ts.map +1 -1
- package/dist/src/formats/graphml/tree.js +34 -19
- package/dist/src/formats/graphml/tree.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts +16 -2
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +83 -12
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts +5 -0
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +68 -25
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +22 -3
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +439 -264
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/positions.d.ts +16 -0
- package/dist/src/formats/json/positions.d.ts.map +1 -0
- package/dist/src/formats/json/positions.js +44 -0
- package/dist/src/formats/json/positions.js.map +1 -0
- package/dist/src/formats/json/styles.d.ts +102 -0
- package/dist/src/formats/json/styles.d.ts.map +1 -0
- package/dist/src/formats/json/styles.js +1753 -0
- package/dist/src/formats/json/styles.js.map +1 -0
- package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
- package/dist/src/formats/neo4j/exporter.js +2 -1
- package/dist/src/formats/neo4j/exporter.js.map +1 -1
- package/dist/src/formats/pajek/exporter.d.ts +2 -0
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +142 -76
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts +4 -0
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +60 -6
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/index.d.ts +2 -0
- package/dist/src/formats/pajek/index.d.ts.map +1 -1
- package/dist/src/formats/pajek/index.js +2 -0
- package/dist/src/formats/pajek/index.js.map +1 -1
- package/dist/src/formats/pajek/styles.d.ts +50 -0
- package/dist/src/formats/pajek/styles.d.ts.map +1 -0
- package/dist/src/formats/pajek/styles.js +569 -0
- package/dist/src/formats/pajek/styles.js.map +1 -0
- package/dist/src/formats/pajek/syntax.d.ts +6 -0
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +6 -0
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
- package/dist/src/formats/xgmml/columns.js +34 -9
- package/dist/src/formats/xgmml/columns.js.map +1 -1
- package/dist/src/formats/xgmml/constants.d.ts +2 -0
- package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
- package/dist/src/formats/xgmml/constants.js +3 -1
- package/dist/src/formats/xgmml/constants.js.map +1 -1
- package/dist/src/formats/xgmml/document.d.ts +12 -8
- package/dist/src/formats/xgmml/document.d.ts.map +1 -1
- package/dist/src/formats/xgmml/document.js +56 -13
- package/dist/src/formats/xgmml/document.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +12 -6
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/exporter.d.ts +3 -1
- package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
- package/dist/src/formats/xgmml/exporter.js +22 -9
- package/dist/src/formats/xgmml/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/importer.d.ts +2 -1
- package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
- package/dist/src/formats/xgmml/importer.js +31 -24
- package/dist/src/formats/xgmml/importer.js.map +1 -1
- package/dist/src/formats/xgmml/styles.d.ts +104 -0
- package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
- package/dist/src/formats/xgmml/styles.js +310 -0
- package/dist/src/formats/xgmml/styles.js.map +1 -0
- package/dist/src/index.d.ts +9 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -7
- package/dist/src/index.js.map +1 -1
- package/dist/src/positions/codes.d.ts +31 -0
- package/dist/src/positions/codes.d.ts.map +1 -0
- package/dist/src/positions/codes.js +26 -0
- package/dist/src/positions/codes.js.map +1 -0
- package/dist/src/positions/convert.d.ts +58 -0
- package/dist/src/positions/convert.d.ts.map +1 -0
- package/dist/src/positions/convert.js +107 -0
- package/dist/src/positions/convert.js.map +1 -0
- package/dist/src/positions/extract.d.ts +27 -0
- package/dist/src/positions/extract.d.ts.map +1 -0
- package/dist/src/positions/extract.js +526 -0
- package/dist/src/positions/extract.js.map +1 -0
- package/dist/src/positions/index.d.ts +10 -0
- package/dist/src/positions/index.d.ts.map +1 -0
- package/dist/src/positions/index.js +9 -0
- package/dist/src/positions/index.js.map +1 -0
- package/dist/src/positions/types.d.ts +208 -0
- package/dist/src/positions/types.d.ts.map +1 -0
- package/dist/src/positions/types.js +10 -0
- package/dist/src/positions/types.js.map +1 -0
- package/dist/src/registry.d.ts +30 -0
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +130 -9
- package/dist/src/registry.js.map +1 -1
- package/dist/src/styles/annotations.d.ts +132 -0
- package/dist/src/styles/annotations.d.ts.map +1 -0
- package/dist/src/styles/annotations.js +320 -0
- package/dist/src/styles/annotations.js.map +1 -0
- package/dist/src/styles/budget.d.ts +45 -0
- package/dist/src/styles/budget.d.ts.map +1 -0
- package/dist/src/styles/budget.js +58 -0
- package/dist/src/styles/budget.js.map +1 -0
- package/dist/src/styles/canon/bends.d.ts +32 -0
- package/dist/src/styles/canon/bends.d.ts.map +1 -0
- package/dist/src/styles/canon/bends.js +74 -0
- package/dist/src/styles/canon/bends.js.map +1 -0
- package/dist/src/styles/canon/color-tables.d.ts +22 -0
- package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
- package/dist/src/styles/canon/color-tables.js +369 -0
- package/dist/src/styles/canon/color-tables.js.map +1 -0
- package/dist/src/styles/canon/color.d.ts +66 -0
- package/dist/src/styles/canon/color.d.ts.map +1 -0
- package/dist/src/styles/canon/color.js +548 -0
- package/dist/src/styles/canon/color.js.map +1 -0
- package/dist/src/styles/canon/enums.d.ts +25 -0
- package/dist/src/styles/canon/enums.d.ts.map +1 -0
- package/dist/src/styles/canon/enums.js +187 -0
- package/dist/src/styles/canon/enums.js.map +1 -0
- package/dist/src/styles/canon/graphviz.d.ts +48 -0
- package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
- package/dist/src/styles/canon/graphviz.js +160 -0
- package/dist/src/styles/canon/graphviz.js.map +1 -0
- package/dist/src/styles/canon/index.d.ts +13 -0
- package/dist/src/styles/canon/index.d.ts.map +1 -0
- package/dist/src/styles/canon/index.js +13 -0
- package/dist/src/styles/canon/index.js.map +1 -0
- package/dist/src/styles/canon/number.d.ts +59 -0
- package/dist/src/styles/canon/number.d.ts.map +1 -0
- package/dist/src/styles/canon/number.js +142 -0
- package/dist/src/styles/canon/number.js.map +1 -0
- package/dist/src/styles/canon/site.d.ts +51 -0
- package/dist/src/styles/canon/site.d.ts.map +1 -0
- package/dist/src/styles/canon/site.js +63 -0
- package/dist/src/styles/canon/site.js.map +1 -0
- package/dist/src/styles/canon/text.d.ts +61 -0
- package/dist/src/styles/canon/text.d.ts.map +1 -0
- package/dist/src/styles/canon/text.js +199 -0
- package/dist/src/styles/canon/text.js.map +1 -0
- package/dist/src/styles/codes.d.ts +95 -0
- package/dist/src/styles/codes.d.ts.map +1 -0
- package/dist/src/styles/codes.js +97 -0
- package/dist/src/styles/codes.js.map +1 -0
- package/dist/src/styles/cyjs/cascade.d.ts +134 -0
- package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
- package/dist/src/styles/cyjs/cascade.js +2252 -0
- package/dist/src/styles/cyjs/cascade.js.map +1 -0
- package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
- package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
- package/dist/src/styles/cyjs/defaults-table.js +76 -0
- package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
- package/dist/src/styles/cyjs/emit.d.ts +82 -0
- package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
- package/dist/src/styles/cyjs/emit.js +791 -0
- package/dist/src/styles/cyjs/emit.js.map +1 -0
- package/dist/src/styles/cyjs/index.d.ts +13 -0
- package/dist/src/styles/cyjs/index.d.ts.map +1 -0
- package/dist/src/styles/cyjs/index.js +13 -0
- package/dist/src/styles/cyjs/index.js.map +1 -0
- package/dist/src/styles/cyjs/live.d.ts +46 -0
- package/dist/src/styles/cyjs/live.d.ts.map +1 -0
- package/dist/src/styles/cyjs/live.js +108 -0
- package/dist/src/styles/cyjs/live.js.map +1 -0
- package/dist/src/styles/cyjs/mappers.d.ts +147 -0
- package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
- package/dist/src/styles/cyjs/mappers.js +744 -0
- package/dist/src/styles/cyjs/mappers.js.map +1 -0
- package/dist/src/styles/cyjs/selector.d.ts +113 -0
- package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
- package/dist/src/styles/cyjs/selector.js +611 -0
- package/dist/src/styles/cyjs/selector.js.map +1 -0
- package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
- package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
- package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
- package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
- package/dist/src/styles/cytoscape/emit.d.ts +125 -0
- package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/emit.js +1025 -0
- package/dist/src/styles/cytoscape/emit.js.map +1 -0
- package/dist/src/styles/cytoscape/index.d.ts +10 -0
- package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/index.js +10 -0
- package/dist/src/styles/cytoscape/index.js.map +1 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/lexicon.js +605 -0
- package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
- package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
- package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/mappings.js +460 -0
- package/dist/src/styles/cytoscape/mappings.js.map +1 -0
- package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
- package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/resolve.js +381 -0
- package/dist/src/styles/cytoscape/resolve.js.map +1 -0
- package/dist/src/styles/cytoscape/translate.d.ts +50 -0
- package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/translate.js +156 -0
- package/dist/src/styles/cytoscape/translate.js.map +1 -0
- package/dist/src/styles/defaults.d.ts +90 -0
- package/dist/src/styles/defaults.d.ts.map +1 -0
- package/dist/src/styles/defaults.js +414 -0
- package/dist/src/styles/defaults.js.map +1 -0
- package/dist/src/styles/index.d.ts +15 -0
- package/dist/src/styles/index.d.ts.map +1 -0
- package/dist/src/styles/index.js +14 -0
- package/dist/src/styles/index.js.map +1 -0
- package/dist/src/styles/internal.d.ts +17 -0
- package/dist/src/styles/internal.d.ts.map +1 -0
- package/dist/src/styles/internal.js +16 -0
- package/dist/src/styles/internal.js.map +1 -0
- package/dist/src/styles/io/approximations.d.ts +24 -0
- package/dist/src/styles/io/approximations.d.ts.map +1 -0
- package/dist/src/styles/io/approximations.js +51 -0
- package/dist/src/styles/io/approximations.js.map +1 -0
- package/dist/src/styles/io/block.d.ts +166 -0
- package/dist/src/styles/io/block.d.ts.map +1 -0
- package/dist/src/styles/io/block.js +930 -0
- package/dist/src/styles/io/block.js.map +1 -0
- package/dist/src/styles/io/generic.d.ts +88 -0
- package/dist/src/styles/io/generic.d.ts.map +1 -0
- package/dist/src/styles/io/generic.js +516 -0
- package/dist/src/styles/io/generic.js.map +1 -0
- package/dist/src/styles/io/index.d.ts +8 -0
- package/dist/src/styles/io/index.d.ts.map +1 -0
- package/dist/src/styles/io/index.js +7 -0
- package/dist/src/styles/io/index.js.map +1 -0
- package/dist/src/styles/io/writer.d.ts +89 -0
- package/dist/src/styles/io/writer.d.ts.map +1 -0
- package/dist/src/styles/io/writer.js +626 -0
- package/dist/src/styles/io/writer.js.map +1 -0
- package/dist/src/styles/notes.d.ts +47 -0
- package/dist/src/styles/notes.d.ts.map +1 -0
- package/dist/src/styles/notes.js +140 -0
- package/dist/src/styles/notes.js.map +1 -0
- package/dist/src/styles/plan/classes.d.ts +31 -0
- package/dist/src/styles/plan/classes.d.ts.map +1 -0
- package/dist/src/styles/plan/classes.js +139 -0
- package/dist/src/styles/plan/classes.js.map +1 -0
- package/dist/src/styles/plan/continuous.d.ts +32 -0
- package/dist/src/styles/plan/continuous.d.ts.map +1 -0
- package/dist/src/styles/plan/continuous.js +165 -0
- package/dist/src/styles/plan/continuous.js.map +1 -0
- package/dist/src/styles/plan/discrete.d.ts +39 -0
- package/dist/src/styles/plan/discrete.d.ts.map +1 -0
- package/dist/src/styles/plan/discrete.js +127 -0
- package/dist/src/styles/plan/discrete.js.map +1 -0
- package/dist/src/styles/plan/families.d.ts +31 -0
- package/dist/src/styles/plan/families.d.ts.map +1 -0
- package/dist/src/styles/plan/families.js +95 -0
- package/dist/src/styles/plan/families.js.map +1 -0
- package/dist/src/styles/plan/features.d.ts +58 -0
- package/dist/src/styles/plan/features.d.ts.map +1 -0
- package/dist/src/styles/plan/features.js +185 -0
- package/dist/src/styles/plan/features.js.map +1 -0
- package/dist/src/styles/plan/index.d.ts +7 -0
- package/dist/src/styles/plan/index.d.ts.map +1 -0
- package/dist/src/styles/plan/index.js +7 -0
- package/dist/src/styles/plan/index.js.map +1 -0
- package/dist/src/styles/plan/plan.d.ts +71 -0
- package/dist/src/styles/plan/plan.d.ts.map +1 -0
- package/dist/src/styles/plan/plan.js +893 -0
- package/dist/src/styles/plan/plan.js.map +1 -0
- package/dist/src/styles/plan/resolve.d.ts +137 -0
- package/dist/src/styles/plan/resolve.d.ts.map +1 -0
- package/dist/src/styles/plan/resolve.js +587 -0
- package/dist/src/styles/plan/resolve.js.map +1 -0
- package/dist/src/styles/types.d.ts +702 -0
- package/dist/src/styles/types.d.ts.map +1 -0
- package/dist/src/styles/types.js +10 -0
- package/dist/src/styles/types.js.map +1 -0
- package/dist/src/styles/vocabulary.d.ts +41 -0
- package/dist/src/styles/vocabulary.d.ts.map +1 -0
- package/dist/src/styles/vocabulary.js +140 -0
- package/dist/src/styles/vocabulary.js.map +1 -0
- package/dist/src/types.d.ts +64 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/styles.d.ts +1 -0
- package/dist/styles.js +322 -0
- package/dist/styles.js.map +1 -0
- package/dist/xgmml.js +5 -4
- package/dist/xgmml.js.map +1 -1
- package/package.json +13 -2
- package/src/common/codes.ts +7 -0
- package/src/common/escape.ts +5 -2
- package/src/common/export.ts +179 -140
- package/src/common/input.ts +8 -4
- package/src/common/json-elements.ts +169 -38
- package/src/common/notes.ts +94 -0
- package/src/common/report.ts +41 -1
- package/src/common/units.ts +42 -0
- package/src/common/xml.ts +45 -5
- package/src/formats/cx/exporter.ts +95 -11
- package/src/formats/cx/importer.ts +126 -90
- package/src/formats/cx/styles.ts +304 -0
- package/src/formats/cx2/exporter.ts +234 -77
- package/src/formats/cx2/importer.ts +19 -1
- package/src/formats/cx2/styles.ts +29 -0
- package/src/formats/cys/constants.ts +3 -0
- package/src/formats/cys/exporter.ts +246 -60
- package/src/formats/cys/importer.ts +125 -9
- package/src/formats/cys/session.ts +6 -0
- package/src/formats/cys/styles.ts +254 -0
- package/src/formats/cys/tables.ts +117 -48
- package/src/formats/dot/exporter.ts +262 -126
- package/src/formats/dot/importer.ts +111 -20
- package/src/formats/dot/index.ts +1 -0
- package/src/formats/dot/positions.ts +77 -0
- package/src/formats/dot/styles.ts +1755 -0
- package/src/formats/gexf/exporter.ts +27 -11
- package/src/formats/gexf/importer.ts +308 -158
- package/src/formats/gexf/index.ts +10 -0
- package/src/formats/gexf/schema.ts +5 -0
- package/src/formats/gexf/styles.ts +719 -0
- package/src/formats/gml/exporter.ts +33 -14
- package/src/formats/gml/importer.ts +4 -0
- package/src/formats/gml/index.ts +2 -1
- package/src/formats/gml/positions.ts +52 -0
- package/src/formats/gml/styles.ts +1248 -0
- package/src/formats/gml/syntax.ts +173 -62
- package/src/formats/graphml/constants.ts +5 -0
- package/src/formats/graphml/exporter.ts +163 -71
- package/src/formats/graphml/importer.ts +119 -45
- package/src/formats/graphml/index.ts +1 -0
- package/src/formats/graphml/styles-plain.ts +236 -0
- package/src/formats/graphml/styles-yed.ts +1221 -0
- package/src/formats/graphml/styles-yfiles3.ts +573 -0
- package/src/formats/graphml/tree.ts +36 -20
- package/src/formats/graphml/yfiles.ts +89 -13
- package/src/formats/json/exporter.ts +76 -26
- package/src/formats/json/importer.ts +541 -322
- package/src/formats/json/positions.ts +50 -0
- package/src/formats/json/styles.ts +2082 -0
- package/src/formats/neo4j/exporter.ts +2 -1
- package/src/formats/pajek/exporter.ts +195 -106
- package/src/formats/pajek/importer.ts +78 -9
- package/src/formats/pajek/index.ts +2 -0
- package/src/formats/pajek/styles.ts +685 -0
- package/src/formats/pajek/syntax.ts +7 -0
- package/src/formats/xgmml/columns.ts +39 -9
- package/src/formats/xgmml/constants.ts +3 -0
- package/src/formats/xgmml/document.ts +54 -12
- package/src/formats/xgmml/emit.ts +11 -6
- package/src/formats/xgmml/exporter.ts +32 -13
- package/src/formats/xgmml/importer.ts +43 -29
- package/src/formats/xgmml/styles.ts +400 -0
- package/src/index.ts +16 -0
- package/src/positions/codes.ts +32 -0
- package/src/positions/convert.ts +123 -0
- package/src/positions/extract.ts +619 -0
- package/src/positions/index.ts +23 -0
- package/src/positions/types.ts +221 -0
- package/src/registry.ts +179 -8
- package/src/styles/annotations.ts +478 -0
- package/src/styles/budget.ts +60 -0
- package/src/styles/canon/bends.ts +84 -0
- package/src/styles/canon/color-tables.ts +386 -0
- package/src/styles/canon/color.ts +624 -0
- package/src/styles/canon/enums.ts +211 -0
- package/src/styles/canon/graphviz.ts +189 -0
- package/src/styles/canon/index.ts +13 -0
- package/src/styles/canon/number.ts +152 -0
- package/src/styles/canon/site.ts +87 -0
- package/src/styles/canon/text.ts +221 -0
- package/src/styles/codes.ts +104 -0
- package/src/styles/cyjs/cascade.ts +2670 -0
- package/src/styles/cyjs/defaults-table.ts +82 -0
- package/src/styles/cyjs/emit.ts +952 -0
- package/src/styles/cyjs/index.ts +37 -0
- package/src/styles/cyjs/live.ts +147 -0
- package/src/styles/cyjs/mappers.ts +879 -0
- package/src/styles/cyjs/selector.ts +778 -0
- package/src/styles/cyjs/stylesheet-text.ts +214 -0
- package/src/styles/cytoscape/emit.ts +1264 -0
- package/src/styles/cytoscape/index.ts +40 -0
- package/src/styles/cytoscape/lexicon.ts +658 -0
- package/src/styles/cytoscape/mappings.ts +603 -0
- package/src/styles/cytoscape/resolve.ts +521 -0
- package/src/styles/cytoscape/translate.ts +237 -0
- package/src/styles/defaults.ts +504 -0
- package/src/styles/index.ts +57 -0
- package/src/styles/internal.ts +17 -0
- package/src/styles/io/approximations.ts +47 -0
- package/src/styles/io/block.ts +1138 -0
- package/src/styles/io/generic.ts +687 -0
- package/src/styles/io/index.ts +18 -0
- package/src/styles/io/writer.ts +780 -0
- package/src/styles/notes.ts +165 -0
- package/src/styles/plan/classes.ts +166 -0
- package/src/styles/plan/continuous.ts +218 -0
- package/src/styles/plan/discrete.ts +165 -0
- package/src/styles/plan/families.ts +115 -0
- package/src/styles/plan/features.ts +234 -0
- package/src/styles/plan/index.ts +7 -0
- package/src/styles/plan/plan.ts +1129 -0
- package/src/styles/plan/resolve.ts +685 -0
- package/src/styles/types.ts +814 -0
- package/src/styles/vocabulary.ts +172 -0
- package/src/types.ts +76 -1
- package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
- package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
- package/dist/chunks/export-rKLeGQMo.js.map +0 -1
- package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
- package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
- package/dist/chunks/exporter-RVtXVetw.js.map +0 -1
- package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
- package/dist/chunks/importer-C98dpSH4.js.map +0 -1
- package/dist/chunks/importer-D794XUTe.js.map +0 -1
- package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
- package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
- package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
- package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
- package/dist/chunks/json-elements-DKSqpNW1.js.map +0 -1
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, l as DUPLICATE_ATTRIBUTE_CODE, d as UNKNOWN_ELEMENT_CODE, ax as EMPTY_COLUMN_DROPPED_CODE, a6 as PARENT_CYCLE_CODE, P as PRECISION_CODE, s as UNKNOWN_ENCODING_CODE, W as JSON_NONSTANDARD_NUMBER_CODE, t as ENCODING_FALLBACK_CODE, u as INVALID_ENCODING_CODE, v as INVALID_UTF8_CODE, O as OPTION_IGNORED_CODE, S as SINK_OPTION_CODE, H as HYPEREDGE_CODE, a1 as TOO_LARGE_CODE, f as DANGLING_REFERENCE_CODE, a2 as AMBIGUOUS_GRAPH_NAME_CODE, a3 as GRAPH_NOT_FOUND_CODE, i as MULTIPLE_GRAPHS_CODE, I as ID_MERGED_CODE, j as DUPLICATE_EDGE_ID_CODE, k as DUPLICATE_NODE_CODE, m as UNKNOWN_PARENT_CODE, Y as BAD_VALUE_CODE, n as MISSING_ENDPOINT_CODE, o as MISSING_ID_CODE, a8 as SYNTAX_CODE, E as EMPTY_INPUT_CODE, y as ELEMENT_ISSUE, z as INPUT_ISSUE, Z as ImportReportBuilder, p as plural, a as agree, ag as GRAPH_COLUMN_AS_METADATA_CODE, ah as TYPEDEF_NODES_CODE, ai as RELATION_ASSUMED_CODE, a9 as COLUMN_AS_PROPERTY_VALUE_CODE, aE as NONFINITE_AS_NULL_CODE, av as DIRECTION_DROPPED_CODE, af as NODE_ORDER_CODE, $ as formatF32, a0 as formatF64 } from "./format-BpQBx8MZ.js";
|
|
3
|
+
import { c as capabilities, g as resolveImportOptions, ab as readText, j as reportSinkOptions, i as reportUnusedOptions, h as throwIfAborted, I as IdCoercer, l as DirectionResolver, w as weightFromValue, u as uniqueColumnName, f as chooseGraph, k as graphChosen, d as declareResolved, p as pairFolding, e as explicitWeights, L as LOSS, a as checkCapabilities, r as resolveExportOptions, ah as otherFormatDialect, ai as countMixedEdges } from "./export-BvqAXCKh.js";
|
|
4
4
|
import { j as joinText, e as encodeChunks, i as indentUnit } from "./writer-DxjgHwSe.js";
|
|
5
|
-
import { t as
|
|
6
|
-
import {
|
|
5
|
+
import { S as STYLE_BLOCK_NAME, C as toolDefaults, t as StyleNotes, u as parseStyleBlock, s as styleFingerprint, a as STYLE_ISSUE, p as plainCell, m as canonBoolean, o as canonText, h as canonNumber, v as blockStyles, g as canonColor, l as canonEnum, j as canonOpacity, r as resolveStyles } from "./block-CPCHkX42.js";
|
|
6
|
+
import { t as trimTrailingZeros } from "./text-CzJNFOS9.js";
|
|
7
|
+
import { d as OBOGRAPHS_PREDICATE_TAGS, g as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, h as synonymScopeOf, O as OBO_NODE_COLUMNS, c as capabilityNotes, s as slotColumn, e as emptyColumnNotes, j as OBO_PURL, f as framelessNodes, m as movedNodes, U as UNWRITTEN_ROLES, n as notePropertyColumn, a as cellOf, v as valuesOf$1, k as OBO_IN_OWL, b as fitsVocabulary, t as textOf, S as SYNONYM_SCOPES } from "./ontology-export-G4MqRdux.js";
|
|
8
|
+
import { M as MAYBE_UNSAFE_INTEGER, g as MAYBE_INEXACT_EXPONENT, j as rewriteNumbers, l as findDuplicateKeys, m as keysInTextOrder } from "./json-elements-DJZRZ6jd.js";
|
|
9
|
+
import { c as cytoscapeJsStyles, C as CYTOSCAPE_IMPORT_KEY, t as toCytoscapeStylesheet, a as cyjsHoldsExactly, b as CYJS_EDGE_PROPERTIES, d as CYJS_NODE_PROPERTIES } from "./emit-DZy6JgdA.js";
|
|
10
|
+
import { S as StyleApproximations } from "./approximations-DJMHdDvv.js";
|
|
11
|
+
import { f as flipY } from "./convert-BcQ8_jMo.js";
|
|
7
12
|
const JSON_DIALECTS = Object.freeze([
|
|
8
13
|
"node-link",
|
|
9
14
|
"d3",
|
|
@@ -357,15 +362,15 @@ function sniffFormat(hints, importers) {
|
|
|
357
362
|
function sniffJsonDialectHead(head) {
|
|
358
363
|
const text = typeof head === "string" ? head : new TextDecoder("utf-8", { fatal: false }).decode(head);
|
|
359
364
|
const body = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
|
|
360
|
-
const
|
|
361
|
-
if (!
|
|
365
|
+
const trimmed2 = body.trimStart();
|
|
366
|
+
if (!trimmed2.startsWith("{") && !trimmed2.startsWith("[")) {
|
|
362
367
|
return null;
|
|
363
368
|
}
|
|
364
369
|
let root;
|
|
365
370
|
try {
|
|
366
|
-
root = JSON.parse(
|
|
371
|
+
root = JSON.parse(trimmed2);
|
|
367
372
|
} catch {
|
|
368
|
-
const skeleton = skeletonOf(
|
|
373
|
+
const skeleton = skeletonOf(trimmed2);
|
|
369
374
|
root = skeleton;
|
|
370
375
|
if (typeof skeleton === "object" && skeleton !== null && !Array.isArray(skeleton) && !["edges", "links", "directed", "multigraph", "graph"].some((key) => key in skeleton)) {
|
|
371
376
|
const guess = sniffJsonDialect(skeleton);
|
|
@@ -565,6 +570,1367 @@ function clamp(value) {
|
|
|
565
570
|
}
|
|
566
571
|
return Math.min(value, 1);
|
|
567
572
|
}
|
|
573
|
+
const Y_DOWN_MARKERS = ["vx", "vy", "fx", "fy", "index", "physics"];
|
|
574
|
+
function jsonPositions(snapshot) {
|
|
575
|
+
if (snapshot.nodes.byRole("position") !== null) {
|
|
576
|
+
return null;
|
|
577
|
+
}
|
|
578
|
+
const x = numeric(snapshot.nodes.get("x"));
|
|
579
|
+
const y = numeric(snapshot.nodes.get("y"));
|
|
580
|
+
if (x === null || y === null) {
|
|
581
|
+
return null;
|
|
582
|
+
}
|
|
583
|
+
const z = numeric(snapshot.nodes.get("z"));
|
|
584
|
+
const down = z === null && Y_DOWN_MARKERS.some((name) => snapshot.nodes.get(name) !== null);
|
|
585
|
+
return {
|
|
586
|
+
x: x.meta.name,
|
|
587
|
+
y: y.meta.name,
|
|
588
|
+
...z === null ? {} : { z: z.meta.name },
|
|
589
|
+
yAxis: down ? "down" : "up",
|
|
590
|
+
units: down ? "px" : "file"
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
function numeric(column) {
|
|
594
|
+
const numericDtypes = ["f64", "f32", "i32", "u32", "u8"];
|
|
595
|
+
return column !== null && column.meta.components === 1 && numericDtypes.includes(column.dtype) ? column : null;
|
|
596
|
+
}
|
|
597
|
+
const TARGETS = ["node", "edge"];
|
|
598
|
+
function jsonStyles(snapshot, context) {
|
|
599
|
+
const src = context.kept;
|
|
600
|
+
if (!isJsonObject(src)) {
|
|
601
|
+
return null;
|
|
602
|
+
}
|
|
603
|
+
switch (src.dialect) {
|
|
604
|
+
case "cytoscape":
|
|
605
|
+
return cytoscapeStyles(snapshot, src, context);
|
|
606
|
+
case "graphology":
|
|
607
|
+
return graphologyStyles(snapshot, src, context);
|
|
608
|
+
case "vis":
|
|
609
|
+
return visStyles(snapshot, src, context);
|
|
610
|
+
case "node-link":
|
|
611
|
+
if (src.networkx === true) {
|
|
612
|
+
return networkxStyles(snapshot);
|
|
613
|
+
}
|
|
614
|
+
return src.block === null ? null : { canonical: true, block: src.block };
|
|
615
|
+
default:
|
|
616
|
+
return src.block === null ? null : { canonical: true, block: src.block };
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
function cytoscapeStyles(snapshot, src, context) {
|
|
620
|
+
const sheetless = (src.style === void 0 || src.style === null) && src.generatedBy?.startsWith("cytoscape-") === true;
|
|
621
|
+
const graphty = src.block !== null && parseStyleBlock(src.block, styleFingerprint(snapshot)).ok;
|
|
622
|
+
const read = cytoscapeJsStyles({
|
|
623
|
+
elements: withGeneratedIds(src.elements, src.generatedIds),
|
|
624
|
+
style: sheetless ? [] : src.style ?? [],
|
|
625
|
+
snapshot,
|
|
626
|
+
toolDefaults: !graphty && !sheetless,
|
|
627
|
+
budget: context.budget,
|
|
628
|
+
signal: context.signal
|
|
629
|
+
});
|
|
630
|
+
if (!("canonical" in read)) {
|
|
631
|
+
return read;
|
|
632
|
+
}
|
|
633
|
+
let tool = "cytoscape-js";
|
|
634
|
+
if (graphty) {
|
|
635
|
+
tool = null;
|
|
636
|
+
exactFromBlock(
|
|
637
|
+
snapshot,
|
|
638
|
+
src.block,
|
|
639
|
+
{ node: read.node?.values ?? {}, edge: read.edge?.values ?? {} },
|
|
640
|
+
CYJS_WRITTEN,
|
|
641
|
+
cyjsHoldsExactly
|
|
642
|
+
);
|
|
643
|
+
} else if (sheetless) {
|
|
644
|
+
tool = "cytoscape";
|
|
645
|
+
}
|
|
646
|
+
return { ...read, tool, block: src.block };
|
|
647
|
+
}
|
|
648
|
+
const trimmed = (property) => (want) => {
|
|
649
|
+
const v = want(property);
|
|
650
|
+
return typeof v === "string" ? v.trim() : null;
|
|
651
|
+
};
|
|
652
|
+
const CYJS_TEXT = {
|
|
653
|
+
node: ["label"],
|
|
654
|
+
edge: ["label", "sourceLabel", "targetLabel"]
|
|
655
|
+
};
|
|
656
|
+
const CYJS_WRITTEN = {
|
|
657
|
+
node: Object.fromEntries(CYJS_TEXT.node.map((p) => [p, trimmed(p)])),
|
|
658
|
+
edge: {
|
|
659
|
+
...Object.fromEntries(CYJS_TEXT.edge.map((p) => [p, trimmed(p)])),
|
|
660
|
+
// Cytoscape.js draws a loop curved whatever its curve style says
|
|
661
|
+
curved: (want, e, snapshot) => snapshot.edgeSource(e) === snapshot.edgeTarget(e) && want("curved") !== null ? true : want("curved")
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
function withGeneratedIds(elements, ids) {
|
|
665
|
+
if (ids === void 0 || ids.size === 0) {
|
|
666
|
+
return elements;
|
|
667
|
+
}
|
|
668
|
+
const patch = (e) => {
|
|
669
|
+
const id = isJsonObject(e) ? ids.get(e) : void 0;
|
|
670
|
+
return id === void 0 || !isJsonObject(e) ? e : { ...e, data: { ...e.data, id } };
|
|
671
|
+
};
|
|
672
|
+
if (Array.isArray(elements)) {
|
|
673
|
+
return elements.map(patch);
|
|
674
|
+
}
|
|
675
|
+
if (isJsonObject(elements) && Array.isArray(elements.nodes)) {
|
|
676
|
+
return { ...elements, nodes: elements.nodes.map(patch) };
|
|
677
|
+
}
|
|
678
|
+
return elements;
|
|
679
|
+
}
|
|
680
|
+
function networkxStyles(snapshot) {
|
|
681
|
+
return {
|
|
682
|
+
canonical: true,
|
|
683
|
+
dialect: null,
|
|
684
|
+
tool: "networkx",
|
|
685
|
+
units: "px",
|
|
686
|
+
node: { values: {} },
|
|
687
|
+
edge: directedArrows(snapshot)
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
function directedArrows(snapshot) {
|
|
691
|
+
if (!snapshot.directed || snapshot.edgeCount === 0) {
|
|
692
|
+
return { values: {}, rules: [], columns: /* @__PURE__ */ new Map() };
|
|
693
|
+
}
|
|
694
|
+
const col = snapshot.edges.byRole("directed");
|
|
695
|
+
const flags = Array.from(
|
|
696
|
+
{ length: snapshot.edgeCount },
|
|
697
|
+
(_v, e) => col === null || plainCell(col.value(e)) !== false ? true : null
|
|
698
|
+
);
|
|
699
|
+
return {
|
|
700
|
+
values: {},
|
|
701
|
+
rules: [
|
|
702
|
+
{
|
|
703
|
+
id: "edge.tool.arrow",
|
|
704
|
+
target: "edge",
|
|
705
|
+
role: "group",
|
|
706
|
+
origin: "tool",
|
|
707
|
+
where: { has: { style: "directed" } },
|
|
708
|
+
set: { targetArrow: "triangle" }
|
|
709
|
+
}
|
|
710
|
+
],
|
|
711
|
+
columns: /* @__PURE__ */ new Map([["directed", flags]])
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
function cells(snapshot, target, name) {
|
|
715
|
+
const table = target === "node" ? snapshot.nodes : snapshot.edges;
|
|
716
|
+
return table.has(name) ? (i) => plainCell(table.value(name, i)) : null;
|
|
717
|
+
}
|
|
718
|
+
function valuesOf(n) {
|
|
719
|
+
const values = {};
|
|
720
|
+
return {
|
|
721
|
+
values,
|
|
722
|
+
put: (p, i, v) => {
|
|
723
|
+
if (v !== null) {
|
|
724
|
+
setValue(values, p, n, i, v);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
function setValue(values, property, n, i, v) {
|
|
730
|
+
values[property] ??= new Array(n).fill(null);
|
|
731
|
+
values[property][i] = v;
|
|
732
|
+
}
|
|
733
|
+
function graphologyStyles(snapshot, src, context) {
|
|
734
|
+
const notes = new StyleNotes();
|
|
735
|
+
const out = { node: {}, edge: {} };
|
|
736
|
+
const readFrom = { node: [], edge: [] };
|
|
737
|
+
for (const target of TARGETS) {
|
|
738
|
+
const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
|
|
739
|
+
const { values, put } = valuesOf(n);
|
|
740
|
+
const keys = {
|
|
741
|
+
color: cells(snapshot, target, "color"),
|
|
742
|
+
size: cells(snapshot, target, "size"),
|
|
743
|
+
label: cells(snapshot, target, "label"),
|
|
744
|
+
hidden: cells(snapshot, target, "hidden")
|
|
745
|
+
};
|
|
746
|
+
readFrom[target].push(...Object.entries(keys).flatMap(([name, c]) => c === null ? [] : [name]));
|
|
747
|
+
for (let i = 0; i < n; i++) {
|
|
748
|
+
const site = (property) => ({
|
|
749
|
+
notes,
|
|
750
|
+
target,
|
|
751
|
+
property,
|
|
752
|
+
element: i,
|
|
753
|
+
budget: context.budget
|
|
754
|
+
});
|
|
755
|
+
readSigmaRow(keys, target, i, put, site);
|
|
756
|
+
}
|
|
757
|
+
out[target] = values;
|
|
758
|
+
}
|
|
759
|
+
exactFromBlock(snapshot, blockText(snapshot, src), out, GRAPHOLOGY_WRITTEN);
|
|
760
|
+
return {
|
|
761
|
+
canonical: true,
|
|
762
|
+
dialect: "graphology",
|
|
763
|
+
tool: "sigma",
|
|
764
|
+
opacityInColor: true,
|
|
765
|
+
units: "relative",
|
|
766
|
+
node: { values: out.node },
|
|
767
|
+
edge: { values: out.edge },
|
|
768
|
+
notes: notes.list(),
|
|
769
|
+
readFrom
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
function readSigmaRow(keys, target, i, put, site) {
|
|
773
|
+
const { color, size, label, hidden } = keys;
|
|
774
|
+
if (color !== null) {
|
|
775
|
+
const [fill, opacity] = target === "node" ? ["fill", "fillOpacity"] : ["color", "opacity"];
|
|
776
|
+
putColor(put, fill, opacity, i, color(i), site(fill));
|
|
777
|
+
}
|
|
778
|
+
if (size !== null) {
|
|
779
|
+
const v = canonNumber(size(i), site("width"));
|
|
780
|
+
put("width", i, v);
|
|
781
|
+
if (target === "node") {
|
|
782
|
+
put("height", i, v);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
if (label !== null) {
|
|
786
|
+
put("label", i, canonText(label(i), site("label")));
|
|
787
|
+
}
|
|
788
|
+
if (hidden !== null && canonBoolean(hidden(i), site("visible")) === true) {
|
|
789
|
+
put("visible", i, false);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
function putColor(put, property, opacity, i, raw, site) {
|
|
793
|
+
if (raw === null || raw === void 0 || raw === "") {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
const c = canonColor(raw, "css", site);
|
|
797
|
+
if (c === null) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
put(property, i, c.color);
|
|
801
|
+
if (c.alpha < 1) {
|
|
802
|
+
if (opacity === null) {
|
|
803
|
+
site.notes.add(STYLE_ISSUE.ALPHA_DROPPED, site.target, property, { sample: raw, element: i });
|
|
804
|
+
} else {
|
|
805
|
+
put(opacity, i, c.alpha);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
function blockText(snapshot, src) {
|
|
810
|
+
if (src.block !== null) {
|
|
811
|
+
return src.block;
|
|
812
|
+
}
|
|
813
|
+
if (!snapshot.graph.has(STYLE_BLOCK_NAME)) {
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
const v = plainCell(snapshot.graph.value(STYLE_BLOCK_NAME, 0));
|
|
817
|
+
return typeof v === "string" ? v : null;
|
|
818
|
+
}
|
|
819
|
+
function exactFromBlock(snapshot, text, values, written, holdsExactly) {
|
|
820
|
+
if (text === null) {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
|
|
824
|
+
const ex = parsed.ok ? blockStyles(parsed.block, snapshot, "json") : null;
|
|
825
|
+
if (ex === null) {
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
for (const target of TARGETS) {
|
|
829
|
+
const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
|
|
830
|
+
const cache = /* @__PURE__ */ new Map();
|
|
831
|
+
const resolved = (p) => {
|
|
832
|
+
let r = cache.get(p);
|
|
833
|
+
if (r === void 0) {
|
|
834
|
+
r = resolveStyles(ex, target, p, snapshot);
|
|
835
|
+
cache.set(p, r);
|
|
836
|
+
}
|
|
837
|
+
return r;
|
|
838
|
+
};
|
|
839
|
+
if (holdsExactly !== void 0) {
|
|
840
|
+
const properties = new Set(
|
|
841
|
+
ex.styles.rules.filter((r) => r.target === target).flatMap((r) => [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})])
|
|
842
|
+
);
|
|
843
|
+
for (const property of properties) {
|
|
844
|
+
const held = (w) => holdsExactly(target, property, w);
|
|
845
|
+
takeUnheld(values[target], property, resolved(property), n, held);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
for (const [property, write2] of Object.entries(written[target] ?? {})) {
|
|
849
|
+
takeWritten(values[target], property, n, resolved, write2, snapshot);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
function takeWritten(column, property, n, resolved, write2, snapshot) {
|
|
854
|
+
const want = resolved(property);
|
|
855
|
+
for (let i = 0; i < n; i++) {
|
|
856
|
+
const w = want[i];
|
|
857
|
+
const native = column[property]?.[i] ?? null;
|
|
858
|
+
if (native !== w && native !== null && native === write2((p) => resolved(p)[i], i, snapshot)) {
|
|
859
|
+
setValue(column, property, n, i, w);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
function takeUnheld(values, property, want, n, held) {
|
|
864
|
+
for (let i = 0; i < n; i++) {
|
|
865
|
+
const w = want[i];
|
|
866
|
+
if (w !== null && !held(w)) {
|
|
867
|
+
setValue(values, property, n, i, w);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
const oneSize = (want) => {
|
|
872
|
+
const w = want("width");
|
|
873
|
+
const h = want("height");
|
|
874
|
+
return typeof w === "number" && typeof h === "number" ? Math.max(w, h) : w ?? h;
|
|
875
|
+
};
|
|
876
|
+
const GRAPHOLOGY_WRITTEN = { node: { width: oneSize, height: oneSize } };
|
|
877
|
+
const VIS_SIZED = /* @__PURE__ */ new Set([
|
|
878
|
+
"image",
|
|
879
|
+
"circularImage",
|
|
880
|
+
"diamond",
|
|
881
|
+
"dot",
|
|
882
|
+
"star",
|
|
883
|
+
"triangle",
|
|
884
|
+
"triangleDown",
|
|
885
|
+
"hexagon",
|
|
886
|
+
"square",
|
|
887
|
+
"icon"
|
|
888
|
+
]);
|
|
889
|
+
const VIS_GROUP_PALETTE = [
|
|
890
|
+
["#2B7CE9", "#97C2FC"],
|
|
891
|
+
["#FFA500", "#FFFF00"],
|
|
892
|
+
["#FA0A10", "#FB7E81"],
|
|
893
|
+
["#41A906", "#7BE141"],
|
|
894
|
+
["#E129F0", "#EB7DF4"],
|
|
895
|
+
["#7C29F0", "#AD85E4"],
|
|
896
|
+
["#C37F00", "#FFA807"],
|
|
897
|
+
["#4220FB", "#6E6EFD"],
|
|
898
|
+
["#FD5A77", "#FFC0CB"],
|
|
899
|
+
["#4AD63A", "#C2FABC"],
|
|
900
|
+
["#990000", "#EE0000"],
|
|
901
|
+
["#FF6000", "#FF6000"],
|
|
902
|
+
["#97C2FC", "#2B7CE9"],
|
|
903
|
+
["#399605", "#255C03"],
|
|
904
|
+
["#B70054", "#FF007E"],
|
|
905
|
+
["#AD85E4", "#7C29F0"],
|
|
906
|
+
["#4557FA", "#000EA1"],
|
|
907
|
+
["#FFC0CB", "#FD5A77"],
|
|
908
|
+
["#C2FABC", "#74D66A"],
|
|
909
|
+
["#EE0000", "#990000"]
|
|
910
|
+
];
|
|
911
|
+
const VIS_EDGE_COLOR = "#848484";
|
|
912
|
+
function visParseColor(text) {
|
|
913
|
+
let hex = text;
|
|
914
|
+
const rgb = /^rgb\( *(\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3}) *\)$/i.exec(text);
|
|
915
|
+
if (rgb?.slice(1).every((c) => Number(c) <= 255)) {
|
|
916
|
+
hex = `#${((1 << 24) + (Number(rgb[1]) << 16) + (Number(rgb[2]) << 8) + Number(rgb[3])).toString(16).slice(1)}`;
|
|
917
|
+
}
|
|
918
|
+
if (!/^#([0-9a-f]{6}|[0-9a-f]{3})$/i.test(hex)) {
|
|
919
|
+
return { background: text, border: text };
|
|
920
|
+
}
|
|
921
|
+
const full = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;
|
|
922
|
+
return { background: full, border: visBorder(full) };
|
|
923
|
+
}
|
|
924
|
+
function visBorder(full) {
|
|
925
|
+
const n = Number.parseInt(full.slice(1), 16);
|
|
926
|
+
const [r, g, b] = [n >> 16 & 255, n >> 8 & 255, n & 255].map((c) => c / 255);
|
|
927
|
+
const max = Math.max(r, g, b);
|
|
928
|
+
const min = Math.min(r, g, b);
|
|
929
|
+
let h = 0;
|
|
930
|
+
let s = 0;
|
|
931
|
+
if (max !== min) {
|
|
932
|
+
let d = b - r;
|
|
933
|
+
let k = 5;
|
|
934
|
+
if (r === min) {
|
|
935
|
+
d = g - b;
|
|
936
|
+
k = 3;
|
|
937
|
+
} else if (b === min) {
|
|
938
|
+
d = r - g;
|
|
939
|
+
k = 1;
|
|
940
|
+
}
|
|
941
|
+
h = 60 * (k - d / (max - min)) / 360;
|
|
942
|
+
s = (max - min) / max;
|
|
943
|
+
}
|
|
944
|
+
const sv = Math.min(1, s * 1.25);
|
|
945
|
+
const vv = max * 0.8;
|
|
946
|
+
const i = Math.floor(h * 6);
|
|
947
|
+
const f = h * 6 - i;
|
|
948
|
+
const p = vv * (1 - sv);
|
|
949
|
+
const q = vv * (1 - f * sv);
|
|
950
|
+
const t = vv * (1 - (1 - f) * sv);
|
|
951
|
+
const rgbOut = [
|
|
952
|
+
[vv, t, p],
|
|
953
|
+
[q, vv, p],
|
|
954
|
+
[p, vv, t],
|
|
955
|
+
[p, q, vv],
|
|
956
|
+
[t, p, vv],
|
|
957
|
+
[vv, p, q]
|
|
958
|
+
][i % 6].map((c) => Math.floor(c * 255));
|
|
959
|
+
return `#${((1 << 24) + (rgbOut[0] << 16) + (rgbOut[1] << 8) + rgbOut[2]).toString(16).slice(1)}`;
|
|
960
|
+
}
|
|
961
|
+
function visLayer(o, target) {
|
|
962
|
+
if (!isJsonObject(o)) {
|
|
963
|
+
return {};
|
|
964
|
+
}
|
|
965
|
+
const layer = {};
|
|
966
|
+
const set = (k, v) => {
|
|
967
|
+
if (v !== void 0 && v !== null) {
|
|
968
|
+
layer[k] = v;
|
|
969
|
+
}
|
|
970
|
+
};
|
|
971
|
+
if (target === "node") {
|
|
972
|
+
visNodeLayer(o, set);
|
|
973
|
+
} else {
|
|
974
|
+
visEdgeLayer(o, set);
|
|
975
|
+
}
|
|
976
|
+
set("hidden", o.hidden);
|
|
977
|
+
set("label", o.label);
|
|
978
|
+
set("title", o.title);
|
|
979
|
+
visFontLayer(o.font, set);
|
|
980
|
+
return layer;
|
|
981
|
+
}
|
|
982
|
+
function visNodeLayer(o, set) {
|
|
983
|
+
const { color } = o;
|
|
984
|
+
if (typeof color === "string") {
|
|
985
|
+
const parsed = visParseColor(color.trim());
|
|
986
|
+
set("fill", parsed.background);
|
|
987
|
+
set("border", parsed.border);
|
|
988
|
+
} else if (isJsonObject(color)) {
|
|
989
|
+
set("fill", color.background);
|
|
990
|
+
set("border", color.border);
|
|
991
|
+
}
|
|
992
|
+
set("shape", o.shape);
|
|
993
|
+
set("size", o.size);
|
|
994
|
+
set("borderWidth", o.borderWidth);
|
|
995
|
+
set("opacity", o.opacity);
|
|
996
|
+
}
|
|
997
|
+
function visEdgeLayer(o, set) {
|
|
998
|
+
const { color } = o;
|
|
999
|
+
if (typeof color === "string") {
|
|
1000
|
+
set("edgeColor", color);
|
|
1001
|
+
set("inherit", false);
|
|
1002
|
+
} else if (isJsonObject(color)) {
|
|
1003
|
+
set("edgeColor", color.color);
|
|
1004
|
+
set("edgeOpacity", color.opacity);
|
|
1005
|
+
const own = color.color !== void 0 || color.highlight !== void 0 || color.hover !== void 0;
|
|
1006
|
+
set("inherit", own ? false : color.inherit);
|
|
1007
|
+
}
|
|
1008
|
+
set("width", o.width);
|
|
1009
|
+
set("dashes", o.dashes);
|
|
1010
|
+
set("arrows", o.arrows);
|
|
1011
|
+
}
|
|
1012
|
+
function visFontLayer(font, set) {
|
|
1013
|
+
if (isJsonObject(font)) {
|
|
1014
|
+
set("fontColor", font.color);
|
|
1015
|
+
set("fontSize", font.size);
|
|
1016
|
+
set("fontFace", font.face);
|
|
1017
|
+
} else if (typeof font === "string") {
|
|
1018
|
+
const m = /^\s*(\d+(?:\.\d+)?)(?:px)?\s+(\S+)(?:\s+(\S+))?/.exec(font.slice(0, 256));
|
|
1019
|
+
if (m !== null) {
|
|
1020
|
+
set("fontSize", Number(m[1]));
|
|
1021
|
+
set("fontFace", m[2]);
|
|
1022
|
+
set("fontColor", m[3]);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
function visValues(layer, target, site, sized) {
|
|
1027
|
+
const out = {};
|
|
1028
|
+
const put = (p, v) => {
|
|
1029
|
+
if (v !== null) {
|
|
1030
|
+
out[p] = v;
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
const color = (p, opacity, raw) => {
|
|
1034
|
+
if (raw === void 0 || raw === null || raw === "") {
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
const c = canonColor(raw, "vis", site(p));
|
|
1038
|
+
if (c !== null) {
|
|
1039
|
+
put(p, c.color);
|
|
1040
|
+
if (c.alpha < 1 && opacity !== null) {
|
|
1041
|
+
put(opacity, c.alpha);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
if (target === "node") {
|
|
1046
|
+
color("fill", "fillOpacity", layer.fill);
|
|
1047
|
+
color("borderColor", null, layer.border);
|
|
1048
|
+
visNodeValues(layer, sized, put, site);
|
|
1049
|
+
} else {
|
|
1050
|
+
color("color", "opacity", layer.edgeColor);
|
|
1051
|
+
visEdgeValues(layer, put, site);
|
|
1052
|
+
}
|
|
1053
|
+
if (layer.hidden !== void 0 && canonBoolean(layer.hidden, site("visible")) === true) {
|
|
1054
|
+
put("visible", false);
|
|
1055
|
+
}
|
|
1056
|
+
if (layer.label !== void 0) {
|
|
1057
|
+
put("label", canonText(layer.label, site("label")));
|
|
1058
|
+
}
|
|
1059
|
+
if (layer.title !== void 0) {
|
|
1060
|
+
put("tooltip", canonText(layer.title, site("tooltip")));
|
|
1061
|
+
}
|
|
1062
|
+
color("labelColor", null, layer.fontColor);
|
|
1063
|
+
if (layer.fontSize !== void 0) {
|
|
1064
|
+
put("labelSize", canonNumber(layer.fontSize, site("labelSize")));
|
|
1065
|
+
}
|
|
1066
|
+
if (layer.fontFace !== void 0) {
|
|
1067
|
+
put("labelFont", canonText(layer.fontFace, site("labelFont")));
|
|
1068
|
+
}
|
|
1069
|
+
return out;
|
|
1070
|
+
}
|
|
1071
|
+
function visNodeValues(layer, sized, put, site) {
|
|
1072
|
+
if (layer.shape !== void 0) {
|
|
1073
|
+
put("shape", canonEnum("shape", layer.shape, "vis", site("shape")));
|
|
1074
|
+
}
|
|
1075
|
+
if (sized && layer.size !== void 0) {
|
|
1076
|
+
const v = canonNumber(layer.size, site("width"));
|
|
1077
|
+
put("width", v);
|
|
1078
|
+
put("height", v);
|
|
1079
|
+
}
|
|
1080
|
+
if (layer.borderWidth !== void 0) {
|
|
1081
|
+
put("borderWidth", canonNumber(layer.borderWidth, site("borderWidth")));
|
|
1082
|
+
}
|
|
1083
|
+
if (layer.opacity !== void 0) {
|
|
1084
|
+
put("opacity", canonOpacity(layer.opacity, "vis", site("opacity")));
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
function visEdgeValues(layer, put, site) {
|
|
1088
|
+
if (layer.edgeOpacity !== void 0) {
|
|
1089
|
+
put("opacity", canonOpacity(layer.edgeOpacity, "vis", site("opacity")));
|
|
1090
|
+
}
|
|
1091
|
+
if (layer.width !== void 0) {
|
|
1092
|
+
put("width", canonNumber(layer.width, site("width")));
|
|
1093
|
+
}
|
|
1094
|
+
if (layer.dashes !== void 0) {
|
|
1095
|
+
put("lineStyle", layer.dashes === false || layer.dashes === "false" ? "solid" : "dashed");
|
|
1096
|
+
}
|
|
1097
|
+
if (layer.arrows !== void 0) {
|
|
1098
|
+
const [to, from] = visArrows(layer.arrows, site);
|
|
1099
|
+
put("targetArrow", to);
|
|
1100
|
+
put("sourceArrow", from);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
function visArrows(arrows, site) {
|
|
1104
|
+
const end = (name, property) => {
|
|
1105
|
+
if (typeof arrows === "string") {
|
|
1106
|
+
return new RegExp(String.raw`\b${name}\b`).test(arrows.slice(0, 256)) ? "triangle" : "none";
|
|
1107
|
+
}
|
|
1108
|
+
if (!isJsonObject(arrows)) {
|
|
1109
|
+
return null;
|
|
1110
|
+
}
|
|
1111
|
+
const a = arrows[name];
|
|
1112
|
+
if (a === true) {
|
|
1113
|
+
return "triangle";
|
|
1114
|
+
}
|
|
1115
|
+
if (!isJsonObject(a) || a.enabled === false) {
|
|
1116
|
+
return "none";
|
|
1117
|
+
}
|
|
1118
|
+
return canonEnum("arrow", a.type ?? "arrow", "vis", site(property));
|
|
1119
|
+
};
|
|
1120
|
+
return [end("to", "targetArrow"), end("from", "sourceArrow")];
|
|
1121
|
+
}
|
|
1122
|
+
function visStyles(snapshot, src, context) {
|
|
1123
|
+
const notes = new StyleNotes();
|
|
1124
|
+
const options = isJsonObject(src.options) ? src.options : {};
|
|
1125
|
+
const n = snapshot.nodeCount;
|
|
1126
|
+
const ruleSite = (target) => (property) => ({ notes, target, property });
|
|
1127
|
+
const nodeRules = [];
|
|
1128
|
+
const nodeColumns = /* @__PURE__ */ new Map();
|
|
1129
|
+
const nodeDefaults = visLayer(options.nodes, "node");
|
|
1130
|
+
const groupCol = cells(snapshot, "node", "group");
|
|
1131
|
+
const groupOf = (i) => {
|
|
1132
|
+
const g = groupCol?.(i);
|
|
1133
|
+
return typeof g === "string" || typeof g === "number" ? String(g) : null;
|
|
1134
|
+
};
|
|
1135
|
+
const { groupLayers, paletteRows } = visGroupLayers(n, groupOf, visGroupDefs(src, options));
|
|
1136
|
+
context.budget.spend("node", n);
|
|
1137
|
+
const node = valuesOf(n);
|
|
1138
|
+
const records = nodeRecords(snapshot);
|
|
1139
|
+
const rawShape = (layer) => typeof layer.shape === "string" ? layer.shape : null;
|
|
1140
|
+
for (let i = 0; i < n; i++) {
|
|
1141
|
+
const g = groupOf(i);
|
|
1142
|
+
const own = records(i);
|
|
1143
|
+
const group = g === null ? {} : groupLayers.get(g) ?? {};
|
|
1144
|
+
const shape = rawShape(own) ?? rawShape(group) ?? rawShape(nodeDefaults) ?? "ellipse";
|
|
1145
|
+
const site = (property) => ({
|
|
1146
|
+
notes,
|
|
1147
|
+
target: "node",
|
|
1148
|
+
property,
|
|
1149
|
+
element: i,
|
|
1150
|
+
budget: context.budget
|
|
1151
|
+
});
|
|
1152
|
+
const merged = { ...nodeDefaults, ...group, ...own };
|
|
1153
|
+
for (const [p, v] of Object.entries(visValues(merged, "node", site, VIS_SIZED.has(shape)))) {
|
|
1154
|
+
node.put(p, i, v);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
const declaredNode = visValues(nodeDefaults, "node", ruleSite("node"), true);
|
|
1158
|
+
if (Object.keys(declaredNode).length > 0) {
|
|
1159
|
+
nodeRules.push(rule("node.vis.defaults", "node", "defaults", "declared", { all: true }, declaredNode));
|
|
1160
|
+
}
|
|
1161
|
+
let k = 0;
|
|
1162
|
+
for (const [g, layer] of groupLayers) {
|
|
1163
|
+
const set = paletteRows.get(g) ?? visValues(layer, "node", ruleSite("node"), true);
|
|
1164
|
+
if (Object.keys(set).length === 0) {
|
|
1165
|
+
continue;
|
|
1166
|
+
}
|
|
1167
|
+
const key = `group.${String(k)}`;
|
|
1168
|
+
nodeColumns.set(
|
|
1169
|
+
key,
|
|
1170
|
+
Array.from({ length: n }, (_v, i) => groupOf(i) === g ? true : null)
|
|
1171
|
+
);
|
|
1172
|
+
const origin = paletteRows.has(g) ? "tool" : "declared";
|
|
1173
|
+
const r = rule(`node.vis.group.${String(k++)}`, "node", "group", origin, { has: { style: key } }, set);
|
|
1174
|
+
nodeRules.push({ ...r, facts: { names: [[key, g]] } });
|
|
1175
|
+
}
|
|
1176
|
+
const toolNode = toolDefaults("vis-network")?.node;
|
|
1177
|
+
const borderOf = (i) => node.values.borderColor?.[i] ?? toolNode?.borderColor?.value ?? "#2b7ce9";
|
|
1178
|
+
const edge = visEdges(snapshot, visLayer(options.edges, "edge"), borderOf, notes, context);
|
|
1179
|
+
const values = { node: node.values, edge: edge.values };
|
|
1180
|
+
exactFromBlock(snapshot, src.block, values, VIS_WRITTEN);
|
|
1181
|
+
return {
|
|
1182
|
+
canonical: true,
|
|
1183
|
+
dialect: "vis",
|
|
1184
|
+
tool: "vis-network",
|
|
1185
|
+
opacityInColor: true,
|
|
1186
|
+
units: "px",
|
|
1187
|
+
node: { values: values.node, rules: nodeRules, columns: nodeColumns },
|
|
1188
|
+
edge: { values: values.edge, rules: edge.rules, columns: edge.columns },
|
|
1189
|
+
notes: notes.list(),
|
|
1190
|
+
block: src.block,
|
|
1191
|
+
readFrom: {
|
|
1192
|
+
node: VIS_KEYS.node.filter((x) => snapshot.nodes.has(x)),
|
|
1193
|
+
edge: VIS_KEYS.edge.filter((x) => snapshot.edges.has(x))
|
|
1194
|
+
}
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
function visGroupDefs(src, options) {
|
|
1198
|
+
if (isJsonObject(options.groups)) {
|
|
1199
|
+
return options.groups;
|
|
1200
|
+
}
|
|
1201
|
+
return isJsonObject(src.groups) ? src.groups : {};
|
|
1202
|
+
}
|
|
1203
|
+
function visGroupLayers(n, groupOf, groupDefs) {
|
|
1204
|
+
const groupLayers = /* @__PURE__ */ new Map();
|
|
1205
|
+
const paletteRows = /* @__PURE__ */ new Map();
|
|
1206
|
+
let palette = 0;
|
|
1207
|
+
for (let i = 0; i < n; i++) {
|
|
1208
|
+
const g = groupOf(i);
|
|
1209
|
+
if (g === null || groupLayers.has(g)) {
|
|
1210
|
+
continue;
|
|
1211
|
+
}
|
|
1212
|
+
if (Object.hasOwn(groupDefs, g)) {
|
|
1213
|
+
groupLayers.set(g, visLayer(groupDefs[g], "node"));
|
|
1214
|
+
} else {
|
|
1215
|
+
const [border, background] = VIS_GROUP_PALETTE[palette++ % VIS_GROUP_PALETTE.length];
|
|
1216
|
+
groupLayers.set(g, { fill: background, border });
|
|
1217
|
+
paletteRows.set(g, { fill: background.toLowerCase(), borderColor: border.toLowerCase() });
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
return { groupLayers, paletteRows };
|
|
1221
|
+
}
|
|
1222
|
+
function visEdges(snapshot, edgeDefaults, borderOf, notes, context) {
|
|
1223
|
+
const m = snapshot.edgeCount;
|
|
1224
|
+
const edge = valuesOf(m);
|
|
1225
|
+
const edgeRecords = elementRecords(snapshot, "edge");
|
|
1226
|
+
const inherited = new Array(m).fill(null);
|
|
1227
|
+
let inheriting = 0;
|
|
1228
|
+
for (let e = 0; e < m; e++) {
|
|
1229
|
+
const own = edgeRecords(e);
|
|
1230
|
+
const merged = { ...edgeDefaults, ...own };
|
|
1231
|
+
const site = (property) => ({
|
|
1232
|
+
notes,
|
|
1233
|
+
target: "edge",
|
|
1234
|
+
property,
|
|
1235
|
+
element: e,
|
|
1236
|
+
budget: context.budget
|
|
1237
|
+
});
|
|
1238
|
+
const vals = visValues(merged, "edge", site, true);
|
|
1239
|
+
for (const [p, v] of Object.entries(vals)) {
|
|
1240
|
+
edge.put(p, e, v);
|
|
1241
|
+
}
|
|
1242
|
+
const inherit = own.inherit ?? edgeDefaults.inherit ?? "from";
|
|
1243
|
+
if (inherit === false || inherit === "false") {
|
|
1244
|
+
if (vals.color === void 0) {
|
|
1245
|
+
edge.put("color", e, VIS_EDGE_COLOR);
|
|
1246
|
+
}
|
|
1247
|
+
continue;
|
|
1248
|
+
}
|
|
1249
|
+
if (inherit === "both") {
|
|
1250
|
+
notes.add(STYLE_ISSUE.GRADIENT, "edge", "color", { sample: "inherit both", element: e });
|
|
1251
|
+
}
|
|
1252
|
+
inherited[e] = borderOf(inherit === "to" ? snapshot.edgeTarget(e) : snapshot.edgeSource(e));
|
|
1253
|
+
inheriting++;
|
|
1254
|
+
}
|
|
1255
|
+
context.budget.spend("edge", m);
|
|
1256
|
+
const edgeRules = [];
|
|
1257
|
+
const edgeColumns = /* @__PURE__ */ new Map();
|
|
1258
|
+
const declaredEdge = visValues(edgeDefaults, "edge", (property) => ({ notes, target: "edge", property }), true);
|
|
1259
|
+
if (Object.keys(declaredEdge).length > 0) {
|
|
1260
|
+
edgeRules.push(rule("edge.vis.defaults", "edge", "defaults", "declared", { all: true }, declaredEdge));
|
|
1261
|
+
}
|
|
1262
|
+
if (inheriting > 0) {
|
|
1263
|
+
edgeColumns.set("source-color", inherited);
|
|
1264
|
+
edgeRules.push({
|
|
1265
|
+
id: "edge.tool.source-color",
|
|
1266
|
+
target: "edge",
|
|
1267
|
+
role: "passthrough",
|
|
1268
|
+
origin: "tool",
|
|
1269
|
+
where: { has: { style: "source-color" } },
|
|
1270
|
+
map: { color: { kind: "passthrough", by: { style: "source-color" } } },
|
|
1271
|
+
facts: { elements: inheriting, reason: "SOURCE_NODE_COLOR" }
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
return { values: edge.values, rules: edgeRules, columns: edgeColumns };
|
|
1275
|
+
}
|
|
1276
|
+
const VIS_KEYS = {
|
|
1277
|
+
node: ["color", "shape", "size", "borderWidth", "opacity", "hidden", "label", "title", "font"],
|
|
1278
|
+
edge: ["color", "width", "dashes", "arrows", "hidden", "label", "title", "font"]
|
|
1279
|
+
};
|
|
1280
|
+
function nodeRecords(snapshot) {
|
|
1281
|
+
return elementRecords(snapshot, "node");
|
|
1282
|
+
}
|
|
1283
|
+
function elementRecords(snapshot, target) {
|
|
1284
|
+
const readers = VIS_KEYS[target].map((name) => [name, cells(snapshot, target, name)]).filter((x) => x[1] !== null);
|
|
1285
|
+
return (i) => {
|
|
1286
|
+
const record = {};
|
|
1287
|
+
for (const [name, read] of readers) {
|
|
1288
|
+
const v = read(i);
|
|
1289
|
+
if (v !== null) {
|
|
1290
|
+
record[name] = v;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
return visLayer(record, target);
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
function rule(id, target, role, origin, where, set) {
|
|
1297
|
+
const values = {};
|
|
1298
|
+
for (const [p, v] of Object.entries(set)) {
|
|
1299
|
+
if (v !== null) {
|
|
1300
|
+
values[p] = v;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
return { id, target, role, origin, where, set: values };
|
|
1304
|
+
}
|
|
1305
|
+
const VIS_SHAPES = /* @__PURE__ */ new Map([
|
|
1306
|
+
["ellipse", ["dot", true]],
|
|
1307
|
+
["rectangle", ["square", true]],
|
|
1308
|
+
["round-rectangle", ["box", true]],
|
|
1309
|
+
["triangle", ["triangle", true]],
|
|
1310
|
+
["diamond", ["diamond", true]],
|
|
1311
|
+
["star", ["star", true]],
|
|
1312
|
+
["hexagon", ["hexagon", true]],
|
|
1313
|
+
["none", ["text", true]],
|
|
1314
|
+
["pentagon", ["hexagon", false]],
|
|
1315
|
+
["octagon", ["hexagon", false]],
|
|
1316
|
+
["parallelogram", ["box", false]],
|
|
1317
|
+
["trapezoid", ["box", false]],
|
|
1318
|
+
["vee", ["triangle", false]]
|
|
1319
|
+
]);
|
|
1320
|
+
const VIS_ARROW_TYPES = /* @__PURE__ */ new Map([
|
|
1321
|
+
["triangle", ["arrow", true]],
|
|
1322
|
+
["tee", ["bar", true]],
|
|
1323
|
+
["circle", ["circle", true]],
|
|
1324
|
+
["square", ["box", true]],
|
|
1325
|
+
["crow", ["crow", true]],
|
|
1326
|
+
["diamond", ["diamond", true]],
|
|
1327
|
+
["vee", ["vee", true]],
|
|
1328
|
+
["inverted", ["inv_triangle", true]],
|
|
1329
|
+
["triangle-open", ["arrow", false]],
|
|
1330
|
+
["diamond-open", ["diamond", false]],
|
|
1331
|
+
["circle-open", ["circle", false]],
|
|
1332
|
+
["half", ["arrow", false]]
|
|
1333
|
+
]);
|
|
1334
|
+
function visShape(shape) {
|
|
1335
|
+
const known = VIS_SHAPES.get(shape);
|
|
1336
|
+
if (known !== void 0) {
|
|
1337
|
+
return known;
|
|
1338
|
+
}
|
|
1339
|
+
return shape.startsWith("other:") ? [shape.slice(6), true] : ["dot", false];
|
|
1340
|
+
}
|
|
1341
|
+
function visArrowType(arrow) {
|
|
1342
|
+
if (arrow === "none") {
|
|
1343
|
+
return [null, true];
|
|
1344
|
+
}
|
|
1345
|
+
const known = VIS_ARROW_TYPES.get(arrow);
|
|
1346
|
+
if (known !== void 0) {
|
|
1347
|
+
return known;
|
|
1348
|
+
}
|
|
1349
|
+
return arrow.startsWith("other:") ? [arrow.slice(6), true] : ["arrow", false];
|
|
1350
|
+
}
|
|
1351
|
+
const visSize = (want) => {
|
|
1352
|
+
const s = want("shape");
|
|
1353
|
+
const shape = typeof s === "string" ? visShape(s)[0] : "ellipse";
|
|
1354
|
+
return VIS_SIZED.has(shape) ? oneSize(want) : null;
|
|
1355
|
+
};
|
|
1356
|
+
const VIS_WRITTEN = {
|
|
1357
|
+
node: {
|
|
1358
|
+
width: visSize,
|
|
1359
|
+
height: visSize,
|
|
1360
|
+
shape: (want) => {
|
|
1361
|
+
const s = want("shape");
|
|
1362
|
+
if (typeof s !== "string") {
|
|
1363
|
+
return null;
|
|
1364
|
+
}
|
|
1365
|
+
const site = { notes: new StyleNotes(), target: "node", property: "shape" };
|
|
1366
|
+
return canonEnum("shape", visShape(s)[0], "vis", site);
|
|
1367
|
+
}
|
|
1368
|
+
},
|
|
1369
|
+
edge: {
|
|
1370
|
+
lineStyle: (want) => {
|
|
1371
|
+
const s = want("lineStyle");
|
|
1372
|
+
if (s === null) {
|
|
1373
|
+
return null;
|
|
1374
|
+
}
|
|
1375
|
+
return s === "solid" ? "solid" : "dashed";
|
|
1376
|
+
},
|
|
1377
|
+
targetArrow: (want) => arrowBack(want("targetArrow")),
|
|
1378
|
+
sourceArrow: (want) => arrowBack(want("sourceArrow"))
|
|
1379
|
+
}
|
|
1380
|
+
};
|
|
1381
|
+
function arrowBack(a) {
|
|
1382
|
+
if (typeof a !== "string") {
|
|
1383
|
+
return null;
|
|
1384
|
+
}
|
|
1385
|
+
const [type] = visArrowType(a);
|
|
1386
|
+
const site = { notes: new StyleNotes(), target: "edge", property: "targetArrow" };
|
|
1387
|
+
return type === null ? "none" : canonEnum("arrow", type, "vis", site);
|
|
1388
|
+
}
|
|
1389
|
+
function cyjsProperties(map, extra) {
|
|
1390
|
+
const out = /* @__PURE__ */ new Set();
|
|
1391
|
+
for (const spec of map.values()) {
|
|
1392
|
+
if (!spec.property.startsWith("_")) {
|
|
1393
|
+
out.add(spec.property);
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
for (const p of extra) {
|
|
1397
|
+
out.add(p);
|
|
1398
|
+
}
|
|
1399
|
+
return [...out];
|
|
1400
|
+
}
|
|
1401
|
+
const NATIVE = {
|
|
1402
|
+
cytoscape: {
|
|
1403
|
+
node: cyjsProperties(CYJS_NODE_PROPERTIES, ["labelPosition", "labelItalic", "visible"]),
|
|
1404
|
+
edge: cyjsProperties(CYJS_EDGE_PROPERTIES, ["curved", "labelItalic", "visible"])
|
|
1405
|
+
},
|
|
1406
|
+
graphology: {
|
|
1407
|
+
node: ["fill", "fillOpacity", "width", "height", "label", "visible"],
|
|
1408
|
+
edge: ["color", "opacity", "width", "label", "visible"]
|
|
1409
|
+
},
|
|
1410
|
+
vis: {
|
|
1411
|
+
node: [
|
|
1412
|
+
"fill",
|
|
1413
|
+
"fillOpacity",
|
|
1414
|
+
"borderColor",
|
|
1415
|
+
"borderWidth",
|
|
1416
|
+
"shape",
|
|
1417
|
+
"width",
|
|
1418
|
+
"height",
|
|
1419
|
+
"opacity",
|
|
1420
|
+
"label",
|
|
1421
|
+
"tooltip",
|
|
1422
|
+
"labelColor",
|
|
1423
|
+
"labelSize",
|
|
1424
|
+
"labelFont",
|
|
1425
|
+
"visible"
|
|
1426
|
+
],
|
|
1427
|
+
edge: [
|
|
1428
|
+
"color",
|
|
1429
|
+
"opacity",
|
|
1430
|
+
"width",
|
|
1431
|
+
"lineStyle",
|
|
1432
|
+
"targetArrow",
|
|
1433
|
+
"sourceArrow",
|
|
1434
|
+
"label",
|
|
1435
|
+
"tooltip",
|
|
1436
|
+
"labelColor",
|
|
1437
|
+
"labelSize",
|
|
1438
|
+
"labelFont",
|
|
1439
|
+
"visible"
|
|
1440
|
+
]
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
1443
|
+
const JSON_STYLE_CAPABILITIES = Object.freeze({
|
|
1444
|
+
node: Object.freeze([
|
|
1445
|
+
.../* @__PURE__ */ new Set([...NATIVE.cytoscape.node, ...NATIVE.vis.node, ...NATIVE.graphology.node])
|
|
1446
|
+
]),
|
|
1447
|
+
edge: Object.freeze([
|
|
1448
|
+
.../* @__PURE__ */ new Set([...NATIVE.cytoscape.edge, ...NATIVE.vis.edge, ...NATIVE.graphology.edge])
|
|
1449
|
+
]),
|
|
1450
|
+
block: "native"
|
|
1451
|
+
});
|
|
1452
|
+
const BLOCK_AS_ATTRIBUTE = /* @__PURE__ */ new Set(["node-link", "jgf", "graphology"]);
|
|
1453
|
+
function jsonStyledExport(snapshot, dialect, input) {
|
|
1454
|
+
if (input === void 0) {
|
|
1455
|
+
return null;
|
|
1456
|
+
}
|
|
1457
|
+
const native = dialect === "cytoscape" || dialect === "graphology" || dialect === "vis" ? NATIVE[dialect] : null;
|
|
1458
|
+
const notes = [...notWritten(input, dialect, native), ...rulesNotKept(snapshot, dialect, input)];
|
|
1459
|
+
if (dialect === "obographs") {
|
|
1460
|
+
return { snapshot, topLevelBlock: null, stylesheet: null, groups: null, notes };
|
|
1461
|
+
}
|
|
1462
|
+
const out = snapshot.withColumns();
|
|
1463
|
+
const read = dataColumnsRead(input.rules.styles.rules);
|
|
1464
|
+
for (const [table, target] of [
|
|
1465
|
+
[out.nodes, "node"],
|
|
1466
|
+
[out.edges, "edge"]
|
|
1467
|
+
]) {
|
|
1468
|
+
removeEarlierStyleKeys(table, dialect, read[target]);
|
|
1469
|
+
for (const [name, col] of input.tags[target]) {
|
|
1470
|
+
setColumn(table, name, col);
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
if (out.graph.has(STYLE_BLOCK_NAME)) {
|
|
1474
|
+
out.graph.remove(STYLE_BLOCK_NAME);
|
|
1475
|
+
}
|
|
1476
|
+
if (BLOCK_AS_ATTRIBUTE.has(dialect)) {
|
|
1477
|
+
out.graph.set(STYLE_BLOCK_NAME, [input.block], { dtype: "string" });
|
|
1478
|
+
}
|
|
1479
|
+
let stylesheet = null;
|
|
1480
|
+
const approximated = new StyleApproximations();
|
|
1481
|
+
const replaced = new Replaced(out.nodes);
|
|
1482
|
+
if (dialect === "cytoscape") {
|
|
1483
|
+
const emitted = writeCytoscapeStyles(out, input);
|
|
1484
|
+
({ stylesheet } = emitted);
|
|
1485
|
+
notes.push(...emitted.notes.map(lossOf));
|
|
1486
|
+
addUntrimmedText(input, approximated);
|
|
1487
|
+
} else if (dialect === "graphology") {
|
|
1488
|
+
writeGraphology$1(out, input, approximated, replaced);
|
|
1489
|
+
} else if (dialect === "vis") {
|
|
1490
|
+
writeVis$1(out, input, approximated, replaced);
|
|
1491
|
+
}
|
|
1492
|
+
notes.push(...approximated.notes(`the ${dialect} dialect of JSON`), ...replaced.notes(dialect));
|
|
1493
|
+
return {
|
|
1494
|
+
snapshot: out,
|
|
1495
|
+
topLevelBlock: BLOCK_AS_ATTRIBUTE.has(dialect) ? null : input.block,
|
|
1496
|
+
stylesheet,
|
|
1497
|
+
groups: dialect === "vis" ? visGroups(out) : null,
|
|
1498
|
+
notes
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
function rulesNotKept(snapshot, dialect, input) {
|
|
1502
|
+
let message = null;
|
|
1503
|
+
if (dialect === "jgf" && !jgfKeepsNodes(snapshot)) {
|
|
1504
|
+
message = "the style rules are not kept: JGF changes the node ids' type or order (number ids become text, integer-like ids are read first), so the graphty.styles block no longer matches the graph read back";
|
|
1505
|
+
} else if (dialect === "obographs") {
|
|
1506
|
+
message = "the style rules are not kept: OBO Graphs has no place for them";
|
|
1507
|
+
}
|
|
1508
|
+
if (message === null) {
|
|
1509
|
+
return [];
|
|
1510
|
+
}
|
|
1511
|
+
return [
|
|
1512
|
+
Object.freeze({
|
|
1513
|
+
code: STYLE_ISSUE.RULES_NOT_KEPT,
|
|
1514
|
+
message,
|
|
1515
|
+
column: null,
|
|
1516
|
+
count: input.rules.styles.rules.length
|
|
1517
|
+
})
|
|
1518
|
+
];
|
|
1519
|
+
}
|
|
1520
|
+
function removeEarlierStyleKeys(table, dialect, read) {
|
|
1521
|
+
for (const name of table.names()) {
|
|
1522
|
+
const styleKey = name.startsWith("graphty.style.") || name.startsWith("graphty_style_") || name === CYTOSCAPE_IMPORT_KEY;
|
|
1523
|
+
if (styleKey && !read.has(name)) {
|
|
1524
|
+
table.remove(name);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
if (dialect === "cytoscape") {
|
|
1528
|
+
for (const name of ["style#element", "css#element"].filter((c) => table.has(c))) {
|
|
1529
|
+
table.remove(name);
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
function writeCytoscapeStyles(out, input) {
|
|
1534
|
+
const features = {
|
|
1535
|
+
node: input.rules.features.node.filter((f) => !("data" in f.ref) || out.nodes.has(f.ref.data)),
|
|
1536
|
+
edge: input.rules.features.edge.filter((f) => !("data" in f.ref) || out.edges.has(f.ref.data))
|
|
1537
|
+
};
|
|
1538
|
+
const emitted = toCytoscapeStylesheet({ ...input.rules, features });
|
|
1539
|
+
for (const [table, target] of [
|
|
1540
|
+
[out.nodes, "node"],
|
|
1541
|
+
[out.edges, "edge"]
|
|
1542
|
+
]) {
|
|
1543
|
+
const rows = emitted.elementData[target];
|
|
1544
|
+
const keys = new Set(rows.flatMap((row) => Object.keys(row ?? {})));
|
|
1545
|
+
for (const key of keys) {
|
|
1546
|
+
setColumn(
|
|
1547
|
+
table,
|
|
1548
|
+
key,
|
|
1549
|
+
rows.map((row) => row?.[key] ?? null)
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
const bypass = emitted.bypass[target].map((b) => b === null || Object.keys(b).length === 0 ? null : b);
|
|
1553
|
+
if (bypass.some((b) => b !== null)) {
|
|
1554
|
+
setColumn(table, "style#element", bypass);
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
return emitted;
|
|
1558
|
+
}
|
|
1559
|
+
function addUntrimmedText(input, approximated) {
|
|
1560
|
+
for (const target of TARGETS) {
|
|
1561
|
+
for (const property of CYJS_TEXT[target]) {
|
|
1562
|
+
for (const v of input.picture(target, property)) {
|
|
1563
|
+
if (typeof v === "string" && v.trim() !== v) {
|
|
1564
|
+
approximated.add(target, property, JSON.stringify(v));
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
function visGroups(snapshot) {
|
|
1571
|
+
const column = snapshot.nodes.get("group");
|
|
1572
|
+
if (column === null || column === void 0) {
|
|
1573
|
+
return null;
|
|
1574
|
+
}
|
|
1575
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1576
|
+
for (let i = 0; i < snapshot.nodeCount; i++) {
|
|
1577
|
+
const value = column.isSet(i) ? column.value(i) : null;
|
|
1578
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
1579
|
+
groups.set(String(value), {});
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
return groups.size === 0 ? null : Object.fromEntries(groups);
|
|
1583
|
+
}
|
|
1584
|
+
function dataColumnsRead(rules) {
|
|
1585
|
+
const out = { node: /* @__PURE__ */ new Set(), edge: /* @__PURE__ */ new Set() };
|
|
1586
|
+
for (const rule2 of rules) {
|
|
1587
|
+
const refs = [
|
|
1588
|
+
...predicateRefs(rule2.where),
|
|
1589
|
+
...Object.values(rule2.map ?? {}).flatMap((m) => m === void 0 ? [] : [m.by])
|
|
1590
|
+
];
|
|
1591
|
+
for (const ref of refs) {
|
|
1592
|
+
if ("data" in ref) {
|
|
1593
|
+
out[rule2.target].add(ref.data);
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
return out;
|
|
1598
|
+
}
|
|
1599
|
+
function predicateRefs(where) {
|
|
1600
|
+
const refs = [];
|
|
1601
|
+
const stack = [where];
|
|
1602
|
+
while (stack.length > 0) {
|
|
1603
|
+
const p = stack.pop();
|
|
1604
|
+
if ("has" in p) {
|
|
1605
|
+
refs.push(p.has);
|
|
1606
|
+
} else if ("eq" in p) {
|
|
1607
|
+
refs.push(p.eq[0]);
|
|
1608
|
+
} else if ("in" in p) {
|
|
1609
|
+
refs.push(p.in[0]);
|
|
1610
|
+
} else if ("and" in p) {
|
|
1611
|
+
stack.push(...p.and);
|
|
1612
|
+
} else if ("or" in p) {
|
|
1613
|
+
stack.push(...p.or);
|
|
1614
|
+
} else if ("not" in p) {
|
|
1615
|
+
stack.push(p.not);
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
return refs;
|
|
1619
|
+
}
|
|
1620
|
+
function jgfKeepsNodes(snapshot) {
|
|
1621
|
+
let last = -1;
|
|
1622
|
+
let other = false;
|
|
1623
|
+
for (let i = 0; i < snapshot.nodeCount; i++) {
|
|
1624
|
+
const id = snapshot.ids.idOf(i);
|
|
1625
|
+
if (typeof id === "number") {
|
|
1626
|
+
return false;
|
|
1627
|
+
}
|
|
1628
|
+
if (/^(0|[1-9]\d*)$/.test(id) && Number(id) < 4294967295) {
|
|
1629
|
+
if (other || Number(id) <= last) {
|
|
1630
|
+
return false;
|
|
1631
|
+
}
|
|
1632
|
+
last = Number(id);
|
|
1633
|
+
} else {
|
|
1634
|
+
other = true;
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
return true;
|
|
1638
|
+
}
|
|
1639
|
+
function notWritten(input, dialect, native) {
|
|
1640
|
+
const out = [];
|
|
1641
|
+
for (const target of TARGETS) {
|
|
1642
|
+
const all = new Set(JSON_STYLE_CAPABILITIES[target]);
|
|
1643
|
+
const held = new Set(native?.[target] ?? []);
|
|
1644
|
+
const used = /* @__PURE__ */ new Set();
|
|
1645
|
+
for (const r of input.rules.styles.rules) {
|
|
1646
|
+
if (r.target === target) {
|
|
1647
|
+
for (const p of [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})]) {
|
|
1648
|
+
used.add(p);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
for (const property of used) {
|
|
1653
|
+
if (!all.has(property) || held.has(property)) {
|
|
1654
|
+
continue;
|
|
1655
|
+
}
|
|
1656
|
+
const count = input.picture(target, property).filter((v) => v !== null).length;
|
|
1657
|
+
out.push(
|
|
1658
|
+
Object.freeze({
|
|
1659
|
+
code: STYLE_ISSUE.NOT_WRITTEN,
|
|
1660
|
+
message: `${target} ${property} is not written: the ${dialect} dialect of JSON has no place for it`,
|
|
1661
|
+
column: null,
|
|
1662
|
+
count,
|
|
1663
|
+
style: Object.freeze({ target, property })
|
|
1664
|
+
})
|
|
1665
|
+
);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
return out;
|
|
1669
|
+
}
|
|
1670
|
+
function lossOf(n) {
|
|
1671
|
+
return Object.freeze({
|
|
1672
|
+
code: n.code,
|
|
1673
|
+
message: n.message,
|
|
1674
|
+
column: null,
|
|
1675
|
+
count: n.params.count,
|
|
1676
|
+
style: n.params.target === null || n.params.property === null ? void 0 : Object.freeze({ target: n.params.target, property: n.params.property })
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
function setColumn(table, name, values) {
|
|
1680
|
+
const kinds = new Set(values.filter((v) => v !== null && v !== void 0).map((v) => typeof v));
|
|
1681
|
+
let dtype = "json";
|
|
1682
|
+
if (kinds.size === 1) {
|
|
1683
|
+
if (kinds.has("number")) {
|
|
1684
|
+
dtype = "f64";
|
|
1685
|
+
} else if (kinds.has("boolean")) {
|
|
1686
|
+
dtype = "bool";
|
|
1687
|
+
} else if (kinds.has("string")) {
|
|
1688
|
+
dtype = "string";
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
table.set(
|
|
1692
|
+
name,
|
|
1693
|
+
values.map((v) => v === null ? void 0 : v),
|
|
1694
|
+
{ dtype }
|
|
1695
|
+
);
|
|
1696
|
+
}
|
|
1697
|
+
function writeKey(table, name, values, replaced) {
|
|
1698
|
+
const old = table.get(name);
|
|
1699
|
+
let changed = 0;
|
|
1700
|
+
if (old !== null) {
|
|
1701
|
+
for (let i = 0; i < values.length; i++) {
|
|
1702
|
+
const before = plainCell(old.value(i));
|
|
1703
|
+
const after = values[i] ?? null;
|
|
1704
|
+
if (before !== null && JSON.stringify(before) !== JSON.stringify(after)) {
|
|
1705
|
+
changed++;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
if (changed > 0) {
|
|
1710
|
+
replaced.add(table === replaced.nodes ? "node" : "edge", name, changed);
|
|
1711
|
+
}
|
|
1712
|
+
if (values.every((v) => v === null || v === void 0)) {
|
|
1713
|
+
if (old !== null) {
|
|
1714
|
+
table.remove(name);
|
|
1715
|
+
}
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
setColumn(table, name, values);
|
|
1719
|
+
}
|
|
1720
|
+
const STYLE_KEY_REPLACED_CODE = "W_JSON_STYLE_KEY_REPLACED";
|
|
1721
|
+
class Replaced {
|
|
1722
|
+
/**
|
|
1723
|
+
* Counts the replaced values of one export.
|
|
1724
|
+
* @param nodes - the node table being written, which tells node columns from edge columns
|
|
1725
|
+
*/
|
|
1726
|
+
constructor(nodes) {
|
|
1727
|
+
this.nodes = nodes;
|
|
1728
|
+
}
|
|
1729
|
+
#counts = /* @__PURE__ */ new Map();
|
|
1730
|
+
/**
|
|
1731
|
+
* Counts replaced values.
|
|
1732
|
+
* @param target - nodes or edges
|
|
1733
|
+
* @param key - the key
|
|
1734
|
+
* @param count - how many
|
|
1735
|
+
*/
|
|
1736
|
+
add(target, key, count) {
|
|
1737
|
+
this.#counts.set(`${target}\0${key}`, (this.#counts.get(`${target}\0${key}`) ?? 0) + count);
|
|
1738
|
+
}
|
|
1739
|
+
/**
|
|
1740
|
+
* The notes, one per key.
|
|
1741
|
+
* @param dialect - the dialect, for the message
|
|
1742
|
+
* @returns the notes
|
|
1743
|
+
*/
|
|
1744
|
+
notes(dialect) {
|
|
1745
|
+
return Array.from(this.#counts, ([key, count]) => {
|
|
1746
|
+
const [target, name] = key.split("\0");
|
|
1747
|
+
return Object.freeze({
|
|
1748
|
+
code: STYLE_KEY_REPLACED_CODE,
|
|
1749
|
+
message: `${target} column "${name}" is the ${dialect} dialect's style key: ${String(count)} ${target}${count === 1 ? "" : "s"} get what graphty draws instead of the value the column held`,
|
|
1750
|
+
column: name,
|
|
1751
|
+
count
|
|
1752
|
+
});
|
|
1753
|
+
});
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
function cssColor(color, alpha) {
|
|
1757
|
+
if (typeof color !== "string") {
|
|
1758
|
+
return null;
|
|
1759
|
+
}
|
|
1760
|
+
if (typeof alpha !== "number" || alpha >= 1) {
|
|
1761
|
+
return color;
|
|
1762
|
+
}
|
|
1763
|
+
const n = Number.parseInt(color.slice(1), 16);
|
|
1764
|
+
return `rgba(${String(n >> 16 & 255)},${String(n >> 8 & 255)},${String(n & 255)},${String(alpha)})`;
|
|
1765
|
+
}
|
|
1766
|
+
function nodeSizes(width, height, approximated) {
|
|
1767
|
+
return width.map((_v, i) => {
|
|
1768
|
+
const w = width[i];
|
|
1769
|
+
const h = height[i];
|
|
1770
|
+
if (typeof w === "number" && typeof h === "number" && w !== h) {
|
|
1771
|
+
approximated.add("node", w > h ? "height" : "width", `${String(w)} x ${String(h)}`);
|
|
1772
|
+
return Math.max(w, h);
|
|
1773
|
+
}
|
|
1774
|
+
if (typeof w === "number") {
|
|
1775
|
+
return w;
|
|
1776
|
+
}
|
|
1777
|
+
return typeof h === "number" ? h : null;
|
|
1778
|
+
});
|
|
1779
|
+
}
|
|
1780
|
+
function writeGraphology$1(out, input, approximated, replaced) {
|
|
1781
|
+
const p = (target, property) => input.picture(target, property);
|
|
1782
|
+
for (const [table, target] of [
|
|
1783
|
+
[out.nodes, "node"],
|
|
1784
|
+
[out.edges, "edge"]
|
|
1785
|
+
]) {
|
|
1786
|
+
const [fill, opacity] = target === "node" ? ["fill", "fillOpacity"] : ["color", "opacity"];
|
|
1787
|
+
const colors = p(target, fill);
|
|
1788
|
+
const alphas = p(target, opacity);
|
|
1789
|
+
writeKey(
|
|
1790
|
+
table,
|
|
1791
|
+
"color",
|
|
1792
|
+
colors.map((c, i) => cssColor(c, alphas[i])),
|
|
1793
|
+
replaced
|
|
1794
|
+
);
|
|
1795
|
+
writeKey(
|
|
1796
|
+
table,
|
|
1797
|
+
"size",
|
|
1798
|
+
target === "node" ? nodeSizes(p("node", "width"), p("node", "height"), approximated) : p("edge", "width"),
|
|
1799
|
+
replaced
|
|
1800
|
+
);
|
|
1801
|
+
writeKey(table, "label", p(target, "label"), replaced);
|
|
1802
|
+
writeKey(
|
|
1803
|
+
table,
|
|
1804
|
+
"hidden",
|
|
1805
|
+
p(target, "visible").map((v) => v === false ? true : null),
|
|
1806
|
+
replaced
|
|
1807
|
+
);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
function writeVis$1(out, input, approximated, replaced) {
|
|
1811
|
+
const p = (target, property) => input.picture(target, property);
|
|
1812
|
+
const font = (target) => {
|
|
1813
|
+
const color2 = p(target, "labelColor");
|
|
1814
|
+
const size = p(target, "labelSize");
|
|
1815
|
+
const face = p(target, "labelFont");
|
|
1816
|
+
return color2.map((_v, i) => {
|
|
1817
|
+
const f = {};
|
|
1818
|
+
if (color2[i] !== null) {
|
|
1819
|
+
f.color = color2[i];
|
|
1820
|
+
}
|
|
1821
|
+
if (size[i] !== null) {
|
|
1822
|
+
f.size = size[i];
|
|
1823
|
+
}
|
|
1824
|
+
if (face[i] !== null) {
|
|
1825
|
+
f.face = face[i];
|
|
1826
|
+
}
|
|
1827
|
+
return Object.keys(f).length === 0 ? null : f;
|
|
1828
|
+
});
|
|
1829
|
+
};
|
|
1830
|
+
const label = (table, target) => {
|
|
1831
|
+
writeKey(table, "label", p(target, "label"), replaced);
|
|
1832
|
+
writeKey(table, "title", p(target, "tooltip"), replaced);
|
|
1833
|
+
writeKey(table, "font", font(target), replaced);
|
|
1834
|
+
writeKey(
|
|
1835
|
+
table,
|
|
1836
|
+
"hidden",
|
|
1837
|
+
p(target, "visible").map((v) => v === false ? true : null),
|
|
1838
|
+
replaced
|
|
1839
|
+
);
|
|
1840
|
+
};
|
|
1841
|
+
const fill = p("node", "fill");
|
|
1842
|
+
const fillOpacity = p("node", "fillOpacity");
|
|
1843
|
+
const border = p("node", "borderColor");
|
|
1844
|
+
writeKey(
|
|
1845
|
+
out.nodes,
|
|
1846
|
+
"color",
|
|
1847
|
+
fill.map((_v, i) => {
|
|
1848
|
+
const c = {};
|
|
1849
|
+
const bg = cssColor(fill[i], fillOpacity[i]);
|
|
1850
|
+
if (bg !== null) {
|
|
1851
|
+
c.background = bg;
|
|
1852
|
+
}
|
|
1853
|
+
if (typeof border[i] === "string") {
|
|
1854
|
+
c.border = border[i];
|
|
1855
|
+
}
|
|
1856
|
+
return Object.keys(c).length === 0 ? null : c;
|
|
1857
|
+
}),
|
|
1858
|
+
replaced
|
|
1859
|
+
);
|
|
1860
|
+
const sizes = nodeSizes(p("node", "width"), p("node", "height"), approximated);
|
|
1861
|
+
const shapes = p("node", "shape").map((s, i) => {
|
|
1862
|
+
const [shape, exact] = typeof s === "string" ? visShape(s) : [null, true];
|
|
1863
|
+
if (!exact) {
|
|
1864
|
+
approximated.add("node", "shape", s);
|
|
1865
|
+
}
|
|
1866
|
+
if (sizes[i] !== null && !VIS_SIZED.has(shape ?? "ellipse")) {
|
|
1867
|
+
approximated.add("node", "width", `${String(s ?? "ellipse")} sized by its label`);
|
|
1868
|
+
}
|
|
1869
|
+
return shape;
|
|
1870
|
+
});
|
|
1871
|
+
writeKey(out.nodes, "shape", shapes, replaced);
|
|
1872
|
+
writeKey(out.nodes, "size", sizes, replaced);
|
|
1873
|
+
writeKey(out.nodes, "borderWidth", p("node", "borderWidth"), replaced);
|
|
1874
|
+
writeKey(out.nodes, "opacity", p("node", "opacity"), replaced);
|
|
1875
|
+
label(out.nodes, "node");
|
|
1876
|
+
const color = p("edge", "color");
|
|
1877
|
+
const opacity = p("edge", "opacity");
|
|
1878
|
+
writeKey(
|
|
1879
|
+
out.edges,
|
|
1880
|
+
"color",
|
|
1881
|
+
color.map((_v, e) => {
|
|
1882
|
+
const c = {};
|
|
1883
|
+
if (typeof color[e] === "string") {
|
|
1884
|
+
c.color = color[e];
|
|
1885
|
+
}
|
|
1886
|
+
if (typeof opacity[e] === "number") {
|
|
1887
|
+
c.opacity = opacity[e];
|
|
1888
|
+
}
|
|
1889
|
+
return Object.keys(c).length === 0 ? null : c;
|
|
1890
|
+
}),
|
|
1891
|
+
replaced
|
|
1892
|
+
);
|
|
1893
|
+
writeKey(out.edges, "width", p("edge", "width"), replaced);
|
|
1894
|
+
writeKey(
|
|
1895
|
+
out.edges,
|
|
1896
|
+
"dashes",
|
|
1897
|
+
p("edge", "lineStyle").map((s) => {
|
|
1898
|
+
if (typeof s !== "string") {
|
|
1899
|
+
return null;
|
|
1900
|
+
}
|
|
1901
|
+
if (s !== "solid" && s !== "dashed") {
|
|
1902
|
+
approximated.add("edge", "lineStyle", s);
|
|
1903
|
+
}
|
|
1904
|
+
return s !== "solid";
|
|
1905
|
+
}),
|
|
1906
|
+
replaced
|
|
1907
|
+
);
|
|
1908
|
+
const to = p("edge", "targetArrow");
|
|
1909
|
+
const from = p("edge", "sourceArrow");
|
|
1910
|
+
writeKey(
|
|
1911
|
+
out.edges,
|
|
1912
|
+
"arrows",
|
|
1913
|
+
to.map((_v, e) => {
|
|
1914
|
+
const a = {};
|
|
1915
|
+
for (const [end, value, property] of [
|
|
1916
|
+
["to", to[e], "targetArrow"],
|
|
1917
|
+
["from", from[e], "sourceArrow"]
|
|
1918
|
+
]) {
|
|
1919
|
+
if (typeof value !== "string") {
|
|
1920
|
+
continue;
|
|
1921
|
+
}
|
|
1922
|
+
const [type, exact] = visArrowType(value);
|
|
1923
|
+
if (!exact) {
|
|
1924
|
+
approximated.add("edge", property, value);
|
|
1925
|
+
}
|
|
1926
|
+
a[end] = type === null ? { enabled: false } : { enabled: true, type };
|
|
1927
|
+
}
|
|
1928
|
+
return Object.keys(a).length === 0 ? null : a;
|
|
1929
|
+
}),
|
|
1930
|
+
replaced
|
|
1931
|
+
);
|
|
1932
|
+
label(out.edges, "edge");
|
|
1933
|
+
}
|
|
568
1934
|
const JSON_ISSUE = Object.freeze({
|
|
569
1935
|
...INPUT_ISSUE,
|
|
570
1936
|
...ELEMENT_ISSUE,
|
|
@@ -726,9 +2092,12 @@ const JGF_EDGE_KEYS = /* @__PURE__ */ new Set([
|
|
|
726
2092
|
"metadata"
|
|
727
2093
|
]);
|
|
728
2094
|
const JGF_HYPEREDGE_KEYS = /* @__PURE__ */ new Set([...JGF_EDGE_KEYS, "nodes"]);
|
|
2095
|
+
const ARRAY_INDEX = /^(?:0|[1-9]\d{0,9})$/;
|
|
729
2096
|
const JGF_NODE_KEYS = /* @__PURE__ */ new Set(["label", "metadata"]);
|
|
730
2097
|
const GRAPHOLOGY_NODE_KEYS = /* @__PURE__ */ new Set(["key", "attributes"]);
|
|
731
2098
|
const GRAPHOLOGY_EDGE_KEYS = /* @__PURE__ */ new Set(["key", "source", "target", "attributes", "undirected"]);
|
|
2099
|
+
const GEPHI_NODE_KEYS = /* @__PURE__ */ new Set(["id", "attributes"]);
|
|
2100
|
+
const GEPHI_EDGE_KEYS = /* @__PURE__ */ new Set([...GRAPHOLOGY_EDGE_KEYS, "id"]);
|
|
732
2101
|
const VIS_SOURCE_KEYS = Object.freeze(["from"]);
|
|
733
2102
|
const VIS_TARGET_KEYS = Object.freeze(["to"]);
|
|
734
2103
|
const PATH_DIALECTS = /* @__PURE__ */ new Set([
|
|
@@ -1050,11 +2419,13 @@ class ImportContext {
|
|
|
1050
2419
|
* @param explicitDefaultDirected - whether the caller passed defaultDirected
|
|
1051
2420
|
*/
|
|
1052
2421
|
constructor(sink, report, options, json2, explicitDefaultDirected) {
|
|
2422
|
+
this.text = "";
|
|
1053
2423
|
this.elementsSinceCheck = 0;
|
|
1054
2424
|
this.fileDirected = false;
|
|
1055
2425
|
this.danglingIds = [];
|
|
1056
2426
|
this.danglingCount = 0;
|
|
1057
2427
|
this.nodesFromEdges = false;
|
|
2428
|
+
this.styleSource = null;
|
|
1058
2429
|
this.nearMatches = [];
|
|
1059
2430
|
this.sink = sink;
|
|
1060
2431
|
this.report = report;
|
|
@@ -1213,10 +2584,34 @@ class ImportContext {
|
|
|
1213
2584
|
if (missingSource) {
|
|
1214
2585
|
this.dangling(source);
|
|
1215
2586
|
}
|
|
1216
|
-
if (missingTarget) {
|
|
1217
|
-
this.dangling(target);
|
|
2587
|
+
if (missingTarget) {
|
|
2588
|
+
this.dangling(target);
|
|
2589
|
+
}
|
|
2590
|
+
return edge;
|
|
2591
|
+
}
|
|
2592
|
+
/**
|
|
2593
|
+
* A Cytoscape.js endpoint or parent id: Cytoscape.js holds every id as text, so an endpoint `0` names the node
|
|
2594
|
+
* `"0"` and an endpoint `"0"` the node `0` when the file has no node of the endpoint's own type.
|
|
2595
|
+
* @param raw - the JSON value
|
|
2596
|
+
* @param element - the element name for issues
|
|
2597
|
+
* @returns the id, or null when the value was reported
|
|
2598
|
+
*/
|
|
2599
|
+
textualId(raw, element) {
|
|
2600
|
+
const id = this.coerceId(raw, element);
|
|
2601
|
+
if (id === null || this.sink.indexOf(id) !== INVALID_INDEX) {
|
|
2602
|
+
return id;
|
|
2603
|
+
}
|
|
2604
|
+
let other = null;
|
|
2605
|
+
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
2606
|
+
other = String(raw);
|
|
2607
|
+
} else if (typeof raw === "string" && /^-?\d+(?:\.\d+)?$/.test(raw)) {
|
|
2608
|
+
other = Number(raw);
|
|
1218
2609
|
}
|
|
1219
|
-
|
|
2610
|
+
if (other === null) {
|
|
2611
|
+
return id;
|
|
2612
|
+
}
|
|
2613
|
+
const alt = this.ids.value(other);
|
|
2614
|
+
return this.sink.indexOf(alt) === INVALID_INDEX ? id : alt;
|
|
1220
2615
|
}
|
|
1221
2616
|
/**
|
|
1222
2617
|
* Count a placeholder node an edge endpoint created.
|
|
@@ -1379,10 +2774,14 @@ class ImportContext {
|
|
|
1379
2774
|
* @param record - the element record
|
|
1380
2775
|
* @param dict - the nested attribute dict
|
|
1381
2776
|
* @param structural - the element keys that are not attributes
|
|
1382
|
-
* @param weightFrom - the weight key to skip in the dict, or null
|
|
1383
2777
|
* @param element - the element name for issues
|
|
2778
|
+
* @param how - `weightFrom`: the weight key to skip in the dict; `plain`: write the element-level keys under their
|
|
2779
|
+
* own names, not with the `#element` suffix
|
|
2780
|
+
* @param how.weightFrom - the weight key to skip in the dict, or null (the default)
|
|
2781
|
+
* @param how.plain - write the element-level keys under their own names (default false)
|
|
1384
2782
|
*/
|
|
1385
|
-
writeNested(writer, row, record, dict, structural,
|
|
2783
|
+
writeNested(writer, row, record, dict, structural, element, how = {}) {
|
|
2784
|
+
const { weightFrom = null, plain = false } = how;
|
|
1386
2785
|
for (const key of Object.keys(dict)) {
|
|
1387
2786
|
if (key !== weightFrom) {
|
|
1388
2787
|
writer.write(row, key, dict[key], SUFFIX.data, element);
|
|
@@ -1390,7 +2789,7 @@ class ImportContext {
|
|
|
1390
2789
|
}
|
|
1391
2790
|
for (const key of Object.keys(record)) {
|
|
1392
2791
|
if (!structural.has(key)) {
|
|
1393
|
-
writer.write(row, `${key}${SUFFIX.element}`, record[key], SUFFIX.data, element);
|
|
2792
|
+
writer.write(row, plain ? key : `${key}${SUFFIX.element}`, record[key], SUFFIX.data, element);
|
|
1394
2793
|
}
|
|
1395
2794
|
}
|
|
1396
2795
|
}
|
|
@@ -1728,8 +3127,14 @@ function reportUnreadKeys(ctx, record, known, prefix) {
|
|
|
1728
3127
|
);
|
|
1729
3128
|
}
|
|
1730
3129
|
}
|
|
1731
|
-
const VIS_DOCUMENT_KEYS = /* @__PURE__ */ new Set(["nodes", "edges"]);
|
|
1732
|
-
const GRAPHOLOGY_DOCUMENT_KEYS = /* @__PURE__ */ new Set([
|
|
3130
|
+
const VIS_DOCUMENT_KEYS = /* @__PURE__ */ new Set(["nodes", "edges", STYLE_BLOCK_NAME]);
|
|
3131
|
+
const GRAPHOLOGY_DOCUMENT_KEYS = /* @__PURE__ */ new Set([
|
|
3132
|
+
"nodes",
|
|
3133
|
+
"edges",
|
|
3134
|
+
"options",
|
|
3135
|
+
"attributes",
|
|
3136
|
+
STYLE_BLOCK_NAME
|
|
3137
|
+
]);
|
|
1733
3138
|
const JGF_GRAPH_KEYS = /* @__PURE__ */ new Set([
|
|
1734
3139
|
"id",
|
|
1735
3140
|
"type",
|
|
@@ -1748,10 +3153,46 @@ function isIndexBelow(value, bound) {
|
|
|
1748
3153
|
}
|
|
1749
3154
|
function importNodeLink(ctx, root, dialect) {
|
|
1750
3155
|
const { report, json: json2 } = ctx;
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
3156
|
+
const edgesKey = json2.edgesKey ?? (hasKey(root, "edges") || !hasKey(root, "links") ? "edges" : "links");
|
|
3157
|
+
const { nodeList, edgeList } = nodeLinkSections(ctx, root, edgesKey);
|
|
3158
|
+
const directed = flagOf(root.directed, "directed", ctx.defaultDirected(dialect), report);
|
|
3159
|
+
const multigraph = hasKey(root, "multigraph") ? flagOf(root.multigraph, "multigraph", false, report) : null;
|
|
3160
|
+
ctx.setHeader(directed);
|
|
3161
|
+
ctx.writeGraphDict(root.graph, "graph");
|
|
3162
|
+
reportUnreadKeys(ctx, root, /* @__PURE__ */ new Set(["nodes", edgesKey, "directed", "multigraph", "graph", STYLE_BLOCK_NAME]), "");
|
|
3163
|
+
const networkx = hasKey(root, "directed") && hasKey(root, "multigraph") && hasKey(root, "graph");
|
|
3164
|
+
ctx.styleSource = { dialect, block: blockOf(root), networkx };
|
|
3165
|
+
ctx.sink.reserve(nodeList.length, edgeList.length);
|
|
3166
|
+
const nodeIdKey = nodeLinkIdKey(ctx, nodeList);
|
|
3167
|
+
const positional = nodeIdKey === null;
|
|
3168
|
+
let indexLinks;
|
|
3169
|
+
if (positional) {
|
|
3170
|
+
indexLinks = true;
|
|
3171
|
+
} else if (json2.indexLinks === "auto") {
|
|
3172
|
+
indexLinks = looksIndexLinked(nodeList, edgeList, nodeIdKey, json2);
|
|
3173
|
+
} else {
|
|
3174
|
+
({ indexLinks } = json2);
|
|
1754
3175
|
}
|
|
3176
|
+
if (indexLinks && !positional && json2.indexLinks === "auto") {
|
|
3177
|
+
reportAmbiguousIndexLinks(ctx, nodeList, edgeList, nodeIdKey);
|
|
3178
|
+
}
|
|
3179
|
+
const positionIds = importNodeLinkNodes(ctx, nodeList, nodeIdKey, indexLinks);
|
|
3180
|
+
throwIfAborted(ctx.options.signal);
|
|
3181
|
+
const endpointKeys = importNodeLinkEdges(ctx, edgeList, edgesKey, positionIds, multigraph);
|
|
3182
|
+
ctx.setMeta(
|
|
3183
|
+
{
|
|
3184
|
+
dialect,
|
|
3185
|
+
edgesKey,
|
|
3186
|
+
nodeIdKey,
|
|
3187
|
+
indexLinks,
|
|
3188
|
+
sourceKey: endpointKeys.source ?? void 0,
|
|
3189
|
+
targetKey: endpointKeys.target ?? void 0
|
|
3190
|
+
},
|
|
3191
|
+
{ declaredMultigraph: multigraph, ...ctx.weightOriginPatch() }
|
|
3192
|
+
);
|
|
3193
|
+
}
|
|
3194
|
+
function nodeLinkSections(ctx, root, edgesKey) {
|
|
3195
|
+
const { report } = ctx;
|
|
1755
3196
|
const nodes = arraySection(root.nodes, "nodes", report);
|
|
1756
3197
|
const edges = arraySection(root[edgesKey], edgesKey, report);
|
|
1757
3198
|
if (nodes === null) {
|
|
@@ -1771,94 +3212,67 @@ function importNodeLink(ctx, root, dialect) {
|
|
|
1771
3212
|
{ element: edgesKey }
|
|
1772
3213
|
);
|
|
1773
3214
|
}
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
const edgeList = edges ?? [];
|
|
1781
|
-
ctx.sink.reserve(nodeList.length, edgeList.length);
|
|
1782
|
-
let { nodeIdKey } = json2;
|
|
1783
|
-
let positional = ctx.options.nodeIdFrom === "index";
|
|
1784
|
-
if (!positional && nodeIdKey === null) {
|
|
1785
|
-
const candidates = ctx.options.nodeIdFrom === "label" ? ["label", "name", "id"] : ["id", "name"];
|
|
1786
|
-
nodeIdKey = candidates.find((key) => anyHas(nodeList, key)) ?? null;
|
|
1787
|
-
if (ctx.options.nodeIdFrom === "label" && (nodeIdKey === "id" || nodeIdKey === "name")) {
|
|
1788
|
-
report.warning(
|
|
1789
|
-
"unsupported",
|
|
1790
|
-
JSON_ISSUE.OPTION_IGNORED,
|
|
1791
|
-
nodeIdKey === "id" ? 'nodeIdFrom "label": no node has a label or name key; ids are read from "id"' : 'nodeIdFrom "label": no node has a "label" key; ids are read from "name"',
|
|
1792
|
-
{ element: "nodeIdFrom" }
|
|
1793
|
-
);
|
|
1794
|
-
}
|
|
1795
|
-
if (nodeIdKey === null) {
|
|
1796
|
-
if (nodeList.length > 0) {
|
|
1797
|
-
positional = true;
|
|
1798
|
-
report.warning(
|
|
1799
|
-
"missing-value",
|
|
1800
|
-
JSON_ISSUE.POSITIONAL_NODES,
|
|
1801
|
-
"no node has an id or name key; array positions are the node ids",
|
|
1802
|
-
{ element: "nodes" }
|
|
1803
|
-
);
|
|
1804
|
-
} else {
|
|
1805
|
-
nodeIdKey = "id";
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
3215
|
+
return { nodeList: nodes ?? [], edgeList: edges ?? [] };
|
|
3216
|
+
}
|
|
3217
|
+
function nodeLinkIdKey(ctx, nodeList) {
|
|
3218
|
+
const { report, json: json2 } = ctx;
|
|
3219
|
+
if (ctx.options.nodeIdFrom === "index") {
|
|
3220
|
+
return null;
|
|
1808
3221
|
}
|
|
1809
|
-
if (
|
|
1810
|
-
nodeIdKey
|
|
3222
|
+
if (json2.nodeIdKey !== null) {
|
|
3223
|
+
return json2.nodeIdKey;
|
|
1811
3224
|
}
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
3225
|
+
const byLabel = ctx.options.nodeIdFrom === "label";
|
|
3226
|
+
const candidates = byLabel ? ["label", "name", "id"] : ["id", "name"];
|
|
3227
|
+
const found = candidates.find((key) => anyHas(nodeList, key)) ?? null;
|
|
3228
|
+
if (byLabel && (found === "id" || found === "name")) {
|
|
3229
|
+
report.warning(
|
|
3230
|
+
"unsupported",
|
|
3231
|
+
JSON_ISSUE.OPTION_IGNORED,
|
|
3232
|
+
found === "id" ? 'nodeIdFrom "label": no node has a label or name key; ids are read from "id"' : 'nodeIdFrom "label": no node has a "label" key; ids are read from "name"',
|
|
3233
|
+
{ element: "nodeIdFrom" }
|
|
3234
|
+
);
|
|
1819
3235
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
reportAmbiguousIndexLinks(ctx, nodeList, edgeList, nodeIdKey);
|
|
3236
|
+
if (found !== null || nodeList.length === 0) {
|
|
3237
|
+
return found ?? "id";
|
|
1823
3238
|
}
|
|
3239
|
+
report.warning(
|
|
3240
|
+
"missing-value",
|
|
3241
|
+
JSON_ISSUE.POSITIONAL_NODES,
|
|
3242
|
+
"no node has an id or name key; array positions are the node ids",
|
|
3243
|
+
{ element: "nodes" }
|
|
3244
|
+
);
|
|
3245
|
+
return null;
|
|
3246
|
+
}
|
|
3247
|
+
function importNodeLinkNodes(ctx, nodeList, nodeIdKey, indexLinks) {
|
|
3248
|
+
const positionIds = indexLinks ? [] : null;
|
|
1824
3249
|
for (let i = 0; i < nodeList.length; i++) {
|
|
1825
3250
|
const element = `nodes[${i}]`;
|
|
1826
3251
|
const record = nodeList[i];
|
|
1827
3252
|
let pushed = null;
|
|
1828
|
-
if (
|
|
1829
|
-
ctx
|
|
3253
|
+
if (isJsonObject(record)) {
|
|
3254
|
+
pushed = pushNodeLinkNode(ctx, record, i, nodeIdKey);
|
|
1830
3255
|
} else {
|
|
1831
|
-
|
|
1832
|
-
if (nodeIdKey === null) {
|
|
1833
|
-
id = i;
|
|
1834
|
-
} else {
|
|
1835
|
-
id = ctx.coerceId(hasKey(record, nodeIdKey) ? record[nodeIdKey] : void 0, element);
|
|
1836
|
-
}
|
|
1837
|
-
if (id === null) {
|
|
1838
|
-
ctx.countSkipped("node");
|
|
1839
|
-
} else {
|
|
1840
|
-
const index = ctx.pushNode(id, element);
|
|
1841
|
-
if (index >= 0) {
|
|
1842
|
-
pushed = id;
|
|
1843
|
-
writeFlat(ctx.nodes, index, record, id, (key) => key !== nodeIdKey);
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
3256
|
+
ctx.badElement("node", element);
|
|
1846
3257
|
}
|
|
1847
3258
|
positionIds?.push(pushed);
|
|
1848
3259
|
}
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
3260
|
+
return positionIds;
|
|
3261
|
+
}
|
|
3262
|
+
function pushNodeLinkNode(ctx, record, i, nodeIdKey) {
|
|
3263
|
+
const element = `nodes[${i}]`;
|
|
3264
|
+
const raw = nodeIdKey !== null && hasKey(record, nodeIdKey) ? record[nodeIdKey] : void 0;
|
|
3265
|
+
const id = nodeIdKey === null ? i : ctx.coerceId(raw, element);
|
|
3266
|
+
if (id === null) {
|
|
3267
|
+
ctx.countSkipped("node");
|
|
3268
|
+
return null;
|
|
3269
|
+
}
|
|
3270
|
+
const index = ctx.pushNode(id, element);
|
|
3271
|
+
if (index < 0) {
|
|
3272
|
+
return null;
|
|
3273
|
+
}
|
|
3274
|
+
writeFlat(ctx.nodes, index, record, id, (key) => key !== nodeIdKey);
|
|
3275
|
+
return id;
|
|
1862
3276
|
}
|
|
1863
3277
|
function importNodeLinkEdges(ctx, edgeList, edgesKey, positionIds, multigraph) {
|
|
1864
3278
|
const { json: json2 } = ctx;
|
|
@@ -2088,6 +3502,7 @@ function importVis(ctx, root) {
|
|
|
2088
3502
|
{ element: "arrows" }
|
|
2089
3503
|
);
|
|
2090
3504
|
}
|
|
3505
|
+
ctx.styleSource = { dialect: "vis", block: blockOf(root), options: root.options, groups: root.groups };
|
|
2091
3506
|
ctx.setMeta(
|
|
2092
3507
|
{ dialect: "vis", nodeIdKey, sourceKey: sourceKey ?? void 0, targetKey: targetKey ?? void 0 },
|
|
2093
3508
|
ctx.weightOriginPatch()
|
|
@@ -2353,28 +3768,19 @@ function importGraphology(ctx, root) {
|
|
|
2353
3768
|
});
|
|
2354
3769
|
}
|
|
2355
3770
|
const type = graphologyType(ctx, options);
|
|
2356
|
-
ctx.setHeader(
|
|
3771
|
+
ctx.setHeader(type === "mixed" ? mostlyDirected(ctx, edges) : type === "directed");
|
|
2357
3772
|
const multi = hasKey(options, "multi") ? flagOf(options.multi, "options.multi", false, report) : null;
|
|
2358
3773
|
const allowSelfLoops = hasKey(options, "allowSelfLoops") ? flagOf(options.allowSelfLoops, "options.allowSelfLoops", true, report) : void 0;
|
|
2359
3774
|
ctx.writeGraphDict(root.attributes, "attributes");
|
|
3775
|
+
const firstNode = nodes.find((n) => isJsonObject(n));
|
|
3776
|
+
const gephi = isJsonObject(firstNode) && !hasKey(firstNode, "key") && hasKey(firstNode, "id");
|
|
3777
|
+
ctx.styleSource = { dialect: "graphology", block: blockOf(root), gephi };
|
|
2360
3778
|
ctx.reportNodeIdFrom("graphology", "the node key");
|
|
2361
3779
|
ctx.sink.reserve(nodes.length, edges.length);
|
|
2362
|
-
|
|
2363
|
-
pushGraphologyNode(ctx, nodes[i], `nodes[${i}]`);
|
|
2364
|
-
}
|
|
3780
|
+
importGraphologyNodes(ctx, nodes, gephi);
|
|
2365
3781
|
throwIfAborted(ctx.options.signal);
|
|
2366
|
-
const
|
|
2367
|
-
|
|
2368
|
-
type,
|
|
2369
|
-
allowSelfLoops,
|
|
2370
|
-
// what the edges do against the declared options: graphology itself refuses such a document
|
|
2371
|
-
violations: { selfLoops: 0, parallels: 0, flags: 0 },
|
|
2372
|
-
pairs: multi === false ? /* @__PURE__ */ new Set() : null
|
|
2373
|
-
};
|
|
2374
|
-
for (let i = 0; i < edges.length; i++) {
|
|
2375
|
-
readGraphologyEdge(ctx, reading, edges[i], `edges[${i}]`);
|
|
2376
|
-
}
|
|
2377
|
-
reportGraphologyViolations(ctx, reading.violations, type);
|
|
3782
|
+
const violations = importGraphologyEdges(ctx, edges, { type, gephi, multi, allowSelfLoops });
|
|
3783
|
+
reportGraphologyViolations(ctx, violations, type);
|
|
2378
3784
|
ctx.setMeta({ dialect: "graphology", allowSelfLoops }, { declaredMultigraph: multi, ...ctx.weightOriginPatch() });
|
|
2379
3785
|
}
|
|
2380
3786
|
function graphologyType(ctx, options) {
|
|
@@ -2391,81 +3797,101 @@ function graphologyType(ctx, options) {
|
|
|
2391
3797
|
}
|
|
2392
3798
|
return "mixed";
|
|
2393
3799
|
}
|
|
2394
|
-
function
|
|
2395
|
-
if (type !== "mixed") {
|
|
2396
|
-
return type === "directed";
|
|
2397
|
-
}
|
|
3800
|
+
function mostlyDirected(ctx, edges) {
|
|
2398
3801
|
const objects = edges.filter((edge) => isJsonObject(edge));
|
|
2399
3802
|
const undirectedEdges = objects.filter((edge) => edge.undirected === true).length;
|
|
2400
3803
|
return objects.length === 0 ? ctx.defaultDirected("graphology") : undirectedEdges < objects.length;
|
|
2401
3804
|
}
|
|
2402
|
-
function
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
3805
|
+
function importGraphologyNodes(ctx, nodes, gephi) {
|
|
3806
|
+
const nodeKey = gephi ? "id" : "key";
|
|
3807
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
3808
|
+
const element = `nodes[${i}]`;
|
|
3809
|
+
const record = nodes[i];
|
|
3810
|
+
if (!isJsonObject(record)) {
|
|
3811
|
+
ctx.badElement("node", element);
|
|
3812
|
+
continue;
|
|
3813
|
+
}
|
|
3814
|
+
const id = ctx.coerceId(hasKey(record, nodeKey) ? record[nodeKey] : void 0, element);
|
|
3815
|
+
if (id === null) {
|
|
3816
|
+
ctx.countSkipped("node");
|
|
3817
|
+
continue;
|
|
3818
|
+
}
|
|
3819
|
+
pushNestedNode(ctx, id, record, "attributes", gephi ? GEPHI_NODE_KEYS : GRAPHOLOGY_NODE_KEYS, element, gephi);
|
|
2406
3820
|
}
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
3821
|
+
}
|
|
3822
|
+
function importGraphologyEdges(ctx, edges, declared) {
|
|
3823
|
+
const { gephi } = declared;
|
|
3824
|
+
const ids = ctx.declareEdgeIds(edges, (edge) => gephi && !hasKey(edge, "key") ? edge.id : edge.key, "key", true);
|
|
3825
|
+
const violations = { selfLoops: 0, parallels: 0, flags: 0 };
|
|
3826
|
+
const pairs = declared.multi === false ? /* @__PURE__ */ new Set() : null;
|
|
3827
|
+
for (let i = 0; i < edges.length; i++) {
|
|
3828
|
+
const element = `edges[${i}]`;
|
|
3829
|
+
const record = graphologyEdgeRecord(ctx, edges[i], element);
|
|
3830
|
+
if (record === null) {
|
|
3831
|
+
continue;
|
|
3832
|
+
}
|
|
3833
|
+
try {
|
|
3834
|
+
const pushed = pushGraphologyEdge(ctx, record, element, ids, declared, violations);
|
|
3835
|
+
if (pushed !== null && pairs !== null) {
|
|
3836
|
+
violations.parallels += pairs.has(pushed) ? 1 : 0;
|
|
3837
|
+
pairs.add(pushed);
|
|
3838
|
+
}
|
|
3839
|
+
} catch (err) {
|
|
3840
|
+
ctx.skip(err, "edge", element);
|
|
3841
|
+
}
|
|
2411
3842
|
}
|
|
2412
|
-
|
|
3843
|
+
return violations;
|
|
2413
3844
|
}
|
|
2414
|
-
function
|
|
3845
|
+
function graphologyEdgeRecord(ctx, record, element) {
|
|
2415
3846
|
if (!isJsonObject(record)) {
|
|
2416
3847
|
ctx.badElement("edge", element);
|
|
2417
|
-
return;
|
|
3848
|
+
return null;
|
|
2418
3849
|
}
|
|
2419
3850
|
if (!present(record, "source") || !present(record, "target")) {
|
|
2420
3851
|
ctx.missingEndpoint(element, present(record, "source") ? "target" : "source");
|
|
2421
|
-
return;
|
|
2422
|
-
}
|
|
2423
|
-
try {
|
|
2424
|
-
const u = ctx.coerceId(record.source, `${element}.source`);
|
|
2425
|
-
const v = ctx.coerceId(record.target, `${element}.target`);
|
|
2426
|
-
if (u === null || v === null) {
|
|
2427
|
-
ctx.countSkipped("edge");
|
|
2428
|
-
return;
|
|
2429
|
-
}
|
|
2430
|
-
const kind = graphologyEdgeKind(ctx, reading, record, element);
|
|
2431
|
-
const attributes = graphologyEdgeAttributes(ctx, record, element);
|
|
2432
|
-
const idValue = ctx.edgeIdValue(reading.ids, record.key);
|
|
2433
|
-
const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(attributes), element);
|
|
2434
|
-
ctx.setEdgeId(reading.ids, edge, idValue);
|
|
2435
|
-
ctx.writeNested(ctx.edges, edge, record, attributes, GRAPHOLOGY_EDGE_KEYS, ctx.options.weightFrom, element);
|
|
2436
|
-
if (reading.allowSelfLoops === false && u === v) {
|
|
2437
|
-
reading.violations.selfLoops++;
|
|
2438
|
-
}
|
|
2439
|
-
if (reading.pairs !== null) {
|
|
2440
|
-
const pair = `${kind} ${pairKey(u, v, kind === "directed")}`;
|
|
2441
|
-
reading.violations.parallels += reading.pairs.has(pair) ? 1 : 0;
|
|
2442
|
-
reading.pairs.add(pair);
|
|
2443
|
-
}
|
|
2444
|
-
} catch (err) {
|
|
2445
|
-
ctx.skip(err, "edge", element);
|
|
3852
|
+
return null;
|
|
2446
3853
|
}
|
|
3854
|
+
return record;
|
|
2447
3855
|
}
|
|
2448
|
-
function
|
|
2449
|
-
const {
|
|
2450
|
-
|
|
2451
|
-
|
|
3856
|
+
function pushGraphologyEdge(ctx, record, element, ids, declared, violations) {
|
|
3857
|
+
const { report } = ctx;
|
|
3858
|
+
const { type, gephi } = declared;
|
|
3859
|
+
const u = ctx.coerceId(record.source, `${element}.source`);
|
|
3860
|
+
const v = ctx.coerceId(record.target, `${element}.target`);
|
|
3861
|
+
if (u === null || v === null) {
|
|
3862
|
+
ctx.countSkipped("edge");
|
|
3863
|
+
return null;
|
|
2452
3864
|
}
|
|
2453
|
-
|
|
2454
|
-
|
|
3865
|
+
let kind;
|
|
3866
|
+
if (type === "mixed") {
|
|
3867
|
+
kind = flagOf(record.undirected, `${element}.undirected`, false, report) ? "undirected" : "directed";
|
|
3868
|
+
} else {
|
|
3869
|
+
kind = type;
|
|
3870
|
+
if (typeof record.undirected === "boolean" && record.undirected !== (type === "undirected")) {
|
|
3871
|
+
violations.flags++;
|
|
3872
|
+
}
|
|
2455
3873
|
}
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
const { attributes } = record;
|
|
2460
|
-
if (attributes !== void 0 && attributes !== null && !isJsonObject(attributes)) {
|
|
2461
|
-
ctx.report.error(
|
|
3874
|
+
const { attributes: rawAttributes } = record;
|
|
3875
|
+
if (rawAttributes !== void 0 && rawAttributes !== null && !isJsonObject(rawAttributes)) {
|
|
3876
|
+
report.error(
|
|
2462
3877
|
"validation-error",
|
|
2463
3878
|
JSON_ISSUE.BAD_VALUE,
|
|
2464
|
-
`${element}: attributes must be an object, found ${describe(
|
|
3879
|
+
`${element}: attributes must be an object, found ${describe(rawAttributes)}`,
|
|
2465
3880
|
{ element }
|
|
2466
3881
|
);
|
|
2467
3882
|
}
|
|
2468
|
-
|
|
3883
|
+
const attributes = isJsonObject(rawAttributes) ? rawAttributes : {};
|
|
3884
|
+
const idValue = ctx.edgeIdValue(ids, record.key);
|
|
3885
|
+
const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(attributes), element);
|
|
3886
|
+
ctx.setEdgeId(ids, edge, idValue);
|
|
3887
|
+
ctx.writeNested(ctx.edges, edge, record, attributes, gephi ? GEPHI_EDGE_KEYS : GRAPHOLOGY_EDGE_KEYS, element, {
|
|
3888
|
+
weightFrom: ctx.options.weightFrom,
|
|
3889
|
+
plain: gephi
|
|
3890
|
+
});
|
|
3891
|
+
if (declared.allowSelfLoops === false && u === v) {
|
|
3892
|
+
violations.selfLoops++;
|
|
3893
|
+
}
|
|
3894
|
+
return `${kind} ${pairKey(u, v, kind === "directed")}`;
|
|
2469
3895
|
}
|
|
2470
3896
|
function reportGraphologyViolations(ctx, violations, type) {
|
|
2471
3897
|
const notes = [];
|
|
@@ -2490,7 +3916,7 @@ function reportGraphologyViolations(ctx, violations, type) {
|
|
|
2490
3916
|
});
|
|
2491
3917
|
}
|
|
2492
3918
|
}
|
|
2493
|
-
function pushNestedNode(ctx, id, record, dictKey, structural, element) {
|
|
3919
|
+
function pushNestedNode(ctx, id, record, dictKey, structural, element, plain = false) {
|
|
2494
3920
|
const index = ctx.pushNode(id, element);
|
|
2495
3921
|
if (index < 0) {
|
|
2496
3922
|
return index;
|
|
@@ -2505,7 +3931,7 @@ function pushNestedNode(ctx, id, record, dictKey, structural, element) {
|
|
|
2505
3931
|
{ element }
|
|
2506
3932
|
);
|
|
2507
3933
|
}
|
|
2508
|
-
ctx.writeNested(ctx.nodes, index, record, isJsonObject(dict) ? dict : {}, structural,
|
|
3934
|
+
ctx.writeNested(ctx.nodes, index, record, isJsonObject(dict) ? dict : {}, structural, element, { plain });
|
|
2509
3935
|
} catch (err) {
|
|
2510
3936
|
ctx.report.recordError(err, { element: String(id) });
|
|
2511
3937
|
}
|
|
@@ -2523,7 +3949,7 @@ function importJgf(ctx, root) {
|
|
|
2523
3949
|
`graph.nodes must be an object keyed by id or an array, found ${describe(nodesRaw)}`
|
|
2524
3950
|
);
|
|
2525
3951
|
}
|
|
2526
|
-
const
|
|
3952
|
+
const nodeRecords2 = Array.isArray(nodesRaw) ? nodesRaw : Object.values(nodesRaw ?? {});
|
|
2527
3953
|
const directed = jgfDirected(ctx, graph, edges);
|
|
2528
3954
|
ctx.setHeader(directed);
|
|
2529
3955
|
ctx.writeGraphDict(graph.metadata, "graph.metadata");
|
|
@@ -2534,18 +3960,18 @@ function importJgf(ctx, root) {
|
|
|
2534
3960
|
};
|
|
2535
3961
|
const label = typeof graph.label === "string" ? graph.label : null;
|
|
2536
3962
|
ctx.reportNodeIdFrom("jgf", "the node keys");
|
|
2537
|
-
ctx.sink.reserve(
|
|
3963
|
+
ctx.sink.reserve(nodeRecords2.length, edges.length);
|
|
2538
3964
|
const labelColumn = ctx.nodes.declareIf(
|
|
2539
3965
|
{ name: "label", dtype: "string", role: "label", nullable: true },
|
|
2540
|
-
anyHas(
|
|
3966
|
+
anyHas(nodeRecords2, "label")
|
|
2541
3967
|
);
|
|
2542
3968
|
if (isJsonObject(nodesRaw)) {
|
|
2543
|
-
for (const key of
|
|
3969
|
+
for (const key of jgfNodeKeys(ctx, root, graph, nodesRaw)) {
|
|
2544
3970
|
pushJgfKeyedNode(ctx, key, nodesRaw[key], labelColumn);
|
|
2545
3971
|
}
|
|
2546
3972
|
} else {
|
|
2547
|
-
for (let i = 0; i <
|
|
2548
|
-
pushJgfListedNode(ctx,
|
|
3973
|
+
for (let i = 0; i < nodeRecords2.length; i++) {
|
|
3974
|
+
pushJgfListedNode(ctx, nodeRecords2[i], labelColumn, `nodes[${i}]`);
|
|
2549
3975
|
}
|
|
2550
3976
|
}
|
|
2551
3977
|
throwIfAborted(ctx.options.signal);
|
|
@@ -2630,7 +4056,7 @@ function jgfEdgeWriter(ctx, edges, hyperedges) {
|
|
|
2630
4056
|
element
|
|
2631
4057
|
});
|
|
2632
4058
|
}
|
|
2633
|
-
ctx.writeNested(ctx.edges, edge, record, dict, structural, ctx.options.weightFrom
|
|
4059
|
+
ctx.writeNested(ctx.edges, edge, record, dict, structural, element, { weightFrom: ctx.options.weightFrom });
|
|
2634
4060
|
};
|
|
2635
4061
|
}
|
|
2636
4062
|
function readJgfEdge(ctx, record, element, directed, writeJgfEdge) {
|
|
@@ -2655,6 +4081,14 @@ function readJgfEdge(ctx, record, element, directed, writeJgfEdge) {
|
|
|
2655
4081
|
ctx.skip(err, "edge", element);
|
|
2656
4082
|
}
|
|
2657
4083
|
}
|
|
4084
|
+
function jgfNodeKeys(ctx, root, graph, nodes) {
|
|
4085
|
+
const keys = Object.keys(nodes);
|
|
4086
|
+
if (!keys.some((k) => ARRAY_INDEX.test(k))) {
|
|
4087
|
+
return keys;
|
|
4088
|
+
}
|
|
4089
|
+
const path = isJsonObject(root.graph) ? ["graph", "nodes"] : ["graphs", root.graphs.indexOf(graph), "nodes"];
|
|
4090
|
+
return keysInTextOrder(ctx.text, path) ?? keys;
|
|
4091
|
+
}
|
|
2658
4092
|
function jgfGraphOf(ctx, root) {
|
|
2659
4093
|
const single = isJsonObject(root.graph);
|
|
2660
4094
|
reportUnreadKeys(ctx, root, /* @__PURE__ */ new Set([single ? "graph" : "graphs"]), "");
|
|
@@ -2761,7 +4195,7 @@ function pushJgfNode(ctx, id, record, labelColumn, element) {
|
|
|
2761
4195
|
element
|
|
2762
4196
|
});
|
|
2763
4197
|
}
|
|
2764
|
-
ctx.writeNested(ctx.nodes, index, record, isJsonObject(metadata) ? metadata : {}, JGF_NODE_KEYS,
|
|
4198
|
+
ctx.writeNested(ctx.nodes, index, record, isJsonObject(metadata) ? metadata : {}, JGF_NODE_KEYS, element);
|
|
2765
4199
|
} catch (err) {
|
|
2766
4200
|
ctx.report.recordError(err, { element: String(id) });
|
|
2767
4201
|
}
|
|
@@ -2910,44 +4344,35 @@ function distinctMembers(ctx, members, element) {
|
|
|
2910
4344
|
function importCytoscape(ctx, root) {
|
|
2911
4345
|
const { elements, extra } = cytoscapeRoot(ctx, root);
|
|
2912
4346
|
const { nodes, edges } = cytoscapeSections(ctx, elements);
|
|
4347
|
+
const generatedIds = cytoscapeGeneratedIds(nodes);
|
|
4348
|
+
ctx.styleSource = {
|
|
4349
|
+
dialect: "cytoscape",
|
|
4350
|
+
block: blockOf(root),
|
|
4351
|
+
elements: elements ?? [],
|
|
4352
|
+
style: isJsonObject(root) ? root.style : void 0,
|
|
4353
|
+
generatedBy: isJsonObject(root) && typeof root.generated_by === "string" ? root.generated_by : null,
|
|
4354
|
+
generatedIds
|
|
4355
|
+
};
|
|
2913
4356
|
ctx.setHeader(ctx.defaultDirected("cytoscape"));
|
|
2914
4357
|
ctx.reportNodeIdFrom("cytoscape", "data.id");
|
|
2915
4358
|
ctx.sink.reserve(nodes.length, edges.length);
|
|
2916
|
-
const
|
|
2917
|
-
const reading = {
|
|
2918
|
-
positionColumn: ctx.nodes.declareIf(
|
|
2919
|
-
{
|
|
2920
|
-
name: POSITION_COLUMN,
|
|
2921
|
-
dtype: "f64",
|
|
2922
|
-
components: 3,
|
|
2923
|
-
role: "position",
|
|
2924
|
-
mutable: true,
|
|
2925
|
-
nullable: true,
|
|
2926
|
-
// 3D layouts written by Cytoscape-compatible tools carry a z
|
|
2927
|
-
extra: { sourceDims: nodes.some(hasPositionZ) ? 3 : 2, units: "file" },
|
|
2928
|
-
origin: { format: "json", namespace: "cytoscape" }
|
|
2929
|
-
},
|
|
2930
|
-
anyHas(nodes, "position")
|
|
2931
|
-
),
|
|
2932
|
-
classesColumn: ctx.nodes.declareIf(
|
|
2933
|
-
{ name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
|
|
2934
|
-
anyHas(nodes, "classes")
|
|
2935
|
-
),
|
|
2936
|
-
parents: [],
|
|
2937
|
-
point: [0, 0, 0]
|
|
2938
|
-
};
|
|
2939
|
-
const parentColumn = ctx.nodes.declareIf(
|
|
2940
|
-
{ name: PARENT_COLUMN, dtype: "u32", role: "parent", refersTo: "node", nullable: true },
|
|
2941
|
-
dataHas(nodes, "parent")
|
|
2942
|
-
);
|
|
4359
|
+
const columns = cytoscapeNodeColumns(ctx, nodes);
|
|
2943
4360
|
const edgeClassesColumn = ctx.edges.declareIf(
|
|
2944
4361
|
{ name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
|
|
2945
4362
|
anyHas(edges, "classes")
|
|
2946
4363
|
);
|
|
4364
|
+
const parents = [];
|
|
2947
4365
|
for (let i = 0; i < nodes.length; i++) {
|
|
2948
|
-
|
|
4366
|
+
const element = `nodes[${i}]`;
|
|
4367
|
+
const record = nodes[i];
|
|
4368
|
+
if (isJsonObject(record) && isJsonObject(record.data)) {
|
|
4369
|
+
const raw = record.data.id === void 0 ? generatedIds.get(record) : record.data.id;
|
|
4370
|
+
importCytoscapeNode(ctx, record, record.data, raw, element, columns, parents);
|
|
4371
|
+
} else {
|
|
4372
|
+
ctx.badElement("node", element, "an element with a data object");
|
|
4373
|
+
}
|
|
2949
4374
|
}
|
|
2950
|
-
resolveCytoscapeParents(ctx,
|
|
4375
|
+
resolveCytoscapeParents(ctx, parents, columns.parent);
|
|
2951
4376
|
throwIfAborted(ctx.options.signal);
|
|
2952
4377
|
importCytoscapeEdges(ctx, edges, edgeClassesColumn);
|
|
2953
4378
|
ctx.setMeta({ dialect: "cytoscape", cytoscape: extra }, ctx.weightOriginPatch());
|
|
@@ -2962,23 +4387,46 @@ function cytoscapeRoot(ctx, root) {
|
|
|
2962
4387
|
`a Cytoscape document must be an object or an array, found ${describe(root)}`
|
|
2963
4388
|
);
|
|
2964
4389
|
}
|
|
2965
|
-
|
|
4390
|
+
const object = root;
|
|
4391
|
+
ctx.writeGraphDict(object.data, "data");
|
|
2966
4392
|
const rest = {};
|
|
2967
|
-
for (const key of Object.keys(
|
|
2968
|
-
if (key !== "elements" && key !== "data") {
|
|
2969
|
-
rest[key] =
|
|
4393
|
+
for (const key of Object.keys(object)) {
|
|
4394
|
+
if (key !== "elements" && key !== "data" && key !== STYLE_BLOCK_NAME) {
|
|
4395
|
+
rest[key] = object[key];
|
|
2970
4396
|
}
|
|
2971
4397
|
}
|
|
2972
|
-
return Object.keys(rest).length > 0 ? { elements:
|
|
4398
|
+
return Object.keys(rest).length > 0 ? { elements: object.elements, extra: rest } : { elements: object.elements };
|
|
4399
|
+
}
|
|
4400
|
+
function cytoscapeNodeColumns(ctx, nodes) {
|
|
4401
|
+
const dataHas = (items, key) => items.some((item) => isJsonObject(item) && isJsonObject(item.data) && item.data[key] !== void 0);
|
|
4402
|
+
return {
|
|
4403
|
+
position: ctx.nodes.declareIf(
|
|
4404
|
+
{
|
|
4405
|
+
name: POSITION_COLUMN,
|
|
4406
|
+
dtype: "f64",
|
|
4407
|
+
components: 3,
|
|
4408
|
+
role: "position",
|
|
4409
|
+
mutable: true,
|
|
4410
|
+
nullable: true,
|
|
4411
|
+
// 3D layouts written by Cytoscape-compatible tools carry a z
|
|
4412
|
+
extra: { sourceDims: nodes.some(hasPositionZ) ? 3 : 2, units: "file" },
|
|
4413
|
+
origin: { format: "json", namespace: "cytoscape" }
|
|
4414
|
+
},
|
|
4415
|
+
anyHas(nodes, "position")
|
|
4416
|
+
),
|
|
4417
|
+
classes: ctx.nodes.declareIf(
|
|
4418
|
+
{ name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
|
|
4419
|
+
anyHas(nodes, "classes")
|
|
4420
|
+
),
|
|
4421
|
+
parent: ctx.nodes.declareIf(
|
|
4422
|
+
{ name: PARENT_COLUMN, dtype: "u32", role: "parent", refersTo: "node", nullable: true },
|
|
4423
|
+
dataHas(nodes, "parent")
|
|
4424
|
+
)
|
|
4425
|
+
};
|
|
2973
4426
|
}
|
|
2974
|
-
function
|
|
4427
|
+
function importCytoscapeNode(ctx, record, data, raw, element, columns, parents) {
|
|
2975
4428
|
const { report } = ctx;
|
|
2976
|
-
|
|
2977
|
-
ctx.badElement("node", element, "an element with a data object");
|
|
2978
|
-
return;
|
|
2979
|
-
}
|
|
2980
|
-
const { data } = record;
|
|
2981
|
-
const id = ctx.coerceId(hasKey(data, "id") ? data.id : void 0, element);
|
|
4429
|
+
const id = ctx.coerceId(raw, element);
|
|
2982
4430
|
if (id === null) {
|
|
2983
4431
|
ctx.countSkipped("node");
|
|
2984
4432
|
return;
|
|
@@ -2996,44 +4444,30 @@ function readCytoscapeNode(ctx, reading, record, element) {
|
|
|
2996
4444
|
);
|
|
2997
4445
|
}
|
|
2998
4446
|
try {
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
4447
|
+
for (const key of Object.keys(data).filter((k) => k !== "id")) {
|
|
4448
|
+
if (key !== "parent") {
|
|
4449
|
+
ctx.nodes.write(index, key, data[key], SUFFIX.data, element);
|
|
4450
|
+
continue;
|
|
4451
|
+
}
|
|
4452
|
+
const parent = data.parent === null ? null : ctx.coerceId(data.parent, `${element}.data.parent`);
|
|
4453
|
+
if (parent !== null) {
|
|
4454
|
+
parents.push({ index, parent, element });
|
|
4455
|
+
}
|
|
4456
|
+
}
|
|
4457
|
+
writeCytoscapePosition$1(ctx, columns.position, index, record.position, element);
|
|
4458
|
+
writeClasses(ctx, ctx.nodes, columns.classes, index, record.classes, element);
|
|
3002
4459
|
writeElementKeys(ctx.nodes, index, record, element);
|
|
3003
4460
|
} catch (err) {
|
|
3004
4461
|
report.recordError(err, { element: String(id) });
|
|
3005
4462
|
}
|
|
3006
4463
|
}
|
|
3007
|
-
function
|
|
3008
|
-
for (const key of Object.keys(data)) {
|
|
3009
|
-
if (key === "id") {
|
|
3010
|
-
continue;
|
|
3011
|
-
}
|
|
3012
|
-
if (key !== "parent") {
|
|
3013
|
-
ctx.nodes.write(index, key, data[key], SUFFIX.data, element);
|
|
3014
|
-
continue;
|
|
3015
|
-
}
|
|
3016
|
-
const raw = data.parent;
|
|
3017
|
-
if (raw === void 0 || raw === null) {
|
|
3018
|
-
continue;
|
|
3019
|
-
}
|
|
3020
|
-
const parent = ctx.coerceId(raw, `${element}.data.parent`);
|
|
3021
|
-
if (parent !== null) {
|
|
3022
|
-
reading.parents.push({ index, parent, element });
|
|
3023
|
-
}
|
|
3024
|
-
}
|
|
3025
|
-
}
|
|
3026
|
-
function writeCytoscapePosition$1(ctx, reading, index, position, element) {
|
|
4464
|
+
function writeCytoscapePosition$1(ctx, column, index, position, element) {
|
|
3027
4465
|
if (position === void 0 || position === null) {
|
|
3028
4466
|
return;
|
|
3029
4467
|
}
|
|
3030
4468
|
const z = isJsonObject(position) ? position.z ?? 0 : 0;
|
|
3031
4469
|
if (isJsonObject(position) && isCoordinate(position.x) && isCoordinate(position.y) && isCoordinate(z)) {
|
|
3032
|
-
|
|
3033
|
-
point[0] = position.x;
|
|
3034
|
-
point[1] = flipY(position.y);
|
|
3035
|
-
point[2] = z;
|
|
3036
|
-
ctx.nodes.set(reading.positionColumn, index, point);
|
|
4470
|
+
ctx.nodes.set(column, index, [position.x, flipY(position.y), z]);
|
|
3037
4471
|
} else {
|
|
3038
4472
|
ctx.report.error(
|
|
3039
4473
|
"validation-error",
|
|
@@ -3047,7 +4481,11 @@ function resolveCytoscapeParents(ctx, parents, parentColumn) {
|
|
|
3047
4481
|
const { report } = ctx;
|
|
3048
4482
|
const linkOf = /* @__PURE__ */ new Map();
|
|
3049
4483
|
for (let order = 0; order < parents.length; order++) {
|
|
3050
|
-
const { index,
|
|
4484
|
+
const { index, element } = parents[order];
|
|
4485
|
+
let { parent } = parents[order];
|
|
4486
|
+
if (ctx.sink.indexOf(parent) === INVALID_INDEX) {
|
|
4487
|
+
parent = ctx.textualId(parent, element) ?? parent;
|
|
4488
|
+
}
|
|
3051
4489
|
const parentIndex = ctx.sink.indexOf(parent);
|
|
3052
4490
|
if (parentIndex === INVALID_INDEX) {
|
|
3053
4491
|
report.error(
|
|
@@ -3122,8 +4560,8 @@ function importCytoscapeEdges(ctx, edges, edgeClassesColumn) {
|
|
|
3122
4560
|
function importCytoscapeEdge(ctx, shared, record, data, element) {
|
|
3123
4561
|
const { ids, kind, edgeClassesColumn } = shared;
|
|
3124
4562
|
try {
|
|
3125
|
-
const u = ctx.
|
|
3126
|
-
const v = ctx.
|
|
4563
|
+
const u = ctx.textualId(data.source, `${element}.data.source`);
|
|
4564
|
+
const v = ctx.textualId(data.target, `${element}.data.target`);
|
|
3127
4565
|
if (u === null || v === null) {
|
|
3128
4566
|
ctx.countSkipped("edge");
|
|
3129
4567
|
return;
|
|
@@ -3175,6 +4613,36 @@ function cytoscapeSections(ctx, elements) {
|
|
|
3175
4613
|
}
|
|
3176
4614
|
return report.fail(JSON_ISSUE.SHAPE, `elements must be an object or an array, found ${describe(elements)}`);
|
|
3177
4615
|
}
|
|
4616
|
+
function cytoscapeGeneratedIds(nodes) {
|
|
4617
|
+
const out = /* @__PURE__ */ new Map();
|
|
4618
|
+
const missing = nodes.filter(
|
|
4619
|
+
(n) => isJsonObject(n) && isJsonObject(n.data) && n.data.id === void 0
|
|
4620
|
+
);
|
|
4621
|
+
if (missing.length === 0) {
|
|
4622
|
+
return out;
|
|
4623
|
+
}
|
|
4624
|
+
const taken = /* @__PURE__ */ new Set();
|
|
4625
|
+
for (const n of nodes) {
|
|
4626
|
+
const id = isJsonObject(n) && isJsonObject(n.data) ? n.data.id : void 0;
|
|
4627
|
+
if (typeof id === "string" || typeof id === "number") {
|
|
4628
|
+
taken.add(String(id));
|
|
4629
|
+
}
|
|
4630
|
+
}
|
|
4631
|
+
for (let k = 0; k < missing.length; k++) {
|
|
4632
|
+
let id = `n${String(k)}`;
|
|
4633
|
+
let j = 2;
|
|
4634
|
+
while (taken.has(id)) {
|
|
4635
|
+
id = `n${String(k)}_${String(j)}`;
|
|
4636
|
+
j++;
|
|
4637
|
+
}
|
|
4638
|
+
taken.add(id);
|
|
4639
|
+
out.set(missing[k], id);
|
|
4640
|
+
}
|
|
4641
|
+
return out;
|
|
4642
|
+
}
|
|
4643
|
+
function blockOf(root) {
|
|
4644
|
+
return isJsonObject(root) && typeof root[STYLE_BLOCK_NAME] === "string" ? root[STYLE_BLOCK_NAME] : null;
|
|
4645
|
+
}
|
|
3178
4646
|
function hasPositionZ(element) {
|
|
3179
4647
|
return isJsonObject(element) && isJsonObject(element.position) && typeof element.position.z === "number";
|
|
3180
4648
|
}
|
|
@@ -3235,6 +4703,7 @@ const jsonImporter = Object.freeze({
|
|
|
3235
4703
|
"typedefs"
|
|
3236
4704
|
]),
|
|
3237
4705
|
extensions: Object.freeze([".json"]),
|
|
4706
|
+
positions: jsonPositions,
|
|
3238
4707
|
mimeTypes: Object.freeze(["application/json"]),
|
|
3239
4708
|
/**
|
|
3240
4709
|
* Confidence that the head is a JSON graph document: 0 unless it starts with `{` or `[`, 0.5
|
|
@@ -3245,12 +4714,12 @@ const jsonImporter = Object.freeze({
|
|
|
3245
4714
|
*/
|
|
3246
4715
|
sniff(head) {
|
|
3247
4716
|
const text = new TextDecoder("utf-8").decode(headBytes(head).subarray(0, SNIFF_BYTES));
|
|
3248
|
-
const
|
|
3249
|
-
if (!
|
|
4717
|
+
const trimmed2 = (text.startsWith(BOM) ? text.slice(1) : text).trimStart();
|
|
4718
|
+
if (!trimmed2.startsWith("{") && !trimmed2.startsWith("[")) {
|
|
3250
4719
|
return 0;
|
|
3251
4720
|
}
|
|
3252
|
-
const score = SNIFF_KEYS.some((key) =>
|
|
3253
|
-
return
|
|
4721
|
+
const score = SNIFF_KEYS.some((key) => trimmed2.includes(key)) ? 0.9 : 0.5;
|
|
4722
|
+
return trimmed2.startsWith("[") && sniffJsonDialectHead(trimmed2) !== "cytoscape" ? Math.min(score, 0.3) : score;
|
|
3254
4723
|
},
|
|
3255
4724
|
/**
|
|
3256
4725
|
* Read a JSON graph document into the sink.
|
|
@@ -3265,7 +4734,7 @@ const jsonImporter = Object.freeze({
|
|
|
3265
4734
|
const report = new ImportReportBuilder("json", resolved.errorLimit);
|
|
3266
4735
|
const text = await readText(input, report, { ...resolved, bomlessUtf16: true });
|
|
3267
4736
|
const { root, dialect } = documentOf(parseDocument(text, report), json2, report);
|
|
3268
|
-
readGraph(root, dialect, sink, report, resolved, json2, options);
|
|
4737
|
+
readGraph({ root, dialect, text }, sink, report, resolved, json2, options);
|
|
3269
4738
|
return report.finish();
|
|
3270
4739
|
},
|
|
3271
4740
|
/**
|
|
@@ -3302,17 +4771,35 @@ const jsonImporter = Object.freeze({
|
|
|
3302
4771
|
const reports = [];
|
|
3303
4772
|
for (let i = 0; i < Math.max(graphs, 1); i++) {
|
|
3304
4773
|
const report = i === 0 ? first : new ImportReportBuilder("json", resolved.errorLimit);
|
|
3305
|
-
readGraph(
|
|
4774
|
+
readGraph(
|
|
4775
|
+
{ root, dialect, text },
|
|
4776
|
+
sinkFor(i),
|
|
4777
|
+
report,
|
|
4778
|
+
resolved,
|
|
4779
|
+
{ ...json2, graphIndex: i, all: true },
|
|
4780
|
+
options
|
|
4781
|
+
);
|
|
3306
4782
|
reports.push(report.finish());
|
|
3307
4783
|
}
|
|
3308
4784
|
return reports;
|
|
3309
|
-
}
|
|
4785
|
+
},
|
|
4786
|
+
/**
|
|
4787
|
+
* The document's styles, read by its dialect's reader (Cytoscape.js stylesheets, graphology and vis.js keys,
|
|
4788
|
+
* NetworkX's defaults); a `graphty.styles` block gives back the rules graphty wrote.
|
|
4789
|
+
* @param snapshot - the graph the import built
|
|
4790
|
+
* @param context - the work budget and what the import kept
|
|
4791
|
+
* @returns the styles, or null when the dialect has none
|
|
4792
|
+
*/
|
|
4793
|
+
styles: jsonStyles
|
|
3310
4794
|
});
|
|
3311
|
-
function readGraph(
|
|
4795
|
+
function readGraph(doc, sink, report, resolved, json2, options) {
|
|
4796
|
+
const { root, dialect, text } = doc;
|
|
3312
4797
|
const ctx = new ImportContext(sink, report, resolved, json2, options?.defaultDirected !== void 0);
|
|
4798
|
+
ctx.text = text;
|
|
3313
4799
|
reportSinkOptions(sink, options, report, dialect === "obographs");
|
|
3314
4800
|
reportUnusedOptions(options, report, USED_OPTIONS);
|
|
3315
4801
|
readDialect(ctx, root, dialect);
|
|
4802
|
+
report.keepForStyles(ctx.styleSource ?? { dialect, block: blockOf(root) });
|
|
3316
4803
|
ctx.reportDangling();
|
|
3317
4804
|
ctx.nodes.reportNullOnly();
|
|
3318
4805
|
ctx.edges.reportNullOnly();
|
|
@@ -4043,7 +5530,7 @@ function graphPropertyValues(snapshot) {
|
|
|
4043
5530
|
const values = [];
|
|
4044
5531
|
for (const column of snapshot.graph) {
|
|
4045
5532
|
const dtype = column.dtype === "list" ? column.child.dtype : column.dtype;
|
|
4046
|
-
for (const item of valuesOf(cellOf(column, 0))) {
|
|
5533
|
+
for (const item of valuesOf$1(cellOf(column, 0))) {
|
|
4047
5534
|
values.push({ pred: column.meta.name, val: typeof item === "string" ? item : textOf(item, dtype) });
|
|
4048
5535
|
}
|
|
4049
5536
|
}
|
|
@@ -4222,10 +5709,10 @@ ${settings.indent}` : "";
|
|
|
4222
5709
|
planIds() {
|
|
4223
5710
|
const { snapshot } = this;
|
|
4224
5711
|
const typeColumn = snapshot.nodes.get("type");
|
|
4225
|
-
let
|
|
5712
|
+
let numeric2 = 0;
|
|
4226
5713
|
for (let i = 0; i < snapshot.nodeCount; i++) {
|
|
4227
5714
|
const id = snapshot.ids.idOf(i);
|
|
4228
|
-
|
|
5715
|
+
numeric2 += typeof id === "number" ? 1 : 0;
|
|
4229
5716
|
const text = String(id);
|
|
4230
5717
|
let { iri, exact } = this.iriOf(text);
|
|
4231
5718
|
const typedef = typeColumn !== null && typeColumn.isSet(i) && typeColumn.value(i) === "Typedef";
|
|
@@ -4241,12 +5728,12 @@ ${settings.indent}` : "";
|
|
|
4241
5728
|
this.changedRows.add(i);
|
|
4242
5729
|
}
|
|
4243
5730
|
}
|
|
4244
|
-
if (
|
|
5731
|
+
if (numeric2 > 0) {
|
|
4245
5732
|
this.note(
|
|
4246
5733
|
LOSS.ID_TEXT_TYPE,
|
|
4247
|
-
`${
|
|
5734
|
+
`${numeric2} numeric node id${plural(numeric2)} ${agree(numeric2, "is", "are")} written as text and read back as strings`,
|
|
4248
5735
|
null,
|
|
4249
|
-
|
|
5736
|
+
numeric2
|
|
4250
5737
|
);
|
|
4251
5738
|
}
|
|
4252
5739
|
}
|
|
@@ -4594,7 +6081,7 @@ ${settings.indent}` : "";
|
|
|
4594
6081
|
for (const tag of PROPERTY_TAGS) {
|
|
4595
6082
|
const v = this.at(tag, i);
|
|
4596
6083
|
const pred = TAG_PREDICATES.get(tag) ?? tag;
|
|
4597
|
-
for (const item of valuesOf(v)) {
|
|
6084
|
+
for (const item of valuesOf$1(v)) {
|
|
4598
6085
|
const text = String(item);
|
|
4599
6086
|
values.push({ pred, val: tag === "replaced_by" || tag === "consider" ? this.iriOf(text).iri : text });
|
|
4600
6087
|
}
|
|
@@ -4873,7 +6360,12 @@ const JSON_LOSS = Object.freeze({
|
|
|
4873
6360
|
* OBO Graphs: an OBO attribute stored as text where graph-io uses a dictionary (or the other way round); it reads
|
|
4874
6361
|
* back with graph-io's usual type. The values are the same.
|
|
4875
6362
|
*/
|
|
4876
|
-
DTYPE_UNSUPPORTED: LOSS.DTYPE
|
|
6363
|
+
DTYPE_UNSUPPORTED: LOSS.DTYPE,
|
|
6364
|
+
/**
|
|
6365
|
+
* Saving with styles: a column named like one of the dialect's style keys (graphology's `color`, `size`, `label`,
|
|
6366
|
+
* vis.js's `color`, `shape`, `font`, ...) is written with what graphty draws, so the values it held differ.
|
|
6367
|
+
*/
|
|
6368
|
+
STYLE_KEY_REPLACED: STYLE_KEY_REPLACED_CODE
|
|
4877
6369
|
});
|
|
4878
6370
|
const SLOT_ROLES = Object.freeze({
|
|
4879
6371
|
"node-link": /* @__PURE__ */ new Set(),
|
|
@@ -5132,7 +6624,9 @@ function plan(snapshot, resolved) {
|
|
|
5132
6624
|
const caps = dialectCapabilities(dialect);
|
|
5133
6625
|
const notes = checkCapabilities(snapshot, caps, resolved.common, {
|
|
5134
6626
|
roles: SLOT_ROLES[dialect],
|
|
5135
|
-
positionDtype: "f64"
|
|
6627
|
+
positionDtype: "f64",
|
|
6628
|
+
// Deprecated (next major): role columns are written as plain attributes; styles go through the style writer.
|
|
6629
|
+
vizAsAttributes: true
|
|
5136
6630
|
}).filter((n) => n.code !== LOSS.POSITIONS && n.code !== LOSS.EDGE_IDS_DROPPED);
|
|
5137
6631
|
const note = (code, message, column = null, count = null) => {
|
|
5138
6632
|
notes.push(Object.freeze({ code, message, column, count }));
|
|
@@ -5202,7 +6696,7 @@ function reservedKeys(snapshot, resolved) {
|
|
|
5202
6696
|
break;
|
|
5203
6697
|
case "vis":
|
|
5204
6698
|
node.add(resolved.nodeIdKey ?? "id");
|
|
5205
|
-
edge.add(resolved.sourceKey).add(resolved.targetKey);
|
|
6699
|
+
edge.add(resolved.sourceKey).add(resolved.targetKey).add("source").add("target");
|
|
5206
6700
|
break;
|
|
5207
6701
|
case "cytoscape":
|
|
5208
6702
|
node.add("id").add("parent");
|
|
@@ -5443,7 +6937,7 @@ function countNonZeroZ(column) {
|
|
|
5443
6937
|
function jgfIdNotes(snapshot, note) {
|
|
5444
6938
|
const { ids } = snapshot;
|
|
5445
6939
|
const seen = /* @__PURE__ */ new Set();
|
|
5446
|
-
let
|
|
6940
|
+
let numeric2 = 0;
|
|
5447
6941
|
let collisions = 0;
|
|
5448
6942
|
let indexLike = 0;
|
|
5449
6943
|
let lastIndex = -1;
|
|
@@ -5453,7 +6947,7 @@ function jgfIdNotes(snapshot, note) {
|
|
|
5453
6947
|
const id = ids.idOf(i);
|
|
5454
6948
|
const text = String(id);
|
|
5455
6949
|
if (typeof id === "number") {
|
|
5456
|
-
|
|
6950
|
+
numeric2++;
|
|
5457
6951
|
}
|
|
5458
6952
|
if (seen.has(text)) {
|
|
5459
6953
|
collisions++;
|
|
@@ -5470,12 +6964,12 @@ function jgfIdNotes(snapshot, note) {
|
|
|
5470
6964
|
sawOther = true;
|
|
5471
6965
|
}
|
|
5472
6966
|
}
|
|
5473
|
-
if (
|
|
6967
|
+
if (numeric2 > 0) {
|
|
5474
6968
|
note(
|
|
5475
6969
|
JSON_LOSS.NUMERIC_IDS_STRINGIFIED,
|
|
5476
|
-
`${
|
|
6970
|
+
`${numeric2} numeric node id${plural(numeric2)} ${agree(numeric2, "becomes", "become")} JGF object keys (strings); pass ids: "canonical" on re-import`,
|
|
5477
6971
|
null,
|
|
5478
|
-
|
|
6972
|
+
numeric2
|
|
5479
6973
|
);
|
|
5480
6974
|
}
|
|
5481
6975
|
if (collisions > 0) {
|
|
@@ -5664,9 +7158,20 @@ function* writeNodeLink(snapshot, p) {
|
|
|
5664
7158
|
yield w.take();
|
|
5665
7159
|
}
|
|
5666
7160
|
w.close("]");
|
|
7161
|
+
writeTopLevelBlock(c, p);
|
|
5667
7162
|
w.close("}");
|
|
5668
7163
|
yield w.take();
|
|
5669
7164
|
}
|
|
7165
|
+
function writeTopLevelBlock(c, p) {
|
|
7166
|
+
const groups = p.resolved.styled?.groups ?? null;
|
|
7167
|
+
if (groups !== null) {
|
|
7168
|
+
c.w.member("groups", JSON.stringify(groups));
|
|
7169
|
+
}
|
|
7170
|
+
const block = p.resolved.styled?.topLevelBlock ?? null;
|
|
7171
|
+
if (block !== null) {
|
|
7172
|
+
c.w.member(STYLE_BLOCK_NAME, JSON.stringify(block));
|
|
7173
|
+
}
|
|
7174
|
+
}
|
|
5670
7175
|
function* writeVis(snapshot, p) {
|
|
5671
7176
|
const { resolved } = p;
|
|
5672
7177
|
const c = { w: new JsonWriter(resolved.indent), ids: snapshot.ids, nonfinite: { count: 0 } };
|
|
@@ -5709,6 +7214,7 @@ function* writeVis(snapshot, p) {
|
|
|
5709
7214
|
yield w.take();
|
|
5710
7215
|
}
|
|
5711
7216
|
w.close("]");
|
|
7217
|
+
writeTopLevelBlock(c, p);
|
|
5712
7218
|
w.close("}");
|
|
5713
7219
|
yield w.take();
|
|
5714
7220
|
}
|
|
@@ -5891,7 +7397,7 @@ function* writeCytoscape(snapshot, p) {
|
|
|
5891
7397
|
writeSlots(c, p.nodes, i, parentSlots);
|
|
5892
7398
|
writeSlots(c, p.nodes, i, ATTRIBUTE_SLOTS);
|
|
5893
7399
|
w.close("}");
|
|
5894
|
-
writeCytoscapePosition(c, p
|
|
7400
|
+
writeCytoscapePosition(c, p, i);
|
|
5895
7401
|
writeSlots(c, p.nodes, i, ELEMENT_SLOTS);
|
|
5896
7402
|
w.close("}");
|
|
5897
7403
|
yield w.take();
|
|
@@ -5928,13 +7434,14 @@ function* writeCytoscape(snapshot, p) {
|
|
|
5928
7434
|
w.key("data");
|
|
5929
7435
|
writeGraphObject(c, p);
|
|
5930
7436
|
}
|
|
5931
|
-
|
|
7437
|
+
writeCytoscapeTopLevel(c, p);
|
|
7438
|
+
writeTopLevelBlock(c, p);
|
|
5932
7439
|
w.close("}");
|
|
5933
7440
|
yield w.take();
|
|
5934
7441
|
}
|
|
5935
|
-
function writeCytoscapePosition(c,
|
|
7442
|
+
function writeCytoscapePosition(c, p, i) {
|
|
5936
7443
|
const { w } = c;
|
|
5937
|
-
for (const item of
|
|
7444
|
+
for (const item of p.nodes) {
|
|
5938
7445
|
if (item.slot === "cytoscapePosition" && item.column.isSet(i)) {
|
|
5939
7446
|
const value = item.column.value(i);
|
|
5940
7447
|
const f32 = item.column.dtype === "f32";
|
|
@@ -5946,15 +7453,18 @@ function writeCytoscapePosition(c, items, i) {
|
|
|
5946
7453
|
}
|
|
5947
7454
|
}
|
|
5948
7455
|
}
|
|
5949
|
-
function
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
7456
|
+
function writeCytoscapeTopLevel(c, p) {
|
|
7457
|
+
const { w } = c;
|
|
7458
|
+
const extra = p.resolved.shape.cytoscape ?? {};
|
|
7459
|
+
const stylesheet = p.resolved.styled?.stylesheet ?? null;
|
|
5953
7460
|
for (const key of Object.keys(extra)) {
|
|
5954
|
-
if (key !== "elements" && key !== "data") {
|
|
5955
|
-
|
|
7461
|
+
if (key !== "elements" && key !== "data" && !(key === "style" && stylesheet !== null)) {
|
|
7462
|
+
w.member(key, valueText(extra[key], false, c.nonfinite));
|
|
5956
7463
|
}
|
|
5957
7464
|
}
|
|
7465
|
+
if (stylesheet !== null) {
|
|
7466
|
+
w.member("style", valueText(stylesheet, false, c.nonfinite));
|
|
7467
|
+
}
|
|
5958
7468
|
}
|
|
5959
7469
|
function edgeIdGenerator(snapshot, p) {
|
|
5960
7470
|
const used = /* @__PURE__ */ new Set();
|
|
@@ -5979,7 +7489,13 @@ function edgeIdGenerator(snapshot, p) {
|
|
|
5979
7489
|
};
|
|
5980
7490
|
}
|
|
5981
7491
|
function parts(snapshot, resolved) {
|
|
5982
|
-
|
|
7492
|
+
const s = resolved.styled?.snapshot ?? snapshot;
|
|
7493
|
+
return resolved.dialect === "obographs" ? planObographs(s, resolved).write() : write(s, plan(s, resolved));
|
|
7494
|
+
}
|
|
7495
|
+
function resolveStyled(snapshot, options) {
|
|
7496
|
+
const resolved = resolve(snapshot, options);
|
|
7497
|
+
const styled = jsonStyledExport(snapshot, resolved.dialect, options?.styles);
|
|
7498
|
+
return styled === null ? resolved : { ...resolved, styled };
|
|
5983
7499
|
}
|
|
5984
7500
|
const jsonExporter = Object.freeze({
|
|
5985
7501
|
format: "json",
|
|
@@ -5995,6 +7511,7 @@ const jsonExporter = Object.freeze({
|
|
|
5995
7511
|
"weightKey"
|
|
5996
7512
|
]),
|
|
5997
7513
|
capabilities: dialectCapabilities("node-link"),
|
|
7514
|
+
styles: Object.freeze({ capabilities: JSON_STYLE_CAPABILITIES }),
|
|
5998
7515
|
/**
|
|
5999
7516
|
* Pre-flight: every loss of the selected dialect, without writing anything.
|
|
6000
7517
|
* @param snapshot - the snapshot
|
|
@@ -6002,9 +7519,10 @@ const jsonExporter = Object.freeze({
|
|
|
6002
7519
|
* @returns the notes, empty when the export is exact
|
|
6003
7520
|
*/
|
|
6004
7521
|
check(snapshot, options) {
|
|
6005
|
-
const resolved =
|
|
6006
|
-
const
|
|
6007
|
-
|
|
7522
|
+
const resolved = resolveStyled(snapshot, options);
|
|
7523
|
+
const s = resolved.styled?.snapshot ?? snapshot;
|
|
7524
|
+
const notes = resolved.dialect === "obographs" ? planObographs(s, resolved).notes : plan(s, resolved).notes;
|
|
7525
|
+
return Object.freeze([...notes, ...resolved.styled?.notes ?? []]);
|
|
6008
7526
|
},
|
|
6009
7527
|
/**
|
|
6010
7528
|
* Write the document as UTF-8 chunks.
|
|
@@ -6013,7 +7531,7 @@ const jsonExporter = Object.freeze({
|
|
|
6013
7531
|
* @returns the chunks
|
|
6014
7532
|
*/
|
|
6015
7533
|
export(snapshot, options) {
|
|
6016
|
-
return encodeChunks(parts(snapshot,
|
|
7534
|
+
return encodeChunks(parts(snapshot, resolveStyled(snapshot, options)));
|
|
6017
7535
|
},
|
|
6018
7536
|
/**
|
|
6019
7537
|
* Write the document as one string.
|
|
@@ -6022,7 +7540,7 @@ const jsonExporter = Object.freeze({
|
|
|
6022
7540
|
* @returns the document
|
|
6023
7541
|
*/
|
|
6024
7542
|
exportToString(snapshot, options) {
|
|
6025
|
-
return joinText(parts(snapshot,
|
|
7543
|
+
return joinText(parts(snapshot, resolveStyled(snapshot, options)));
|
|
6026
7544
|
}
|
|
6027
7545
|
});
|
|
6028
7546
|
function jsonCapabilities(dialect) {
|
|
@@ -6046,4 +7564,4 @@ export {
|
|
|
6046
7564
|
rankFormats as r,
|
|
6047
7565
|
sniffFormat as s
|
|
6048
7566
|
};
|
|
6049
|
-
//# sourceMappingURL=exporter-
|
|
7567
|
+
//# sourceMappingURL=exporter-C-9cgZKa.js.map
|