@graphty/graph-io 0.3.47 → 0.3.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{approximations-wWjCRzKj.js → approximations-C2riR4NT.js} +2 -2
- package/dist/chunks/{approximations-wWjCRzKj.js.map → approximations-C2riR4NT.js.map} +1 -1
- package/dist/chunks/{block-DiGq58c3.js → block-Cu22ewuS.js} +92 -21
- package/dist/chunks/block-Cu22ewuS.js.map +1 -0
- package/dist/chunks/{choose--jM0yYCo.js → choose-Cdx6Enl2.js} +3 -3
- package/dist/chunks/{choose--jM0yYCo.js.map → choose-Cdx6Enl2.js.map} +1 -1
- package/dist/chunks/codes-CV_Bhcyi.js +153 -0
- package/dist/chunks/codes-CV_Bhcyi.js.map +1 -0
- package/dist/chunks/{constants-BKwqelYD.js → constants-D0LqcsLJ.js} +2 -2
- package/dist/chunks/{constants-BKwqelYD.js.map → constants-D0LqcsLJ.js.map} +1 -1
- package/dist/chunks/context-cgmmOxZ2.js +663 -0
- package/dist/chunks/context-cgmmOxZ2.js.map +1 -0
- package/dist/chunks/credentials-BiQsnMTb.js +347 -0
- package/dist/chunks/credentials-BiQsnMTb.js.map +1 -0
- package/dist/chunks/cx-export-BEeF6ymo.js +259 -0
- package/dist/chunks/cx-export-BEeF6ymo.js.map +1 -0
- package/dist/chunks/descriptor-BJ-W0Jd-.js +137 -0
- package/dist/chunks/descriptor-BJ-W0Jd-.js.map +1 -0
- package/dist/chunks/descriptor-C-YDhtsn.js +48 -0
- package/dist/chunks/descriptor-C-YDhtsn.js.map +1 -0
- package/dist/chunks/{emit-CwU8cUmG.js → emit-CD8xnY8s.js} +70 -10
- package/dist/chunks/emit-CD8xnY8s.js.map +1 -0
- package/dist/chunks/{escape-CgzxiYPg.js → escape-DH2Egt-l.js} +12 -12
- package/dist/chunks/{escape-CgzxiYPg.js.map → escape-DH2Egt-l.js.map} +1 -1
- package/dist/chunks/{export-BvqAXCKh.js → export-CZ7VRm4I.js} +53 -1443
- package/dist/chunks/export-CZ7VRm4I.js.map +1 -0
- package/dist/chunks/{exporter-DndFlGSa.js → exporter-BIdaoIgh.js} +7 -6
- package/dist/chunks/{exporter-DndFlGSa.js.map → exporter-BIdaoIgh.js.map} +1 -1
- package/dist/chunks/{exporter-CJgfhF-l.js → exporter-ChjL5fmP.js} +8 -7
- package/dist/chunks/{exporter-CJgfhF-l.js.map → exporter-ChjL5fmP.js.map} +1 -1
- package/dist/chunks/{exporter--Mk9gXCJ.js → exporter-Dcw7Ldtq.js} +6 -4
- package/dist/chunks/{exporter--Mk9gXCJ.js.map → exporter-Dcw7Ldtq.js.map} +1 -1
- package/dist/chunks/exporter-DtVU80Fa.js +1008 -0
- package/dist/chunks/exporter-DtVU80Fa.js.map +1 -0
- package/dist/chunks/{exporter-CrDWIyiq.js → exporter-bxxjOrDZ.js} +11 -9
- package/dist/chunks/{exporter-CrDWIyiq.js.map → exporter-bxxjOrDZ.js.map} +1 -1
- package/dist/chunks/format-BMS-1Nxb.js +64 -0
- package/dist/chunks/format-BMS-1Nxb.js.map +1 -0
- package/dist/chunks/{generic-Dq1ntt9q.js → generic-CP6YD34u.js} +4 -4
- package/dist/chunks/{generic-Dq1ntt9q.js.map → generic-CP6YD34u.js.map} +1 -1
- package/dist/chunks/{importer-DiZRmOQG.js → importer-B87_fmVx.js} +13 -17
- package/dist/chunks/importer-B87_fmVx.js.map +1 -0
- package/dist/chunks/{importer-BSvfrX_h.js → importer-Bji2MeWr.js} +18 -1014
- package/dist/chunks/importer-Bji2MeWr.js.map +1 -0
- package/dist/chunks/{importer-COTK9Tsl.js → importer-CB_zV5_L.js} +14 -11
- package/dist/chunks/importer-CB_zV5_L.js.map +1 -0
- package/dist/chunks/{importer-e6LGpqHB.js → importer-CVT-JyDE.js} +12 -9
- package/dist/chunks/importer-CVT-JyDE.js.map +1 -0
- package/dist/chunks/{importer-yh_aBCU6.js → importer-Cyy6UseH.js} +7 -6
- package/dist/chunks/{importer-yh_aBCU6.js.map → importer-Cyy6UseH.js.map} +1 -1
- package/dist/chunks/{importer-iFYPEKaJ.js → importer-DPZDN40-.js} +14 -10
- package/dist/chunks/{importer-iFYPEKaJ.js.map → importer-DPZDN40-.js.map} +1 -1
- package/dist/chunks/{importer-CMmeMWlC.js → importer-e3huMZbm.js} +8 -260
- package/dist/chunks/importer-e3huMZbm.js.map +1 -0
- package/dist/chunks/input-Ccg9I22A.js +1397 -0
- package/dist/chunks/input-Ccg9I22A.js.map +1 -0
- package/dist/chunks/{json-elements-DJZRZ6jd.js → json-elements-By172SVq.js} +4 -4
- package/dist/chunks/{json-elements-DJZRZ6jd.js.map → json-elements-By172SVq.js.map} +1 -1
- package/dist/chunks/{lexicon-CT69Kd87.js → lexicon-u2SI5xcx.js} +19 -5
- package/dist/chunks/lexicon-u2SI5xcx.js.map +1 -0
- package/dist/chunks/{ontology-export-G4MqRdux.js → ontology-export-BwgMyuF0.js} +4 -3
- package/dist/chunks/{ontology-export-G4MqRdux.js.map → ontology-export-BwgMyuF0.js.map} +1 -1
- package/dist/chunks/{records-CiaWZrFH.js → records-Cgvxz-Vx.js} +2 -2
- package/dist/chunks/{records-CiaWZrFH.js.map → records-Cgvxz-Vx.js.map} +1 -1
- package/dist/chunks/{format-BpQBx8MZ.js → report-CgdsL9Hb.js} +72 -129
- package/dist/chunks/report-CgdsL9Hb.js.map +1 -0
- package/dist/chunks/sigv4-LkAzsLAu.js +247 -0
- package/dist/chunks/sigv4-LkAzsLAu.js.map +1 -0
- package/dist/chunks/{styles-BQnsga7p.js → styles-CaABMoO1.js} +76 -43
- package/dist/chunks/styles-CaABMoO1.js.map +1 -0
- package/dist/chunks/{styles-D3fRphrO.js → styles-P_gmFAOi.js} +101 -21
- package/dist/chunks/styles-P_gmFAOi.js.map +1 -0
- package/dist/chunks/{styles-yed-BF5x3_Y5.js → styles-yed-Cs1nmrjn.js} +60 -20
- package/dist/chunks/styles-yed-Cs1nmrjn.js.map +1 -0
- package/dist/chunks/{text-CzJNFOS9.js → text-BuKQVMz2.js} +2 -2
- package/dist/chunks/{text-CzJNFOS9.js.map → text-BuKQVMz2.js.map} +1 -1
- package/dist/chunks/{writer-DMKvthQE.js → writer-DvHTl36J.js} +5 -4
- package/dist/chunks/writer-DvHTl36J.js.map +1 -0
- package/dist/csv.js +7 -5
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +5 -4
- package/dist/cx.js.map +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +2 -2
- package/dist/gexf.js +7 -5
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +16 -13
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +1181 -224
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +3 -3
- package/dist/json.js +1 -1
- package/dist/neo4j.js +6 -4
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/sources-cypher.d.ts +1 -0
- package/dist/sources-cypher.js +1236 -0
- package/dist/sources-cypher.js.map +1 -0
- package/dist/sources-ndex.d.ts +1 -0
- package/dist/sources-ndex.js +278 -0
- package/dist/sources-ndex.js.map +1 -0
- package/dist/sources-rest.d.ts +1 -0
- package/dist/sources-rest.js +1367 -0
- package/dist/sources-rest.js.map +1 -0
- package/dist/src/common/report.d.ts +6 -3
- package/dist/src/common/report.d.ts.map +1 -1
- package/dist/src/common/report.js +15 -9
- package/dist/src/common/report.js.map +1 -1
- package/dist/src/formats/cx/styles.d.ts.map +1 -1
- package/dist/src/formats/cx/styles.js +1 -0
- package/dist/src/formats/cx/styles.js.map +1 -1
- package/dist/src/formats/dot/styles.d.ts.map +1 -1
- package/dist/src/formats/dot/styles.js +3 -1
- package/dist/src/formats/dot/styles.js.map +1 -1
- package/dist/src/formats/gexf/styles.d.ts +29 -12
- package/dist/src/formats/gexf/styles.d.ts.map +1 -1
- package/dist/src/formats/gexf/styles.js +160 -31
- package/dist/src/formats/gexf/styles.js.map +1 -1
- package/dist/src/formats/gml/styles.d.ts.map +1 -1
- package/dist/src/formats/gml/styles.js +5 -4
- package/dist/src/formats/gml/styles.js.map +1 -1
- package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-plain.js +3 -3
- package/dist/src/formats/graphml/styles-plain.js.map +1 -1
- package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-yed.js +89 -19
- package/dist/src/formats/graphml/styles-yed.js.map +1 -1
- package/dist/src/formats/pajek/styles.d.ts.map +1 -1
- package/dist/src/formats/pajek/styles.js +1 -0
- package/dist/src/formats/pajek/styles.js.map +1 -1
- package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
- package/dist/src/formats/xgmml/styles.js +1 -0
- package/dist/src/formats/xgmml/styles.js.map +1 -1
- package/dist/src/index.d.ts +8 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts +173 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +196 -1
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sources/builtins.d.ts +11 -0
- package/dist/src/sources/builtins.d.ts.map +1 -0
- package/dist/src/sources/builtins.js +47 -0
- package/dist/src/sources/builtins.js.map +1 -0
- package/dist/src/sources/codes.d.ts +230 -0
- package/dist/src/sources/codes.d.ts.map +1 -0
- package/dist/src/sources/codes.js +58 -0
- package/dist/src/sources/codes.js.map +1 -0
- package/dist/src/sources/context.d.ts +112 -0
- package/dist/src/sources/context.d.ts.map +1 -0
- package/dist/src/sources/context.js +739 -0
- package/dist/src/sources/context.js.map +1 -0
- package/dist/src/sources/credentials.d.ts +179 -0
- package/dist/src/sources/credentials.d.ts.map +1 -0
- package/dist/src/sources/credentials.js +301 -0
- package/dist/src/sources/credentials.js.map +1 -0
- package/dist/src/sources/cypher/descriptor.d.ts +21 -0
- package/dist/src/sources/cypher/descriptor.d.ts.map +1 -0
- package/dist/src/sources/cypher/descriptor.js +119 -0
- package/dist/src/sources/cypher/descriptor.js.map +1 -0
- package/dist/src/sources/cypher/flatten.d.ts +72 -0
- package/dist/src/sources/cypher/flatten.d.ts.map +1 -0
- package/dist/src/sources/cypher/flatten.js +279 -0
- package/dist/src/sources/cypher/flatten.js.map +1 -0
- package/dist/src/sources/cypher/index.d.ts +33 -0
- package/dist/src/sources/cypher/index.d.ts.map +1 -0
- package/dist/src/sources/cypher/index.js +405 -0
- package/dist/src/sources/cypher/index.js.map +1 -0
- package/dist/src/sources/cypher/params.d.ts +40 -0
- package/dist/src/sources/cypher/params.d.ts.map +1 -0
- package/dist/src/sources/cypher/params.js +6 -0
- package/dist/src/sources/cypher/params.js.map +1 -0
- package/dist/src/sources/cypher/profiles.d.ts +44 -0
- package/dist/src/sources/cypher/profiles.d.ts.map +1 -0
- package/dist/src/sources/cypher/profiles.js +61 -0
- package/dist/src/sources/cypher/profiles.js.map +1 -0
- package/dist/src/sources/cypher/query-builder.d.ts +106 -0
- package/dist/src/sources/cypher/query-builder.d.ts.map +1 -0
- package/dist/src/sources/cypher/query-builder.js +236 -0
- package/dist/src/sources/cypher/query-builder.js.map +1 -0
- package/dist/src/sources/cypher/transports/bolt.d.ts +21 -0
- package/dist/src/sources/cypher/transports/bolt.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/bolt.js +185 -0
- package/dist/src/sources/cypher/transports/bolt.js.map +1 -0
- package/dist/src/sources/cypher/transports/neptune-analytics.d.ts +15 -0
- package/dist/src/sources/cypher/transports/neptune-analytics.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/neptune-analytics.js +38 -0
- package/dist/src/sources/cypher/transports/neptune-analytics.js.map +1 -0
- package/dist/src/sources/cypher/transports/neptune-https.d.ts +31 -0
- package/dist/src/sources/cypher/transports/neptune-https.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/neptune-https.js +104 -0
- package/dist/src/sources/cypher/transports/neptune-https.js.map +1 -0
- package/dist/src/sources/cypher/transports/query-api.d.ts +14 -0
- package/dist/src/sources/cypher/transports/query-api.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/query-api.js +80 -0
- package/dist/src/sources/cypher/transports/query-api.js.map +1 -0
- package/dist/src/sources/cypher/transports/transport.d.ts +78 -0
- package/dist/src/sources/cypher/transports/transport.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/transport.js +77 -0
- package/dist/src/sources/cypher/transports/transport.js.map +1 -0
- package/dist/src/sources/cypher/types-map.d.ts +91 -0
- package/dist/src/sources/cypher/types-map.d.ts.map +1 -0
- package/dist/src/sources/cypher/types-map.js +306 -0
- package/dist/src/sources/cypher/types-map.js.map +1 -0
- package/dist/src/sources/define.d.ts +47 -0
- package/dist/src/sources/define.d.ts.map +1 -0
- package/dist/src/sources/define.js +173 -0
- package/dist/src/sources/define.js.map +1 -0
- package/dist/src/sources/fail.d.ts +33 -0
- package/dist/src/sources/fail.d.ts.map +1 -0
- package/dist/src/sources/fail.js +49 -0
- package/dist/src/sources/fail.js.map +1 -0
- package/dist/src/sources/ids.d.ts +64 -0
- package/dist/src/sources/ids.d.ts.map +1 -0
- package/dist/src/sources/ids.js +64 -0
- package/dist/src/sources/ids.js.map +1 -0
- package/dist/src/sources/ndex/client.d.ts +31 -0
- package/dist/src/sources/ndex/client.d.ts.map +1 -0
- package/dist/src/sources/ndex/client.js +90 -0
- package/dist/src/sources/ndex/client.js.map +1 -0
- package/dist/src/sources/ndex/descriptor.d.ts +10 -0
- package/dist/src/sources/ndex/descriptor.d.ts.map +1 -0
- package/dist/src/sources/ndex/descriptor.js +55 -0
- package/dist/src/sources/ndex/descriptor.js.map +1 -0
- package/dist/src/sources/ndex/expand.d.ts +20 -0
- package/dist/src/sources/ndex/expand.d.ts.map +1 -0
- package/dist/src/sources/ndex/expand.js +87 -0
- package/dist/src/sources/ndex/expand.js.map +1 -0
- package/dist/src/sources/ndex/index.d.ts +25 -0
- package/dist/src/sources/ndex/index.d.ts.map +1 -0
- package/dist/src/sources/ndex/index.js +191 -0
- package/dist/src/sources/ndex/index.js.map +1 -0
- package/dist/src/sources/ndex/params.d.ts +17 -0
- package/dist/src/sources/ndex/params.d.ts.map +1 -0
- package/dist/src/sources/ndex/params.js +6 -0
- package/dist/src/sources/ndex/params.js.map +1 -0
- package/dist/src/sources/ndex/share-url.d.ts +40 -0
- package/dist/src/sources/ndex/share-url.d.ts.map +1 -0
- package/dist/src/sources/ndex/share-url.js +64 -0
- package/dist/src/sources/ndex/share-url.js.map +1 -0
- package/dist/src/sources/params.d.ts +28 -0
- package/dist/src/sources/params.d.ts.map +1 -0
- package/dist/src/sources/params.js +6 -0
- package/dist/src/sources/params.js.map +1 -0
- package/dist/src/sources/registry.d.ts +118 -0
- package/dist/src/sources/registry.d.ts.map +1 -0
- package/dist/src/sources/registry.js +193 -0
- package/dist/src/sources/registry.js.map +1 -0
- package/dist/src/sources/rest/descriptor.d.ts +16 -0
- package/dist/src/sources/rest/descriptor.d.ts.map +1 -0
- package/dist/src/sources/rest/descriptor.js +71 -0
- package/dist/src/sources/rest/descriptor.js.map +1 -0
- package/dist/src/sources/rest/index.d.ts +14 -0
- package/dist/src/sources/rest/index.d.ts.map +1 -0
- package/dist/src/sources/rest/index.js +13 -0
- package/dist/src/sources/rest/index.js.map +1 -0
- package/dist/src/sources/rest/mapping.d.ts +30 -0
- package/dist/src/sources/rest/mapping.d.ts.map +1 -0
- package/dist/src/sources/rest/mapping.js +362 -0
- package/dist/src/sources/rest/mapping.js.map +1 -0
- package/dist/src/sources/rest/openalex.d.ts +27 -0
- package/dist/src/sources/rest/openalex.d.ts.map +1 -0
- package/dist/src/sources/rest/openalex.js +269 -0
- package/dist/src/sources/rest/openalex.js.map +1 -0
- package/dist/src/sources/rest/paging.d.ts +53 -0
- package/dist/src/sources/rest/paging.d.ts.map +1 -0
- package/dist/src/sources/rest/paging.js +138 -0
- package/dist/src/sources/rest/paging.js.map +1 -0
- package/dist/src/sources/rest/params.d.ts +216 -0
- package/dist/src/sources/rest/params.d.ts.map +1 -0
- package/dist/src/sources/rest/params.js +7 -0
- package/dist/src/sources/rest/params.js.map +1 -0
- package/dist/src/sources/rest/records.d.ts +41 -0
- package/dist/src/sources/rest/records.d.ts.map +1 -0
- package/dist/src/sources/rest/records.js +240 -0
- package/dist/src/sources/rest/records.js.map +1 -0
- package/dist/src/sources/rest/samples/deps-dev.d.ts +10 -0
- package/dist/src/sources/rest/samples/deps-dev.d.ts.map +1 -0
- package/dist/src/sources/rest/samples/deps-dev.js +47 -0
- package/dist/src/sources/rest/samples/deps-dev.js.map +1 -0
- package/dist/src/sources/rest/samples/string.d.ts +9 -0
- package/dist/src/sources/rest/samples/string.d.ts.map +1 -0
- package/dist/src/sources/rest/samples/string.js +42 -0
- package/dist/src/sources/rest/samples/string.js.map +1 -0
- package/dist/src/sources/rest/selectors.d.ts +41 -0
- package/dist/src/sources/rest/selectors.d.ts.map +1 -0
- package/dist/src/sources/rest/selectors.js +81 -0
- package/dist/src/sources/rest/selectors.js.map +1 -0
- package/dist/src/sources/rest/source.d.ts +67 -0
- package/dist/src/sources/rest/source.d.ts.map +1 -0
- package/dist/src/sources/rest/source.js +635 -0
- package/dist/src/sources/rest/source.js.map +1 -0
- package/dist/src/sources/rest/templates.d.ts +38 -0
- package/dist/src/sources/rest/templates.d.ts.map +1 -0
- package/dist/src/sources/rest/templates.js +125 -0
- package/dist/src/sources/rest/templates.js.map +1 -0
- package/dist/src/sources/run.d.ts +93 -0
- package/dist/src/sources/run.d.ts.map +1 -0
- package/dist/src/sources/run.js +673 -0
- package/dist/src/sources/run.js.map +1 -0
- package/dist/src/sources/sha256.d.ts +12 -0
- package/dist/src/sources/sha256.d.ts.map +1 -0
- package/dist/src/sources/sha256.js +95 -0
- package/dist/src/sources/sha256.js.map +1 -0
- package/dist/src/sources/sigv4.d.ts +24 -0
- package/dist/src/sources/sigv4.d.ts.map +1 -0
- package/dist/src/sources/sigv4.js +182 -0
- package/dist/src/sources/sigv4.js.map +1 -0
- package/dist/src/sources/testing.d.ts +96 -0
- package/dist/src/sources/testing.d.ts.map +1 -0
- package/dist/src/sources/testing.js +138 -0
- package/dist/src/sources/testing.js.map +1 -0
- package/dist/src/sources/types.d.ts +665 -0
- package/dist/src/sources/types.d.ts.map +1 -0
- package/dist/src/sources/types.js +10 -0
- package/dist/src/sources/types.js.map +1 -0
- package/dist/src/styles/canon/enums.d.ts.map +1 -1
- package/dist/src/styles/canon/enums.js +1 -0
- package/dist/src/styles/canon/enums.js.map +1 -1
- package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
- package/dist/src/styles/cyjs/cascade.js +68 -2
- package/dist/src/styles/cyjs/cascade.js.map +1 -1
- package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
- package/dist/src/styles/cyjs/defaults-table.js +2 -0
- package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
- package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
- package/dist/src/styles/cyjs/emit.js +18 -7
- package/dist/src/styles/cyjs/emit.js.map +1 -1
- package/dist/src/styles/cyjs/mappers.d.ts +4 -1
- package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
- package/dist/src/styles/cyjs/mappers.js +2 -0
- package/dist/src/styles/cyjs/mappers.js.map +1 -1
- package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/emit.js +59 -7
- package/dist/src/styles/cytoscape/emit.js.map +1 -1
- package/dist/src/styles/cytoscape/lexicon.d.ts +6 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/lexicon.js +26 -2
- package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
- package/dist/src/styles/cytoscape/resolve.d.ts +4 -1
- package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/resolve.js +10 -6
- package/dist/src/styles/cytoscape/resolve.js.map +1 -1
- package/dist/src/styles/cytoscape/translate.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/translate.js +10 -10
- package/dist/src/styles/cytoscape/translate.js.map +1 -1
- package/dist/src/styles/defaults.d.ts +30 -0
- package/dist/src/styles/defaults.d.ts.map +1 -1
- package/dist/src/styles/defaults.js +45 -4
- package/dist/src/styles/defaults.js.map +1 -1
- package/dist/src/styles/io/block.d.ts.map +1 -1
- package/dist/src/styles/io/block.js +9 -0
- package/dist/src/styles/io/block.js.map +1 -1
- package/dist/src/styles/io/writer.d.ts.map +1 -1
- package/dist/src/styles/io/writer.js +7 -3
- package/dist/src/styles/io/writer.js.map +1 -1
- package/dist/src/styles/plan/resolve.d.ts +2 -1
- package/dist/src/styles/plan/resolve.d.ts.map +1 -1
- package/dist/src/styles/plan/resolve.js +13 -2
- package/dist/src/styles/plan/resolve.js.map +1 -1
- package/dist/src/styles/types.d.ts +19 -2
- package/dist/src/styles/types.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.js +15 -1
- package/dist/src/styles/vocabulary.js.map +1 -1
- package/dist/src/types.d.ts +19 -5
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/styles.js +11 -11
- package/dist/xgmml.js +3 -3
- package/docs/samples/people.json +6 -0
- package/package.json +29 -4
- package/src/common/report.ts +27 -7
- package/src/formats/cx/styles.ts +1 -0
- package/src/formats/dot/styles.ts +3 -1
- package/src/formats/gexf/styles.ts +185 -37
- package/src/formats/gml/styles.ts +5 -4
- package/src/formats/graphml/styles-plain.ts +3 -9
- package/src/formats/graphml/styles-yed.ts +93 -20
- package/src/formats/pajek/styles.ts +1 -0
- package/src/formats/xgmml/styles.ts +1 -0
- package/src/index.ts +90 -0
- package/src/registry.ts +326 -1
- package/src/sources/builtins.ts +56 -0
- package/src/sources/codes.ts +235 -0
- package/src/sources/context.ts +893 -0
- package/src/sources/credentials.ts +409 -0
- package/src/sources/cypher/descriptor.ts +125 -0
- package/src/sources/cypher/flatten.ts +323 -0
- package/src/sources/cypher/index.ts +498 -0
- package/src/sources/cypher/params.ts +41 -0
- package/src/sources/cypher/profiles.ts +78 -0
- package/src/sources/cypher/query-builder.ts +294 -0
- package/src/sources/cypher/transports/bolt.ts +228 -0
- package/src/sources/cypher/transports/neptune-analytics.ts +41 -0
- package/src/sources/cypher/transports/neptune-https.ts +122 -0
- package/src/sources/cypher/transports/query-api.ts +100 -0
- package/src/sources/cypher/transports/transport.ts +139 -0
- package/src/sources/cypher/types-map.ts +418 -0
- package/src/sources/define.ts +195 -0
- package/src/sources/fail.ts +70 -0
- package/src/sources/ids.ts +74 -0
- package/src/sources/ndex/client.ts +102 -0
- package/src/sources/ndex/descriptor.ts +64 -0
- package/src/sources/ndex/expand.ts +100 -0
- package/src/sources/ndex/index.ts +235 -0
- package/src/sources/ndex/params.ts +17 -0
- package/src/sources/ndex/share-url.ts +84 -0
- package/src/sources/params.ts +29 -0
- package/src/sources/registry.ts +325 -0
- package/src/sources/rest/descriptor.ts +74 -0
- package/src/sources/rest/index.ts +22 -0
- package/src/sources/rest/mapping.ts +401 -0
- package/src/sources/rest/openalex.ts +288 -0
- package/src/sources/rest/paging.ts +180 -0
- package/src/sources/rest/params.ts +243 -0
- package/src/sources/rest/records.ts +289 -0
- package/src/sources/rest/samples/deps-dev.ts +49 -0
- package/src/sources/rest/samples/string.ts +44 -0
- package/src/sources/rest/selectors.ts +91 -0
- package/src/sources/rest/source.ts +760 -0
- package/src/sources/rest/templates.ts +151 -0
- package/src/sources/run.ts +793 -0
- package/src/sources/sha256.ts +99 -0
- package/src/sources/sigv4.ts +207 -0
- package/src/sources/testing.ts +210 -0
- package/src/sources/types.ts +741 -0
- package/src/styles/canon/enums.ts +1 -0
- package/src/styles/cyjs/cascade.ts +81 -2
- package/src/styles/cyjs/defaults-table.ts +2 -0
- package/src/styles/cyjs/emit.ts +18 -7
- package/src/styles/cyjs/mappers.ts +6 -1
- package/src/styles/cytoscape/emit.ts +61 -7
- package/src/styles/cytoscape/lexicon.ts +28 -2
- package/src/styles/cytoscape/resolve.ts +22 -6
- package/src/styles/cytoscape/translate.ts +11 -11
- package/src/styles/defaults.ts +93 -4
- package/src/styles/io/block.ts +10 -0
- package/src/styles/io/writer.ts +8 -3
- package/src/styles/plan/resolve.ts +14 -2
- package/src/styles/types.ts +28 -2
- package/src/styles/vocabulary.ts +15 -1
- package/src/types.ts +19 -5
- package/dist/chunks/block-DiGq58c3.js.map +0 -1
- package/dist/chunks/emit-CwU8cUmG.js.map +0 -1
- package/dist/chunks/export-BvqAXCKh.js.map +0 -1
- package/dist/chunks/format-BpQBx8MZ.js.map +0 -1
- package/dist/chunks/importer-BSvfrX_h.js.map +0 -1
- package/dist/chunks/importer-CMmeMWlC.js.map +0 -1
- package/dist/chunks/importer-COTK9Tsl.js.map +0 -1
- package/dist/chunks/importer-DiZRmOQG.js.map +0 -1
- package/dist/chunks/importer-e6LGpqHB.js.map +0 -1
- package/dist/chunks/lexicon-CT69Kd87.js.map +0 -1
- package/dist/chunks/styles-BQnsga7p.js.map +0 -1
- package/dist/chunks/styles-D3fRphrO.js.map +0 -1
- package/dist/chunks/styles-yed-BF5x3_Y5.js.map +0 -1
- package/dist/chunks/writer-DMKvthQE.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"importer-COTK9Tsl.js","sources":["../../src/formats/dot/names.ts","../../src/formats/dot/styles.ts","../../src/formats/dot/exporter.ts","../../src/formats/dot/positions.ts","../../src/formats/dot/tokenizer.ts","../../src/formats/dot/importer.ts"],"sourcesContent":["/**\n * The names the DOT importer and exporter share: the format name, the column origin, the\n * format-owned columns (design section 5.6: `graphty.` prefix) and the attribute names the format\n * gives a fixed meaning to.\n */\n\nimport { type ColumnOriginInput } from \"@graphty/graph-format\";\n\n/**\n * The format name.\n * @category Plugin helpers\n */\nexport const DOT_FORMAT = \"dot\";\n\n/**\n * The origin recorded on every column the importer declares.\n * @category Plugin helpers\n */\nexport const DOT_ORIGIN: ColumnOriginInput = Object.freeze({ format: DOT_FORMAT });\n\n/**\n * The bool node column marking a cluster's container node.\n * @category Plugin helpers\n */\nexport const CLUSTER_COLUMN = \"graphty.cluster\";\n\n/**\n * The u32 node column (role parent, refersTo node) holding a member's cluster.\n * @category Plugin helpers\n */\nexport const PARENT_COLUMN = \"graphty.parent\";\n\n/**\n * The string edge column (role sourcePort) holding an edge's tail port.\n * @category Plugin helpers\n */\nexport const SOURCE_PORT_COLUMN = \"graphty.sourcePort\";\n\n/**\n * The string edge column (role targetPort) holding an edge's head port.\n * @category Plugin helpers\n */\nexport const TARGET_PORT_COLUMN = \"graphty.targetPort\";\n\n/**\n * The attribute that is the display label (kept as text with role label).\n * @category Plugin helpers\n */\nexport const LABEL_ATTRIBUTE = \"label\";\n\n/**\n * The node attribute holding a position, mapped to the position role column (design section 5.2).\n * @category Plugin helpers\n */\nexport const POS_ATTRIBUTE = \"pos\";\n\n/**\n * The node position column when the import keeps `pos` as text too (the `keepPositionSource` option).\n * @category Plugin helpers\n */\nexport const POSITION_COLUMN = \"graphty.position\";\n\n/**\n * The edge attribute cgraph uses as an edge's identity within its endpoints, mapped to the edge id role.\n * @category Plugin helpers\n */\nexport const KEY_ATTRIBUTE = \"key\";\n\n/**\n * The node attribute a `!` suffix of `pos` sets (Graphviz's own spelling of a pinned position).\n * @category Plugin helpers\n */\nexport const PIN_ATTRIBUTE = \"pin\";\n\n/**\n * The key under meta.extra holding the format's graph flags (`{ strict: true }`).\n * @category Plugin helpers\n */\nexport const DOT_META_KEY = \"dot\";\n","/**\n * DOT styles: every node's, cluster's and edge's attributes read the way Graphviz draws them, with Graphviz's\n * defaults beneath, and a graph's styles written back as Graphviz attributes.\n *\n * Reading follows Graphviz's own rules, measured against `dot` 2.43:\n *\n * - Labels: a node with no `label` shows its name (`\\N`), as one tool-default rule over a style column holding each\n * node's name. Escapes are applied in Graphviz's two passes; an HTML label shows its text, a record label its\n * fields, and a `point` draws no label.\n * - Fills: `point` is always filled; `filled` and `radial` fill any shape, `striped` only boxes, `wedged` only\n * ellipses; an empty `fillcolor` falls back to `color`, then light gray.\n * - Colors through Graphviz's color rules: a `colorscheme` applies to its own object only, an unknown color is black,\n * `none` and `invis` are transparent, and a color list is read as Graphviz draws it for that use.\n * - Outlines: `plain`, `plaintext` and `none` draw none. `setlinewidth(n)` is a pen width, `bold` a width of 2.\n * - Sizes: exact with `fixedsize`, an empty label or a `point`; otherwise minimums Graphviz grows to fit the label,\n * carried and noted as `W_STYLE_SIZE_MINIMUM`.\n * - Arrows per `dir`, `arrowhead` and `arrowtail`, with the graph's kind deciding the default: a target arrow on\n * directed edges, as one tool-default rule.\n * - A cluster's container node holds the cluster's attributes: its fill (`bgcolor`, or the fill when `filled`) and\n * outline (`pencolor`, else `color`) are the cluster's, it is drawn as a rectangle, and it has no label by default.\n * Cluster membership is offered to the planner, so clusters whose nodes share a fill become one rule.\n *\n * Writing: Graphviz attributes from what graphty draws (`fillcolor` with `style=filled`, `width` and `height` with\n * `fixedsize=true`, `penwidth`, `style`, arrows with `dir`, font attributes, graph `bgcolor`) replace every style\n * attribute the reader reads. The `graphty.styles` block is the quoted graph attribute `\"graphty.styles\"`, and the\n * per-element values its rules read are quoted `\"graphty.style.<target>.<key>\"` attributes.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { isWritableDotText } from \"../../common/escape.js\";\nimport { inferTextDtype } from \"../../common/text.js\";\nimport { canonColor, colorOpacity } from \"../../styles/canon/color.js\";\nimport { canonEnum } from \"../../styles/canon/enums.js\";\nimport { canonNumber, DOT_POINTS_PER_INCH, num6 } from \"../../styles/canon/number.js\";\nimport { type CanonSite, MAX_STYLE_VALUE_LENGTH, noteAt } from \"../../styles/canon/site.js\";\nimport { type DotEscapeNames, dotLabelText, htmlLabelText, recordLabelText } from \"../../styles/canon/text.js\";\nimport { STYLE_ISSUE } from \"../../styles/codes.js\";\nimport { toolDefaults } from \"../../styles/defaults.js\";\nimport { StyleApproximations } from \"../../styles/io/approximations.js\";\nimport {\n blockStyles,\n parseStyleBlock,\n STYLE_BLOCK_NAME,\n styleBlockLosses,\n writeStyleBlock,\n} from \"../../styles/io/block.js\";\nimport { type ExporterStyleInput, sharedInExportCall } from \"../../styles/io/writer.js\";\nimport { StyleNotes } from \"../../styles/notes.js\";\nimport { styleFingerprint } from \"../../styles/plan/features.js\";\nimport { plainCell, resolveStyles } from \"../../styles/plan/resolve.js\";\nimport type {\n ImporterStyles,\n StyleColumn,\n StyleFeature,\n StyleReadContext,\n StyleRule,\n StyleTarget,\n StyleValue,\n StyleWriteCapabilities,\n} from \"../../styles/types.js\";\nimport type { LossNote } from \"../../types.js\";\nimport { type ValueColumns, valueColumns } from \"../graphml/styles-yed.js\";\nimport { CLUSTER_COLUMN, LABEL_ATTRIBUTE } from \"./names.js\";\n\n/**\n * The graph attribute holding the `graphty.styles` block of a DOT file graphty wrote.\n * @category Built-in formats\n */\nexport { STYLE_BLOCK_NAME as DOT_STYLE_BLOCK_ATTRIBUTE } from \"../../styles/io/block.js\";\n\n/**\n * What the DOT writer holds natively: Graphviz's node, cluster and edge attributes, and the graph's `bgcolor`. The\n * `graphty.styles` block and the per-element values its rules read are quoted attributes.\n * @category Built-in formats\n */\nexport const DOT_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({\n node: Object.freeze([\n \"fill\",\n \"fillOpacity\",\n \"borderColor\",\n \"borderWidth\",\n \"borderStyle\",\n \"shape\",\n \"width\",\n \"height\",\n \"label\",\n \"labelColor\",\n \"labelSize\",\n \"labelFont\",\n \"tooltip\",\n \"visible\",\n ] as const),\n edge: Object.freeze([\n \"color\",\n \"opacity\",\n \"width\",\n \"lineStyle\",\n \"sourceArrow\",\n \"targetArrow\",\n \"arrowSize\",\n \"label\",\n \"sourceLabel\",\n \"targetLabel\",\n \"labelColor\",\n \"labelSize\",\n \"labelFont\",\n \"tooltip\",\n \"visible\",\n ] as const),\n graph: Object.freeze([\"background\"] as const),\n block: \"native\",\n});\n\n/** The style column holding the name each node shows when it has no label (Graphviz's `\\N`). */\nconst NAME_KEY = \"name\";\n\n/** The style column marking directed edges, which Graphviz draws with an arrow at the target. */\nconst DIRECTED_KEY = \"directed\";\n\n/** The style column marking a cluster's container node. */\nconst CLUSTER_KEY = \"cluster\";\n\n/** Every node and cluster attribute the reader reads; the writer replaces them all. */\nconst NODE_ATTRIBUTES: readonly string[] = [\n \"colorscheme\",\n \"color\",\n \"fillcolor\",\n \"bgcolor\",\n \"pencolor\",\n \"style\",\n \"shape\",\n \"width\",\n \"height\",\n \"fixedsize\",\n \"regular\",\n \"penwidth\",\n \"fontname\",\n \"fontsize\",\n \"fontcolor\",\n \"tooltip\",\n];\n\n/** Every edge attribute the reader reads; the writer replaces them all. */\nconst EDGE_ATTRIBUTES: readonly string[] = [\n \"colorscheme\",\n \"color\",\n \"style\",\n \"penwidth\",\n \"fontname\",\n \"fontsize\",\n \"fontcolor\",\n \"tooltip\",\n \"edgetooltip\",\n \"arrowhead\",\n \"arrowtail\",\n \"dir\",\n \"arrowsize\",\n \"headlabel\",\n \"taillabel\",\n];\n\n/** Attributes the reader notes as not carried. */\nconst NOTED_ATTRIBUTES: readonly string[] = [\"peripheries\", \"xlabel\"];\n\nconst CIRCLE_LIKE: ReadonlySet<string> = new Set([\"circle\", \"doublecircle\", \"mcircle\", \"square\", \"msquare\"]);\nconst BOX_LIKE: ReadonlySet<string> = new Set([\"box\", \"rect\", \"rectangle\", \"square\"]);\nconst ELLIPSE_LIKE: ReadonlySet<string> = new Set([\"\", \"ellipse\", \"oval\", \"circle\"]);\nconst NO_OUTLINE: ReadonlySet<string> = new Set([\"plain\", \"plaintext\", \"none\"]);\nconst RECORD: ReadonlySet<string> = new Set([\"record\", \"mrecord\"]);\nconst TRUE_TEXTS: ReadonlySet<string> = new Set([\"true\", \"yes\", \"shape\"]);\n\n/** A point's size when the file gives none: 0.05 inch. */\nconst POINT_SIZE = 0.05;\n\n/** The size in inches Graphviz gives a circle, a square or a `regular` node that states none. */\nconst REGULAR_SIZE = 0.5;\n\n/** One attribute of an element as text, or null when it is unset. */\ntype Attr = (name: string) => string | null;\n\n/** One element's canonical value of a property; null leaves it unset. */\ntype Put = (property: string, value: StyleValue | null) => void;\n\n/** Where a value of an element was read, by property. */\ntype At = (property: string) => CanonSite;\n\n/** What a node's label escapes and its defaults depend on. */\ninterface NodeContext {\n /** The node's name (its id as text). */\n readonly name: string;\n /** The graph's name, for `\\G`. */\n readonly graph: string;\n /** Whether the node is a cluster's container. */\n readonly cluster: boolean;\n /** The HTML strings of the file, for Graphviz's shared string pool. */\n readonly html: ReadonlySet<string>;\n}\n\n/** What an edge's label escapes depend on. */\ninterface EdgeContext {\n /** The names `\\E`, `\\T`, `\\H` and `\\G` stand for. */\n readonly names: DotEscapeNames;\n /** Whether the edge is directed. */\n readonly directed: boolean;\n /** The HTML strings of the file. */\n readonly html: ReadonlySet<string>;\n}\n\n/**\n * Whether a text is an HTML string (balanced angle brackets around the whole text), which graph-io keeps with its\n * brackets and DOT writes bare as `<...>`.\n * @param text - the text\n * @returns true for an HTML string\n */\nexport function isHtmlString(text: string): boolean {\n if (text.length < 2 || !text.startsWith(\"<\") || !text.endsWith(\">\")) {\n return false;\n }\n let depth = 0;\n for (let i = 0; i < text.length; i++) {\n const c = text.codePointAt(i);\n if (c === 0x3c) {\n depth++;\n } else if (c === 0x3e) {\n depth--;\n if (depth === 0 && i !== text.length - 1) {\n return false;\n }\n }\n }\n return depth === 0;\n}\n\n/**\n * The value of an attribute cell as text, or null when it is unset.\n * @param table - the node, edge or graph table\n * @param name - the attribute\n * @param i - the row\n * @returns the text\n */\nfunction cellText(table: GraphSnapshot[\"nodes\"], name: string, i: number): string | null {\n if (!table.has(name)) {\n return null;\n }\n const v = plainCell(table.value(name, i));\n if (typeof v === \"string\") {\n return v;\n }\n return typeof v === \"number\" || typeof v === \"boolean\" ? String(v) : null;\n}\n\n/**\n * A text, or null when it is empty.\n * @param v - the text\n * @returns the text\n */\nfunction nonEmpty(v: string | null): string | null {\n return v === null || v === \"\" ? null : v;\n}\n\n/**\n * The tokens of a `style` value: split on commas, lowercased, blanks before a token skipped (blanks after it make it\n * a token Graphviz does not know, so they are kept).\n * @param raw - the value\n * @param at - where it was read\n * @returns the tokens\n */\nfunction styleTokens(raw: string | null, at: CanonSite): string[] {\n if (raw === null) {\n return [];\n }\n if (raw.length > MAX_STYLE_VALUE_LENGTH) {\n noteAt(at, STYLE_ISSUE.VALUE_TOO_LONG, `${String(raw.length)} characters`);\n return [];\n }\n return raw\n .toLowerCase()\n .split(\",\")\n .map((t) => t.replace(/^[ \\t\\r\\n]+/, \"\"))\n .filter((t) => t !== \"\");\n}\n\n/**\n * The pen width a style's `setlinewidth(n)` gives, or null.\n * @param tokens - the style's tokens\n * @returns the width's text\n */\nfunction setLineWidth(tokens: readonly string[]): string | null {\n for (const t of tokens) {\n if (t.startsWith(\"setlinewidth(\") && t.endsWith(\")\")) {\n return t.slice(\"setlinewidth(\".length, -1).trim();\n }\n }\n return null;\n}\n\n/**\n * Whether an attribute is one of Graphviz's true spellings (`true`, `yes`, a non-zero number; `fixedsize` also\n * takes `shape`).\n * @param raw - the value\n * @returns true when set\n */\nfunction isTrue(raw: string | null): boolean {\n if (raw === null) {\n return false;\n }\n const t = raw.trim().toLowerCase();\n return TRUE_TEXTS.has(t) || (/^-?\\d+$/.test(t) && Number(t) !== 0);\n}\n\n/**\n * The text a label draws: an HTML label's text (also for a quoted label equal to an HTML label's content elsewhere\n * in the file, since Graphviz 2.43 marks HTML on a pooled string), a record's fields, the escapes applied.\n * @param raw - the label as the file gives it\n * @param names - what the escapes stand for\n * @param html - the file's HTML strings\n * @param record - whether the node is a record\n * @param at - where it was read\n * @returns the text\n */\nfunction labelText(\n raw: string,\n names: DotEscapeNames,\n html: ReadonlySet<string>,\n record: boolean,\n at: CanonSite,\n): string {\n if (isHtmlString(raw)) {\n return htmlLabelText(raw, at);\n }\n if (html.has(`<${raw}>`)) {\n return htmlLabelText(`<${raw}>`, at);\n }\n return dotLabelText(record ? recordLabelText(raw, at) : raw, names, at);\n}\n\n/**\n * Reads a color into a property and its alpha into the property's opacity.\n * @param raw - the color\n * @param scheme - the object's color scheme\n * @param use - how Graphviz draws it\n * @param property - the color property\n * @param opacity - its opacity property, or null when the alpha is dropped\n * @param put - receives the values\n * @param at - the sites\n * @returns the alpha, or null when the color is absent\n */\nfunction readColor(\n raw: string | null,\n scheme: string | null,\n use: \"line\" | \"fill\" | \"edge\",\n property: string,\n opacity: string | null,\n put: Put,\n at: At,\n): number | null {\n if (raw === null) {\n return null;\n }\n const c = canonColor(raw, \"graphviz\", at(property), { scheme, use });\n if (c === null) {\n return null;\n }\n put(property, c.color);\n if (opacity !== null) {\n put(opacity, c.alpha);\n } else if (c.alpha > 0 || property !== \"borderColor\") {\n // a transparent outline is no outline (the caller sets its width to 0); any other alpha is dropped, noted\n colorOpacity(c, null, at(property), false);\n }\n return c.alpha;\n}\n\n/**\n * A length in points as the shortest inches (at least 6 significant digits) that read back as the same length.\n * @param points - the length\n * @returns the inches\n */\nfunction inchesOf(points: number): number {\n const want = num6(points);\n for (let digits = 6; digits < 17; digits++) {\n const inches = Number((points / DOT_POINTS_PER_INCH).toPrecision(digits));\n if (num6(inches * DOT_POINTS_PER_INCH) === want) {\n return inches + 0;\n }\n }\n return points / DOT_POINTS_PER_INCH;\n}\n\n/**\n * A size attribute in inches, or null with a note when it is not a non-negative number.\n * @param raw - the value\n * @param at - where it was read\n * @returns the inches\n */\nfunction inches(raw: string | null, at: CanonSite): number | null {\n if (raw === null) {\n return null;\n }\n const v = raw.trim() === \"\" ? Number.NaN : Number(raw);\n if (!Number.isFinite(v) || v < 0) {\n noteAt(at, STYLE_ISSUE.BAD_VALUE, raw.slice(0, MAX_STYLE_VALUE_LENGTH));\n return null;\n }\n return v;\n}\n\n/**\n * Reads the attributes every element shares: font, tooltip, visibility.\n * @param get - the element's attributes\n * @param tokens - its style tokens\n * @param scheme - its color scheme\n * @param names - what the tooltip's escapes stand for\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readCommon(\n get: Attr,\n tokens: readonly string[],\n scheme: string | null,\n names: DotEscapeNames,\n put: Put,\n at: At,\n): void {\n if (tokens.includes(\"invis\")) {\n put(\"visible\", false);\n }\n readColor(nonEmpty(get(\"fontcolor\")), scheme, \"line\", \"labelColor\", null, put, at);\n const size = get(\"fontsize\");\n put(\"labelSize\", size === null ? null : canonNumber(size, at(\"labelSize\")));\n const font = get(\"fontname\");\n if (font !== null && font.length <= MAX_STYLE_VALUE_LENGTH) {\n put(\"labelFont\", font);\n }\n const tip = get(\"tooltip\") ?? get(\"edgetooltip\");\n if (tip !== null) {\n put(\"tooltip\", dotLabelText(tip, names, at(\"tooltip\")));\n }\n}\n\n/** What the parts of readNode() read: the node's attributes and what is worked out from them once. */\ninterface NodeRead {\n readonly get: Attr;\n readonly cx: NodeContext;\n readonly put: Put;\n readonly at: At;\n readonly tokens: readonly string[];\n /** The shape as written, or null. */\n readonly shapeRaw: string | null;\n /** The shape, lowercase (\"\" when none is written). */\n readonly shape: string;\n /** Whether it is a point (never a cluster). */\n readonly point: boolean;\n readonly scheme: string | null;\n readonly color: string | null;\n}\n\n/**\n * Reads one node, or one cluster's container, the way Graphviz draws it.\n * @param get - its attributes\n * @param cx - its name and kind\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readNode(get: Attr, cx: NodeContext, put: Put, at: At): void {\n const tokens = styleTokens(get(\"style\"), at(\"visible\"));\n const shapeRaw = nonEmpty(get(\"shape\"));\n const shape = (shapeRaw ?? \"\").toLowerCase();\n const n: NodeRead = {\n get,\n cx,\n put,\n at,\n tokens,\n shapeRaw,\n shape,\n point: !cx.cluster && shape === \"point\",\n scheme: get(\"colorscheme\"),\n color: nonEmpty(get(\"color\")),\n };\n // in a node's label \\E stands for nothing (measured with dot 2.43); \\T and \\H stand for their letters\n const names: DotEscapeNames = cx.cluster ? { graph: cx.name } : { node: cx.name, graph: cx.graph, edge: \"\" };\n readCommon(get, tokens, n.scheme, names, put, at);\n if (cx.cluster) {\n readClusterFill(n);\n } else {\n readNodeFill(n);\n }\n readNodeOutline(n);\n readNodeShape(n);\n // label: a node shows its name unless it has a label (the tool-default rule); a cluster and a point show none\n const label = n.point ? null : get(LABEL_ATTRIBUTE);\n if (label !== null) {\n put(\"label\", labelText(label, names, cx.html, RECORD.has(shape), at(\"label\")));\n }\n if (!cx.cluster) {\n readSize(get, shape, n.point, label ?? (n.point ? null : cx.name), put, at);\n }\n if (Number(get(\"peripheries\")) > 1 || nonEmpty(get(\"xlabel\")) !== null) {\n noteAt(at(\"label\"), STYLE_ISSUE.NOT_CARRIED, nonEmpty(get(\"xlabel\")) === null ? \"peripheries\" : \"xlabel\");\n }\n}\n\n/**\n * Reads a cluster's fill: its fill color when filled, else its background.\n * @param n - the cluster\n */\nfunction readClusterFill(n: NodeRead): void {\n const { get, tokens } = n;\n const filled = tokens.includes(\"filled\") || tokens.includes(\"radial\") || tokens.includes(\"striped\");\n const bg = nonEmpty(get(\"bgcolor\"));\n const raw = filled ? (nonEmpty(get(\"fillcolor\")) ?? n.color ?? bg ?? \"lightgrey\") : bg;\n readColor(raw, n.scheme, \"fill\", \"fill\", \"fillOpacity\", n.put, n.at);\n}\n\n/**\n * Reads a node's fill: a point is always filled; a striped fill fills a box and a wedged one an ellipse only.\n * @param n - the node\n */\nfunction readNodeFill(n: NodeRead): void {\n const { shape, point } = n;\n const fillcolor = nonEmpty(n.get(\"fillcolor\"));\n const filled =\n point ||\n n.tokens.some(\n (t) =>\n t === \"filled\" ||\n t === \"radial\" ||\n (t === \"striped\" && BOX_LIKE.has(shape)) ||\n (t === \"wedged\" && ELLIPSE_LIKE.has(shape)),\n );\n if (filled) {\n const raw = fillcolor ?? n.color ?? (point ? \"black\" : \"lightgrey\");\n readColor(raw, n.scheme, \"fill\", \"fill\", \"fillOpacity\", n.put, n.at);\n } else if (fillcolor !== null) {\n noteAt(n.at(\"fill\"), STYLE_ISSUE.UNFILLED, fillcolor.slice(0, MAX_STYLE_VALUE_LENGTH));\n }\n}\n\n/**\n * Reads a node's or cluster's outline: its color, width and dashes.\n * @param n - the node\n */\nfunction readNodeOutline(n: NodeRead): void {\n const { get, cx, put, at, tokens } = n;\n if (!cx.cluster && NO_OUTLINE.has(n.shape)) {\n put(\"borderWidth\", 0);\n } else {\n const outline = cx.cluster ? (nonEmpty(get(\"pencolor\")) ?? n.color) : n.color;\n const alpha = readColor(outline, n.scheme, \"line\", \"borderColor\", null, put, at);\n const width = nonEmpty(get(\"penwidth\")) ?? setLineWidth(tokens);\n if (alpha === 0) {\n put(\"borderWidth\", 0);\n } else if (width !== null) {\n put(\"borderWidth\", penWidth(width, get(\"penwidth\") !== null, at(\"borderWidth\")));\n } else if (tokens.includes(\"bold\")) {\n put(\"borderWidth\", 2);\n }\n }\n if (tokens.includes(\"dashed\")) {\n put(\"borderStyle\", \"dashed\");\n } else if (tokens.includes(\"dotted\")) {\n put(\"borderStyle\", \"dotted\");\n }\n}\n\n/**\n * Reads a node's or cluster's shape: a cluster is a rectangle, rounded by the `rounded` style as a box is.\n * @param n - the node\n */\nfunction readNodeShape(n: NodeRead): void {\n const rounded = n.tokens.includes(\"rounded\");\n if (n.cx.cluster) {\n n.put(\"shape\", rounded ? \"round-rectangle\" : \"rectangle\");\n } else if (n.shapeRaw !== null) {\n n.put(\n \"shape\",\n rounded && BOX_LIKE.has(n.shape)\n ? \"round-rectangle\"\n : canonEnum(\"shape\", n.shapeRaw, \"graphviz\", n.at(\"shape\")),\n );\n }\n}\n\n/**\n * A pen width as Graphviz draws it: a negative `penwidth` is raised to 0, its minimum, and noted.\n * @param raw - the `penwidth` or `setlinewidth` value\n * @param attribute - whether it is the `penwidth` attribute\n * @param site - where it was read\n * @returns the width, or null when it does not parse\n */\nfunction penWidth(raw: string, attribute: boolean, site: CanonSite): number | null {\n const value = Number(raw.trim());\n if (attribute && Number.isFinite(value) && value < 0) {\n noteAt(site, STYLE_ISSUE.BAD_VALUE, raw.slice(0, MAX_STYLE_VALUE_LENGTH));\n return 0;\n }\n return canonNumber(raw, site);\n}\n\n/**\n * Reads a node's width and height: exact where Graphviz draws them exactly (`fixedsize`, an empty label that is not\n * a record's, a point), otherwise minimums it grows to fit the label, noted.\n * @param get - the node's attributes\n * @param shape - its shape, lowercase\n * @param point - whether it is a point\n * @param label - the label it shows, or null\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readSize(get: Attr, shape: string, point: boolean, label: string | null, put: Put, at: At): void {\n let w = inches(get(\"width\"), at(\"width\"));\n let h = inches(get(\"height\"), at(\"height\"));\n const same = point || CIRCLE_LIKE.has(shape) || isTrue(get(\"regular\"));\n if (shape === \"plain\") {\n // plain is plaintext with its width and height forced to 0: exactly the size of its label\n w = h = 0;\n } else if (w === null && h === null) {\n if (point) {\n put(\"width\", num6(POINT_SIZE * DOT_POINTS_PER_INCH));\n put(\"height\", num6(POINT_SIZE * DOT_POINTS_PER_INCH));\n return;\n }\n if (!same) {\n return;\n }\n // a regular shape takes the smaller of the default width and height (0.5 inch) for both\n w = h = REGULAR_SIZE;\n }\n let ww = w;\n let hh = h;\n if (point) {\n ww = hh = Math.min(w ?? Infinity, h ?? Infinity);\n } else if (same) {\n ww = hh = Math.max(w ?? 0, h ?? 0);\n }\n const exact = point || isTrue(get(\"fixedsize\")) || (label === \"\" && !RECORD.has(shape));\n if (!exact) {\n noteAt(at(\"width\"), STYLE_ISSUE.SIZE_MINIMUM, \"grows to fit its label\");\n }\n put(\"width\", ww === null ? null : canonNumber(ww, at(\"width\"), DOT_POINTS_PER_INCH));\n put(\"height\", hh === null ? null : canonNumber(hh, at(\"height\"), DOT_POINTS_PER_INCH));\n}\n\n/**\n * Reads one edge the way Graphviz draws it.\n * @param get - its attributes\n * @param cx - its names and direction\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readEdge(get: Attr, cx: EdgeContext, put: Put, at: At): void {\n const tokens = styleTokens(get(\"style\"), at(\"visible\"));\n const scheme = get(\"colorscheme\");\n readCommon(get, tokens, scheme, cx.names, put, at);\n readColor(nonEmpty(get(\"color\")), scheme, \"edge\", \"color\", \"opacity\", put, at);\n readEdgeLine(get, tokens, put, at);\n readEdgeArrows(get, cx, put, at);\n for (const [attribute, property] of [\n [LABEL_ATTRIBUTE, \"label\"],\n [\"headlabel\", \"targetLabel\"],\n [\"taillabel\", \"sourceLabel\"],\n ] as const) {\n const raw = get(attribute);\n if (raw !== null) {\n put(property, labelText(raw, cx.names, cx.html, false, at(property)));\n }\n }\n if (nonEmpty(get(\"xlabel\")) !== null) {\n noteAt(at(\"label\"), STYLE_ISSUE.NOT_CARRIED, \"xlabel\");\n }\n}\n\n/**\n * Reads an edge's line: its width and dashes.\n * @param get - its attributes\n * @param tokens - its style tokens\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readEdgeLine(get: Attr, tokens: readonly string[], put: Put, at: At): void {\n const width = nonEmpty(get(\"penwidth\")) ?? setLineWidth(tokens);\n if (width !== null) {\n put(\"width\", penWidth(width, get(\"penwidth\") !== null, at(\"width\")));\n } else if (tokens.includes(\"bold\")) {\n put(\"width\", 2);\n }\n if (tokens.includes(\"dashed\")) {\n put(\"lineStyle\", \"dashed\");\n } else if (tokens.includes(\"dotted\")) {\n put(\"lineStyle\", \"dotted\");\n } else if (tokens.includes(\"solid\") || tokens.includes(\"bold\")) {\n put(\"lineStyle\", \"solid\");\n } else if (tokens.includes(\"tapered\")) {\n put(\"lineStyle\", \"other:tapered\");\n }\n}\n\n/**\n * Reads an edge's arrows and their size.\n * @param get - its attributes\n * @param cx - its names and direction\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readEdgeArrows(get: Attr, cx: EdgeContext, put: Put, at: At): void {\n const dirRaw = nonEmpty(get(\"dir\"));\n const head = nonEmpty(get(\"arrowhead\"));\n const tail = nonEmpty(get(\"arrowtail\"));\n // with none of these the tool-default rule draws the arrow of the graph's kind\n if (dirRaw !== null || head !== null || tail !== null) {\n const dir = (dirRaw ?? (cx.directed ? \"forward\" : \"none\")).trim().toLowerCase();\n const forward = dir === \"forward\" || dir === \"both\";\n const back = dir === \"back\" || dir === \"both\";\n put(\"targetArrow\", forward ? canonEnum(\"arrow\", head ?? \"normal\", \"graphviz\", at(\"targetArrow\")) : \"none\");\n put(\"sourceArrow\", back ? canonEnum(\"arrow\", tail ?? \"normal\", \"graphviz\", at(\"sourceArrow\")) : \"none\");\n }\n const size = get(\"arrowsize\");\n if (size !== null) {\n put(\"arrowSize\", canonNumber(size, at(\"arrowSize\")));\n }\n}\n\n/**\n * The HTML strings of a file: its HTML node names and labels, for Graphviz's shared string pool.\n * @param snapshot - the graph\n * @returns the strings, with their brackets\n */\nfunction htmlStrings(snapshot: GraphSnapshot): Set<string> {\n const out = new Set<string>();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id = snapshot.ids.idOf(i);\n if (typeof id === \"string\" && isHtmlString(id)) {\n out.add(id);\n }\n }\n for (const [table, n] of [\n [snapshot.nodes, snapshot.nodeCount],\n [snapshot.edges, snapshot.edgeCount],\n ] as const) {\n for (const name of [LABEL_ATTRIBUTE, \"headlabel\", \"taillabel\"].filter((c) => table.has(c))) {\n addHtmlCells(table, name, n, out);\n }\n }\n return out;\n}\n\n/**\n * Adds the HTML strings of one label column.\n * @param table - the node or edge table\n * @param name - the column\n * @param n - its rows\n * @param out - receives the strings\n */\nfunction addHtmlCells(table: GraphSnapshot[\"nodes\"], name: string, n: number, out: Set<string>): void {\n for (let i = 0; i < n; i++) {\n const v = cellText(table, name, i);\n if (v !== null && isHtmlString(v)) {\n out.add(v);\n }\n }\n}\n\n/**\n * Which edges are directed: every edge of a directed graph, or as its direction column says.\n * @param snapshot - the graph\n * @returns per edge\n */\nfunction directedEdges(snapshot: GraphSnapshot): boolean[] {\n const out = new Array<boolean>(snapshot.edgeCount).fill(snapshot.directed);\n const col = snapshot.directed ? snapshot.edges.byRole(\"directed\") : null;\n if (col !== null) {\n for (let e = 0; e < snapshot.edgeCount; e++) {\n const v = plainCell(col.value(e));\n if (typeof v === \"boolean\") {\n out[e] = v;\n }\n }\n }\n return out;\n}\n\n/**\n * Whether a node is a cluster's container.\n * @param snapshot - the graph\n * @param i - the node\n * @returns true for a container\n */\nfunction isCluster(snapshot: GraphSnapshot, i: number): boolean {\n return snapshot.nodes.has(CLUSTER_COLUMN) && snapshot.nodes.value(CLUSTER_COLUMN, i) === true;\n}\n\n/**\n * Per element, what its labels' escapes and defaults depend on.\n * @param snapshot - the graph\n * @param written - the direction every edge is written with when the graph mixes both, or null to read it per edge\n * @returns the contexts\n */\nfunction contexts(\n snapshot: GraphSnapshot,\n written: boolean | null = null,\n): {\n readonly node: (i: number) => NodeContext;\n readonly edge: (e: number) => EdgeContext;\n} {\n const html = htmlStrings(snapshot);\n const graph = snapshot.meta.name ?? \"\";\n const own = directedEdges(snapshot);\n // a graph mixing both directions is written with one, every edge then drawn as that one\n const directed = written === null || own.every((d) => d === snapshot.directed) ? own : own.map(() => written);\n const name = (i: number): string => String(snapshot.ids.idOf(i));\n return {\n node: (i) => ({ name: name(i), graph, cluster: isCluster(snapshot, i), html }),\n edge: (e) => {\n const tail = name(snapshot.edgeSource(e));\n const head = name(snapshot.edgeTarget(e));\n return {\n names: { graph, tail, head, edge: `${tail}${directed[e] ? \"->\" : \"--\"}${head}` },\n directed: directed[e],\n html,\n };\n },\n };\n}\n\n/**\n * The label a node shows when it has none of its own: its name, escapes applied (an HTML name shows its text); null\n * for a cluster's container and a point.\n * @param cx - the node\n * @param shape - its shape, lowercase\n * @param notes - where an HTML name is noted\n * @returns the label, or null\n */\nfunction defaultLabel(cx: NodeContext, shape: string, notes: StyleNotes): string | null {\n if (cx.cluster || shape === \"point\") {\n return null;\n }\n const at: CanonSite = { notes, target: \"node\", property: \"label\" };\n return isHtmlString(cx.name)\n ? htmlLabelText(cx.name, at)\n : dotLabelText(String.raw`\\N`, { node: cx.name, graph: cx.graph }, at);\n}\n\n/**\n * The columns of a table that hold styles: Graphviz's style attributes and graphty's per-element style values.\n * @param table - the node or edge table\n * @param attributes - the style attributes of the table\n * @returns the column names\n */\nfunction styleColumns(table: GraphSnapshot[\"nodes\"], attributes: readonly string[]): string[] {\n const own = new Set([...attributes, ...NOTED_ATTRIBUTES]);\n return [...table.names()].filter((c) => own.has(c) || c.startsWith(\"graphty.style.\"));\n}\n\n/**\n * The styles of a DOT file, read the way Graphviz draws it, with Graphviz's defaults beneath: an unfilled black\n * ellipse 54 x 36 labeled with its name, black edges with a target arrow in a directed graph. A file graphty wrote\n * gives back its `graphty.styles` block.\n * @param snapshot - the graph the import built\n * @param context - the work budget\n * @returns the styles\n */\nexport function dotStyles(snapshot: GraphSnapshot, context: StyleReadContext): ImporterStyles {\n const notes = new StyleNotes();\n const cx = contexts(snapshot);\n const node = valueColumns(snapshot.nodeCount);\n const nameColumn = new Array<StyleValue | null>(snapshot.nodeCount).fill(null);\n const clusterColumn = new Array<StyleValue | null>(snapshot.nodeCount).fill(null);\n let named = 0;\n let clusters = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n context.budget.spend(\"node\", NODE_ATTRIBUTES.length);\n const get: Attr = (name) => cellText(snapshot.nodes, name, i);\n const ncx = cx.node(i);\n const at: At = (property) => ({ notes, target: \"node\", property, element: i, budget: context.budget });\n readNode(\n get,\n ncx,\n (p, v) => {\n node.put(i, p, v);\n },\n at,\n );\n const shown = defaultLabel(ncx, (get(\"shape\") ?? \"\").toLowerCase(), notes);\n if (shown !== null) {\n nameColumn[i] = shown;\n named++;\n }\n if (ncx.cluster) {\n clusterColumn[i] = true;\n clusters++;\n }\n }\n const edge = valueColumns(snapshot.edgeCount);\n for (let e = 0; e < snapshot.edgeCount; e++) {\n context.budget.spend(\"edge\", EDGE_ATTRIBUTES.length);\n const get: Attr = (name) => cellText(snapshot.edges, name, e);\n const at: At = (property) => ({ notes, target: \"edge\", property, element: e, budget: context.budget });\n readEdge(\n get,\n cx.edge(e),\n (p, v) => {\n edge.put(e, p, v);\n },\n at,\n );\n }\n const graph: Record<string, StyleValue> = {};\n const bg = nonEmpty(cellText(snapshot.graph, \"bgcolor\", 0));\n if (snapshot.graph.has(\"bgcolor\") && bg !== null) {\n readColor(\n bg,\n cellText(snapshot.graph, \"colorscheme\", 0),\n \"fill\",\n \"background\",\n null,\n (p, v) => {\n if (v !== null) {\n graph[p] = v;\n }\n },\n (property) => ({ notes, target: \"graph\", property }),\n );\n }\n const blockText = cellText(snapshot.graph, STYLE_BLOCK_NAME, 0);\n if (blockText !== null) {\n exactFromBlock(snapshot, blockText, { node: node.values, edge: edge.values }, cx);\n }\n // Graphviz's defaults that are rules: each node shows its name, and a directed edge has an arrow at its target\n const nodeRules: StyleRule[] = [];\n const nodeColumns = new Map<string, StyleColumn>();\n if (named > 0) {\n nodeColumns.set(NAME_KEY, nameColumn);\n nodeRules.push({\n id: \"node.tool.name-label\",\n target: \"node\",\n role: \"passthrough\",\n origin: \"tool\",\n where: { has: { style: NAME_KEY } },\n map: { label: { kind: \"passthrough\", by: { style: NAME_KEY } } },\n facts: { elements: named, reason: \"NODE_NAME\" },\n });\n }\n const features: StyleFeature[] = clusters > 0 ? [{ ref: { style: CLUSTER_KEY }, values: clusterColumn }] : [];\n const edgeRules: StyleRule[] = [];\n const edgeColumns = new Map<string, StyleColumn>();\n const directed = directedEdges(snapshot);\n if (directed.some(Boolean)) {\n edgeColumns.set(\n DIRECTED_KEY,\n directed.map((d) => (d ? true : null)),\n );\n edgeRules.push({\n id: \"edge.tool.arrow\",\n target: \"edge\",\n role: \"group\",\n origin: \"tool\",\n where: { has: { style: DIRECTED_KEY } },\n set: { targetArrow: \"triangle\" },\n });\n }\n return {\n canonical: true,\n dialect: \"graphviz\",\n tool: \"graphviz\",\n units: \"px\",\n node: { values: node.values, rules: nodeRules, columns: nodeColumns, features },\n edge: { values: edge.values, rules: edgeRules, columns: edgeColumns },\n graph,\n notes: notes.list(),\n readFrom: {\n node: styleColumns(snapshot.nodes, NODE_ATTRIBUTES),\n edge: styleColumns(snapshot.edges, EDGE_ATTRIBUTES),\n },\n };\n}\n\n// ============================================================ writing\n\n/** One element's value of a property. */\ntype Get = (property: string) => StyleValue | null;\n\n/** Records a value written as the nearest one Graphviz has. */\ntype Approximate = (property: string, value: StyleValue) => void;\n\n/** A written attribute value: text, or a number written as one. */\ntype Written = string | number;\n\n/** Neutral shapes by the Graphviz shape that draws them exactly. */\nconst SHAPES: ReadonlyMap<string, string> = new Map([\n [\"ellipse\", \"ellipse\"],\n [\"rectangle\", \"box\"],\n [\"round-rectangle\", \"box\"],\n [\"triangle\", \"triangle\"],\n [\"diamond\", \"diamond\"],\n [\"pentagon\", \"pentagon\"],\n [\"hexagon\", \"hexagon\"],\n [\"octagon\", \"octagon\"],\n [\"parallelogram\", \"parallelogram\"],\n [\"trapezoid\", \"trapezium\"],\n [\"star\", \"star\"],\n [\"none\", \"none\"],\n]);\n\n/** Neutral arrows by the Graphviz arrow that draws them. */\nconst ARROWS: ReadonlyMap<string, string> = new Map([\n [\"none\", \"none\"],\n [\"triangle\", \"normal\"],\n [\"triangle-open\", \"onormal\"],\n [\"vee\", \"vee\"],\n [\"tee\", \"tee\"],\n [\"diamond\", \"diamond\"],\n [\"diamond-open\", \"odiamond\"],\n [\"circle\", \"dot\"],\n [\"circle-open\", \"odot\"],\n [\"square\", \"box\"],\n [\"crow\", \"crow\"],\n [\"half\", \"lnormal\"],\n [\"inverted\", \"inv\"],\n]);\n\n/** Line and border styles Graphviz draws exactly; the others are written as the nearest. */\nconst STROKES: ReadonlyMap<string, string> = new Map([\n [\"dashed\", \"dashed\"],\n [\"dotted\", \"dotted\"],\n]);\n\n/**\n * The attribute values Graphviz draws when an attribute is absent, from the tool-defaults table: the writer leaves\n * them out, so a file states what differs from Graphviz's drawing (and a size stays one Graphviz may grow).\n * @param target - nodes or edges\n * @returns the default text of each attribute\n */\nfunction graphvizDefaults(target: StyleTarget): ReadonlyMap<string, Written> {\n const t = toolDefaults(\"graphviz\")?.[target] as Readonly<Record<string, { readonly value: unknown } | undefined>>;\n const out = new Map<string, Written>();\n const add = (attribute: string, property: string, scale = 1): void => {\n const v = t[property]?.value;\n if (typeof v === \"number\") {\n out.set(attribute, num6(v / scale));\n } else if (typeof v === \"string\") {\n out.set(attribute, v);\n }\n };\n add(\"fontcolor\", \"labelColor\");\n add(\"fontsize\", \"labelSize\");\n add(\"fontname\", \"labelFont\");\n if (target === \"node\") {\n add(\"color\", \"borderColor\");\n add(\"pencolor\", \"borderColor\");\n add(\"penwidth\", \"borderWidth\");\n add(\"shape\", \"shape\");\n add(\"width\", \"width\", DOT_POINTS_PER_INCH);\n add(\"height\", \"height\", DOT_POINTS_PER_INCH);\n } else {\n add(\"color\", \"color\");\n add(\"penwidth\", \"width\");\n add(\"arrowsize\", \"arrowSize\");\n }\n return out;\n}\n\nconst DEFAULT_ATTRIBUTES: Readonly<Record<StyleTarget, ReadonlyMap<string, Written>>> = {\n node: graphvizDefaults(\"node\"),\n edge: graphvizDefaults(\"edge\"),\n};\n\n/**\n * Leaves out every attribute whose value is the one Graphviz draws without it.\n * @param out - the attributes, changed in place\n * @param target - nodes or edges\n * @returns the attributes\n */\nfunction withoutDefaults(out: Map<string, Written>, target: StyleTarget): Map<string, Written> {\n for (const [attribute, value] of DEFAULT_ATTRIBUTES[target]) {\n if (out.get(attribute) === value) {\n out.delete(attribute);\n }\n }\n if (!out.has(\"width\") && !out.has(\"height\")) {\n out.delete(\"fixedsize\");\n }\n return out;\n}\n\n/**\n * A color as Graphviz writes it: `#rrggbb`, or `#rrggbbaa` with an opacity below 1.\n * @param color - the canonical color\n * @param opacity - the opacity, or null\n * @returns the text\n */\nfunction gvColor(color: string, opacity: StyleValue | null): string {\n if (typeof opacity !== \"number\" || opacity >= 1) {\n return color;\n }\n const a = Math.max(0, Math.min(255, Math.round(opacity * 255)));\n return color + a.toString(16).padStart(2, \"0\");\n}\n\n/**\n * A label's text as a DOT label: backslashes and line breaks escaped, so Graphviz's escape passes give the text back.\n * @param text - the text\n * @returns the label\n */\nfunction escapeLabel(text: string): string {\n return text.replaceAll(\"\\\\\", String.raw`\\\\`).replaceAll(\"\\n\", String.raw`\\n`);\n}\n\n/**\n * A shape, line or arrow value in Graphviz's spelling.\n * @param table - the exact spellings\n * @param value - the neutral value\n * @param nearest - the spelling written when there is no exact one\n * @param property - the property, for the approximation note\n * @param approximate - records approximations\n * @returns the spelling\n */\nfunction spelled(\n table: ReadonlyMap<string, string>,\n value: string,\n nearest: string,\n property: string,\n approximate: Approximate,\n): string {\n const exact = table.get(value);\n if (exact !== undefined) {\n return exact;\n }\n if (value.startsWith(\"other:\")) {\n return value.slice(\"other:\".length);\n }\n approximate(property, value);\n return nearest;\n}\n\n/**\n * The font, tooltip and visibility attributes every element shares.\n * @param get - the element's values\n * @param out - the attributes, added to\n * @param tokens - the style tokens, added to\n */\nfunction writeCommon(get: Get, out: Map<string, Written>, tokens: string[]): void {\n const color = get(\"labelColor\");\n if (typeof color === \"string\") {\n out.set(\"fontcolor\", color);\n }\n const size = get(\"labelSize\");\n if (typeof size === \"number\") {\n out.set(\"fontsize\", size);\n }\n const font = get(\"labelFont\");\n if (typeof font === \"string\") {\n out.set(\"fontname\", font);\n }\n const tip = get(\"tooltip\");\n if (typeof tip === \"string\") {\n out.set(\"tooltip\", escapeLabel(tip));\n }\n if (get(\"visible\") === false) {\n tokens.push(\"invis\");\n }\n}\n\n/**\n * A node's or cluster's Graphviz attributes from its values.\n * @param get - the node's values\n * @param cx - the node's name and kind\n * @param approximate - records approximations\n * @param notes - where an HTML name is noted\n * @returns the attributes\n */\nfunction nodeAttributes(get: Get, cx: NodeContext, approximate: Approximate, notes: StyleNotes): Map<string, Written> {\n const out = new Map<string, Written>();\n const tokens: string[] = [];\n writeCommon(get, out, tokens);\n writeNodeOutline(get, cx, approximate, out, tokens);\n const gvShape = writeNodeShape(get, cx, approximate, out, tokens);\n if (!cx.cluster) {\n writeNodeSize(get, out);\n }\n // the label is written where it differs from what Graphviz shows without one (the name), \"\" for none\n const label = get(\"label\");\n const shown = defaultLabel(cx, gvShape, notes);\n if (typeof label === \"string\" && label !== shown) {\n out.set(LABEL_ATTRIBUTE, escapeLabel(label));\n } else if (label === null && shown !== null) {\n out.set(LABEL_ATTRIBUTE, \"\");\n }\n if (tokens.length > 0) {\n out.set(\"style\", tokens.join(\",\"));\n }\n return withoutDefaults(out, \"node\");\n}\n\n/**\n * A node's or cluster's fill and outline attributes.\n * @param get - the node's values\n * @param cx - the node's name and kind\n * @param approximate - records approximations\n * @param out - the attributes, added to\n * @param tokens - the style tokens, added to\n */\nfunction writeNodeOutline(\n get: Get,\n cx: NodeContext,\n approximate: Approximate,\n out: Map<string, Written>,\n tokens: string[],\n): void {\n const fill = get(\"fill\");\n const fillOpacity = get(\"fillOpacity\");\n if (typeof fill === \"string\" && fillOpacity !== 0) {\n tokens.push(\"filled\");\n out.set(\"fillcolor\", gvColor(fill, fillOpacity));\n }\n const border = get(\"borderColor\");\n if (typeof border === \"string\") {\n out.set(cx.cluster ? \"pencolor\" : \"color\", border);\n }\n const borderWidth = get(\"borderWidth\");\n if (typeof borderWidth === \"number\") {\n out.set(\"penwidth\", borderWidth);\n }\n const borderStyle = get(\"borderStyle\");\n if (typeof borderStyle === \"string\" && borderStyle !== \"solid\") {\n const nearest = borderStyle.includes(\"dash\") ? \"dashed\" : \"solid\";\n tokens.push(spelled(STROKES, borderStyle, nearest, \"borderStyle\", approximate));\n }\n}\n\n/**\n * A node's shape attribute; a cluster is always a rectangle, rounded or not, and any other shape is approximated.\n * @param get - the node's values\n * @param cx - the node's name and kind\n * @param approximate - records approximations\n * @param out - the attributes, added to\n * @param tokens - the style tokens, added to\n * @returns the Graphviz shape written, \"\" for none\n */\nfunction writeNodeShape(\n get: Get,\n cx: NodeContext,\n approximate: Approximate,\n out: Map<string, Written>,\n tokens: string[],\n): string {\n const shape = get(\"shape\");\n if (typeof shape !== \"string\") {\n return \"\";\n }\n if (shape === \"round-rectangle\") {\n tokens.push(\"rounded\");\n }\n if (cx.cluster) {\n if (shape !== \"rectangle\" && shape !== \"round-rectangle\") {\n approximate(\"shape\", shape);\n }\n return \"\";\n }\n const gvShape = spelled(SHAPES, shape, shape === \"vee\" ? \"invtriangle\" : \"box\", \"shape\", approximate);\n out.set(\"shape\", gvShape);\n return gvShape;\n}\n\n/**\n * A node's width and height, fixed so Graphviz does not grow them to fit the label.\n * @param get - the node's values\n * @param out - the attributes, added to\n */\nfunction writeNodeSize(get: Get, out: Map<string, Written>): void {\n const width = get(\"width\");\n const height = get(\"height\");\n if (typeof width === \"number\" || typeof height === \"number\") {\n out.set(\"fixedsize\", \"true\");\n }\n if (typeof width === \"number\") {\n out.set(\"width\", inchesOf(width));\n }\n if (typeof height === \"number\") {\n out.set(\"height\", inchesOf(height));\n }\n}\n\n/**\n * An edge's Graphviz attributes from its values.\n * @param get - the edge's values\n * @param directed - whether the edge is directed (its default arrows)\n * @param approximate - records approximations\n * @returns the attributes\n */\nfunction edgeAttributes(get: Get, directed: boolean, approximate: Approximate): Map<string, Written> {\n const out = new Map<string, Written>();\n const tokens: string[] = [];\n writeCommon(get, out, tokens);\n const color = get(\"color\");\n if (typeof color === \"string\") {\n out.set(\"color\", gvColor(color, get(\"opacity\")));\n }\n const width = get(\"width\");\n if (typeof width === \"number\") {\n out.set(\"penwidth\", width);\n }\n const line = get(\"lineStyle\");\n if (typeof line === \"string\" && line !== \"solid\") {\n tokens.push(spelled(STROKES, line, line.includes(\"dash\") ? \"dashed\" : \"solid\", \"lineStyle\", approximate));\n }\n writeEdgeArrows(get, directed, approximate, out);\n const arrowSize = get(\"arrowSize\");\n if (typeof arrowSize === \"number\") {\n out.set(\"arrowsize\", arrowSize);\n }\n for (const [property, attribute] of [\n [\"label\", LABEL_ATTRIBUTE],\n [\"targetLabel\", \"headlabel\"],\n [\"sourceLabel\", \"taillabel\"],\n ] as const) {\n const v = get(property);\n if (typeof v === \"string\") {\n out.set(attribute, escapeLabel(v));\n }\n }\n if (tokens.length > 0) {\n out.set(\"style\", tokens.join(\",\"));\n }\n return withoutDefaults(out, \"edge\");\n}\n\n/**\n * An edge's arrow attributes, written where they differ from the graph's own: a target arrow on a directed edge.\n * @param get - the edge's values\n * @param directed - whether the edge is directed\n * @param approximate - records approximations\n * @param out - the attributes, added to\n */\nfunction writeEdgeArrows(get: Get, directed: boolean, approximate: Approximate, out: Map<string, Written>): void {\n const source = get(\"sourceArrow\");\n const target = get(\"targetArrow\");\n const tail = typeof source === \"string\" && source !== \"none\";\n const head = typeof target === \"string\" && target !== \"none\";\n const plain = directed ? head && !tail && target === \"triangle\" : !head && !tail;\n if (plain || (source === null && target === null)) {\n return;\n }\n let dir = \"none\";\n if (head && tail) {\n dir = \"both\";\n } else if (head) {\n dir = \"forward\";\n } else if (tail) {\n dir = \"back\";\n }\n out.set(\"dir\", dir);\n if (head) {\n out.set(\"arrowhead\", spelled(ARROWS, target, \"normal\", \"targetArrow\", approximate));\n }\n if (tail) {\n out.set(\"arrowtail\", spelled(ARROWS, source, \"normal\", \"sourceArrow\", approximate));\n }\n}\n\n/**\n * Each element's values of the properties the writer writes, as a getter per element.\n * @param picture - each element's value of a property\n * @param target - nodes or edges\n * @returns the getter\n */\nfunction getter(\n picture: (target: StyleTarget, property: string) => readonly (StyleValue | null)[],\n target: StyleTarget,\n): (i: number) => Get {\n const columns = new Map<string, readonly (StyleValue | null)[]>();\n for (const p of DOT_STYLE_CAPABILITIES[target]) {\n columns.set(p, picture(target, p));\n }\n return (i) => (property) => columns.get(property)?.[i] ?? null;\n}\n\n/**\n * For a file graphty wrote: where a value read from the attributes is what the writer writes for the block's own\n * value (a hexagon written as a hexagon, a pentagon-like vee as an inverted triangle, an opacity rounded to 255 steps,\n * a size rounded in inches), the block's exact value is the truth, so a re-import gives back the same rules; a value\n * another program changed since stays the truth.\n * @param snapshot - the graph\n * @param text - the block's text\n * @param read - the values read, changed in place\n * @param read.node - the node values\n * @param read.edge - the edge values\n * @param cx - the elements' contexts\n */\nfunction exactFromBlock(\n snapshot: GraphSnapshot,\n text: string,\n read: { readonly node: ValueColumns; readonly edge: ValueColumns },\n cx: ReturnType<typeof contexts>,\n): void {\n const parsed = parseStyleBlock(text, styleFingerprint(snapshot));\n const ex = parsed.ok ? blockStyles(parsed.block, snapshot, \"dot\") : null;\n if (ex === null) {\n return;\n }\n const notes = new StyleNotes();\n for (const target of [\"node\", \"edge\"] as const) {\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const get = getter((t, p) => resolveStyles(ex, t, p as never, snapshot), target);\n const values = read[target];\n for (let i = 0; i < n; i++) {\n const want = get(i);\n const back = writtenAndReadBack(target, i, want, cx, notes);\n for (const property of DOT_STYLE_CAPABILITIES[target]) {\n const native = values[property]?.[i] ?? null;\n const w = want(property);\n if (native !== w && native === (back.get(property) ?? null)) {\n values[property] ??= new Array<StyleValue | null>(n).fill(null);\n values[property][i] = w;\n }\n }\n }\n }\n}\n\n/**\n * An element's values written as the writer writes them and read back as the reader reads them.\n * @param target - nodes or edges\n * @param i - the element\n * @param want - its values\n * @param cx - the elements' contexts\n * @param notes - a scratch for the notes the round trip makes\n * @returns the values read back, by property\n */\nfunction writtenAndReadBack(\n target: StyleTarget,\n i: number,\n want: Get,\n cx: ReturnType<typeof contexts>,\n notes: StyleNotes,\n): Map<string, StyleValue> {\n const ignore: Approximate = () => undefined;\n const back = new Map<string, StyleValue>();\n const put: Put = (property, value) => {\n if (value !== null) {\n back.set(property, value);\n }\n };\n const at: At = (property) => ({ notes, target, property });\n if (target === \"node\") {\n const ncx = cx.node(i);\n const attrs = nodeAttributes(want, ncx, ignore, notes);\n readNode((name) => textOf(attrs.get(name)), ncx, put, at);\n } else {\n const ecx = cx.edge(i);\n const attrs = edgeAttributes(want, ecx.directed, ignore);\n readEdge((name) => textOf(attrs.get(name)), ecx, put, at);\n }\n return back;\n}\n\n/**\n * A written value as the text the importer would read back.\n * @param v - the value\n * @returns its text, or null\n */\nfunction textOf(v: Written | undefined): string | null {\n return v === undefined ? null : String(v);\n}\n\n/**\n * Whether a style column written as a DOT attribute reads back as the same values: DOT values are untyped and the\n * importer infers a column's type from its text, so a text column whose every value looks like a number does not.\n * @param col - the values\n * @returns true when it reads back unchanged\n */\nfunction readsBack(col: StyleColumn): boolean {\n const vals = col.filter((v): v is StyleValue => v !== null);\n if (vals.every((v) => typeof v === \"number\")) {\n return vals.every((v) => Number.isFinite(v));\n }\n if (vals.every((v) => typeof v === \"boolean\")) {\n return true;\n }\n if (vals.every((v) => typeof v === \"string\")) {\n return vals.some((v) => inferTextDtype(v) === \"string\") && vals.every((v) => isWritableDotText(v));\n }\n return false;\n}\n\n/**\n * A `graphty.styles` block's JSON with every quote and backslash inside its strings written as a `\\u` escape, so the\n * text holds no backslash before a quote, which a DOT quoted string cannot carry; it parses to the same value.\n * @param json - the block\n * @returns the block\n */\nfunction dotSafeJson(json: string): string {\n return json.replaceAll(/\\\\([\"\\\\])/g, (_m, c: string) => (c === '\"' ? String.raw`\\u0022` : String.raw`\\u005c`));\n}\n\n/** A DOT export with styles worked out. */\ninterface DotStyledExport {\n /** The graph to write: Graphviz attributes written from the styles, the block and the per-element values added. */\n readonly snapshot: GraphSnapshot;\n /** W_STYLE_APPROXIMATED for every value written as the nearest one Graphviz has. */\n readonly notes: readonly LossNote[];\n}\n\n/**\n * Works out a DOT export with styles: every node's, cluster's and edge's Graphviz attributes from what graphty draws,\n * in place of every style attribute it had; the graph's `bgcolor`; the `graphty.styles` block as the graph attribute\n * `\"graphty.styles\"` and the per-element values its rules read as `\"graphty.style.<target>.<key>\"` attributes. A\n * style column whose values would not read back as written (text that looks like numbers) goes inside the block\n * instead, with all the others.\n * @param snapshot - the graph handed to the exporter\n * @param input - the styles, or undefined when none are written\n * @param onMixedDirection - the exporter's option: the direction a graph mixing both is written with\n * @returns the styled export, or null without styles\n */\nexport function dotStyledExport(\n snapshot: GraphSnapshot,\n input: ExporterStyleInput | undefined,\n onMixedDirection?: unknown,\n): DotStyledExport | null {\n if (input === undefined) {\n return null;\n }\n // the registry's check before writing and the write of one export call share the work\n return sharedInExportCall(input, [snapshot, onMixedDirection], () =>\n styledExport(snapshot, input, onMixedDirection),\n );\n}\n\n/**\n * Works out a DOT export with styles: dotStyledExport() without the sharing.\n * @param snapshot - the graph handed to the exporter\n * @param input - the styles\n * @param onMixedDirection - the exporter's option\n * @returns the styled export\n */\nfunction styledExport(snapshot: GraphSnapshot, input: ExporterStyleInput, onMixedDirection: unknown): DotStyledExport {\n const approximated = new StyleApproximations();\n const replaced: LossNote[] = [];\n const out = snapshot.withColumns();\n const written = onMixedDirection === \"directed\" || onMixedDirection === \"undirected\";\n const cx = contexts(snapshot, written ? onMixedDirection === \"directed\" : null);\n const notes = new StyleNotes();\n for (const target of [\"node\", \"edge\"] as const) {\n const table = target === \"node\" ? out.nodes : out.edges;\n const read = dataRead(input.rules.styles.rules, target);\n const approximate: Approximate = (property, value) => {\n approximated.add(target, property, value);\n };\n const columns = attributeColumns(snapshot, input, target, { cx, approximate, notes, read });\n replaced.push(...removeStyleAttributes(table, target, columns, read));\n setAttributeColumns(table, columns);\n }\n const { background } = input.rules.styles.graph;\n if (out.graph.has(\"bgcolor\")) {\n out.graph.remove(\"bgcolor\");\n }\n if (typeof background === \"string\") {\n out.graph.set(\"bgcolor\", [background], { dtype: \"string\" });\n }\n const inline = [...input.tags.node.values(), ...input.tags.edge.values()].some((col) => !readsBack(col));\n if (!inline) {\n setTagColumns(out, input);\n }\n const block = inline ? writeStyleBlock(input.rules, { inlineColumns: true, snapshot }) : input.block;\n out.graph.set(STYLE_BLOCK_NAME, [dotSafeJson(block)], { dtype: \"string\" });\n const losses = approximated.notes(\"Graphviz\");\n if (inline) {\n losses.push(...styleBlockLosses(block, input.rules.styles.rules.length, \"size\"));\n }\n return { snapshot: out, notes: [...replaced, ...losses] };\n}\n\n/** What attributeColumns() reads besides the graph and the styles. */\ninterface AttributeWrite {\n /** The elements' contexts. */\n readonly cx: ReturnType<typeof contexts>;\n /** Records approximations. */\n readonly approximate: Approximate;\n /** Where an HTML name is noted. */\n readonly notes: StyleNotes;\n /** The data columns the target's rules read. */\n readonly read: ReadonlySet<string>;\n}\n\n/**\n * Every element's Graphviz attributes of a target, as columns.\n * @param snapshot - the graph handed to the exporter\n * @param input - the styles\n * @param target - nodes or edges\n * @param w - the contexts, the recorders and the columns the rules read\n * @returns the attribute columns, by name\n */\nfunction attributeColumns(\n snapshot: GraphSnapshot,\n input: ExporterStyleInput,\n target: StyleTarget,\n w: AttributeWrite,\n): Map<string, (Written | null)[]> {\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const get = getter((t, p) => input.picture(t, p as never), target);\n const columns = new Map<string, (Written | null)[]>();\n for (let i = 0; i < n; i++) {\n const attrs =\n target === \"node\"\n ? nodeAttributes(get(i), w.cx.node(i), w.approximate, w.notes)\n : edgeAttributes(get(i), w.cx.edge(i).directed, w.approximate);\n // no label is written label=\"\" (Graphviz would show the name), which a rule reading the label column\n // reads back as the empty label\n if (w.read.has(LABEL_ATTRIBUTE) && attrs.get(LABEL_ATTRIBUTE) === \"\" && get(i)(\"label\") === null) {\n w.approximate(\"label\", \"\");\n }\n for (const [name, value] of attrs) {\n let col = columns.get(name);\n if (col === undefined) {\n col = new Array<Written | null>(n).fill(null);\n columns.set(name, col);\n }\n col[i] = value;\n }\n }\n return columns;\n}\n\n/**\n * Removes every column Graphviz reads as how to draw: the picture writes them, so a data column of the same name (a\n * `label` attribute graphty does not draw) would draw something graphty does not. One a rule reads, whose values the\n * picture does not write, is lost to the rule, and said so.\n * @param table - the node or edge table, changed in place\n * @param target - nodes or edges\n * @param columns - the attributes the picture writes\n * @param read - the data columns the rules read\n * @returns the notes of the columns lost to a rule\n */\nfunction removeStyleAttributes(\n table: GraphSnapshot[\"nodes\"],\n target: StyleTarget,\n columns: ReadonlyMap<string, (Written | null)[]>,\n read: ReadonlySet<string>,\n): LossNote[] {\n const attributes = target === \"node\" ? NODE_ATTRIBUTES : EDGE_ATTRIBUTES;\n const replaced: LossNote[] = [];\n for (const name of table.names()) {\n if (!attributes.includes(name) && name !== LABEL_ATTRIBUTE && !name.startsWith(\"graphty.style.\")) {\n continue;\n }\n const differs = read.has(name) ? replacedRows(table, name, columns.get(name)) : 0;\n if (differs > 0) {\n replaced.push(\n Object.freeze({\n code: DOT_ATTRIBUTE_CLASH_CODE,\n message: `${target} column \"${name}\" is not written: the ${name} attribute holds what graphty draws (${String(differs)} ${target}${differs === 1 ? \"\" : \"s\"} differ)`,\n column: name,\n count: differs,\n }),\n );\n }\n table.remove(name);\n }\n return replaced;\n}\n\n/**\n * Sets the attribute columns the picture writes: the label with its role, numbers as f64, the rest as text.\n * @param table - the node or edge table, changed in place\n * @param columns - the attributes\n */\nfunction setAttributeColumns(table: GraphSnapshot[\"nodes\"], columns: ReadonlyMap<string, (Written | null)[]>): void {\n for (const [name, col] of columns) {\n if (name === LABEL_ATTRIBUTE) {\n table.set(name, col, { dtype: \"string\", role: \"label\" }, { replaceRole: true });\n } else if (col.every((v) => v === null || typeof v === \"number\")) {\n table.set(name, col, { dtype: \"f64\" });\n } else {\n table.set(\n name,\n col.map((v) => (v === null ? null : String(v))),\n { dtype: \"string\" },\n );\n }\n }\n}\n\n/**\n * Sets the per-element values the rules read as `\"graphty.style.<target>.<key>\"` attributes.\n * @param out - the graph, changed in place\n * @param input - the styles\n */\nfunction setTagColumns(out: GraphSnapshot, input: ExporterStyleInput): void {\n for (const target of [\"node\", \"edge\"] as const) {\n const table = target === \"node\" ? out.nodes : out.edges;\n for (const [name, col] of input.tags[target]) {\n const kinds = new Set(col.filter((v) => v !== null).map((v) => typeof v));\n let dtype: \"string\" | \"bool\" | \"f64\" = \"string\";\n if (kinds.has(\"number\")) {\n dtype = \"f64\";\n } else if (kinds.has(\"boolean\")) {\n dtype = \"bool\";\n }\n table.set(name, col, { dtype });\n }\n }\n}\n\n/**\n * The data columns the rules of a target read.\n * @param rules - the rules\n * @param target - nodes or edges\n * @returns the column names\n */\nfunction dataRead(rules: readonly StyleRule[], target: StyleTarget): Set<string> {\n const out = new Set<string>();\n for (const { ext: _ext, ...rule } of rules.filter((r) => r.target === target)) {\n JSON.stringify(rule, (_k, v: unknown) => {\n if (typeof v === \"object\" && v !== null && !Array.isArray(v) && Object.keys(v).length === 1) {\n const { data } = v as { data?: unknown };\n if (typeof data === \"string\") {\n out.add(data);\n }\n }\n return v;\n });\n }\n return out;\n}\n\n/**\n * A data column named like an attribute the export writes is not written: the exporter's `DOT_LOSS.ATTRIBUTE_CLASH`.\n */\nexport const DOT_ATTRIBUTE_CLASH_CODE = \"W_DOT_ATTRIBUTE_CLASH\";\n\n/**\n * How many rows of a data column the attribute written in its place does not hold as it is.\n * @param table - the table\n * @param name - the column\n * @param written - the attribute's values, or undefined when none is written\n * @returns the rows that differ\n */\nfunction replacedRows(\n table: GraphSnapshot[\"nodes\"],\n name: string,\n written: readonly (Written | null)[] | undefined,\n): number {\n const column = table.get(name);\n let n = 0;\n for (let i = 0; column !== null && i < column.length; i++) {\n const cell = column.isSet(i) ? plainCell(column.value(i)) : null;\n const w = written?.[i] ?? null;\n const text = typeof cell === \"string\" ? cell : JSON.stringify(cell);\n if (cell !== null && (w === null || String(w) !== text)) {\n n++;\n }\n }\n return n;\n}\n","/**\n * The DOT / Graphviz exporter (design section 8.5; research note 07 section 9). Writes one\n * `[strict] graph | digraph [name] { ... }` with the graph attributes first, every node in index\n * order (a node statement carrying its set cells as attributes, or a `subgraph` block for a cluster\n * container node with its members nested inside), then every logical edge in index order with its\n * explicit weight, `key` (the edge id role), ports and attributes.\n *\n * What the format keeps and what check() reports: any id and any text (DOT quotes everything\n * except a text ending in a backslash, which the lexer cannot read back); bool / i32 / f64 cells\n * (f64 written with a decimal point so the dtype survives re-import; other numeric dtypes are\n * written and read back inferred); containment through the parent role (clusters); graph\n * attributes; node positions as `pos=\"x,y\"`. Mixed direction is folded per onMixedDirection\n * (DOT has none); lists, json, defaults, options, temporal and visual roles cannot be written.\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { type ChildrenCsr, childrenCsr } from \"../../children.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { isWritableDotText, quoteDotId } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, countMixedEdges, LOSS, sanitizeIds } from \"../../common/export.js\";\nimport { formatDecimal, formatF32, formatF64, formatInteger, idText } from \"../../common/format.js\";\nimport { canonicalId } from \"../../common/ids.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { inferTextDtype } from \"../../common/text.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, indentUnit, joinText } from \"../../common/writer.js\";\nimport type { ExporterStyleOptions } from \"../../styles/io/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport {\n CLUSTER_COLUMN,\n DOT_FORMAT,\n DOT_META_KEY,\n KEY_ATTRIBUTE,\n LABEL_ATTRIBUTE,\n PARENT_COLUMN,\n POS_ATTRIBUTE,\n SOURCE_PORT_COLUMN,\n TARGET_PORT_COLUMN,\n} from \"./names.js\";\nimport { DOT_ATTRIBUTE_CLASH_CODE, DOT_STYLE_CAPABILITIES, dotStyledExport, isHtmlString } from \"./styles.js\";\n\n/** What the writer takes: the format's options, the common ones and the styles. */\ntype DotWriteOptions = DotExportOptions & CommonExportOptions & ExporterStyleOptions;\n\n/**\n * The DOT exporter's format-specific options.\n * @category Built-in formats\n */\nexport interface DotExportOptions extends CommonExportOptions {\n /**\n * The indentation of one nesting level: a number of spaces, or the text itself (spaces or tabs,\n * such as \"\\t\").\n * @defaultValue 4\n */\n indent?: number | string | undefined;\n /**\n * The graph name to write, or null for an anonymous graph. The default is the graph's name\n * (`snapshot.meta.name`), which a DOT, GML or GEXF import keeps.\n * @defaultValue the graph's name\n */\n name?: string | null | undefined;\n /**\n * Whether to write the `strict` keyword. The default is to write it when the graph was read\n * from a strict DOT file.\n * @defaultValue as read\n */\n strict?: boolean | undefined;\n}\n\n/**\n * The LossNote codes of the DOT exporter; the shared ones are LOSS's.\n * @category Built-in formats\n */\nexport const DOT_LOSS = Object.freeze({\n /**\n * An id, name or text with a backslash before a quote or a line break, or at its end, cannot be written as a DOT\n * quoted string; the save fails.\n */\n TRAILING_BACKSLASH: \"E_DOT_TRAILING_BACKSLASH\",\n /** NaN or an infinity has no DOT number spelling; it is written as text and reads back as text. */\n NON_FINITE: \"W_DOT_NON_FINITE\",\n /**\n * A text value that reads back as a number or a boolean, because the format does not record that it was text (the\n * text \"42\" reads back as the number 42).\n */\n TEXT_INFERRED: LOSS.TEXT_INFERRED,\n /** A plain column named like an attribute the exporter writes for a role (weight, key, pos) is not written. */\n ATTRIBUTE_CLASH: DOT_ATTRIBUTE_CLASH_CODE,\n /** A mutual pair is written as two directed edges. */\n MUTUAL_EXPANDED: LOSS.MUTUAL_EXPANDED,\n /** A parents (multi-parent) column cannot be written; DOT clusters nest. */\n PARENTS_DROPPED: LOSS.PARENTS,\n /** A position column that is not a node column of 2 or 3 components is not written. */\n POSITION_SHAPE: \"W_DOT_POSITION_SHAPE\",\n /** An id that reads back as a different type, such as the decimal 1.5 as text or the text \"1\" as the number 1. */\n ID_TEXT_TYPE: LOSS.ID_TEXT_TYPE,\n /** A declared column whose every row is unset is not written (DOT writes cells, never declarations). */\n EMPTY_COLUMN_DROPPED: LOSS.EMPTY_COLUMN,\n /**\n * An attribute without a role is written where the format keeps a role (for example, a `name` column as the label), and\n * reads back with that role.\n */\n ROLE_ASSUMED: LOSS.ROLE_ASSUMED,\n /** A parent that is a plain node is written as a node and a cluster of one name; it reads back marked as a cluster. */\n CLUSTER_MARKED: \"W_DOT_CLUSTER_MARKED\",\n /** The file is written in UTF-8, so a graph `charset` naming another encoding is written as `UTF-8`. */\n CHARSET_REWRITTEN: \"W_DOT_CHARSET_REWRITTEN\",\n});\n\n/** A graph `charset` that names the encoding the exporter writes (Graphviz accepts both spellings). */\nconst UTF8_CHARSET = /^utf-?8$/i;\n\n/**\n * W_DOT_CHARSET_REWRITTEN for a graph `charset` naming another encoding than the UTF-8 the file is written in.\n * @param column - a graph column\n * @returns the note, or none\n */\nfunction charsetNotes(column: Column): LossNote[] {\n const declared = isCharset(column) && column.isSet(0) ? cellText(column, 0) : null;\n if (declared === null || UTF8_CHARSET.test(declared)) {\n return [];\n }\n return [\n Object.freeze({\n code: DOT_LOSS.CHARSET_REWRITTEN,\n message: `graph attribute charset ${JSON.stringify(declared)} is written as \"UTF-8\", the encoding the file is written in`,\n column: column.meta.name,\n count: 1,\n }),\n ];\n}\n\n/**\n * Whether a graph column is the `charset` attribute, which must name the encoding the file is written in.\n * @param column - the column\n * @returns true for the charset column\n */\nfunction isCharset(column: Column): boolean {\n return column.meta.name.toLowerCase() === \"charset\";\n}\n\n/** The roles DOT has a slot for (the label attribute, key, ports, clusters); every other role is reported. */\nconst KEPT_ROLES: ReadonlySet<string> = new Set([\"label\", \"id\", \"sourcePort\", \"targetPort\", \"parent\"]);\n\n/** The column name the importer gives each mapped role on re-import. */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: LABEL_ATTRIBUTE,\n id: KEY_ATTRIBUTE,\n sourcePort: SOURCE_PORT_COLUMN,\n targetPort: TARGET_PORT_COLUMN,\n parent: PARENT_COLUMN,\n position: POS_ATTRIBUTE,\n});\n\nconst CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"optional\",\n idCharset: \"any\",\n dtypes: [\"bool\", \"i32\", \"f64\", \"string\"],\n components: false,\n lists: false,\n json: false,\n defaults: false,\n options: false,\n hierarchy: true,\n temporal: \"none\",\n graphAttributes: true,\n positions: true,\n viz: false,\n});\n\nconst DEFAULT_INDENT = \" \";\nconst CLUSTER_PREFIX = \"cluster\";\nconst COMPASS_POINTS: ReadonlySet<string> = new Set([\"n\", \"ne\", \"e\", \"se\", \"s\", \"sw\", \"w\", \"nw\", \"c\", \"_\"]);\n\n/** Roles never written as attributes, per domain. */\nconst SKIPPED_NODE_ROLES: ReadonlySet<string> = new Set([\n \"parent\",\n \"parents\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n \"timeText\",\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n]);\nconst SKIPPED_EDGE_ROLES: ReadonlySet<string> = new Set([\n \"id\",\n \"weight\",\n \"directed\",\n \"pair\",\n \"mutual\",\n \"sourcePort\",\n \"targetPort\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n \"timeText\",\n \"parent\",\n \"parents\",\n]);\nconst SKIPPED_GRAPH_ROLES: ReadonlySet<string> = new Set([\"position\", \"color\", \"size\", \"shape\", \"thickness\"]);\n/** Text columns whose values are read back as text regardless of their spelling (no TEXT_INFERRED note). */\nconst TEXT_ROLES: ReadonlySet<string> = new Set([\"label\", \"id\", \"sourcePort\", \"targetPort\"]);\n\n/**\n * The exporter plugin for DOT / Graphviz text.\n * @category Built-in formats\n */\nexport const dotExporter: GraphExporter<DotExportOptions> = Object.freeze({\n format: DOT_FORMAT,\n options: Object.freeze([\"indent\", \"name\", \"strict\"]),\n capabilities: CAPABILITIES,\n styles: Object.freeze({ capabilities: DOT_STYLE_CAPABILITIES }),\n\n /**\n * Pre-flight: every loss the DOT text would incur, without writing anything; with styles, also the values\n * written as the nearest ones Graphviz has.\n * @param snapshot - the snapshot to check\n * @param options - format-specific and common options\n * @returns the notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: DotWriteOptions): readonly LossNote[] {\n const styled = dotStyledExport(snapshot, options?.styles, options?.onMixedDirection);\n if (styled === null) {\n return checkPlain(snapshot, options);\n }\n return Object.freeze([...checkPlain(styled.snapshot, options), ...styled.notes]);\n },\n\n /**\n * Write the snapshot as UTF-8 chunks.\n * @param snapshot - the snapshot to write\n * @param options - format-specific and common options\n * @returns the encoded chunks\n */\n export(snapshot: GraphSnapshot, options?: DotWriteOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(\n writeDot(\n dotStyledExport(snapshot, options?.styles, options?.onMixedDirection)?.snapshot ?? snapshot,\n options,\n ),\n );\n },\n\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot to write\n * @param options - format-specific and common options\n * @returns the whole document\n */\n exportToString(snapshot: GraphSnapshot, options?: DotWriteOptions): Promise<string> {\n return joinText(\n writeDot(\n dotStyledExport(snapshot, options?.styles, options?.onMixedDirection)?.snapshot ?? snapshot,\n options,\n ),\n );\n },\n});\n\n/**\n * Every loss the DOT text of a snapshot would incur.\n * @param snapshot - the snapshot to check\n * @param options - format-specific and common options\n * @returns the notes\n */\nfunction checkPlain(snapshot: GraphSnapshot, options?: DotExportOptions & CommonExportOptions): LossNote[] {\n const resolved = resolveExportOptions(options);\n const notes = checkCapabilities(snapshot, CAPABILITIES, resolved, {\n positionDtype: \"f64\",\n roles: KEPT_ROLES,\n roleNames: ROLE_NAMES,\n });\n const plan = new ExportPlan(snapshot, resolved, options);\n return [...notes, ...plan.notes()];\n}\n\n/**\n * The text parts of a DOT document.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @yields one statement (or header / footer) at a time\n * @returns nothing\n */\nfunction* writeDot(snapshot: GraphSnapshot, options?: DotExportOptions & CommonExportOptions): Generator<string> {\n const resolved = resolveExportOptions(options);\n const plan = new ExportPlan(snapshot, resolved, options);\n plan.refuse();\n yield* plan.write();\n}\n\n/**\n * Whether a text ends in a backslash, which a DOT quoted string cannot carry (the lexer would read\n * the backslash and the closing quote as an escaped quote; common/escape.ts isWritableDotText).\n * @param text - the text\n * @returns true when unwritable\n */\nfunction endsWithBackslash(text: string): boolean {\n return !isWritableDotText(text);\n}\n\n/**\n * Write a text as a DOT ID: an HTML string bare, everything else through quoteDotId.\n * @param text - the text\n * @returns the DOT ID\n */\nfunction writeId(text: string): string {\n return isHtmlString(text) ? text : quoteDotId(text);\n}\n\n/**\n * Write a port text (`f0`, `f0:ne`, `ne`) as its DOT spelling after the endpoint.\n * @param port - the port text\n * @returns `:port[:compass]`\n */\nfunction writePort(port: string): string {\n const colon = port.lastIndexOf(\":\");\n if (colon > 0 && COMPASS_POINTS.has(port.slice(colon + 1))) {\n return `:${quoteDotId(port.slice(0, colon))}:${port.slice(colon + 1)}`;\n }\n return `:${quoteDotId(port)}`;\n}\n\n/**\n * Whether a column can be written as attribute text: every scalar dtype; lists and json cannot.\n * @param column - the column\n * @returns true when writable\n */\nfunction isTextualDtype(column: Column): boolean {\n return column.dtype !== \"list\" && column.dtype !== \"json\";\n}\n\n/**\n * The E_UNSUPPORTED error of a DOT option with a value of the wrong type.\n * @param option - the option name\n * @param found - the caller's value\n * @param expected - what the option takes, in words\n * @returns the error\n */\nfunction badOption(option: string, found: unknown, expected: string): GraphFormatError {\n return new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option ${option} of the DOT exporter: expected ${expected}, got ${JSON.stringify(found)}`,\n {\n option,\n found,\n },\n );\n}\n\n/**\n * Everything one export needs to know about a snapshot, computed once and shared by check() and\n * write(): the output direction, the columns written per table, the cluster structure, and the\n * format-specific loss notes.\n */\n\n/** A note-recording callback. */\ntype DotNote = (code: string, message: string, column?: string | null, count?: number | null) => void;\n\n/**\n * The notes of one node, edge or graph column: dropped when empty, read back with the label role, non-finite\n * numbers and text that reads back typed.\n * @param label - node, edge or graph\n * @param column - the column\n * @param note - the recorder\n */\nfunction columnNotes(label: \"node\" | \"edge\" | \"graph\", column: Column, note: DotNote): void {\n const { name, role } = column.meta;\n const text = column.dtype === \"string\" || column.dtype === \"dict\";\n if (label !== \"graph\" && column.nullCount === column.length) {\n note(\n DOT_LOSS.EMPTY_COLUMN_DROPPED,\n `${label} column \"${name}\" has no set cell and is not written: DOT writes cells, never declarations`,\n name,\n 0,\n );\n return;\n }\n if (label !== \"graph\" && role === null && name === LABEL_ATTRIBUTE && text) {\n note(\n DOT_LOSS.ROLE_ASSUMED,\n `${label} column \"${name}\" reads back with the label role`,\n name,\n column.length - column.nullCount,\n );\n }\n const bad = column.dtype === \"f32\" || column.dtype === \"f64\" ? countNonFinite(column) : 0;\n if (bad > 0) {\n note(\n DOT_LOSS.NON_FINITE,\n `${label} column \"${name}\" holds ${bad} non-finite value${plural(bad)} with no numeric DOT spelling; they read back as text`,\n name,\n bad,\n );\n }\n const typed = text && (role === null || !TEXT_ROLES.has(role)) ? countTypedLookingText(column) : 0;\n if (typed > 0) {\n note(\n DOT_LOSS.TEXT_INFERRED,\n `${label} column \"${name}\" holds ${typed} text value${plural(typed)} that look like numbers or booleans; DOT values are untyped and they read back as such`,\n name,\n typed,\n );\n }\n}\n\n/**\n * The notes of position columns DOT cannot write: a node position of other than 2 or 3 components, and any edge or\n * graph position.\n * @param snapshot - the snapshot\n * @param position - the node position column, or null\n * @param note - the recorder\n */\nfunction positionNotes(snapshot: GraphSnapshot, position: Column | null, note: DotNote): void {\n if (position !== null && position.meta.components !== 2 && position.meta.components !== 3) {\n note(\n DOT_LOSS.POSITION_SHAPE,\n `node column \"${position.meta.name}\" (position) has ${position.meta.components} components and is not written; pos takes 2 or 3`,\n position.meta.name,\n position.length - position.nullCount,\n );\n }\n for (const [label, table] of [\n [\"edge\", snapshot.edges],\n [\"graph\", snapshot.graph],\n ] as const) {\n const column = table.byRole(\"position\");\n if (column !== null) {\n note(\n DOT_LOSS.POSITION_SHAPE,\n `${label} column \"${column.meta.name}\" (position) is not written; only node positions map to pos`,\n column.meta.name,\n column.length - column.nullCount,\n );\n }\n }\n}\n\nclass ExportPlan {\n private readonly snapshot: GraphSnapshot;\n\n private readonly resolved: ResolvedExportOptions;\n\n private readonly indent: string;\n\n private readonly name: string | null;\n\n private readonly strict: boolean;\n\n private readonly mixed: number;\n\n private readonly directed: boolean;\n\n private readonly nodeColumns: Column[];\n\n private readonly edgeColumns: Column[];\n\n private readonly graphColumns: Column[];\n\n private readonly position: Column | null;\n\n private readonly positionDims: 2 | 3;\n\n private readonly parent: Column | null;\n\n private readonly cluster: Column | null;\n\n private readonly edgeId: Column | null;\n\n private readonly weights: ExplicitWeights;\n\n private readonly folding: PairFolding;\n\n private readonly sourcePort: Column | null;\n\n private readonly targetPort: Column | null;\n\n /** The node and edge label role columns, written under `label` whatever their name. */\n private readonly nodeLabel: Column | null;\n\n private readonly edgeLabel: Column | null;\n\n private readonly children: ChildrenCsr;\n\n private readonly extraNotes: LossNote[] = [];\n\n /**\n * Plan one export.\n * @param snapshot - the snapshot\n * @param resolved - the resolved common options\n * @param options - the caller's options (format-specific fields read here)\n */\n constructor(snapshot: GraphSnapshot, resolved: ResolvedExportOptions, options?: DotExportOptions) {\n this.snapshot = snapshot;\n this.resolved = resolved;\n const { indent, name, strict } = options ?? {};\n if (name !== undefined && name !== null && typeof name !== \"string\") {\n throw badOption(\"name\", name, \"a string or null\");\n }\n if (strict !== undefined && typeof strict !== \"boolean\") {\n throw badOption(\"strict\", strict, \"a boolean\");\n }\n this.indent = indentUnit(indent, DEFAULT_INDENT);\n this.name = name === undefined ? snapshot.meta.name : name;\n this.strict = strict ?? isStrictMeta(snapshot);\n this.mixed = countMixedEdges(snapshot);\n if (this.mixed > 0 && resolved.onMixedDirection !== \"error\") {\n this.directed = resolved.onMixedDirection === \"directed\";\n } else {\n this.directed = snapshot.directed;\n }\n const { nodes, edges, graph } = snapshot;\n this.position = nodes.byRole(\"position\");\n this.positionDims = positionDims(this.position);\n this.parent = nodes.byRole(\"parent\");\n const cluster = nodes.get(CLUSTER_COLUMN);\n this.cluster = cluster !== null && cluster.dtype === \"bool\" ? cluster : null;\n this.edgeId = edges.byRole(\"id\");\n this.weights = explicitWeights(snapshot);\n this.folding = pairFolding(snapshot);\n this.sourcePort = edges.byRole(\"sourcePort\");\n this.targetPort = edges.byRole(\"targetPort\");\n this.nodeLabel = nodes.byRole(\"label\");\n this.edgeLabel = edges.byRole(\"label\");\n this.nodeColumns = [...nodes].filter((c) => this.writesNodeColumn(c));\n this.edgeColumns = [...edges].filter((c) => this.writesEdgeColumn(c));\n this.graphColumns = [...graph].filter(\n (c) => isTextualDtype(c) && (c.meta.role === null || !SKIPPED_GRAPH_ROLES.has(c.meta.role)),\n );\n this.children = childrenCsr(snapshot, {\n column: this.parent !== null && this.parent.dtype === \"u32\" ? this.parent : null,\n });\n // in the order a reader first meets them, which is the order it gives the columns: the file read and written\n // again is the same, whichever node or edge first held a column\n this.nodeColumns = firstSeenOrder(this.nodeColumns, this.nodeTextOrder());\n const edgeRows: number[] = [];\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (!this.folding.folded(e)) {\n edgeRows.push(e);\n }\n }\n this.edgeColumns = firstSeenOrder(this.edgeColumns, edgeRows);\n }\n\n /**\n * The nodes in the order a reader of the document takes their attributes: a node's statement before the members\n * of its cluster, and a cluster's own `graph [...]` attributes when its subgraph closes, after its members.\n * @returns the node indices\n */\n private nodeTextOrder(): number[] {\n const order: number[] = [];\n const seen = new Uint8Array(this.snapshot.nodeCount);\n // a negative entry -(i + 1) is cluster i's own attributes, taken once its members are\n const stack: number[] = [];\n for (let root = this.snapshot.nodeCount - 1; root >= 0; root--) {\n stack.push(root);\n }\n while (stack.length > 0) {\n const i = stack.pop() as number;\n if (i < 0) {\n order.push(-i - 1);\n continue;\n }\n if (seen[i] === 1) {\n continue;\n }\n seen[i] = 1;\n const marked = this.cluster !== null && this.cluster.isSet(i) && this.cluster.value(i) === true;\n if (marked) {\n stack.push(-i - 1);\n } else {\n order.push(i);\n }\n const kids = this.children.childrenOf(i);\n for (let k = kids.length - 1; k >= 0; k--) {\n stack.push(kids[k]);\n }\n }\n return order;\n }\n\n /**\n * Whether a node column is written as node attributes.\n * @param column - the column\n * @returns true when written\n */\n private writesNodeColumn(column: Column): boolean {\n const { name, role } = column.meta;\n if (!isTextualDtype(column) || name === CLUSTER_COLUMN) {\n return false;\n }\n if (role !== null && SKIPPED_NODE_ROLES.has(role)) {\n return false;\n }\n if (name === POS_ATTRIBUTE && role !== \"position\") {\n this.clash(\"node\", name, \"the position role is written as pos\");\n return false;\n }\n return this.labelFree(\"node\", column, this.nodeLabel);\n }\n\n /**\n * Whether an edge column is written as edge attributes.\n * @param column - the column\n * @returns true when written\n */\n private writesEdgeColumn(column: Column): boolean {\n const { name, role } = column.meta;\n if (!isTextualDtype(column)) {\n return false;\n }\n if (role !== null && SKIPPED_EDGE_ROLES.has(role)) {\n return false;\n }\n if (name === KEY_ATTRIBUTE && this.edgeId !== null) {\n this.clash(\"edge\", name, \"the edge id role is written as key\");\n return false;\n }\n if (name === \"weight\") {\n this.clash(\"edge\", name, \"the weight is written as weight\");\n return false;\n }\n return this.labelFree(\"edge\", column, this.edgeLabel);\n }\n\n /**\n * Whether a column may be written: false (reported) for a plain `label` column when the label\n * role column is named otherwise, since that one is written as `label`.\n * @param domain - the table\n * @param column - the column\n * @param labelRole - the table's label role column, or null\n * @returns true when written\n */\n private labelFree(domain: string, column: Column, labelRole: Column | null): boolean {\n if (column.meta.name !== LABEL_ATTRIBUTE || labelRole === null || labelRole === column) {\n return true;\n }\n this.clash(domain, column.meta.name, \"the label role is written as label\");\n return false;\n }\n\n /**\n * Record a column not written because its name is an attribute the exporter writes for a role.\n * @param domain - the table\n * @param name - the column name\n * @param reason - why\n */\n private clash(domain: string, name: string, reason: string): void {\n this.extraNotes.push(\n Object.freeze({\n code: DOT_LOSS.ATTRIBUTE_CLASH,\n message: `${domain} column \"${name}\" has no role and is not written: ${reason}`,\n column: name,\n count: null,\n }),\n );\n }\n\n /**\n * The format-specific loss notes (the generic ones come from checkCapabilities).\n * @returns the notes\n */\n notes(): LossNote[] {\n const notes: LossNote[] = [...this.extraNotes];\n const note: DotNote = (code, message, column = null, count = null) => {\n notes.push(Object.freeze({ code, message, column, count }));\n };\n const { snapshot } = this;\n const unwritable = this.countUnwritable();\n if (unwritable > 0) {\n note(\n DOT_LOSS.TRAILING_BACKSLASH,\n `${unwritable} ids, names or text values hold a backslash before a quote or a line break, or at the end, which a DOT quoted string cannot carry; the save fails`,\n null,\n unwritable,\n );\n }\n for (const [label, columns] of [\n [\"node\", this.nodeColumns],\n [\"edge\", this.edgeColumns],\n [\"graph\", this.graphColumns],\n ] as const) {\n for (const column of columns) {\n if (label === \"graph\") {\n notes.push(...charsetNotes(column));\n }\n columnNotes(label, column, note);\n }\n }\n this.structureNotes(note);\n positionNotes(snapshot, this.position, note);\n const textIds = countTextIds(snapshot);\n if (textIds > 0) {\n note(\n DOT_LOSS.ID_TEXT_TYPE,\n `${textIds} node id${plural(textIds)} ${agree(textIds, \"reads\", \"read\")} back as the other type under ids: \"canonical\" (a string \"1\" becomes 1, a number 1.5 becomes \"1.5\")`,\n null,\n textIds,\n );\n }\n return notes;\n }\n\n /**\n * The notes of the graph's structure DOT changes: parents written as clusters, mutual pairs and parents lists.\n * @param note - the recorder\n */\n private structureNotes(note: DotNote): void {\n const { snapshot } = this;\n let unmarked = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const marked = this.cluster?.isSet(i) === true && this.cluster.value(i) === true;\n if (!marked && this.children.childrenOf(i).length > 0) {\n unmarked++;\n }\n }\n if (unmarked > 0) {\n note(\n DOT_LOSS.CLUSTER_MARKED,\n `${unmarked} parent node${plural(unmarked)} ${agree(unmarked, \"is\", \"are\")} written as a node and a cluster of the same name and read back with \"${CLUSTER_COLUMN}\" true`,\n CLUSTER_COLUMN,\n unmarked,\n );\n }\n const mutual = this.folding.mutualCount;\n if (mutual > 0) {\n note(\n DOT_LOSS.MUTUAL_EXPANDED,\n `${mutual} mutual pair${plural(mutual)} ${agree(mutual, \"is\", \"are\")} written as two directed edges each; the mutual mark is lost`,\n null,\n mutual,\n );\n }\n const parents = snapshot.nodes.byRole(\"parents\");\n if (parents !== null) {\n note(\n DOT_LOSS.PARENTS_DROPPED,\n `node column \"${parents.meta.name}\" (parents) cannot be written: a DOT node is in one cluster`,\n parents.meta.name,\n parents.length - parents.nullCount,\n );\n }\n }\n\n /**\n * Throw for the conditions check() reports as errors: mixed direction under \"error\", and an\n * unwritable id / name / text.\n */\n refuse(): void {\n if (this.mixed > 0 && this.resolved.onMixedDirection === \"error\") {\n throw new GraphFormatError(\n \"E_DIRECTED\",\n `${this.mixed} undirected edge${plural(this.mixed)} in a directed graph, and DOT holds one direction per file, so the save fails unless onMixedDirection is \"directed\" or \"undirected\"`,\n { reason: LOSS.MIXED_DIRECTION_ERROR, count: this.mixed },\n );\n }\n const first = this.firstUnwritable();\n if (first !== null) {\n throw new GraphFormatError(\n first.kind === \"id\" ? \"E_INVALID_ID\" : \"E_COLUMN_TYPE\",\n `${first.kind} ${JSON.stringify(first.text)} holds a backslash before a quote or a line break, or at its end, which a DOT quoted string cannot carry`,\n { reason: \"trailing backslash\", kind: first.kind, value: first.text },\n );\n }\n sanitizeIds(this.snapshot, CAPABILITIES.idCharset, this.resolved.sanitizeIds);\n }\n\n /**\n * How many ids, names and text values end in a backslash.\n * @returns the count\n */\n private countUnwritable(): number {\n let count = 0;\n this.forEachText((text) => {\n if (endsWithBackslash(text)) {\n count++;\n }\n });\n return count;\n }\n\n /**\n * The first id, name or text value ending in a backslash.\n * @returns what it is and its text, or null\n */\n private firstUnwritable(): { kind: string; text: string } | null {\n let found: { kind: string; text: string } | null = null;\n this.forEachText((text, kind) => {\n if (found === null && endsWithBackslash(text)) {\n found = { kind, text };\n }\n });\n return found;\n }\n\n /**\n * Visit every text the document writes as a quoted string: the graph name, node ids, column\n * names and string / dict cells.\n * @param visit - the visitor\n */\n private forEachText(visit: (text: string, kind: string) => void): void {\n const { snapshot } = this;\n if (this.name !== null) {\n visit(this.name, \"graph name\");\n }\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id = snapshot.ids.idOf(i);\n if (typeof id === \"string\") {\n visit(id, \"id\");\n }\n }\n for (const columns of [this.nodeColumns, this.edgeColumns, this.graphColumns]) {\n for (const column of columns) {\n visit(this.attributeName(column), \"attribute name\");\n if (column.dtype === \"string\" || column.dtype === \"dict\") {\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r)) {\n visit(column.value(r) as string, \"value\");\n }\n }\n }\n }\n }\n for (const column of [this.edgeId, this.sourcePort, this.targetPort]) {\n if (column !== null && (column.dtype === \"string\" || column.dtype === \"dict\")) {\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r)) {\n visit(column.value(r) as string, \"value\");\n }\n }\n }\n }\n }\n\n /**\n * The document, one statement per part.\n * @yields the parts\n * @returns nothing\n */\n *write(): Generator<string> {\n const { snapshot, indent } = this;\n const keyword = this.directed ? \"digraph\" : \"graph\";\n const name = this.name === null ? \"\" : ` ${quoteDotId(this.name)}`;\n yield `${this.strict ? \"strict \" : \"\"}${keyword}${name} {\\n`;\n const graphAttributes = this.attributesOf(this.graphColumns, 0);\n if (graphAttributes.length > 0) {\n yield `${indent}graph [${graphAttributes.join(\", \")}];\\n`;\n }\n const emitted = new Uint8Array(snapshot.nodeCount);\n for (let i = 0; i < snapshot.nodeCount; i++) {\n yield* this.writeNode(i, 1, emitted);\n }\n yield* this.writeEdges();\n yield \"}\\n\";\n }\n\n /**\n * Write one node (and, for a container, its cluster block with the members nested).\n * @param i - the node index\n * @param depth - the nesting depth\n * @param emitted - which nodes were written already\n * @yields the statements\n * @returns nothing\n */\n private *writeNode(i: number, depth: number, emitted: Uint8Array): Generator<string> {\n if (emitted[i] === 1) {\n return;\n }\n emitted[i] = 1;\n const pad = this.indent.repeat(depth);\n const idText = this.idText(i);\n const kids = this.children.childrenOf(i);\n const marked = this.cluster !== null && this.cluster.isSet(i) && this.cluster.value(i) === true;\n if (kids.length === 0 && !marked) {\n yield `${pad}${this.nodeStatement(i, idText)};\\n`;\n return;\n }\n if (!marked) {\n // a real node that is also a parent: its cells are node attributes, the cluster only groups\n yield `${pad}${this.nodeStatement(i, idText)};\\n`;\n }\n const inner = `${pad}${this.indent}`;\n yield `${pad}subgraph ${writeId(idText)} {\\n`;\n if (!idText.startsWith(CLUSTER_PREFIX)) {\n yield `${inner}cluster=true;\\n`;\n }\n if (marked) {\n const attributes = this.nodeAttributes(i);\n if (attributes.length > 0) {\n yield `${inner}graph [${attributes.join(\", \")}];\\n`;\n }\n }\n for (const child of kids) {\n if (emitted[child] === 1) {\n yield `${inner}${writeId(this.idText(child))};\\n`;\n } else {\n yield* this.writeNode(child, depth + 1, emitted);\n }\n }\n yield `${pad}}\\n`;\n }\n\n /**\n * A node statement without its terminator.\n * @param i - the node index\n * @param idText - the id text\n * @returns `id` or `id [attrs]`\n */\n private nodeStatement(i: number, idText: string): string {\n const attributes = this.nodeAttributes(i);\n return attributes.length === 0 ? writeId(idText) : `${writeId(idText)} [${attributes.join(\", \")}]`;\n }\n\n /**\n * The attributes of a node: its set cells plus `pos` from the position column.\n * @param i - the node index\n * @returns the attribute texts\n */\n private nodeAttributes(i: number): string[] {\n const attributes = this.attributesOf(this.nodeColumns, i);\n const pos = this.positionText(i);\n if (pos !== null) {\n attributes.push(`${POS_ATTRIBUTE}=${quoteDotId(pos)}`);\n }\n return attributes;\n }\n\n /**\n * The `pos` text of a node, or null when it has none.\n * @param i - the node index\n * @returns `x,y` or `x,y,z`\n */\n private positionText(i: number): string | null {\n const column = this.position;\n if (!column?.isSet(i)) {\n return null;\n }\n if (column.dtype !== \"f32\" && column.dtype !== \"f64\" && column.dtype !== \"i32\") {\n return null;\n }\n const { components } = column.meta;\n if (components !== 2 && components !== 3) {\n return null;\n }\n const format = column.dtype === \"f32\" ? formatF32 : formatF64;\n const base = i * components;\n const { data } = column;\n const parts = [format(data[base]), format(data[base + 1])];\n if (this.positionDims === 3) {\n parts.push(format(components === 3 ? data[base + 2] : 0));\n }\n return parts.join(\",\");\n }\n\n /**\n * The attribute a column is written as: `label` for a node or edge label role column (the\n * importer gives that attribute the role back), the column name otherwise.\n * @param column - the column\n * @returns the attribute name\n */\n private attributeName(column: Column): string {\n return column === this.nodeLabel || column === this.edgeLabel ? LABEL_ATTRIBUTE : column.meta.name;\n }\n\n /**\n * The `name=value` attributes of one row over a column list (set cells only).\n * @param columns - the columns\n * @param row - the row\n * @returns the attribute texts\n */\n private attributesOf(columns: readonly Column[], row: number): string[] {\n const out: string[] = [];\n for (const column of columns) {\n if (!column.isSet(row)) {\n continue;\n }\n let text = cellText(column, row);\n if (text !== null && columns === this.graphColumns && isCharset(column) && !UTF8_CHARSET.test(text)) {\n text = \"UTF-8\";\n }\n if (text !== null) {\n out.push(`${quoteDotId(this.attributeName(column))}=${writeId(text)}`);\n }\n }\n return out;\n }\n\n /**\n * Every logical edge in index order, mirror halves of expanded undirected pairs folded away.\n * @yields the edge statements\n * @returns nothing\n */\n private *writeEdges(): Generator<string> {\n const { snapshot, indent } = this;\n const list = snapshot.edgeList();\n const op = this.directed ? \"->\" : \"--\";\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (this.folding.folded(e)) {\n continue;\n }\n const attributes = this.attributesOf(this.edgeColumns, e);\n const weight = this.weights.text(e);\n if (weight !== null) {\n attributes.unshift(`weight=${quoteDotId(weight)}`);\n }\n const key = this.keyText(e);\n if (key !== null) {\n attributes.unshift(`${KEY_ATTRIBUTE}=${writeId(key)}`);\n }\n const source = `${writeId(this.idText(list.src[e]))}${this.portText(this.sourcePort, e)}`;\n const target = `${writeId(this.idText(list.dst[e]))}${this.portText(this.targetPort, e)}`;\n const tail = attributes.length === 0 ? \"\" : ` [${attributes.join(\", \")}]`;\n yield `${indent}${source} ${op} ${target}${tail};\\n`;\n }\n }\n\n /**\n * The edge id of an edge as `key` text, or null.\n * @param e - the edge index\n * @returns the text\n */\n private keyText(e: number): string | null {\n const column = this.edgeId;\n if (!column?.isSet(e)) {\n return null;\n }\n if (column.dtype === \"f32\" || column.dtype === \"f64\") {\n return formatF64(column.data[e]);\n }\n return cellText(column, e);\n }\n\n /**\n * The port suffix of an endpoint.\n * @param column - the port column, or null\n * @param e - the edge index\n * @returns `:port` or \"\"\n */\n private portText(column: Column | null, e: number): string {\n if (!column?.isSet(e)) {\n return \"\";\n }\n const text = cellText(column, e);\n return text === null || text.length === 0 ? \"\" : writePort(text);\n }\n\n /**\n * The id text of a node.\n * @param i - the node index\n * @returns String(id)\n */\n private idText(i: number): string {\n return idText(this.snapshot.ids.idOf(i));\n }\n}\n\n/**\n * Whether the snapshot's meta records a strict graph.\n * @param snapshot - the snapshot\n * @returns true when meta.extra.dot.strict is true\n */\nfunction isStrictMeta(snapshot: GraphSnapshot): boolean {\n const dot: unknown = snapshot.meta.extra[DOT_META_KEY];\n return typeof dot === \"object\" && dot !== null && (dot as { strict?: unknown }).strict === true;\n}\n\n/**\n * The dimensions `pos` is written with: what the importer recorded in extra.sourceDims, else 2\n * for a 2-component column and 3 otherwise.\n * @param column - the position column, or null\n * @returns 2 or 3\n */\nfunction positionDims(column: Column | null): 2 | 3 {\n if (column === null) {\n return 2;\n }\n const dims: unknown = column.meta.extra.sourceDims;\n if (dims === 2 || dims === 3) {\n return dims;\n }\n return column.meta.components === 2 ? 2 : 3;\n}\n\n/**\n * Columns in the order the rows first hold a written value of each; a column no row writes keeps its place at the end.\n * @param columns - the columns, in the snapshot's order\n * @param rows - the rows in the order the document writes them\n * @returns the columns\n */\nfunction firstSeenOrder(columns: readonly Column[], rows: Iterable<number>): Column[] {\n const left = new Set(columns);\n const out: Column[] = [];\n for (const row of rows) {\n if (left.size === 0) {\n break;\n }\n for (const column of columns) {\n if (left.has(column) && column.isSet(row) && cellText(column, row) !== null) {\n out.push(column);\n left.delete(column);\n }\n }\n }\n return [...out, ...left];\n}\n\n/**\n * The attribute text of one set cell, or null for a dtype the format cannot write.\n * @param column - the column\n * @param row - the row\n * @returns the text\n */\nfunction cellText(column: Column, row: number): string | null {\n switch (column.dtype) {\n case \"bool\":\n return column.value(row) === true ? \"true\" : \"false\";\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return numericText(column, row, formatInteger);\n case \"f32\":\n return numericText(column, row, (v) => formatDecimal(v, \"f32\"));\n case \"f64\":\n return numericText(column, row, (v) => formatDecimal(v, \"f64\"));\n case \"dict\":\n case \"string\":\n return column.value(row) ?? \"\";\n case \"list\":\n case \"json\":\n return null;\n default: {\n const name: string = (column as Column).dtype;\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `unknown dtype ${name}`, { dtype: name });\n }\n }\n}\n\n/**\n * The text of a numeric cell: one number, or the `components` numbers joined by commas.\n * @param column - a numeric column\n * @param row - the row\n * @param format - the per-number formatter\n * @returns the text\n */\nfunction numericText(\n column: Column & { readonly data: ArrayLike<number> },\n row: number,\n format: (value: number) => string,\n): string {\n const { components } = column.meta;\n if (components === 1) {\n return format(column.data[row]);\n }\n const parts: string[] = [];\n for (let k = 0; k < components; k++) {\n parts.push(format(column.data[row * components + k]));\n }\n return parts.join(\",\");\n}\n\n/**\n * How many set cells of an f32 / f64 column are non-finite.\n * @param column - the column\n * @returns the count\n */\nfunction countNonFinite(column: Column): number {\n if (column.dtype !== \"f32\" && column.dtype !== \"f64\") {\n return 0;\n }\n const { components } = column.meta;\n let count = 0;\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n for (let k = 0; k < components; k++) {\n if (!Number.isFinite(column.data[r * components + k])) {\n count++;\n break;\n }\n }\n }\n return count;\n}\n\n/**\n * How many set cells of a text column read back as something other than text under the 5.1 grammar.\n * @param column - a string or dict column\n * @returns the count\n */\nfunction countTypedLookingText(column: Column): number {\n if (column.dtype !== \"string\" && column.dtype !== \"dict\") {\n return 0;\n }\n let count = 0;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && inferTextDtype(column.value(r) ?? \"\") !== \"string\") {\n count++;\n }\n }\n return count;\n}\n\n/**\n * How many ids read back as the other type under the canonical rule: numeric ids that are not\n * canonical integer text (read back as strings) and string ids that are (read back as numbers).\n * @param snapshot - the snapshot\n * @returns the count\n */\nfunction countTextIds(snapshot: GraphSnapshot): number {\n const { ids } = snapshot;\n if (ids.kind === \"identity\" || ids.kind === \"dense\") {\n return 0;\n }\n let count = 0;\n for (let i = 0; i < ids.size; i++) {\n const id = ids.idOf(i);\n if (canonicalId(idText(id)) !== id) {\n count++;\n }\n }\n return count;\n}\n","/**\n * How a DOT file's `pos` values are spelled, for `extractPositions()`: the node's center, y up.\n * Graphviz layout output (the root graph has `bb`) is in points; input `pos` for neato and fdp is\n * in inches. Each cluster's `bb` gives its container node a box.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { median } from \"../../positions/convert.js\";\nimport type { ImporterGroupBox, ImporterPositions } from \"../../positions/types.js\";\n\n/** Points per inch: node `width` is in inches, laid-out coordinates in points. */\nconst POINTS_PER_INCH = 72;\n\n/**\n * The spelling of a DOT file's positions.\n * @param snapshot - the graph the DOT importer read\n * @returns the spelling, or null when no node has a position\n */\nexport function dotPositions(snapshot: GraphSnapshot): ImporterPositions | null {\n if (snapshot.nodes.byRole(\"position\") === null) {\n return null;\n }\n const bb = snapshot.graph.get(\"bb\");\n const laidOut = bb !== null && bb.isSet(0) && boxOf(bb.value(0)) !== null;\n const width = snapshot.nodes.get(\"width\");\n const widths: number[] = [];\n for (let row = 0; width !== null && row < width.length; row++) {\n const w = width.isSet(row) ? Number(width.value(row)) : Number.NaN;\n if (Number.isFinite(w)) {\n widths.push(laidOut ? w * POINTS_PER_INCH : w);\n }\n }\n return {\n units: laidOut ? \"px\" : \"file\",\n // input inches are drawn beside the styles' point lengths at 72 points each\n ...(laidOut ? {} : { pxPerUnit: POINTS_PER_INCH }),\n yAxis: \"up\",\n groups: clusterBoxes(snapshot),\n medianNodeSize: median(widths),\n ...(laidOut ? { tool: \"graphviz\" } : {}),\n };\n}\n\n/**\n * The boxes of the cluster container nodes that carry a `bb`.\n * @param snapshot - the graph\n * @returns one box per container, centered, y up\n */\nfunction clusterBoxes(snapshot: GraphSnapshot): ImporterGroupBox[] {\n const bb = snapshot.nodes.get(\"bb\");\n const out: ImporterGroupBox[] = [];\n for (let node = 0; bb !== null && node < bb.length; node++) {\n const box = bb.isSet(node) ? boxOf(bb.value(node)) : null;\n if (box !== null) {\n out.push({ node, box });\n }\n }\n return out;\n}\n\n/**\n * A Graphviz `bb` (\"llx,lly,urx,ury\", y up) as a centered box.\n * @param value - the attribute value\n * @returns the box, or null when the value is not four finite numbers\n */\nfunction boxOf(value: unknown): ImporterGroupBox[\"box\"] | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const parts = value.split(\",\").map(Number);\n if (parts.length !== 4 || !parts.every(Number.isFinite)) {\n return null;\n }\n const [llx, lly, urx, ury] = parts;\n return { x: (llx + urx) / 2, y: (lly + ury) / 2, width: urx - llx, height: ury - lly };\n}\n","/**\n * The DOT lexer (graphviz.org/doc/info/lang.html): IDs in their four spellings (an alphanumeric\n * identifier, a numeral, a double-quoted string with `\\\"` as its only escape, backslash pairs\n * consumed as units and backslash-newline as a line continuation, an HTML string in balanced\n * angle brackets), the punctuation of the\n * grammar, the two edge operators, the `+` of quoted-string concatenation, and the three comment\n * forms (`//`, `/* ... *\\/`, and a `#` line, which is C preprocessor output). Keywords are not\n * distinguished here: the parser matches a bare id case-insensitively, since a quoted `\"node\"` is\n * an ordinary id. Line numbers are 1-based and attached to every token for the report.\n */\n\n/** The kinds of token. */\ntype DotTokenKind = \"id\" | \"punct\" | \"eof\";\n\n/**\n * One token of a DOT document.\n * @category Plugin helpers\n */\nexport interface DotToken {\n /** The kind. */\n readonly kind: DotTokenKind;\n /**\n * The decoded text of an id (quotes removed, `\\\"` unescaped, an HTML string kept with its outer\n * angle brackets), the punctuation itself for \"punct\" (`{ } [ ] ; , = : + -> --`), \"\" at the end.\n */\n readonly text: string;\n /** Whether an id was double-quoted (a quoted keyword is an ordinary id). */\n readonly quoted: boolean;\n /** Whether an id was an HTML string. */\n readonly html: boolean;\n /** The 1-based line the token starts on. */\n readonly line: number;\n}\n\n/**\n * The error the lexer and parser throw for a grammar violation; the importer turns it into a fatal parse-error.\n * @category Plugin helpers\n */\nexport class DotSyntaxError extends Error {\n /** The 1-based line of the violation. */\n readonly line: number;\n\n /**\n * Create a syntax error.\n * @param message - a plain-ASCII message\n * @param line - the 1-based line\n */\n constructor(message: string, line: number) {\n super(message);\n this.name = \"DotSyntaxError\";\n this.line = line;\n }\n}\n\nconst EOF_TOKEN_TEXT = \"\";\n\n/**\n * Whether a UTF-16 code unit may start a bare DOT identifier: a letter, an underscore or any code\n * of 128 and above (the grammar's `\\200-\\377` range, read here as every non-ASCII unit).\n * @param c - the code unit\n * @returns true for an identifier start\n */\nfunction isIdentifierStart(c: number): boolean {\n return (c >= 65 && c <= 90) || (c >= 97 && c <= 122) || c === 95 || (c >= 128 && c !== BOM_CODE);\n}\n\n/** U+FEFF: a byte order mark, which only the decoder strips from the very start of the input. */\nconst BOM_CODE = 0xfeff;\n\n/**\n * Whether a UTF-16 code unit may continue a bare DOT identifier. A U+FEFF inside an identifier\n * run stays part of it, as Graphviz keeps its bytes (in its `\\200-\\377` range); only a U+FEFF\n * between tokens is skipped as a stray BOM.\n * @param c - the code unit\n * @returns true for an identifier character\n */\nfunction isIdentifierPart(c: number): boolean {\n return isIdentifierStart(c) || isDigit(c) || c === BOM_CODE;\n}\n\n/**\n * Whether a code unit is an ASCII digit.\n * @param c - the code unit\n * @returns true for 0-9\n */\nfunction isDigit(c: number): boolean {\n return c >= 48 && c <= 57;\n}\n\n/**\n * Whether a code unit is a blank between tokens: space, tab, vertical tab, form feed, or a U+FEFF\n * after the start (concatenated files), which the shared text check reports.\n * @param c - the code unit\n * @returns true for a blank\n */\nfunction isBlank(c: number): boolean {\n return c === 0x20 || c === 0x09 || c === 0x0b || c === 0x0c || c === BOM_CODE;\n}\n\n/**\n * A pull lexer over one DOT document with arbitrary lookahead.\n * @category Plugin helpers\n */\nexport class DotTokenizer {\n private readonly text: string;\n\n private pos = 0;\n\n private line = 1;\n\n private readonly lookahead: DotToken[] = [];\n\n private readonly onAmbiguity: ((numeral: string, line: number) => void) | null;\n\n /**\n * Create a lexer over a whole document.\n * @param text - the DOT text (BOM already removed)\n * @param onAmbiguity - called for a badly delimited numeral (`1e3`, which Graphviz splits into\n * `1` and `e3` with a warning), with the numeral text and its line\n */\n constructor(text: string, onAmbiguity: ((numeral: string, line: number) => void) | null = null) {\n this.text = text;\n this.onAmbiguity = onAmbiguity;\n }\n\n /**\n * Look at a token without consuming it.\n * @param n - how far ahead (0 = the next token)\n * @returns the token; an \"eof\" token past the end\n */\n peek(n = 0): DotToken {\n while (this.lookahead.length <= n) {\n this.lookahead.push(this.lex());\n }\n return this.lookahead[n];\n }\n\n /**\n * Consume the next token.\n * @returns the token; an \"eof\" token past the end\n */\n next(): DotToken {\n const ahead = this.lookahead.shift();\n return ahead ?? this.lex();\n }\n\n /**\n * Produce the next token from the text.\n * @returns the token\n */\n private lex(): DotToken {\n this.skipTrivia();\n const { text } = this;\n if (this.pos >= text.length) {\n return { kind: \"eof\", text: EOF_TOKEN_TEXT, quoted: false, html: false, line: this.line };\n }\n const start = this.pos;\n const { line } = this;\n const c = text.charCodeAt(start);\n switch (c) {\n case 0x7b: // \"{\"\n case 0x7d: // \"}\"\n case 0x5b: // \"[\"\n case 0x5d: // \"]\"\n case 0x3b: // \";\"\n case 0x2c: // \",\"\n case 0x3d: // \"=\"\n case 0x3a: // \":\"\n case 0x2b: // \"+\"\n this.pos++;\n return { kind: \"punct\", text: text[start], quoted: false, html: false, line };\n case 0x2d: {\n // - : an edge operator, or the sign of a numeral\n const d = text.charCodeAt(start + 1);\n if (d === 0x3e || d === 0x2d) {\n this.pos += 2;\n return { kind: \"punct\", text: text.slice(start, start + 2), quoted: false, html: false, line };\n }\n if (isDigit(d) || (d === 0x2e && isDigit(text.charCodeAt(start + 2)))) {\n return this.numeral(start, line);\n }\n throw new DotSyntaxError(\"unexpected '-': not an edge operator or a numeral\", line);\n }\n case 0x22:\n return this.quoted(start, line);\n case 0x3c:\n return this.html(start, line);\n default:\n break;\n }\n if (isIdentifierStart(c)) {\n let end = start + 1;\n while (end < text.length && isIdentifierPart(text.charCodeAt(end))) {\n end++;\n }\n this.pos = end;\n return { kind: \"id\", text: text.slice(start, end), quoted: false, html: false, line };\n }\n if (isDigit(c) || (c === 0x2e && isDigit(text.charCodeAt(start + 1)))) {\n return this.numeral(start, line);\n }\n throw new DotSyntaxError(`unexpected character ${JSON.stringify(text[start])}`, line);\n }\n\n /**\n * Lex a numeral `-?(.[0-9]+ | [0-9]+(.[0-9]*)?)` starting at `start`.\n * @param start - the offset of the first character (a sign, a digit or a dot)\n * @param line - the line\n * @returns the id token holding the numeral text\n */\n private numeral(start: number, line: number): DotToken {\n const { text } = this;\n let end = start;\n if (text.charCodeAt(end) === 0x2d) {\n end++;\n }\n while (end < text.length && isDigit(text.charCodeAt(end))) {\n end++;\n }\n if (text.charCodeAt(end) === 0x2e) {\n end++;\n while (end < text.length && isDigit(text.charCodeAt(end))) {\n end++;\n }\n }\n this.pos = end;\n const numeral = text.slice(start, end);\n const after = text.charCodeAt(end); // NOSONAR(S7758): reads UTF-16 code units on purpose\n // a letter (`1e3`) or a second dot (`1.2.3`) right after the numeral: Graphviz splits there\n if (end < text.length && (isIdentifierStart(after) || after === 0x2e) && this.onAmbiguity !== null) {\n // Graphviz: \"syntax ambiguity - badly delimited number '1e' ... splits into two tokens\"\n this.onAmbiguity(numeral, line);\n }\n return { kind: \"id\", text: numeral, quoted: false, html: false, line };\n }\n\n /**\n * Lex a double-quoted string starting at the opening quote: `\\\"` is the only escape, a\n * backslash followed by a line break is a continuation (both removed), every other backslash is\n * kept as written, and raw line breaks are allowed inside.\n * @param start - the offset of the opening quote\n * @param line - the line of the opening quote\n * @returns the id token holding the decoded text\n */\n private quoted(start: number, line: number): DotToken {\n const { text } = this;\n let out = \"\";\n let segment = start + 1;\n let i = start + 1;\n for (;;) {\n if (i >= text.length) {\n throw new DotSyntaxError(\"unterminated quoted string (missing closing quote)\", line);\n }\n const c = text.charCodeAt(i);\n if (c === 0x22) {\n out += text.slice(segment, i);\n this.pos = i + 1;\n return { kind: \"id\", text: out, quoted: true, html: false, line };\n }\n if (c === 0x5c && this.isQuotedSplice(i)) {\n out += text.slice(segment, i);\n if (text.codePointAt(i + 1) === 0x22) {\n out += '\"';\n }\n i = this.quotedSpliceEnd(i);\n segment = i;\n } else {\n i = this.quotedStep(i, c);\n }\n }\n }\n\n /**\n * Whether the backslash at `i` inside a quoted string starts a sequence that changes the decoded\n * text: `\\\"` (an escaped quote) or a backslash before a line break (a line continuation).\n * @param i - the offset of the backslash\n * @returns true for an escaped quote or a line continuation\n */\n private isQuotedSplice(i: number): boolean {\n const d = this.text.codePointAt(i + 1);\n return d === 0x22 || d === 0x0a || d === 0x0d;\n }\n\n /**\n * The offset just past an escaped quote or a line continuation, counting the line a\n * continuation ends.\n * @param i - the offset of the backslash\n * @returns the offset after the sequence\n */\n private quotedSpliceEnd(i: number): number {\n const { text } = this;\n const d = text.charCodeAt(i + 1);\n if (d === 0x22) {\n return i + 2;\n }\n this.line++;\n return d === 0x0d && text.codePointAt(i + 2) === 0x0a ? i + 3 : i + 2;\n }\n\n /**\n * Step over one unit of a quoted string kept as written: a backslash pair (consumed as one unit,\n * as Graphviz's scanner does, so the second backslash never escapes a closing quote: \"x\\\\\" is\n * the text x\\\\), a lone backslash, a raw line break (counted) or any other character.\n * @param i - the offset of the unit\n * @param c - the code unit at `i`\n * @returns the offset after the unit\n */\n private quotedStep(i: number, c: number): number {\n const { text } = this;\n if (c === 0x5c) {\n return text.codePointAt(i + 1) === 0x5c ? i + 2 : i + 1;\n }\n if (c === 0x0a) {\n this.line++;\n } else if (c === 0x0d) {\n this.line++;\n return text.codePointAt(i + 1) === 0x0a ? i + 2 : i + 1;\n }\n return i + 1;\n }\n\n /**\n * Lex an HTML string starting at the opening angle bracket: the text up to the matching\n * closing bracket, brackets balanced, kept verbatim including the outer pair.\n * @param start - the offset of the opening bracket\n * @param line - the line of the opening bracket\n * @returns the id token holding the whole `<...>` text\n */\n private html(start: number, line: number): DotToken {\n const { text } = this;\n let depth = 0;\n for (let i = start; i < text.length; i++) {\n const c = text.charCodeAt(i);\n if (c === 0x3c) {\n depth++;\n } else if (c === 0x3e) {\n depth--;\n if (depth === 0) {\n this.pos = i + 1;\n return { kind: \"id\", text: text.slice(start, i + 1), quoted: false, html: true, line };\n }\n } else if (c === 0x0a || (c === 0x0d && text.charCodeAt(i + 1) !== 0x0a)) {\n this.line++;\n }\n }\n throw new DotSyntaxError(\"unterminated HTML string (missing closing '>')\", line);\n }\n\n /**\n * Skip whitespace and comments, counting lines.\n */\n private skipTrivia(): void {\n const { text } = this;\n while (this.pos < text.length) {\n const c = text.charCodeAt(this.pos);\n if (isBlank(c)) {\n this.pos++;\n } else if (!this.skipBreakOrComment(c)) {\n return;\n }\n }\n }\n\n /**\n * Skip one line break, comment or leading `#` line at the current position.\n * @param c - the code unit at the current position\n * @returns false when the current position starts a token\n */\n private skipBreakOrComment(c: number): boolean {\n if (c === 0x0a || c === 0x0d) {\n this.skipLineBreak(c);\n return true;\n }\n if (c === 0x2f) {\n return this.skipComment();\n }\n if (c === 0x23 && this.pos === 0) {\n this.skipToLineEnd();\n return true;\n }\n return false;\n }\n\n /**\n * Consume the line break at the current position (CR LF as one) and a `#` line after it.\n * @param c - the code unit at the current position, LF or CR\n */\n private skipLineBreak(c: number): void {\n this.line++;\n this.pos += c === 0x0d && this.text.codePointAt(this.pos + 1) === 0x0a ? 2 : 1;\n this.skipPreprocessorLine();\n }\n\n /**\n * Skip a `//` or block comment starting at the current `/`.\n * @returns false when the `/` starts no comment\n */\n private skipComment(): boolean {\n const d = this.text.codePointAt(this.pos + 1);\n if (d === 0x2f) {\n this.skipToLineEnd();\n return true;\n }\n if (d === 0x2a) {\n this.skipBlockComment();\n return true;\n }\n return false;\n }\n\n /**\n * Discard a `#` line when one starts at the current position (the start of a line).\n */\n private skipPreprocessorLine(): void {\n if (this.text.charCodeAt(this.pos) === 0x23) {\n this.skipToLineEnd();\n }\n }\n\n /**\n * Advance to the next line break without consuming it.\n */\n private skipToLineEnd(): void {\n const { text } = this;\n while (this.pos < text.length) {\n const c = text.charCodeAt(this.pos);\n if (c === 0x0a || c === 0x0d) {\n return;\n }\n this.pos++;\n }\n }\n\n /**\n * Skip a block comment starting at the current `/*`.\n */\n private skipBlockComment(): void {\n const { text } = this;\n const startLine = this.line;\n let i = this.pos + 2;\n for (; i < text.length; i++) {\n const c = text.charCodeAt(i);\n if (c === 0x2a && text.charCodeAt(i + 1) === 0x2f) {\n this.pos = i + 2;\n return;\n }\n if (c === 0x0a || (c === 0x0d && text.charCodeAt(i + 1) !== 0x0a)) {\n this.line++;\n }\n }\n throw new DotSyntaxError(\"unterminated block comment\", startLine);\n }\n}\n","/**\n * The DOT / Graphviz importer (design sections 8.4, 4.1, 5.1; research note 07 section 2.4). A\n * recursive-descent parser over the DOT grammar pushes nodes and edges into the sink as they are\n * mentioned, in first-mention order:\n *\n * - `graph` / `digraph` set the direction through the DirectionResolver (rule 1 of 8.4); `strict`\n * merges parallel edges as cgraph does and is recorded in `meta.extra.dot.strict`; the graph name\n * becomes `meta.name`.\n * - node, edge and graph attribute statements (`node [..]`, `edge [..]`, `graph [..]`, `ID = ID`)\n * are stateful, scoped defaults applied to the elements created after them in the same or a\n * nested subgraph; every element receives its effective attributes as plain cells, so the\n * exporter writes them back explicitly.\n * - edge chains `a -> b -> c` and subgraph endpoints `{a b} -> c` expand to one edge per pair, in\n * cgraph order; a port on an edge endpoint is kept in the `graphty.sourcePort` /\n * `graphty.targetPort` edge columns (roles sourcePort / targetPort) and never part of the id; a\n * port on a node statement has no meaning and is dropped with a warning.\n * - a subgraph named `cluster*` (or carrying `cluster=true`) becomes a container NODE whose id is\n * the cluster name (design section 5.10: containment is the `parent` role, never an adjacency\n * edge); members get `graphty.parent` = the container's index, the container's own attributes are\n * its node cells, and `graphty.cluster` = true marks it. A plain node and a cluster of the same\n * name (fdp's cluster edges) merge into that one node with a warning. Other subgraphs are\n * transparent grouping; their attributes are reported as dropped.\n * - attribute values are ID strings inferred per column by the sink under the 5.1 grammar, except\n * `label` (text, role label), `pos` on a node (the position role column, f64 x3, design section\n * 5.2), `weight` (THE weight, `weightFrom`) and `key` (cgraph's edge identity, the edge id role).\n * - ids are coerced with the common rule (`canonical` by default: `1` and `\"1\"` are the same node,\n * as the DOT grammar says).\n *\n * The whole text is read first (design section 8.4 allows it for DOT). A grammar violation is\n * fatal, as it is for Graphviz itself: the import aborts with ImportError (issue code E_SYNTAX)\n * carrying the partial report. Errors the sink raises for one element are recorded and the element\n * is skipped (section 8.6).\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n GraphFormatError,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport { declareResolved } from \"../../common/attributes.js\";\nimport { importChosenGraph } from \"../../common/choose.js\";\nimport {\n AMBIGUOUS_GRAPH_NAME_CODE,\n COLUMN_RENAMED_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n DUPLICATE_ATTRIBUTE_CODE,\n ELEMENT_ISSUE,\n EMPTY_INPUT_CODE,\n ENCODING_CONFLICT_CODE,\n ENCODING_FALLBACK_CODE,\n GRAPH_NOT_FOUND_CODE,\n ID_MERGED_CODE,\n INPUT_ISSUE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MIXED_DIRECTION_CODE,\n MULTIPLE_GRAPHS_CODE,\n OPTION_IGNORED_CODE,\n PRECISION_CODE,\n ROLE_TAKEN_CODE,\n SINK_OPTION_CODE,\n SYNTAX_CODE,\n UNKNOWN_ENCODING_CODE,\n} from \"../../common/codes.js\";\nimport { DirectionResolver, type EdgeKind } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { canonicalEncoding, readText, throwIfAborted } from \"../../common/input.js\";\nimport {\n graphChosen,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { plural } from \"../../common/plural.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { inferTextDtype, parseTextCell, TextCellWriter, WIDENING_UNSUPPORTED_CODE } from \"../../common/text.js\";\nimport { parseWeightText } from \"../../common/weights.js\";\nimport {\n type CommonImportOptions,\n type GraphChoiceOptions,\n type GraphImporter,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport {\n CLUSTER_COLUMN,\n DOT_FORMAT,\n DOT_ORIGIN,\n KEY_ATTRIBUTE,\n LABEL_ATTRIBUTE,\n PARENT_COLUMN,\n PIN_ATTRIBUTE,\n POS_ATTRIBUTE,\n POSITION_COLUMN,\n SOURCE_PORT_COLUMN,\n TARGET_PORT_COLUMN,\n} from \"./names.js\";\nimport { dotPositions } from \"./positions.js\";\nimport { dotStyles } from \"./styles.js\";\nimport { DotSyntaxError, type DotToken, DotTokenizer } from \"./tokenizer.js\";\n\n/**\n * The DOT importer's format-specific options.\n * @category Built-in formats\n */\nexport interface DotImportOptions extends GraphChoiceOptions, CommonImportOptions {\n /**\n * What an edge operator that contradicts the graph keyword means (`--` in a digraph, `->` in a\n * graph; Graphviz refuses such a file): \"operator\" reads the edge with the operator's\n * direction, so the graph has both directions and `onMixedDirection` decides, with a warning;\n * \"header\" reads it with the graph's direction, with a warning; \"error\" stops the import with an\n * ImportError whose `issue.code` is E_SYNTAX, as Graphviz does.\n * @defaultValue \"operator\"\n */\n mismatchedEdgeOperator?: \"operator\" | \"header\" | \"error\" | undefined;\n /**\n * Read a node's `pos` attribute as its position (a trailing `!` becomes a `pin` attribute);\n * false keeps `pos` as the text the file wrote, like any other attribute.\n * @defaultValue true\n */\n positions?: boolean | undefined;\n /**\n * With `positions`, also keep `pos` as the text the file wrote; the position column is then\n * named `graphty.position`, so a reader gets both.\n * @defaultValue false\n */\n keepPositionSource?: boolean | undefined;\n}\n\n/**\n * The issue codes the DOT importer records, by name: the codes shared with\n * the other importers and the DOT-specific ones. A key is the code without\n * its severity and format prefixes.\n * @category Built-in formats\n */\nexport const DOT_ISSUE = Object.freeze({\n ...INPUT_ISSUE,\n ...ELEMENT_ISSUE,\n /** The text breaks DOT's syntax; the message says where. The import stops. */\n SYNTAX: SYNTAX_CODE,\n /** The input holds no graph: it is empty or only comments. The import stops. */\n EMPTY_INPUT: EMPTY_INPUT_CODE,\n /** The input is not valid UTF-8. The import stops. */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /**\n * Some bytes are not valid in the encoding that was chosen (by a byte order mark, the file's declaration or the\n * `encoding` option). The import stops.\n */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** A declared encoding the byte order mark contradicts (the mark wins). */\n ENCODING_CONFLICT: ENCODING_CONFLICT_CODE,\n /** Subgraphs or braces are nested deeper than graph-io reads. The import stops. */\n NESTING: \"E_DOT_NESTING\",\n /**\n * An edge operator contradicting the graph keyword, read under mismatchedEdgeOperator \"operator\" or \"header\".\n * Under \"error\" the import stops with E_SYNTAX instead.\n */\n EDGE_OPERATOR: \"W_DOT_EDGE_OPERATOR\",\n /**\n * The file holds several graphs and only the first was read. It is not added when `graphIndex` or `graphName` chose the graph.\n * `importAllGraphs()` reads every one.\n */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** `graphIndex` or `graphName` names no graph of the file; the message lists the graphs it holds. The import stops. */\n GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,\n /** `graphName` matches more than one graph; pass `graphIndex`. The import stops. */\n AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,\n /** A badly delimited numeral (`1e3`) split into two tokens, as Graphviz does with a warning. */\n NUMERAL_AMBIGUITY: \"W_DOT_NUMERAL_AMBIGUITY\",\n /** Attributes of a subgraph that is not a cluster (rank=same and the like) cannot be represented. */\n SUBGRAPH_ATTRIBUTES_DROPPED: \"W_DOT_SUBGRAPH_ATTRIBUTES_DROPPED\",\n /** A port on a node statement has no meaning and was dropped. */\n NODE_PORT_DROPPED: \"W_DOT_NODE_PORT_DROPPED\",\n /** A plain node and a cluster share a name and were merged into one container node. */\n CLUSTER_NODE_MERGED: \"W_DOT_CLUSTER_NODE_MERGED\",\n /** A node mentioned in two unrelated clusters keeps the first. */\n CLUSTER_CONFLICT: \"W_DOT_CLUSTER_CONFLICT\",\n /** A node's `pos` is not a point, or has a coordinate that is not finite; the value was dropped. */\n BAD_POS: \"W_DOT_BAD_POS\",\n /** Node `pos` values mix two and three coordinates; the position column records the first's. */\n POS_DIMS: \"W_DOT_POS_DIMS\",\n /** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: \"string\"` to keep every digit. */\n PRECISION: PRECISION_CODE,\n /** The same attribute twice in one statement's attribute lists; the last value stands, as in Graphviz. */\n DUPLICATE_ATTRIBUTE: DUPLICATE_ATTRIBUTE_CODE,\n /** The second part of a port (`a:p:zz`) is not a compass point; kept as written, as Graphviz warns. */\n COMPASS_POINT: \"W_DOT_COMPASS_POINT\",\n /** A `charset` attribute beyond the head the decoder reads it from; the input was decoded without it. */\n LATE_CHARSET: \"W_DOT_LATE_CHARSET\",\n\n /** A parallel edge merged into an earlier one under `strict`. */\n STRICT_MERGED: \"W_DOT_STRICT_MERGED\",\n /** An edge merged into an earlier one with the same endpoints and `key`. */\n KEY_MERGED: \"W_DOT_KEY_MERGED\",\n /**\n * You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as\n * a plain attribute.\n */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /**\n * An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example\n * two attributes declared with the same name.\n */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** You set an option this format does not use; it had no effect. The message names the option. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** Two different id texts became the same number because `ids` is \"number\", so their nodes were merged. */\n ID_MERGED: ID_MERGED_CODE,\n /**\n * You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,\n * `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.\n */\n SINK_OPTION: SINK_OPTION_CODE,\n /**\n * You read into a graph builder whose direction is already set, or which already holds edges, so the file is read\n * with the builder's direction instead of its own.\n */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges of the other direction were read with the direction `onMixedDirection` chose. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /**\n * The graph has both directed and undirected edges and `onMixedDirection` is \"error\". An import stops; a save to a\n * format that holds one direction per file fails with E_DIRECTED. Pass \"directed\" or \"undirected\" to read or write\n * it anyway.\n */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n /**\n * Your graph builder cannot change an attribute's type after its first value, so a text column keeps the type of\n * its first values.\n */\n WIDENING_UNSUPPORTED: WIDENING_UNSUPPORTED_CODE,\n});\n\n/** The common options the DOT importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"weightFrom\",\n \"weightDtype\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** The deepest nesting of subgraphs and braces the parser accepts (each level is one stack frame). */\nconst MAX_NESTING = 1024;\n\nconst EXTENSIONS: readonly string[] = Object.freeze([\".dot\", \".gv\"]);\nconst MIME_TYPES: readonly string[] = Object.freeze([\"text/vnd.graphviz\"]);\nconst CLUSTER_PREFIX = \"cluster\";\nconst CLUSTER_ATTRIBUTE = \"cluster\";\nconst STATEMENTS_PER_ABORT_CHECK = 64;\nconst MAX_ANCESTOR_WALK = 4096;\n\n/**\n * The header keyword, ended by what may follow it in DOT: space, `{`, a quoted ID or a comment.\n * A `[` after it is GML (`Graph [ ... ]`), which DOT never allows there.\n */\nconst DOT_HEADER = /^\\s*(strict\\s+)?(di)?graph(?=[\\s{\"/]|$)(?!\\s*\\[)/i;\nconst TRUE_TEXTS: ReadonlySet<string> = new Set([\"true\", \"yes\", \"1\"]);\nconst COMPASS_POINTS: ReadonlySet<string> = new Set([\"n\", \"ne\", \"e\", \"se\", \"s\", \"sw\", \"w\", \"nw\", \"c\", \"_\"]);\n/**\n * A DOT number: digits with an optional fraction, or a bare fraction (`.5`), then an exponent.\n * Written so each digit has exactly one way to match; `[0-9]*\\.?[0-9]+` took quadratic time on a\n * long run of digits.\n */\nconst POINT_NUMBER = String.raw`[-+]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][-+]?\\d+)?`;\n/** A point \"x,y[,z][!]\". The `!` and its trailing space are one optional group, so spaces cannot split two ways. */\nconst POINT_TEXT = new RegExp(\n String.raw`^\\s*(${POINT_NUMBER})\\s*,\\s*(${POINT_NUMBER})(?:\\s*,\\s*(${POINT_NUMBER}))?\\s*(?:(!)\\s*)?$`,\n);\n\n/** An attribute as written: name, value text and the line of the assignment. */\ninterface DotAttribute {\n readonly name: string;\n readonly value: string;\n readonly line: number;\n}\n\n/** Where an edge issue is recorded: the statement's line and the edge's description. */\ninterface EdgeWhere {\n readonly line: number;\n readonly element: string;\n}\n\n/** One endpoint of an edge chain: a mentioned node and its port. */\ninterface Endpoint {\n readonly id: NodeId;\n readonly index: number;\n readonly port: string | null;\n}\n\n/** A lexical scope: the root graph or one subgraph. */\ninterface Scope {\n readonly root: boolean;\n /** The subgraph name, null for the root and for an anonymous subgraph. */\n readonly name: string | null;\n readonly line: number;\n /** Defaults for nodes created in this scope, copied from the enclosing scope on entry. */\n readonly nodeDefaults: Map<string, string>;\n /** Defaults for edges created in this scope. */\n readonly edgeDefaults: Map<string, string>;\n /** Node indices mentioned in this scope (nested scopes included), in first-mention order. */\n readonly members: number[];\n readonly memberSet: Set<number>;\n /** Container nodes of clusters closed inside this scope. */\n readonly containers: number[];\n /** Subgraph attributes buffered until the subgraph closes (the root applies them at once). */\n readonly attributes: Map<string, DotAttribute>;\n /** Whether the subgraph is a cluster (by name or by `cluster=true`). */\n cluster: boolean;\n /** The container node index once created, or INVALID_INDEX. */\n container: number;\n}\n\n/**\n * The importer plugin for DOT / Graphviz text.\n * @category Built-in formats\n */\nexport const dotImporter: GraphImporter<DotImportOptions> = Object.freeze({\n format: DOT_FORMAT,\n options: Object.freeze([\"keepPositionSource\", \"mismatchedEdgeOperator\", \"positions\"]),\n extensions: EXTENSIONS,\n mimeTypes: MIME_TYPES,\n styles: dotStyles,\n positions: dotPositions,\n\n /**\n * Confidence that the head of an input is DOT: the `[strict] graph | digraph` header after\n * optional comments.\n * @param head - the first bytes of the input\n * @returns 0.95 for a header followed by `{`, 0.8 for a header alone, 0 otherwise\n */\n sniff(head: Uint8Array): number {\n const text = stripLeadingComments(new TextDecoder(\"utf-8\").decode(head));\n const match = DOT_HEADER.exec(text);\n if (match === null) {\n return 0;\n }\n return text.includes(\"{\") ? 0.95 : 0.8;\n },\n\n /**\n * Read a DOT document into the sink.\n * @param input - the text, bytes or stream\n * @param sink - the sink to push into\n * @param options - format-specific and common options\n * @returns the import report; ImportError (E_IMPORT) on a syntax error or beyond the error limit\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: DotImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n if (graphChosen(options)) {\n // the choice is honored here too, not only by the registry\n return importChosenGraph(dotImporter, input, sink, options);\n }\n const resolved = resolveImportOptions(options, {\n ids: \"canonical\",\n defaultDirected: true,\n weightFrom: \"weight\",\n });\n const mismatch = mismatchOption(options?.mismatchedEdgeOperator);\n const report = new ImportReportBuilder(DOT_FORMAT, resolved.errorLimit);\n reportUnusedOptions(options, report, USED_OPTIONS);\n reportSinkOptions(sink, options, report);\n const head: { charset?: string | null } = {};\n const text = await readText(input, report, {\n ...resolved,\n declaredEncoding: (h) => (head.charset = dotCharset(h)),\n declarationBytes: CHARSET_HEAD_BYTES,\n });\n const reports = { current: report };\n const lexer = dotLexer(text, reports);\n const first = guard(report, () => lexer.next());\n const parser = new DotParser(\n lexer,\n sink,\n report,\n resolved,\n mismatch,\n options?.positions !== false,\n options?.keepPositionSource === true,\n );\n parser.headCharset = head.charset;\n const trailing = parseGraph(parser, report, first);\n if (trailing.kind !== \"eof\") {\n // anything after the graph must be graphs too: Graphviz refuses the file otherwise\n const skipped = guard(report, () => countGraphs(lexer, trailing));\n report.warning(\n \"unsupported\",\n MULTIPLE_GRAPHS_CODE,\n `the input holds ${skipped} more graph${plural(skipped)} after the first; the first is read (graphIndex or graphName chooses another; importAllGraphs() reads every one)`,\n { line: trailing.line },\n );\n }\n // an abort raised during the last few statements (after the last periodic check) still rejects\n throwIfAborted(resolved.signal);\n return report.finish();\n },\n\n /**\n * Read every graph of a DOT file (Graphviz renders each one), each into its own sink.\n * @param input - the text, bytes or stream\n * @param sinkFor - the sink of the graph with this index, called before its first push\n * @param options - format-specific and common options\n * @returns one report per graph; ImportError (E_IMPORT) on a syntax error anywhere\n */\n async importAll(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: DotImportOptions & CommonImportOptions,\n ): Promise<ImportReport[]> {\n const resolved = resolveImportOptions(options, {\n ids: \"canonical\",\n defaultDirected: true,\n weightFrom: \"weight\",\n });\n const mismatch = mismatchOption(options?.mismatchedEdgeOperator);\n const first = new ImportReportBuilder(DOT_FORMAT, resolved.errorLimit);\n reportUnusedOptions(options, first, USED_OPTIONS);\n const head: { charset?: string | null } = {};\n const text = await readText(input, first, {\n ...resolved,\n declaredEncoding: (h) => (head.charset = dotCharset(h)),\n declarationBytes: CHARSET_HEAD_BYTES,\n });\n const reports = { current: first };\n const lexer = dotLexer(text, reports);\n const done: ImportReport[] = [];\n let token = guard(first, () => lexer.next());\n do {\n const report = done.length === 0 ? first : new ImportReportBuilder(DOT_FORMAT, resolved.errorLimit);\n reports.current = report;\n const sink = sinkFor(done.length);\n reportSinkOptions(sink, options, report);\n const parser = new DotParser(\n lexer,\n sink,\n report,\n resolved,\n mismatch,\n options?.positions !== false,\n options?.keepPositionSource === true,\n );\n parser.headCharset = head.charset;\n token = parseGraph(parser, report, token);\n throwIfAborted(resolved.signal);\n done.push(report.finish());\n } while (token.kind !== \"eof\");\n return done;\n },\n});\n\n/**\n * The tokenizer of one input; its badly-delimited-numeral warnings go to the report of the graph\n * being read.\n * @param text - the DOT text\n * @param reports - holds the current graph's report\n * @param reports.current - the report warnings are recorded in\n * @returns the tokenizer\n */\nfunction dotLexer(text: string, reports: { current: ImportReportBuilder }): DotTokenizer {\n return new DotTokenizer(text, (numeral, line) => {\n reports.current.warning(\n \"validation-error\",\n DOT_ISSUE.NUMERAL_AMBIGUITY,\n `badly delimited number ${JSON.stringify(numeral)} splits into two tokens (Graphviz warns the same)`,\n { line, element: numeral },\n );\n });\n}\n\n/**\n * Run a step that may throw DotSyntaxError, turning it into the fatal E_SYNTAX issue.\n * @param report - the report of the graph being read\n * @param step - the step\n * @returns the step's result\n */\nfunction guard<T>(report: ImportReportBuilder, step: () => T): T {\n try {\n return step();\n } catch (err) {\n if (err instanceof DotSyntaxError) {\n report.fail(SYNTAX_CODE, err.message, { line: err.line }, { line: err.line });\n }\n throw err;\n }\n}\n\n/**\n * Parse one graph.\n * @param parser - the parser of this graph\n * @param report - its report\n * @param first - the graph's first token (already read)\n * @returns the token after the graph's closing brace\n */\nfunction parseGraph(parser: DotParser, report: ImportReportBuilder, first: DotToken): DotToken {\n return guard(report, () => parser.parse(first));\n}\n\n/**\n * Count the graphs that follow the first one without reading their statements: each must be\n * `[strict] (graph | digraph) [ID] { ... }` with balanced braces, as Graphviz requires.\n * @param lexer - the tokenizer, positioned after `first`\n * @param first - the first token after the first graph\n * @returns how many graphs follow; DotSyntaxError on anything else\n */\nfunction countGraphs(lexer: DotTokenizer, first: DotToken): number {\n let count = 0;\n let token = first;\n while (token.kind !== \"eof\") {\n if (isKeyword(token, \"strict\")) {\n token = lexer.next();\n }\n if (isPunct(token, \"}\")) {\n throw new DotSyntaxError('unexpected \"}\" after the end of the graph: no \"{\" is open', token.line);\n }\n if (!isKeyword(token, \"graph\") && !isKeyword(token, \"digraph\")) {\n throw new DotSyntaxError(`expected \"graph\" or \"digraph\", found ${describeToken(token)}`, token.line);\n }\n token = lexer.next();\n if (token.kind === \"id\") {\n token = lexer.next();\n }\n if (!isPunct(token, \"{\")) {\n throw new DotSyntaxError(`expected \"{\" after the graph header, found ${describeToken(token)}`, token.line);\n }\n for (let depth = 1; depth > 0;) {\n token = lexer.next();\n if (token.kind === \"eof\") {\n throw new DotSyntaxError('missing \"}\" at the end of a graph', token.line);\n }\n if (isPunct(token, \"{\")) {\n depth++;\n } else if (isPunct(token, \"}\")) {\n depth--;\n }\n }\n count++;\n token = lexer.next();\n }\n return count;\n}\n\n/** How many leading bytes the `charset` search sees: a license comment may come before the graph. */\nconst CHARSET_HEAD_BYTES = 64 * 1024;\n\n/**\n * The encoding a DOT file declares with the graph attribute `charset` (Graphviz reads UTF-8,\n * Latin1 and Big-5), for the shared byte decoder; Graphviz's spellings `latin-1` and `big-5` are\n * mapped to the WHATWG labels. Only a graph-level assignment counts (`charset=...` as a statement\n * or inside `graph [...]`), never one in a comment, a quoted value or a node / edge attribute list.\n * @param head - the start of the file, decoded as windows-1252\n * @returns the declared label, or null\n */\nfunction dotCharset(head: string): string | null {\n const lexer = new DotTokenizer(head);\n // the attribute list an open `[` belongs to: the graph's (`graph [`) or a node's / an edge's\n let list: \"graph\" | \"other\" | null = null;\n let previous: DotToken | null = null;\n try {\n let token = lexer.next();\n while (token.kind !== \"eof\") {\n if (isPunct(token, \"[\")) {\n list = previous !== null && isKeyword(previous, \"graph\") ? \"graph\" : \"other\";\n } else if (isPunct(token, \"]\")) {\n list = null;\n } else if (list !== \"other\" && isKeyword(token, \"charset\")) {\n const equals = lexer.next();\n const value = isPunct(equals, \"=\") ? lexer.next() : equals;\n if (value !== equals && value.kind === \"id\") {\n return value.text.replace(/^(latin|big)-/i, \"$1\");\n }\n token = value;\n }\n previous = token;\n token = lexer.next();\n }\n } catch (err) {\n // the head ends inside a comment or a string: nothing further is seen\n if (!(err instanceof DotSyntaxError)) {\n throw err;\n }\n }\n return null;\n}\n\n/**\n * Resolve the mismatchedEdgeOperator option.\n * @param value - the caller's value\n * @returns the value or the default; E_UNSUPPORTED for anything else\n */\nfunction mismatchOption(value: unknown): NonNullable<DotImportOptions[\"mismatchedEdgeOperator\"]> {\n if (value === undefined) {\n return \"operator\";\n }\n if (value === \"operator\" || value === \"header\" || value === \"error\") {\n return value;\n }\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option mismatchedEdgeOperator: ${JSON.stringify(value)} is not one of \"operator\", \"header\", \"error\"`,\n { option: \"mismatchedEdgeOperator\", found: value, supported: [\"operator\", \"header\", \"error\"] },\n );\n}\n\n/**\n * Remove leading whitespace and comments from a head sample so the header regex sees the keyword.\n * @param text - the decoded head\n * @returns the text from the first non-comment character\n */\nfunction stripLeadingComments(text: string): string {\n let rest = text;\n for (;;) {\n const trimmed = rest.replace(/^\\s+/, \"\");\n if (trimmed.startsWith(\"//\") || trimmed.startsWith(\"#\")) {\n const nl = trimmed.search(/[\\r\\n]/);\n if (nl < 0) {\n return \"\";\n }\n rest = trimmed.slice(nl);\n continue;\n }\n if (trimmed.startsWith(\"/*\")) {\n const end = trimmed.indexOf(\"*/\");\n if (end < 0) {\n return \"\";\n }\n rest = trimmed.slice(end + 2);\n continue;\n }\n return trimmed;\n }\n}\n\n/**\n * Whether a bare token is a given keyword (keywords are case-insensitive; a quoted id never is).\n * @param token - the token\n * @param keyword - the lower-case keyword\n * @returns true for a match\n */\nfunction isKeyword(token: DotToken, keyword: string): boolean {\n return token.kind === \"id\" && !token.quoted && !token.html && token.text.toLowerCase() === keyword;\n}\n\n/**\n * Whether a token is a given punctuation.\n * @param token - the token\n * @param text - the punctuation\n * @returns true for a match\n */\nfunction isPunct(token: DotToken, text: string): boolean {\n return token.kind === \"punct\" && token.text === text;\n}\n\n/**\n * Whether a token is an edge operator.\n * @param token - the token\n * @returns true for `->` or `--`\n */\nfunction isEdgeOp(token: DotToken): boolean {\n return token.kind === \"punct\" && (token.text === \"->\" || token.text === \"--\");\n}\n\n/**\n * A short description of a token for syntax error messages.\n * @param token - the token\n * @returns `end of input`, or the token text in quotes\n */\nfunction describeToken(token: DotToken): string {\n if (token.kind === \"eof\") {\n return \"end of input\";\n }\n return JSON.stringify(token.text.length > 40 ? `${token.text.slice(0, 40)}...` : token.text);\n}\n\n/**\n * Whether a subgraph name marks a cluster.\n * @param name - the name, or null\n * @returns true when it starts with `cluster`\n */\nfunction isClusterName(name: string | null): boolean {\n return name?.startsWith(CLUSTER_PREFIX) === true;\n}\n\n/**\n * The parser and pusher for one import call.\n */\nclass DotParser {\n private readonly lexer: DotTokenizer;\n\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly mismatch: \"operator\" | \"header\" | \"error\";\n private readonly positions: boolean;\n\n private readonly keepPositionSource: boolean;\n\n private readonly ids: IdCoercer;\n\n private readonly resolver: DirectionResolver;\n\n private directed = true;\n\n private strict = false;\n\n private statements = 0;\n\n /** The id of every node mentioned so far, by index (the sink has no idOf). */\n private readonly idOf = new Map<number, NodeId>();\n\n /** Container nodes this import created or adopted. */\n private readonly containers = new Set<number>();\n\n /** The parent assigned to a node by this import. */\n private readonly parentOf = new Map<number, number>();\n\n /** Nodes already warned about a cluster conflict. */\n private readonly conflictWarned = new Set<number>();\n\n /** Under `strict`: the edge index of every (source, target) pair pushed. */\n private readonly strictEdges = new Map<string, number>();\n\n /** The edge index of every (source, target, key) triple pushed. */\n private readonly keyedEdges = new Map<string, number>();\n\n /** Columns of the caller's sink adopted under a name the importer declares with another shape; values are inferred for them. */\n\n private nodeLabelHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private edgeLabelHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private positionHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private clusterHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private parentHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private keyHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private sourcePortHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private targetPortHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n /** The current subgraph nesting depth. */\n private depth = 0;\n\n /** The coordinate count of the first `pos`, or 0 before one. */\n private posDims = 0;\n\n /**\n * What the decoder's look at the head found for `charset`: a label, null for none, undefined\n * when it never looked (text input, a BOM, the encoding option). A `charset` assignment read\n * when the head had none came too late to decode by.\n */\n headCharset: string | null | undefined = undefined;\n\n /** The inferred attribute columns by name, per domain (the 5.1 text grammar per column). */\n private readonly nodeWriters = new Map<string, TextCellWriter>();\n\n private readonly edgeWriters = new Map<string, TextCellWriter>();\n\n /**\n * Create a parser for one graph of a document.\n * @param lexer - the document's tokenizer, positioned at the graph\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param mismatch - the resolved mismatchedEdgeOperator option\n * @param positions - whether `pos` goes to the position column\n * @param keepPositionSource - whether `pos` also stays as text\n */\n constructor(\n lexer: DotTokenizer,\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n mismatch: \"operator\" | \"header\" | \"error\",\n positions: boolean,\n keepPositionSource: boolean,\n ) {\n this.lexer = lexer;\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.mismatch = mismatch;\n this.positions = positions;\n this.keepPositionSource = keepPositionSource;\n this.ids = new IdCoercer(options.ids);\n this.resolver = new DirectionResolver(sink, report, options.onMixedDirection);\n }\n\n /**\n * Parse one graph: `[strict] (graph | digraph) [ID] { stmt_list }`.\n * @param first - the graph's first token (already read from the tokenizer)\n * @returns the token after the closing brace (eof when the document ends there)\n */\n parse(first: DotToken): DotToken {\n const { lexer } = this;\n let token = first;\n if (token.kind === \"eof\") {\n this.report.fail(EMPTY_INPUT_CODE, \"the input holds no graph (empty or only comments)\", {\n line: token.line,\n });\n }\n if (isKeyword(token, \"strict\")) {\n this.strict = true;\n token = lexer.next();\n }\n if (isKeyword(token, \"digraph\")) {\n this.directed = true;\n } else if (isKeyword(token, \"graph\")) {\n this.directed = false;\n } else {\n throw new DotSyntaxError(`expected \"graph\" or \"digraph\", found ${describeToken(token)}`, token.line);\n }\n const headerLine = token.line;\n token = lexer.next();\n let name: string | null = null;\n if (token.kind === \"id\") {\n name = token.text;\n token = lexer.next();\n }\n if (!isPunct(token, \"{\")) {\n throw new DotSyntaxError(`expected \"{\" after the graph header, found ${describeToken(token)}`, token.line);\n }\n this.resolver.setHeader(this.directed, { line: headerLine });\n this.sink.setMeta({\n name,\n sourceFormat: DOT_FORMAT,\n ...(this.strict ? { extra: { dot: { strict: true } } } : {}),\n });\n const root = this.newScope(null, headerLine, true, null);\n this.statementList(root);\n return lexer.next();\n }\n\n /**\n * Create a scope.\n * @param parent - the enclosing scope, or null for the root\n * @param line - the line the scope opens on\n * @param root - whether this is the root graph\n * @param name - the subgraph name, or null\n * @returns the scope\n */\n private newScope(parent: Scope | null, line: number, root: boolean, name: string | null): Scope {\n return {\n root,\n name,\n line,\n nodeDefaults: new Map(parent?.nodeDefaults),\n edgeDefaults: new Map(parent?.edgeDefaults),\n members: [],\n memberSet: new Set(),\n containers: [],\n attributes: new Map(),\n cluster: false,\n container: INVALID_INDEX,\n };\n }\n\n /**\n * Parse `stmt_list }` for a scope whose `{` was consumed.\n * @param scope - the scope\n */\n private statementList(scope: Scope): void {\n const { lexer } = this;\n for (;;) {\n const token = lexer.peek();\n if (isPunct(token, \"}\")) {\n lexer.next();\n return;\n }\n if (token.kind === \"eof\") {\n throw new DotSyntaxError(\n scope.root\n ? 'unexpected end of input: missing \"}\" closing the graph'\n : `unexpected end of input: missing \"}\" closing the subgraph opened on line ${scope.line}`,\n token.line,\n );\n }\n if (isPunct(token, \";\")) {\n lexer.next();\n continue;\n }\n this.statement(scope);\n if (++this.statements % STATEMENTS_PER_ABORT_CHECK === 0) {\n throwIfAborted(this.options.signal);\n }\n }\n }\n\n /**\n * Parse one statement of a scope.\n * @param scope - the scope\n */\n private statement(scope: Scope): void {\n const { lexer } = this;\n const token = lexer.peek();\n if (token.kind === \"punct\") {\n if (token.text === \"{\") {\n const group = this.subgraph(scope);\n this.maybeEdgeStatement(scope, group, token.line);\n return;\n }\n throw new DotSyntaxError(`unexpected ${describeToken(token)} at the start of a statement`, token.line);\n }\n if (!token.quoted && !token.html && this.keywordStatement(scope, token)) {\n return;\n }\n this.idStatement(scope);\n }\n\n /**\n * Parse a statement that starts with a keyword: an attribute statement or a subgraph.\n * @param scope - the scope\n * @param token - the statement's first token, not yet read\n * @returns false when the token is no statement keyword (an ID)\n */\n private keywordStatement(scope: Scope, token: DotToken): boolean {\n const keyword = token.text.toLowerCase();\n if (keyword === \"node\" || keyword === \"edge\" || keyword === \"graph\") {\n this.lexer.next();\n this.attributeStatement(scope, keyword, token.line);\n return true;\n }\n if (keyword === \"subgraph\") {\n const group = this.subgraph(scope);\n this.maybeEdgeStatement(scope, group, token.line);\n return true;\n }\n if (keyword === \"digraph\" || keyword === \"strict\") {\n throw new DotSyntaxError(`unexpected keyword ${describeToken(token)} inside a graph`, token.line);\n }\n return false;\n }\n\n /**\n * Parse a statement that starts with an ID: `ID = ID`, a node statement, or an edge statement starting with a\n * node.\n * @param scope - the scope\n */\n private idStatement(scope: Scope): void {\n const { lexer } = this;\n // ID '=' ID, a node statement, or an edge statement starting with a node\n const id = this.identifier();\n if (isPunct(lexer.peek(), \"=\")) {\n lexer.next();\n const value = this.identifier();\n this.scopeAttribute(scope, { name: id.text, value: value.text, line: id.line });\n return;\n }\n const port = this.port();\n if (isPunct(lexer.peek(), \",\")) {\n this.nodeListStatement(scope, [{ id, port }, ...this.moreNodes()]);\n return;\n }\n if (isEdgeOp(lexer.peek())) {\n const endpoint = this.mentionEndpoint(scope, id, port);\n this.edgeStatement(scope, endpoint === null ? [] : [endpoint], id.line);\n return;\n }\n this.nodeStatement(scope, id, port);\n }\n\n /**\n * Read the rest of a node list after its first node: `, ID [port]` repeated (`a, b, c`).\n * @returns the further nodes, in order\n */\n private moreNodes(): { id: DotToken; port: string | null }[] {\n const out: { id: DotToken; port: string | null }[] = [];\n while (isPunct(this.lexer.peek(), \",\")) {\n this.lexer.next();\n const id = this.identifier();\n out.push({ id, port: this.port() });\n }\n return out;\n }\n\n /**\n * A statement starting with a node list (`a, b [attrs]` or `a, b -> c`): an edge statement from every node of\n * the list, or a node statement for each.\n * @param scope - the scope\n * @param nodes - the listed nodes with their ports\n */\n private nodeListStatement(scope: Scope, nodes: readonly { id: DotToken; port: string | null }[]): void {\n if (isEdgeOp(this.lexer.peek())) {\n this.edgeStatement(scope, this.mentionAll(scope, nodes), nodes[0].id.line);\n return;\n }\n const attributes = this.attributeList();\n for (const n of nodes) {\n this.applyNodeStatement(scope, n.id, n.port, attributes);\n }\n }\n\n /**\n * Read an ID, concatenating quoted strings joined by `+`.\n * @returns the id token (the concatenation keeps the first token's line and quoted flag)\n */\n private identifier(): DotToken {\n const { lexer } = this;\n const token = lexer.next();\n if (token.kind !== \"id\") {\n throw new DotSyntaxError(`expected an identifier, found ${describeToken(token)}`, token.line);\n }\n if (!token.quoted || !isPunct(lexer.peek(), \"+\")) {\n return token;\n }\n let { text } = token;\n while (isPunct(lexer.peek(), \"+\")) {\n const plus = lexer.next();\n const more = lexer.next();\n if (more.kind !== \"id\" || !more.quoted) {\n throw new DotSyntaxError(\n `expected a quoted string after \"+\", found ${describeToken(more)}`,\n more.kind === \"eof\" ? plus.line : more.line,\n );\n }\n text += more.text;\n }\n return { kind: \"id\", text, quoted: true, html: false, line: token.line };\n }\n\n /**\n * Read an optional port after a node id: `: ID [ : compass ]` or `: compass`.\n * @returns the port text (`f0`, `f0:n`, `n`), or null when there is none\n */\n private port(): string | null {\n const { lexer } = this;\n if (!isPunct(lexer.peek(), \":\")) {\n return null;\n }\n lexer.next();\n let { text } = this.identifier();\n if (isPunct(lexer.peek(), \":\")) {\n lexer.next();\n const compass = this.identifier();\n text += `:${compass.text}`;\n if (!COMPASS_POINTS.has(compass.text)) {\n this.report.warning(\n \"validation-error\",\n DOT_ISSUE.COMPASS_POINT,\n `port ${JSON.stringify(text)}: ${JSON.stringify(compass.text)} is not a compass point (n, ne, e, se, s, sw, w, nw, c, _); the port is kept as written`,\n { line: compass.line, element: text },\n );\n }\n }\n return text;\n }\n\n /**\n * Parse `[subgraph [ID]] { stmt_list }` and return its member nodes for use as an edge endpoint.\n * @param parent - the enclosing scope\n * @returns the endpoints (every node mentioned in the subgraph, in first-mention order)\n */\n private subgraph(parent: Scope): Endpoint[] {\n const { lexer } = this;\n let token = lexer.next();\n let name: string | null = null;\n if (isKeyword(token, \"subgraph\")) {\n token = lexer.next();\n if (token.kind === \"id\") {\n name = token.text;\n token = lexer.next();\n }\n }\n if (!isPunct(token, \"{\")) {\n throw new DotSyntaxError(`expected \"{\" to open a subgraph, found ${describeToken(token)}`, token.line);\n }\n if (++this.depth > MAX_NESTING) {\n this.report.fail(\n DOT_ISSUE.NESTING,\n `subgraphs nested deeper than ${MAX_NESTING} levels (the parser recurses per level)`,\n { line: token.line },\n );\n }\n const scope = this.newScope(parent, token.line, false, name);\n if (isClusterName(name)) {\n scope.cluster = true;\n this.ensureContainer(scope);\n }\n this.statementList(scope);\n this.depth--;\n this.closeScope(scope, parent);\n return scope.members.map((index) => ({ id: this.idOf.get(index) ?? index, index, port: null }));\n }\n\n /**\n * Finish a subgraph: apply its attributes to the container node when it is a cluster (or report\n * them dropped), assign parents to its members, and propagate members and containers upward.\n * @param scope - the closed scope\n * @param parent - the enclosing scope\n */\n private closeScope(scope: Scope, parent: Scope): void {\n const { container } = scope;\n if (container !== INVALID_INDEX) {\n for (const attribute of scope.attributes.values()) {\n if (attribute.name !== CLUSTER_ATTRIBUTE) {\n this.setNodeAttribute(container, attribute.name, attribute.value, attribute.line);\n }\n }\n for (const nested of scope.containers) {\n if (nested !== container && !this.parentOf.has(nested)) {\n this.setParent(nested, container);\n }\n }\n for (const member of scope.members) {\n if (member === container) {\n continue;\n }\n const existing = this.parentOf.get(member);\n if (existing === undefined) {\n this.setParent(member, container);\n } else if (existing !== container && !this.isAncestor(container, existing)) {\n this.clusterConflict(member, existing, container, scope.line);\n }\n }\n parent.containers.push(container);\n } else {\n if (scope.attributes.size > 0) {\n const names = [...scope.attributes.keys()].join(\", \");\n this.report.warning(\n \"unsupported\",\n DOT_ISSUE.SUBGRAPH_ATTRIBUTES_DROPPED,\n `subgraph ${scope.name === null ? \"(anonymous)\" : JSON.stringify(scope.name)} is not a cluster; its attributes (${names}) cannot be represented and were dropped`,\n { line: scope.line, element: scope.name },\n );\n }\n for (const nested of scope.containers) {\n parent.containers.push(nested);\n }\n }\n if (!parent.root) {\n for (const member of scope.members) {\n if (!parent.memberSet.has(member)) {\n parent.memberSet.add(member);\n parent.members.push(member);\n }\n }\n }\n }\n\n /**\n * Whether `candidate` is an ancestor of `node` through the parents assigned so far.\n * @param candidate - the possible ancestor\n * @param node - the node whose chain is walked\n * @returns true when candidate is reached\n */\n private isAncestor(candidate: number, node: number): boolean {\n let current: number | undefined = node;\n for (let steps = 0; current !== undefined && steps < MAX_ANCESTOR_WALK; steps++) {\n if (current === candidate) {\n return true;\n }\n current = this.parentOf.get(current);\n }\n return false;\n }\n\n /**\n * Record a node mentioned in two unrelated clusters (once per node).\n * @param member - the node\n * @param existing - its parent\n * @param container - the cluster it was also mentioned in\n * @param line - the line of the losing cluster\n */\n private clusterConflict(member: number, existing: number, container: number, line: number): void {\n if (this.conflictWarned.has(member)) {\n return;\n }\n this.conflictWarned.add(member);\n const id = this.idOf.get(member) ?? member;\n this.report.warning(\n \"coercion\",\n DOT_ISSUE.CLUSTER_CONFLICT,\n `node ${JSON.stringify(id)} is in cluster ${JSON.stringify(this.idOf.get(existing) ?? existing)} and in cluster ${JSON.stringify(this.idOf.get(container) ?? container)}; the first is kept`,\n { line, element: String(id) },\n );\n }\n\n /**\n * Assign a parent.\n * @param node - the node index\n * @param container - the container index\n */\n private setParent(node: number, container: number): void {\n if (node === container) {\n return;\n }\n try {\n this.sink.setNodeValue(this.parentColumn(), node, container);\n this.parentOf.set(node, container);\n } catch (err) {\n this.report.recordError(err, { element: String(this.idOf.get(node) ?? node) });\n }\n }\n\n /**\n * Create (or adopt) the container node of a cluster scope.\n * @param scope - the cluster scope\n */\n private ensureContainer(scope: Scope): void {\n if (scope.container !== INVALID_INDEX || scope.name === null) {\n return;\n }\n const id = this.coerceId(scope.name, scope.line);\n if (id === null) {\n return;\n }\n let index = this.sink.indexOf(id);\n try {\n if (index === INVALID_INDEX) {\n index = this.sink.addNode(id);\n this.report.counts.nodes++;\n } else if (!this.containers.has(index)) {\n this.report.warning(\n \"coercion\",\n DOT_ISSUE.CLUSTER_NODE_MERGED,\n `cluster ${JSON.stringify(scope.name)} and the node of the same name were merged into one container node`,\n { line: scope.line, element: scope.name },\n );\n }\n this.idOf.set(index, id);\n if (!this.containers.has(index)) {\n this.containers.add(index);\n this.sink.setNodeValue(this.clusterColumn(), index, true);\n }\n scope.container = index;\n } catch (err) {\n this.report.recordError(err, { line: scope.line, element: scope.name });\n if (index === INVALID_INDEX) {\n this.report.counts.skippedNodes++;\n }\n }\n }\n\n /**\n * Apply an `ID = ID` or `graph [..]` attribute: the graph table at the root, a buffered\n * subgraph attribute otherwise (`cluster=true` turns the subgraph into a cluster).\n * @param scope - the scope\n * @param attribute - the attribute\n */\n private scopeAttribute(scope: Scope, attribute: DotAttribute): void {\n if (scope.root) {\n this.setGraphAttribute(attribute);\n return;\n }\n scope.attributes.set(attribute.name, attribute);\n if (attribute.name === CLUSTER_ATTRIBUTE && TRUE_TEXTS.has(attribute.value.trim().toLowerCase())) {\n scope.cluster = true;\n this.ensureContainer(scope);\n }\n }\n\n /**\n * Parse `node|edge|graph attr_list` after the keyword.\n * @param scope - the scope\n * @param keyword - which defaults are set\n * @param line - the keyword's line\n */\n private attributeStatement(scope: Scope, keyword: string, line: number): void {\n if (!isPunct(this.lexer.peek(), \"[\")) {\n const found = this.lexer.peek();\n throw new DotSyntaxError(`expected \"[\" after \"${keyword}\", found ${describeToken(found)}`, found.line);\n }\n const attributes = this.attributeList();\n switch (keyword) {\n case \"node\":\n for (const a of attributes) {\n scope.nodeDefaults.set(a.name, a.value);\n }\n break;\n case \"edge\":\n for (const a of attributes) {\n scope.edgeDefaults.set(a.name, a.value);\n }\n break;\n case \"graph\":\n for (const a of attributes) {\n this.scopeAttribute(scope, a);\n }\n break;\n default:\n throw new DotSyntaxError(`unknown attribute statement \"${keyword}\"`, line);\n }\n }\n\n /**\n * Parse one or more `[ a_list ]` groups.\n * @returns the attributes in order (a repeated name keeps its last value at application time)\n */\n private attributeList(): DotAttribute[] {\n const { lexer } = this;\n const out: DotAttribute[] = [];\n const names = new Set<string>();\n while (isPunct(lexer.peek(), \"[\")) {\n lexer.next();\n for (;;) {\n const token = lexer.peek();\n if (isPunct(token, \"]\")) {\n lexer.next();\n break;\n }\n if (isPunct(token, \";\") || isPunct(token, \",\")) {\n lexer.next();\n continue;\n }\n const name = this.identifier();\n const eq = lexer.next();\n if (!isPunct(eq, \"=\")) {\n throw new DotSyntaxError(\n `expected \"=\" after attribute name ${JSON.stringify(name.text)}, found ${describeToken(eq)}`,\n eq.line,\n );\n }\n const value = this.identifier();\n if (names.has(name.text)) {\n this.report.warning(\n \"merged\",\n DOT_ISSUE.DUPLICATE_ATTRIBUTE,\n `attribute ${JSON.stringify(name.text)} is set twice in one statement; the last value ${JSON.stringify(value.text)} stands`,\n { line: name.line, element: name.text },\n );\n }\n names.add(name.text);\n out.push({ name: name.text, value: value.text, line: name.line });\n }\n }\n return out;\n }\n\n /**\n * Parse a node statement after its id and port: an optional attribute list, then apply.\n * @param scope - the scope\n * @param id - the id token\n * @param port - the port, if any (dropped with a warning)\n */\n private nodeStatement(scope: Scope, id: DotToken, port: string | null): void {\n this.applyNodeStatement(scope, id, port, this.attributeList());\n }\n\n /**\n * Mention a node of a node statement and apply the statement's attributes to it.\n * @param scope - the scope\n * @param id - the id token\n * @param port - the port, if any (dropped with a warning)\n * @param attributes - the statement's attributes\n */\n private applyNodeStatement(\n scope: Scope,\n id: DotToken,\n port: string | null,\n attributes: readonly DotAttribute[],\n ): void {\n const endpoint = this.mentionEndpoint(scope, id, null);\n if (endpoint === null) {\n return;\n }\n if (port !== null) {\n this.report.warning(\n \"unsupported\",\n DOT_ISSUE.NODE_PORT_DROPPED,\n `port ${JSON.stringify(port)} on the node statement of ${JSON.stringify(id.text)} has no meaning and was dropped`,\n { line: id.line, element: id.text },\n );\n }\n for (const attribute of attributes) {\n this.setNodeAttribute(endpoint.index, attribute.name, attribute.value, attribute.line);\n }\n }\n\n /**\n * After a subgraph statement: continue as an edge statement when an edge operator follows.\n * @param scope - the scope\n * @param group - the subgraph's members\n * @param line - the statement's line\n */\n private maybeEdgeStatement(scope: Scope, group: Endpoint[], line: number): void {\n if (isEdgeOp(this.lexer.peek())) {\n this.edgeStatement(scope, group, line);\n }\n }\n\n /**\n * Parse `edgeRHS [attr_list]` after the first endpoint group and push the edges.\n * @param scope - the scope\n * @param first - the first group (empty when its node could not be created)\n * @param line - the statement's line\n */\n private edgeStatement(scope: Scope, first: Endpoint[], line: number): void {\n const { lexer } = this;\n const groups: Endpoint[][] = [first];\n const kinds: EdgeKind[] = [];\n while (isEdgeOp(lexer.peek())) {\n const op = lexer.next();\n kinds.push(this.edgeKind(op));\n const next = lexer.peek();\n if (isPunct(next, \"{\") || isKeyword(next, \"subgraph\")) {\n groups.push(this.subgraph(scope));\n } else {\n const id = this.identifier();\n groups.push(this.mentionAll(scope, [{ id, port: this.port() }, ...this.moreNodes()]));\n }\n }\n const attributes = this.attributeList();\n for (let k = 0; k < kinds.length; k++) {\n const targets = groups[k + 1];\n for (const source of groups[k]) {\n for (const target of targets) {\n this.pushEdge(scope, source, target, kinds[k], attributes, line);\n }\n }\n }\n }\n\n /**\n * Mention each listed node as an edge endpoint.\n * @param scope - the scope\n * @param nodes - the nodes with their ports\n * @returns the endpoints of the nodes that could be created\n */\n private mentionAll(scope: Scope, nodes: readonly { id: DotToken; port: string | null }[]): Endpoint[] {\n const group: Endpoint[] = [];\n for (const n of nodes) {\n const endpoint = this.mentionEndpoint(scope, n.id, n.port);\n if (endpoint !== null) {\n group.push(endpoint);\n }\n }\n return group;\n }\n\n /**\n * The direction of an edge from its operator, checked against the graph keyword.\n * @param op - the operator token\n * @returns the edge kind\n */\n private edgeKind(op: DotToken): EdgeKind {\n const operatorDirected = op.text === \"->\";\n if (operatorDirected === this.directed) {\n return operatorDirected ? \"directed\" : \"undirected\";\n }\n const message = `edge operator \"${op.text}\" in a ${this.directed ? \"digraph\" : \"graph\"}`;\n switch (this.mismatch) {\n case \"error\":\n throw new DotSyntaxError(`${message} (mismatchedEdgeOperator: \"error\")`, op.line);\n case \"header\":\n this.report.warnOnce(\n \"coercion\",\n DOT_ISSUE.EDGE_OPERATOR,\n `${message}; read with the graph's direction (mismatchedEdgeOperator: \"header\")`,\n { line: op.line },\n );\n return this.directed ? \"directed\" : \"undirected\";\n case \"operator\":\n this.report.warnOnce(\n \"coercion\",\n DOT_ISSUE.EDGE_OPERATOR,\n `${message}; read with the operator's direction, and onMixedDirection decides how the mixed graph is stored`,\n { line: op.line },\n );\n return operatorDirected ? \"directed\" : \"undirected\";\n default: {\n const name: string = this.mismatch;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown mismatchedEdgeOperator ${name}`, { found: name });\n }\n }\n }\n\n /**\n * Coerce an id text, recording a merge under ids: \"number\".\n * @param text - the id text\n * @param line - the line, for issues\n * @returns the id, or null when the text was rejected (recorded, node skipped)\n */\n private coerceId(text: string, line: number): NodeId | null {\n try {\n const id = this.ids.text(text);\n const merge = this.ids.lastMerge;\n if (merge !== null) {\n this.report.warning(\n \"coercion\",\n DOT_ISSUE.ID_MERGED,\n `id text ${JSON.stringify(merge.text)} merged with ${JSON.stringify(merge.previousText)} as ${merge.id} under ids: \"number\"`,\n { line, element: text },\n );\n }\n return id;\n } catch (err) {\n this.report.recordError(err, { line, element: text });\n this.report.counts.skippedNodes++;\n return null;\n }\n }\n\n /**\n * Mention a node: create it on first mention (applying the scope's node defaults), record it as\n * a member of the scope, and return it as an endpoint.\n * @param scope - the scope\n * @param id - the id token\n * @param port - the endpoint's port, or null\n * @returns the endpoint, or null when the node could not be created (recorded)\n */\n private mentionEndpoint(scope: Scope, id: DotToken, port: string | null): Endpoint | null {\n const nodeId = this.coerceId(id.text, id.line);\n if (nodeId === null) {\n return null;\n }\n const { sink } = this;\n let index = sink.indexOf(nodeId);\n if (index === INVALID_INDEX) {\n try {\n index = sink.addNode(nodeId);\n } catch (err) {\n this.report.recordError(err, { line: id.line, element: id.text });\n this.report.counts.skippedNodes++;\n return null;\n }\n this.report.counts.nodes++;\n this.idOf.set(index, nodeId);\n for (const [name, value] of scope.nodeDefaults) {\n this.setNodeAttribute(index, name, value, id.line);\n }\n } else if (!this.idOf.has(index)) {\n this.idOf.set(index, nodeId);\n }\n if (!scope.root && !scope.memberSet.has(index)) {\n scope.memberSet.add(index);\n scope.members.push(index);\n }\n return { id: nodeId, index, port };\n }\n\n /**\n * Push one edge with its effective attributes (scope defaults overridden by the statement's).\n * @param scope - the scope\n * @param source - the source endpoint\n * @param target - the target endpoint\n * @param kind - the edge's direction\n * @param attributes - the statement's attributes\n * @param line - the statement's line\n */\n private pushEdge(\n scope: Scope,\n source: Endpoint,\n target: Endpoint,\n kind: EdgeKind,\n attributes: readonly DotAttribute[],\n line: number,\n ): void {\n const effective = new Map(scope.edgeDefaults);\n for (const a of attributes) {\n effective.set(a.name, a.value);\n }\n const element = `${String(source.id)} ${kind === \"directed\" ? \"->\" : \"--\"} ${String(target.id)}`;\n const where: EdgeWhere = { line, element };\n const { weightFrom } = this.options;\n let weight: number | undefined;\n const weightText = weightFrom === null ? undefined : effective.get(weightFrom);\n if (weightText !== undefined) {\n try {\n weight = parseWeightText(weightText, this.report);\n } catch (err) {\n this.report.recordError(err, where);\n this.report.counts.skippedEdges++;\n return;\n }\n }\n const key = effective.get(KEY_ATTRIBUTE);\n const dedupeKey = this.dedupeKey(source.index, target.index, kind, key);\n if (dedupeKey !== null) {\n const existing = (this.strict ? this.strictEdges : this.keyedEdges).get(dedupeKey);\n if (existing !== undefined) {\n this.mergeEdge(existing, weight, effective, where, key);\n this.setPorts(existing, source, target, where);\n return;\n }\n }\n const { sink } = this;\n const before = sink.edgeCount;\n let e: number;\n try {\n e = this.resolver.addEdge(source.id, target.id, kind, weight, where);\n } catch (err) {\n this.report.recordError(err, where);\n this.report.counts.skippedEdges++;\n return;\n }\n this.report.counts.edges += sink.edgeCount - before;\n if (dedupeKey !== null) {\n (this.strict ? this.strictEdges : this.keyedEdges).set(dedupeKey, e);\n }\n for (const [name, value] of effective) {\n if (name !== weightFrom) {\n this.setEdgeAttribute(e, name, value, line, element);\n }\n }\n this.setPorts(e, source, target, where);\n }\n\n /**\n * Write the endpoints' ports of an edge, when they have any.\n * @param e - the edge index\n * @param source - the source endpoint\n * @param target - the target endpoint\n * @param where - the line and element\n */\n private setPorts(e: number, source: Endpoint, target: Endpoint, where: EdgeWhere): void {\n if (source.port !== null) {\n this.setPort(e, \"source\", source.port, where);\n }\n if (target.port !== null) {\n this.setPort(e, \"target\", target.port, where);\n }\n }\n\n /**\n * The key under which an edge is merged with an earlier one: every (source, target) pair under\n * `strict` (unordered for an undirected edge), else the (source, target, key) triple of an edge\n * carrying a `key` attribute (cgraph's edge identity).\n * @param source - the source index\n * @param target - the target index\n * @param kind - the edge's direction\n * @param key - the `key` attribute, or undefined\n * @returns the dedupe key, or null when the edge is never merged\n */\n private dedupeKey(source: number, target: number, kind: EdgeKind, key: string | undefined): string | null {\n const ordered = kind === \"undirected\" && target < source ? `${target}>${source}` : `${source}>${target}`;\n if (this.strict) {\n return ordered;\n }\n return key === undefined ? null : `${ordered}#${key}`;\n }\n\n /**\n * Merge a repeated edge into the earlier one: its attributes overwrite, an explicit weight too.\n * @param e - the existing edge index\n * @param weight - the repeated edge's weight, or undefined\n * @param effective - the repeated edge's effective attributes\n * @param where - the line and element\n * @param key - the `key` attribute when the merge is by key\n */\n private mergeEdge(\n e: number,\n weight: number | undefined,\n effective: ReadonlyMap<string, string>,\n where: EdgeWhere,\n key: string | undefined,\n ): void {\n const byKey = !this.strict && key !== undefined;\n this.report.warning(\n \"merged\",\n byKey ? DOT_ISSUE.KEY_MERGED : DOT_ISSUE.STRICT_MERGED,\n byKey\n ? `edge ${where.element} with key ${JSON.stringify(key)} repeats an earlier edge; attributes merged`\n : `parallel edge ${where.element} merged into the earlier one (strict graph)`,\n where,\n );\n try {\n if (weight !== undefined) {\n this.sink.setEdgeWeight(e, weight);\n }\n } catch (err) {\n this.report.recordError(err, where);\n }\n for (const [name, value] of effective) {\n if (name !== this.options.weightFrom) {\n this.setEdgeAttribute(e, name, value, where.line, where.element);\n }\n }\n }\n\n /**\n * Write one node attribute: `label` to the label column, `pos` to the position column,\n * anything else as an inferred cell.\n * @param index - the node index\n * @param name - the attribute name\n * @param value - the value text\n * @param line - the line, for issues\n */\n private setNodeAttribute(index: number, name: string, value: string, line: number): void {\n const element = String(this.idOf.get(index) ?? index);\n try {\n if (name === LABEL_ATTRIBUTE) {\n this.sink.setNodeValue(this.nodeLabel(), index, value);\n } else if (name === POS_ATTRIBUTE && this.positions) {\n this.setPosition(index, value, line, element);\n if (this.keepPositionSource) {\n this.textWriter(\"node\", name).write(index, value);\n }\n } else {\n this.textWriter(\"node\", name).write(index, value);\n }\n } catch (err) {\n this.report.recordError(err, { line, element });\n }\n }\n\n /**\n * Write one edge attribute: `label` to the label column, `key` to the edge id column, anything\n * else as an inferred cell.\n * @param e - the edge index\n * @param name - the attribute name\n * @param value - the value text\n * @param line - the line, for issues\n * @param element - the edge description, for issues\n */\n private setEdgeAttribute(e: number, name: string, value: string, line: number, element: string): void {\n try {\n if (name === LABEL_ATTRIBUTE) {\n this.setEdgeText(this.edgeLabel(), e, value);\n } else if (name === KEY_ATTRIBUTE) {\n this.setEdgeText(this.keyColumn(), e, value);\n } else {\n this.textWriter(\"edge\", name).write(e, value);\n }\n } catch (err) {\n this.report.recordError(err, { line, element });\n }\n }\n\n /**\n * Write a graph attribute (the root's `ID = ID` and `graph [..]`).\n * @param attribute - the attribute\n */\n private setGraphAttribute(attribute: DotAttribute): void {\n if (attribute.name.toLowerCase() === \"charset\" && this.headCharset === null) {\n const canonical = canonicalEncoding(attribute.value);\n if (canonical !== \"utf-8\") {\n this.report.warning(\n \"unsupported\",\n DOT_ISSUE.LATE_CHARSET,\n `charset ${JSON.stringify(attribute.value)} is declared beyond the first 1024 bytes, after the input was decoded without it; pass the encoding option to decode it as declared`,\n { line: attribute.line, element: attribute.name },\n );\n }\n }\n try {\n if (attribute.name === LABEL_ATTRIBUTE) {\n this.sink.setGraphValue(attribute.name, attribute.value, { dtype: \"string\", origin: DOT_ORIGIN });\n } else {\n // the dtype comes from the text's grammar, so \"20.0\" stays f64 as it does in a node column\n this.sink.setGraphValue(attribute.name, parseTextCell(attribute.value), {\n dtype: inferTextDtype(attribute.value),\n origin: DOT_ORIGIN,\n });\n }\n } catch (err) {\n this.report.recordError(err, { line: attribute.line, element: attribute.name });\n }\n }\n\n /**\n * Write a node's `pos`: `x,y[,z][!]` into the position column, the `!` as `pin` = true.\n * @param index - the node index\n * @param text - the pos text\n * @param line - the line\n * @param element - the node id text\n */\n private setPosition(index: number, text: string, line: number, element: string): void {\n const match = POINT_TEXT.exec(text);\n if (match === null) {\n this.report.warning(\n \"validation-error\",\n DOT_ISSUE.BAD_POS,\n `pos ${JSON.stringify(text)} is not a point \"x,y[,z][!]\"; dropped`,\n { line, element },\n );\n return;\n }\n const x = Number(match[1]);\n const y = Number(match[2]);\n const z = match[3] === undefined ? 0 : Number(match[3]);\n const dims = match[3] === undefined ? 2 : 3;\n const point = [x, y, z];\n if (point.some((v) => !Number.isFinite(v))) {\n // a half-infinite point would be a half-valid position\n this.report.warning(\n \"validation-error\",\n DOT_ISSUE.BAD_POS,\n `pos ${JSON.stringify(text)} has a coordinate that is not finite; dropped`,\n { line, element },\n );\n return;\n }\n if (this.posDims === 0) {\n this.posDims = dims;\n } else if (dims !== this.posDims) {\n this.report.warnOnce(\n \"validation-error\",\n DOT_ISSUE.POS_DIMS,\n `pos values mix ${this.posDims} and ${dims} coordinates; the position column records sourceDims ${this.posDims}`,\n { line, element },\n );\n }\n this.sink.setNodeValue(this.positionColumn(dims), index, point);\n if (match[4] === \"!\") {\n this.sink.setNodeValue(PIN_ATTRIBUTE, index, true);\n }\n }\n\n /**\n * Write an endpoint's port into the source / target port column.\n * @param e - the edge index\n * @param side - which endpoint\n * @param port - the port text\n * @param where - the line and element\n */\n private setPort(e: number, side: \"source\" | \"target\", port: string, where: EdgeWhere): void {\n try {\n this.setEdgeText(side === \"source\" ? this.sourcePortColumn() : this.targetPortColumn(), e, port);\n } catch (err) {\n this.report.recordError(err, where);\n }\n }\n\n /**\n * Write a text cell into one of the importer's edge text columns.\n * @param handle - the column\n * @param e - the edge index\n * @param text - the text\n */\n private setEdgeText(handle: ColumnHandle, e: number, text: string): void {\n this.sink.setEdgeValue(handle, e, text);\n }\n\n // ============================================================ lazily declared columns\n\n /**\n * The node label column (string, role label).\n * @returns the handle\n */\n private nodeLabel(): ColumnHandle {\n if (this.nodeLabelHandle === INVALID_INDEX) {\n this.nodeLabelHandle = this.declare(\"node\", {\n name: LABEL_ATTRIBUTE,\n dtype: \"string\",\n nullable: true,\n role: \"label\",\n origin: DOT_ORIGIN,\n });\n }\n return this.nodeLabelHandle;\n }\n\n /**\n * The edge label column (string, role label).\n * @returns the handle\n */\n private edgeLabel(): ColumnHandle {\n if (this.edgeLabelHandle === INVALID_INDEX) {\n this.edgeLabelHandle = this.declare(\"edge\", {\n name: LABEL_ATTRIBUTE,\n dtype: \"string\",\n nullable: true,\n role: \"label\",\n origin: DOT_ORIGIN,\n });\n }\n return this.edgeLabelHandle;\n }\n\n /**\n * The position column (f64 x3, role position, design section 5.2), declared on the first `pos`.\n * @param dims - the dimensions of the first value, recorded in extra.sourceDims\n * @returns the handle\n */\n private positionColumn(dims: 2 | 3): ColumnHandle {\n if (this.positionHandle === INVALID_INDEX) {\n this.positionHandle = this.declare(\"node\", {\n name: this.keepPositionSource ? POSITION_COLUMN : POS_ATTRIBUTE,\n dtype: \"f64\",\n components: 3,\n nullable: true,\n mutable: true,\n role: \"position\",\n origin: { ...DOT_ORIGIN, type: \"point\" },\n extra: { sourceDims: dims, units: \"file\" },\n });\n }\n return this.positionHandle;\n }\n\n /**\n * The cluster marker column (bool).\n * @returns the handle\n */\n private clusterColumn(): ColumnHandle {\n if (this.clusterHandle === INVALID_INDEX) {\n this.clusterHandle = this.declare(\"node\", {\n name: CLUSTER_COLUMN,\n dtype: \"bool\",\n nullable: true,\n origin: DOT_ORIGIN,\n });\n }\n return this.clusterHandle;\n }\n\n /**\n * The parent column (u32, role parent, refersTo node).\n * @returns the handle\n */\n private parentColumn(): ColumnHandle {\n if (this.parentHandle === INVALID_INDEX) {\n this.parentHandle = this.declare(\"node\", {\n name: PARENT_COLUMN,\n dtype: \"u32\",\n nullable: true,\n role: \"parent\",\n refersTo: \"node\",\n origin: DOT_ORIGIN,\n });\n }\n return this.parentHandle;\n }\n\n /**\n * The edge key column (string, role id): cgraph's edge identity within a source / target pair.\n * @returns the handle\n */\n private keyColumn(): ColumnHandle {\n if (this.keyHandle === INVALID_INDEX) {\n this.keyHandle = this.declare(\"edge\", {\n name: KEY_ATTRIBUTE,\n dtype: \"string\",\n nullable: true,\n role: \"id\",\n origin: { ...DOT_ORIGIN, id: KEY_ATTRIBUTE },\n });\n }\n return this.keyHandle;\n }\n\n /**\n * The source port column (string, role sourcePort).\n * @returns the handle\n */\n private sourcePortColumn(): ColumnHandle {\n if (this.sourcePortHandle === INVALID_INDEX) {\n this.sourcePortHandle = this.declare(\"edge\", {\n name: SOURCE_PORT_COLUMN,\n dtype: \"string\",\n nullable: true,\n role: \"sourcePort\",\n origin: DOT_ORIGIN,\n });\n }\n return this.sourcePortHandle;\n }\n\n /**\n * The target port column (string, role targetPort).\n * @returns the handle\n */\n private targetPortColumn(): ColumnHandle {\n if (this.targetPortHandle === INVALID_INDEX) {\n this.targetPortHandle = this.declare(\"edge\", {\n name: TARGET_PORT_COLUMN,\n dtype: \"string\",\n nullable: true,\n role: \"targetPort\",\n origin: DOT_ORIGIN,\n });\n }\n return this.targetPortHandle;\n }\n\n /**\n * The inferred-column writer of an attribute name in a domain (design section 5.1: the column's\n * dtype follows the text grammar per column; a caller's column of the name receives parsed\n * values through the sink's own inference).\n * @param domain - node or edge\n * @param name - the attribute name\n * @returns the writer\n */\n private textWriter(domain: \"node\" | \"edge\", name: string): TextCellWriter {\n const writers = domain === \"node\" ? this.nodeWriters : this.edgeWriters;\n let writer = writers.get(name);\n if (writer === undefined) {\n writer = new TextCellWriter(name, domain, this.sink, this.report);\n writers.set(name, writer);\n }\n return writer;\n }\n\n /**\n * Declare one of the importer's columns on the sink through the shared design section 5.6\n * rule: a caller's sink that already holds the role gets the column without it (reported), one\n * that holds the name with another shape gets it renamed `<name>#<id>` (reported).\n * @param domain - node or edge\n * @param decl - the declaration\n * @returns the handle\n */\n private declare(domain: \"node\" | \"edge\", decl: ColumnDecl): ColumnHandle {\n const withId: ColumnDecl =\n decl.origin?.id === undefined ? { ...decl, origin: { ...decl.origin, id: decl.name } } : decl;\n return declareResolved(this.sink, domain, withId, this.report, { element: decl.name }).handle;\n }\n}\n"],"names":["TRUE_TEXTS","cellText","inches","CLUSTER_PREFIX","COMPASS_POINTS","idText"],"mappings":"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"}
|