@graphty/graph-io 0.3.25 → 0.3.26
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-BbJI55dx.js +56 -0
- package/dist/chunks/choose-BbJI55dx.js.map +1 -0
- package/dist/chunks/constants-BCsFsMj4.js +231 -0
- package/dist/chunks/constants-BCsFsMj4.js.map +1 -0
- package/dist/chunks/{escape-B-tkk_Cl.js → escape-D0g6NNUy.js} +382 -92
- package/dist/chunks/escape-D0g6NNUy.js.map +1 -0
- package/dist/chunks/export-BTI4yQgy.js +4333 -0
- package/dist/chunks/export-BTI4yQgy.js.map +1 -0
- package/dist/chunks/exporter-BMqk5oxW.js +3465 -0
- package/dist/chunks/exporter-BMqk5oxW.js.map +1 -0
- package/dist/chunks/{importer-eUREhBGj.js → exporter-Cra2GYcN.js} +4969 -3201
- package/dist/chunks/exporter-Cra2GYcN.js.map +1 -0
- package/dist/chunks/{exporter-BGrsWamJ.js → exporter-Dxh231ZF.js} +38 -229
- package/dist/chunks/exporter-Dxh231ZF.js.map +1 -0
- package/dist/chunks/{exporter-DIeGJXAZ.js → exporter-tne475KK.js} +22 -20
- package/dist/chunks/exporter-tne475KK.js.map +1 -0
- package/dist/chunks/importer-90YWhJoF.js +2811 -0
- package/dist/chunks/importer-90YWhJoF.js.map +1 -0
- package/dist/chunks/{importer-D_e7e7LX.js → importer-Bcl1d4xH.js} +398 -145
- package/dist/chunks/importer-Bcl1d4xH.js.map +1 -0
- package/dist/chunks/{importer-BWY2FFc5.js → importer-BfIsp1f9.js} +255 -77
- package/dist/chunks/importer-BfIsp1f9.js.map +1 -0
- package/dist/chunks/{importer-zGLo8Dg_.js → importer-C_TEA1zJ.js} +484 -157
- package/dist/chunks/importer-C_TEA1zJ.js.map +1 -0
- package/dist/chunks/{importer-DET1tg6s.js → importer-DCjOvO7U.js} +1687 -310
- package/dist/chunks/importer-DCjOvO7U.js.map +1 -0
- package/dist/chunks/{importer-vi3bSdtw.js → importer-DfVu6j59.js} +509 -76
- package/dist/chunks/importer-DfVu6j59.js.map +1 -0
- package/dist/chunks/{importer-DIrbbnAf.js → importer-Dku_VAIY.js} +585 -226
- package/dist/chunks/importer-Dku_VAIY.js.map +1 -0
- package/dist/chunks/json-elements-3tnyt5uZ.js +1225 -0
- package/dist/chunks/json-elements-3tnyt5uZ.js.map +1 -0
- package/dist/chunks/ontology-export-B9Tcf37D.js +357 -0
- package/dist/chunks/ontology-export-B9Tcf37D.js.map +1 -0
- package/dist/chunks/{records-dbRkxwaq.js → records-CQXT__mY.js} +298 -114
- package/dist/chunks/records-CQXT__mY.js.map +1 -0
- package/dist/chunks/{text-Dr0Ifpag.js → text-DmcUs5_Q.js} +29 -11
- package/dist/chunks/text-DmcUs5_Q.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 +951 -261
- 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 +342 -85
- 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 +564 -157
- 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 +19 -1
- 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 +33 -17
- 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 +868 -188
- 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 +2 -0
- 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 +400 -83
- 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 +145 -32
- 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 +680 -285
- 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 +226 -79
- 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 +98 -24
- 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 +108 -26
- 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 +238 -85
- 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 +66 -34
- 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 +183 -51
- 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 +20 -21
- 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 +7 -2
- 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 +38 -4
- package/src/common/direction.ts +78 -51
- package/src/common/escape.ts +33 -17
- 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 +1034 -198
- package/src/common/line-format.ts +249 -0
- package/src/common/lists.ts +6 -1
- 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 +477 -88
- package/src/common/zip.ts +169 -7
- package/src/formats/csv/exporter.ts +201 -46
- 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 +888 -300
- package/src/formats/cx/index.ts +4 -3
- package/src/formats/cx2/exporter.ts +61 -338
- package/src/formats/cx2/importer.ts +317 -86
- 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 +139 -31
- 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 +111 -26
- 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 +320 -101
- 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 +89 -41
- package/src/formats/pajek/importer.ts +407 -93
- package/src/formats/pajek/index.ts +2 -1
- package/src/formats/pajek/syntax.ts +213 -52
- 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 +35 -27
- package/src/formats/xgmml/importer.ts +64 -86
- package/src/formats/xgmml/index.ts +1 -0
- package/src/formats/xgmml/values.ts +11 -3
- 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
package/dist/gml.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ak as SYNTAX_CODE, b as plural, a as checkCapabilities, L as LOSS, p as pairFolding, $ as agree, c as capabilities, r as resolveExportOptions, ac as DictHeuristic, aG as formatInteger, bw as formatGmlReal, aE as sanitizeIds, bE as countMixedEdges, e as explicitWeights, bV as DICT_SAMPLE_ROWS, R as ROLE_TAKEN_CODE$1, aj as WIDENED_CODE$1, P as PRECISION_CODE$1, n as DUPLICATE_NODE_CODE$1, s as MISSING_ENDPOINT_CODE$1, t as MISSING_ID_CODE$1, l as MULTIPLE_GRAPHS_CODE, N as NO_GRAPH_CODE$1, al as resolveImportOptions, a8 as ImportReportBuilder, an as reportUnusedOptions, bC as readText, am as throwIfAborted, ao as reportSinkOptions, ap as graphChosen, ar as IdCoercer, aq as DirectionResolver, a0 as uniqueColumnName, C as COLUMN_RENAMED_CODE, as as weightFromValue, bW as reportWeightPrecision, aL as parseWeightText, a1 as declareResolved, M as MIXED_DIRECTION_CODE, D as DIRECTION_FORCED_CODE, d as DIRECTION_REFUSED_CODE, S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, I as ID_MERGED_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, w as UNKNOWN_ENCODING_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE } from "./chunks/export-BTI4yQgy.js";
|
|
2
2
|
import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { j as joinText, e as encodeChunks } from "./chunks/writer-C7flM-Ih.js";
|
|
3
|
+
import { k as decodeGmlString, m as quoteGmlString } from "./chunks/escape-D0g6NNUy.js";
|
|
4
|
+
import { j as joinText, e as encodeChunks } from "./chunks/writer-DxjgHwSe.js";
|
|
5
|
+
import { i as importChosenGraph } from "./chunks/choose-BbJI55dx.js";
|
|
7
6
|
const TOKEN_WORD = 0;
|
|
8
7
|
const TOKEN_INT = 1;
|
|
9
8
|
const TOKEN_REAL = 2;
|
|
@@ -85,14 +84,20 @@ class GmlTokens {
|
|
|
85
84
|
* @returns the body with character references decoded
|
|
86
85
|
*/
|
|
87
86
|
stringOf(i) {
|
|
88
|
-
|
|
87
|
+
let text = this.textOf(i);
|
|
88
|
+
if (text.includes("\r")) {
|
|
89
|
+
text = text.replaceAll(/\r\n?/g, "\n");
|
|
90
|
+
}
|
|
89
91
|
if (text.indexOf("&") < 0) {
|
|
90
92
|
return text;
|
|
91
93
|
}
|
|
92
94
|
const report = this.onUnknownEntity;
|
|
93
|
-
return decodeGmlString(
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
return decodeGmlString(
|
|
96
|
+
text,
|
|
97
|
+
report === null ? void 0 : (entity) => {
|
|
98
|
+
report(entity, this.line[i]);
|
|
99
|
+
}
|
|
100
|
+
);
|
|
96
101
|
}
|
|
97
102
|
/**
|
|
98
103
|
* Whether a token is a `[` or `]`.
|
|
@@ -133,6 +138,7 @@ function tokenizeGml(text) {
|
|
|
133
138
|
const n = text.length;
|
|
134
139
|
let i = 0;
|
|
135
140
|
let line = 1;
|
|
141
|
+
let spanningLine = 0;
|
|
136
142
|
while (i < n) {
|
|
137
143
|
const c = text.charCodeAt(i);
|
|
138
144
|
if (c === 10) {
|
|
@@ -146,6 +152,8 @@ function tokenizeGml(text) {
|
|
|
146
152
|
}
|
|
147
153
|
} else if (c === 32 || c === 9 || c === 11 || c === 12) {
|
|
148
154
|
i++;
|
|
155
|
+
} else if (c === 65279) {
|
|
156
|
+
i++;
|
|
149
157
|
} else if (c === 35) {
|
|
150
158
|
i = endOfLine(text, i);
|
|
151
159
|
} else if (c === 91) {
|
|
@@ -156,11 +164,21 @@ function tokenizeGml(text) {
|
|
|
156
164
|
i++;
|
|
157
165
|
} else if (c === 34) {
|
|
158
166
|
const close = text.indexOf('"', i + 1);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string at line ${line}`, line);
|
|
167
|
+
if (close < 0) {
|
|
168
|
+
const hint = spanningLine === 0 ? "" : `; the string opened at line ${spanningLine} spans lines, so a quote may be missing there`;
|
|
169
|
+
throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string opened at line ${line}${hint}`, line);
|
|
162
170
|
}
|
|
163
171
|
tokens.push(TOKEN_STRING, i + 1, close, line);
|
|
172
|
+
const opened = line;
|
|
173
|
+
for (let k = i + 1; k < close; k++) {
|
|
174
|
+
const d = text.codePointAt(k);
|
|
175
|
+
if (d === 10 || d === 13 && text.codePointAt(k + 1) !== 10) {
|
|
176
|
+
line++;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (line !== opened && spanningLine === 0) {
|
|
180
|
+
spanningLine = opened;
|
|
181
|
+
}
|
|
164
182
|
i = close + 1;
|
|
165
183
|
} else {
|
|
166
184
|
let j = i + 1;
|
|
@@ -198,8 +216,12 @@ function classifyBare(text, start, end, line) {
|
|
|
198
216
|
if (REAL_TEXT.test(token) || NON_FINITE_TEXT.test(token)) {
|
|
199
217
|
return TOKEN_REAL;
|
|
200
218
|
}
|
|
201
|
-
const
|
|
202
|
-
|
|
219
|
+
const hex = (c) => (c.codePointAt(0) ?? 0).toString(16).toUpperCase().padStart(4, "0");
|
|
220
|
+
const head = token.length > 20 ? `${token.slice(0, 20)}...` : token;
|
|
221
|
+
const shown = head.replaceAll(/[^\x20-\x7e]/gu, (c) => String.raw`\u` + hex(c));
|
|
222
|
+
const odd = /[^\x21-\x7e]/u.exec(token);
|
|
223
|
+
const note2 = odd === null ? "" : ` (it holds U+${hex(odd[0])}, which GML allows only inside a string)`;
|
|
224
|
+
throw new GmlSyntaxError(SYNTAX_TOKEN_CODE, `cannot tokenize "${shown}" at line ${line}${note2}`, line);
|
|
203
225
|
}
|
|
204
226
|
function validateStructure(tokens) {
|
|
205
227
|
const { count, kind } = tokens;
|
|
@@ -252,7 +274,7 @@ function validateStructure(tokens) {
|
|
|
252
274
|
const open = stack[stack.length - 1];
|
|
253
275
|
throw new GmlSyntaxError(
|
|
254
276
|
SYNTAX_BRACKET_CODE,
|
|
255
|
-
`unexpected end of input: ${stack.length} bracket(
|
|
277
|
+
`unexpected end of input: ${stack.length} bracket${plural(stack.length)} still open, the last opened at line ${tokens.line[open]}`,
|
|
256
278
|
tokens.line[open]
|
|
257
279
|
);
|
|
258
280
|
}
|
|
@@ -436,8 +458,11 @@ function isWritten(column) {
|
|
|
436
458
|
return role === null || !SKIPPED_ROLES.has(role);
|
|
437
459
|
}
|
|
438
460
|
function preferredKey(meta) {
|
|
439
|
-
const { origin } = meta;
|
|
440
|
-
|
|
461
|
+
const { origin, name } = meta;
|
|
462
|
+
if (origin?.format !== "gml" || origin.id === null) {
|
|
463
|
+
return name;
|
|
464
|
+
}
|
|
465
|
+
return name === origin.id || name.startsWith(`${origin.id}#`) ? origin.id : name;
|
|
441
466
|
}
|
|
442
467
|
function hasWeights(snapshot) {
|
|
443
468
|
return snapshot.flags.weighted;
|
|
@@ -480,7 +505,7 @@ function selectColumns(table, reserved, label, plan, notes, filter = () => true)
|
|
|
480
505
|
notes.push(
|
|
481
506
|
note(
|
|
482
507
|
code,
|
|
483
|
-
`${label} column "${column.meta.name}" ${why};
|
|
508
|
+
`${label} column "${column.meta.name}" ${why}; the save fails unless sanitizeKeys is "mangle"`,
|
|
484
509
|
column.meta.name
|
|
485
510
|
)
|
|
486
511
|
);
|
|
@@ -564,7 +589,7 @@ function jsonNotes(columns, label, plan, notes) {
|
|
|
564
589
|
notes.push(
|
|
565
590
|
note(
|
|
566
591
|
RECORD_NUMBER_TYPE_CODE,
|
|
567
|
-
`${where} holds numbers in ${stats.numbers} row(
|
|
592
|
+
`${where} holds numbers in ${stats.numbers} row${plural(stats.numbers)}; GML records cannot keep the int / real distinction`,
|
|
568
593
|
name,
|
|
569
594
|
stats.numbers
|
|
570
595
|
)
|
|
@@ -574,7 +599,7 @@ function jsonNotes(columns, label, plan, notes) {
|
|
|
574
599
|
notes.push(
|
|
575
600
|
note(
|
|
576
601
|
RECORD_BOOLEAN_CODE,
|
|
577
|
-
`${where} holds booleans in ${stats.booleans} row(
|
|
602
|
+
`${where} holds booleans in ${stats.booleans} row${plural(stats.booleans)}; written as 1 / 0`,
|
|
578
603
|
name,
|
|
579
604
|
stats.booleans
|
|
580
605
|
)
|
|
@@ -584,7 +609,7 @@ function jsonNotes(columns, label, plan, notes) {
|
|
|
584
609
|
notes.push(
|
|
585
610
|
note(
|
|
586
611
|
RECORD_NULL_CODE,
|
|
587
|
-
`${where} holds nulls in ${stats.nulls} row(
|
|
612
|
+
`${where} holds nulls in ${stats.nulls} row${plural(stats.nulls)}; GML has no null, the key is omitted`,
|
|
588
613
|
name,
|
|
589
614
|
stats.nulls
|
|
590
615
|
)
|
|
@@ -594,7 +619,7 @@ function jsonNotes(columns, label, plan, notes) {
|
|
|
594
619
|
notes.push(
|
|
595
620
|
note(
|
|
596
621
|
JSON_ARRAY_CODE,
|
|
597
|
-
`${where} holds arrays as values in ${stats.arrays} row(
|
|
622
|
+
`${where} holds arrays as values in ${stats.arrays} row${plural(stats.arrays)}; written as repeated keys, they re-import as a list`,
|
|
598
623
|
name,
|
|
599
624
|
stats.arrays
|
|
600
625
|
)
|
|
@@ -604,7 +629,7 @@ function jsonNotes(columns, label, plan, notes) {
|
|
|
604
629
|
notes.push(
|
|
605
630
|
note(
|
|
606
631
|
NESTED_ARRAY_CODE,
|
|
607
|
-
`${where} holds arrays nested in arrays in ${stats.nestedArrays} row(
|
|
632
|
+
`${where} holds arrays nested in arrays in ${stats.nestedArrays} row${plural(stats.nestedArrays)}; GML cannot write them and the save fails`,
|
|
608
633
|
name,
|
|
609
634
|
stats.nestedArrays
|
|
610
635
|
)
|
|
@@ -614,12 +639,12 @@ function jsonNotes(columns, label, plan, notes) {
|
|
|
614
639
|
notes.push(
|
|
615
640
|
plan.mangle ? note(
|
|
616
641
|
KEY_MANGLED_CODE,
|
|
617
|
-
`${where}: ${stats.invalidKeys} record key(
|
|
642
|
+
`${where}: ${stats.invalidKeys} record key${plural(stats.invalidKeys)} ${agree(stats.invalidKeys, "is", "are")} not GML keys and are rewritten`,
|
|
618
643
|
name,
|
|
619
644
|
stats.invalidKeys
|
|
620
645
|
) : note(
|
|
621
646
|
INVALID_KEY_CODE,
|
|
622
|
-
`${where}: ${stats.invalidKeys} record key(
|
|
647
|
+
`${where}: ${stats.invalidKeys} record key${plural(stats.invalidKeys)} ${agree(stats.invalidKeys, "is", "are")} not GML keys; the save fails unless sanitizeKeys is "mangle"`,
|
|
623
648
|
name,
|
|
624
649
|
stats.invalidKeys
|
|
625
650
|
)
|
|
@@ -716,7 +741,7 @@ function graphicsNotes(snapshot, notes) {
|
|
|
716
741
|
notes.push(
|
|
717
742
|
note(
|
|
718
743
|
GRAPHICS_OVERRIDDEN_CODE,
|
|
719
|
-
`${overridden} node graphics record(
|
|
744
|
+
`${overridden} node graphics record${plural(overridden)} ${agree(overridden, "has", "have")} x / y / z keys the position column replaces`,
|
|
720
745
|
"graphics",
|
|
721
746
|
overridden
|
|
722
747
|
)
|
|
@@ -726,7 +751,7 @@ function graphicsNotes(snapshot, notes) {
|
|
|
726
751
|
notes.push(
|
|
727
752
|
note(
|
|
728
753
|
GRAPHICS_CONFLICT_CODE,
|
|
729
|
-
`${conflicts} node graphics value(
|
|
754
|
+
`${conflicts} node graphics value${plural(conflicts)} ${agree(conflicts, "is", "are")} not records and cannot hold the position; the save fails`,
|
|
730
755
|
"graphics",
|
|
731
756
|
conflicts
|
|
732
757
|
)
|
|
@@ -841,7 +866,7 @@ function check(snapshot, options) {
|
|
|
841
866
|
notes.push(
|
|
842
867
|
note(
|
|
843
868
|
LOSS.WEIGHT_KEY_CLASH,
|
|
844
|
-
`edge column "${clash.column.meta.name}" is written under "${plan.weightKey}", the key the importer reads
|
|
869
|
+
`edge column "${clash.column.meta.name}" is written under "${plan.weightKey}", the key the importer reads edge weights from; it reads back as the weight, not as a column`,
|
|
845
870
|
clash.column.meta.name,
|
|
846
871
|
clash.column.length - clash.column.nullCount
|
|
847
872
|
)
|
|
@@ -853,7 +878,7 @@ function check(snapshot, options) {
|
|
|
853
878
|
notes.push(
|
|
854
879
|
note(
|
|
855
880
|
LOSS.MUTUAL_EXPANDED,
|
|
856
|
-
`${folding.mutualCount} mutual pair(
|
|
881
|
+
`${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, "is", "are")} written as two directed edges; the mutual mark is lost`,
|
|
857
882
|
null,
|
|
858
883
|
folding.mutualCount
|
|
859
884
|
)
|
|
@@ -1159,7 +1184,7 @@ function contextOf(snapshot, options) {
|
|
|
1159
1184
|
if (mixed > 0 && plan.common.onMixedDirection === "error") {
|
|
1160
1185
|
throw new GraphFormatError(
|
|
1161
1186
|
"E_DIRECTED",
|
|
1162
|
-
`${mixed} undirected edge(
|
|
1187
|
+
`${mixed} undirected edge${plural(mixed)} in a directed graph, and GML holds one direction per file, so the save fails unless onMixedDirection is "directed" or "undirected"`,
|
|
1163
1188
|
{
|
|
1164
1189
|
reason: "mixed direction",
|
|
1165
1190
|
count: mixed
|
|
@@ -1319,6 +1344,7 @@ function writeGraphics(w, context, i) {
|
|
|
1319
1344
|
}
|
|
1320
1345
|
const gmlExporter = Object.freeze({
|
|
1321
1346
|
format: "gml",
|
|
1347
|
+
options: Object.freeze(["sanitizeKeys", "weightKey"]),
|
|
1322
1348
|
capabilities: GML_CAPABILITIES,
|
|
1323
1349
|
check,
|
|
1324
1350
|
/**
|
|
@@ -1358,7 +1384,12 @@ const FLAG_TYPE_CODE = "E_GML_FLAG_TYPE";
|
|
|
1358
1384
|
const FLAG_VALUE_CODE = "W_GML_FLAG_VALUE";
|
|
1359
1385
|
const QUOTED_INT = /^\s*[+-]?[0-9]+\s*$/;
|
|
1360
1386
|
const UNKNOWN_ENTITY_CODE = "W_GML_UNKNOWN_ENTITY";
|
|
1387
|
+
const GRAPHICS_CODE = "W_GML_GRAPHICS";
|
|
1388
|
+
const NESTED_ELEMENT_CODE = "W_GML_NESTED_ELEMENT";
|
|
1389
|
+
const GROUPS_CODE = "W_GML_GROUPS";
|
|
1390
|
+
const WIDENED_CODE = WIDENED_CODE$1;
|
|
1361
1391
|
const PRECISION_CODE = PRECISION_CODE$1;
|
|
1392
|
+
const COLUMN_RENAMED_CODE_GML = COLUMN_RENAMED_CODE;
|
|
1362
1393
|
const ROLE_TAKEN_CODE = ROLE_TAKEN_CODE$1;
|
|
1363
1394
|
const ID_DROPPED_CODE = "W_GML_ID_DROPPED";
|
|
1364
1395
|
const FORMAT_DEFAULTS = { ids: "canonical", defaultDirected: false, weightFrom: "value" };
|
|
@@ -1380,12 +1411,19 @@ const USED_OPTIONS = /* @__PURE__ */ new Set([
|
|
|
1380
1411
|
"weightFrom",
|
|
1381
1412
|
"weightDtype",
|
|
1382
1413
|
"restoreMangledIds",
|
|
1414
|
+
"long",
|
|
1383
1415
|
"errorLimit",
|
|
1384
1416
|
"signal",
|
|
1385
1417
|
"onProgress"
|
|
1386
1418
|
]);
|
|
1387
1419
|
const GRAPH_SEQ = -1;
|
|
1388
1420
|
const TOP_SEQ = -2;
|
|
1421
|
+
function isLabel(domain, key) {
|
|
1422
|
+
return roleOf(domain, key) === "label";
|
|
1423
|
+
}
|
|
1424
|
+
function isRecord(value) {
|
|
1425
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1426
|
+
}
|
|
1389
1427
|
function roleOf(domain, key) {
|
|
1390
1428
|
if (key === "label" && domain !== "graph") {
|
|
1391
1429
|
return "label";
|
|
@@ -1437,6 +1475,7 @@ class GmlImport {
|
|
|
1437
1475
|
this.nodeOrdinal = 0;
|
|
1438
1476
|
this.elementsSinceCheck = 0;
|
|
1439
1477
|
this.idMap = null;
|
|
1478
|
+
this.skippedIds = /* @__PURE__ */ new Set();
|
|
1440
1479
|
this.declared = new Uint32Array(64);
|
|
1441
1480
|
this.touched = [];
|
|
1442
1481
|
this.graphTouched = [];
|
|
@@ -1458,7 +1497,7 @@ class GmlImport {
|
|
|
1458
1497
|
this.report.warnOnce(
|
|
1459
1498
|
"parse-error",
|
|
1460
1499
|
UNKNOWN_ENTITY_CODE,
|
|
1461
|
-
`
|
|
1500
|
+
`character entity ${entity} cannot be decoded; it is kept as written`,
|
|
1462
1501
|
{ line, element: entity },
|
|
1463
1502
|
`${UNKNOWN_ENTITY_CODE}:${entity}`
|
|
1464
1503
|
);
|
|
@@ -1473,10 +1512,14 @@ class GmlImport {
|
|
|
1473
1512
|
*/
|
|
1474
1513
|
scan() {
|
|
1475
1514
|
const t = this.requireTokens();
|
|
1515
|
+
let scalarGraph = -1;
|
|
1476
1516
|
for (let p = 0; p < t.count; p = t.nextPair(p)) {
|
|
1477
1517
|
const key = t.textOf(p);
|
|
1478
1518
|
const v = p + 1;
|
|
1479
1519
|
const record = t.kind[v] === TOKEN_OPEN;
|
|
1520
|
+
if (key === "graph" && !record && scalarGraph < 0) {
|
|
1521
|
+
scalarGraph = v;
|
|
1522
|
+
}
|
|
1480
1523
|
if (key === "graph" && record) {
|
|
1481
1524
|
if (this.graphCount++ === this.which) {
|
|
1482
1525
|
this.graphOpen = v;
|
|
@@ -1491,6 +1534,13 @@ class GmlImport {
|
|
|
1491
1534
|
}
|
|
1492
1535
|
}
|
|
1493
1536
|
if (this.graphOpen < 0) {
|
|
1537
|
+
if (scalarGraph >= 0) {
|
|
1538
|
+
this.report.fail(
|
|
1539
|
+
NO_GRAPH_CODE,
|
|
1540
|
+
`the graph key at line ${t.line[scalarGraph]} holds ${describeValue(t, scalarGraph)}, not a [ ... ] block; the input contains no graph block`,
|
|
1541
|
+
{ line: t.line[scalarGraph] }
|
|
1542
|
+
);
|
|
1543
|
+
}
|
|
1494
1544
|
this.report.fail(NO_GRAPH_CODE, "the input contains no graph [ ... ] block", { line: null });
|
|
1495
1545
|
}
|
|
1496
1546
|
}
|
|
@@ -1576,7 +1626,9 @@ class GmlImport {
|
|
|
1576
1626
|
*/
|
|
1577
1627
|
observe(schema, domain, key, v, seq) {
|
|
1578
1628
|
const t = this.requireTokens();
|
|
1629
|
+
this.noteStructure(domain, key, v);
|
|
1579
1630
|
let entry = schema.get(key);
|
|
1631
|
+
const graphics = domain === "node" && key === "graphics" && this.positions;
|
|
1580
1632
|
if (entry === void 0) {
|
|
1581
1633
|
entry = {
|
|
1582
1634
|
key,
|
|
@@ -1592,13 +1644,17 @@ class GmlImport {
|
|
|
1592
1644
|
schema.set(key, entry);
|
|
1593
1645
|
} else if (entry.lastSeq === seq) {
|
|
1594
1646
|
entry.list = true;
|
|
1647
|
+
entry.rest ||= graphics;
|
|
1595
1648
|
} else {
|
|
1596
1649
|
entry.lastSeq = seq;
|
|
1597
1650
|
}
|
|
1651
|
+
if (graphics && t.kind[v] !== TOKEN_OPEN) {
|
|
1652
|
+
entry.rest = true;
|
|
1653
|
+
}
|
|
1598
1654
|
switch (t.kind[v]) {
|
|
1599
1655
|
case TOKEN_STRING: {
|
|
1600
1656
|
const raw = t.textOf(v);
|
|
1601
|
-
if (raw === LIST_START_MARKER || raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT) {
|
|
1657
|
+
if (raw === LIST_START_MARKER || !isLabel(domain, key) && (raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT)) {
|
|
1602
1658
|
entry.list = true;
|
|
1603
1659
|
return;
|
|
1604
1660
|
}
|
|
@@ -1625,8 +1681,48 @@ class GmlImport {
|
|
|
1625
1681
|
this.inspectGraphics(entry, v);
|
|
1626
1682
|
}
|
|
1627
1683
|
return;
|
|
1628
|
-
default:
|
|
1684
|
+
default: {
|
|
1629
1685
|
entry.kinds |= KIND_REAL;
|
|
1686
|
+
const text = t.textOf(v);
|
|
1687
|
+
if (/\d/.test(text) && !Number.isFinite(Number(text))) {
|
|
1688
|
+
this.report.warnOnce(
|
|
1689
|
+
"precision",
|
|
1690
|
+
PRECISION_CODE,
|
|
1691
|
+
`${domain} key "${key}" holds the real ${text}, beyond the f64 range; it is stored as ${numberOfText(text) > 0 ? "" : "-"}Infinity`,
|
|
1692
|
+
{ line: t.line[v], element: key },
|
|
1693
|
+
`${PRECISION_CODE}:overflow:${domain}:${key}`
|
|
1694
|
+
);
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
/**
|
|
1700
|
+
* Warn about keys of a node or edge whose meaning GML readers give but this import does not:
|
|
1701
|
+
* a nested graph / node / edge record, and yEd's group hierarchy.
|
|
1702
|
+
* @param domain - the table
|
|
1703
|
+
* @param key - the key
|
|
1704
|
+
* @param v - the value token
|
|
1705
|
+
*/
|
|
1706
|
+
noteStructure(domain, key, v) {
|
|
1707
|
+
const t = this.requireTokens();
|
|
1708
|
+
if (domain === "graph") {
|
|
1709
|
+
return;
|
|
1710
|
+
}
|
|
1711
|
+
if ((key === "graph" || key === "node" || key === "edge") && t.kind[v] === TOKEN_OPEN) {
|
|
1712
|
+
this.report.warnOnce(
|
|
1713
|
+
"unsupported",
|
|
1714
|
+
NESTED_ELEMENT_CODE,
|
|
1715
|
+
`a nested ${key} record inside a ${domain} is kept as the json column "${key}"; it is not read as structure`,
|
|
1716
|
+
{ line: t.line[v], element: key },
|
|
1717
|
+
`${NESTED_ELEMENT_CODE}:${domain}:${key}`
|
|
1718
|
+
);
|
|
1719
|
+
} else if (domain === "node" && (key === "isGroup" || key === "gid")) {
|
|
1720
|
+
this.report.warnOnce(
|
|
1721
|
+
"unsupported",
|
|
1722
|
+
GROUPS_CODE,
|
|
1723
|
+
"yEd group keys (isGroup, gid) are kept as plain node columns; the group hierarchy is not read as containment",
|
|
1724
|
+
{ line: t.line[v], element: key }
|
|
1725
|
+
);
|
|
1630
1726
|
}
|
|
1631
1727
|
}
|
|
1632
1728
|
/**
|
|
@@ -1708,16 +1804,26 @@ class GmlImport {
|
|
|
1708
1804
|
* @returns the plan
|
|
1709
1805
|
*/
|
|
1710
1806
|
planOf(domain, entry, top = false) {
|
|
1711
|
-
const
|
|
1807
|
+
const asText = entry.unsafe && this.options.long === "string" && kindOf(entry) === "int";
|
|
1808
|
+
const kind = asText ? "string" : kindOf(entry);
|
|
1712
1809
|
let scalar = dtypeOfKind(kind, entry);
|
|
1713
1810
|
if (scalar === "string" && !entry.list && entry.dict !== null && entry.kinds === KIND_STRING && entry.dict.decide() === "dict") {
|
|
1714
1811
|
scalar = "dict";
|
|
1715
1812
|
}
|
|
1716
|
-
if (entry.
|
|
1813
|
+
if ((entry.kinds & KIND_STRING) !== 0 && (entry.kinds & (KIND_INT | KIND_REAL)) !== 0 && (entry.kinds & KIND_RECORD) === 0) {
|
|
1814
|
+
this.report.warnOnce(
|
|
1815
|
+
"coercion",
|
|
1816
|
+
WIDENED_CODE,
|
|
1817
|
+
`${domain} key "${entry.key}" mixes numbers and strings; the column is string and the numbers are kept as written`,
|
|
1818
|
+
{ element: entry.key },
|
|
1819
|
+
`${WIDENED_CODE}:${domain}:${entry.key}`
|
|
1820
|
+
);
|
|
1821
|
+
}
|
|
1822
|
+
if (entry.unsafe && !asText) {
|
|
1717
1823
|
this.report.warnOnce(
|
|
1718
1824
|
"precision",
|
|
1719
1825
|
PRECISION_CODE,
|
|
1720
|
-
`${domain} key "${entry.key}" holds integers beyond 2^53; they are stored as the nearest f64`,
|
|
1826
|
+
`${domain} key "${entry.key}" holds integers beyond 2^53; they are stored as the nearest f64 (pass long: "string" to keep every digit as text)`,
|
|
1721
1827
|
{ element: entry.key },
|
|
1722
1828
|
`${PRECISION_CODE}:${domain}:${entry.key}`
|
|
1723
1829
|
);
|
|
@@ -1743,7 +1849,7 @@ class GmlImport {
|
|
|
1743
1849
|
items: null,
|
|
1744
1850
|
seq: Number.NEGATIVE_INFINITY
|
|
1745
1851
|
};
|
|
1746
|
-
if (domain === "node" && entry.key === "graphics" &&
|
|
1852
|
+
if (domain === "node" && entry.key === "graphics" && this.positions && (entry.kinds & KIND_RECORD) !== 0) {
|
|
1747
1853
|
const taken = (candidate) => this.nodeSchema.has(candidate) || this.sink.nodeColumn(candidate) !== INVALID_INDEX;
|
|
1748
1854
|
const position = {
|
|
1749
1855
|
...plan,
|
|
@@ -1751,9 +1857,10 @@ class GmlImport {
|
|
|
1751
1857
|
dtype: "f64",
|
|
1752
1858
|
itemDtype: null,
|
|
1753
1859
|
kind: "real",
|
|
1860
|
+
list: false,
|
|
1754
1861
|
role: "position"
|
|
1755
1862
|
};
|
|
1756
|
-
const rest = entry.rest ? { ...plan } : null;
|
|
1863
|
+
const rest = entry.rest ? { ...plan, dtype: "json", itemDtype: null, kind: "record", list: false } : null;
|
|
1757
1864
|
return { ...plan, position, rest };
|
|
1758
1865
|
}
|
|
1759
1866
|
return plan;
|
|
@@ -1766,6 +1873,14 @@ class GmlImport {
|
|
|
1766
1873
|
uniqueGraphName(key) {
|
|
1767
1874
|
const name = uniqueColumnName(key, key, (candidate) => this.graphNames.has(candidate));
|
|
1768
1875
|
this.graphNames.add(name);
|
|
1876
|
+
if (name !== key) {
|
|
1877
|
+
this.report.warning(
|
|
1878
|
+
"coercion",
|
|
1879
|
+
COLUMN_RENAMED_CODE_GML,
|
|
1880
|
+
`the top-level key "${key}" and a key of the graph block share the graph column name; the top-level value is stored as "${name}"`,
|
|
1881
|
+
{ element: key }
|
|
1882
|
+
);
|
|
1883
|
+
}
|
|
1769
1884
|
return name;
|
|
1770
1885
|
}
|
|
1771
1886
|
/** Set the graph metadata: source format, creator, version, multigraph flag, weight origin. */
|
|
@@ -1930,6 +2045,7 @@ class GmlImport {
|
|
|
1930
2045
|
this.checkAbort();
|
|
1931
2046
|
let index;
|
|
1932
2047
|
let sinkId;
|
|
2048
|
+
let fileId;
|
|
1933
2049
|
try {
|
|
1934
2050
|
let idTok = -1;
|
|
1935
2051
|
let labelTok = -1;
|
|
@@ -1947,7 +2063,7 @@ class GmlImport {
|
|
|
1947
2063
|
if (idTok < 0) {
|
|
1948
2064
|
throw new GraphFormatError("E_INVALID_ID", "node has no id", { reason: "missing id" });
|
|
1949
2065
|
}
|
|
1950
|
-
|
|
2066
|
+
fileId = this.coerceFileId(idTok, this.fileIdOf(idTok, "id"));
|
|
1951
2067
|
if (originalTok >= 0) {
|
|
1952
2068
|
sinkId = this.restoredId(originalTok);
|
|
1953
2069
|
} else {
|
|
@@ -1967,13 +2083,25 @@ class GmlImport {
|
|
|
1967
2083
|
sinkId = fileId;
|
|
1968
2084
|
}
|
|
1969
2085
|
}
|
|
2086
|
+
index = sink.addNode(sinkId);
|
|
1970
2087
|
if (this.idMap !== null) {
|
|
2088
|
+
const before = this.idMap.get(fileId);
|
|
2089
|
+
if (before !== void 0 && before !== sinkId) {
|
|
2090
|
+
report.warning(
|
|
2091
|
+
"merged",
|
|
2092
|
+
DUPLICATE_NODE_CODE,
|
|
2093
|
+
`file id ${JSON.stringify(fileId)} is declared twice (nodes ${JSON.stringify(before)} and ${JSON.stringify(sinkId)}); edges to it resolve to the later`,
|
|
2094
|
+
{ line, element: String(fileId) }
|
|
2095
|
+
);
|
|
2096
|
+
}
|
|
1971
2097
|
this.idMap.set(fileId, sinkId);
|
|
1972
2098
|
}
|
|
1973
|
-
index = sink.addNode(sinkId);
|
|
1974
2099
|
} catch (err) {
|
|
1975
2100
|
this.recordNodeError(err, line);
|
|
1976
2101
|
report.counts.skippedNodes++;
|
|
2102
|
+
if (fileId !== void 0) {
|
|
2103
|
+
this.skippedIds.add(fileId);
|
|
2104
|
+
}
|
|
1977
2105
|
return;
|
|
1978
2106
|
}
|
|
1979
2107
|
if (this.isDeclared(index)) {
|
|
@@ -1989,16 +2117,27 @@ class GmlImport {
|
|
|
1989
2117
|
}
|
|
1990
2118
|
this.beginElement(this.seq++);
|
|
1991
2119
|
try {
|
|
2120
|
+
const graphics = [];
|
|
2121
|
+
let graphicsPlan = null;
|
|
1992
2122
|
for (let p = open + 1; p < close; p = t.nextPair(p)) {
|
|
1993
2123
|
const key = t.textOf(p);
|
|
1994
2124
|
if (key === "id" || key === ORIGINAL_ID_KEY && options.restoreMangledIds) {
|
|
1995
2125
|
continue;
|
|
1996
2126
|
}
|
|
1997
2127
|
const plan = this.nodePlans.get(key);
|
|
1998
|
-
if (plan !== void 0) {
|
|
2128
|
+
if (plan !== void 0 && plan.position !== null) {
|
|
2129
|
+
graphicsPlan = plan;
|
|
2130
|
+
graphics.push(p + 1);
|
|
2131
|
+
} else if (plan !== void 0) {
|
|
1999
2132
|
this.writeNode(plan, index, p + 1);
|
|
2000
2133
|
}
|
|
2001
2134
|
}
|
|
2135
|
+
if (graphicsPlan !== null) {
|
|
2136
|
+
this.writeGraphics(graphicsPlan, index, graphics, {
|
|
2137
|
+
line: t.line[graphics[0]],
|
|
2138
|
+
element: String(sinkId)
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
2002
2141
|
this.flushLists("node", index);
|
|
2003
2142
|
} catch (err) {
|
|
2004
2143
|
this.touched.length = 0;
|
|
@@ -2194,7 +2333,18 @@ class GmlImport {
|
|
|
2194
2333
|
*/
|
|
2195
2334
|
endpoint(v, key) {
|
|
2196
2335
|
const id = this.coerceFileId(v, this.fileIdOf(v, key));
|
|
2197
|
-
|
|
2336
|
+
const mapped = this.idMap?.get(id);
|
|
2337
|
+
if (mapped !== void 0) {
|
|
2338
|
+
return mapped;
|
|
2339
|
+
}
|
|
2340
|
+
if (this.skippedIds.has(id)) {
|
|
2341
|
+
throw new GraphFormatError(
|
|
2342
|
+
"E_UNKNOWN_NODE",
|
|
2343
|
+
`${key} ${JSON.stringify(id)} names a node block that was skipped after an error`,
|
|
2344
|
+
{ reason: "skipped node", id }
|
|
2345
|
+
);
|
|
2346
|
+
}
|
|
2347
|
+
return id;
|
|
2198
2348
|
}
|
|
2199
2349
|
/**
|
|
2200
2350
|
* The weight of an edge from its weight token.
|
|
@@ -2205,11 +2355,17 @@ class GmlImport {
|
|
|
2205
2355
|
const t = this.requireTokens();
|
|
2206
2356
|
switch (t.kind[v]) {
|
|
2207
2357
|
case TOKEN_STRING:
|
|
2208
|
-
return parseWeightText(t.stringOf(v));
|
|
2358
|
+
return parseWeightText(t.stringOf(v), this.report);
|
|
2209
2359
|
case TOKEN_OPEN:
|
|
2210
2360
|
throw new GraphFormatError("E_INVALID_WEIGHT", "edge weight is a record", { value: "[...]" });
|
|
2211
|
-
default:
|
|
2212
|
-
|
|
2361
|
+
default: {
|
|
2362
|
+
const text = t.textOf(v);
|
|
2363
|
+
const weight = weightFromValue(numberOfText(text));
|
|
2364
|
+
if (weight !== void 0) {
|
|
2365
|
+
reportWeightPrecision(text, weight, this.report);
|
|
2366
|
+
}
|
|
2367
|
+
return weight;
|
|
2368
|
+
}
|
|
2213
2369
|
}
|
|
2214
2370
|
}
|
|
2215
2371
|
/**
|
|
@@ -2271,10 +2427,6 @@ class GmlImport {
|
|
|
2271
2427
|
* @param v - the value token
|
|
2272
2428
|
*/
|
|
2273
2429
|
writeNode(plan, index, v) {
|
|
2274
|
-
if (plan.position !== null) {
|
|
2275
|
-
this.writeGraphics(plan, index, v);
|
|
2276
|
-
return;
|
|
2277
|
-
}
|
|
2278
2430
|
if (plan.list) {
|
|
2279
2431
|
this.collectItem(plan, v, this.seqNow, this.touched);
|
|
2280
2432
|
return;
|
|
@@ -2305,36 +2457,89 @@ class GmlImport {
|
|
|
2305
2457
|
this.collectItem(plan, v, seq, this.graphTouched);
|
|
2306
2458
|
return;
|
|
2307
2459
|
}
|
|
2308
|
-
|
|
2460
|
+
const value = this.scalarOf(plan, v);
|
|
2461
|
+
this.sink.setGraphValue(plan.name, value, graphDecl(plan));
|
|
2462
|
+
if (seq === GRAPH_SEQ && plan.key === "name" && typeof value === "string") {
|
|
2463
|
+
this.sink.setMeta({ name: value });
|
|
2464
|
+
}
|
|
2309
2465
|
}
|
|
2310
2466
|
/**
|
|
2311
|
-
* Write a node's graphics
|
|
2312
|
-
* the
|
|
2467
|
+
* Write a node's graphics values: the position column from the x / y / z of the first record,
|
|
2468
|
+
* everything else (the remaining keys, a value that is not a record, a repeated record) to the
|
|
2469
|
+
* json column, with a warning when the value cannot give a position as written.
|
|
2313
2470
|
* @param plan - the graphics plan
|
|
2314
2471
|
* @param index - the node index
|
|
2315
|
-
* @param
|
|
2472
|
+
* @param vs - the value tokens of the node's graphics keys, in order
|
|
2473
|
+
* @param where - the line and the node, for issues
|
|
2316
2474
|
*/
|
|
2317
|
-
writeGraphics(plan, index,
|
|
2475
|
+
writeGraphics(plan, index, vs, where) {
|
|
2318
2476
|
const t = this.requireTokens();
|
|
2319
2477
|
const { sink } = this;
|
|
2320
|
-
const
|
|
2321
|
-
const
|
|
2478
|
+
const values = vs.map((v) => t.kind[v] === TOKEN_OPEN ? parseRecord(t, v) : this.scalarOf(plan, v));
|
|
2479
|
+
const first = values[0];
|
|
2322
2480
|
const positionPlan = plan.position;
|
|
2323
|
-
|
|
2324
|
-
|
|
2481
|
+
let rest = first;
|
|
2482
|
+
if (isRecord(first) && positionPlan !== null) {
|
|
2483
|
+
rest = this.writePosition(positionPlan, index, first, where);
|
|
2484
|
+
} else if (!isRecord(first)) {
|
|
2485
|
+
this.graphicsWarning("scalar", `node ${where.element}'s graphics is not a record`, where);
|
|
2486
|
+
}
|
|
2487
|
+
if (values.length > 1) {
|
|
2488
|
+
this.graphicsWarning(
|
|
2489
|
+
"repeated",
|
|
2490
|
+
`node ${where.element} has ${values.length} graphics records; the position comes from the first`,
|
|
2491
|
+
where
|
|
2492
|
+
);
|
|
2493
|
+
rest = values;
|
|
2494
|
+
}
|
|
2495
|
+
if (rest !== void 0 && plan.rest !== null) {
|
|
2496
|
+
sink.setNodeValue(this.handleOf(plan.rest, "node"), index, rest);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
/**
|
|
2500
|
+
* Write a node's position from the x / y / z of its graphics record, taking them out of it.
|
|
2501
|
+
* @param positionPlan - the position column's plan
|
|
2502
|
+
* @param index - the node index
|
|
2503
|
+
* @param record - the graphics record
|
|
2504
|
+
* @param where - the line and the node, for issues
|
|
2505
|
+
* @returns what is left of the record for the json column, or undefined when nothing is
|
|
2506
|
+
*/
|
|
2507
|
+
writePosition(positionPlan, index, record, where) {
|
|
2508
|
+
const { x, y, z } = record;
|
|
2509
|
+
let rest = record;
|
|
2510
|
+
if (typeof x === "number" && typeof y === "number") {
|
|
2511
|
+
const depth = typeof z === "number" ? z : 0;
|
|
2512
|
+
this.sink.setNodeValue(this.handleOf(positionPlan, "node"), index, [x, y, depth]);
|
|
2325
2513
|
delete record.x;
|
|
2326
2514
|
delete record.y;
|
|
2327
2515
|
if (typeof z === "number") {
|
|
2328
2516
|
delete record.z;
|
|
2329
2517
|
}
|
|
2330
|
-
|
|
2331
|
-
sink.setNodeValue(this.handleOf(plan.rest, "node"), index, record);
|
|
2332
|
-
}
|
|
2333
|
-
return;
|
|
2518
|
+
rest = Object.keys(record).length > 0 ? record : void 0;
|
|
2334
2519
|
}
|
|
2335
|
-
if (
|
|
2336
|
-
|
|
2520
|
+
if ("x" in record || "y" in record || "z" in record) {
|
|
2521
|
+
this.graphicsWarning(
|
|
2522
|
+
"coordinate",
|
|
2523
|
+
`node ${where.element}'s graphics x / y / z is not one number each`,
|
|
2524
|
+
where
|
|
2525
|
+
);
|
|
2337
2526
|
}
|
|
2527
|
+
return rest;
|
|
2528
|
+
}
|
|
2529
|
+
/**
|
|
2530
|
+
* Warn once per kind of graphics problem.
|
|
2531
|
+
* @param kind - the problem
|
|
2532
|
+
* @param what - the message start, naming the node
|
|
2533
|
+
* @param where - the line and the node
|
|
2534
|
+
*/
|
|
2535
|
+
graphicsWarning(kind, what, where) {
|
|
2536
|
+
this.report.warnOnce(
|
|
2537
|
+
"validation-error",
|
|
2538
|
+
GRAPHICS_CODE,
|
|
2539
|
+
`${what}; the value is kept in the graphics json column (warned once for every such node)`,
|
|
2540
|
+
where,
|
|
2541
|
+
`${GRAPHICS_CODE}:${kind}`
|
|
2542
|
+
);
|
|
2338
2543
|
}
|
|
2339
2544
|
/**
|
|
2340
2545
|
* Collect one list item.
|
|
@@ -2586,6 +2791,7 @@ function sniffGml(head) {
|
|
|
2586
2791
|
}
|
|
2587
2792
|
const gmlImporter = Object.freeze({
|
|
2588
2793
|
format: "gml",
|
|
2794
|
+
options: Object.freeze(["dictionaries", "positions"]),
|
|
2589
2795
|
extensions: Object.freeze([".gml"]),
|
|
2590
2796
|
mimeTypes: Object.freeze(["text/x-gml", "text/plain"]),
|
|
2591
2797
|
sniff: sniffGml,
|
|
@@ -2597,6 +2803,9 @@ const gmlImporter = Object.freeze({
|
|
|
2597
2803
|
* @returns the report
|
|
2598
2804
|
*/
|
|
2599
2805
|
async import(input, sink, options) {
|
|
2806
|
+
if (graphChosen(options)) {
|
|
2807
|
+
return importChosenGraph(gmlImporter, input, sink, options);
|
|
2808
|
+
}
|
|
2600
2809
|
const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);
|
|
2601
2810
|
const report = new ImportReportBuilder("gml", resolved.errorLimit);
|
|
2602
2811
|
reportSinkOptions(sink, options, report);
|
|
@@ -2609,7 +2818,7 @@ const gmlImporter = Object.freeze({
|
|
|
2609
2818
|
report.warning(
|
|
2610
2819
|
"unsupported",
|
|
2611
2820
|
SECOND_GRAPH_CODE,
|
|
2612
|
-
`the input holds ${gml.graphCount - 1} more graph block(
|
|
2821
|
+
`the input holds ${gml.graphCount - 1} more graph block${plural(gml.graphCount - 1)} after the first; the first is read (graphIndex or graphName chooses another; importAllGraphs() reads every one)`
|
|
2613
2822
|
);
|
|
2614
2823
|
}
|
|
2615
2824
|
throwIfAborted(resolved.signal);
|
|
@@ -2655,20 +2864,32 @@ function tokenize(text, report) {
|
|
|
2655
2864
|
}
|
|
2656
2865
|
}
|
|
2657
2866
|
const GML_ISSUE = Object.freeze({
|
|
2658
|
-
|
|
2867
|
+
...INPUT_ISSUE,
|
|
2868
|
+
...ELEMENT_ISSUE,
|
|
2869
|
+
/**
|
|
2870
|
+
* The text breaks GML's syntax: a word that is not a key or a value, an unclosed string or `[`, a stray `]`, or a
|
|
2871
|
+
* key without a value. The import stops.
|
|
2872
|
+
*/
|
|
2659
2873
|
SYNTAX: SYNTAX_CODE,
|
|
2660
|
-
/** The input
|
|
2874
|
+
/** The input is not valid UTF-8. The import stops. */
|
|
2661
2875
|
INVALID_UTF8: INVALID_UTF8_CODE,
|
|
2662
|
-
/**
|
|
2876
|
+
/**
|
|
2877
|
+
* Some bytes are not valid in the encoding that was chosen (by a byte order mark, the file's declaration or the
|
|
2878
|
+
* `encoding` option). The import stops.
|
|
2879
|
+
*/
|
|
2663
2880
|
INVALID_ENCODING: INVALID_ENCODING_CODE,
|
|
2664
2881
|
/** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */
|
|
2665
2882
|
ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,
|
|
2666
2883
|
/** A declared encoding the platform cannot decode was ignored. */
|
|
2667
2884
|
UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,
|
|
2668
|
-
/**
|
|
2885
|
+
/** There is no `graph [` block. The import stops. */
|
|
2669
2886
|
NO_GRAPH: NO_GRAPH_CODE,
|
|
2670
|
-
/**
|
|
2887
|
+
/** The file holds more than one `graph` block and only the first was read. It is not added when `graphIndex` or `graphName` chose the graph. */
|
|
2671
2888
|
MULTIPLE_GRAPHS: SECOND_GRAPH_CODE,
|
|
2889
|
+
/** `graphIndex` or `graphName` names no graph of the file; the message lists the graphs it holds. The import stops. */
|
|
2890
|
+
GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,
|
|
2891
|
+
/** `graphName` matches more than one graph; pass `graphIndex`. The import stops. */
|
|
2892
|
+
AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,
|
|
2672
2893
|
/** A node without an `id`. */
|
|
2673
2894
|
MISSING_ID: MISSING_ID_CODE,
|
|
2674
2895
|
/** A node without a `label` under nodeIdFrom "label". */
|
|
@@ -2677,7 +2898,10 @@ const GML_ISSUE = Object.freeze({
|
|
|
2677
2898
|
MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,
|
|
2678
2899
|
/** A node id, source or target that is neither an integer nor a string. */
|
|
2679
2900
|
ID_TYPE: ID_TYPE_CODE,
|
|
2680
|
-
/**
|
|
2901
|
+
/**
|
|
2902
|
+
* Node ids, sources or targets are text, where GML expects integers. They are read under the `ids` option.
|
|
2903
|
+
* Reported once per file.
|
|
2904
|
+
*/
|
|
2681
2905
|
STRING_ID: STRING_ID_CODE,
|
|
2682
2906
|
/** A node id declared twice (later keys overwrite). */
|
|
2683
2907
|
DUPLICATE_NODE: DUPLICATE_NODE_CODE,
|
|
@@ -2689,41 +2913,74 @@ const GML_ISSUE = Object.freeze({
|
|
|
2689
2913
|
FLAG_TYPE: FLAG_TYPE_CODE,
|
|
2690
2914
|
/** A `directed` / `multigraph` flag outside 0 / 1, or repeated. */
|
|
2691
2915
|
FLAG_VALUE: FLAG_VALUE_CODE,
|
|
2692
|
-
/** A named entity
|
|
2916
|
+
/** A named entity no table decodes, or a numeric reference beyond U+10FFFF; kept as written. */
|
|
2693
2917
|
UNKNOWN_ENTITY: UNKNOWN_ENTITY_CODE,
|
|
2694
|
-
/** An integer beyond 2^53
|
|
2918
|
+
/** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: "string"` to keep every digit. */
|
|
2695
2919
|
PRECISION: PRECISION_CODE,
|
|
2696
|
-
/** A
|
|
2920
|
+
/** A node's graphics value that cannot give a position as written; kept in the graphics json column. */
|
|
2921
|
+
GRAPHICS: GRAPHICS_CODE,
|
|
2922
|
+
/** A graph, node or edge record nested in a node or edge; kept as json, not read as structure. */
|
|
2923
|
+
NESTED_ELEMENT: NESTED_ELEMENT_CODE,
|
|
2924
|
+
/** YEd's isGroup / gid keys, kept as plain columns; the hierarchy is not read as containment. */
|
|
2925
|
+
GROUPS: GROUPS_CODE,
|
|
2926
|
+
/**
|
|
2927
|
+
* An attribute's type was widened because a later value did not fit: an integer above 2^31 in an integer column,
|
|
2928
|
+
* or two declared types for one attribute.
|
|
2929
|
+
*/
|
|
2930
|
+
WIDENED: WIDENED_CODE,
|
|
2931
|
+
/**
|
|
2932
|
+
* An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example
|
|
2933
|
+
* two attributes declared with the same name.
|
|
2934
|
+
*/
|
|
2697
2935
|
COLUMN_RENAMED: COLUMN_RENAMED_CODE,
|
|
2698
|
-
/**
|
|
2936
|
+
/**
|
|
2937
|
+
* You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as
|
|
2938
|
+
* a plain attribute.
|
|
2939
|
+
*/
|
|
2699
2940
|
ROLE_TAKEN: ROLE_TAKEN_CODE,
|
|
2700
|
-
/** Two id texts
|
|
2941
|
+
/** Two different id texts became the same number because `ids` is "number", so their nodes were merged. */
|
|
2701
2942
|
ID_MERGED: ID_MERGED_CODE,
|
|
2702
|
-
/**
|
|
2943
|
+
/** You set an option this format does not use; it had no effect. The message names the option. */
|
|
2703
2944
|
OPTION_IGNORED: OPTION_IGNORED_CODE,
|
|
2704
|
-
/**
|
|
2945
|
+
/**
|
|
2946
|
+
* You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,
|
|
2947
|
+
* `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.
|
|
2948
|
+
*/
|
|
2705
2949
|
SINK_OPTION: SINK_OPTION_CODE,
|
|
2706
|
-
/**
|
|
2950
|
+
/**
|
|
2951
|
+
* You read into a graph builder whose direction is already set, or which already holds edges, so the file is read
|
|
2952
|
+
* with the builder's direction instead of its own.
|
|
2953
|
+
*/
|
|
2707
2954
|
DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,
|
|
2708
|
-
/** Edges
|
|
2955
|
+
/** Edges of the other direction were read with the direction `onMixedDirection` chose. */
|
|
2709
2956
|
DIRECTION_FORCED: DIRECTION_FORCED_CODE,
|
|
2710
|
-
/**
|
|
2957
|
+
/**
|
|
2958
|
+
* The graph has both directed and undirected edges and `onMixedDirection` is "error". An import stops; a save to a
|
|
2959
|
+
* format that holds one direction per file fails with E_DIRECTED. Pass "directed" or "undirected" to read or write
|
|
2960
|
+
* it anyway.
|
|
2961
|
+
*/
|
|
2711
2962
|
MIXED_DIRECTION: MIXED_DIRECTION_CODE,
|
|
2712
|
-
/**
|
|
2963
|
+
/**
|
|
2964
|
+
* Under `nodeIdFrom: "label"` or `"index"` the file's integer ids are not kept. It is listed in `report.lossy`, not
|
|
2965
|
+
* in `report.issues`.
|
|
2966
|
+
*/
|
|
2713
2967
|
ID_DROPPED: ID_DROPPED_CODE
|
|
2714
2968
|
});
|
|
2715
2969
|
const GML_LOSS = Object.freeze({
|
|
2716
|
-
/** A json column holds numbers; GML records cannot keep int versus real
|
|
2970
|
+
/** A json column holds numbers; GML records cannot keep int versus real. */
|
|
2717
2971
|
RECORD_NUMBER_TYPE: RECORD_NUMBER_TYPE_CODE,
|
|
2718
2972
|
/** A json column holds booleans, written 1 / 0. */
|
|
2719
2973
|
RECORD_BOOLEAN: RECORD_BOOLEAN_CODE,
|
|
2720
2974
|
/** A json column holds nulls, omitted. */
|
|
2721
2975
|
RECORD_NULL: RECORD_NULL_CODE,
|
|
2722
|
-
/** An array inside an array;
|
|
2976
|
+
/** An attribute holds an array inside an array, which GML cannot write; the save fails. */
|
|
2723
2977
|
NESTED_ARRAY: NESTED_ARRAY_CODE,
|
|
2724
2978
|
/** A json row that is an array, written as repeated keys. */
|
|
2725
2979
|
JSON_ARRAY: JSON_ARRAY_CODE,
|
|
2726
|
-
/**
|
|
2980
|
+
/**
|
|
2981
|
+
* An attribute name GML cannot use as a key (keys are letters and digits, starting with a letter). The save fails
|
|
2982
|
+
* unless `sanitizeKeys` is "mangle".
|
|
2983
|
+
*/
|
|
2727
2984
|
INVALID_KEY: INVALID_KEY_CODE,
|
|
2728
2985
|
/** A column named like a structural key. */
|
|
2729
2986
|
RESERVED_KEY: RESERVED_KEY_CODE,
|