@graphty/graph-io 0.3.25 → 0.3.27
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/README.md +49 -414
- package/dist/chunks/children-CL3Cy0ez.js.map +1 -1
- package/dist/chunks/choose-DrXtu_96.js +56 -0
- package/dist/chunks/choose-DrXtu_96.js.map +1 -0
- package/dist/chunks/constants-ikG85dT8.js +231 -0
- package/dist/chunks/constants-ikG85dT8.js.map +1 -0
- package/dist/chunks/{escape-B-tkk_Cl.js → escape-D1HPTUrP.js} +390 -99
- package/dist/chunks/escape-D1HPTUrP.js.map +1 -0
- package/dist/chunks/export-CHd4tQE2.js +4333 -0
- package/dist/chunks/export-CHd4tQE2.js.map +1 -0
- package/dist/chunks/{importer-eUREhBGj.js → exporter-D23CKNqF.js} +4969 -3201
- package/dist/chunks/exporter-D23CKNqF.js.map +1 -0
- package/dist/chunks/{exporter-DIeGJXAZ.js → exporter-DfWTgrti.js} +23 -21
- package/dist/chunks/exporter-DfWTgrti.js.map +1 -0
- package/dist/chunks/exporter-DhtW6FxK.js +3465 -0
- package/dist/chunks/exporter-DhtW6FxK.js.map +1 -0
- package/dist/chunks/{exporter-BGrsWamJ.js → exporter-IHv4nkCm.js} +38 -229
- package/dist/chunks/exporter-IHv4nkCm.js.map +1 -0
- package/dist/chunks/{importer-BWY2FFc5.js → importer-B1wmPQjr.js} +255 -77
- package/dist/chunks/importer-B1wmPQjr.js.map +1 -0
- package/dist/chunks/{importer-D_e7e7LX.js → importer-B2W_58pz.js} +399 -146
- package/dist/chunks/importer-B2W_58pz.js.map +1 -0
- package/dist/chunks/importer-BSALvkui.js +2811 -0
- package/dist/chunks/importer-BSALvkui.js.map +1 -0
- package/dist/chunks/{importer-vi3bSdtw.js → importer-BVRE--Un.js} +510 -77
- package/dist/chunks/importer-BVRE--Un.js.map +1 -0
- package/dist/chunks/{importer-DET1tg6s.js → importer-CIAzt-wo.js} +1689 -312
- package/dist/chunks/importer-CIAzt-wo.js.map +1 -0
- package/dist/chunks/{importer-DIrbbnAf.js → importer-DpEW5zeG.js} +585 -226
- package/dist/chunks/importer-DpEW5zeG.js.map +1 -0
- package/dist/chunks/{importer-zGLo8Dg_.js → importer-z_FL4VMb.js} +488 -161
- package/dist/chunks/importer-z_FL4VMb.js.map +1 -0
- package/dist/chunks/json-elements-BAmNBZok.js +1225 -0
- package/dist/chunks/json-elements-BAmNBZok.js.map +1 -0
- package/dist/chunks/ontology-export-Bab4eUA8.js +357 -0
- package/dist/chunks/ontology-export-Bab4eUA8.js.map +1 -0
- package/dist/chunks/{records-dbRkxwaq.js → records-CdlvL4RO.js} +298 -114
- package/dist/chunks/records-CdlvL4RO.js.map +1 -0
- package/dist/chunks/{text-Dr0Ifpag.js → text-DzXjAiTl.js} +29 -11
- package/dist/chunks/text-DzXjAiTl.js.map +1 -0
- package/dist/chunks/{writer-C7flM-Ih.js → writer-DxjgHwSe.js} +19 -1
- package/dist/chunks/writer-DxjgHwSe.js.map +1 -0
- package/dist/csv.js +952 -262
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +6 -3
- package/dist/cx2.js +2 -2
- package/dist/cys.js +6 -3
- package/dist/dot.js +1 -1
- package/dist/gexf.js +554 -122
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +344 -87
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +1105 -213
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +3 -2
- package/dist/graphml.js.map +1 -1
- package/dist/json.js +3 -2
- package/dist/neo4j.js +565 -158
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +6 -3
- package/dist/pajek.js +1 -1
- package/dist/src/children.d.ts +18 -6
- package/dist/src/children.d.ts.map +1 -1
- package/dist/src/children.js +6 -3
- package/dist/src/children.js.map +1 -1
- package/dist/src/common/attributes.d.ts +29 -11
- package/dist/src/common/attributes.d.ts.map +1 -1
- package/dist/src/common/attributes.js +25 -7
- package/dist/src/common/attributes.js.map +1 -1
- package/dist/src/common/cell-budget.d.ts +9 -2
- package/dist/src/common/cell-budget.d.ts.map +1 -1
- package/dist/src/common/cell-budget.js +11 -3
- package/dist/src/common/cell-budget.js.map +1 -1
- package/dist/src/common/choose.d.ts +19 -0
- package/dist/src/common/choose.d.ts.map +1 -0
- package/dist/src/common/choose.js +72 -0
- package/dist/src/common/choose.js.map +1 -0
- package/dist/src/common/codes.d.ts +456 -66
- package/dist/src/common/codes.d.ts.map +1 -1
- package/dist/src/common/codes.js +458 -66
- package/dist/src/common/codes.js.map +1 -1
- package/dist/src/common/compare.d.ts +81 -0
- package/dist/src/common/compare.d.ts.map +1 -0
- package/dist/src/common/compare.js +394 -0
- package/dist/src/common/compare.js.map +1 -0
- package/dist/src/common/cx-export.d.ts +123 -0
- package/dist/src/common/cx-export.d.ts.map +1 -0
- package/dist/src/common/cx-export.js +334 -0
- package/dist/src/common/cx-export.js.map +1 -0
- package/dist/src/common/declared-types.d.ts +22 -2
- package/dist/src/common/declared-types.d.ts.map +1 -1
- package/dist/src/common/declared-types.js +21 -3
- package/dist/src/common/declared-types.js.map +1 -1
- package/dist/src/common/direction.d.ts +74 -50
- package/dist/src/common/direction.d.ts.map +1 -1
- package/dist/src/common/direction.js +47 -27
- package/dist/src/common/direction.js.map +1 -1
- package/dist/src/common/escape.d.ts +21 -9
- package/dist/src/common/escape.d.ts.map +1 -1
- package/dist/src/common/escape.js +39 -22
- package/dist/src/common/escape.js.map +1 -1
- package/dist/src/common/export.d.ts +144 -32
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +216 -42
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/format.d.ts +23 -1
- package/dist/src/common/format.d.ts.map +1 -1
- package/dist/src/common/format.js +26 -1
- package/dist/src/common/format.js.map +1 -1
- package/dist/src/common/ids.d.ts +9 -2
- package/dist/src/common/ids.d.ts.map +1 -1
- package/dist/src/common/ids.js +6 -2
- package/dist/src/common/ids.js.map +1 -1
- package/dist/src/common/input.d.ts +122 -28
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +890 -124
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/json-elements.d.ts +144 -20
- package/dist/src/common/json-elements.d.ts.map +1 -1
- package/dist/src/common/json-elements.js +869 -189
- package/dist/src/common/json-elements.js.map +1 -1
- package/dist/src/common/line-format.d.ts +90 -0
- package/dist/src/common/line-format.d.ts.map +1 -0
- package/dist/src/common/line-format.js +185 -0
- package/dist/src/common/line-format.js.map +1 -0
- package/dist/src/common/lists.d.ts +6 -1
- package/dist/src/common/lists.d.ts.map +1 -1
- package/dist/src/common/lists.js +3 -1
- package/dist/src/common/lists.js.map +1 -1
- package/dist/src/common/ontology-export.d.ts +167 -0
- package/dist/src/common/ontology-export.d.ts.map +1 -0
- package/dist/src/common/ontology-export.js +359 -0
- package/dist/src/common/ontology-export.js.map +1 -0
- package/dist/src/common/ontology.d.ts +25 -3
- package/dist/src/common/ontology.d.ts.map +1 -1
- package/dist/src/common/ontology.js +30 -9
- package/dist/src/common/ontology.js.map +1 -1
- package/dist/src/common/options.d.ts +62 -12
- package/dist/src/common/options.d.ts.map +1 -1
- package/dist/src/common/options.js +89 -11
- package/dist/src/common/options.js.map +1 -1
- package/dist/src/common/plural.d.ts +31 -0
- package/dist/src/common/plural.d.ts.map +1 -0
- package/dist/src/common/plural.js +46 -0
- package/dist/src/common/plural.js.map +1 -0
- package/dist/src/common/report.d.ts +72 -14
- package/dist/src/common/report.d.ts.map +1 -1
- package/dist/src/common/report.js +146 -22
- package/dist/src/common/report.js.map +1 -1
- package/dist/src/common/temporal.d.ts +22 -5
- package/dist/src/common/temporal.d.ts.map +1 -1
- package/dist/src/common/temporal.js +13 -2
- package/dist/src/common/temporal.js.map +1 -1
- package/dist/src/common/text.d.ts +39 -23
- package/dist/src/common/text.d.ts.map +1 -1
- package/dist/src/common/text.js +51 -21
- package/dist/src/common/text.js.map +1 -1
- package/dist/src/common/weights.d.ts +37 -4
- package/dist/src/common/weights.d.ts.map +1 -1
- package/dist/src/common/weights.js +61 -2
- package/dist/src/common/weights.js.map +1 -1
- package/dist/src/common/writer.d.ts +19 -3
- package/dist/src/common/writer.d.ts.map +1 -1
- package/dist/src/common/writer.js +30 -2
- package/dist/src/common/writer.js.map +1 -1
- package/dist/src/common/xml.d.ts +125 -9
- package/dist/src/common/xml.d.ts.map +1 -1
- package/dist/src/common/xml.js +402 -85
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/common/zip.d.ts +44 -4
- package/dist/src/common/zip.d.ts.map +1 -1
- package/dist/src/common/zip.js +134 -5
- package/dist/src/common/zip.js.map +1 -1
- package/dist/src/formats/csv/exporter.d.ts +80 -24
- package/dist/src/formats/csv/exporter.d.ts.map +1 -1
- package/dist/src/formats/csv/exporter.js +146 -33
- package/dist/src/formats/csv/exporter.js.map +1 -1
- package/dist/src/formats/csv/header.d.ts +38 -9
- package/dist/src/formats/csv/header.d.ts.map +1 -1
- package/dist/src/formats/csv/header.js +46 -10
- package/dist/src/formats/csv/header.js.map +1 -1
- package/dist/src/formats/csv/importer.d.ts +187 -37
- package/dist/src/formats/csv/importer.d.ts.map +1 -1
- package/dist/src/formats/csv/importer.js +835 -204
- package/dist/src/formats/csv/importer.js.map +1 -1
- package/dist/src/formats/csv/index.d.ts +100 -19
- package/dist/src/formats/csv/index.d.ts.map +1 -1
- package/dist/src/formats/csv/index.js +94 -21
- package/dist/src/formats/csv/index.js.map +1 -1
- package/dist/src/formats/csv/records.d.ts +95 -10
- package/dist/src/formats/csv/records.d.ts.map +1 -1
- package/dist/src/formats/csv/records.js +333 -122
- package/dist/src/formats/csv/records.js.map +1 -1
- package/dist/src/formats/csv/values.d.ts +1 -0
- package/dist/src/formats/csv/values.d.ts.map +1 -1
- package/dist/src/formats/csv/values.js +1 -0
- package/dist/src/formats/csv/values.js.map +1 -1
- package/dist/src/formats/cx/exporter.d.ts +102 -0
- package/dist/src/formats/cx/exporter.d.ts.map +1 -0
- package/dist/src/formats/cx/exporter.js +1217 -0
- package/dist/src/formats/cx/exporter.js.map +1 -0
- package/dist/src/formats/cx/importer.d.ts +79 -32
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +682 -287
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx/index.d.ts +4 -3
- package/dist/src/formats/cx/index.d.ts.map +1 -1
- package/dist/src/formats/cx/index.js +4 -3
- package/dist/src/formats/cx/index.js.map +1 -1
- package/dist/src/formats/cx2/exporter.d.ts +29 -11
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +39 -268
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts +78 -28
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +227 -80
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cx2/index.d.ts +2 -1
- package/dist/src/formats/cx2/index.d.ts.map +1 -1
- package/dist/src/formats/cx2/index.js +2 -1
- package/dist/src/formats/cx2/index.js.map +1 -1
- package/dist/src/formats/cys/constants.d.ts +66 -17
- package/dist/src/formats/cys/constants.d.ts.map +1 -1
- package/dist/src/formats/cys/constants.js +59 -18
- package/dist/src/formats/cys/constants.js.map +1 -1
- package/dist/src/formats/cys/exporter.d.ts +118 -0
- package/dist/src/formats/cys/exporter.d.ts.map +1 -0
- package/dist/src/formats/cys/exporter.js +1072 -0
- package/dist/src/formats/cys/exporter.js.map +1 -0
- package/dist/src/formats/cys/importer.d.ts +22 -8
- package/dist/src/formats/cys/importer.d.ts.map +1 -1
- package/dist/src/formats/cys/importer.js +510 -149
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/index.d.ts +4 -2
- package/dist/src/formats/cys/index.d.ts.map +1 -1
- package/dist/src/formats/cys/index.js +4 -2
- package/dist/src/formats/cys/index.js.map +1 -1
- package/dist/src/formats/cys/session.d.ts +46 -7
- package/dist/src/formats/cys/session.d.ts.map +1 -1
- package/dist/src/formats/cys/session.js +101 -27
- package/dist/src/formats/cys/session.js.map +1 -1
- package/dist/src/formats/cys/tables.d.ts +9 -2
- package/dist/src/formats/cys/tables.d.ts.map +1 -1
- package/dist/src/formats/cys/tables.js +29 -7
- package/dist/src/formats/cys/tables.js.map +1 -1
- package/dist/src/formats/dot/exporter.d.ts +42 -14
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +56 -29
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts +91 -29
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +190 -39
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/index.d.ts +2 -1
- package/dist/src/formats/dot/index.d.ts.map +1 -1
- package/dist/src/formats/dot/index.js +2 -1
- package/dist/src/formats/dot/index.js.map +1 -1
- package/dist/src/formats/dot/names.d.ts +44 -11
- package/dist/src/formats/dot/names.d.ts.map +1 -1
- package/dist/src/formats/dot/names.js +44 -11
- package/dist/src/formats/dot/names.js.map +1 -1
- package/dist/src/formats/dot/tokenizer.d.ts +9 -2
- package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
- package/dist/src/formats/dot/tokenizer.js +20 -5
- package/dist/src/formats/dot/tokenizer.js.map +1 -1
- package/dist/src/formats/gexf/exporter.d.ts +46 -15
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +45 -15
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +87 -23
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +471 -90
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/index.d.ts +84 -21
- package/dist/src/formats/gexf/index.d.ts.map +1 -1
- package/dist/src/formats/gexf/index.js +80 -23
- package/dist/src/formats/gexf/index.js.map +1 -1
- package/dist/src/formats/gexf/schema.d.ts +67 -15
- package/dist/src/formats/gexf/schema.d.ts.map +1 -1
- package/dist/src/formats/gexf/schema.js +59 -13
- package/dist/src/formats/gexf/schema.js.map +1 -1
- package/dist/src/formats/gml/exporter.d.ts +69 -21
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +74 -29
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts +116 -25
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +290 -61
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/index.d.ts +87 -24
- package/dist/src/formats/gml/index.d.ts.map +1 -1
- package/dist/src/formats/gml/index.js +79 -26
- package/dist/src/formats/gml/index.js.map +1 -1
- package/dist/src/formats/gml/syntax.d.ts +67 -18
- package/dist/src/formats/gml/syntax.d.ts.map +1 -1
- package/dist/src/formats/gml/syntax.js +110 -28
- package/dist/src/formats/gml/syntax.js.map +1 -1
- package/dist/src/formats/graphml/constants.d.ts +174 -44
- package/dist/src/formats/graphml/constants.d.ts.map +1 -1
- package/dist/src/formats/graphml/constants.js +165 -44
- package/dist/src/formats/graphml/constants.js.map +1 -1
- package/dist/src/formats/graphml/exporter.d.ts +17 -9
- package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
- package/dist/src/formats/graphml/exporter.js +33 -12
- package/dist/src/formats/graphml/exporter.js.map +1 -1
- package/dist/src/formats/graphml/importer.d.ts +19 -7
- package/dist/src/formats/graphml/importer.d.ts.map +1 -1
- package/dist/src/formats/graphml/importer.js +466 -39
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/graphml/index.d.ts +2 -1
- package/dist/src/formats/graphml/index.d.ts.map +1 -1
- package/dist/src/formats/graphml/index.js +2 -1
- package/dist/src/formats/graphml/index.js.map +1 -1
- package/dist/src/formats/graphml/tree.d.ts +6 -2
- package/dist/src/formats/graphml/tree.d.ts.map +1 -1
- package/dist/src/formats/graphml/tree.js +6 -2
- package/dist/src/formats/graphml/tree.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts +8 -3
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +36 -15
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/dialect.d.ts +88 -24
- package/dist/src/formats/json/dialect.d.ts.map +1 -1
- package/dist/src/formats/json/dialect.js +109 -19
- package/dist/src/formats/json/dialect.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts +134 -22
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +135 -54
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +173 -52
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +899 -220
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/index.d.ts +3 -2
- package/dist/src/formats/json/index.d.ts.map +1 -1
- package/dist/src/formats/json/index.js +3 -2
- package/dist/src/formats/json/index.js.map +1 -1
- package/dist/src/formats/json/obographs-export.d.ts +68 -0
- package/dist/src/formats/json/obographs-export.d.ts.map +1 -0
- package/dist/src/formats/json/obographs-export.js +941 -0
- package/dist/src/formats/json/obographs-export.js.map +1 -0
- package/dist/src/formats/json/obographs.d.ts +26 -0
- package/dist/src/formats/json/obographs.d.ts.map +1 -1
- package/dist/src/formats/json/obographs.js +297 -80
- package/dist/src/formats/json/obographs.js.map +1 -1
- package/dist/src/formats/neo4j/exporter.d.ts +109 -21
- package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
- package/dist/src/formats/neo4j/exporter.js +239 -86
- package/dist/src/formats/neo4j/exporter.js.map +1 -1
- package/dist/src/formats/neo4j/header.d.ts +17 -4
- package/dist/src/formats/neo4j/header.d.ts.map +1 -1
- package/dist/src/formats/neo4j/header.js +36 -4
- package/dist/src/formats/neo4j/header.js.map +1 -1
- package/dist/src/formats/neo4j/importer.d.ts +107 -27
- package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
- package/dist/src/formats/neo4j/importer.js +415 -63
- package/dist/src/formats/neo4j/importer.js.map +1 -1
- package/dist/src/formats/neo4j/index.d.ts +73 -23
- package/dist/src/formats/neo4j/index.d.ts.map +1 -1
- package/dist/src/formats/neo4j/index.js +65 -25
- package/dist/src/formats/neo4j/index.js.map +1 -1
- package/dist/src/formats/obo/exporter.d.ts +150 -0
- package/dist/src/formats/obo/exporter.d.ts.map +1 -0
- package/dist/src/formats/obo/exporter.js +1736 -0
- package/dist/src/formats/obo/exporter.js.map +1 -0
- package/dist/src/formats/obo/importer.d.ts +95 -19
- package/dist/src/formats/obo/importer.d.ts.map +1 -1
- package/dist/src/formats/obo/importer.js +475 -104
- package/dist/src/formats/obo/importer.js.map +1 -1
- package/dist/src/formats/obo/index.d.ts +6 -3
- package/dist/src/formats/obo/index.d.ts.map +1 -1
- package/dist/src/formats/obo/index.js +6 -3
- package/dist/src/formats/obo/index.js.map +1 -1
- package/dist/src/formats/obo/syntax.d.ts +108 -4
- package/dist/src/formats/obo/syntax.d.ts.map +1 -1
- package/dist/src/formats/obo/syntax.js +211 -34
- package/dist/src/formats/obo/syntax.js.map +1 -1
- package/dist/src/formats/pajek/exporter.d.ts +54 -16
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +67 -35
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts +84 -22
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +303 -83
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/index.d.ts +2 -1
- package/dist/src/formats/pajek/index.d.ts.map +1 -1
- package/dist/src/formats/pajek/index.js +2 -1
- package/dist/src/formats/pajek/index.js.map +1 -1
- package/dist/src/formats/pajek/syntax.d.ts +77 -14
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +186 -54
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/columns.d.ts +1 -0
- package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
- package/dist/src/formats/xgmml/columns.js +4 -0
- package/dist/src/formats/xgmml/columns.js.map +1 -1
- package/dist/src/formats/xgmml/constants.d.ts +186 -56
- package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
- package/dist/src/formats/xgmml/constants.js +181 -57
- package/dist/src/formats/xgmml/constants.js.map +1 -1
- package/dist/src/formats/xgmml/document.d.ts +65 -11
- package/dist/src/formats/xgmml/document.d.ts.map +1 -1
- package/dist/src/formats/xgmml/document.js +157 -28
- package/dist/src/formats/xgmml/document.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts +61 -3
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +129 -26
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/exporter.d.ts +13 -6
- package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
- package/dist/src/formats/xgmml/exporter.js +21 -22
- package/dist/src/formats/xgmml/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/importer.d.ts +33 -12
- package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
- package/dist/src/formats/xgmml/importer.js +35 -72
- package/dist/src/formats/xgmml/importer.js.map +1 -1
- package/dist/src/formats/xgmml/index.d.ts +1 -0
- package/dist/src/formats/xgmml/index.d.ts.map +1 -1
- package/dist/src/formats/xgmml/index.js +1 -0
- package/dist/src/formats/xgmml/index.js.map +1 -1
- package/dist/src/formats/xgmml/values.d.ts +8 -1
- package/dist/src/formats/xgmml/values.d.ts.map +1 -1
- package/dist/src/formats/xgmml/values.js +8 -3
- package/dist/src/formats/xgmml/values.js.map +1 -1
- package/dist/src/index.d.ts +23 -18
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +28 -16
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts +478 -92
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +807 -88
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sniff.d.ts +61 -19
- package/dist/src/sniff.d.ts.map +1 -1
- package/dist/src/sniff.js +121 -29
- package/dist/src/sniff.js.map +1 -1
- package/dist/src/types.d.ts +362 -112
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +28 -7
- package/dist/src/types.js.map +1 -1
- package/dist/xgmml.js +2 -2
- package/docs/samples/README.md +25 -0
- package/docs/samples/got-edges.csv +353 -0
- package/docs/samples/got-network.graphml +1384 -0
- package/docs/samples/got-nodes.csv +108 -0
- package/docs/samples/got.cx +930 -0
- package/docs/samples/got.cx2 +465 -0
- package/docs/samples/got.gexf +471 -0
- package/docs/samples/got.gml +2650 -0
- package/docs/samples/got.json +2546 -0
- package/docs/samples/got.net +461 -0
- package/docs/samples/movies-nodes.csv +9 -0
- package/docs/samples/movies-rels.csv +8 -0
- package/docs/samples/networks.cys +0 -0
- package/docs/samples/proteins.xgmml +9 -0
- package/docs/samples/teams.gv +24 -0
- package/docs/samples/vehicles.obo +25 -0
- package/package.json +9 -4
- package/src/children.ts +18 -6
- package/src/common/attributes.ts +29 -11
- package/src/common/cell-budget.ts +11 -3
- package/src/common/choose.ts +89 -0
- package/src/common/codes.ts +490 -66
- package/src/common/compare.ts +472 -0
- package/src/common/cx-export.ts +432 -0
- package/src/common/declared-types.ts +40 -6
- package/src/common/direction.ts +78 -51
- package/src/common/escape.ts +39 -22
- package/src/common/export.ts +284 -47
- package/src/common/format.ts +30 -1
- package/src/common/ids.ts +14 -3
- package/src/common/input.ts +1057 -134
- package/src/common/json-elements.ts +1035 -199
- package/src/common/line-format.ts +249 -0
- package/src/common/lists.ts +7 -2
- package/src/common/ontology-export.ts +461 -0
- package/src/common/ontology.ts +31 -9
- package/src/common/options.ts +110 -15
- package/src/common/plural.ts +49 -0
- package/src/common/report.ts +168 -25
- package/src/common/temporal.ts +22 -5
- package/src/common/text.ts +62 -23
- package/src/common/weights.ts +74 -4
- package/src/common/writer.ts +37 -3
- package/src/common/xml.ts +479 -90
- package/src/common/zip.ts +169 -7
- package/src/formats/csv/exporter.ts +202 -47
- package/src/formats/csv/header.ts +50 -11
- package/src/formats/csv/importer.ts +1133 -245
- package/src/formats/csv/index.ts +106 -19
- package/src/formats/csv/records.ts +396 -122
- package/src/formats/csv/values.ts +1 -0
- package/src/formats/cx/exporter.ts +1483 -0
- package/src/formats/cx/importer.ts +890 -302
- package/src/formats/cx/index.ts +4 -3
- package/src/formats/cx2/exporter.ts +62 -339
- package/src/formats/cx2/importer.ts +318 -87
- package/src/formats/cx2/index.ts +2 -1
- package/src/formats/cys/constants.ts +62 -17
- package/src/formats/cys/exporter.ts +1368 -0
- package/src/formats/cys/importer.ts +659 -157
- package/src/formats/cys/index.ts +4 -2
- package/src/formats/cys/session.ts +142 -34
- package/src/formats/cys/tables.ts +47 -9
- package/src/formats/dot/exporter.ts +83 -37
- package/src/formats/dot/importer.ts +248 -54
- package/src/formats/dot/index.ts +2 -1
- package/src/formats/dot/names.ts +44 -11
- package/src/formats/dot/tokenizer.ts +25 -6
- package/src/formats/gexf/exporter.ts +57 -18
- package/src/formats/gexf/importer.ts +636 -105
- package/src/formats/gexf/index.ts +90 -21
- package/src/formats/gexf/schema.ts +67 -15
- package/src/formats/gml/exporter.ts +90 -36
- package/src/formats/gml/importer.ts +388 -67
- package/src/formats/gml/index.ts +85 -24
- package/src/formats/gml/syntax.ts +113 -28
- package/src/formats/graphml/constants.ts +178 -44
- package/src/formats/graphml/exporter.ts +52 -18
- package/src/formats/graphml/importer.ts +640 -60
- package/src/formats/graphml/index.ts +2 -1
- package/src/formats/graphml/tree.ts +6 -2
- package/src/formats/graphml/yfiles.ts +37 -15
- package/src/formats/json/dialect.ts +128 -29
- package/src/formats/json/exporter.ts +205 -68
- package/src/formats/json/importer.ts +1163 -253
- package/src/formats/json/index.ts +3 -1
- package/src/formats/json/obographs-export.ts +1197 -0
- package/src/formats/json/obographs.ts +353 -92
- package/src/formats/neo4j/exporter.ts +321 -102
- package/src/formats/neo4j/header.ts +44 -6
- package/src/formats/neo4j/importer.ts +512 -73
- package/src/formats/neo4j/index.ts +75 -23
- package/src/formats/obo/exporter.ts +2210 -0
- package/src/formats/obo/importer.ts +622 -109
- package/src/formats/obo/index.ts +6 -3
- package/src/formats/obo/syntax.ts +232 -37
- package/src/formats/pajek/exporter.ts +90 -42
- package/src/formats/pajek/importer.ts +407 -93
- package/src/formats/pajek/index.ts +2 -1
- package/src/formats/pajek/syntax.ts +216 -55
- package/src/formats/xgmml/columns.ts +10 -0
- package/src/formats/xgmml/constants.ts +183 -56
- package/src/formats/xgmml/document.ts +212 -34
- package/src/formats/xgmml/emit.ts +175 -34
- package/src/formats/xgmml/exporter.ts +36 -28
- package/src/formats/xgmml/importer.ts +64 -86
- package/src/formats/xgmml/index.ts +1 -0
- package/src/formats/xgmml/values.ts +12 -4
- package/src/index.ts +81 -11
- package/src/registry.ts +1121 -135
- package/src/sniff.ts +163 -32
- package/src/types.ts +385 -114
- package/dist/chunks/escape-B-tkk_Cl.js.map +0 -1
- package/dist/chunks/export-Bh60Dv-n.js +0 -582
- package/dist/chunks/export-Bh60Dv-n.js.map +0 -1
- package/dist/chunks/exporter-BGrsWamJ.js.map +0 -1
- package/dist/chunks/exporter-DIeGJXAZ.js.map +0 -1
- package/dist/chunks/importer-BWY2FFc5.js.map +0 -1
- package/dist/chunks/importer-DD-xv9_Y.js +0 -1471
- package/dist/chunks/importer-DD-xv9_Y.js.map +0 -1
- package/dist/chunks/importer-DET1tg6s.js.map +0 -1
- package/dist/chunks/importer-DEcKhsmQ.js +0 -1614
- package/dist/chunks/importer-DEcKhsmQ.js.map +0 -1
- package/dist/chunks/importer-DIrbbnAf.js.map +0 -1
- package/dist/chunks/importer-D_e7e7LX.js.map +0 -1
- package/dist/chunks/importer-eUREhBGj.js.map +0 -1
- package/dist/chunks/importer-vi3bSdtw.js.map +0 -1
- package/dist/chunks/importer-zGLo8Dg_.js.map +0 -1
- package/dist/chunks/json-elements-DDS8N2Dd.js +0 -779
- package/dist/chunks/json-elements-DDS8N2Dd.js.map +0 -1
- package/dist/chunks/ontology-BnrJ4I98.js +0 -113
- package/dist/chunks/ontology-BnrJ4I98.js.map +0 -1
- package/dist/chunks/records-dbRkxwaq.js.map +0 -1
- package/dist/chunks/report-B1z4WT9e.js +0 -2372
- package/dist/chunks/report-B1z4WT9e.js.map +0 -1
- package/dist/chunks/text-Dr0Ifpag.js.map +0 -1
- package/dist/chunks/weights-Dzba96G3.js +0 -176
- package/dist/chunks/weights-Dzba96G3.js.map +0 -1
- package/dist/chunks/writer-C7flM-Ih.js.map +0 -1
|
@@ -20,47 +20,66 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { GraphFormatError, INVALID_INDEX, } from "@graphty/graph-format";
|
|
22
22
|
import { declareResolved, uniqueColumnName } from "../../common/attributes.js";
|
|
23
|
-
import { ASPECT_ORDER_CODE, BAD_ASPECT_BLOCK_CODE, BAD_DEFAULT_CODE, BAD_VALUE_CODE, COLUMN_RENAMED_CODE, COUNT_MISMATCH_CODE, DANGLING_REFERENCE_CODE, DIRECTION_FORCED_CODE, DIRECTION_REFUSED_CODE, DUPLICATE_ATTRIBUTE_CODE, DUPLICATE_EDGE_ID_CODE, DUPLICATE_NODE_CODE, EMPTY_INPUT_CODE, ENCODING_FALLBACK_CODE, ID_MERGED_CODE, ID_TEXT_TYPE_CODE, INVALID_ENCODING_CODE, INVALID_UTF8_CODE, MISSING_ENDPOINT_CODE, MISSING_ID_CODE, OPTION_IGNORED_CODE, PRECISION_CODE, ROLE_TAKEN_CODE, SINK_OPTION_CODE, STATUS_FAILED_CODE, STATUS_WARNING_CODE, STYLES_NOT_IMPORTED_CODE, SYNTAX_CODE, TOO_LARGE_CODE, UNKNOWN_ATTR_TYPE_CODE, UNKNOWN_ELEMENT_CODE, UNKNOWN_ENCODING_CODE, } from "../../common/codes.js";
|
|
23
|
+
import { ASPECT_ORDER_CODE, BAD_ASPECT_BLOCK_CODE, BAD_DEFAULT_CODE, BAD_VALUE_CODE, COLUMN_RENAMED_CODE, COUNT_MISMATCH_CODE, DANGLING_REFERENCE_CODE, DIRECTION_FORCED_CODE, DIRECTION_REFUSED_CODE, DUPLICATE_ATTRIBUTE_CODE, DUPLICATE_EDGE_ID_CODE, DUPLICATE_NODE_CODE, ELEMENT_ISSUE, EMPTY_INPUT_CODE, ENCODING_FALLBACK_CODE, ID_MERGED_CODE, ID_TEXT_TYPE_CODE, INPUT_ISSUE, INVALID_ENCODING_CODE, INVALID_UTF8_CODE, JSON_NONSTANDARD_NUMBER_CODE, MISSING_ENDPOINT_CODE, MISSING_ID_CODE, MULTI_ASPECT_FRAGMENT_CODE, OPTION_IGNORED_CODE, PRECISION_CODE, ROLE_TAKEN_CODE, SINGLE_OBJECT_ASPECT_CODE, SINK_OPTION_CODE, STATUS_FAILED_CODE, STATUS_WARNING_CODE, STYLES_NOT_IMPORTED_CODE, SYNTAX_CODE, TOO_LARGE_CODE, UNKNOWN_ATTR_TYPE_CODE, UNKNOWN_ELEMENT_CODE, UNKNOWN_ENCODING_CODE, } from "../../common/codes.js";
|
|
24
24
|
import { DirectionResolver } from "../../common/direction.js";
|
|
25
25
|
import { IdCoercer } from "../../common/ids.js";
|
|
26
26
|
import { textChunks, throwIfAborted } from "../../common/input.js";
|
|
27
|
-
import { cxId, CxStructure, declareFresh, ExactInteger, flipY, inexactLiteral, isRecord, JsonScanError, plainJson, positionDecl, reportTooDeep, scanAspects, zDecl, } from "../../common/json-elements.js";
|
|
27
|
+
import { cxId, CxStructure, declareFresh, ExactInteger, fitsF32, flipY, headText, inexactLiteral, isRecord, JsonScanError, keptPrecision, plainJson, positionDecl, reportSharedBlock, reportTooDeep, scanAspects, setOwn, zDecl, } from "../../common/json-elements.js";
|
|
28
28
|
import { reportSinkOptions, reportUnusedOptions, resolveImportOptions, } from "../../common/options.js";
|
|
29
|
+
import { agree, plural } from "../../common/plural.js";
|
|
29
30
|
import { ImportReportBuilder } from "../../common/report.js";
|
|
30
31
|
import { weightFromValue } from "../../common/weights.js";
|
|
31
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* The format name.
|
|
34
|
+
* @category Plugin helpers
|
|
35
|
+
*/
|
|
32
36
|
export const CX2_FORMAT = "cx2";
|
|
33
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* The node attribute the exporter's `sanitizeIds: "mangle"` keeps an original id in.
|
|
39
|
+
* @category Plugin helpers
|
|
40
|
+
*/
|
|
34
41
|
export const ORIGINAL_ID_ATTRIBUTE = "graphty:originalId";
|
|
35
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* The origin namespace of the per-element visual property columns.
|
|
44
|
+
* @category Plugin helpers
|
|
45
|
+
*/
|
|
36
46
|
export const BYPASS_NAMESPACE = "cx2.bypass";
|
|
37
47
|
/**
|
|
38
|
-
* The issue codes the CX2 importer records
|
|
39
|
-
* the other importers
|
|
48
|
+
* The issue codes the CX2 importer records, by name: the codes shared with
|
|
49
|
+
* the other importers and the CX2-specific ones. A key is the code without
|
|
40
50
|
* its severity and format prefixes.
|
|
51
|
+
* @category Built-in formats
|
|
41
52
|
*/
|
|
42
53
|
export const CX2_ISSUE = Object.freeze({
|
|
43
|
-
|
|
54
|
+
...INPUT_ISSUE,
|
|
55
|
+
...ELEMENT_ISSUE,
|
|
56
|
+
/** The input is empty. The import stops. */
|
|
44
57
|
EMPTY_INPUT: EMPTY_INPUT_CODE,
|
|
45
|
-
/** The text is not JSON
|
|
58
|
+
/** The text is not valid JSON. The import stops. */
|
|
46
59
|
SYNTAX: SYNTAX_CODE,
|
|
47
|
-
/**
|
|
60
|
+
/** The input is not valid UTF-8. The import stops. */
|
|
48
61
|
INVALID_UTF8: INVALID_UTF8_CODE,
|
|
49
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Some bytes are not valid in the encoding that was chosen (by a byte order mark or the `encoding` option). The
|
|
64
|
+
* import stops.
|
|
65
|
+
*/
|
|
50
66
|
INVALID_ENCODING: INVALID_ENCODING_CODE,
|
|
51
67
|
/** Bytes that are not UTF-8 were read as windows-1252. */
|
|
52
68
|
ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,
|
|
53
69
|
/** An encoding the platform cannot decode was ignored. */
|
|
54
70
|
UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,
|
|
55
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* The document is not a JSON array, or its first element is not the CX2 descriptor with `CXVersion`. The import
|
|
73
|
+
* stops.
|
|
74
|
+
*/
|
|
56
75
|
NO_DESCRIPTOR: "E_CX2_NO_DESCRIPTOR",
|
|
57
|
-
/** CXVersion names a
|
|
76
|
+
/** `CXVersion` names a version other than 2 ("1.x" means the file is CX1; read it as `cx`). The import stops. */
|
|
58
77
|
VERSION: "E_CX2_VERSION",
|
|
59
78
|
/** CXVersion is a 2.x other than "2.0" (or not a string); the document is read. */
|
|
60
79
|
MINOR_VERSION: "W_CX2_MINOR_VERSION",
|
|
61
80
|
/** The document has no status block, or a malformed one. */
|
|
62
81
|
NO_STATUS: "E_CX2_NO_STATUS",
|
|
63
|
-
/** The
|
|
82
|
+
/** The program that wrote the file marked it as failed, so it is incomplete. The import stops. */
|
|
64
83
|
STATUS_FAILED: STATUS_FAILED_CODE,
|
|
65
84
|
/** The producer marked the document as successful with an error text. */
|
|
66
85
|
STATUS_WARNING: STATUS_WARNING_CODE,
|
|
@@ -84,9 +103,18 @@ export const CX2_ISSUE = Object.freeze({
|
|
|
84
103
|
ALIAS_BYPASSED: "W_CX2_ALIAS_BYPASSED",
|
|
85
104
|
/** A CX1 cartesianLayout aspect next to node coordinates; kept, not applied. */
|
|
86
105
|
LEGACY_LAYOUT: "W_CX2_LEGACY_LAYOUT",
|
|
87
|
-
/**
|
|
106
|
+
/** An aspect CX2 defines as an array of elements written as one object; read as one element. */
|
|
107
|
+
SINGLE_OBJECT_ASPECT: SINGLE_OBJECT_ASPECT_CODE,
|
|
108
|
+
/** A member holding several aspects; each array-valued key is read as its own block. */
|
|
109
|
+
MULTI_ASPECT_FRAGMENT: MULTI_ASPECT_FRAGMENT_CODE,
|
|
110
|
+
/** The bare tokens NaN / Infinity / -Infinity (Python's json writes them), read as numbers. */
|
|
111
|
+
JSON_NONSTANDARD_NUMBER: JSON_NONSTANDARD_NUMBER_CODE,
|
|
112
|
+
/** The file's style rules are not applied; they are kept so a CX2 export writes them back. */
|
|
88
113
|
STYLES_NOT_IMPORTED: STYLES_NOT_IMPORTED_CODE,
|
|
89
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* A member of the file's top-level array that is not a block with one key (`{"nodes": [...]}`), or an element of a
|
|
116
|
+
* block that is not an object. It is skipped; the rest of the file is read.
|
|
117
|
+
*/
|
|
90
118
|
BAD_ASPECT_BLOCK: BAD_ASPECT_BLOCK_CODE,
|
|
91
119
|
/** An aspect out of its place (after the post-metadata or the status, a third metaData, late declarations). */
|
|
92
120
|
ASPECT_ORDER: ASPECT_ORDER_CODE,
|
|
@@ -118,25 +146,37 @@ export const CX2_ISSUE = Object.freeze({
|
|
|
118
146
|
INVALID_WEIGHT: "E_INVALID_WEIGHT",
|
|
119
147
|
/** An id spelled as a string or a non-integer literal; read as the integer. */
|
|
120
148
|
ID_TEXT_TYPE: ID_TEXT_TYPE_CODE,
|
|
121
|
-
/** An integer beyond 2^53
|
|
149
|
+
/** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: "string"` to keep every digit. */
|
|
122
150
|
PRECISION: PRECISION_CODE,
|
|
123
151
|
/** Two id texts merged under `ids: "number"`. */
|
|
124
152
|
ID_MERGED: ID_MERGED_CODE,
|
|
125
153
|
/** An element key CX2 does not define. */
|
|
126
154
|
UNKNOWN_ELEMENT: UNKNOWN_ELEMENT_CODE,
|
|
127
|
-
/**
|
|
155
|
+
/**
|
|
156
|
+
* An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example
|
|
157
|
+
* two attributes declared with the same name.
|
|
158
|
+
*/
|
|
128
159
|
COLUMN_RENAMED: COLUMN_RENAMED_CODE,
|
|
129
|
-
/**
|
|
160
|
+
/**
|
|
161
|
+
* You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as
|
|
162
|
+
* a plain attribute.
|
|
163
|
+
*/
|
|
130
164
|
ROLE_TAKEN: ROLE_TAKEN_CODE,
|
|
131
|
-
/**
|
|
165
|
+
/**
|
|
166
|
+
* You read into a graph builder whose direction is already set, or which already holds edges, so the file is read
|
|
167
|
+
* with the builder's direction instead of its own.
|
|
168
|
+
*/
|
|
132
169
|
DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,
|
|
133
|
-
/** Edges
|
|
170
|
+
/** Edges of the other direction were read with the direction `onMixedDirection` chose. */
|
|
134
171
|
DIRECTION_FORCED: DIRECTION_FORCED_CODE,
|
|
135
|
-
/**
|
|
172
|
+
/** You set an option this format does not use; it had no effect. The message names the option. */
|
|
136
173
|
OPTION_IGNORED: OPTION_IGNORED_CODE,
|
|
137
|
-
/**
|
|
174
|
+
/**
|
|
175
|
+
* You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,
|
|
176
|
+
* `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.
|
|
177
|
+
*/
|
|
138
178
|
SINK_OPTION: SINK_OPTION_CODE,
|
|
139
|
-
/** The input is
|
|
179
|
+
/** The input is larger than graph-io's size limit. The import stops. */
|
|
140
180
|
TOO_LARGE: TOO_LARGE_CODE,
|
|
141
181
|
});
|
|
142
182
|
const USED_OPTIONS = new Set([
|
|
@@ -177,26 +217,38 @@ const STYLE_ASPECTS = [
|
|
|
177
217
|
];
|
|
178
218
|
/** The aspects the stream structure owns; never kept as opaque. */
|
|
179
219
|
const STRUCTURE_ASPECTS = new Set(["metaData", "status"]);
|
|
220
|
+
/** The aspects CX2 defines as an array of elements, which a reader expects in that form. */
|
|
221
|
+
const ARRAY_ASPECTS = new Set([
|
|
222
|
+
"nodes",
|
|
223
|
+
"edges",
|
|
224
|
+
"attributeDeclarations",
|
|
225
|
+
"networkAttributes",
|
|
226
|
+
"nodeBypasses",
|
|
227
|
+
"edgeBypasses",
|
|
228
|
+
"status",
|
|
229
|
+
"metaData",
|
|
230
|
+
]);
|
|
180
231
|
/** The type spellings CX2 defines, plus the Python spellings ndex2 writes. */
|
|
181
|
-
const SCALARS =
|
|
182
|
-
string
|
|
183
|
-
long
|
|
184
|
-
integer
|
|
185
|
-
double
|
|
186
|
-
boolean
|
|
187
|
-
str
|
|
188
|
-
int
|
|
189
|
-
bool
|
|
190
|
-
float
|
|
191
|
-
|
|
232
|
+
const SCALARS = new Map([
|
|
233
|
+
["string", "string"],
|
|
234
|
+
["long", "long"],
|
|
235
|
+
["integer", "integer"],
|
|
236
|
+
["double", "double"],
|
|
237
|
+
["boolean", "boolean"],
|
|
238
|
+
["str", "string"],
|
|
239
|
+
["int", "integer"],
|
|
240
|
+
["bool", "boolean"],
|
|
241
|
+
["float", "double"],
|
|
242
|
+
]);
|
|
192
243
|
/**
|
|
193
244
|
* Resolve a declared type text.
|
|
194
245
|
* @param d - the `d` value
|
|
195
246
|
* @returns the type, or null when CX2 does not define it
|
|
247
|
+
* @category Plugin helpers
|
|
196
248
|
*/
|
|
197
249
|
export function cx2Type(d) {
|
|
198
250
|
const list = d.startsWith("list_of_");
|
|
199
|
-
const scalar = SCALARS
|
|
251
|
+
const scalar = SCALARS.get(list ? d.slice("list_of_".length) : d);
|
|
200
252
|
if (scalar === undefined) {
|
|
201
253
|
return null;
|
|
202
254
|
}
|
|
@@ -246,6 +298,7 @@ function convertScalar(value, scalar, long, onPrecision) {
|
|
|
246
298
|
return typeof value === "boolean" ? value : BAD;
|
|
247
299
|
case "double":
|
|
248
300
|
if (value instanceof ExactInteger) {
|
|
301
|
+
onPrecision(value.digits);
|
|
249
302
|
return Number(value.digits);
|
|
250
303
|
}
|
|
251
304
|
return typeof value === "number" ? value : BAD;
|
|
@@ -316,15 +369,16 @@ function shown(value) {
|
|
|
316
369
|
* The inexact-literal bits of an element.
|
|
317
370
|
* @param text - the element's JSON text
|
|
318
371
|
* @param keys - the id keys to check, bit 1, 2, 4 in order
|
|
372
|
+
* @param depth - the depth of the element's own keys in the text (2: a member's single object)
|
|
319
373
|
* @returns the bits
|
|
320
374
|
*/
|
|
321
|
-
function inexactBits(text, keys) {
|
|
375
|
+
function inexactBits(text, keys, depth = 1) {
|
|
322
376
|
if (!/[0-9][.eE]/.test(text)) {
|
|
323
377
|
return 0;
|
|
324
378
|
}
|
|
325
379
|
let bits = 0;
|
|
326
380
|
keys.forEach((key, i) => {
|
|
327
|
-
if (inexactLiteral(text, key)) {
|
|
381
|
+
if (inexactLiteral(text, key, depth)) {
|
|
328
382
|
bits |= 1 << i;
|
|
329
383
|
}
|
|
330
384
|
});
|
|
@@ -355,22 +409,24 @@ async function readDocument(input, report, options) {
|
|
|
355
409
|
let descriptor = false;
|
|
356
410
|
let elementsSeen = false;
|
|
357
411
|
let sinceCheck = 0;
|
|
358
|
-
const
|
|
412
|
+
const opaquePrecision = keptPrecision(report, "meta.extra.cx2.opaque");
|
|
413
|
+
const collect = (aspect, value, text, line, exact, depth = 1) => {
|
|
359
414
|
structure.element(aspect, value, line);
|
|
360
415
|
switch (aspect) {
|
|
361
416
|
case "nodes":
|
|
362
417
|
elementsSeen = true;
|
|
363
|
-
doc.nodes.push({ value, line, inexact: inexactBits(text, ["id"]) });
|
|
418
|
+
doc.nodes.push({ value, line, inexact: inexactBits(text, ["id"], depth) });
|
|
364
419
|
return;
|
|
365
420
|
case "edges":
|
|
366
421
|
elementsSeen = true;
|
|
367
|
-
doc.edges.push({ value, line, inexact: inexactBits(text, ["id", "s", "t"]) });
|
|
422
|
+
doc.edges.push({ value, line, inexact: inexactBits(text, ["id", "s", "t"], depth) });
|
|
368
423
|
return;
|
|
369
424
|
case "attributeDeclarations":
|
|
370
425
|
if (elementsSeen) {
|
|
371
426
|
report.warnOnce("validation-error", ASPECT_ORDER_CODE, "attributeDeclarations comes after the elements it types; the declarations are applied to them", { line, element: aspect }, `${ASPECT_ORDER_CODE}:declarations`);
|
|
372
427
|
}
|
|
373
|
-
|
|
428
|
+
// not plainJson(): a long default beyond 2^53 keeps its digits for long: "string"
|
|
429
|
+
doc.declarations.push({ value, line, inexact: 0 });
|
|
374
430
|
return;
|
|
375
431
|
case "networkAttributes":
|
|
376
432
|
elementsSeen = true;
|
|
@@ -392,18 +448,18 @@ async function readDocument(input, report, options) {
|
|
|
392
448
|
if (!doc.opaque.has(aspect)) {
|
|
393
449
|
doc.opaque.set(aspect, []);
|
|
394
450
|
}
|
|
395
|
-
doc.opaque.get(aspect)?.push(exact ? plainJson(value,
|
|
451
|
+
doc.opaque.get(aspect)?.push(exact ? plainJson(value, opaquePrecision) : value);
|
|
396
452
|
}
|
|
397
453
|
};
|
|
398
454
|
try {
|
|
399
|
-
for await (const event of scanAspects(textChunks(input, report, options))) {
|
|
455
|
+
for await (const event of scanAspects(textChunks(input, report, options), report)) {
|
|
400
456
|
if (++sinceCheck >= ABORT_CHECK_INTERVAL) {
|
|
401
457
|
sinceCheck = 0;
|
|
402
458
|
throwIfAborted(options.signal);
|
|
403
459
|
}
|
|
404
460
|
switch (event.kind) {
|
|
405
461
|
case "root":
|
|
406
|
-
report.fail(CX2_ISSUE.NO_DESCRIPTOR, `a CX2 document is a JSON array; found ${
|
|
462
|
+
report.fail(CX2_ISSUE.NO_DESCRIPTOR, `a CX2 document is a JSON array; found ${event.object ? "an object" : shown(event.value)}`, { line: event.line });
|
|
407
463
|
break;
|
|
408
464
|
case "member":
|
|
409
465
|
if (!descriptor) {
|
|
@@ -412,10 +468,11 @@ async function readDocument(input, report, options) {
|
|
|
412
468
|
break;
|
|
413
469
|
}
|
|
414
470
|
memberAspect(event.value, event.line, structure, report, (aspect, value) => {
|
|
415
|
-
collect(aspect, value,
|
|
471
|
+
collect(aspect, value, event.text, event.line, event.exact, 2);
|
|
416
472
|
});
|
|
417
473
|
break;
|
|
418
474
|
case "block":
|
|
475
|
+
reportSharedBlock(report, event);
|
|
419
476
|
if (!descriptor) {
|
|
420
477
|
report.fail(CX2_ISSUE.NO_DESCRIPTOR, `the document starts with a "${event.aspect}" block, not a descriptor with CXVersion${event.aspect === "numberVerification" || event.aspect === "metaData" ? "; this looks like CX version 1 (read it with the cx importer)" : ""}`, { line: event.line });
|
|
421
478
|
}
|
|
@@ -431,7 +488,7 @@ async function readDocument(input, report, options) {
|
|
|
431
488
|
}
|
|
432
489
|
break;
|
|
433
490
|
case "extraKeys":
|
|
434
|
-
report.error("parse-error", BAD_ASPECT_BLOCK_CODE, `the "${event.aspect}" block holds more keys (${event.keys.join(", ")}); an aspect block has one key, the others are skipped`, { line: event.line, element: event.aspect });
|
|
491
|
+
report.error("parse-error", BAD_ASPECT_BLOCK_CODE, `the "${event.aspect}" block holds more keys (${event.keys.join(", ")}) whose values are not arrays; an aspect block has one key, the others are skipped`, { line: event.line, element: event.aspect });
|
|
435
492
|
break;
|
|
436
493
|
default:
|
|
437
494
|
break;
|
|
@@ -463,8 +520,9 @@ function readDescriptor(value, line, doc, report) {
|
|
|
463
520
|
}
|
|
464
521
|
const raw = value.CXVersion;
|
|
465
522
|
const text = typeof raw === "string" || typeof raw === "number" ? String(raw) : "";
|
|
466
|
-
|
|
467
|
-
const
|
|
523
|
+
// the major version: "2.0", "2.1", "2.0.1", "2.1-beta", " 2.0" are all CX2
|
|
524
|
+
const match = /^\s*(\d+)(?=$|[.\s-])/.exec(text);
|
|
525
|
+
const major = match === null ? Number.NaN : Number(match[1]);
|
|
468
526
|
if (major === 1) {
|
|
469
527
|
report.fail(CX2_ISSUE.VERSION, `CXVersion ${shown(raw)} is CX version 1, a different document shape; read it with the cx importer`, { line, element: "CXVersion" });
|
|
470
528
|
}
|
|
@@ -504,6 +562,9 @@ function readDescriptor(value, line, doc, report) {
|
|
|
504
562
|
function memberAspect(value, line, structure, report, collect) {
|
|
505
563
|
const keys = isRecord(value) ? Object.keys(value) : [];
|
|
506
564
|
if (isRecord(value) && keys.length === 1 && isRecord(value[keys[0]])) {
|
|
565
|
+
if (ARRAY_ASPECTS.has(keys[0])) {
|
|
566
|
+
report.warning("validation-error", CX2_ISSUE.SINGLE_OBJECT_ASPECT, `the "${keys[0]}" aspect is one object, not an array of elements; read as one element`, { line, element: keys[0] });
|
|
567
|
+
}
|
|
507
568
|
structure.block(keys[0], line);
|
|
508
569
|
collect(keys[0], value[keys[0]]);
|
|
509
570
|
return;
|
|
@@ -596,7 +657,20 @@ class DeclarationTable {
|
|
|
596
657
|
}
|
|
597
658
|
}
|
|
598
659
|
/** The domain key of attributeDeclarations for each table. */
|
|
599
|
-
const DECLARATION_KEYS =
|
|
660
|
+
const DECLARATION_KEYS = new Map([
|
|
661
|
+
["nodes", "node"],
|
|
662
|
+
["edges", "edge"],
|
|
663
|
+
["networkAttributes", "network"],
|
|
664
|
+
]);
|
|
665
|
+
/**
|
|
666
|
+
* Whether an object has an own property (never one of Object.prototype, as `in` would find).
|
|
667
|
+
* @param record - the object
|
|
668
|
+
* @param key - the key
|
|
669
|
+
* @returns true for an own property
|
|
670
|
+
*/
|
|
671
|
+
function hasOwn(record, key) {
|
|
672
|
+
return Object.hasOwn(record, key);
|
|
673
|
+
}
|
|
600
674
|
// ============================================================ the build
|
|
601
675
|
/** Reads a collected document into a sink. */
|
|
602
676
|
class Cx2Reader {
|
|
@@ -619,6 +693,8 @@ class Cx2Reader {
|
|
|
619
693
|
this.nodeRows = new Map();
|
|
620
694
|
/** CX node id -> the id the sink holds it under (differs when a mangled id is restored). */
|
|
621
695
|
this.sinkIds = new Map();
|
|
696
|
+
/** The original ids restored so far: a second node with one keeps its CX id. */
|
|
697
|
+
this.restored = new Set();
|
|
622
698
|
/** CX edge id -> sink edge index. */
|
|
623
699
|
this.edgeRows = new Map();
|
|
624
700
|
this.positionHandle = INVALID_INDEX;
|
|
@@ -651,7 +727,7 @@ class Cx2Reader {
|
|
|
651
727
|
}
|
|
652
728
|
this.readLegacyLayout();
|
|
653
729
|
if (this.positioned.size > 0 && this.positioned.size < this.nodeRows.size) {
|
|
654
|
-
report.warnOnce("missing-value", CX2_ISSUE.PARTIAL_LAYOUT, `${this.nodeRows.size - this.positioned.size} of ${this.nodeRows.size} node(
|
|
730
|
+
report.warnOnce("missing-value", CX2_ISSUE.PARTIAL_LAYOUT, `${this.nodeRows.size - this.positioned.size} of ${this.nodeRows.size} node${plural(this.nodeRows.size)} ${agree(this.nodeRows.size - this.positioned.size, "has", "have")} no coordinates; their positions are unset`, { element: "nodes" });
|
|
655
731
|
}
|
|
656
732
|
for (const held of doc.edges) {
|
|
657
733
|
this.readEdge(held);
|
|
@@ -660,7 +736,7 @@ class Cx2Reader {
|
|
|
660
736
|
this.readBypasses("node", doc.nodeBypasses);
|
|
661
737
|
this.readBypasses("edge", doc.edgeBypasses);
|
|
662
738
|
for (const [kind, count] of this.dangling) {
|
|
663
|
-
report.warning("validation-error", DANGLING_REFERENCE_CODE, `${count} ${kind} name
|
|
739
|
+
report.warning("validation-error", DANGLING_REFERENCE_CODE, `${count} ${kind}${plural(count)} ${agree(count, "names", "name")} no element; ignored`, { element: kind });
|
|
664
740
|
}
|
|
665
741
|
this.checkAspects();
|
|
666
742
|
this.setMeta();
|
|
@@ -678,9 +754,12 @@ class Cx2Reader {
|
|
|
678
754
|
continue;
|
|
679
755
|
}
|
|
680
756
|
for (const [key, table] of Object.entries(held.value)) {
|
|
681
|
-
const domain = DECLARATION_KEYS
|
|
757
|
+
const domain = DECLARATION_KEYS.get(key);
|
|
682
758
|
if (domain === undefined) {
|
|
683
|
-
|
|
759
|
+
report.warning("unsupported", UNKNOWN_ELEMENT_CODE, `attributeDeclarations holds the table "${key}", which CX2 does not define; kept in meta.extra.cx2.declarations, not applied`, { line: held.line, element: key });
|
|
760
|
+
setOwn(this.decls.other, key, plainJson(table, (digits) => {
|
|
761
|
+
this.precision(key, digits);
|
|
762
|
+
}));
|
|
684
763
|
continue;
|
|
685
764
|
}
|
|
686
765
|
if (!isRecord(table)) {
|
|
@@ -713,7 +792,10 @@ class Cx2Reader {
|
|
|
713
792
|
}
|
|
714
793
|
for (const [key, raw] of Object.entries(value.v)) {
|
|
715
794
|
const resolved = table.resolve(key);
|
|
716
|
-
if (
|
|
795
|
+
if (key === "" ||
|
|
796
|
+
(resolved !== null && resolved.decl.type !== null) ||
|
|
797
|
+
raw === null ||
|
|
798
|
+
raw === undefined) {
|
|
717
799
|
continue;
|
|
718
800
|
}
|
|
719
801
|
const name = resolved?.decl.name ?? key;
|
|
@@ -760,6 +842,10 @@ class Cx2Reader {
|
|
|
760
842
|
const { report } = this;
|
|
761
843
|
const table = this.decls[domain];
|
|
762
844
|
const where = { line, element: name };
|
|
845
|
+
if (name === "") {
|
|
846
|
+
report.error("validation-error", BAD_VALUE_CODE, `a ${domain} attribute declaration has an empty name; ignored`, where);
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
763
849
|
if (!isRecord(raw)) {
|
|
764
850
|
report.error("validation-error", BAD_VALUE_CODE, `the declaration of "${name}" is not an object; ignored`, where);
|
|
765
851
|
return;
|
|
@@ -782,6 +868,9 @@ class Cx2Reader {
|
|
|
782
868
|
}
|
|
783
869
|
return;
|
|
784
870
|
}
|
|
871
|
+
if (raw.a !== undefined && raw.a !== null && typeof raw.a !== "string") {
|
|
872
|
+
report.error("validation-error", BAD_VALUE_CODE, `the alias ${shown(raw.a)} of "${name}" is not a string; ignored`, where);
|
|
873
|
+
}
|
|
785
874
|
let alias = typeof raw.a === "string" ? raw.a : null;
|
|
786
875
|
let hasDefault = raw.v !== undefined && raw.v !== null;
|
|
787
876
|
if (domain === "network" && (raw.a !== undefined || raw.v !== undefined)) {
|
|
@@ -817,7 +906,9 @@ class Cx2Reader {
|
|
|
817
906
|
* @returns the default, or BAD when dropped
|
|
818
907
|
*/
|
|
819
908
|
convertDefault(name, value, type, where) {
|
|
820
|
-
const converted = convertValue(value, type, this.options.long, () =>
|
|
909
|
+
const converted = convertValue(value, type, this.options.long, (digits) => {
|
|
910
|
+
this.precision(name, digits);
|
|
911
|
+
});
|
|
821
912
|
if (converted !== BAD) {
|
|
822
913
|
return converted;
|
|
823
914
|
}
|
|
@@ -922,28 +1013,29 @@ class Cx2Reader {
|
|
|
922
1013
|
* @param raw - the parsed id
|
|
923
1014
|
* @param inexact - whether the literal was not a plain integer
|
|
924
1015
|
* @param element - the element name for issues
|
|
1016
|
+
* @param line - the element's line
|
|
925
1017
|
* @param edgeId - whether this is an edge's own id (stored in the f64 id column, not kept as digits)
|
|
926
1018
|
* @returns the id, or null when it was reported
|
|
927
1019
|
*/
|
|
928
|
-
idOf(raw, inexact, element, edgeId = false) {
|
|
1020
|
+
idOf(raw, inexact, element, line, edgeId = false) {
|
|
929
1021
|
let id;
|
|
930
1022
|
try {
|
|
931
1023
|
const parsed = cxId(raw, inexact);
|
|
932
1024
|
if (parsed.note === "text") {
|
|
933
|
-
this.report.warnOnce("coercion", ID_TEXT_TYPE_CODE, `${element}: the id ${shown(raw)} is not written as an integer; read as ${String(parsed.id)}`, { element });
|
|
1025
|
+
this.report.warnOnce("coercion", ID_TEXT_TYPE_CODE, `${element}: the id ${shown(raw)} is not written as an integer; read as ${String(parsed.id)}`, { line, element });
|
|
934
1026
|
}
|
|
935
1027
|
else if (parsed.note === "precision" && edgeId) {
|
|
936
1028
|
// the edge is told apart by its digits, but the id column is f64
|
|
937
|
-
this.report.warnOnce("precision", PRECISION_CODE, `${element}: the edge id ${String(parsed.id)} is beyond 2^53; the id column holds the nearest double`, { element }, `${PRECISION_CODE}:edge`);
|
|
1029
|
+
this.report.warnOnce("precision", PRECISION_CODE, `${element}: the edge id ${String(parsed.id)} is beyond 2^53; the id column holds the nearest double`, { line, element }, `${PRECISION_CODE}:edge`);
|
|
938
1030
|
}
|
|
939
1031
|
else if (parsed.note === "precision") {
|
|
940
1032
|
this.idType = "mixed";
|
|
941
|
-
this.report.warnOnce("precision", PRECISION_CODE, `${element}: the id ${String(parsed.id)} is beyond 2^53; kept as its digits (a string id)`, { element });
|
|
1033
|
+
this.report.warnOnce("precision", PRECISION_CODE, `${element}: the id ${String(parsed.id)} is beyond 2^53; kept as its digits (a string id)`, { line, element });
|
|
942
1034
|
}
|
|
943
1035
|
id = this.options.ids === "keep" ? parsed.id : this.coercer.value(parsed.id);
|
|
944
1036
|
}
|
|
945
1037
|
catch (err) {
|
|
946
|
-
this.report.recordError(err, { element });
|
|
1038
|
+
this.report.recordError(err, { line, element });
|
|
947
1039
|
return null;
|
|
948
1040
|
}
|
|
949
1041
|
return id;
|
|
@@ -995,7 +1087,7 @@ class Cx2Reader {
|
|
|
995
1087
|
return;
|
|
996
1088
|
}
|
|
997
1089
|
const element = `node ${shown(value.id)}`;
|
|
998
|
-
const cx = this.idOf(value.id, (held.inexact & 1) !== 0, element);
|
|
1090
|
+
const cx = this.idOf(value.id, (held.inexact & 1) !== 0, element, line);
|
|
999
1091
|
if (cx === null) {
|
|
1000
1092
|
report.counts.skippedNodes++;
|
|
1001
1093
|
return;
|
|
@@ -1012,7 +1104,14 @@ class Cx2Reader {
|
|
|
1012
1104
|
report.warning("merged", DUPLICATE_NODE_CODE, `${element} is declared more than once; its attributes are merged (the later values win)`, { line, element });
|
|
1013
1105
|
}
|
|
1014
1106
|
else {
|
|
1015
|
-
|
|
1107
|
+
let original = this.originalIdOf(attrs, element, line);
|
|
1108
|
+
if (original !== null && this.restored.has(original)) {
|
|
1109
|
+
report.warning("merged", DUPLICATE_NODE_CODE, `${element}: its original id ${shown(original)} is already another node's; it keeps its CX id`, { line, element });
|
|
1110
|
+
original = null;
|
|
1111
|
+
}
|
|
1112
|
+
if (original !== null) {
|
|
1113
|
+
this.restored.add(original);
|
|
1114
|
+
}
|
|
1016
1115
|
this.idTypeOf(original ?? cx);
|
|
1017
1116
|
try {
|
|
1018
1117
|
row = sink.addNode(original ?? cx);
|
|
@@ -1034,14 +1133,19 @@ class Cx2Reader {
|
|
|
1034
1133
|
/**
|
|
1035
1134
|
* The original id the exporter's `sanitizeIds: "mangle"` kept, when it is to be restored.
|
|
1036
1135
|
* @param attrs - the node's v
|
|
1136
|
+
* @param element - the element name for issues
|
|
1137
|
+
* @param line - its line
|
|
1037
1138
|
* @returns the original id, or null
|
|
1038
1139
|
*/
|
|
1039
|
-
originalIdOf(attrs) {
|
|
1140
|
+
originalIdOf(attrs, element, line) {
|
|
1040
1141
|
if (attrs === null || !this.options.restoreMangledIds) {
|
|
1041
1142
|
return null;
|
|
1042
1143
|
}
|
|
1043
1144
|
const alias = this.decls.node.byName.get(ORIGINAL_ID_ATTRIBUTE)?.alias ?? null;
|
|
1044
1145
|
const raw = attrs[ORIGINAL_ID_ATTRIBUTE] ?? (alias === null ? undefined : attrs[alias]);
|
|
1146
|
+
if (raw !== undefined && raw !== null && typeof raw !== "string") {
|
|
1147
|
+
this.report.error("validation-error", BAD_VALUE_CODE, `${element}: ${ORIGINAL_ID_ATTRIBUTE} is ${shown(raw)}, not a string; the node keeps its CX id`, { line, element });
|
|
1148
|
+
}
|
|
1045
1149
|
return typeof raw === "string" ? raw : null;
|
|
1046
1150
|
}
|
|
1047
1151
|
/**
|
|
@@ -1085,7 +1189,10 @@ class Cx2Reader {
|
|
|
1085
1189
|
// the specification requires x and y with z
|
|
1086
1190
|
this.report.warnOnce("missing-value", CX2_ISSUE.PARTIAL_LAYOUT, `${element} has z without x and y; ${this.zAs === "column" ? "z is kept in the z column" : "with no position, z is dropped"}`, { line, element }, `${CX2_ISSUE.PARTIAL_LAYOUT}:z`);
|
|
1087
1191
|
}
|
|
1088
|
-
if (x !== null && y !== null) {
|
|
1192
|
+
if (x !== null && y !== null && (!fitsF32(x) || !fitsF32(y))) {
|
|
1193
|
+
this.report.error("validation-error", BAD_VALUE_CODE, `${element}: the coordinates ${String(x)}, ${String(y)} are beyond what the f32 position column holds; the position is unset`, { line, element });
|
|
1194
|
+
}
|
|
1195
|
+
else if (x !== null && y !== null) {
|
|
1089
1196
|
this.setPosition(row, x, y, z);
|
|
1090
1197
|
}
|
|
1091
1198
|
if (z !== null && this.zAs === "column") {
|
|
@@ -1120,9 +1227,12 @@ class Cx2Reader {
|
|
|
1120
1227
|
}
|
|
1121
1228
|
if (this.positioned.size > 0) {
|
|
1122
1229
|
this.doc.opaque.set("cartesianLayout", cartesianLayout.map((h) => plainJson(h.value)));
|
|
1123
|
-
this.report.warning("unsupported", CX2_ISSUE.LEGACY_LAYOUT, `a CX1 cartesianLayout aspect (${cartesianLayout.length} element(
|
|
1230
|
+
this.report.warning("unsupported", CX2_ISSUE.LEGACY_LAYOUT, `a CX1 cartesianLayout aspect (${cartesianLayout.length} element${plural(cartesianLayout.length)}) next to node coordinates; the node coordinates are used, the aspect is kept in meta.extra.cx2`, { element: "cartesianLayout" });
|
|
1124
1231
|
return;
|
|
1125
1232
|
}
|
|
1233
|
+
// the first view named is the layout; a CX1 file with several views keeps the others
|
|
1234
|
+
let view;
|
|
1235
|
+
const seen = new Set();
|
|
1126
1236
|
for (const held of cartesianLayout) {
|
|
1127
1237
|
const entry = held.value;
|
|
1128
1238
|
if (!isRecord(entry) || typeof entry.x !== "number" || typeof entry.y !== "number") {
|
|
@@ -1134,6 +1244,16 @@ class Cx2Reader {
|
|
|
1134
1244
|
this.dangle("cartesianLayout entry");
|
|
1135
1245
|
continue;
|
|
1136
1246
|
}
|
|
1247
|
+
view ?? (view = entry.view ?? null);
|
|
1248
|
+
if ((entry.view ?? null) !== view) {
|
|
1249
|
+
this.doc.opaque.set("cartesianLayout", cartesianLayout.map((h) => plainJson(h.value)));
|
|
1250
|
+
this.report.warnOnce("validation-error", DUPLICATE_ATTRIBUTE_CODE, `the cartesianLayout aspect names several views; view ${shown(view)} is read, the aspect is kept in meta.extra.cx2`, { line: held.line, element: "cartesianLayout" }, `${DUPLICATE_ATTRIBUTE_CODE}:layout:view`);
|
|
1251
|
+
continue;
|
|
1252
|
+
}
|
|
1253
|
+
if (seen.has(row)) {
|
|
1254
|
+
this.report.warnOnce("validation-error", DUPLICATE_ATTRIBUTE_CODE, `node ${shown(entry.node)} has two cartesianLayout entries; the later wins`, { line: held.line, element: "cartesianLayout" }, `${DUPLICATE_ATTRIBUTE_CODE}:layout`);
|
|
1255
|
+
}
|
|
1256
|
+
seen.add(row);
|
|
1137
1257
|
const z = typeof entry.z === "number" ? entry.z : null;
|
|
1138
1258
|
this.setPosition(row, entry.x, entry.y, z);
|
|
1139
1259
|
if (z !== null && this.zAs === "column") {
|
|
@@ -1180,6 +1300,10 @@ class Cx2Reader {
|
|
|
1180
1300
|
const table = this.decls[domain];
|
|
1181
1301
|
for (const key of Object.keys(attrs)) {
|
|
1182
1302
|
const value = attrs[key];
|
|
1303
|
+
if (key === "") {
|
|
1304
|
+
report.error("validation-error", BAD_VALUE_CODE, `${element}: v holds an attribute with an empty name; skipped`, { line, element });
|
|
1305
|
+
continue;
|
|
1306
|
+
}
|
|
1183
1307
|
const resolved = table.resolve(key);
|
|
1184
1308
|
const name = resolved?.decl.name ?? key;
|
|
1185
1309
|
if (domain === "node" && this.options.restoreMangledIds && name === ORIGINAL_ID_ATTRIBUTE) {
|
|
@@ -1195,7 +1319,7 @@ class Cx2Reader {
|
|
|
1195
1319
|
!resolved.viaAlias &&
|
|
1196
1320
|
resolved.decl.alias !== null &&
|
|
1197
1321
|
resolved.decl.alias !== key) {
|
|
1198
|
-
if (resolved.decl.alias
|
|
1322
|
+
if (hasOwn(attrs, resolved.decl.alias)) {
|
|
1199
1323
|
report.warning("validation-error", DUPLICATE_ATTRIBUTE_CODE, `${element}: "${name}" is given under its alias and its full name; the alias wins`, { line, element });
|
|
1200
1324
|
continue;
|
|
1201
1325
|
}
|
|
@@ -1274,9 +1398,9 @@ class Cx2Reader {
|
|
|
1274
1398
|
return;
|
|
1275
1399
|
}
|
|
1276
1400
|
}
|
|
1277
|
-
const id = this.idOf(value.id, (held.inexact & 1) !== 0, element, true);
|
|
1278
|
-
const s = id === null ? null : this.idOf(value.s, (held.inexact & 2) !== 0, element);
|
|
1279
|
-
const t = s === null ? null : this.idOf(value.t, (held.inexact & 4) !== 0, element);
|
|
1401
|
+
const id = this.idOf(value.id, (held.inexact & 1) !== 0, element, line, true);
|
|
1402
|
+
const s = id === null ? null : this.idOf(value.s, (held.inexact & 2) !== 0, element, line);
|
|
1403
|
+
const t = s === null ? null : this.idOf(value.t, (held.inexact & 4) !== 0, element, line);
|
|
1280
1404
|
if (id === null || s === null || t === null) {
|
|
1281
1405
|
report.counts.skippedEdges++;
|
|
1282
1406
|
return;
|
|
@@ -1293,6 +1417,12 @@ class Cx2Reader {
|
|
|
1293
1417
|
return;
|
|
1294
1418
|
}
|
|
1295
1419
|
const attrs = isRecord(value.v) ? value.v : null;
|
|
1420
|
+
if (value.v !== undefined && value.v !== null && attrs === null) {
|
|
1421
|
+
report.error("validation-error", BAD_VALUE_CODE, `${element}: v is ${shown(value.v)}, not an object`, {
|
|
1422
|
+
line,
|
|
1423
|
+
element,
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1296
1426
|
let weight;
|
|
1297
1427
|
const weightKey = this.weightKey(attrs);
|
|
1298
1428
|
try {
|
|
@@ -1334,10 +1464,10 @@ class Cx2Reader {
|
|
|
1334
1464
|
return null;
|
|
1335
1465
|
}
|
|
1336
1466
|
const alias = this.decls.edge.byName.get(weightFrom)?.alias ?? null;
|
|
1337
|
-
if (alias !== null && alias
|
|
1467
|
+
if (alias !== null && hasOwn(attrs, alias)) {
|
|
1338
1468
|
return alias;
|
|
1339
1469
|
}
|
|
1340
|
-
return weightFrom
|
|
1470
|
+
return hasOwn(attrs, weightFrom) ? weightFrom : null;
|
|
1341
1471
|
}
|
|
1342
1472
|
/**
|
|
1343
1473
|
* The sink id of an edge endpoint: a known node, or a node created under addMissingNodes.
|
|
@@ -1455,13 +1585,27 @@ class Cx2Reader {
|
|
|
1455
1585
|
if (raw === null || raw === undefined) {
|
|
1456
1586
|
continue;
|
|
1457
1587
|
}
|
|
1588
|
+
if (property === "") {
|
|
1589
|
+
this.report.error("validation-error", BAD_VALUE_CODE, `a ${domain}Bypasses element holds a visual property with an empty name; skipped`, { line, element: `${domain}Bypasses` });
|
|
1590
|
+
continue;
|
|
1591
|
+
}
|
|
1458
1592
|
let column = columns.get(property);
|
|
1459
1593
|
if (column === undefined) {
|
|
1460
|
-
column = { rows: [], values: [] };
|
|
1594
|
+
column = { rows: [], values: [], at: new Map() };
|
|
1461
1595
|
columns.set(property, column);
|
|
1462
1596
|
}
|
|
1463
|
-
|
|
1464
|
-
column.
|
|
1597
|
+
const plain = plainJson(raw);
|
|
1598
|
+
const index = column.at.get(row);
|
|
1599
|
+
if (index === undefined) {
|
|
1600
|
+
column.at.set(row, column.rows.length);
|
|
1601
|
+
column.rows.push(row);
|
|
1602
|
+
column.values.push(plain);
|
|
1603
|
+
continue;
|
|
1604
|
+
}
|
|
1605
|
+
if (JSON.stringify(column.values[index]) !== JSON.stringify(plain)) {
|
|
1606
|
+
this.report.warnOnce("validation-error", DUPLICATE_ATTRIBUTE_CODE, `a ${domain} has the visual property "${property}" in two ${domain}Bypasses elements; the later wins`, { line, element: property }, `${DUPLICATE_ATTRIBUTE_CODE}:bypass:${domain}:${property}`);
|
|
1607
|
+
}
|
|
1608
|
+
column.values[index] = plain;
|
|
1465
1609
|
}
|
|
1466
1610
|
}
|
|
1467
1611
|
for (const [property, { rows: targets, values }] of columns) {
|
|
@@ -1496,7 +1640,7 @@ class Cx2Reader {
|
|
|
1496
1640
|
}
|
|
1497
1641
|
}
|
|
1498
1642
|
if (styles.length > 0) {
|
|
1499
|
-
report.warning("unsupported", STYLES_NOT_IMPORTED_CODE, `the file's style rules are not applied (${styles.join("; ")}); they are kept in meta.extra.cx2.opaque
|
|
1643
|
+
report.warning("unsupported", STYLES_NOT_IMPORTED_CODE, `the file's style rules are not applied (${styles.join("; ")}); they are kept in meta.extra.cx2.opaque`, { element: STYLE_ASPECTS.filter((a) => doc.opaque.has(a)).join(",") });
|
|
1500
1644
|
}
|
|
1501
1645
|
for (const aspect of SINGLE_ELEMENT_ASPECTS.slice(1)) {
|
|
1502
1646
|
const count = doc.opaque.get(aspect)?.length ?? 0;
|
|
@@ -1590,14 +1734,15 @@ function describeStyle(aspect, elements) {
|
|
|
1590
1734
|
const defaults = isRecord(first.default)
|
|
1591
1735
|
? Object.values(first.default).reduce((n, v) => n + (isRecord(v) ? Object.keys(v).length : 0), 0)
|
|
1592
1736
|
: 0;
|
|
1593
|
-
return `visualProperties: ${defaults} default(
|
|
1737
|
+
return `visualProperties: ${defaults} default${plural(defaults)}, ${count("nodeMapping")} node mapping${plural(count("nodeMapping"))}, ${count("edgeMapping")} edge mapping${plural(count("edgeMapping"))}`;
|
|
1594
1738
|
}
|
|
1595
|
-
return `${aspect}: ${elements.length} element(
|
|
1739
|
+
return `${aspect}: ${elements.length} element${plural(elements.length)}`;
|
|
1596
1740
|
}
|
|
1597
1741
|
/**
|
|
1598
1742
|
* Resolve the zAs option.
|
|
1599
1743
|
* @param value - the option
|
|
1600
1744
|
* @returns the mode; E_UNSUPPORTED for any other value
|
|
1745
|
+
* @category Plugin helpers
|
|
1601
1746
|
*/
|
|
1602
1747
|
export function zAsOption(value) {
|
|
1603
1748
|
if (value === undefined) {
|
|
@@ -1612,10 +1757,12 @@ export function zAsOption(value) {
|
|
|
1612
1757
|
});
|
|
1613
1758
|
}
|
|
1614
1759
|
/**
|
|
1615
|
-
* The CX2 importer plugin
|
|
1760
|
+
* The CX2 importer plugin.
|
|
1761
|
+
* @category Built-in formats
|
|
1616
1762
|
*/
|
|
1617
1763
|
export const cx2Importer = Object.freeze({
|
|
1618
1764
|
format: CX2_FORMAT,
|
|
1765
|
+
options: Object.freeze(["zAs"]),
|
|
1619
1766
|
extensions: Object.freeze([".cx2"]),
|
|
1620
1767
|
mimeTypes: Object.freeze(["application/json"]),
|
|
1621
1768
|
/**
|
|
@@ -1625,7 +1772,7 @@ export const cx2Importer = Object.freeze({
|
|
|
1625
1772
|
* @returns the confidence
|
|
1626
1773
|
*/
|
|
1627
1774
|
sniff(head) {
|
|
1628
|
-
const text =
|
|
1775
|
+
const text = headText(head);
|
|
1629
1776
|
return /^\s*\[\s*\{(?:\s*"[^"]*"\s*:\s*(?:true|false|"[^"]*"|[0-9.]+)\s*,)*\s*"CXVersion"\s*:/.test(text)
|
|
1630
1777
|
? 0.97
|
|
1631
1778
|
: 0;
|