@graphty/graph-io 0.3.47 → 0.3.49
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-Bzn3L-je.js} +2 -2
- package/dist/chunks/{approximations-wWjCRzKj.js.map → approximations-Bzn3L-je.js.map} +1 -1
- package/dist/chunks/bends-BGXjv_U4.js +129 -0
- package/dist/chunks/bends-BGXjv_U4.js.map +1 -0
- package/dist/chunks/{block-DiGq58c3.js → block-iptrlMBb.js} +947 -134
- package/dist/chunks/block-iptrlMBb.js.map +1 -0
- package/dist/chunks/choose-CczZJaX_.js +717 -0
- package/dist/chunks/choose-CczZJaX_.js.map +1 -0
- package/dist/chunks/codes-BE2xir2k.js +157 -0
- package/dist/chunks/codes-BE2xir2k.js.map +1 -0
- package/dist/chunks/{constants-BKwqelYD.js → constants-CKkYLPtt.js} +2 -2
- package/dist/chunks/{constants-BKwqelYD.js.map → constants-CKkYLPtt.js.map} +1 -1
- package/dist/chunks/context-C3p0RQxR.js +664 -0
- package/dist/chunks/context-C3p0RQxR.js.map +1 -0
- package/dist/chunks/{convert-BcQ8_jMo.js → convert-Ct2zelbQ.js} +7 -2
- package/dist/chunks/convert-Ct2zelbQ.js.map +1 -0
- package/dist/chunks/credentials-DXHx7nwR.js +349 -0
- package/dist/chunks/credentials-DXHx7nwR.js.map +1 -0
- package/dist/chunks/cx-export-Bt6NoqTQ.js +259 -0
- package/dist/chunks/cx-export-Bt6NoqTQ.js.map +1 -0
- package/dist/chunks/descriptor-B28U25x4.js +60 -0
- package/dist/chunks/descriptor-B28U25x4.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/descriptor-DLA5kINx.js +142 -0
- package/dist/chunks/descriptor-DLA5kINx.js.map +1 -0
- package/dist/chunks/{emit-CwU8cUmG.js → emit-BwHQkZle.js} +1690 -103
- package/dist/chunks/emit-BwHQkZle.js.map +1 -0
- package/dist/chunks/{escape-CgzxiYPg.js → escape-CuCIzNMB.js} +12 -12
- package/dist/chunks/{escape-CgzxiYPg.js.map → escape-CuCIzNMB.js.map} +1 -1
- package/dist/chunks/{export-BvqAXCKh.js → export-Cha4dRFz.js} +48 -1780
- package/dist/chunks/export-Cha4dRFz.js.map +1 -0
- package/dist/chunks/{exporter--Mk9gXCJ.js → exporter-BP6otMO6.js} +6 -4
- package/dist/chunks/{exporter--Mk9gXCJ.js.map → exporter-BP6otMO6.js.map} +1 -1
- package/dist/chunks/{exporter-CrDWIyiq.js → exporter-D2CETOMK.js} +1222 -154
- package/dist/chunks/exporter-D2CETOMK.js.map +1 -0
- package/dist/chunks/{exporter-DndFlGSa.js → exporter-D9yMtocA.js} +7 -6
- package/dist/chunks/{exporter-DndFlGSa.js.map → exporter-D9yMtocA.js.map} +1 -1
- package/dist/chunks/exporter-_jrBTnos.js +1009 -0
- package/dist/chunks/exporter-_jrBTnos.js.map +1 -0
- package/dist/chunks/{exporter-CJgfhF-l.js → exporter-nDfxIK5D.js} +9 -7
- package/dist/chunks/{exporter-CJgfhF-l.js.map → exporter-nDfxIK5D.js.map} +1 -1
- package/dist/chunks/format-BXiAb-1h.js +408 -0
- package/dist/chunks/format-BXiAb-1h.js.map +1 -0
- package/dist/chunks/{generic-Dq1ntt9q.js → generic-ymWCETAJ.js} +387 -31
- package/dist/chunks/generic-ymWCETAJ.js.map +1 -0
- package/dist/chunks/{importer-CMmeMWlC.js → importer-B92x1xY5.js} +15 -263
- package/dist/chunks/importer-B92x1xY5.js.map +1 -0
- package/dist/chunks/{importer-DiZRmOQG.js → importer-CT9mJ1nn.js} +328 -90
- package/dist/chunks/importer-CT9mJ1nn.js.map +1 -0
- package/dist/chunks/{importer-COTK9Tsl.js → importer-DaLTjbds.js} +116 -1099
- package/dist/chunks/importer-DaLTjbds.js.map +1 -0
- package/dist/chunks/{importer-iFYPEKaJ.js → importer-GREKMdIf.js} +28 -16
- package/dist/chunks/importer-GREKMdIf.js.map +1 -0
- package/dist/chunks/{importer-BSvfrX_h.js → importer-PqaaKKnY.js} +23 -1016
- package/dist/chunks/importer-PqaaKKnY.js.map +1 -0
- package/dist/chunks/{importer-yh_aBCU6.js → importer-Vn5QvmmJ.js} +66 -12
- package/dist/chunks/importer-Vn5QvmmJ.js.map +1 -0
- package/dist/chunks/{importer-e6LGpqHB.js → importer-vRq4h3j5.js} +1470 -354
- package/dist/chunks/importer-vRq4h3j5.js.map +1 -0
- package/dist/chunks/input-CAxt_aV-.js +1397 -0
- package/dist/chunks/input-CAxt_aV-.js.map +1 -0
- package/dist/chunks/{json-elements-DJZRZ6jd.js → json-elements-Cq76WjnZ.js} +4 -4
- package/dist/chunks/{json-elements-DJZRZ6jd.js.map → json-elements-Cq76WjnZ.js.map} +1 -1
- package/dist/chunks/{lexicon-CT69Kd87.js → lexicon-Clf4QIyl.js} +299 -77
- package/dist/chunks/lexicon-Clf4QIyl.js.map +1 -0
- package/dist/chunks/{ontology-export-G4MqRdux.js → ontology-export-OMo91mb0.js} +4 -3
- package/dist/chunks/{ontology-export-G4MqRdux.js.map → ontology-export-OMo91mb0.js.map} +1 -1
- package/dist/chunks/{records-CiaWZrFH.js → records-NJiYvekn.js} +2 -2
- package/dist/chunks/{records-CiaWZrFH.js.map → records-NJiYvekn.js.map} +1 -1
- package/dist/chunks/{format-BpQBx8MZ.js → report-CwMfYa9J.js} +70 -127
- package/dist/chunks/report-CwMfYa9J.js.map +1 -0
- package/dist/chunks/round-trip-Zm3_ivgq.js +79 -0
- package/dist/chunks/round-trip-Zm3_ivgq.js.map +1 -0
- package/dist/chunks/sigv4-EokFic1V.js +247 -0
- package/dist/chunks/sigv4-EokFic1V.js.map +1 -0
- package/dist/chunks/{styles-BQnsga7p.js → styles-CCs214_3.js} +1300 -168
- package/dist/chunks/styles-CCs214_3.js.map +1 -0
- package/dist/chunks/styles-Cm62yyQX.js +2812 -0
- package/dist/chunks/styles-Cm62yyQX.js.map +1 -0
- package/dist/chunks/styles-DPQQIig4.js +1928 -0
- package/dist/chunks/styles-DPQQIig4.js.map +1 -0
- package/dist/chunks/styles-yed-UMFdNqze.js +1213 -0
- package/dist/chunks/styles-yed-UMFdNqze.js.map +1 -0
- package/dist/chunks/{text-CzJNFOS9.js → text-ystE2bYi.js} +2 -2
- package/dist/chunks/{text-CzJNFOS9.js.map → text-ystE2bYi.js.map} +1 -1
- 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 +5 -4
- package/dist/dot.js.map +1 -1
- package/dist/gexf.js +42 -10
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +850 -193
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +1189 -220
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +3 -3
- package/dist/json.js +3 -2
- package/dist/neo4j.js +6 -4
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/positions.js +45 -3
- package/dist/positions.js.map +1 -1
- package/dist/sources-cypher.d.ts +1 -0
- package/dist/sources-cypher.js +1351 -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 +1377 -0
- package/dist/sources-rest.js.map +1 -0
- package/dist/sources-sparql.d.ts +1 -0
- package/dist/sources-sparql.js +405 -0
- package/dist/sources-sparql.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/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +5 -1
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx/styles.d.ts +24 -1
- package/dist/src/formats/cx/styles.d.ts.map +1 -1
- package/dist/src/formats/cx/styles.js +118 -11
- package/dist/src/formats/cx/styles.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +1 -0
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cx2/styles.d.ts.map +1 -1
- package/dist/src/formats/cx2/styles.js +3 -1
- package/dist/src/formats/cx2/styles.js.map +1 -1
- package/dist/src/formats/cys/importer.d.ts.map +1 -1
- package/dist/src/formats/cys/importer.js +1 -0
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/styles.d.ts +2 -0
- package/dist/src/formats/cys/styles.d.ts.map +1 -1
- package/dist/src/formats/cys/styles.js +15 -7
- package/dist/src/formats/cys/styles.js.map +1 -1
- package/dist/src/formats/dot/drawing.d.ts +98 -0
- package/dist/src/formats/dot/drawing.d.ts.map +1 -0
- package/dist/src/formats/dot/drawing.js +734 -0
- package/dist/src/formats/dot/drawing.js.map +1 -0
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +108 -31
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/label-places.d.ts +34 -0
- package/dist/src/formats/dot/label-places.d.ts.map +1 -0
- package/dist/src/formats/dot/label-places.js +179 -0
- package/dist/src/formats/dot/label-places.js.map +1 -0
- package/dist/src/formats/dot/record.d.ts +50 -0
- package/dist/src/formats/dot/record.d.ts.map +1 -0
- package/dist/src/formats/dot/record.js +275 -0
- package/dist/src/formats/dot/record.js.map +1 -0
- package/dist/src/formats/dot/styles.d.ts +62 -2
- package/dist/src/formats/dot/styles.d.ts.map +1 -1
- package/dist/src/formats/dot/styles.js +1457 -120
- package/dist/src/formats/dot/styles.js.map +1 -1
- package/dist/src/formats/gexf/dialog-metrics.d.ts +15 -0
- package/dist/src/formats/gexf/dialog-metrics.d.ts.map +1 -0
- package/dist/src/formats/gexf/dialog-metrics.js +59 -0
- package/dist/src/formats/gexf/dialog-metrics.js.map +1 -0
- package/dist/src/formats/gexf/importer.d.ts +7 -0
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +41 -5
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/preview.d.ts +77 -0
- package/dist/src/formats/gexf/preview.d.ts.map +1 -0
- package/dist/src/formats/gexf/preview.js +191 -0
- package/dist/src/formats/gexf/preview.js.map +1 -0
- package/dist/src/formats/gexf/schema.d.ts.map +1 -1
- package/dist/src/formats/gexf/schema.js +2 -1
- package/dist/src/formats/gexf/schema.js.map +1 -1
- package/dist/src/formats/gexf/styles.d.ts +60 -16
- package/dist/src/formats/gexf/styles.d.ts.map +1 -1
- package/dist/src/formats/gexf/styles.js +883 -131
- package/dist/src/formats/gexf/styles.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts +5 -2
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +258 -71
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/index.d.ts +1 -1
- package/dist/src/formats/gml/index.d.ts.map +1 -1
- package/dist/src/formats/gml/index.js +1 -1
- package/dist/src/formats/gml/index.js.map +1 -1
- package/dist/src/formats/gml/positions.d.ts +7 -0
- package/dist/src/formats/gml/positions.d.ts.map +1 -1
- package/dist/src/formats/gml/positions.js +29 -7
- package/dist/src/formats/gml/positions.js.map +1 -1
- package/dist/src/formats/gml/styles.d.ts.map +1 -1
- package/dist/src/formats/gml/styles.js +756 -103
- 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 +8 -12
- package/dist/src/formats/graphml/styles-plain.js.map +1 -1
- package/dist/src/formats/graphml/styles-yed.d.ts +21 -15
- package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-yed.js +749 -148
- package/dist/src/formats/graphml/styles-yed.js.map +1 -1
- package/dist/src/formats/graphml/styles-yfiles3.d.ts +1 -1
- package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-yfiles3.js +429 -64
- package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts +3 -3
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +16 -6
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/dialect.d.ts +3 -2
- package/dist/src/formats/json/dialect.d.ts.map +1 -1
- package/dist/src/formats/json/dialect.js +39 -5
- package/dist/src/formats/json/dialect.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +13 -2
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +42 -6
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/index.d.ts +1 -1
- package/dist/src/formats/json/index.d.ts.map +1 -1
- package/dist/src/formats/json/index.js +1 -1
- package/dist/src/formats/json/index.js.map +1 -1
- package/dist/src/formats/json/positions.d.ts +5 -2
- package/dist/src/formats/json/positions.d.ts.map +1 -1
- package/dist/src/formats/json/positions.js +20 -4
- package/dist/src/formats/json/positions.js.map +1 -1
- package/dist/src/formats/json/styles.d.ts +12 -1
- package/dist/src/formats/json/styles.d.ts.map +1 -1
- package/dist/src/formats/json/styles.js +1755 -136
- package/dist/src/formats/json/styles.js.map +1 -1
- package/dist/src/formats/pajek/draw.d.ts +96 -0
- package/dist/src/formats/pajek/draw.d.ts.map +1 -0
- package/dist/src/formats/pajek/draw.js +372 -0
- package/dist/src/formats/pajek/draw.js.map +1 -0
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +70 -51
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts +9 -0
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +233 -102
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/index.d.ts +1 -0
- package/dist/src/formats/pajek/index.d.ts.map +1 -1
- package/dist/src/formats/pajek/index.js.map +1 -1
- package/dist/src/formats/pajek/styles.d.ts +15 -7
- package/dist/src/formats/pajek/styles.d.ts.map +1 -1
- package/dist/src/formats/pajek/styles.js +1279 -114
- package/dist/src/formats/pajek/styles.js.map +1 -1
- package/dist/src/formats/pajek/syntax.d.ts +10 -1
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +26 -2
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts +1 -0
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +65 -5
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/styles.d.ts +23 -3
- package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
- package/dist/src/formats/xgmml/styles.js +278 -60
- package/dist/src/formats/xgmml/styles.js.map +1 -1
- package/dist/src/index.d.ts +10 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/positions/convert.d.ts.map +1 -1
- package/dist/src/positions/convert.js +11 -1
- package/dist/src/positions/convert.js.map +1 -1
- package/dist/src/positions/extract.d.ts.map +1 -1
- package/dist/src/positions/extract.js +53 -1
- package/dist/src/positions/extract.js.map +1 -1
- package/dist/src/positions/index.d.ts +1 -1
- package/dist/src/positions/index.d.ts.map +1 -1
- package/dist/src/positions/types.d.ts +59 -0
- package/dist/src/positions/types.d.ts.map +1 -1
- package/dist/src/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 +53 -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 +740 -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 +124 -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 +511 -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 +123 -0
- package/dist/src/sources/cypher/query-builder.d.ts.map +1 -0
- package/dist/src/sources/cypher/query-builder.js +267 -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 +69 -0
- package/dist/src/sources/ids.d.ts.map +1 -0
- package/dist/src/sources/ids.js +69 -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 +31 -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 +76 -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 +650 -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 +26 -0
- package/dist/src/sources/sigv4.d.ts.map +1 -0
- package/dist/src/sources/sigv4.js +184 -0
- package/dist/src/sources/sigv4.js.map +1 -0
- package/dist/src/sources/sparql/descriptor.d.ts +10 -0
- package/dist/src/sources/sparql/descriptor.d.ts.map +1 -0
- package/dist/src/sources/sparql/descriptor.js +64 -0
- package/dist/src/sources/sparql/descriptor.js.map +1 -0
- package/dist/src/sources/sparql/index.d.ts +28 -0
- package/dist/src/sources/sparql/index.d.ts.map +1 -0
- package/dist/src/sources/sparql/index.js +314 -0
- package/dist/src/sources/sparql/index.js.map +1 -0
- package/dist/src/sources/sparql/ntriples.d.ts +69 -0
- package/dist/src/sources/sparql/ntriples.d.ts.map +1 -0
- package/dist/src/sources/sparql/ntriples.js +180 -0
- package/dist/src/sources/sparql/ntriples.js.map +1 -0
- package/dist/src/sources/sparql/params.d.ts +27 -0
- package/dist/src/sources/sparql/params.d.ts.map +1 -0
- package/dist/src/sources/sparql/params.js +5 -0
- package/dist/src/sources/sparql/params.js.map +1 -0
- package/dist/src/sources/sparql/query.d.ts +72 -0
- package/dist/src/sources/sparql/query.d.ts.map +1 -0
- package/dist/src/sources/sparql/query.js +113 -0
- package/dist/src/sources/sparql/query.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 +696 -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/annotations.d.ts +61 -5
- package/dist/src/styles/annotations.d.ts.map +1 -1
- package/dist/src/styles/annotations.js +130 -22
- package/dist/src/styles/annotations.js.map +1 -1
- package/dist/src/styles/canon/bends.d.ts +46 -0
- package/dist/src/styles/canon/bends.d.ts.map +1 -1
- package/dist/src/styles/canon/bends.js +123 -0
- package/dist/src/styles/canon/bends.js.map +1 -1
- package/dist/src/styles/canon/color-tables.d.ts +6 -1
- package/dist/src/styles/canon/color-tables.d.ts.map +1 -1
- package/dist/src/styles/canon/color-tables.js +10 -4
- package/dist/src/styles/canon/color-tables.js.map +1 -1
- package/dist/src/styles/canon/color.d.ts +3 -1
- package/dist/src/styles/canon/color.d.ts.map +1 -1
- package/dist/src/styles/canon/color.js +103 -3
- package/dist/src/styles/canon/color.js.map +1 -1
- package/dist/src/styles/canon/enums.d.ts +2 -2
- package/dist/src/styles/canon/enums.d.ts.map +1 -1
- package/dist/src/styles/canon/enums.js +82 -7
- package/dist/src/styles/canon/enums.js.map +1 -1
- package/dist/src/styles/canon/graphviz.d.ts +12 -3
- package/dist/src/styles/canon/graphviz.d.ts.map +1 -1
- package/dist/src/styles/canon/graphviz.js +57 -9
- package/dist/src/styles/canon/graphviz.js.map +1 -1
- package/dist/src/styles/canon/number.d.ts +8 -0
- package/dist/src/styles/canon/number.d.ts.map +1 -1
- package/dist/src/styles/canon/number.js +18 -0
- package/dist/src/styles/canon/number.js.map +1 -1
- package/dist/src/styles/canon/text.d.ts +29 -2
- package/dist/src/styles/canon/text.d.ts.map +1 -1
- package/dist/src/styles/canon/text.js +156 -16
- package/dist/src/styles/canon/text.js.map +1 -1
- package/dist/src/styles/codes.d.ts +2 -0
- package/dist/src/styles/codes.d.ts.map +1 -1
- package/dist/src/styles/codes.js +2 -0
- package/dist/src/styles/codes.js.map +1 -1
- package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
- package/dist/src/styles/cyjs/cascade.js +1037 -35
- 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 +5 -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 +216 -12
- package/dist/src/styles/cyjs/emit.js.map +1 -1
- package/dist/src/styles/cyjs/face.d.ts +20 -0
- package/dist/src/styles/cyjs/face.d.ts.map +1 -0
- package/dist/src/styles/cyjs/face.js +332 -0
- package/dist/src/styles/cyjs/face.js.map +1 -0
- package/dist/src/styles/cyjs/mappers.d.ts +48 -2
- package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
- package/dist/src/styles/cyjs/mappers.js +463 -26
- package/dist/src/styles/cyjs/mappers.js.map +1 -1
- package/dist/src/styles/cyjs/routes.d.ts +53 -0
- package/dist/src/styles/cyjs/routes.d.ts.map +1 -0
- package/dist/src/styles/cyjs/routes.js +360 -0
- package/dist/src/styles/cyjs/routes.js.map +1 -0
- package/dist/src/styles/cytoscape/charts.d.ts +23 -0
- package/dist/src/styles/cytoscape/charts.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/charts.js +560 -0
- package/dist/src/styles/cytoscape/charts.js.map +1 -0
- package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/emit.js +204 -44
- package/dist/src/styles/cytoscape/emit.js.map +1 -1
- package/dist/src/styles/cytoscape/lexicon.d.ts +97 -3
- package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/lexicon.js +413 -79
- package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
- package/dist/src/styles/cytoscape/mappings.d.ts +30 -0
- package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/mappings.js +92 -0
- package/dist/src/styles/cytoscape/mappings.js.map +1 -1
- package/dist/src/styles/cytoscape/resolve.d.ts +46 -3
- package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/resolve.js +632 -22
- 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 +50 -0
- package/dist/src/styles/defaults.d.ts.map +1 -1
- package/dist/src/styles/defaults.js +315 -37
- package/dist/src/styles/defaults.js.map +1 -1
- package/dist/src/styles/index.d.ts +4 -3
- package/dist/src/styles/index.d.ts.map +1 -1
- package/dist/src/styles/index.js +3 -2
- package/dist/src/styles/index.js.map +1 -1
- package/dist/src/styles/internal.d.ts +1 -0
- package/dist/src/styles/internal.d.ts.map +1 -1
- package/dist/src/styles/internal.js +1 -0
- package/dist/src/styles/internal.js.map +1 -1
- package/dist/src/styles/io/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/generic.d.ts.map +1 -1
- package/dist/src/styles/io/generic.js +56 -16
- package/dist/src/styles/io/generic.js.map +1 -1
- package/dist/src/styles/io/round-trip.d.ts +56 -0
- package/dist/src/styles/io/round-trip.d.ts.map +1 -0
- package/dist/src/styles/io/round-trip.js +138 -0
- package/dist/src/styles/io/round-trip.js.map +1 -0
- package/dist/src/styles/io/writer.d.ts.map +1 -1
- package/dist/src/styles/io/writer.js +13 -4
- package/dist/src/styles/io/writer.js.map +1 -1
- package/dist/src/styles/notes.d.ts.map +1 -1
- package/dist/src/styles/notes.js +1 -0
- package/dist/src/styles/notes.js.map +1 -1
- package/dist/src/styles/plan/features.d.ts +1 -1
- package/dist/src/styles/plan/features.d.ts.map +1 -1
- package/dist/src/styles/plan/features.js +22 -2
- package/dist/src/styles/plan/features.js.map +1 -1
- package/dist/src/styles/plan/index.d.ts +1 -1
- package/dist/src/styles/plan/index.d.ts.map +1 -1
- package/dist/src/styles/plan/index.js +1 -1
- package/dist/src/styles/plan/index.js.map +1 -1
- package/dist/src/styles/plan/plan.d.ts.map +1 -1
- package/dist/src/styles/plan/plan.js +61 -4
- package/dist/src/styles/plan/plan.js.map +1 -1
- package/dist/src/styles/plan/resolve.d.ts +13 -1
- package/dist/src/styles/plan/resolve.d.ts.map +1 -1
- package/dist/src/styles/plan/resolve.js +53 -6
- package/dist/src/styles/plan/resolve.js.map +1 -1
- package/dist/src/styles/slots.d.ts +14 -0
- package/dist/src/styles/slots.d.ts.map +1 -0
- package/dist/src/styles/slots.js +20 -0
- package/dist/src/styles/slots.js.map +1 -0
- package/dist/src/styles/types.d.ts +638 -5
- package/dist/src/styles/types.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.d.ts +3 -2
- package/dist/src/styles/vocabulary.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.js +218 -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 +29 -238
- package/dist/styles.js.map +1 -1
- package/dist/xgmml.js +3 -3
- package/docs/samples/people.json +6 -0
- package/package.json +53 -8
- package/src/common/report.ts +27 -7
- package/src/formats/cx/importer.ts +6 -1
- package/src/formats/cx/styles.ts +144 -9
- package/src/formats/cx2/importer.ts +1 -0
- package/src/formats/cx2/styles.ts +3 -1
- package/src/formats/cys/importer.ts +1 -0
- package/src/formats/cys/styles.ts +27 -5
- package/src/formats/dot/drawing.ts +799 -0
- package/src/formats/dot/importer.ts +120 -35
- package/src/formats/dot/label-places.ts +228 -0
- package/src/formats/dot/record.ts +336 -0
- package/src/formats/dot/styles.ts +1657 -154
- package/src/formats/gexf/dialog-metrics.ts +61 -0
- package/src/formats/gexf/importer.ts +50 -5
- package/src/formats/gexf/preview.ts +217 -0
- package/src/formats/gexf/schema.ts +2 -1
- package/src/formats/gexf/styles.ts +1144 -142
- package/src/formats/gml/importer.ts +291 -76
- package/src/formats/gml/index.ts +1 -1
- package/src/formats/gml/positions.ts +29 -7
- package/src/formats/gml/styles.ts +854 -111
- package/src/formats/graphml/styles-plain.ts +8 -23
- package/src/formats/graphml/styles-yed.ts +821 -159
- package/src/formats/graphml/styles-yfiles3.ts +485 -63
- package/src/formats/graphml/yfiles.ts +19 -6
- package/src/formats/json/dialect.ts +41 -5
- package/src/formats/json/importer.ts +59 -7
- package/src/formats/json/index.ts +1 -0
- package/src/formats/json/positions.ts +22 -5
- package/src/formats/json/styles.ts +2041 -185
- package/src/formats/pajek/draw.ts +458 -0
- package/src/formats/pajek/exporter.ts +81 -49
- package/src/formats/pajek/importer.ts +278 -103
- package/src/formats/pajek/index.ts +1 -0
- package/src/formats/pajek/styles.ts +1382 -133
- package/src/formats/pajek/syntax.ts +27 -2
- package/src/formats/xgmml/emit.ts +73 -5
- package/src/formats/xgmml/styles.ts +331 -71
- package/src/index.ts +94 -0
- package/src/positions/convert.ts +12 -1
- package/src/positions/extract.ts +55 -1
- package/src/positions/index.ts +1 -0
- package/src/positions/types.ts +60 -0
- package/src/registry.ts +326 -1
- package/src/sources/builtins.ts +63 -0
- package/src/sources/codes.ts +235 -0
- package/src/sources/context.ts +894 -0
- package/src/sources/credentials.ts +409 -0
- package/src/sources/cypher/descriptor.ts +131 -0
- package/src/sources/cypher/flatten.ts +323 -0
- package/src/sources/cypher/index.ts +628 -0
- package/src/sources/cypher/params.ts +41 -0
- package/src/sources/cypher/profiles.ts +78 -0
- package/src/sources/cypher/query-builder.ts +327 -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 +80 -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 +32 -0
- package/src/sources/registry.ts +325 -0
- package/src/sources/rest/descriptor.ts +79 -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 +776 -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 +209 -0
- package/src/sources/sparql/descriptor.ts +67 -0
- package/src/sources/sparql/index.ts +356 -0
- package/src/sources/sparql/ntriples.ts +219 -0
- package/src/sources/sparql/params.ts +28 -0
- package/src/sources/sparql/query.ts +162 -0
- package/src/sources/testing.ts +210 -0
- package/src/sources/types.ts +776 -0
- package/src/styles/annotations.ts +201 -27
- package/src/styles/canon/bends.ts +137 -0
- package/src/styles/canon/color-tables.ts +10 -4
- package/src/styles/canon/color.ts +105 -3
- package/src/styles/canon/enums.ts +99 -8
- package/src/styles/canon/graphviz.ts +71 -10
- package/src/styles/canon/number.ts +19 -0
- package/src/styles/canon/text.ts +187 -16
- package/src/styles/codes.ts +2 -0
- package/src/styles/cyjs/cascade.ts +1193 -38
- package/src/styles/cyjs/defaults-table.ts +5 -0
- package/src/styles/cyjs/emit.ts +247 -16
- package/src/styles/cyjs/face.ts +372 -0
- package/src/styles/cyjs/mappers.ts +498 -28
- package/src/styles/cyjs/routes.ts +432 -0
- package/src/styles/cytoscape/charts.ts +684 -0
- package/src/styles/cytoscape/emit.ts +220 -44
- package/src/styles/cytoscape/lexicon.ts +459 -80
- package/src/styles/cytoscape/mappings.ts +108 -0
- package/src/styles/cytoscape/resolve.ts +763 -23
- package/src/styles/cytoscape/translate.ts +11 -11
- package/src/styles/defaults.ts +436 -38
- package/src/styles/index.ts +5 -0
- package/src/styles/internal.ts +1 -0
- package/src/styles/io/block.ts +10 -0
- package/src/styles/io/generic.ts +79 -23
- package/src/styles/io/round-trip.ts +202 -0
- package/src/styles/io/writer.ts +14 -4
- package/src/styles/notes.ts +1 -0
- package/src/styles/plan/features.ts +23 -2
- package/src/styles/plan/index.ts +1 -1
- package/src/styles/plan/plan.ts +69 -5
- package/src/styles/plan/resolve.ts +61 -6
- package/src/styles/slots.ts +25 -0
- package/src/styles/types.ts +658 -4
- package/src/styles/vocabulary.ts +226 -3
- package/src/types.ts +19 -5
- package/dist/chunks/block-DiGq58c3.js.map +0 -1
- package/dist/chunks/choose--jM0yYCo.js +0 -57
- package/dist/chunks/choose--jM0yYCo.js.map +0 -1
- package/dist/chunks/convert-BcQ8_jMo.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/exporter-CrDWIyiq.js.map +0 -1
- package/dist/chunks/format-BpQBx8MZ.js.map +0 -1
- package/dist/chunks/generic-Dq1ntt9q.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/importer-iFYPEKaJ.js.map +0 -1
- package/dist/chunks/importer-yh_aBCU6.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 +0 -690
- package/dist/chunks/styles-D3fRphrO.js.map +0 -1
- package/dist/chunks/styles-yed-BF5x3_Y5.js +0 -842
- package/dist/chunks/styles-yed-BF5x3_Y5.js.map +0 -1
- package/dist/chunks/writer-DMKvthQE.js +0 -448
- package/dist/chunks/writer-DMKvthQE.js.map +0 -1
package/dist/neo4j.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neo4j.js","sources":["../src/formats/neo4j/header.ts","../src/formats/neo4j/importer.ts","../src/formats/neo4j/exporter.ts","../src/formats/neo4j/index.ts"],"sourcesContent":["/**\n * The neo4j-admin import header grammar (research note 07 section 2.6): every header cell is\n * `<name>:<field type>(<id space>){<options>}` where the name and every later part are optional.\n * The field types `ID`, `LABEL`, `START_ID`, `END_ID`, `TYPE` and `IGNORE` are structural; any\n * other field type is a property type of design section 5.1 (`int`, `long`, `float`, `double`,\n * `boolean`, `byte`, `short`, `char`, `string`, `point`, `date`, `localtime`, `time`,\n * `localdatetime`, `datetime`, `duration`, each with an optional `[]` suffix); a cell without a\n * colon is a string property. An id space may follow `ID`, `START_ID` and `END_ID`; brace options\n * (`label`, `id-type`) may follow any structural type.\n */\n\nimport { GraphFormatError } from \"@graphty/graph-format\";\n\n/**\n * The structural field types and the marker for a property column.\n * @category Plugin helpers\n */\nexport type FieldKind = \"ID\" | \"LABEL\" | \"START_ID\" | \"END_ID\" | \"TYPE\" | \"IGNORE\" | \"PROPERTY\";\n\n/**\n * One parsed header cell.\n * @category Plugin helpers\n */\nexport interface HeaderField {\n /** The cell text as written. */\n readonly text: string;\n /** The property name (the id property name for `name:ID`); empty when none. */\n readonly name: string;\n /** The field kind. */\n readonly kind: FieldKind;\n /** The property type text for a PROPERTY field (null when the cell declares none); null otherwise. */\n readonly type: string | null;\n /** The id space of an ID / START_ID / END_ID field, or null. */\n readonly space: string | null;\n /** The brace options, keys lower-cased. */\n readonly options: ReadonlyMap<string, string>;\n}\n\nconst STRUCTURAL: ReadonlySet<string> = new Set([\"ID\", \"LABEL\", \"START_ID\", \"END_ID\", \"TYPE\", \"IGNORE\"]);\nconst SPACE_KINDS: ReadonlySet<string> = new Set([\"ID\", \"START_ID\", \"END_ID\"]);\nconst HEADER_MARKER = /^[^:{}()]*:\\s*(ID|START_ID|END_ID)\\s*(\\(|\\{|$)/i;\nconst CELL = /^([^:(){}]*)(?::([^:(){}]*))?(?:\\(([^)]*)\\))?(?:\\{([^}]*)\\})?$/;\n\n/**\n * Whether a record looks like a section header: some cell declares an `ID`, `START_ID` or `END_ID`\n * field. The neo4j-admin convention allows several files, each with its own header; graphty's\n * single-file convention (the CSVDataSource of graphty-element) concatenates sections, so a header\n * may appear anywhere. Mid-file, a quoted marker cell (`\"ref:id\"`) is data unless the whole record\n * is quoted (a QUOTE_ALL export writes its headers that way) and every cell is a valid header cell.\n * ponytail: a fully quoted data row whose every cell is a valid header cell and one of them a marker\n * (`\"1\",\"ref:id\"`) still reads as a header; telling them apart would need the section's column names.\n * @param cells - the record's cells\n * @param count - how many cells are valid\n * @param quoted - which cells were quoted, or undefined to look at every cell (the first record)\n * @returns true when the record is a header\n * @category Plugin helpers\n */\nexport function isHeaderRecord(cells: readonly string[], count: number, quoted?: readonly boolean[]): boolean {\n let quotedMarker = false;\n for (let i = 0; i < count; i++) {\n const cell = cells[i];\n // every header marker holds a colon; the includes keeps the regex off the data rows\n if (cell.includes(\":\") && HEADER_MARKER.test(cell.trim())) {\n if (quoted?.[i] !== true) {\n return true;\n }\n quotedMarker = true;\n }\n }\n return quotedMarker && quoted !== undefined && isQuotedHeader(cells, count, quoted);\n}\n\n/**\n * Whether a record is fully quoted and every cell parses as a header cell.\n * @param cells - the record's cells\n * @param count - how many cells are valid\n * @param quoted - which cells were quoted\n * @returns true when the record reads as a quoted header\n */\nfunction isQuotedHeader(cells: readonly string[], count: number, quoted: readonly boolean[]): boolean {\n for (let i = 0; i < count; i++) {\n if (!quoted[i]) {\n return false;\n }\n try {\n parseHeaderField(cells[i]);\n } catch {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Parse one header cell.\n * @param text - the cell text\n * @returns the field; E_UNSUPPORTED (reason \"header\") for a cell outside the grammar\n * @category Plugin helpers\n */\nexport function parseHeaderField(text: string): HeaderField {\n const trimmed = text.trim();\n const m = CELL.exec(trimmed);\n if (m === null) {\n throw headerError(text, \"not a neo4j header cell\");\n }\n const name = m[1].trim();\n const rawType = m[2] === undefined ? null : m[2].trim();\n const space = m[3] === undefined ? null : m[3].trim();\n const options = parseOptions(text, m[4]);\n if (rawType === null) {\n return untypedField(text, name, space, options);\n }\n if (rawType.length === 0) {\n throw headerError(text, \"an empty field type\");\n }\n const upper = rawType.toUpperCase();\n if (STRUCTURAL.has(upper)) {\n return structuralField(text, name, upper as Exclude<FieldKind, \"PROPERTY\">, space, options);\n }\n if (name.length === 0) {\n throw headerError(text, \"a property column needs a name\");\n }\n if (space !== null) {\n throw headerError(text, \"an id space is only allowed on ID, START_ID and END_ID\");\n }\n return { text, name, kind: \"PROPERTY\", type: rawType, space: null, options };\n}\n\n/**\n * The field of a cell with no type: `name` alone is a string property.\n * @param text - the whole cell, for errors\n * @param name - the property name\n * @param space - the id space, or null\n * @param options - the options\n * @returns the field\n */\nfunction untypedField(\n text: string,\n name: string,\n space: string | null,\n options: ReadonlyMap<string, string>,\n): HeaderField {\n if (name.length === 0) {\n throw headerError(text, \"an empty header cell\");\n }\n if (space !== null || options.size > 0) {\n throw headerError(text, \"an id space or options need a field type\");\n }\n return { text, name, kind: \"PROPERTY\", type: null, space: null, options };\n}\n\n/**\n * The field of a cell with a structural type (ID, START_ID, END_ID, LABEL, TYPE, IGNORE).\n * @param text - the whole cell, for errors\n * @param name - the property name, or empty\n * @param kind - the structural kind\n * @param space - the id space, or null\n * @param options - the options\n * @returns the field\n */\nfunction structuralField(\n text: string,\n name: string,\n kind: Exclude<FieldKind, \"PROPERTY\">,\n space: string | null,\n options: ReadonlyMap<string, string>,\n): HeaderField {\n if (space !== null && !SPACE_KINDS.has(kind)) {\n throw headerError(text, `an id space is only allowed on ID, START_ID and END_ID, not ${kind}`);\n }\n if (name.length > 0 && kind !== \"ID\" && kind !== \"IGNORE\") {\n throw headerError(text, `a ${kind} field cannot be stored as a property`);\n }\n return { text, name, kind, type: null, space: space === \"\" ? null : space, options };\n}\n\n/**\n * Parse the `{key:value, key:value}` options of a header cell.\n * @param text - the whole cell, for errors\n * @param body - the text between the braces, or undefined when absent\n * @returns the options with lower-cased keys\n */\nfunction parseOptions(text: string, body: string | undefined): ReadonlyMap<string, string> {\n const options = new Map<string, string>();\n if (body === undefined || body.trim().length === 0) {\n return options;\n }\n for (const part of body.split(\",\")) {\n const colon = part.indexOf(\":\");\n if (colon < 0) {\n throw headerError(text, `option \"${part.trim()}\" is not key:value`);\n }\n const key = part.slice(0, colon).trim().toLowerCase();\n const value = part.slice(colon + 1).trim();\n if (key.length === 0) {\n throw headerError(text, \"an option needs a key\");\n }\n options.set(key, value);\n }\n return options;\n}\n\n/**\n * The error of a malformed header cell.\n * @param text - the cell\n * @param reason - why\n * @returns the error\n */\nfunction headerError(text: string, reason: string): GraphFormatError {\n return new GraphFormatError(\"E_UNSUPPORTED\", `header cell \"${text}\": ${reason}`, {\n reason: \"header\",\n cell: text,\n detail: reason,\n });\n}\n\n/**\n * Write a header cell from its parts, the inverse of parseHeaderField.\n * @param name - the property name, or empty\n * @param type - the field type or property type\n * @param space - the id space, or null\n * @returns the cell text\n * @category Plugin helpers\n */\nexport function formatHeaderField(name: string, type: string, space: string | null): string {\n const base = `${name}:${type}`;\n return space === null ? base : `${base}(${space})`;\n}\n","/**\n * The Neo4j importer (design sections 8.4 and 5.1, research note 07 sections 2.6 and 2.10): reads\n * neo4j-admin import CSV -- node tables with `:ID`, `:LABEL` and typed property columns,\n * relationship tables with `:START_ID`, `:END_ID`, `:TYPE` and typed property columns -- and pushes\n * scalars into the sink one record at a time. Input is one or more files: the primary input plus the\n * `nodes` and `relationships` option inputs, each read in order; every input holds one or more\n * sections, each starting with its own header row (the single-file convention of graphty-element's\n * CSVDataSource, where a node table and a relationship table follow each other in one file).\n *\n * Mapping (design section 5.1 and decision Q27):\n * - Property columns are declared up front from the header types (`int` -> i32, `long` -> f64\n * with a precision issue beyond 2^53, `float` -> f32, `double` -> f64, `boolean` -> bool,\n * `string` / `char` / `duration` -> string, temporal types -> f64 milliseconds with a `.text`\n * companion when the source text is not canonical, `point` -> json, `type[]` -> list); an\n * untyped column is a string property. An unquoted empty cell is \"property not set\"; a quoted\n * empty cell is an empty string (or an empty list), as neo4j-admin stores it by default.\n * - `:LABEL` becomes the node list-of-dict column `labels` (role `labels`); `:TYPE` the edge dict\n * column `type` (role `kind`); an id space `:ID(Space)` the node dict column `idSpace` (role\n * `idSpace`), and a stored id `name:ID(Space)` also a string node column `name` whose\n * `origin.namespace` is the space. A property whose name collides with one of those is renamed\n * `<name>#<name>` (design section 5.6).\n * - Id spaces: neo4j-admin keeps one id space per `:ID(Space)` name, so `1` in `:ID(Product)` and\n * `1` in `:ID(Category)` are two nodes. The core has one id space, so a node of a spaced section\n * is stored under the string id `Space:id` (every row of the section, collision or not, so an id\n * never depends on file order), its id text goes into the node string column `originalId` and\n * its space into `idSpace`. The column has no role: the `originalId` role means an id rewritten by\n * `sanitizeIds: \"mangle\"`, which other importers restore as the node id. `:START_ID(Space)` /\n * `:END_ID(Space)` endpoints are qualified the same way before the lookup; an endpoint without a\n * space is looked up as written.\n * - Ids are text cells coerced by the `ids` option (\"canonical\" by default, so `1` is the number 1\n * and `007` stays a string; integers beyond 2^53 stay strings). Relationships are always directed\n * (\"In Neo4j, all relationships have a direction\"), so the sink is set directed before the first\n * edge and `onMixedDirection: \"undirected\"` is the way to read a file as undirected.\n * - `:IGNORE` columns are skipped and counted in a loss note.\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 {\n type AttributeDeclarationInput,\n declareAttribute,\n declareCompanion,\n type DeclaredAttribute,\n declareOn,\n losesPrecision,\n parseDeclaredTemporal,\n parseDeclaredValue,\n PRECISION_CODE,\n RENAMED_CODE,\n takenIn,\n uniqueColumnName,\n} from \"../../common/attributes.js\";\nimport {\n DANGLING_REFERENCE_CODE as SHARED_DANGLING_REFERENCE_CODE,\n DUPLICATE_NODE_CODE as SHARED_DUPLICATE_NODE_CODE,\n MISSING_ENDPOINT_CODE as SHARED_MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE as SHARED_MISSING_ID_CODE,\n ROLE_TAKEN_CODE as SHARED_ROLE_TAKEN_CODE,\n} from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec } from \"../../common/declared-types.js\";\nimport { DirectionResolver } from \"../../common/direction.js\";\nimport { ID_MERGED_CODE as SHARED_ID_MERGED_CODE, IdCoercer } from \"../../common/ids.js\";\nimport { inputLength, isImportInput, type ReadOptions, throwIfAborted } from \"../../common/input.js\";\nimport { type ListSyntax, splitListText } from \"../../common/lists.js\";\nimport {\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { agree, plural, withArticle } from \"../../common/plural.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { parseTemporal } from \"../../common/temporal.js\";\nimport { parseWeightText } from \"../../common/weights.js\";\nimport {\n type CommonImportOptions,\n type GraphImporter,\n ImportError,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport { checkRecordSyntax, RecordReader, type RecordSyntax } from \"../csv/records.js\";\nimport { type FieldKind, type HeaderField, isHeaderRecord, parseHeaderField } from \"./header.js\";\n\n/**\n * The format-specific options of the Neo4j importer.\n * @category Built-in formats\n */\nexport interface Neo4jImportOptions extends CommonImportOptions {\n /**\n * More node files, each a string, bytes or a stream with its own header row; read after the\n * main input.\n */\n nodes?: ImportInput | readonly ImportInput[] | undefined;\n /**\n * Relationship files, each a string, bytes or a stream with its own header row; read after the\n * node files.\n */\n relationships?: ImportInput | readonly ImportInput[] | undefined;\n /**\n * The field delimiter, one character (neo4j-admin's `--delimiter`). The default is to detect\n * \",\" or a tab from the first rows, so a `.tsv` file needs no option. It must differ from\n * `arrayDelimiter`: with `delimiter: \";\"`, also pass `arrayDelimiter: \",\"` or `\"|\"`.\n * @defaultValue detected\n */\n delimiter?: string | undefined;\n /**\n * The delimiter inside list values and `:LABEL` cells (neo4j-admin's `--array-delimiter`). It\n * must differ from `delimiter`.\n * @defaultValue \";\"\n */\n arrayDelimiter?: \";\" | \",\" | \"|\" | undefined;\n /**\n * The quote character, one character (neo4j-admin's `--quote`).\n * @defaultValue '\"'\n */\n quote?: string | undefined;\n}\n\n/**\n * The name of the node list column holding `:LABEL` values.\n * @category Built-in formats\n */\nexport const LABELS_COLUMN = \"labels\";\n\n/**\n * The name of the edge dict column holding `:TYPE` values.\n * @category Built-in formats\n */\nexport const TYPE_COLUMN = \"type\";\n\n/**\n * The name of the node dict column holding the id space of `:ID(Space)`.\n * @category Built-in formats\n */\nexport const ID_SPACE_COLUMN = \"idSpace\";\n\n/**\n * Neo4j CSV: the name of the node column that holds a node's id as the file wrote it, for a node of an id\n * space (`:ID(Person)`), whose node id is `Person:<id>`. It has nothing to do with the `originalId` role that\n * `sanitizeIds: \"mangle\"` uses.\n * @category Built-in formats\n */\nexport const ORIGINAL_ID_COLUMN = \"originalId\";\n\n/**\n * A header row (or a whole section) is malformed; the import aborts.\n * @category Issue and loss codes\n */\nexport const HEADER_CODE = \"E_NEO4J_HEADER\";\n\n/**\n * A row has a different number of cells than its header.\n * @category Issue and loss codes\n */\nexport const COLUMN_COUNT_CODE = \"E_NEO4J_COLUMN_COUNT\";\n\n/**\n * A node row has an unquoted empty `:ID` cell (a quoted empty cell is the id \"\").\n * @category Issue and loss codes\n */\nexport const MISSING_ID_CODE = SHARED_MISSING_ID_CODE;\n\n/**\n * A relationship row has an unquoted empty `:START_ID` or `:END_ID` cell.\n * @category Issue and loss codes\n */\nexport const MISSING_ENDPOINT_CODE = SHARED_MISSING_ENDPOINT_CODE;\n\n/**\n * A node id was declared twice (same id space); the later row's properties win.\n * @category Issue and loss codes\n */\nexport const DUPLICATE_NODE_CODE = SHARED_DUPLICATE_NODE_CODE;\n\n/**\n * A node id was declared in two id spaces -- a spaced id `Space:id` equals the text of an id declared without a space;\n * the later row is skipped.\n * @category Issue and loss codes\n */\nexport const ID_SPACE_COLLISION_CODE = \"E_NEO4J_ID_SPACE_COLLISION\";\n\n/**\n * A `:START_ID(Space)` / `:END_ID(Space)` endpoint's qualified id `Space:id` names a node a node row declared in\n * another id space (without a space); the row is skipped.\n * @category Issue and loss codes\n */\nexport const ENDPOINT_SPACE_CODE = \"E_NEO4J_ENDPOINT_SPACE\";\n\n/**\n * Two different id cells became one id under `ids: \"number\"`.\n * @category Issue and loss codes\n */\nexport const ID_MERGED_CODE = SHARED_ID_MERGED_CODE;\n\n/**\n * A header brace option the importer does not act on.\n * @category Issue and loss codes\n */\nexport const HEADER_OPTION_CODE = \"W_NEO4J_HEADER_OPTION_IGNORED\";\n\n/**\n * You read into a graph builder that already has the labels, type or id space attribute, so this file's one is kept\n * without its role.\n * @category Issue and loss codes\n */\nexport const ROLE_TAKEN_CODE = SHARED_ROLE_TAKEN_CODE;\n\n/**\n * A relationship row with an empty `:TYPE` cell (neo4j-admin requires a type); the relationship is kept.\n * @category Issue and loss codes\n */\nexport const MISSING_TYPE_CODE = \"W_NEO4J_MISSING_TYPE\";\n\n/**\n * A file given under the `nodes` option holds a relationship header, or the reverse.\n * @category Issue and loss codes\n */\nexport const SECTION_KIND_CODE = \"W_NEO4J_SECTION_KIND\";\n\n/**\n * Relationship endpoints that no node row declares became nodes (the shared W_DANGLING_REFERENCE).\n * @category Issue and loss codes\n */\nexport const DANGLING_REFERENCE_CODE = SHARED_DANGLING_REFERENCE_CODE;\n\n/**\n * `:IGNORE` columns were skipped.\n * @category Built-in formats\n */\nexport const IGNORED_COLUMNS_LOSS = \"W_NEO4J_IGNORED_COLUMNS\";\n\n/** The common options the Neo4j 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 \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\nconst NEO4J = \"neo4j\";\n\n/** Rows between two checks of the cancellation signal (a whole string input is one chunk). */\nconst ABORT_CHECK_INTERVAL = 64;\n\nconst LABELS_DECL: ColumnDecl = {\n name: LABELS_COLUMN,\n dtype: \"list\",\n itemDtype: \"dict\",\n nullable: true,\n role: \"labels\",\n origin: { format: NEO4J, id: \":LABEL\", title: null, type: \"LABEL\", namespace: null },\n};\n\nconst TYPE_DECL: ColumnDecl = {\n name: TYPE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n role: \"kind\",\n origin: { format: NEO4J, id: \":TYPE\", title: null, type: \"TYPE\", namespace: null },\n};\n\nconst ID_SPACE_DECL: ColumnDecl = {\n name: ID_SPACE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n role: \"idSpace\",\n origin: { format: NEO4J, id: \":ID\", title: null, type: \"ID\", namespace: null },\n};\n\nconst ORIGINAL_ID_DECL: ColumnDecl = {\n name: ORIGINAL_ID_COLUMN,\n dtype: \"string\",\n nullable: true,\n // origin.type stays null so the column is never mistaken for a stored id (`name:ID`)\n origin: { format: NEO4J, id: \":ID\", title: null, type: null, namespace: null },\n};\n\nconst ARRAY_DELIMITERS: Readonly<Record<string, ListSyntax>> = { \";\": \"semicolon\", \",\": \"comma\", \"|\": \"pipe\" };\n\n/** The resolved format-specific options. */\ninterface ResolvedNeo4jOptions {\n readonly nodes: readonly ImportInput[];\n readonly relationships: readonly ImportInput[];\n readonly syntax: RecordSyntax;\n readonly listSyntax: ListSyntax;\n}\n\n/** One property column of a section. */\ninterface PropertySlot {\n /** The cell index. */\n readonly cell: number;\n /** The column name (after any rename). */\n readonly name: string;\n /** The column handle. */\n readonly handle: ColumnHandle;\n /** How the cell text is parsed. */\n readonly spec: DeclaredTypeSpec;\n /** The declaration of the companion text column of a temporal property, or null. */\n readonly companionDecl: ColumnDecl | null;\n /** The companion's handle once a value needed it (design section 5.1); INVALID_INDEX before. */\n companion: ColumnHandle;\n}\n\n/** A node section: the header interpreted. */\ninterface NodeSection {\n readonly kind: \"node\";\n readonly width: number;\n readonly idCell: number;\n /** The column holding the id as a property (`name:ID`), or INVALID_INDEX. */\n readonly idHandle: ColumnHandle;\n readonly space: string | null;\n readonly spaceCode: number;\n readonly labelCells: readonly number[];\n readonly extraLabels: readonly string[];\n readonly properties: readonly PropertySlot[];\n}\n\n/** A relationship section: the header interpreted. */\ninterface RelationshipSection {\n readonly kind: \"relationship\";\n readonly width: number;\n readonly startCell: number;\n readonly endCell: number;\n /** The id space of `:START_ID` / `:END_ID`, or null when the header declares none. */\n readonly startSpace: string | null;\n readonly endSpace: string | null;\n /** The id space of `:START_ID` / `:END_ID` as a registry code, or 0 when the header declares none. */\n readonly startSpaceCode: number;\n readonly endSpaceCode: number;\n /** The `:TYPE` cell, or -1. */\n readonly typeCell: number;\n /** The cell of the property named by `weightFrom`, or -1. */\n readonly weightCell: number;\n readonly properties: readonly PropertySlot[];\n}\n\ntype Section = NodeSection | RelationshipSection;\n\n/** The delimiters sniffed between when none is given: neo4j-admin's default and the TSV tab. */\nconst NEO4J_DELIMITER_CANDIDATES: readonly string[] = Object.freeze([\",\", \"\\t\"]);\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the resolved options; E_UNSUPPORTED for an invalid value\n */\nfunction resolveNeo4jOptions(options: Neo4jImportOptions | undefined): ResolvedNeo4jOptions {\n const o: Neo4jImportOptions = options ?? {};\n const arrayDelimiter = o.arrayDelimiter ?? \";\";\n const listSyntax = ARRAY_DELIMITERS[arrayDelimiter];\n if (typeof arrayDelimiter !== \"string\" || listSyntax === undefined) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option arrayDelimiter: ${JSON.stringify(arrayDelimiter)} is not one of \";\", \",\", \"|\"`,\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n if (arrayDelimiter === \",\" && o.delimiter === undefined) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n 'option arrayDelimiter \",\" needs the delimiter option: the field delimiter is a comma unless another is given',\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n const syntax = checkRecordSyntax({\n delimiter: o.delimiter ?? null,\n quote: o.quote ?? '\"',\n candidates: NEO4J_DELIMITER_CANDIDATES.filter((d) => d !== arrayDelimiter),\n });\n if (syntax.delimiter === arrayDelimiter) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `options delimiter and arrayDelimiter must differ: both are ${JSON.stringify(arrayDelimiter)}; pass another arrayDelimiter (\";\", \",\" or \"|\")`,\n {\n option: \"arrayDelimiter\",\n found: arrayDelimiter,\n },\n );\n }\n return {\n nodes: inputList(\"nodes\", o.nodes),\n relationships: inputList(\"relationships\", o.relationships),\n syntax,\n listSyntax,\n };\n}\n\n/**\n * Normalize an input-list option.\n * @param name - the option name\n * @param value - one input, a list of inputs, or undefined\n * @returns the inputs; E_UNSUPPORTED for anything else\n */\nfunction inputList(name: string, value: unknown): readonly ImportInput[] {\n if (value === undefined || value === null) {\n return [];\n }\n const list: unknown[] = Array.isArray(value) ? (value as unknown[]) : [value];\n for (const item of list) {\n if (!isImportInput(item)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option ${name}: an entry is not an ImportInput`, {\n option: name,\n found: typeof item,\n });\n }\n }\n return list as ImportInput[];\n}\n\n/**\n * Which nodes were declared by a node row and in which id space, by node index, so a repeated id\n * is reported (a duplicate in one space, a collision across spaces).\n */\nclass NodeRegistry {\n private codes = new Uint32Array(1024);\n\n private readonly spaces = new Map<string | null, number>();\n\n /**\n * The code of an id space (1 for \"no space\").\n * @param space - the space name or null\n * @returns a code >= 1\n */\n codeOf(space: string | null): number {\n let code = this.spaces.get(space);\n if (code === undefined) {\n code = this.spaces.size + 1;\n this.spaces.set(space, code);\n }\n return code;\n }\n\n /**\n * Record that a node row declared a node.\n * @param index - the node index\n * @param code - the space code\n * @returns \"new\" for a first declaration, \"duplicate\" for a repeat in the same space, \"collision\" across spaces\n */\n declare(index: number, code: number): \"new\" | \"duplicate\" | \"collision\" {\n if (index >= this.codes.length) {\n let size = this.codes.length * 2;\n while (size <= index) {\n size *= 2;\n }\n const grown = new Uint32Array(size);\n grown.set(this.codes);\n this.codes = grown;\n }\n const previous = this.codes[index];\n if (previous === 0) {\n this.codes[index] = code;\n return \"new\";\n }\n return previous === code ? \"duplicate\" : \"collision\";\n }\n\n /**\n * The space code a node row declared a node in.\n * @param index - the node index\n * @returns the code, or 0 when no node row declared the node\n */\n codeAt(index: number): number {\n return index < this.codes.length ? this.codes[index] : 0;\n }\n}\n\n/**\n * Byte progress over several inputs as one sequence: each input's progress is offset by the bytes\n * of the inputs before it, and the total is known only when every input is in memory.\n */\nclass ProgressTracker {\n private readonly callback: ((bytesDone: number, bytesTotal?: number) => void) | null;\n\n private readonly total: number | undefined;\n\n private offset = 0;\n\n private lastDone = 0;\n\n /**\n * Create a tracker.\n * @param callback - the caller's onProgress, or null\n * @param inputs - every input in reading order\n */\n constructor(callback: ((bytesDone: number, bytesTotal?: number) => void) | null, inputs: readonly ImportInput[]) {\n this.callback = callback;\n let total: number | undefined = 0;\n for (const input of inputs) {\n const length = inputLength(input);\n if (length === null) {\n total = undefined;\n break;\n }\n total += length;\n }\n this.total = total;\n }\n\n /**\n * The read options for one input.\n * @param signal - the cancellation signal\n * @returns options whose onProgress reports cumulative bytes\n */\n optionsFor(signal: AbortSignal | null): ReadOptions {\n const { callback } = this;\n if (callback === null) {\n return { signal };\n }\n return {\n signal,\n onProgress: (done: number): void => {\n this.lastDone = done;\n callback(this.offset + done, this.total);\n },\n };\n }\n\n /** Move the offset past the input just finished. */\n finishInput(): void {\n this.offset += this.lastDone;\n this.lastDone = 0;\n }\n}\n\n/**\n * The state of one import call: the sink, the report, the resolved options, the reserved column\n * handles and the per-section row handlers.\n */\nclass Neo4jImportSession {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly common: ResolvedImportOptions;\n\n private readonly options: ResolvedNeo4jOptions;\n\n private readonly coercer: IdCoercer;\n\n private readonly direction: DirectionResolver;\n\n private readonly registry = new NodeRegistry();\n\n /** The relationship property the weights were read from, when it is not \"weight\"; the exporter writes it back under that name. */\n weightProperty: string | null = null;\n\n private labelsHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private typeHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private idSpaceHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private originalIdHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private ignoredColumns = 0;\n\n /** Whether the sink's direction was set (before the first relationship, design section 8.4 rule 1). */\n private headerSet = false;\n\n /** Scratch: the parsed value of every cell of the current row. */\n private values: unknown[] = [];\n\n /** Scratch: the companion text of every cell of the current row. */\n private texts: (string | null)[] = [];\n\n /** Scratch: the property slots of the current row that lost precision. */\n private readonly precisionSlots: PropertySlot[] = [];\n\n /** Scratch: the values of the current row that overflowed their float / double type. */\n private readonly overflows: string[] = [];\n\n /** The section kind the option of the input being read names, or null for the primary input. */\n private expectedKind: Section[\"kind\"] | null = null;\n\n /** Whether any node row was read. */\n private nodeRows = false;\n\n /** Nodes relationship endpoints created (no node row declared them yet), the first few by id. */\n private readonly placeholders: { readonly id: NodeId; readonly index: number }[] = [];\n\n /**\n * Create a session.\n * @param sink - the sink\n * @param report - the report\n * @param common - the resolved common options\n * @param options - the resolved format options\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n options: ResolvedNeo4jOptions,\n ) {\n this.sink = sink;\n this.report = report;\n this.common = common;\n this.options = options;\n this.coercer = new IdCoercer(common.ids);\n this.direction = new DirectionResolver(sink, report, common.onMixedDirection);\n }\n\n /**\n * Read every input. A header-only input lends its header to the headerless input after it (the\n * neo4j-admin convention `--nodes=header.csv,part1.csv`); an empty input is an error only when\n * it is the only one.\n * @param inputs - the inputs in reading order, each with the kind of section its option names (null for the primary input)\n */\n async run(\n inputs: readonly { readonly input: ImportInput; readonly kind: Section[\"kind\"] | null }[],\n ): Promise<void> {\n const progress = new ProgressTracker(\n this.common.onProgress,\n inputs.map((i) => i.input),\n );\n let carried: Section | null = null;\n for (const { input, kind } of inputs) {\n this.expectedKind = kind;\n if (carried !== null && kind !== null && carried.kind !== kind) {\n // a nodes header never lends itself to a relationships file, nor the reverse\n carried = null;\n }\n carried = await this.readInput(\n input,\n { ...progress.optionsFor(this.common.signal), encoding: this.common.encoding },\n carried,\n inputs.length > 1,\n );\n progress.finishInput();\n }\n if (this.ignoredColumns > 0) {\n this.report.loss(\n IGNORED_COLUMNS_LOSS,\n `${this.ignoredColumns} :IGNORE column${plural(this.ignoredColumns)} ${agree(this.ignoredColumns, \"was\", \"were\")} skipped as the header instructs`,\n null,\n this.ignoredColumns,\n );\n }\n this.reportDangling();\n }\n\n /**\n * Read one input: a header row, then data rows until the next header row.\n * @param input - the input\n * @param readOptions - cancellation and progress\n * @param carried - the section of a header-only input just before this one, or null\n * @param mayBeEmpty - whether an input without any record is allowed (other inputs exist)\n * @returns this input's section when it held a header and no data row (lent to the next input), else null\n */\n private async readInput(\n input: ImportInput,\n readOptions: ReadOptions,\n carried: Section | null,\n mayBeEmpty: boolean,\n ): Promise<Section | null> {\n const reader = new RecordReader(input, this.report, this.options.syntax, {\n ...readOptions,\n allowEmpty: mayBeEmpty,\n });\n let section: Section | null = carried;\n let records = 0;\n let rows = 0;\n let sinceCheck = 0;\n for await (const count of reader) {\n const { cells, quoted } = reader;\n if (records === 0 && count === 1 && !quoted[0] && cells[0].trim().length === 0) {\n // a whitespace-only line before anything else is a blank line, not an empty header\n continue;\n }\n records++;\n // a quoted marker cell is data (\"ref:id\") unless the whole record is a quoted header\n if (section === null || isHeaderRecord(cells, count, quoted)) {\n section = this.declareSection(reader, count);\n rows = 0;\n continue;\n }\n rows++;\n if (section.kind === \"node\") {\n this.nodeRow(section, reader, count);\n } else {\n this.relationshipRow(section, reader, count);\n }\n if (++sinceCheck >= ABORT_CHECK_INTERVAL) {\n sinceCheck = 0;\n throwIfAborted(readOptions.signal);\n }\n }\n if (records === 0 && carried === null && !mayBeEmpty) {\n this.report.fail(HEADER_CODE, \"the input has no header row\", { line: 1 });\n }\n // the header lent on: a header-only input's, or the one lent to this input when it had none\n if (section === carried) {\n return carried;\n }\n return rows === 0 ? section : null;\n }\n\n /**\n * Interpret a header row: parse every cell, check the section shape, declare its columns.\n * @param reader - the reader positioned on the header\n * @param count - the number of header cells\n * @returns the section\n */\n private declareSection(reader: RecordReader, count: number): Section {\n const { line } = reader;\n const fields: HeaderField[] = [];\n try {\n for (let i = 0; i < count; i++) {\n fields.push(parseHeaderField(reader.cells[i]));\n }\n const kinds = new Map<FieldKind, number[]>();\n fields.forEach((field, i) => {\n const list = kinds.get(field.kind);\n if (list === undefined) {\n kinds.set(field.kind, [i]);\n } else {\n list.push(i);\n }\n });\n const ids = kinds.get(\"ID\") ?? [];\n const starts = kinds.get(\"START_ID\") ?? [];\n const ends = kinds.get(\"END_ID\") ?? [];\n const isNode = ids.length > 0;\n const isRelationship = starts.length > 0 || ends.length > 0;\n if (isNode && isRelationship) {\n throw headerError(\"a header mixes :ID with :START_ID / :END_ID\");\n }\n if (!isNode && !isRelationship) {\n const apoc = fields.some((f) => f.name === \"_id\" || f.name === \"_start\");\n throw headerError(\n apoc\n ? \"a header needs an :ID column (nodes) or :START_ID and :END_ID columns (relationships); this is the apoc.export.csv layout (_id, _labels, _start, _end, _type), which is not the neo4j-admin import format\"\n : \"a header needs an :ID column (nodes) or :START_ID and :END_ID columns (relationships)\",\n );\n }\n if (this.expectedKind !== null && this.expectedKind !== (isNode ? \"node\" : \"relationship\")) {\n this.report.warning(\n \"validation-error\",\n SECTION_KIND_CODE,\n `a ${isNode ? \"node\" : \"relationship\"} header in a file given as ${this.expectedKind === \"node\" ? \"nodes\" : \"relationships\"}; read by its header`,\n { line },\n );\n }\n checkPropertyNames(fields);\n this.ignoredColumns += (kinds.get(\"IGNORE\") ?? []).length;\n if (isNode) {\n if (ids.length > 1) {\n throw headerError(\"a node header has more than one :ID column\");\n }\n if (kinds.has(\"TYPE\")) {\n throw headerError(\"a node header cannot have a :TYPE column\");\n }\n return this.declareNodeSection(fields, ids[0], kinds.get(\"LABEL\") ?? [], line);\n }\n if (starts.length !== 1 || ends.length !== 1) {\n throw headerError(\"a relationship header needs exactly one :START_ID and one :END_ID column\");\n }\n if (kinds.has(\"LABEL\")) {\n throw headerError(\"a relationship header cannot have a :LABEL column\");\n }\n const types = kinds.get(\"TYPE\") ?? [];\n if (types.length > 1) {\n throw headerError(\"a relationship header has more than one :TYPE column\");\n }\n return this.declareRelationshipSection(\n fields,\n starts[0],\n ends[0],\n types.length === 1 ? types[0] : -1,\n line,\n );\n } catch (err) {\n if (err instanceof GraphFormatError && !(err instanceof ImportError)) {\n // a header written with another delimiter reads as one cell holding it\n const other = [\";\", \"|\", \"\\t\", \",\"].find(\n (d) => d !== reader.delimiter && reader.cells.slice(0, count).some((c) => c.includes(d)),\n );\n const hint =\n other === undefined\n ? \"\"\n : `; if the file is delimited by ${JSON.stringify(other)}, pass the delimiter option`;\n this.report.fail(HEADER_CODE, `${err.message}${hint}`, { line }, { cause: err.code });\n }\n throw err;\n }\n }\n\n /**\n * Declare the columns of a node section.\n * @param fields - the parsed header\n * @param idCell - the `:ID` cell\n * @param labelCells - the `:LABEL` cells\n * @param line - the header line\n * @returns the section\n */\n private declareNodeSection(\n fields: readonly HeaderField[],\n idCell: number,\n labelCells: readonly number[],\n line: number,\n ): NodeSection {\n const idField = fields[idCell];\n const extraLabels: string[] = [];\n for (const field of fields) {\n for (const [key, value] of field.options) {\n if (key === \"label\" && field.kind === \"ID\") {\n extraLabels.push(value);\n } else {\n this.report.warning(\n \"unsupported\",\n HEADER_OPTION_CODE,\n `header option ${key}:${value} of \"${field.text}\" is ignored`,\n { line, element: field.text },\n );\n }\n }\n }\n if (labelCells.length > 0 || extraLabels.length > 0) {\n this.ensureLabels();\n }\n if (idField.space !== null) {\n this.ensureIdSpace();\n }\n let idHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n if (idField.name.length > 0) {\n idHandle = this.declareProperty(\n \"node\",\n { ...idField, type: null },\n idCell,\n { origin: { format: NEO4J, id: idField.name, title: null, type: \"ID\", namespace: idField.space } },\n line,\n ).handle;\n }\n const properties = this.declareProperties(\"node\", fields, line, null);\n return {\n kind: \"node\",\n width: fields.length,\n idCell,\n idHandle,\n space: idField.space,\n spaceCode: this.registry.codeOf(idField.space),\n labelCells,\n extraLabels,\n properties,\n };\n }\n\n /**\n * Declare the columns of a relationship section.\n * @param fields - the parsed header\n * @param startCell - the `:START_ID` cell\n * @param endCell - the `:END_ID` cell\n * @param typeCell - the `:TYPE` cell, or -1\n * @param line - the header line\n * @returns the section\n */\n private declareRelationshipSection(\n fields: readonly HeaderField[],\n startCell: number,\n endCell: number,\n typeCell: number,\n line: number,\n ): RelationshipSection {\n for (const field of fields) {\n for (const [key, value] of field.options) {\n this.report.warning(\n \"unsupported\",\n HEADER_OPTION_CODE,\n `header option ${key}:${value} of \"${field.text}\" is ignored`,\n { line, element: field.text },\n );\n }\n }\n if (typeCell >= 0) {\n this.ensureType();\n }\n const { weightFrom } = this.common;\n let weightCell = -1;\n if (weightFrom !== null) {\n weightCell = fields.findIndex((field) => field.kind === \"PROPERTY\" && field.name === weightFrom);\n if (weightCell >= 0 && weightFrom !== \"weight\") {\n this.weightProperty = weightFrom;\n }\n }\n const properties = this.declareProperties(\"edge\", fields, line, weightCell);\n const { space: startSpace } = fields[startCell];\n const { space: endSpace } = fields[endCell];\n return {\n kind: \"relationship\",\n width: fields.length,\n startCell,\n endCell,\n startSpace,\n endSpace,\n startSpaceCode: startSpace === null ? 0 : this.registry.codeOf(startSpace),\n endSpaceCode: endSpace === null ? 0 : this.registry.codeOf(endSpace),\n typeCell,\n weightCell,\n properties,\n };\n }\n\n /**\n * Declare every PROPERTY field of a header.\n * @param domain - node or edge\n * @param fields - the parsed header\n * @param line - the header line\n * @param skipCell - a cell to leave undeclared (the weight), or null\n * @returns the property slots\n */\n private declareProperties(\n domain: \"node\" | \"edge\",\n fields: readonly HeaderField[],\n line: number,\n skipCell: number | null,\n ): PropertySlot[] {\n const slots: PropertySlot[] = [];\n fields.forEach((field, cell) => {\n if (field.kind !== \"PROPERTY\" || cell === skipCell) {\n return;\n }\n slots.push(this.declareProperty(domain, field, cell, {}, line));\n });\n const width = fields.length;\n if (this.values.length < width) {\n this.values = new Array<unknown>(width);\n this.texts = new Array<string | null>(width);\n }\n return slots;\n }\n\n /**\n * Declare one property column on the sink: the same name and shape again shares the column;\n * a different shape under the same name is renamed `<name>#<name>` (design section 5.6).\n * @param domain - node or edge\n * @param field - the header field\n * @param cell - the field's cell index\n * @param patch - declaration fields to override (the id property's origin)\n * @param line - the header line\n * @returns the slot\n */\n private declareProperty(\n domain: \"node\" | \"edge\",\n field: HeaderField,\n cell: number,\n patch: Partial<ColumnDecl>,\n line: number,\n ): PropertySlot {\n const { sink, report } = this;\n const { listSyntax } = this.options;\n const input: AttributeDeclarationInput = {\n format: NEO4J,\n id: field.name,\n title: null,\n type: field.type,\n namespace: null,\n listSyntax,\n long: this.common.long,\n };\n let declared: DeclaredAttribute = declareAttribute(input);\n let decl: ColumnDecl = { ...declared.decl, ...patch };\n let handle: ColumnHandle;\n try {\n handle = declareOn(sink, domain, decl);\n } catch (err) {\n if (!(err instanceof GraphFormatError) || err.code !== \"E_COLUMN_EXISTS\") {\n throw err;\n }\n declared = declareAttribute({ ...input, taken: takenIn(sink, domain) });\n decl = { ...declared.decl, ...patch, name: declared.decl.name };\n handle = declareOn(sink, domain, decl);\n }\n for (const issue of declared.issues) {\n report.warning(issue.category, issue.code, issue.message, { line, element: field.text });\n }\n return {\n cell,\n name: decl.name,\n handle,\n spec: declared.spec,\n companionDecl: declared.companion,\n companion: INVALID_INDEX as ColumnHandle,\n };\n }\n\n /** Declare (or adopt) the labels column. */\n private ensureLabels(): void {\n if (this.labelsHandle === INVALID_INDEX) {\n this.labelsHandle = this.declareReserved(\"node\", LABELS_DECL);\n }\n }\n\n /** Declare (or adopt) the relationship type column. */\n private ensureType(): void {\n if (this.typeHandle === INVALID_INDEX) {\n this.typeHandle = this.declareReserved(\"edge\", TYPE_DECL);\n }\n }\n\n /** Declare (or adopt) the id space column. */\n private ensureIdSpace(): void {\n if (this.idSpaceHandle === INVALID_INDEX) {\n this.idSpaceHandle = this.declareReserved(\"node\", ID_SPACE_DECL);\n this.originalIdHandle = this.declareReserved(\"node\", ORIGINAL_ID_DECL);\n }\n }\n\n /**\n * Declare a reserved column: the same shape again shares it; a name taken by another shape is\n * renamed `<name>#<origin.id>` and reported; a role the sink already holds elsewhere is dropped\n * and reported.\n * @param domain - node or edge\n * @param decl - the reserved declaration\n * @returns the handle\n */\n private declareReserved(domain: \"node\" | \"edge\", decl: ColumnDecl): ColumnHandle {\n const { sink, report } = this;\n let current = decl;\n for (;;) {\n try {\n return declareOn(sink, domain, current);\n } catch (err) {\n if (!(err instanceof GraphFormatError)) {\n throw err;\n }\n if (err.code === \"E_COLUMN_EXISTS\") {\n const name = uniqueColumnName(current.name, current.origin?.id ?? null, takenIn(sink, domain));\n report.warning(\n \"coercion\",\n RENAMED_CODE,\n `column \"${current.name}\" renamed to \"${name}\": the name was taken`,\n { element: current.name },\n );\n current = { ...current, name };\n } else if (err.code === \"E_DUPLICATE_ROLE\") {\n report.warning(\n \"coercion\",\n ROLE_TAKEN_CODE,\n `column \"${current.name}\" declared without role \"${String(current.role)}\": the sink already holds that role`,\n { element: current.name },\n );\n const { role: _role, ...withoutRole } = current;\n current = withoutRole;\n } else {\n throw err;\n }\n }\n }\n }\n\n /**\n * Push one node row.\n * @param section - the section\n * @param reader - the reader positioned on the row\n * @param count - the row's cell count\n */\n private nodeRow(section: NodeSection, reader: RecordReader, count: number): void {\n const { sink, report } = this;\n const { cells, quoted, line } = reader;\n if (count !== section.width) {\n report.error(\n \"validation-error\",\n COLUMN_COUNT_CODE,\n `row has ${count} cell${plural(count)} but the header has ${section.width}`,\n { line },\n );\n report.counts.skippedNodes++;\n return;\n }\n const idText = cells[section.idCell];\n if (idText.length === 0 && !quoted[section.idCell]) {\n // a quoted empty cell is the id \"\" (neo4j-admin: an empty quoted field is an empty string)\n report.error(\"missing-value\", MISSING_ID_CODE, \"empty :ID cell\", { line });\n report.counts.skippedNodes++;\n return;\n }\n const coerced = this.coerceId(idText, line);\n if (coerced === null || !this.parseProperties(section.properties, cells, quoted, line, idText)) {\n report.counts.skippedNodes++;\n return;\n }\n const id = qualify(coerced, section.space);\n let labels: string[] | undefined;\n if (section.labelCells.length > 0 || section.extraLabels.length > 0) {\n labels = this.labelsOf(section, cells, quoted);\n }\n this.nodeRows = true;\n const existed = sink.indexOf(id) !== INVALID_INDEX;\n let index: number;\n try {\n index = sink.addNode(id);\n } catch (err) {\n report.recordError(err, { line, element: idText });\n report.counts.skippedNodes++;\n return;\n }\n const status = this.registry.declare(index, section.spaceCode);\n if (status === \"collision\") {\n report.error(\n \"validation-error\",\n ID_SPACE_COLLISION_CODE,\n `node ${idText} is declared in id space ${section.space ?? \"(none)\"} and in another id space; the core has one id space and this row is skipped`,\n { line, element: idText },\n );\n report.counts.skippedNodes++;\n return;\n }\n if (status === \"duplicate\") {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `node ${idText} is declared twice; the later properties win`,\n {\n line,\n element: idText,\n },\n );\n }\n // a write the sink refuses is recorded and the rest of the row is still written\n const set = (column: ColumnHandle, value: unknown): void => {\n this.guarded(line, idText, () => {\n sink.setNodeValue(column, index, value);\n });\n };\n if (section.idHandle !== INVALID_INDEX) {\n set(section.idHandle, idText);\n }\n if (section.space !== null) {\n set(this.idSpaceHandle, section.space);\n set(this.originalIdHandle, idText);\n }\n if (labels !== undefined) {\n set(this.labelsHandle, labels);\n }\n this.writeProperties(\"node\", section.properties, index, line, idText);\n this.reportPrecision(line, idText);\n // a node a relationship created before its row (or an earlier row) is counted once\n if (!existed) {\n report.counts.nodes++;\n }\n }\n\n /**\n * Run one sink write, recording a refusal (a GraphFormatError) on the row's line instead of\n * letting it escape the import.\n * @param line - the row's line\n * @param element - the row's element name\n * @param write - the write\n */\n private guarded(line: number, element: string, write: () => void): void {\n try {\n write();\n } catch (err) {\n if (!(err instanceof GraphFormatError) || err instanceof ImportError) {\n throw err;\n }\n this.report.recordError(err, { line, element });\n }\n }\n\n /**\n * Report the relationship endpoints no node row declared (the shared W_DANGLING_REFERENCE,\n * once) when the input has node rows: each became a node, where neo4j-admin refuses the\n * relationship.\n */\n private reportDangling(): void {\n const dangling = this.placeholders.filter((p) => this.registry.codeAt(p.index) === 0);\n // without any node row, every node comes from the relationships (a relationships-only file)\n if (dangling.length === 0 || !this.nodeRows) {\n return;\n }\n const shown = dangling\n .slice(0, 5)\n .map((p) => String(p.id))\n .join(\", \");\n this.report.warning(\n \"validation-error\",\n DANGLING_REFERENCE_CODE,\n `${dangling.length} relationship endpoint${plural(dangling.length)} ${agree(dangling.length, \"names\", \"name\")} no node row and became nodes: ${shown}${dangling.length > 5 ? \", ...\" : \"\"} (neo4j-admin refuses such relationships)`,\n { element: String(dangling[0].id) },\n );\n }\n\n /**\n * Push one relationship row.\n * @param section - the section\n * @param reader - the reader positioned on the row\n * @param count - the row's cell count\n */\n private relationshipRow(section: RelationshipSection, reader: RecordReader, count: number): void {\n const { sink, report } = this;\n const { cells, quoted, line } = reader;\n if (!this.headerSet) {\n // a Neo4j file is directed by definition (\"all relationships have a direction\"); the sink's\n // direction is set once, before the first relationship, so a node-only file leaves it alone\n this.headerSet = true;\n this.direction.setHeader(true, { line });\n }\n if (count !== section.width) {\n report.error(\n \"validation-error\",\n COLUMN_COUNT_CODE,\n `row has ${count} cell${plural(count)} but the header has ${section.width}`,\n { line },\n );\n report.counts.skippedEdges++;\n return;\n }\n const startText = cells[section.startCell];\n const endText = cells[section.endCell];\n const startMissing = startText.length === 0 && !quoted[section.startCell];\n if (startMissing || (endText.length === 0 && !quoted[section.endCell])) {\n report.error(\n \"missing-value\",\n MISSING_ENDPOINT_CODE,\n `empty ${startMissing ? \":START_ID\" : \":END_ID\"} cell`,\n {\n line,\n },\n );\n report.counts.skippedEdges++;\n return;\n }\n const element = `${startText}->${endText}`;\n const start = this.coerceId(startText, line);\n const end = start === null ? null : this.coerceId(endText, line);\n if (start === null || end === null) {\n report.counts.skippedEdges++;\n return;\n }\n const source = qualify(start, section.startSpace);\n const target = qualify(end, section.endSpace);\n let wrongSpace: string | null = null;\n if (this.wrongSpace(source, section.startSpaceCode)) {\n wrongSpace = startText;\n } else if (this.wrongSpace(target, section.endSpaceCode)) {\n wrongSpace = endText;\n }\n if (wrongSpace !== null) {\n report.error(\n \"missing-value\",\n ENDPOINT_SPACE_CODE,\n `endpoint ${wrongSpace} is not a node of its declared id space (a node of another id space has that id); the row is skipped`,\n { line, element },\n );\n report.counts.skippedEdges++;\n return;\n }\n let weight: number | undefined;\n if (section.weightCell >= 0) {\n try {\n weight = parseWeightText(cells[section.weightCell], this.report);\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n return;\n }\n }\n if (!this.parseProperties(section.properties, cells, quoted, line, element)) {\n report.counts.skippedEdges++;\n return;\n }\n const created = [source, target].filter(\n (id, k) => (k === 0 || id !== source) && sink.indexOf(id) === INVALID_INDEX,\n );\n let edge: number;\n try {\n edge = this.direction.addEdge(source, target, \"directed\", weight, { line, element });\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n return;\n }\n for (const id of created) {\n // a node no row declared yet: counted now; reported at the end unless a node row follows\n report.counts.nodes++;\n this.placeholders.push({ id, index: sink.indexOf(id) });\n }\n if (section.typeCell >= 0) {\n const type = cells[section.typeCell];\n if (type.length > 0) {\n this.guarded(line, element, () => {\n sink.setEdgeValue(this.typeHandle, edge, type);\n });\n } else {\n report.warning(\n \"missing-value\",\n MISSING_TYPE_CODE,\n \"empty :TYPE cell; neo4j-admin requires a relationship type, the relationship is kept without one\",\n { line, element },\n );\n }\n }\n this.writeProperties(\"edge\", section.properties, edge, line, element);\n this.reportPrecision(line, element);\n report.counts.edges++;\n }\n\n /**\n * Whether a qualified endpoint id belongs to a node a node row declared in another id space than\n * the endpoint's header declares (an unspaced node whose id text is `Space:id`). An endpoint\n * without a declared space, or a node no row declared yet, is looked up by id alone.\n * @param id - the endpoint id\n * @param spaceCode - the endpoint's space code, 0 for none\n * @returns true when the endpoint resolves to a node of another space\n */\n private wrongSpace(id: NodeId, spaceCode: number): boolean {\n if (spaceCode === 0) {\n return false;\n }\n const index = this.sink.indexOf(id);\n if (index < 0) {\n return false;\n }\n const declared = this.registry.codeAt(index);\n return declared !== 0 && declared !== spaceCode;\n }\n\n /**\n * Coerce an id cell, reporting a merge under `ids: \"number\"` and an invalid id as an error.\n * @param text - the cell\n * @param line - the row's line\n * @returns the id, or null when the cell was rejected (the error is recorded)\n */\n private coerceId(text: string, line: number): NodeId | null {\n const { coercer, report } = this;\n let id: NodeId;\n try {\n id = coercer.text(text);\n } catch (err) {\n report.recordError(err, { line, element: text });\n return null;\n }\n const merge = coercer.lastMerge;\n if (merge !== null) {\n report.warning(\n \"coercion\",\n ID_MERGED_CODE,\n `id \"${merge.text}\" merged with \"${merge.previousText}\" as ${merge.id} under ids: \"number\"`,\n { line, element: text },\n );\n }\n return id;\n }\n\n /**\n * Parse the property cells of a row into the scratch arrays.\n * @param slots - the section's property slots\n * @param cells - the row's cells\n * @param quoted - whether each cell was quoted\n * @param line - the row's line\n * @param element - the row's element name for issues\n * @returns true when every cell parsed; false after recording the first error\n */\n private parseProperties(\n slots: readonly PropertySlot[],\n cells: readonly string[],\n quoted: readonly boolean[],\n line: number,\n element: string,\n ): boolean {\n const { values, texts, precisionSlots } = this;\n precisionSlots.length = 0;\n this.overflows.length = 0;\n for (const slot of slots) {\n const text = cells[slot.cell];\n texts[slot.cell] = null;\n if (text.length === 0) {\n values[slot.cell] = quoted[slot.cell] ? emptyValue(slot.spec) : undefined;\n continue;\n }\n const { spec } = slot;\n try {\n this.parseCell(slot, text);\n } catch (err) {\n this.report.recordError(err, { line, element: `${element} ${slot.name}` });\n return false;\n }\n if (overflows(spec, values[slot.cell], text)) {\n this.overflows.push(slot.name);\n }\n if (spec.precision && losesPrecision(spec, text)) {\n precisionSlots.push(slot);\n }\n }\n return true;\n }\n\n /**\n * Parse one non-empty property cell into the scratch arrays; throws on a malformed value.\n * @param slot - the cell's property slot\n * @param text - the cell text\n */\n private parseCell(slot: PropertySlot, text: string): void {\n const { values, texts } = this;\n const { spec } = slot;\n if (spec.temporal !== null && !spec.list) {\n const zoned = withZoneOffset(text, spec);\n const parsed = parseDeclaredTemporal(zoned, spec);\n values[slot.cell] = parsed.value;\n // a zone name is kept in the companion text, the value is its instant\n texts[slot.cell] = zoned === text ? parsed.text : text;\n } else {\n values[slot.cell] = parseDeclaredValue(text, spec, this.options.listSyntax);\n checkNeo4jRange(spec, values[slot.cell], text);\n }\n }\n\n /**\n * Write the parsed property values of a row.\n * @param domain - node or edge\n * @param slots - the section's property slots\n * @param row - the node or edge index\n * @param line - the row's line\n * @param element - the row's element name for issues\n */\n private writeProperties(\n domain: \"node\" | \"edge\",\n slots: readonly PropertySlot[],\n row: number,\n line: number,\n element: string,\n ): void {\n const { sink, values, texts } = this;\n for (const slot of slots) {\n const value = values[slot.cell];\n if (value === undefined) {\n continue;\n }\n const text = texts[slot.cell];\n // a value the sink refuses is recorded on the row's line; the other properties are written\n this.guarded(line, `${element} ${slot.name}`, () => {\n if (text !== null && slot.companion === INVALID_INDEX && slot.companionDecl !== null) {\n slot.companion = declareCompanion(sink, domain, slot.companionDecl);\n }\n if (domain === \"node\") {\n sink.setNodeValue(slot.handle, row, value);\n if (text !== null) {\n sink.setNodeValue(slot.companion, row, text);\n }\n } else {\n sink.setEdgeValue(slot.handle, row, value);\n if (text !== null) {\n sink.setEdgeValue(slot.companion, row, text);\n }\n }\n });\n }\n }\n\n /**\n * Report the precision losses of the row just accepted.\n * @param line - the row's line\n * @param element - the row's element name\n */\n private reportPrecision(line: number, element: string): void {\n for (const slot of this.precisionSlots) {\n this.report.warning(\n \"precision\",\n PRECISION_CODE,\n `long value of \"${slot.name}\" is beyond 2^53 and was stored as the nearest f64`,\n { line, element },\n );\n }\n this.precisionSlots.length = 0;\n for (const name of this.overflows) {\n this.report.warning(\n \"precision\",\n PRECISION_CODE,\n `the value of \"${name}\" is beyond the range of its float / double type and was stored as the nearest representable value`,\n { line, element },\n );\n }\n this.overflows.length = 0;\n }\n\n /**\n * The labels of a node row: every `:LABEL` cell split by the array delimiter (empty items\n * dropped), plus the header's `{label:...}` options.\n * @param section - the section\n * @param cells - the row's cells\n * @param quoted - whether each cell was quoted\n * @returns the labels, or undefined when every label cell is unset and no extra label exists\n */\n private labelsOf(section: NodeSection, cells: readonly string[], quoted: readonly boolean[]): string[] | undefined {\n let labels: string[] | undefined;\n for (const cell of section.labelCells) {\n const text = cells[cell];\n if (text.length === 0 && !quoted[cell]) {\n continue;\n }\n if (labels === undefined) {\n labels = [];\n }\n for (const item of splitListText(text, this.options.listSyntax)) {\n if (item.length > 0) {\n labels.push(item);\n }\n }\n }\n if (section.extraLabels.length > 0) {\n if (labels === undefined) {\n labels = [];\n }\n labels.push(...section.extraLabels);\n }\n return labels;\n }\n}\n\n/**\n * The id a node of an id space is stored under: `Space:id`, so the same id in two spaces stays two\n * nodes (the core has one id space).\n * @param id - the coerced id cell\n * @param space - the id space, or null\n * @returns the id unchanged without a space, else the string `Space:id`\n */\nfunction qualify(id: NodeId, space: string | null): NodeId {\n return space === null ? id : `${space}:${String(id)}`;\n}\n\n/** The integer range of the narrow neo4j-admin types (Java byte and short). */\nconst INTEGER_RANGES: Readonly<Record<string, readonly [number, number]>> = {\n byte: [-128, 127],\n short: [-32768, 32767],\n};\n\n/**\n * A Cypher duration (ISO 8601): unit form `P14DT16H12M` / `PT0.75M` / `P2.5W` (components may be\n * signed or fractional) or the date-time form `P2012-02-02T14:37:21.545`.\n */\n/**\n * Whether a text is a Cypher duration (ISO 8601): unit form `P14DT16H12M` / `PT0.75M` / `P2.5W`\n * (components may be signed or fractional) or the date-time form `P2012-02-02T14:37:21.545`.\n * @param text - the text, trimmed\n * @returns true when it is\n */\nfunction isDuration(text: string): boolean {\n if (DURATION_DATE_TIME.test(text)) {\n return true;\n }\n const m = /^[+-]?P([^T]*)(?:T(.*))?$/i.exec(text);\n if (m === null || m[2] === \"\" || (m[1] === \"\" && m[2] === undefined)) {\n return false;\n }\n return unitsInOrder(m[1], \"YMWD\") && unitsInOrder(m[2] ?? \"\", \"HMS\");\n}\n\n/** The date-time form of a Cypher duration, `P2012-02-02T14:37:21.545`. */\nconst DURATION_DATE_TIME = /^[+-]?P\\d{4}-?\\d{2}-?\\d{2}T\\d{2}:?\\d{2}:?\\d{2}(?:\\.\\d+)?$/i;\n\n/**\n * Whether a run of duration components (`14D`, `-1.5H30M`) names its units in the order given,\n * each at most once.\n * @param text - the components\n * @param units - the unit letters in their order\n * @returns true when it does\n */\nfunction unitsInOrder(text: string, units: string): boolean {\n let rest = text.toUpperCase();\n let from = 0;\n while (rest !== \"\") {\n const m = /^[-+]?\\d+(?:\\.\\d+)?([A-Z])/.exec(rest);\n const at = m === null ? -1 : units.indexOf(m[1], from);\n if (m === null || at < 0) {\n return false;\n }\n from = at + 1;\n rest = rest.slice(m[0].length);\n }\n return true;\n}\n\n/**\n * Check the neo4j-admin types the shared parser maps to a wider dtype: byte and short values within\n * their Java range, a char of one character, a duration in Cypher's syntax.\n * @param spec - the declared type\n * @param value - the parsed value (a list of items for an array type)\n * @param text - the cell text, for the error\n */\nfunction checkNeo4jRange(spec: DeclaredTypeSpec, value: unknown, text: string): void {\n const base = spec.declared.trim().toLowerCase().replace(/\\[\\]$/, \"\");\n const items: unknown[] = spec.list && Array.isArray(value) ? value : [value];\n const range = INTEGER_RANGES[base];\n for (const item of items) {\n let bad = false;\n if (range !== undefined) {\n bad = typeof item === \"number\" && (item < range[0] || item > range[1]);\n } else if (base === \"char\") {\n // a Java char: one UTF-16 code unit\n bad = typeof item === \"string\" && item.length !== 1;\n } else if (base === \"duration\") {\n bad = typeof item === \"string\" && !isDuration(item.trim());\n }\n if (bad) {\n const span = range === undefined ? \"\" : ` (${range[0]} to ${range[1]})`;\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `\"${text}\" is not ${withArticle(base)}${span}`, {\n value: text,\n kind: base,\n });\n }\n }\n}\n\n/** The largest finite f32. */\nconst F32_MAX = 3.4028234663852886e38;\n\n/**\n * Whether a float / double cell overflowed: a finite literal read as an infinity, or a float beyond\n * the f32 range (Java's Double.parseDouble accepts both silently; the value changes).\n * @param spec - the declared type\n * @param value - the parsed value\n * @param text - the cell text\n * @returns true when the stored value is not the one written\n */\nfunction overflows(spec: DeclaredTypeSpec, value: unknown, text: string): boolean {\n if ((spec.kind !== \"float\" && spec.kind !== \"double\") || /inf|nan/i.test(text)) {\n return false;\n }\n const items: unknown[] = spec.list && Array.isArray(value) ? value : [value];\n return items.some(\n (v) => typeof v === \"number\" && (!Number.isFinite(v) || (spec.kind === \"float\" && Math.abs(v) > F32_MAX)),\n );\n}\n\n/**\n * A Cypher date-time with a zone name (`2020-01-01T00:00:00[Europe/Berlin]`) as one with a UTC\n * offset the temporal parser reads: the offset the text gives, else the zone's offset at that wall\n * time. Any other text is returned unchanged.\n * @param text - the cell text\n * @param spec - the declared type\n * @returns the text to parse\n */\nfunction withZoneOffset(text: string, spec: DeclaredTypeSpec): string {\n const trimmed = text.trim();\n const open = trimmed.lastIndexOf(\"[\");\n if (spec.temporal !== \"dateTime\" || open < 0 || !trimmed.endsWith(\"]\")) {\n return text;\n }\n const local = trimmed.slice(0, open);\n const zone = trimmed.slice(open + 1, -1);\n if (zone === \"\" || zone.includes(\"]\") || /[\\n\\r\\u2028\\u2029]/.test(local)) {\n return text;\n }\n let format: Intl.DateTimeFormat;\n try {\n format = new Intl.DateTimeFormat(\"en-US\", { timeZone: zone, timeZoneName: \"longOffset\" });\n } catch {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `\"${text}\" names an unknown time zone ${zone}`, { value: text });\n }\n if (/(Z|z|[+-]\\d{2}(:?\\d{2})?)$/.test(local)) {\n return local;\n }\n const wall = parseTemporal(local, \"localDateTime\").value;\n const offsetAt = (ms: number): number => {\n const name = format.formatToParts(new Date(ms)).find((p) => p.type === \"timeZoneName\")?.value ?? \"GMT\";\n const o = /GMT([+-])(\\d{2}):(\\d{2})/.exec(name);\n if (o === null) {\n return 0;\n }\n return (o[1] === \"-\" ? -1 : 1) * (Number(o[2]) * 60 + Number(o[3]));\n };\n // the offset at the instant the wall time names (twice, so a wall time near a transition settles)\n const minutes = offsetAt(wall - offsetAt(wall) * 60_000);\n const sign = minutes < 0 ? \"-\" : \"+\";\n const abs = Math.abs(minutes);\n return `${local}${sign}${String(Math.floor(abs / 60)).padStart(2, \"0\")}:${String(abs % 60).padStart(2, \"0\")}`;\n}\n\n/**\n * The value of a quoted empty cell: an empty string for a string-kind property, an empty list for\n * a list property, unset for anything else (neo4j-admin's default `--ignore-empty-strings=false`).\n * @param spec - the property's declared type\n * @returns the value, or undefined for unset\n */\nfunction emptyValue(spec: DeclaredTypeSpec): unknown {\n if (spec.list) {\n return [];\n }\n if (spec.kind === \"string\" || spec.kind === \"duration\") {\n return \"\";\n }\n return undefined;\n}\n\n/**\n * Check that no two PROPERTY (or stored-id) fields of one header share a name.\n * @param fields - the parsed header\n */\nfunction checkPropertyNames(fields: readonly HeaderField[]): void {\n const seen = new Set<string>();\n for (const field of fields) {\n if (field.name.length === 0 || field.kind === \"IGNORE\") {\n continue;\n }\n if (seen.has(field.name)) {\n throw headerError(`property \"${field.name}\" is declared twice`);\n }\n seen.add(field.name);\n }\n}\n\n/**\n * The error of a malformed section header.\n * @param reason - why\n * @returns the error\n */\nfunction headerError(reason: string): GraphFormatError {\n return new GraphFormatError(\"E_UNSUPPORTED\", reason, { reason: \"header\" });\n}\n\n/**\n * Confidence that a head of bytes is a neo4j-admin CSV: the first line holds an `:ID`,\n * `:START_ID` or `:END_ID` header cell.\n * @param head - the first bytes of the input\n * @returns 0.95 for a Neo4j header, 0 otherwise\n */\nfunction sniffNeo4j(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\", { fatal: false, ignoreBOM: false }).decode(head);\n const end = text.search(/[\\r\\n]/);\n const first = end < 0 ? text : text.slice(0, end);\n const cells = first.split(/[,;|\\t]/);\n return isHeaderRecord(cells, cells.length) ? 0.95 : 0;\n}\n\n/**\n * The Neo4j importer.\n * @category Built-in formats\n */\nexport const neo4jImporter: GraphImporter<Neo4jImportOptions> = Object.freeze({\n format: NEO4J,\n options: Object.freeze([\"arrayDelimiter\", \"delimiter\", \"nodes\", \"quote\", \"relationships\"]),\n extensions: Object.freeze([\".csv\", \".tsv\"]),\n mimeTypes: Object.freeze([\"text/csv\", \"text/tab-separated-values\"]),\n sniff: sniffNeo4j,\n /**\n * Read one or more neo4j-admin CSV inputs into the sink.\n * @param input - the primary input (a node table, a relationship table, or sections of both)\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report; ImportError beyond the error limit or on a malformed header\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: Neo4jImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const common = resolveImportOptions(options, { ids: \"canonical\", defaultDirected: true, weightFrom: \"weight\" });\n const format = resolveNeo4jOptions(options);\n const report = new ImportReportBuilder(NEO4J, common.errorLimit);\n reportSinkOptions(sink, options, report);\n // nodeIdFrom and defaultDirected are among the reported options: Neo4j ids are the :ID\n // column and every relationship is directed\n reportUnusedOptions(options, report, USED_OPTIONS);\n const session = new Neo4jImportSession(sink, report, common, format);\n await session.run([\n { input, kind: null },\n ...format.nodes.map((file) => ({ input: file, kind: \"node\" as const })),\n ...format.relationships.map((file) => ({ input: file, kind: \"relationship\" as const })),\n ]);\n if (session.weightProperty !== null) {\n sink.setMeta({ extra: { neo4j: { weightProperty: session.weightProperty } } });\n }\n throwIfAborted(common.signal);\n return report.finish();\n },\n});\n","/**\n * The Neo4j exporter (design section 8.5, research note 07 section 9): writes a snapshot as\n * neo4j-admin import CSV -- node sections with `:ID`, `:LABEL` and typed property columns,\n * relationship sections with `:START_ID`, `:END_ID`, `:TYPE`, the weight and typed property\n * columns -- as one document (node sections first) or as the node or relationship part alone.\n *\n * What a property graph cannot carry is reported by check() before anything is written: an\n * undirected snapshot (every edge becomes a directed relationship), expanded mixed direction (per\n * `onMixedDirection`), edge ids, hierarchy, element lifetimes, graph attributes, nested json (points\n * excepted), multi-component columns (flattened to arrays), u32 / u8 columns (written as `long` /\n * `int`), ids whose text would re-import as another type or collide, and list items that contain\n * the array delimiter.\n *\n * Column headers restore the declared Neo4j type from `origin.type` when it is compatible with the\n * column's dtype (`int`, `byte`, `short`, `long`, `char`, `duration`, the temporal types, `point`,\n * `type[]`), and derive it from the dtype otherwise. Temporal columns write their `.text`\n * companion when set and the canonical ISO form otherwise. Nodes are grouped into sections by\n * (id space, stored-id column) in index order, so a re-import restores the same node order;\n * relationships likewise by (start space, end space). A node of an id space is written under its\n * `originalId` value (the id text the importer stored it under as `Space:id`), so a round trip\n * reproduces the source file.\n */\n\nimport {\n type Column,\n type ColumnMeta,\n type Dtype,\n GraphFormatError,\n type GraphSnapshot,\n type NodeId,\n type ScalarDtype,\n} from \"@graphty/graph-format\";\n\nimport { ID_TEXT_COLLISION_CODE, ID_TEXT_TYPE_CODE } from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec, mapDeclaredType } from \"../../common/declared-types.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { quoteCsvCell } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, LOSS } from \"../../common/export.js\";\nimport { formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { isCanonicalIntegerText } from \"../../common/ids.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { formatTemporal, type TemporalKind } from \"../../common/temporal.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport { checkRecordSyntax, type RecordSyntax } from \"../csv/records.js\";\nimport { formatHeaderField } from \"./header.js\";\nimport { ID_SPACE_COLUMN, LABELS_COLUMN, TYPE_COLUMN } from \"./importer.js\";\n\n/**\n * The format-specific options of the Neo4j exporter.\n * @category Built-in formats\n */\nexport interface Neo4jExportOptions extends CommonExportOptions {\n /**\n * Which tables to write: \"all\" (the node sections, then the relationship sections), \"nodes\" or\n * \"relationships\".\n * @defaultValue \"all\"\n */\n part?: \"all\" | \"nodes\" | \"relationships\" | undefined;\n /**\n * The field delimiter, one character. It must differ from `arrayDelimiter`: with\n * `delimiter: \";\"`, also pass `arrayDelimiter: \",\"` or `\"|\"`.\n * @defaultValue \",\"\n */\n delimiter?: string | undefined;\n /**\n * The delimiter inside list values and `:LABEL` cells. It must differ from `delimiter`.\n * @defaultValue \";\"\n */\n arrayDelimiter?: \";\" | \",\" | \"|\" | undefined;\n /**\n * The quote character, one character. Cells that hold the delimiter, the quote character or a\n * line break are quoted with it. Pass the same value as the `quote` import option to read the\n * file back.\n * @defaultValue '\"'\n */\n quote?: string | undefined;\n /**\n * The relationship property that holds the edge weights, written as `<name>:double`; null\n * writes no weights (checkExport() then returns W_WEIGHTS_DROPPED). graph-io reads the\n * \"weight\" property back as the weight; for any other name, pass the same name as the\n * `weightFrom` import option to read the weights back (`weightColumn: \"strength\"` with\n * `weightFrom: \"strength\"`), or they come back as a plain edge attribute. A graph read from Neo4j\n * CSV with `weightFrom` writes its weights back under the property they were read from.\n * @defaultValue \"weight\", or the property a Neo4j import read the weights from\n */\n weightColumn?: string | null | undefined;\n /**\n * The property name of the `:ID` column (`<name>:ID`) for nodes that have no id property of\n * their own; null writes a bare `:ID`.\n * @defaultValue null\n */\n idColumn?: string | null | undefined;\n}\n\n/**\n * Neo4j relationships are always directed, so the edges of an undirected graph, and the undirected edges of a mixed\n * graph, read back as directed.\n * @category Built-in formats\n */\nexport const UNDIRECTED_LOSS = \"W_NEO4J_UNDIRECTED_AS_DIRECTED\";\n\n/**\n * Node ids that read back as a different type, such as the text \"7\" as the number 7.\n * @category Built-in formats\n */\nexport const ID_TEXT_TYPE_LOSS = ID_TEXT_TYPE_CODE;\n\n/**\n * Two node ids share one text; export() throws E_INVALID_ID.\n * @category Built-in formats\n */\nexport const ID_TEXT_COLLISION_LOSS = ID_TEXT_COLLISION_CODE;\n\n/**\n * The `weightColumn` name is already an edge attribute; the save fails.\n * @category Built-in formats\n */\nexport const WEIGHT_COLUMN_TAKEN_LOSS = \"E_NEO4J_WEIGHT_COLUMN_TAKEN\";\n\n/**\n * The `idColumn` name is already a node attribute; the save fails.\n * @category Built-in formats\n */\nexport const ID_COLUMN_TAKEN_LOSS = \"E_NEO4J_ID_COLUMN_TAKEN\";\n\n/**\n * A node has more than one stored-id column set; only the first is written.\n * @category Built-in formats\n */\nexport const MULTIPLE_ID_PROPERTIES_LOSS = \"W_NEO4J_MULTIPLE_ID_PROPERTIES\";\n\n/**\n * A declared integer type holds non-integral values and is written as double.\n * @category Built-in formats\n */\nexport const DECLARED_TYPE_CHANGED_LOSS = \"W_NEO4J_DECLARED_TYPE_CHANGED\";\n\n/**\n * A list item contains the array delimiter, which Neo4j cannot escape.\n * @category Built-in formats\n */\nexport const ARRAY_DELIMITER_LOSS = \"W_NEO4J_ARRAY_DELIMITER\";\n\n/** The roles Neo4j has a slot for: `:TYPE`, `:LABEL` and the id space of `:ID(Space)`. */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"kind\", \"labels\", \"idSpace\"]);\n\nconst NEO4J = \"neo4j\";\nconst ID_TYPE = \"ID\";\n\n/** The weight property the importer reads by default (its weightFrom default). */\nconst DEFAULT_WEIGHT_COLUMN = \"weight\";\n\n/** The names the importer gives the slot columns, for the name-change notes. */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n kind: TYPE_COLUMN,\n labels: LABELS_COLUMN,\n idSpace: ID_SPACE_COLUMN,\n});\n\n/**\n * The capabilities of neo4j-admin CSV: declared scalar types and\n * arrays; a dict column reads back as string (the header has no enumeration type); a position or\n * visual column is written as a plain property (a point for a 2- or 3-component position) and\n * reads back without its role.\n * @category Built-in formats\n */\nexport const NEO4J_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"none\",\n idCharset: \"any\",\n dtypes: [\"f32\", \"f64\", \"i32\", \"bool\", \"string\"],\n components: false,\n lists: true,\n json: false,\n defaults: false,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: false,\n positions: false,\n viz: false,\n});\n\n/** Roles whose columns are never written as properties. */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\n/** Notes about relationships only, dropped when only nodes are written. */\nconst EDGE_NOTE_CODES: ReadonlySet<string> = new Set([\n LOSS.MIXED_DIRECTION,\n LOSS.MIXED_DIRECTION_ERROR,\n LOSS.MULTI_EDGES,\n LOSS.SELF_LOOPS,\n LOSS.EDGE_IDS_GENERATED,\n LOSS.EDGE_IDS_DROPPED,\n UNDIRECTED_LOSS,\n WEIGHT_COLUMN_TAKEN_LOSS,\n]);\n\n/** Notes about nodes only, dropped when only relationships are written. */\nconst NODE_NOTE_CODES: ReadonlySet<string> = new Set([\n LOSS.ID_MANGLED,\n LOSS.ID_CHARSET,\n LOSS.ID_RENUMBERED,\n ID_TEXT_TYPE_LOSS,\n ID_COLUMN_TAKEN_LOSS,\n MULTIPLE_ID_PROPERTIES_LOSS,\n]);\n\nconst ARRAY_SYNTAXES: ReadonlySet<string> = new Set([\";\", \",\", \"|\"]);\nconst PARTS: ReadonlySet<string> = new Set([\"all\", \"nodes\", \"relationships\"]);\n\n/** The resolved format options. */\ninterface ResolvedNeo4jExportOptions {\n readonly part: \"all\" | \"nodes\" | \"relationships\";\n readonly syntax: RecordSyntax & { readonly delimiter: string };\n readonly arrayDelimiter: string;\n readonly weightColumn: string | null;\n readonly idColumn: string | null;\n}\n\n/** How one cell's value is written. */\ntype CellKind = \"integer\" | \"float\" | \"double\" | \"boolean\" | \"string\" | \"temporal\" | \"point\" | \"json\";\n\n/** The Neo4j type and cell kind of one scalar (a column or a list item). */\ninterface ScalarPlan {\n readonly type: string;\n readonly kind: CellKind;\n readonly temporal: TemporalKind | null;\n}\n\n/** One property column as it will be written. */\ninterface ColumnPlan {\n readonly column: Column;\n readonly header: string;\n readonly scalar: ScalarPlan;\n /** A list (or flattened vector) column: items are joined by the array delimiter. */\n readonly list: boolean;\n /** The companion text column of a temporal column, or null. */\n readonly companion: Column | null;\n}\n\n/**\n * Resolve the format options.\n * @param options - the caller's options\n * @param readFrom - the property a Neo4j import read the weights from, the default weightColumn\n * @returns the resolved options; E_UNSUPPORTED for an invalid value\n */\nfunction resolveNeo4jExportOptions(\n options: Neo4jExportOptions | undefined,\n readFrom: string | null,\n): ResolvedNeo4jExportOptions {\n const o: Neo4jExportOptions = options ?? {};\n const part = o.part ?? \"all\";\n if (!PARTS.has(part)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option part: ${JSON.stringify(part)} is not \"all\", \"nodes\" or \"relationships\"`,\n {\n option: \"part\",\n found: part,\n },\n );\n }\n const arrayDelimiter = o.arrayDelimiter ?? \";\";\n if (!ARRAY_SYNTAXES.has(arrayDelimiter)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option arrayDelimiter: ${JSON.stringify(arrayDelimiter)} is not one of \";\", \",\", \"|\"`,\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n const delimiter = o.delimiter ?? \",\";\n const syntax = { ...checkRecordSyntax({ delimiter, quote: o.quote ?? '\"' }), delimiter };\n if (syntax.delimiter === arrayDelimiter) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `options delimiter and arrayDelimiter must differ: both are ${JSON.stringify(arrayDelimiter)}; pass another arrayDelimiter (\";\", \",\" or \"|\")`,\n {\n option: \"arrayDelimiter\",\n found: arrayDelimiter,\n },\n );\n }\n const weightColumn = o.weightColumn === undefined ? (readFrom ?? \"weight\") : o.weightColumn;\n if (weightColumn !== null && (typeof weightColumn !== \"string\" || weightColumn.length === 0)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option weightColumn: expected a non-empty name or null\", {\n option: \"weightColumn\",\n found: weightColumn,\n });\n }\n const idColumn = o.idColumn ?? null;\n if (idColumn !== null && (typeof idColumn !== \"string\" || idColumn.length === 0)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option idColumn: expected a non-empty name or null\", {\n option: \"idColumn\",\n found: idColumn,\n });\n }\n return { part, syntax, arrayDelimiter, weightColumn, idColumn };\n}\n\n/**\n * Everything check() and export() share: the column plans, the section keys, the notes and the\n * error export() throws (if any), computed once from the snapshot and the options.\n */\nclass ExportPlan {\n readonly snapshot: GraphSnapshot;\n\n readonly options: ResolvedNeo4jExportOptions;\n\n readonly common: ResolvedExportOptions;\n\n /** The notes: the generic capability notes first, then the format's own, in that order. */\n readonly notes: LossNote[] = [];\n\n /** The format's own notes, appended after the generic ones. */\n private readonly ownNotes: LossNote[] = [];\n\n /** The error export() throws because of the node sections, or null. */\n private fatalNodes: GraphFormatError | null = null;\n\n /** The error export() throws because of the relationship sections, or null. */\n private fatalEdges: GraphFormatError | null = null;\n\n /** The error export() throws whatever the part (an id text collision), or null. */\n private fatalAll: GraphFormatError | null = null;\n\n readonly nodeColumns: ColumnPlan[] = [];\n\n readonly edgeColumns: ColumnPlan[] = [];\n\n /** Stored-id node columns (`name:ID`), in declaration order. */\n readonly idColumns: Column[] = [];\n\n readonly idSpace: Column | null;\n\n /** The id text of the nodes of an id space (the importer's `originalId` column), or null. */\n readonly originalId: Column | null;\n\n readonly labels: Column | null;\n\n readonly kind: Column | null;\n\n readonly weights: ExplicitWeights | null;\n\n /** The pair folding (design section 3.6): the mirror halves of undirected pairs are not written. */\n readonly folding: PairFolding;\n\n /**\n * Build the plan.\n * @param snapshot - the snapshot\n * @param options - the resolved format options\n * @param common - the resolved common options\n */\n constructor(snapshot: GraphSnapshot, options: ResolvedNeo4jExportOptions, common: ResolvedExportOptions) {\n this.snapshot = snapshot;\n this.options = options;\n this.common = common;\n this.idSpace = snapshot.nodes.byRole(\"idSpace\");\n this.originalId = [...snapshot.nodes].find((column) => isIdText(column.meta)) ?? null;\n this.labels = snapshot.nodes.byRole(\"labels\");\n this.kind = snapshot.edges.byRole(\"kind\");\n for (const column of snapshot.nodes) {\n if (isStoredId(column.meta)) {\n this.idColumns.push(column);\n }\n }\n const generic = checkCapabilities(snapshot, NEO4J_CAPABILITIES, common, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n temporalText: true,\n weights: options.weightColumn !== null,\n });\n this.planColumns(\"node\", snapshot.nodes, this.nodeColumns);\n this.planColumns(\"edge\", snapshot.edges, this.edgeColumns);\n this.weights = this.planWeightSource();\n this.folding = pairFolding(snapshot);\n this.checkIds();\n this.checkIdColumn();\n this.checkStoredIds();\n this.directionNotes();\n const slots = new Set([this.kind, this.labels, this.idSpace].flatMap((c) => (c === null ? [] : [c.meta.name])));\n this.addGenericNotes(generic, slots);\n this.notes.push(...this.ownNotes);\n this.filterNotesByPart();\n }\n\n /**\n * Add the generic capability notes, leaving out the ones this format reads back as they were.\n * @param generic - the notes the capability check found\n * @param slots - the names of the :TYPE, :LABEL and :ID(Space) columns\n */\n private addGenericNotes(generic: ReturnType<typeof checkCapabilities>, slots: ReadonlySet<string>): void {\n for (const gen of generic) {\n if (gen.code === LOSS.JSON && gen.column !== null && this.writtenAsPoint(gen.column)) {\n continue;\n }\n if (gen.code === LOSS.DTYPE && gen.column !== null && slots.has(gen.column)) {\n // :TYPE, :LABEL and :ID(Space) read back as the dict / list-of-dict columns they were\n continue;\n }\n if (gen.code === LOSS.MIXED_DIRECTION_ERROR && this.fatalEdges === null) {\n this.fatalEdges = new GraphFormatError(\"E_DIRECTED\", gen.message, { reason: \"mixed direction\" });\n }\n if ((gen.code === LOSS.POSITIONS || gen.code === LOSS.VIZ) && gen.column !== null) {\n // written as a plain property (a point for a position); the role is what is lost. Deprecated for\n // the style roles (next major): styles reach a file only through the style writer.\n this.notes.push(\n Object.freeze({\n code: gen.code,\n message: `node column \"${gen.column}\" is written as a plain property; its role is lost on re-import`,\n column: gen.column,\n count: gen.count,\n }),\n );\n continue;\n }\n this.notes.push(gen);\n }\n }\n\n /**\n * The direction notes: an undirected snapshot writes every edge as a directed relationship;\n * a mixed snapshot folds its undirected pairs to one directed relationship each under\n * \"directed\" or \"undirected\" (Neo4j has no undirected relationship, so both policies write\n * the same file and the generic W_MIXED_DIRECTION note names the policy); a mutual pair is\n * written as two relationships without its mark.\n */\n private directionNotes(): void {\n const { snapshot, folding } = this;\n if (!snapshot.directed) {\n this.note(\n UNDIRECTED_LOSS,\n `the snapshot is undirected; every edge is written as a directed relationship (${snapshot.edgeCount} edge${plural(snapshot.edgeCount)})`,\n null,\n snapshot.edgeCount,\n );\n } else if (this.common.onMixedDirection !== \"error\") {\n let undirected = 0;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (!folding.folded(e) && !folding.sourceDirected(e)) {\n undirected++;\n }\n }\n if (undirected > 0) {\n this.note(\n UNDIRECTED_LOSS,\n `${undirected} undirected edge${plural(undirected)} ${agree(undirected, \"is\", \"are\")} written as one directed relationship each (source to target, a pair folded to its primary); Neo4j has no undirected relationship`,\n null,\n undirected,\n );\n }\n }\n if (folding.mutualCount > 0) {\n this.note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, \"is\", \"are\")} written as two directed relationships; the mutual mark is lost`,\n null,\n folding.mutualCount,\n );\n }\n }\n\n /**\n * Record a note.\n * @param code - the code\n * @param message - the message\n * @param column - the column, or null\n * @param count - the count, or null\n */\n private note(code: string, message: string, column: string | null = null, count: number | null = null): void {\n this.ownNotes.push(Object.freeze({ code, message, column, count }));\n }\n\n /**\n * Plan the property columns of one table.\n * @param domain - node or edge\n * @param table - the table\n * @param out - receives the plans in declaration order\n */\n private planColumns(domain: \"node\" | \"edge\", table: Iterable<Column>, out: ColumnPlan[]): void {\n const all = [...table];\n const names = new Set(all.map((column) => column.meta.name));\n const companionFor = new Map<string, Column>();\n const companions = new Set<Column>();\n for (const column of all) {\n const target = column.meta.extra.for;\n if (column.dtype === \"string\" && typeof target === \"string\" && names.has(target)) {\n companionFor.set(target, column);\n companions.add(column);\n }\n }\n for (const column of all) {\n const { meta } = column;\n const { role } = meta;\n if (companions.has(column) || (role !== null && SKIPPED_ROLES.has(role))) {\n continue;\n }\n if (\n domain === \"node\" &&\n (isStoredId(meta) || column === this.idSpace || column === this.labels || column === this.originalId)\n ) {\n continue;\n }\n if (domain === \"edge\" && (role === \"id\" || column === this.kind)) {\n continue;\n }\n out.push(this.planColumn(column, companionFor.get(meta.name) ?? null));\n }\n }\n\n /**\n * Plan one property column: its header type, cell kind and notes.\n * @param column - the column\n * @param companion - its text companion, or null\n * @returns the plan\n */\n private planColumn(column: Column, companion: Column | null): ColumnPlan {\n const { meta } = column;\n const declared = meta.origin?.type ?? null;\n const mapped = declared === null ? null : mapDeclaredType(NEO4J, declared, \"f64\");\n const label = `${meta.domain} column \"${meta.name}\"`;\n if (meta.dtype === \"list\") {\n const itemDtype = meta.itemDtype ?? \"string\";\n const compatible =\n mapped !== null && mapped.list && mapped.itemDtype === itemDtype && mapped.kind !== \"long\";\n let scalar = compatible\n ? { type: declaredScalar(declared as string), kind: kindOf(mapped), temporal: mapped.temporal }\n : defaultScalar(itemDtype);\n if (mapped !== null && mapped.list && mapped.kind === \"long\" && itemDtype === \"f64\") {\n scalar = this.integralOrDouble(column, declaredScalar(declared as string), label);\n }\n const itemComponents = meta.itemComponents ?? 1;\n if (itemComponents > 1) {\n this.note(\n LOSS.COMPONENTS,\n `${label} holds items of ${itemComponents} components; they are flattened into one array`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n this.checkArrayItems(column, scalar, label);\n return {\n column,\n header: formatHeaderField(meta.name, `${scalar.type}[]`, null),\n scalar,\n list: true,\n companion,\n };\n }\n let scalar: ScalarPlan;\n const compatible = mapped !== null && !mapped.list && mapped.dtype === meta.dtype;\n if (compatible && mapped.kind === \"long\") {\n scalar = this.integralOrDouble(column, declared as string, label);\n } else if (compatible) {\n scalar = { type: declared as string, kind: kindOf(mapped), temporal: mapped.temporal };\n } else {\n scalar = defaultScalar(meta.dtype);\n }\n // the generic check treats position and visual columns by role only; their dtype and\n // stride are checked here so the notes match those of any other column\n const visual = meta.role === \"position\" || (meta.role !== null && isVizRole(meta.role));\n if (visual && meta.dtype === \"json\" && scalar.kind !== \"point\") {\n this.note(\n LOSS.JSON,\n `${label} holds nested values; the format has no nested values`,\n meta.name,\n column.length - column.nullCount,\n );\n } else if (visual && meta.dtype !== \"json\" && !NEO4J_CAPABILITIES.dtypes.includes(meta.dtype)) {\n this.note(\n LOSS.DTYPE,\n `${label} is ${meta.dtype}; the format cannot keep that dtype`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n if (meta.components > 1) {\n if (visual) {\n this.note(\n LOSS.COMPONENTS,\n `${label} has ${meta.components} components; the format has no strides`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n return {\n column,\n header: formatHeaderField(meta.name, `${scalar.type}[]`, null),\n scalar,\n list: true,\n companion,\n };\n }\n // an untyped Neo4j header (`name` alone) is a string property; restore it as written\n const untyped = declared === null && meta.origin?.format === NEO4J && meta.dtype === \"string\";\n const header = untyped ? meta.name : formatHeaderField(meta.name, scalar.type, null);\n return { column, header, scalar, list: false, companion };\n }\n\n /**\n * The plan of an f64 column declared with an integer type: kept when every set value is\n * integral, written as double (with a note) otherwise.\n * @param column - the column\n * @param declared - the declared type text\n * @param label - the column label for messages\n * @returns the scalar plan\n */\n private integralOrDouble(column: Column, declared: string, label: string): ScalarPlan {\n if (holdsOnlyIntegers(column)) {\n return { type: declared, kind: \"integer\", temporal: null };\n }\n this.note(\n DECLARED_TYPE_CHANGED_LOSS,\n `${label} is declared ${declared} but holds non-integral values; written as double`,\n column.meta.name,\n null,\n );\n return { type: \"double\", kind: \"double\", temporal: null };\n }\n\n /**\n * Count the rows of a list column with an item containing the array delimiter.\n * @param column - the list column\n * @param scalar - the item plan\n * @param label - the column label\n */\n private checkArrayItems(column: Column, scalar: ScalarPlan, label: string): void {\n if (\n column.dtype !== \"list\" ||\n (scalar.kind !== \"string\" && scalar.kind !== \"json\" && scalar.kind !== \"point\")\n ) {\n return;\n }\n const { arrayDelimiter } = this.options;\n let rows = 0;\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n for (const item of column.sliceOf(r)) {\n if (formatScalar(item, scalar, null).includes(arrayDelimiter)) {\n rows++;\n break;\n }\n }\n }\n if (rows > 0) {\n this.note(\n ARRAY_DELIMITER_LOSS,\n `${label}: ${rows} row${plural(rows)} ${agree(rows, \"holds\", \"hold\")} an item containing the array delimiter \"${arrayDelimiter}\", which Neo4j cannot escape`,\n column.meta.name,\n rows,\n );\n }\n }\n\n /**\n * The explicit weights (design section 3.7), and the weight-column name check.\n * @returns the weights, or null when no weights are written\n */\n private planWeightSource(): ExplicitWeights | null {\n const { snapshot } = this;\n const name = this.options.weightColumn;\n if (name === null) {\n return null;\n }\n const weights = explicitWeights(snapshot);\n const taken = this.edgeColumns.find((plan) => plan.column.meta.name === name);\n if (taken !== undefined && weights.weighted) {\n this.note(\n WEIGHT_COLUMN_TAKEN_LOSS,\n `edge column \"${name}\" already exists; explicit weights cannot be written under weightColumn \"${name}\"`,\n name,\n null,\n );\n if (this.fatalEdges === null) {\n this.fatalEdges = new GraphFormatError(\n \"E_COLUMN_EXISTS\",\n `edge column \"${name}\" already exists; choose another weightColumn`,\n { column: name, domain: \"edge\" },\n );\n }\n } else if (taken !== undefined && name === DEFAULT_WEIGHT_COLUMN) {\n this.note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${name}\" is written under the property the importer reads edge weights from (weightFrom \"${name}\"); it reads back as the weight, not as a column`,\n name,\n taken.column.length - taken.column.nullCount,\n );\n }\n return weights.weighted ? weights : null;\n }\n\n /** Check the node ids' text forms: type changes under the canonical rule and collisions. */\n private checkIds(): void {\n const { ids } = this.snapshot;\n let typeChanges = 0;\n let collisions = 0;\n switch (ids.kind) {\n case \"identity\":\n case \"dense\":\n break;\n case \"numeric\":\n for (let i = 0; i < ids.size; i++) {\n if (!Number.isSafeInteger(ids.idOf(i))) {\n typeChanges++;\n }\n }\n break;\n case \"string\":\n for (let i = 0; i < ids.size; i++) {\n if (isCanonicalIntegerText(String(ids.idOf(i)))) {\n typeChanges++;\n }\n }\n break;\n case \"mixed\": {\n const seen = new Set<string>();\n for (let i = 0; i < ids.size; i++) {\n const id = ids.idOf(i);\n const text = String(id);\n if (typeof id === \"number\" ? !Number.isSafeInteger(id) : isCanonicalIntegerText(text)) {\n typeChanges++;\n }\n if (seen.has(text)) {\n collisions++;\n } else {\n seen.add(text);\n }\n }\n break;\n }\n default: {\n const name: string = ids.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown id map kind ${name}`, { kind: name });\n }\n }\n if (typeChanges > 0) {\n this.note(\n ID_TEXT_TYPE_LOSS,\n `${typeChanges} node id${plural(typeChanges)} re-import as another type under the canonical id rule (a string of canonical integer text, or a non-integer number)`,\n null,\n typeChanges,\n );\n }\n if (collisions > 0) {\n this.note(\n ID_TEXT_COLLISION_LOSS,\n `${collisions} node id${plural(collisions)} ${agree(collisions, \"shares\", \"share\")} their text with another id (a number and a string); the save fails`,\n null,\n collisions,\n );\n this.fatalAll = new GraphFormatError(\n \"E_INVALID_ID\",\n `${collisions} node id${plural(collisions)} ${agree(collisions, \"shares\", \"share\")} their text with another id; Neo4j ids are text`,\n { reason: \"text collision\", count: collisions },\n );\n }\n }\n\n /** Check that the idColumn option does not name an existing node property. */\n private checkIdColumn(): void {\n const name = this.options.idColumn;\n if (name === null) {\n return;\n }\n const taken =\n this.nodeColumns.some((plan) => plan.column.meta.name === name) ||\n this.idColumns.some((column) => column.meta.name === name);\n if (!taken) {\n return;\n }\n this.note(\n ID_COLUMN_TAKEN_LOSS,\n `node column \"${name}\" already exists; the :ID column cannot be named idColumn \"${name}\"`,\n name,\n null,\n );\n if (this.fatalNodes === null) {\n this.fatalNodes = new GraphFormatError(\n \"E_COLUMN_EXISTS\",\n `node column \"${name}\" already exists; choose another idColumn`,\n { column: name, domain: \"node\" },\n );\n }\n }\n\n /** Count the nodes with more than one stored-id column set. */\n private checkStoredIds(): void {\n if (this.idColumns.length < 2) {\n return;\n }\n let count = 0;\n for (let i = 0; i < this.snapshot.nodeCount; i++) {\n let set = 0;\n for (const column of this.idColumns) {\n if (column.isSet(i)) {\n set++;\n }\n }\n if (set > 1) {\n count++;\n }\n }\n if (count > 0) {\n this.note(\n MULTIPLE_ID_PROPERTIES_LOSS,\n `${count} node${plural(count)} ${agree(count, \"has\", \"have\")} more than one stored-id column set; only the first in declaration order is written`,\n null,\n count,\n );\n }\n }\n\n /**\n * Whether a json column is written as Neo4j points (so the generic nested-value note does not apply).\n * @param name - the column name\n * @returns true when its plan writes point literals\n */\n private writtenAsPoint(name: string): boolean {\n for (const plan of [...this.nodeColumns, ...this.edgeColumns]) {\n if (plan.column.meta.name === name && plan.scalar.kind === \"point\") {\n return true;\n }\n }\n return false;\n }\n\n /** Drop the notes about the part that is not written. */\n private filterNotesByPart(): void {\n const { part } = this.options;\n if (part === \"all\") {\n return;\n }\n const { snapshot } = this;\n const keep = this.notes.filter((n) => {\n if (part === \"nodes\") {\n if (EDGE_NOTE_CODES.has(n.code)) {\n return false;\n }\n return n.column === null || !snapshot.edges.has(n.column) || snapshot.nodes.has(n.column);\n }\n if (NODE_NOTE_CODES.has(n.code)) {\n return false;\n }\n return n.column === null || !snapshot.nodes.has(n.column) || snapshot.edges.has(n.column);\n });\n this.notes.length = 0;\n this.notes.push(...keep);\n }\n\n /**\n * The error export() throws for the requested part, or null when the export can proceed.\n * @returns the error\n */\n get fatal(): GraphFormatError | null {\n if (this.fatalAll !== null) {\n return this.fatalAll;\n }\n const { part } = this.options;\n if (part !== \"relationships\" && this.fatalNodes !== null) {\n return this.fatalNodes;\n }\n return part === \"nodes\" ? null : this.fatalEdges;\n }\n\n /**\n * The id space of a node.\n * @param index - the node index\n * @returns the space name, or null\n */\n spaceOf(index: number): string | null {\n const { idSpace } = this;\n if (!idSpace?.isSet(index)) {\n return null;\n }\n const value = idSpace.value(index);\n return typeof value === \"string\" ? value : String(value);\n }\n\n /**\n * The `:ID` / `:START_ID` / `:END_ID` text of a node: its originalId value when it has an id\n * space (the importer stored it as `Space:id`), its id otherwise.\n * @param index - the node index\n * @returns the id text\n */\n idTextOf(index: number): string {\n const { originalId } = this;\n if (originalId !== null && originalId.isSet(index) && this.spaceOf(index) !== null) {\n return textOf(originalId, index);\n }\n return idText(this.snapshot.ids.idOf(index));\n }\n\n /**\n * The stored-id column of a node: the first one set in declaration order.\n * @param index - the node index\n * @returns the column, or null\n */\n storedIdOf(index: number): Column | null {\n for (const column of this.idColumns) {\n if (column.isSet(index)) {\n return column;\n }\n }\n return null;\n }\n\n /**\n * The node sections, then the relationship sections, as CSV lines.\n * @yields one line at a time (with its line break)\n * @returns nothing\n */\n *lines(): Generator<string, void, undefined> {\n for (const row of this.rows()) {\n yield row.line;\n }\n }\n\n /**\n * The lines of the requested part, each header line tagged with the file it starts.\n * @yields one line at a time, with the file name on a header line\n * @returns nothing\n */\n *rows(): Generator<SectionLine, void, undefined> {\n if (this.fatal !== null) {\n throw this.fatal;\n }\n const { part } = this.options;\n if (part !== \"relationships\") {\n yield* this.nodeLines();\n }\n if (part !== \"nodes\") {\n yield* this.relationshipLines();\n }\n }\n\n /**\n * The requested part as one file per section kind: a node file per id space (and stored-id\n * property), a relationship file per pair of endpoint id spaces, rows of one kind gathered\n * under one header.\n * @returns the files, node files first\n */\n files(): Neo4jFile[] {\n // keyed by the header row: sections with the same header are one file\n const files = new Map<string, { name: string; kind: \"nodes\" | \"relationships\"; rows: string[] }>();\n const names = new Set<string>();\n let current: { rows: string[] } | null = null;\n for (const row of this.rows()) {\n if (row.file !== null) {\n let file = files.get(row.line);\n if (file === undefined) {\n let name = `${row.file.name}.csv`;\n let k = 2;\n while (names.has(name)) {\n name = `${row.file.name}-${k}.csv`;\n k++;\n }\n names.add(name);\n file = { name, kind: row.file.kind, rows: [] };\n files.set(row.line, file);\n }\n current = file;\n } else if (current !== null) {\n current.rows.push(row.line);\n }\n }\n // a part with no rows (a graph without edges) is a header alone, which neo4j-admin does not need\n const written = [...files].filter(([, f], i) => f.rows.length > 0 || (i === 0 && files.size === 1));\n return written.map(([header, f]) =>\n Object.freeze({ name: f.name, kind: f.kind, text: header + f.rows.join(\"\") }),\n );\n }\n\n /**\n * The node sections.\n * @yields one line at a time\n * @returns nothing\n */\n private *nodeLines(): Generator<SectionLine, void, undefined> {\n const { snapshot } = this;\n let sections = 0;\n let sectionSpace: string | null = null;\n let sectionIdName: string | null = null;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const space = this.spaceOf(i);\n const stored = this.storedIdOf(i);\n const idName = stored === null ? (this.options.idColumn ?? \"\") : stored.meta.name;\n if (sections === 0 || space !== sectionSpace || idName !== sectionIdName) {\n sections++;\n sectionSpace = space;\n sectionIdName = idName;\n yield this.nodeHeader(idName, space, space ?? idName);\n }\n yield { line: this.nodeRow(i), file: null };\n }\n if (sections === 0) {\n // no nodes: one header so the section (and its columns) still exists\n yield this.nodeHeader(this.options.idColumn ?? \"\", null, null);\n }\n }\n\n /**\n * The header line of a node section, which starts its file.\n * @param idName - the id column's name\n * @param space - the id space, or null\n * @param fileKey - what names the file, or null for the default name\n * @returns the line\n */\n private nodeHeader(idName: string, space: string | null, fileKey: string | null): SectionLine {\n const { delimiter } = this.options.syntax;\n const header = [formatHeaderField(idName, ID_TYPE, space)];\n if (this.labels !== null) {\n header.push(\":LABEL\");\n }\n const properties = this.nodeColumns.map((plan) => plan.header).join(delimiter);\n if (properties.length > 0) {\n header.push(properties);\n }\n return { line: `${header.join(delimiter)}\\n`, file: { kind: \"nodes\", name: fileName(\"nodes\", fileKey, null) } };\n }\n\n /**\n * One node's line: the id, the labels, the properties.\n * @param i - the node\n * @returns the line\n */\n private nodeRow(i: number): string {\n const cells = [this.cell(this.idTextOf(i))];\n if (this.labels !== null) {\n cells.push(this.cell(this.labelsText(i)));\n }\n for (const plan of this.nodeColumns) {\n cells.push(this.cell(this.valueText(plan, i)));\n }\n return `${cells.join(this.options.syntax.delimiter)}\\n`;\n }\n\n /**\n * The relationship sections.\n * @yields one line at a time\n * @returns nothing\n */\n private *relationshipLines(): Generator<SectionLine, void, undefined> {\n const { snapshot, folding } = this;\n const list = snapshot.edgeList();\n let sections = 0;\n let sectionStart: string | null = null;\n let sectionEnd: string | null = null;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n const u = list.src[e];\n const v = list.dst[e];\n const startSpace = this.spaceOf(u);\n const endSpace = this.spaceOf(v);\n if (sections === 0 || startSpace !== sectionStart || endSpace !== sectionEnd) {\n sections++;\n sectionStart = startSpace;\n sectionEnd = endSpace;\n yield this.relationshipHeader(startSpace, endSpace);\n }\n yield { line: this.relationshipRow(e, u, v), file: null };\n }\n if (sections === 0) {\n yield this.relationshipHeader(null, null);\n }\n }\n\n /**\n * The header line of a relationship section, which starts its file.\n * @param startSpace - the id space of the start nodes, or null\n * @param endSpace - the id space of the end nodes, or null\n * @returns the line\n */\n private relationshipHeader(startSpace: string | null, endSpace: string | null): SectionLine {\n const { delimiter } = this.options.syntax;\n const header = [formatHeaderField(\"\", \"START_ID\", startSpace), formatHeaderField(\"\", \"END_ID\", endSpace)];\n if (this.kind !== null) {\n header.push(\":TYPE\");\n }\n if (this.weights !== null) {\n header.push(formatHeaderField(this.options.weightColumn ?? \"weight\", \"double\", null));\n }\n const properties = this.edgeColumns.map((plan) => plan.header).join(delimiter);\n if (properties.length > 0) {\n header.push(properties);\n }\n return {\n line: `${header.join(delimiter)}\\n`,\n file: { kind: \"relationships\", name: fileName(\"relationships\", startSpace, endSpace) },\n };\n }\n\n /**\n * One relationship's line: the ends, the type, the weight, the properties.\n * @param e - the edge\n * @param u - its source\n * @param v - its target\n * @returns the line\n */\n private relationshipRow(e: number, u: number, v: number): string {\n const { kind, weights } = this;\n const cells = [this.cell(this.idTextOf(u)), this.cell(this.idTextOf(v))];\n if (kind !== null) {\n cells.push(this.cell(kind.isSet(e) ? textOf(kind, e) : null));\n }\n if (weights !== null) {\n cells.push(this.cell(weights.text(e)));\n }\n for (const plan of this.edgeColumns) {\n cells.push(this.cell(this.valueText(plan, e)));\n }\n return `${cells.join(this.options.syntax.delimiter)}\\n`;\n }\n\n /**\n * A CSV cell: empty for an unset value, a quoted empty string for a set empty string, the\n * quoted text otherwise.\n * @param text - the value text, or null for unset\n * @returns the cell as written\n */\n private cell(text: string | null): string {\n if (text === null) {\n return \"\";\n }\n const { quote } = this.options.syntax;\n if (text.length === 0) {\n return quote + quote;\n }\n return quoteCsvCell(text, this.options.syntax.delimiter, quote);\n }\n\n /**\n * The `:LABEL` cell of a node.\n * @param index - the node index\n * @returns the labels joined by the array delimiter, or null when unset\n */\n private labelsText(index: number): string | null {\n const { labels } = this;\n if (!labels?.isSet(index)) {\n return null;\n }\n if (labels.dtype === \"list\") {\n return labels.sliceOf(index).map(String).join(this.options.arrayDelimiter);\n }\n return textOf(labels, index);\n }\n\n /**\n * The text of one property cell.\n * @param plan - the column plan\n * @param row - the row\n * @returns the text, or null when unset\n */\n private valueText(plan: ColumnPlan, row: number): string | null {\n const { column, scalar, companion } = plan;\n if (!column.isSet(row)) {\n return null;\n }\n if (plan.list) {\n return this.listText(plan, row);\n }\n const text = companion?.isSet(row) ? textOf(companion, row) : null;\n return formatScalar(column.dtype === \"json\" ? column.values[row] : column.value(row), scalar, text);\n }\n\n /**\n * The text of one list cell: its items joined by the array delimiter.\n * @param plan - the column plan\n * @param row - the row, which is set\n * @returns the text\n */\n private listText(plan: ColumnPlan, row: number): string {\n const { column, scalar } = plan;\n const items = column.dtype === \"list\" ? column.sliceOf(row) : (column.value(row) as ArrayLike<unknown>);\n const texts: string[] = [];\n for (const item of Array.from(items)) {\n // an item of several components (itemComponents > 1) is flattened into the array\n if (Array.isArray(item) || ArrayBuffer.isView(item)) {\n for (const component of Array.from(item as ArrayLike<unknown>)) {\n texts.push(formatScalar(component, scalar, null));\n }\n } else {\n texts.push(formatScalar(item, scalar, null));\n }\n }\n return texts.join(this.options.arrayDelimiter);\n }\n}\n\n/**\n * Whether a node column is the importer's id text of the nodes of an id space (`originalId`).\n * @param meta - the column metadata\n * @returns true for the role-less string column the Neo4j importer declares with origin id `:ID` and no type\n */\nfunction isIdText(meta: ColumnMeta): boolean {\n return (\n meta.role === null &&\n meta.dtype === \"string\" &&\n meta.origin !== null &&\n meta.origin.format === NEO4J &&\n meta.origin.id === \":ID\" &&\n meta.origin.type === null\n );\n}\n\n/**\n * Whether a node column is a stored id (`name:ID` on import).\n * @param meta - the column metadata\n * @returns true for a string column declared by the Neo4j importer as the id property\n */\nfunction isStoredId(meta: ColumnMeta): boolean {\n return (\n meta.role === null &&\n meta.dtype === \"string\" &&\n meta.origin !== null &&\n meta.origin.format === NEO4J &&\n meta.origin.type === ID_TYPE\n );\n}\n\n/**\n * Whether a role is one of the visual roles.\n * @param role - the role\n * @returns true for color, size, shape and thickness\n */\nfunction isVizRole(role: string): boolean {\n return role === \"color\" || role === \"size\" || role === \"shape\" || role === \"thickness\";\n}\n\n/**\n * The declared scalar type text of a list declaration (`string[]` -> `string`).\n * @param declared - the declared type text\n * @returns the text without its `[]` suffix\n */\nfunction declaredScalar(declared: string): string {\n const trimmed = declared.trim();\n return trimmed.endsWith(\"[]\") ? trimmed.slice(0, -2) : trimmed;\n}\n\n/**\n * The cell kind of a mapped declared type.\n * @param spec - the mapped type\n * @returns the kind\n */\nfunction kindOf(spec: DeclaredTypeSpec): CellKind {\n switch (spec.kind) {\n case \"boolean\":\n return \"boolean\";\n case \"integer\":\n case \"long\":\n return \"integer\";\n case \"float\":\n return \"float\";\n case \"double\":\n return \"double\";\n case \"string\":\n case \"duration\":\n return \"string\";\n case \"temporal\":\n return \"temporal\";\n case \"point\":\n return \"point\";\n case \"json\":\n return \"json\";\n default: {\n const name: string = spec.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown value kind ${name}`, { kind: name });\n }\n }\n}\n\n/**\n * The Neo4j type of a dtype without a compatible declaration.\n * @param dtype - the column or item dtype\n * @returns the type and cell kind\n */\nfunction defaultScalar(dtype: Dtype | ScalarDtype): ScalarPlan {\n switch (dtype) {\n case \"f32\":\n return { type: \"float\", kind: \"float\", temporal: null };\n case \"f64\":\n return { type: \"double\", kind: \"double\", temporal: null };\n case \"i32\":\n case \"u8\":\n return { type: \"int\", kind: \"integer\", temporal: null };\n case \"u32\":\n return { type: \"long\", kind: \"integer\", temporal: null };\n case \"bool\":\n return { type: \"boolean\", kind: \"boolean\", temporal: null };\n case \"dict\":\n case \"string\":\n return { type: \"string\", kind: \"string\", temporal: null };\n case \"json\":\n return { type: \"string\", kind: \"json\", temporal: null };\n case \"list\":\n return { type: \"string\", kind: \"json\", temporal: null };\n default: {\n const name: string = dtype;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dtype ${name}`, { dtype: name });\n }\n }\n}\n\n/**\n * Format a number with a formatter; any other value is written as String(value).\n * @param value - the value\n * @param format - the number formatter\n * @returns the text\n */\nfunction numberOrString(value: unknown, format: (n: number) => string): string {\n return typeof value === \"number\" ? format(value) : String(value);\n}\n\n/**\n * Format one scalar value for a cell.\n * @param value - the value\n * @param scalar - the plan\n * @param text - the companion text of a temporal value, or null\n * @returns the text\n */\nfunction formatScalar(value: unknown, scalar: ScalarPlan, text: string | null): string {\n switch (scalar.kind) {\n case \"integer\":\n return numberOrString(value, formatInteger);\n case \"float\":\n return numberOrString(value, formatF32);\n case \"double\":\n return numberOrString(value, formatF64);\n case \"boolean\":\n return value === true ? \"true\" : \"false\";\n case \"string\":\n return String(value);\n case \"temporal\":\n return (\n text ??\n numberOrString(value, (n) =>\n scalar.temporal === null ? String(n) : formatTemporal(n, scalar.temporal),\n )\n );\n case \"point\":\n return formatPoint(value);\n case \"json\":\n return JSON.stringify(value) ?? \"\";\n default: {\n const name: string = scalar.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown cell kind ${name}`, { kind: name });\n }\n }\n}\n\n/**\n * A Neo4j point literal `{x:1.5, y:2, crs:'cartesian'}` from a point object; any other value is\n * written as JSON text.\n * @param value - the json value\n * @returns the literal\n */\nfunction formatPoint(value: unknown): string {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return JSON.stringify(value) ?? \"\";\n }\n const parts: string[] = [];\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (typeof item === \"number\") {\n parts.push(`${key}:${formatF64(item)}`);\n } else if (typeof item === \"string\") {\n parts.push(`${key}:'${item.replaceAll(\"'\", \"\")}'`);\n } else {\n return JSON.stringify(value) ?? \"\";\n }\n }\n return `{${parts.join(\", \")}}`;\n}\n\n/**\n * The text of a node id.\n * @param id - the id\n * @returns String(id)\n */\nfunction idText(id: NodeId): string {\n if (typeof id === \"string\") {\n return id;\n }\n return Number.isInteger(id) ? formatInteger(id) : String(id);\n}\n\n/**\n * The text of a set cell of a dict / string (or any scalar) column.\n * @param column - the column\n * @param row - the row\n * @returns the value as text\n */\nfunction textOf(column: Column, row: number): string {\n switch (column.dtype) {\n case \"string\":\n return column.valueAt(row);\n case \"dict\":\n return String(column.value(row));\n case \"list\":\n return column.sliceOf(row).map(String).join(\",\");\n case \"json\":\n return JSON.stringify(column.values[row]) ?? \"\";\n case \"bool\":\n return column.value(row) === true ? \"true\" : \"false\";\n default: {\n const value = column.value(row);\n return typeof value === \"number\" ? String(value) : Array.from(value as ArrayLike<number>).join(\",\");\n }\n }\n}\n\n/**\n * The Neo4j exporter.\n * @category Built-in formats\n */\nexport const neo4jExporter: GraphExporter<Neo4jExportOptions> = Object.freeze({\n format: NEO4J,\n options: Object.freeze([\"arrayDelimiter\", \"delimiter\", \"idColumn\", \"part\", \"quote\", \"weightColumn\"]),\n capabilities: NEO4J_CAPABILITIES,\n /**\n * Pre-flight: what export() would lose.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the notes\n */\n check(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): readonly LossNote[] {\n return Object.freeze([...plan(snapshot, options).notes]);\n },\n /**\n * Write the snapshot as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(plan(snapshot, options).lines());\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): Promise<string> {\n return joinText(plan(snapshot, options).lines());\n },\n});\n\n/** One line of the export; a header line names the file it starts. */\ninterface SectionLine {\n readonly line: string;\n readonly file: { readonly kind: \"nodes\" | \"relationships\"; readonly name: string } | null;\n}\n\n/**\n * One file of exportNeo4jFiles(): the header row and the rows of one section kind.\n * @category Built-in formats\n */\nexport interface Neo4jFile {\n /** A file name made from the section: `nodes-Movie.csv`, `relationships-Person-Movie.csv`, or `nodes.csv` and `relationships.csv` without id spaces. */\n readonly name: string;\n /** Whether neo4j-admin takes the file with `--nodes` or with `--relationships`. */\n readonly kind: \"nodes\" | \"relationships\";\n /** The CSV text, one header row first. */\n readonly text: string;\n}\n\n/**\n * The file name of a section, without \".csv\": the kind, then the id spaces that set it apart.\n * @param kind - \"nodes\" or \"relationships\"\n * @param first - the id space or id property (nodes), or the start id space (relationships)\n * @param second - the end id space (relationships)\n * @returns the name, with characters outside letters, digits, \".\" , \"_\" and \"-\" replaced by \"_\"\n */\nfunction fileName(kind: string, first: string | null, second: string | null): string {\n const parts = [kind, first ?? \"\", second ?? \"\"].filter((p) => p !== \"\");\n return parts.join(\"-\").replaceAll(/[^\\w.-]/g, \"_\");\n}\n\n/**\n * Write a graph as the separate CSV files `neo4j-admin database import` takes: one node file per id\n * space and one relationship file per pair of endpoint id spaces, each with a single header row.\n * `exportGraph(snapshot, \"neo4j\")` writes the same sections into one file, which graph-io reads\n * back but neo4j-admin does not, since it reads one header per file. The options are the Neo4j\n * export options (`part` limits the result to the node or the relationship files), and\n * `checkExport(snapshot, \"neo4j\", options)` returns what the files lose.\n * @param snapshot - the graph to write\n * @param options - the Neo4j export options\n * @returns the files, node files first\n * @category Built-in formats\n * @example\n * ```ts\n * for (const file of await exportNeo4jFiles(snapshot)) {\n * await writeFile(file.name, file.text);\n * }\n * // neo4j-admin database import full --nodes=nodes-Movie.csv --nodes=nodes-Person.csv \\\n * // --relationships=relationships-Person-Movie.csv neo4j\n * ```\n */\nexport function exportNeo4jFiles(\n snapshot: GraphSnapshot,\n options?: Neo4jExportOptions & CommonExportOptions,\n): Promise<Neo4jFile[]> {\n try {\n return Promise.resolve(plan(snapshot, options).files());\n } catch (err) {\n return Promise.reject(err);\n }\n}\n\n/**\n * Build the export plan of a snapshot.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction plan(snapshot: GraphSnapshot, options: (Neo4jExportOptions & CommonExportOptions) | undefined): ExportPlan {\n return new ExportPlan(\n snapshot,\n resolveNeo4jExportOptions(options, weightPropertyOf(snapshot)),\n resolveExportOptions(options),\n );\n}\n\n/**\n * The relationship property a Neo4j import read the weights from, when it was not \"weight\".\n * @param snapshot - the snapshot\n * @returns the property name, or null\n */\nfunction weightPropertyOf(snapshot: GraphSnapshot): string | null {\n const neo4j = (snapshot.meta.extra as { neo4j?: { weightProperty?: unknown } } | null)?.neo4j;\n const name = neo4j?.weightProperty;\n return typeof name === \"string\" && name !== \"\" ? name : null;\n}\n\n/**\n * Whether every set value of an f64 column, or of an f64 list column's items, is integral.\n * @param column - the column\n * @returns false when a value is not an integer\n */\nfunction holdsOnlyIntegers(column: Column): boolean {\n if (column.dtype === \"f64\") {\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && !Number.isInteger(column.data[r])) {\n return false;\n }\n }\n } else if (column.dtype === \"list\" && column.child.dtype === \"f64\") {\n const { data } = column.child;\n for (let i = 0; i < data.length; i++) {\n if (!Number.isInteger(data[i])) {\n return false;\n }\n }\n }\n return true;\n}\n","/**\n * The `@graphty/graph-io/neo4j` subpath: the Neo4j importer and exporter with their option types,\n * the names of the reserved columns and the issue and loss-note codes\n * grouped in two tables.\n * @module @graphty/graph-io/neo4j\n */\n\nimport {\n COLUMN_RENAMED_CODE,\n COLUMN_TYPE_CODE,\n ELEMENT_ISSUE,\n ENCODING_FALLBACK_CODE,\n INPUT_ISSUE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MUTUAL_EXPANDED_CODE,\n OPTION_IGNORED_CODE,\n PRECISION_CODE,\n ROLE_DROPPED_CODE,\n SINK_OPTION_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ENCODING_CODE,\n WEIGHT_KEY_CLASH_CODE,\n} from \"../../common/codes.js\";\nimport { BAD_QUOTE_CODE, UNCLOSED_QUOTE_CODE } from \"../csv/records.js\";\nimport {\n ARRAY_DELIMITER_LOSS,\n DECLARED_TYPE_CHANGED_LOSS,\n ID_COLUMN_TAKEN_LOSS,\n ID_TEXT_COLLISION_LOSS,\n ID_TEXT_TYPE_LOSS,\n MULTIPLE_ID_PROPERTIES_LOSS,\n UNDIRECTED_LOSS,\n WEIGHT_COLUMN_TAKEN_LOSS,\n} from \"./exporter.js\";\nimport {\n COLUMN_COUNT_CODE,\n DANGLING_REFERENCE_CODE,\n DUPLICATE_NODE_CODE,\n ENDPOINT_SPACE_CODE,\n HEADER_CODE,\n HEADER_OPTION_CODE,\n ID_MERGED_CODE,\n ID_SPACE_COLLISION_CODE,\n IGNORED_COLUMNS_LOSS,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MISSING_TYPE_CODE,\n ROLE_TAKEN_CODE,\n SECTION_KIND_CODE,\n} from \"./importer.js\";\n\nexport {\n exportNeo4jFiles,\n NEO4J_CAPABILITIES,\n neo4jExporter,\n type Neo4jExportOptions,\n type Neo4jFile,\n} from \"./exporter.js\";\nexport {\n ID_SPACE_COLUMN,\n LABELS_COLUMN,\n neo4jImporter,\n type Neo4jImportOptions,\n ORIGINAL_ID_COLUMN,\n TYPE_COLUMN,\n} from \"./importer.js\";\n\n/**\n * The issue codes the Neo4j importer records, by name: the codes shared with\n * the other importers and the Neo4j-specific ones.\n * A key is the code without its severity and format prefixes.\n * @category Built-in formats\n */\nexport const NEO4J_ISSUE = Object.freeze({\n ...INPUT_ISSUE,\n ...ELEMENT_ISSUE,\n /**\n * A cell that does not parse as its column's declared type (\"x\" in an `:int` column, a `:byte` beyond 127). The\n * row is skipped.\n */\n COLUMN_TYPE: COLUMN_TYPE_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 quoted field is never closed. The import stops. */\n CSV_UNCLOSED_QUOTE: UNCLOSED_QUOTE_CODE,\n /**\n * There is text after a closing quote, such as `\"a\"b`. Inside a quoted field, write a quote as two quotes. The\n * import stops.\n */\n CSV_QUOTE: BAD_QUOTE_CODE,\n /** The file has no header, or a header neo4j-admin would refuse. The import stops. */\n HEADER: HEADER_CODE,\n /** A row with a different field count than the header. */\n COLUMN_COUNT: COLUMN_COUNT_CODE,\n /** A node row without an id. */\n MISSING_ID: MISSING_ID_CODE,\n /** A relationship row without a start or end id. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A node id repeated in one id space (last write wins). */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A spaced node id `Space:id` that equals the text of an id declared without a space. */\n ID_SPACE_COLLISION: ID_SPACE_COLLISION_CODE,\n /** A spaced relationship endpoint `Space:id` that names a node declared without a space; the row is skipped. */\n ENDPOINT_SPACE: ENDPOINT_SPACE_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 /** A header brace option the importer does not apply. */\n HEADER_OPTION_IGNORED: HEADER_OPTION_CODE,\n /** A declared type the format does not define (kept as string). */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: \"string\"` to keep every digit. */\n PRECISION: PRECISION_CODE,\n /**\n * An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example a\n * repeated column header.\n */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /**\n * You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as\n * a plain attribute.\n */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** You set an option this format does not use; it had no effect. The message names the option. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /**\n * You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,\n * `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.\n */\n SINK_OPTION: SINK_OPTION_CODE,\n /** A relationship with an empty :TYPE cell (neo4j-admin requires one); kept without a type. */\n MISSING_TYPE: MISSING_TYPE_CODE,\n /** A file under the nodes option holds a relationship header, or the reverse; read by its header. */\n SECTION_KIND: SECTION_KIND_CODE,\n /** Relationship endpoints no node row declares became nodes (neo4j-admin refuses them). */\n DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,\n});\n\n/**\n * The loss-note codes of the Neo4j importer (report.lossy) and exporter (check()), by name: the\n * Neo4j ones and, aliased, the shared ones it records (`LOSS` holds the generic pre-flight's).\n * @category Built-in formats\n */\nexport const NEO4J_LOSS = Object.freeze({\n /** `:IGNORE` columns skipped on import. */\n IGNORED_COLUMNS: IGNORED_COLUMNS_LOSS,\n /**\n * Neo4j relationships are always directed, so the edges of an undirected graph, and the undirected edges of a\n * mixed graph, read back as directed.\n */\n UNDIRECTED_AS_DIRECTED: UNDIRECTED_LOSS,\n /** A mutual pair written as two directed relationships without its mark. */\n MUTUAL_EXPANDED: MUTUAL_EXPANDED_CODE,\n /** An attribute with a role the format has no place for is written as a plain attribute; the role is lost. */\n ROLE_DROPPED: ROLE_DROPPED_CODE,\n /**\n * An edge attribute named `weight` that is not the graph's weight reads back as the edge weight, because the\n * Neo4j importer reads weights from the `weight` property by default.\n */\n WEIGHT_KEY_CLASH: WEIGHT_KEY_CLASH_CODE,\n /**\n * A node id that reads back as a different type, such as the text \"7\" as the number 7. Read the file with `ids:\n * \"string\"` or `ids: \"keep\"` to keep the type.\n */\n ID_TEXT_TYPE: ID_TEXT_TYPE_LOSS,\n /** Two node ids would be written as the same text (the number 5 and the text \"5\"); the save fails with E_INVALID_ID. */\n ID_TEXT_COLLISION: ID_TEXT_COLLISION_LOSS,\n /** The `weightColumn` name is already an edge attribute; the save fails. */\n WEIGHT_COLUMN_TAKEN: WEIGHT_COLUMN_TAKEN_LOSS,\n /** The `idColumn` name is already a node attribute; the save fails. */\n ID_COLUMN_TAKEN: ID_COLUMN_TAKEN_LOSS,\n /** Several stored-id properties; one becomes the `:ID` column. */\n MULTIPLE_ID_PROPERTIES: MULTIPLE_ID_PROPERTIES_LOSS,\n /** An integer-typed column with non-integral values written as double. */\n DECLARED_TYPE_CHANGED: DECLARED_TYPE_CHANGED_LOSS,\n /** A list item containing the array delimiter, which Neo4j cannot escape. */\n ARRAY_DELIMITER: ARRAY_DELIMITER_LOSS,\n});\n"],"names":["headerError","SHARED_MISSING_ID_CODE","SHARED_MISSING_ENDPOINT_CODE","SHARED_DUPLICATE_NODE_CODE","SHARED_ID_MERGED_CODE","SHARED_ROLE_TAKEN_CODE","SHARED_DANGLING_REFERENCE_CODE","NEO4J","idText","compatible","scalar","plan"],"mappings":";;;;;;AAsCA,MAAM,aAAkC,oBAAI,IAAI,CAAC,MAAM,SAAS,YAAY,UAAU,QAAQ,QAAQ,CAAC;AACvG,MAAM,cAAmC,oBAAI,IAAI,CAAC,MAAM,YAAY,QAAQ,CAAC;AAC7E,MAAM,gBAAgB;AACtB,MAAM,OAAO;AAgBN,SAAS,eAAe,OAA0B,OAAe,QAAsC;AAC1G,MAAI,eAAe;AACnB,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,UAAM,OAAO,MAAM,CAAC;AAEpB,QAAI,KAAK,SAAS,GAAG,KAAK,cAAc,KAAK,KAAK,KAAA,CAAM,GAAG;AACvD,UAAI,SAAS,CAAC,MAAM,MAAM;AACtB,eAAO;AAAA,MACX;AACA,qBAAe;AAAA,IACnB;AAAA,EACJ;AACA,SAAO,gBAAgB,WAAW,UAAa,eAAe,OAAO,OAAO,MAAM;AACtF;AASA,SAAS,eAAe,OAA0B,OAAe,QAAqC;AAClG,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,QAAI,CAAC,OAAO,CAAC,GAAG;AACZ,aAAO;AAAA,IACX;AACA,QAAI;AACA,uBAAiB,MAAM,CAAC,CAAC;AAAA,IAC7B,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AACA,SAAO;AACX;AAQO,SAAS,iBAAiB,MAA2B;AACxD,QAAM,UAAU,KAAK,KAAA;AACrB,QAAM,IAAI,KAAK,KAAK,OAAO;AAC3B,MAAI,MAAM,MAAM;AACZ,UAAMA,cAAY,MAAM,yBAAyB;AAAA,EACrD;AACA,QAAM,OAAO,EAAE,CAAC,EAAE,KAAA;AAClB,QAAM,UAAU,EAAE,CAAC,MAAM,SAAY,OAAO,EAAE,CAAC,EAAE,KAAA;AACjD,QAAM,QAAQ,EAAE,CAAC,MAAM,SAAY,OAAO,EAAE,CAAC,EAAE,KAAA;AAC/C,QAAM,UAAU,aAAa,MAAM,EAAE,CAAC,CAAC;AACvC,MAAI,YAAY,MAAM;AAClB,WAAO,aAAa,MAAM,MAAM,OAAO,OAAO;AAAA,EAClD;AACA,MAAI,QAAQ,WAAW,GAAG;AACtB,UAAMA,cAAY,MAAM,qBAAqB;AAAA,EACjD;AACA,QAAM,QAAQ,QAAQ,YAAA;AACtB,MAAI,WAAW,IAAI,KAAK,GAAG;AACvB,WAAO,gBAAgB,MAAM,MAAM,OAAyC,OAAO,OAAO;AAAA,EAC9F;AACA,MAAI,KAAK,WAAW,GAAG;AACnB,UAAMA,cAAY,MAAM,gCAAgC;AAAA,EAC5D;AACA,MAAI,UAAU,MAAM;AAChB,UAAMA,cAAY,MAAM,wDAAwD;AAAA,EACpF;AACA,SAAO,EAAE,MAAM,MAAM,MAAM,YAAY,MAAM,SAAS,OAAO,MAAM,QAAA;AACvE;AAUA,SAAS,aACL,MACA,MACA,OACA,SACW;AACX,MAAI,KAAK,WAAW,GAAG;AACnB,UAAMA,cAAY,MAAM,sBAAsB;AAAA,EAClD;AACA,MAAI,UAAU,QAAQ,QAAQ,OAAO,GAAG;AACpC,UAAMA,cAAY,MAAM,0CAA0C;AAAA,EACtE;AACA,SAAO,EAAE,MAAM,MAAM,MAAM,YAAY,MAAM,MAAM,OAAO,MAAM,QAAA;AACpE;AAWA,SAAS,gBACL,MACA,MACA,MACA,OACA,SACW;AACX,MAAI,UAAU,QAAQ,CAAC,YAAY,IAAI,IAAI,GAAG;AAC1C,UAAMA,cAAY,MAAM,+DAA+D,IAAI,EAAE;AAAA,EACjG;AACA,MAAI,KAAK,SAAS,KAAK,SAAS,QAAQ,SAAS,UAAU;AACvD,UAAMA,cAAY,MAAM,KAAK,IAAI,uCAAuC;AAAA,EAC5E;AACA,SAAO,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,OAAO,UAAU,KAAK,OAAO,OAAO,QAAA;AAC/E;AAQA,SAAS,aAAa,MAAc,MAAuD;AACvF,QAAM,8BAAc,IAAA;AACpB,MAAI,SAAS,UAAa,KAAK,KAAA,EAAO,WAAW,GAAG;AAChD,WAAO;AAAA,EACX;AACA,aAAW,QAAQ,KAAK,MAAM,GAAG,GAAG;AAChC,UAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,QAAI,QAAQ,GAAG;AACX,YAAMA,cAAY,MAAM,WAAW,KAAK,KAAA,CAAM,oBAAoB;AAAA,IACtE;AACA,UAAM,MAAM,KAAK,MAAM,GAAG,KAAK,EAAE,KAAA,EAAO,YAAA;AACxC,UAAM,QAAQ,KAAK,MAAM,QAAQ,CAAC,EAAE,KAAA;AACpC,QAAI,IAAI,WAAW,GAAG;AAClB,YAAMA,cAAY,MAAM,uBAAuB;AAAA,IACnD;AACA,YAAQ,IAAI,KAAK,KAAK;AAAA,EAC1B;AACA,SAAO;AACX;AAQA,SAASA,cAAY,MAAc,QAAkC;AACjE,SAAO,IAAI,iBAAiB,iBAAiB,gBAAgB,IAAI,MAAM,MAAM,IAAI;AAAA,IAC7E,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,EAAA,CACX;AACL;AAUO,SAAS,kBAAkB,MAAc,MAAc,OAA8B;AACxF,QAAM,OAAO,GAAG,IAAI,IAAI,IAAI;AAC5B,SAAO,UAAU,OAAO,OAAO,GAAG,IAAI,IAAI,KAAK;AACnD;ACjGO,MAAM,gBAAgB;AAMtB,MAAM,cAAc;AAMpB,MAAM,kBAAkB;AAQxB,MAAM,qBAAqB;AAM3B,MAAM,cAAc;AAMpB,MAAM,oBAAoB;AAM1B,MAAM,kBAAkBC;AAMxB,MAAM,wBAAwBC;AAM9B,MAAM,sBAAsBC;AAO5B,MAAM,0BAA0B;AAOhC,MAAM,sBAAsB;AAM5B,MAAM,iBAAiBC;AAMvB,MAAM,qBAAqB;AAO3B,MAAM,kBAAkBC;AAMxB,MAAM,oBAAoB;AAM1B,MAAM,oBAAoB;AAM1B,MAAM,0BAA0BC;AAMhC,MAAM,uBAAuB;AAGpC,MAAM,mCAA2D,IAA+B;AAAA,EAC5F;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAED,MAAMC,UAAQ;AAGd,MAAM,uBAAuB;AAE7B,MAAM,cAA0B;AAAA,EAC5B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,WAAW;AAAA,EACX,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ,EAAE,QAAQA,SAAO,IAAI,UAAU,OAAO,MAAM,MAAM,SAAS,WAAW,KAAA;AAClF;AAEA,MAAM,YAAwB;AAAA,EAC1B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ,EAAE,QAAQA,SAAO,IAAI,SAAS,OAAO,MAAM,MAAM,QAAQ,WAAW,KAAA;AAChF;AAEA,MAAM,gBAA4B;AAAA,EAC9B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ,EAAE,QAAQA,SAAO,IAAI,OAAO,OAAO,MAAM,MAAM,MAAM,WAAW,KAAA;AAC5E;AAEA,MAAM,mBAA+B;AAAA,EACjC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA;AAAA,EAEV,QAAQ,EAAE,QAAQA,SAAO,IAAI,OAAO,OAAO,MAAM,MAAM,MAAM,WAAW,KAAA;AAC5E;AAEA,MAAM,mBAAyD,EAAE,KAAK,aAAa,KAAK,SAAS,KAAK,OAAA;AA8DtG,MAAM,6BAAgD,OAAO,OAAO,CAAC,KAAK,GAAI,CAAC;AAO/E,SAAS,oBAAoB,SAA+D;AACxF,QAAM,IAAwB,WAAW,CAAA;AACzC,QAAM,iBAAiB,EAAE,kBAAkB;AAC3C,QAAM,aAAa,iBAAiB,cAAc;AAClD,MAAI,OAAO,mBAAmB,YAAY,eAAe,QAAW;AAChE,UAAM,IAAI;AAAA,MACN;AAAA,MACA,0BAA0B,KAAK,UAAU,cAAc,CAAC;AAAA,MACxD,EAAE,QAAQ,kBAAkB,OAAO,eAAA;AAAA,IAAe;AAAA,EAE1D;AACA,MAAI,mBAAmB,OAAO,EAAE,cAAc,QAAW;AACrD,UAAM,IAAI;AAAA,MACN;AAAA,MACA;AAAA,MACA,EAAE,QAAQ,kBAAkB,OAAO,eAAA;AAAA,IAAe;AAAA,EAE1D;AACA,QAAM,SAAS,kBAAkB;AAAA,IAC7B,WAAW,EAAE,aAAa;AAAA,IAC1B,OAAO,EAAE,SAAS;AAAA,IAClB,YAAY,2BAA2B,OAAO,CAAC,MAAM,MAAM,cAAc;AAAA,EAAA,CAC5E;AACD,MAAI,OAAO,cAAc,gBAAgB;AACrC,UAAM,IAAI;AAAA,MACN;AAAA,MACA,8DAA8D,KAAK,UAAU,cAAc,CAAC;AAAA,MAC5F;AAAA,QACI,QAAQ;AAAA,QACR,OAAO;AAAA,MAAA;AAAA,IACX;AAAA,EAER;AACA,SAAO;AAAA,IACH,OAAO,UAAU,SAAS,EAAE,KAAK;AAAA,IACjC,eAAe,UAAU,iBAAiB,EAAE,aAAa;AAAA,IACzD;AAAA,IACA;AAAA,EAAA;AAER;AAQA,SAAS,UAAU,MAAc,OAAwC;AACrE,MAAI,UAAU,UAAa,UAAU,MAAM;AACvC,WAAO,CAAA;AAAA,EACX;AACA,QAAM,OAAkB,MAAM,QAAQ,KAAK,IAAK,QAAsB,CAAC,KAAK;AAC5E,aAAW,QAAQ,MAAM;AACrB,QAAI,CAAC,cAAc,IAAI,GAAG;AACtB,YAAM,IAAI,iBAAiB,iBAAiB,UAAU,IAAI,oCAAoC;AAAA,QAC1F,QAAQ;AAAA,QACR,OAAO,OAAO;AAAA,MAAA,CACjB;AAAA,IACL;AAAA,EACJ;AACA,SAAO;AACX;AAMA,MAAM,aAAa;AAAA,EAAnB,cAAA;AACI,SAAQ,QAAQ,IAAI,YAAY,IAAI;AAEpC,SAAiB,6BAAa,IAAA;AAAA,EAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzD,OAAO,OAA8B;AACjC,QAAI,OAAO,KAAK,OAAO,IAAI,KAAK;AAChC,QAAI,SAAS,QAAW;AACpB,aAAO,KAAK,OAAO,OAAO;AAC1B,WAAK,OAAO,IAAI,OAAO,IAAI;AAAA,IAC/B;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,OAAe,MAAiD;AACpE,QAAI,SAAS,KAAK,MAAM,QAAQ;AAC5B,UAAI,OAAO,KAAK,MAAM,SAAS;AAC/B,aAAO,QAAQ,OAAO;AAClB,gBAAQ;AAAA,MACZ;AACA,YAAM,QAAQ,IAAI,YAAY,IAAI;AAClC,YAAM,IAAI,KAAK,KAAK;AACpB,WAAK,QAAQ;AAAA,IACjB;AACA,UAAM,WAAW,KAAK,MAAM,KAAK;AACjC,QAAI,aAAa,GAAG;AAChB,WAAK,MAAM,KAAK,IAAI;AACpB,aAAO;AAAA,IACX;AACA,WAAO,aAAa,OAAO,cAAc;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,OAAuB;AAC1B,WAAO,QAAQ,KAAK,MAAM,SAAS,KAAK,MAAM,KAAK,IAAI;AAAA,EAC3D;AACJ;AAMA,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAclB,YAAY,UAAqE,QAAgC;AATjH,SAAQ,SAAS;AAEjB,SAAQ,WAAW;AAQf,SAAK,WAAW;AAChB,QAAI,QAA4B;AAChC,eAAW,SAAS,QAAQ;AACxB,YAAM,SAAS,YAAY,KAAK;AAChC,UAAI,WAAW,MAAM;AACjB,gBAAQ;AACR;AAAA,MACJ;AACA,eAAS;AAAA,IACb;AACA,SAAK,QAAQ;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,QAAyC;AAChD,UAAM,EAAE,aAAa;AACrB,QAAI,aAAa,MAAM;AACnB,aAAO,EAAE,OAAA;AAAA,IACb;AACA,WAAO;AAAA,MACH;AAAA,MACA,YAAY,CAAC,SAAuB;AAChC,aAAK,WAAW;AAChB,iBAAS,KAAK,SAAS,MAAM,KAAK,KAAK;AAAA,MAC3C;AAAA,IAAA;AAAA,EAER;AAAA;AAAA,EAGA,cAAoB;AAChB,SAAK,UAAU,KAAK;AACpB,SAAK,WAAW;AAAA,EACpB;AACJ;AAMA,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2DrB,YACI,MACA,QACA,QACA,SACF;AAnDF,SAAiB,WAAW,IAAI,aAAA;AAGhC,SAAA,iBAAgC;AAEhC,SAAQ,eAA6B;AAErC,SAAQ,aAA2B;AAEnC,SAAQ,gBAA8B;AAEtC,SAAQ,mBAAiC;AAEzC,SAAQ,iBAAiB;AAGzB,SAAQ,YAAY;AAGpB,SAAQ,SAAoB,CAAA;AAG5B,SAAQ,QAA2B,CAAA;AAGnC,SAAiB,iBAAiC,CAAA;AAGlD,SAAiB,YAAsB,CAAA;AAGvC,SAAQ,eAAuC;AAG/C,SAAQ,WAAW;AAGnB,SAAiB,eAAkE,CAAA;AAe/E,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,UAAU,IAAI,UAAU,OAAO,GAAG;AACvC,SAAK,YAAY,IAAI,kBAAkB,MAAM,QAAQ,OAAO,gBAAgB;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,IACF,QACa;AACb,UAAM,WAAW,IAAI;AAAA,MACjB,KAAK,OAAO;AAAA,MACZ,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,IAAA;AAE7B,QAAI,UAA0B;AAC9B,eAAW,EAAE,OAAO,KAAA,KAAU,QAAQ;AAClC,WAAK,eAAe;AACpB,UAAI,YAAY,QAAQ,SAAS,QAAQ,QAAQ,SAAS,MAAM;AAE5D,kBAAU;AAAA,MACd;AACA,gBAAU,MAAM,KAAK;AAAA,QACjB;AAAA,QACA,EAAE,GAAG,SAAS,WAAW,KAAK,OAAO,MAAM,GAAG,UAAU,KAAK,OAAO,SAAA;AAAA,QACpE;AAAA,QACA,OAAO,SAAS;AAAA,MAAA;AAEpB,eAAS,YAAA;AAAA,IACb;AACA,QAAI,KAAK,iBAAiB,GAAG;AACzB,WAAK,OAAO;AAAA,QACR;AAAA,QACA,GAAG,KAAK,cAAc,kBAAkB,OAAO,KAAK,cAAc,CAAC,IAAI,MAAM,KAAK,gBAAgB,OAAO,MAAM,CAAC;AAAA,QAChH;AAAA,QACA,KAAK;AAAA,MAAA;AAAA,IAEb;AACA,SAAK,eAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,UACV,OACA,aACA,SACA,YACuB;AACvB,UAAM,SAAS,IAAI,aAAa,OAAO,KAAK,QAAQ,KAAK,QAAQ,QAAQ;AAAA,MACrE,GAAG;AAAA,MACH,YAAY;AAAA,IAAA,CACf;AACD,QAAI,UAA0B;AAC9B,QAAI,UAAU;AACd,QAAI,OAAO;AACX,QAAI,aAAa;AACjB,qBAAiB,SAAS,QAAQ;AAC9B,YAAM,EAAE,OAAO,OAAA,IAAW;AAC1B,UAAI,YAAY,KAAK,UAAU,KAAK,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,EAAE,KAAA,EAAO,WAAW,GAAG;AAE5E;AAAA,MACJ;AACA;AAEA,UAAI,YAAY,QAAQ,eAAe,OAAO,OAAO,MAAM,GAAG;AAC1D,kBAAU,KAAK,eAAe,QAAQ,KAAK;AAC3C,eAAO;AACP;AAAA,MACJ;AACA;AACA,UAAI,QAAQ,SAAS,QAAQ;AACzB,aAAK,QAAQ,SAAS,QAAQ,KAAK;AAAA,MACvC,OAAO;AACH,aAAK,gBAAgB,SAAS,QAAQ,KAAK;AAAA,MAC/C;AACA,UAAI,EAAE,cAAc,sBAAsB;AACtC,qBAAa;AACb,uBAAe,YAAY,MAAM;AAAA,MACrC;AAAA,IACJ;AACA,QAAI,YAAY,KAAK,YAAY,QAAQ,CAAC,YAAY;AAClD,WAAK,OAAO,KAAK,aAAa,+BAA+B,EAAE,MAAM,GAAG;AAAA,IAC5E;AAEA,QAAI,YAAY,SAAS;AACrB,aAAO;AAAA,IACX;AACA,WAAO,SAAS,IAAI,UAAU;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,eAAe,QAAsB,OAAwB;AACjE,UAAM,EAAE,SAAS;AACjB,UAAM,SAAwB,CAAA;AAC9B,QAAI;AACA,eAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,eAAO,KAAK,iBAAiB,OAAO,MAAM,CAAC,CAAC,CAAC;AAAA,MACjD;AACA,YAAM,4BAAY,IAAA;AAClB,aAAO,QAAQ,CAAC,OAAO,MAAM;AACzB,cAAM,OAAO,MAAM,IAAI,MAAM,IAAI;AACjC,YAAI,SAAS,QAAW;AACpB,gBAAM,IAAI,MAAM,MAAM,CAAC,CAAC,CAAC;AAAA,QAC7B,OAAO;AACH,eAAK,KAAK,CAAC;AAAA,QACf;AAAA,MACJ,CAAC;AACD,YAAM,MAAM,MAAM,IAAI,IAAI,KAAK,CAAA;AAC/B,YAAM,SAAS,MAAM,IAAI,UAAU,KAAK,CAAA;AACxC,YAAM,OAAO,MAAM,IAAI,QAAQ,KAAK,CAAA;AACpC,YAAM,SAAS,IAAI,SAAS;AAC5B,YAAM,iBAAiB,OAAO,SAAS,KAAK,KAAK,SAAS;AAC1D,UAAI,UAAU,gBAAgB;AAC1B,cAAM,YAAY,6CAA6C;AAAA,MACnE;AACA,UAAI,CAAC,UAAU,CAAC,gBAAgB;AAC5B,cAAM,OAAO,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,SAAS,QAAQ;AACvE,cAAM;AAAA,UACF,OACM,8MACA;AAAA,QAAA;AAAA,MAEd;AACA,UAAI,KAAK,iBAAiB,QAAQ,KAAK,kBAAkB,SAAS,SAAS,iBAAiB;AACxF,aAAK,OAAO;AAAA,UACR;AAAA,UACA;AAAA,UACA,KAAK,SAAS,SAAS,cAAc,8BAA8B,KAAK,iBAAiB,SAAS,UAAU,eAAe;AAAA,UAC3H,EAAE,KAAA;AAAA,QAAK;AAAA,MAEf;AACA,yBAAmB,MAAM;AACzB,WAAK,mBAAmB,MAAM,IAAI,QAAQ,KAAK,CAAA,GAAI;AACnD,UAAI,QAAQ;AACR,YAAI,IAAI,SAAS,GAAG;AAChB,gBAAM,YAAY,4CAA4C;AAAA,QAClE;AACA,YAAI,MAAM,IAAI,MAAM,GAAG;AACnB,gBAAM,YAAY,0CAA0C;AAAA,QAChE;AACA,eAAO,KAAK,mBAAmB,QAAQ,IAAI,CAAC,GAAG,MAAM,IAAI,OAAO,KAAK,CAAA,GAAI,IAAI;AAAA,MACjF;AACA,UAAI,OAAO,WAAW,KAAK,KAAK,WAAW,GAAG;AAC1C,cAAM,YAAY,0EAA0E;AAAA,MAChG;AACA,UAAI,MAAM,IAAI,OAAO,GAAG;AACpB,cAAM,YAAY,mDAAmD;AAAA,MACzE;AACA,YAAM,QAAQ,MAAM,IAAI,MAAM,KAAK,CAAA;AACnC,UAAI,MAAM,SAAS,GAAG;AAClB,cAAM,YAAY,sDAAsD;AAAA,MAC5E;AACA,aAAO,KAAK;AAAA,QACR;AAAA,QACA,OAAO,CAAC;AAAA,QACR,KAAK,CAAC;AAAA,QACN,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI;AAAA,QAChC;AAAA,MAAA;AAAA,IAER,SAAS,KAAK;AACV,UAAI,eAAe,oBAAoB,EAAE,eAAe,cAAc;AAElE,cAAM,QAAQ,CAAC,KAAK,KAAK,KAAM,GAAG,EAAE;AAAA,UAChC,CAAC,MAAM,MAAM,OAAO,aAAa,OAAO,MAAM,MAAM,GAAG,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAAA,QAAA;AAE3F,cAAM,OACF,UAAU,SACJ,KACA,iCAAiC,KAAK,UAAU,KAAK,CAAC;AAChE,aAAK,OAAO,KAAK,aAAa,GAAG,IAAI,OAAO,GAAG,IAAI,IAAI,EAAE,QAAQ,EAAE,OAAO,IAAI,MAAM;AAAA,MACxF;AACA,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,mBACJ,QACA,QACA,YACA,MACW;AACX,UAAM,UAAU,OAAO,MAAM;AAC7B,UAAM,cAAwB,CAAA;AAC9B,eAAW,SAAS,QAAQ;AACxB,iBAAW,CAAC,KAAK,KAAK,KAAK,MAAM,SAAS;AACtC,YAAI,QAAQ,WAAW,MAAM,SAAS,MAAM;AACxC,sBAAY,KAAK,KAAK;AAAA,QAC1B,OAAO;AACH,eAAK,OAAO;AAAA,YACR;AAAA,YACA;AAAA,YACA,iBAAiB,GAAG,IAAI,KAAK,QAAQ,MAAM,IAAI;AAAA,YAC/C,EAAE,MAAM,SAAS,MAAM,KAAA;AAAA,UAAK;AAAA,QAEpC;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,WAAW,SAAS,KAAK,YAAY,SAAS,GAAG;AACjD,WAAK,aAAA;AAAA,IACT;AACA,QAAI,QAAQ,UAAU,MAAM;AACxB,WAAK,cAAA;AAAA,IACT;AACA,QAAI,WAAyB;AAC7B,QAAI,QAAQ,KAAK,SAAS,GAAG;AACzB,iBAAW,KAAK;AAAA,QACZ;AAAA,QACA,EAAE,GAAG,SAAS,MAAM,KAAA;AAAA,QACpB;AAAA,QACA,EAAE,QAAQ,EAAE,QAAQA,SAAO,IAAI,QAAQ,MAAM,OAAO,MAAM,MAAM,MAAM,WAAW,QAAQ,QAAM;AAAA,QAC/F;AAAA,MAAA,EACF;AAAA,IACN;AACA,UAAM,aAAa,KAAK,kBAAkB,QAAQ,QAAQ,MAAM,IAAI;AACpE,WAAO;AAAA,MACH,MAAM;AAAA,MACN,OAAO,OAAO;AAAA,MACd;AAAA,MACA;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,WAAW,KAAK,SAAS,OAAO,QAAQ,KAAK;AAAA,MAC7C;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAER;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,2BACJ,QACA,WACA,SACA,UACA,MACmB;AACnB,eAAW,SAAS,QAAQ;AACxB,iBAAW,CAAC,KAAK,KAAK,KAAK,MAAM,SAAS;AACtC,aAAK,OAAO;AAAA,UACR;AAAA,UACA;AAAA,UACA,iBAAiB,GAAG,IAAI,KAAK,QAAQ,MAAM,IAAI;AAAA,UAC/C,EAAE,MAAM,SAAS,MAAM,KAAA;AAAA,QAAK;AAAA,MAEpC;AAAA,IACJ;AACA,QAAI,YAAY,GAAG;AACf,WAAK,WAAA;AAAA,IACT;AACA,UAAM,EAAE,eAAe,KAAK;AAC5B,QAAI,aAAa;AACjB,QAAI,eAAe,MAAM;AACrB,mBAAa,OAAO,UAAU,CAAC,UAAU,MAAM,SAAS,cAAc,MAAM,SAAS,UAAU;AAC/F,UAAI,cAAc,KAAK,eAAe,UAAU;AAC5C,aAAK,iBAAiB;AAAA,MAC1B;AAAA,IACJ;AACA,UAAM,aAAa,KAAK,kBAAkB,QAAQ,QAAQ,MAAM,UAAU;AAC1E,UAAM,EAAE,OAAO,eAAe,OAAO,SAAS;AAC9C,UAAM,EAAE,OAAO,aAAa,OAAO,OAAO;AAC1C,WAAO;AAAA,MACH,MAAM;AAAA,MACN,OAAO,OAAO;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB,eAAe,OAAO,IAAI,KAAK,SAAS,OAAO,UAAU;AAAA,MACzE,cAAc,aAAa,OAAO,IAAI,KAAK,SAAS,OAAO,QAAQ;AAAA,MACnE;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAER;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,kBACJ,QACA,QACA,MACA,UACc;AACd,UAAM,QAAwB,CAAA;AAC9B,WAAO,QAAQ,CAAC,OAAO,SAAS;AAC5B,UAAI,MAAM,SAAS,cAAc,SAAS,UAAU;AAChD;AAAA,MACJ;AACA,YAAM,KAAK,KAAK,gBAAgB,QAAQ,OAAO,MAAM,IAAI,IAAI,CAAC;AAAA,IAClE,CAAC;AACD,UAAM,QAAQ,OAAO;AACrB,QAAI,KAAK,OAAO,SAAS,OAAO;AAC5B,WAAK,SAAS,IAAI,MAAe,KAAK;AACtC,WAAK,QAAQ,IAAI,MAAqB,KAAK;AAAA,IAC/C;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,gBACJ,QACA,OACA,MACA,OACA,MACY;AACZ,UAAM,EAAE,MAAM,OAAA,IAAW;AACzB,UAAM,EAAE,eAAe,KAAK;AAC5B,UAAM,QAAmC;AAAA,MACrC,QAAQA;AAAAA,MACR,IAAI,MAAM;AAAA,MACV,OAAO;AAAA,MACP,MAAM,MAAM;AAAA,MACZ,WAAW;AAAA,MACX;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,IAAA;AAEtB,QAAI,WAA8B,iBAAiB,KAAK;AACxD,QAAI,OAAmB,EAAE,GAAG,SAAS,MAAM,GAAG,MAAA;AAC9C,QAAI;AACJ,QAAI;AACA,eAAS,UAAU,MAAM,QAAQ,IAAI;AAAA,IACzC,SAAS,KAAK;AACV,UAAI,EAAE,eAAe,qBAAqB,IAAI,SAAS,mBAAmB;AACtE,cAAM;AAAA,MACV;AACA,iBAAW,iBAAiB,EAAE,GAAG,OAAO,OAAO,QAAQ,MAAM,MAAM,GAAG;AACtE,aAAO,EAAE,GAAG,SAAS,MAAM,GAAG,OAAO,MAAM,SAAS,KAAK,KAAA;AACzD,eAAS,UAAU,MAAM,QAAQ,IAAI;AAAA,IACzC;AACA,eAAW,SAAS,SAAS,QAAQ;AACjC,aAAO,QAAQ,MAAM,UAAU,MAAM,MAAM,MAAM,SAAS,EAAE,MAAM,SAAS,MAAM,KAAA,CAAM;AAAA,IAC3F;AACA,WAAO;AAAA,MACH;AAAA,MACA,MAAM,KAAK;AAAA,MACX;AAAA,MACA,MAAM,SAAS;AAAA,MACf,eAAe,SAAS;AAAA,MACxB,WAAW;AAAA,IAAA;AAAA,EAEnB;AAAA;AAAA,EAGQ,eAAqB;AACzB,QAAI,KAAK,iBAAiB,eAAe;AACrC,WAAK,eAAe,KAAK,gBAAgB,QAAQ,WAAW;AAAA,IAChE;AAAA,EACJ;AAAA;AAAA,EAGQ,aAAmB;AACvB,QAAI,KAAK,eAAe,eAAe;AACnC,WAAK,aAAa,KAAK,gBAAgB,QAAQ,SAAS;AAAA,IAC5D;AAAA,EACJ;AAAA;AAAA,EAGQ,gBAAsB;AAC1B,QAAI,KAAK,kBAAkB,eAAe;AACtC,WAAK,gBAAgB,KAAK,gBAAgB,QAAQ,aAAa;AAC/D,WAAK,mBAAmB,KAAK,gBAAgB,QAAQ,gBAAgB;AAAA,IACzE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,gBAAgB,QAAyB,MAAgC;AAC7E,UAAM,EAAE,MAAM,OAAA,IAAW;AACzB,QAAI,UAAU;AACd,eAAS;AACL,UAAI;AACA,eAAO,UAAU,MAAM,QAAQ,OAAO;AAAA,MAC1C,SAAS,KAAK;AACV,YAAI,EAAE,eAAe,mBAAmB;AACpC,gBAAM;AAAA,QACV;AACA,YAAI,IAAI,SAAS,mBAAmB;AAChC,gBAAM,OAAO,iBAAiB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,CAAC;AAC7F,iBAAO;AAAA,YACH;AAAA,YACA;AAAA,YACA,WAAW,QAAQ,IAAI,iBAAiB,IAAI;AAAA,YAC5C,EAAE,SAAS,QAAQ,KAAA;AAAA,UAAK;AAE5B,oBAAU,EAAE,GAAG,SAAS,KAAA;AAAA,QAC5B,WAAW,IAAI,SAAS,oBAAoB;AACxC,iBAAO;AAAA,YACH;AAAA,YACA;AAAA,YACA,WAAW,QAAQ,IAAI,4BAA4B,OAAO,QAAQ,IAAI,CAAC;AAAA,YACvE,EAAE,SAAS,QAAQ,KAAA;AAAA,UAAK;AAE5B,gBAAM,EAAE,MAAM,OAAO,GAAG,gBAAgB;AACxC,oBAAU;AAAA,QACd,OAAO;AACH,gBAAM;AAAA,QACV;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,QAAQ,SAAsB,QAAsB,OAAqB;AAC7E,UAAM,EAAE,MAAM,OAAA,IAAW;AACzB,UAAM,EAAE,OAAO,QAAQ,KAAA,IAAS;AAChC,QAAI,UAAU,QAAQ,OAAO;AACzB,aAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA,WAAW,KAAK,QAAQ,OAAO,KAAK,CAAC,uBAAuB,QAAQ,KAAK;AAAA,QACzE,EAAE,KAAA;AAAA,MAAK;AAEX,aAAO,OAAO;AACd;AAAA,IACJ;AACA,UAAMC,UAAS,MAAM,QAAQ,MAAM;AACnC,QAAIA,QAAO,WAAW,KAAK,CAAC,OAAO,QAAQ,MAAM,GAAG;AAEhD,aAAO,MAAM,iBAAiB,iBAAiB,kBAAkB,EAAE,MAAM;AACzE,aAAO,OAAO;AACd;AAAA,IACJ;AACA,UAAM,UAAU,KAAK,SAASA,SAAQ,IAAI;AAC1C,QAAI,YAAY,QAAQ,CAAC,KAAK,gBAAgB,QAAQ,YAAY,OAAO,QAAQ,MAAMA,OAAM,GAAG;AAC5F,aAAO,OAAO;AACd;AAAA,IACJ;AACA,UAAM,KAAK,QAAQ,SAAS,QAAQ,KAAK;AACzC,QAAI;AACJ,QAAI,QAAQ,WAAW,SAAS,KAAK,QAAQ,YAAY,SAAS,GAAG;AACjE,eAAS,KAAK,SAAS,SAAS,OAAO,MAAM;AAAA,IACjD;AACA,SAAK,WAAW;AAChB,UAAM,UAAU,KAAK,QAAQ,EAAE,MAAM;AACrC,QAAI;AACJ,QAAI;AACA,cAAQ,KAAK,QAAQ,EAAE;AAAA,IAC3B,SAAS,KAAK;AACV,aAAO,YAAY,KAAK,EAAE,MAAM,SAASA,SAAQ;AACjD,aAAO,OAAO;AACd;AAAA,IACJ;AACA,UAAM,SAAS,KAAK,SAAS,QAAQ,OAAO,QAAQ,SAAS;AAC7D,QAAI,WAAW,aAAa;AACxB,aAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA,QAAQA,OAAM,4BAA4B,QAAQ,SAAS,QAAQ;AAAA,QACnE,EAAE,MAAM,SAASA,QAAA;AAAA,MAAO;AAE5B,aAAO,OAAO;AACd;AAAA,IACJ;AACA,QAAI,WAAW,aAAa;AACxB,aAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA,QAAQA,OAAM;AAAA,QACd;AAAA,UACI;AAAA,UACA,SAASA;AAAA,QAAA;AAAA,MACb;AAAA,IAER;AAEA,UAAM,MAAM,CAAC,QAAsB,UAAyB;AACxD,WAAK,QAAQ,MAAMA,SAAQ,MAAM;AAC7B,aAAK,aAAa,QAAQ,OAAO,KAAK;AAAA,MAC1C,CAAC;AAAA,IACL;AACA,QAAI,QAAQ,aAAa,eAAe;AACpC,UAAI,QAAQ,UAAUA,OAAM;AAAA,IAChC;AACA,QAAI,QAAQ,UAAU,MAAM;AACxB,UAAI,KAAK,eAAe,QAAQ,KAAK;AACrC,UAAI,KAAK,kBAAkBA,OAAM;AAAA,IACrC;AACA,QAAI,WAAW,QAAW;AACtB,UAAI,KAAK,cAAc,MAAM;AAAA,IACjC;AACA,SAAK,gBAAgB,QAAQ,QAAQ,YAAY,OAAO,MAAMA,OAAM;AACpE,SAAK,gBAAgB,MAAMA,OAAM;AAEjC,QAAI,CAAC,SAAS;AACV,aAAO,OAAO;AAAA,IAClB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,QAAQ,MAAc,SAAiB,OAAyB;AACpE,QAAI;AACA,YAAA;AAAA,IACJ,SAAS,KAAK;AACV,UAAI,EAAE,eAAe,qBAAqB,eAAe,aAAa;AAClE,cAAM;AAAA,MACV;AACA,WAAK,OAAO,YAAY,KAAK,EAAE,MAAM,SAAS;AAAA,IAClD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,iBAAuB;AAC3B,UAAM,WAAW,KAAK,aAAa,OAAO,CAAC,MAAM,KAAK,SAAS,OAAO,EAAE,KAAK,MAAM,CAAC;AAEpF,QAAI,SAAS,WAAW,KAAK,CAAC,KAAK,UAAU;AACzC;AAAA,IACJ;AACA,UAAM,QAAQ,SACT,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,OAAO,EAAE,EAAE,CAAC,EACvB,KAAK,IAAI;AACd,SAAK,OAAO;AAAA,MACR;AAAA,MACA;AAAA,MACA,GAAG,SAAS,MAAM,yBAAyB,OAAO,SAAS,MAAM,CAAC,IAAI,MAAM,SAAS,QAAQ,SAAS,MAAM,CAAC,kCAAkC,KAAK,GAAG,SAAS,SAAS,IAAI,UAAU,EAAE;AAAA,MACzL,EAAE,SAAS,OAAO,SAAS,CAAC,EAAE,EAAE,EAAA;AAAA,IAAE;AAAA,EAE1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,gBAAgB,SAA8B,QAAsB,OAAqB;AAC7F,UAAM,EAAE,MAAM,OAAA,IAAW;AACzB,UAAM,EAAE,OAAO,QAAQ,KAAA,IAAS;AAChC,QAAI,CAAC,KAAK,WAAW;AAGjB,WAAK,YAAY;AACjB,WAAK,UAAU,UAAU,MAAM,EAAE,MAAM;AAAA,IAC3C;AACA,QAAI,UAAU,QAAQ,OAAO;AACzB,aAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA,WAAW,KAAK,QAAQ,OAAO,KAAK,CAAC,uBAAuB,QAAQ,KAAK;AAAA,QACzE,EAAE,KAAA;AAAA,MAAK;AAEX,aAAO,OAAO;AACd;AAAA,IACJ;AACA,UAAM,YAAY,MAAM,QAAQ,SAAS;AACzC,UAAM,UAAU,MAAM,QAAQ,OAAO;AACrC,UAAM,eAAe,UAAU,WAAW,KAAK,CAAC,OAAO,QAAQ,SAAS;AACxE,QAAI,gBAAiB,QAAQ,WAAW,KAAK,CAAC,OAAO,QAAQ,OAAO,GAAI;AACpE,aAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA,SAAS,eAAe,cAAc,SAAS;AAAA,QAC/C;AAAA,UACI;AAAA,QAAA;AAAA,MACJ;AAEJ,aAAO,OAAO;AACd;AAAA,IACJ;AACA,UAAM,UAAU,GAAG,SAAS,KAAK,OAAO;AACxC,UAAM,QAAQ,KAAK,SAAS,WAAW,IAAI;AAC3C,UAAM,MAAM,UAAU,OAAO,OAAO,KAAK,SAAS,SAAS,IAAI;AAC/D,QAAI,UAAU,QAAQ,QAAQ,MAAM;AAChC,aAAO,OAAO;AACd;AAAA,IACJ;AACA,UAAM,SAAS,QAAQ,OAAO,QAAQ,UAAU;AAChD,UAAM,SAAS,QAAQ,KAAK,QAAQ,QAAQ;AAC5C,QAAI,aAA4B;AAChC,QAAI,KAAK,WAAW,QAAQ,QAAQ,cAAc,GAAG;AACjD,mBAAa;AAAA,IACjB,WAAW,KAAK,WAAW,QAAQ,QAAQ,YAAY,GAAG;AACtD,mBAAa;AAAA,IACjB;AACA,QAAI,eAAe,MAAM;AACrB,aAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA,YAAY,UAAU;AAAA,QACtB,EAAE,MAAM,QAAA;AAAA,MAAQ;AAEpB,aAAO,OAAO;AACd;AAAA,IACJ;AACA,QAAI;AACJ,QAAI,QAAQ,cAAc,GAAG;AACzB,UAAI;AACA,iBAAS,gBAAgB,MAAM,QAAQ,UAAU,GAAG,KAAK,MAAM;AAAA,MACnE,SAAS,KAAK;AACV,eAAO,YAAY,KAAK,EAAE,MAAM,SAAS;AACzC,eAAO,OAAO;AACd;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,CAAC,KAAK,gBAAgB,QAAQ,YAAY,OAAO,QAAQ,MAAM,OAAO,GAAG;AACzE,aAAO,OAAO;AACd;AAAA,IACJ;AACA,UAAM,UAAU,CAAC,QAAQ,MAAM,EAAE;AAAA,MAC7B,CAAC,IAAI,OAAO,MAAM,KAAK,OAAO,WAAW,KAAK,QAAQ,EAAE,MAAM;AAAA,IAAA;AAElE,QAAI;AACJ,QAAI;AACA,aAAO,KAAK,UAAU,QAAQ,QAAQ,QAAQ,YAAY,QAAQ,EAAE,MAAM,QAAA,CAAS;AAAA,IACvF,SAAS,KAAK;AACV,aAAO,YAAY,KAAK,EAAE,MAAM,SAAS;AACzC,aAAO,OAAO;AACd;AAAA,IACJ;AACA,eAAW,MAAM,SAAS;AAEtB,aAAO,OAAO;AACd,WAAK,aAAa,KAAK,EAAE,IAAI,OAAO,KAAK,QAAQ,EAAE,GAAG;AAAA,IAC1D;AACA,QAAI,QAAQ,YAAY,GAAG;AACvB,YAAM,OAAO,MAAM,QAAQ,QAAQ;AACnC,UAAI,KAAK,SAAS,GAAG;AACjB,aAAK,QAAQ,MAAM,SAAS,MAAM;AAC9B,eAAK,aAAa,KAAK,YAAY,MAAM,IAAI;AAAA,QACjD,CAAC;AAAA,MACL,OAAO;AACH,eAAO;AAAA,UACH;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,MAAM,QAAA;AAAA,QAAQ;AAAA,MAExB;AAAA,IACJ;AACA,SAAK,gBAAgB,QAAQ,QAAQ,YAAY,MAAM,MAAM,OAAO;AACpE,SAAK,gBAAgB,MAAM,OAAO;AAClC,WAAO,OAAO;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,WAAW,IAAY,WAA4B;AACvD,QAAI,cAAc,GAAG;AACjB,aAAO;AAAA,IACX;AACA,UAAM,QAAQ,KAAK,KAAK,QAAQ,EAAE;AAClC,QAAI,QAAQ,GAAG;AACX,aAAO;AAAA,IACX;AACA,UAAM,WAAW,KAAK,SAAS,OAAO,KAAK;AAC3C,WAAO,aAAa,KAAK,aAAa;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,SAAS,MAAc,MAA6B;AACxD,UAAM,EAAE,SAAS,OAAA,IAAW;AAC5B,QAAI;AACJ,QAAI;AACA,WAAK,QAAQ,KAAK,IAAI;AAAA,IAC1B,SAAS,KAAK;AACV,aAAO,YAAY,KAAK,EAAE,MAAM,SAAS,MAAM;AAC/C,aAAO;AAAA,IACX;AACA,UAAM,QAAQ,QAAQ;AACtB,QAAI,UAAU,MAAM;AAChB,aAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA,OAAO,MAAM,IAAI,kBAAkB,MAAM,YAAY,QAAQ,MAAM,EAAE;AAAA,QACrE,EAAE,MAAM,SAAS,KAAA;AAAA,MAAK;AAAA,IAE9B;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,gBACJ,OACA,OACA,QACA,MACA,SACO;AACP,UAAM,EAAE,QAAQ,OAAO,eAAA,IAAmB;AAC1C,mBAAe,SAAS;AACxB,SAAK,UAAU,SAAS;AACxB,eAAW,QAAQ,OAAO;AACtB,YAAM,OAAO,MAAM,KAAK,IAAI;AAC5B,YAAM,KAAK,IAAI,IAAI;AACnB,UAAI,KAAK,WAAW,GAAG;AACnB,eAAO,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,WAAW,KAAK,IAAI,IAAI;AAChE;AAAA,MACJ;AACA,YAAM,EAAE,SAAS;AACjB,UAAI;AACA,aAAK,UAAU,MAAM,IAAI;AAAA,MAC7B,SAAS,KAAK;AACV,aAAK,OAAO,YAAY,KAAK,EAAE,MAAM,SAAS,GAAG,OAAO,IAAI,KAAK,IAAI,GAAA,CAAI;AACzE,eAAO;AAAA,MACX;AACA,UAAI,UAAU,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG;AAC1C,aAAK,UAAU,KAAK,KAAK,IAAI;AAAA,MACjC;AACA,UAAI,KAAK,aAAa,eAAe,MAAM,IAAI,GAAG;AAC9C,uBAAe,KAAK,IAAI;AAAA,MAC5B;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,UAAU,MAAoB,MAAoB;AACtD,UAAM,EAAE,QAAQ,MAAA,IAAU;AAC1B,UAAM,EAAE,SAAS;AACjB,QAAI,KAAK,aAAa,QAAQ,CAAC,KAAK,MAAM;AACtC,YAAM,QAAQ,eAAe,MAAM,IAAI;AACvC,YAAM,SAAS,sBAAsB,OAAO,IAAI;AAChD,aAAO,KAAK,IAAI,IAAI,OAAO;AAE3B,YAAM,KAAK,IAAI,IAAI,UAAU,OAAO,OAAO,OAAO;AAAA,IACtD,OAAO;AACH,aAAO,KAAK,IAAI,IAAI,mBAAmB,MAAM,MAAM,KAAK,QAAQ,UAAU;AAC1E,sBAAgB,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI;AAAA,IACjD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,gBACJ,QACA,OACA,KACA,MACA,SACI;AACJ,UAAM,EAAE,MAAM,QAAQ,MAAA,IAAU;AAChC,eAAW,QAAQ,OAAO;AACtB,YAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,UAAI,UAAU,QAAW;AACrB;AAAA,MACJ;AACA,YAAM,OAAO,MAAM,KAAK,IAAI;AAE5B,WAAK,QAAQ,MAAM,GAAG,OAAO,IAAI,KAAK,IAAI,IAAI,MAAM;AAChD,YAAI,SAAS,QAAQ,KAAK,cAAc,iBAAiB,KAAK,kBAAkB,MAAM;AAClF,eAAK,YAAY,iBAAiB,MAAM,QAAQ,KAAK,aAAa;AAAA,QACtE;AACA,YAAI,WAAW,QAAQ;AACnB,eAAK,aAAa,KAAK,QAAQ,KAAK,KAAK;AACzC,cAAI,SAAS,MAAM;AACf,iBAAK,aAAa,KAAK,WAAW,KAAK,IAAI;AAAA,UAC/C;AAAA,QACJ,OAAO;AACH,eAAK,aAAa,KAAK,QAAQ,KAAK,KAAK;AACzC,cAAI,SAAS,MAAM;AACf,iBAAK,aAAa,KAAK,WAAW,KAAK,IAAI;AAAA,UAC/C;AAAA,QACJ;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAgB,MAAc,SAAuB;AACzD,eAAW,QAAQ,KAAK,gBAAgB;AACpC,WAAK,OAAO;AAAA,QACR;AAAA,QACA;AAAA,QACA,kBAAkB,KAAK,IAAI;AAAA,QAC3B,EAAE,MAAM,QAAA;AAAA,MAAQ;AAAA,IAExB;AACA,SAAK,eAAe,SAAS;AAC7B,eAAW,QAAQ,KAAK,WAAW;AAC/B,WAAK,OAAO;AAAA,QACR;AAAA,QACA;AAAA,QACA,iBAAiB,IAAI;AAAA,QACrB,EAAE,MAAM,QAAA;AAAA,MAAQ;AAAA,IAExB;AACA,SAAK,UAAU,SAAS;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,SAAS,SAAsB,OAA0B,QAAkD;AAC/G,QAAI;AACJ,eAAW,QAAQ,QAAQ,YAAY;AACnC,YAAM,OAAO,MAAM,IAAI;AACvB,UAAI,KAAK,WAAW,KAAK,CAAC,OAAO,IAAI,GAAG;AACpC;AAAA,MACJ;AACA,UAAI,WAAW,QAAW;AACtB,iBAAS,CAAA;AAAA,MACb;AACA,iBAAW,QAAQ,cAAc,MAAM,KAAK,QAAQ,UAAU,GAAG;AAC7D,YAAI,KAAK,SAAS,GAAG;AACjB,iBAAO,KAAK,IAAI;AAAA,QACpB;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,QAAQ,YAAY,SAAS,GAAG;AAChC,UAAI,WAAW,QAAW;AACtB,iBAAS,CAAA;AAAA,MACb;AACA,aAAO,KAAK,GAAG,QAAQ,WAAW;AAAA,IACtC;AACA,WAAO;AAAA,EACX;AACJ;AASA,SAAS,QAAQ,IAAY,OAA8B;AACvD,SAAO,UAAU,OAAO,KAAK,GAAG,KAAK,IAAI,OAAO,EAAE,CAAC;AACvD;AAGA,MAAM,iBAAsE;AAAA,EACxE,MAAM,CAAC,MAAM,GAAG;AAAA,EAChB,OAAO,CAAC,QAAQ,KAAK;AACzB;AAYA,SAAS,WAAW,MAAuB;AACvC,MAAI,mBAAmB,KAAK,IAAI,GAAG;AAC/B,WAAO;AAAA,EACX;AACA,QAAM,IAAI,6BAA6B,KAAK,IAAI;AAChD,MAAI,MAAM,QAAQ,EAAE,CAAC,MAAM,MAAO,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC,MAAM,QAAY;AAClE,WAAO;AAAA,EACX;AACA,SAAO,aAAa,EAAE,CAAC,GAAG,MAAM,KAAK,aAAa,EAAE,CAAC,KAAK,IAAI,KAAK;AACvE;AAGA,MAAM,qBAAqB;AAS3B,SAAS,aAAa,MAAc,OAAwB;AACxD,MAAI,OAAO,KAAK,YAAA;AAChB,MAAI,OAAO;AACX,SAAO,SAAS,IAAI;AAChB,UAAM,IAAI,6BAA6B,KAAK,IAAI;AAChD,UAAM,KAAK,MAAM,OAAO,KAAK,MAAM,QAAQ,EAAE,CAAC,GAAG,IAAI;AACrD,QAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,aAAO;AAAA,IACX;AACA,WAAO,KAAK;AACZ,WAAO,KAAK,MAAM,EAAE,CAAC,EAAE,MAAM;AAAA,EACjC;AACA,SAAO;AACX;AASA,SAAS,gBAAgB,MAAwB,OAAgB,MAAoB;AACjF,QAAM,OAAO,KAAK,SAAS,KAAA,EAAO,cAAc,QAAQ,SAAS,EAAE;AACnE,QAAM,QAAmB,KAAK,QAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC3E,QAAM,QAAQ,eAAe,IAAI;AACjC,aAAW,QAAQ,OAAO;AACtB,QAAI,MAAM;AACV,QAAI,UAAU,QAAW;AACrB,YAAM,OAAO,SAAS,aAAa,OAAO,MAAM,CAAC,KAAK,OAAO,MAAM,CAAC;AAAA,IACxE,WAAW,SAAS,QAAQ;AAExB,YAAM,OAAO,SAAS,YAAY,KAAK,WAAW;AAAA,IACtD,WAAW,SAAS,YAAY;AAC5B,YAAM,OAAO,SAAS,YAAY,CAAC,WAAW,KAAK,MAAM;AAAA,IAC7D;AACA,QAAI,KAAK;AACL,YAAM,OAAO,UAAU,SAAY,KAAK,KAAK,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC;AACpE,YAAM,IAAI,iBAAiB,iBAAiB,IAAI,IAAI,YAAY,YAAY,IAAI,CAAC,GAAG,IAAI,IAAI;AAAA,QACxF,OAAO;AAAA,QACP,MAAM;AAAA,MAAA,CACT;AAAA,IACL;AAAA,EACJ;AACJ;AAGA,MAAM,UAAU;AAUhB,SAAS,UAAU,MAAwB,OAAgB,MAAuB;AAC9E,MAAK,KAAK,SAAS,WAAW,KAAK,SAAS,YAAa,WAAW,KAAK,IAAI,GAAG;AAC5E,WAAO;AAAA,EACX;AACA,QAAM,QAAmB,KAAK,QAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC3E,SAAO,MAAM;AAAA,IACT,CAAC,MAAM,OAAO,MAAM,aAAa,CAAC,OAAO,SAAS,CAAC,KAAM,KAAK,SAAS,WAAW,KAAK,IAAI,CAAC,IAAI;AAAA,EAAA;AAExG;AAUA,SAAS,eAAe,MAAc,MAAgC;AAClE,QAAM,UAAU,KAAK,KAAA;AACrB,QAAM,OAAO,QAAQ,YAAY,GAAG;AACpC,MAAI,KAAK,aAAa,cAAc,OAAO,KAAK,CAAC,QAAQ,SAAS,GAAG,GAAG;AACpE,WAAO;AAAA,EACX;AACA,QAAM,QAAQ,QAAQ,MAAM,GAAG,IAAI;AACnC,QAAM,OAAO,QAAQ,MAAM,OAAO,GAAG,EAAE;AACvC,MAAI,SAAS,MAAM,KAAK,SAAS,GAAG,KAAK,qBAAqB,KAAK,KAAK,GAAG;AACvE,WAAO;AAAA,EACX;AACA,MAAI;AACJ,MAAI;AACA,aAAS,IAAI,KAAK,eAAe,SAAS,EAAE,UAAU,MAAM,cAAc,cAAc;AAAA,EAC5F,QAAQ;AACJ,UAAM,IAAI,iBAAiB,iBAAiB,IAAI,IAAI,gCAAgC,IAAI,IAAI,EAAE,OAAO,KAAA,CAAM;AAAA,EAC/G;AACA,MAAI,6BAA6B,KAAK,KAAK,GAAG;AAC1C,WAAO;AAAA,EACX;AACA,QAAM,OAAO,cAAc,OAAO,eAAe,EAAE;AACnD,QAAM,WAAW,CAAC,OAAuB;AACrC,UAAM,OAAO,OAAO,cAAc,IAAI,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,cAAc,GAAG,SAAS;AACjG,UAAM,IAAI,2BAA2B,KAAK,IAAI;AAC9C,QAAI,MAAM,MAAM;AACZ,aAAO;AAAA,IACX;AACA,YAAQ,EAAE,CAAC,MAAM,MAAM,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;AAAA,EACrE;AAEA,QAAM,UAAU,SAAS,OAAO,SAAS,IAAI,IAAI,GAAM;AACvD,QAAM,OAAO,UAAU,IAAI,MAAM;AACjC,QAAM,MAAM,KAAK,IAAI,OAAO;AAC5B,SAAO,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,KAAK,MAAM,MAAM,EAAE,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAC/G;AAQA,SAAS,WAAW,MAAiC;AACjD,MAAI,KAAK,MAAM;AACX,WAAO,CAAA;AAAA,EACX;AACA,MAAI,KAAK,SAAS,YAAY,KAAK,SAAS,YAAY;AACpD,WAAO;AAAA,EACX;AACA,SAAO;AACX;AAMA,SAAS,mBAAmB,QAAsC;AAC9D,QAAM,2BAAW,IAAA;AACjB,aAAW,SAAS,QAAQ;AACxB,QAAI,MAAM,KAAK,WAAW,KAAK,MAAM,SAAS,UAAU;AACpD;AAAA,IACJ;AACA,QAAI,KAAK,IAAI,MAAM,IAAI,GAAG;AACtB,YAAM,YAAY,aAAa,MAAM,IAAI,qBAAqB;AAAA,IAClE;AACA,SAAK,IAAI,MAAM,IAAI;AAAA,EACvB;AACJ;AAOA,SAAS,YAAY,QAAkC;AACnD,SAAO,IAAI,iBAAiB,iBAAiB,QAAQ,EAAE,QAAQ,UAAU;AAC7E;AAQA,SAAS,WAAW,MAA0B;AAC1C,QAAM,OAAO,IAAI,YAAY,SAAS,EAAE,OAAO,OAAO,WAAW,MAAA,CAAO,EAAE,OAAO,IAAI;AACrF,QAAM,MAAM,KAAK,OAAO,QAAQ;AAChC,QAAM,QAAQ,MAAM,IAAI,OAAO,KAAK,MAAM,GAAG,GAAG;AAChD,QAAM,QAAQ,MAAM,MAAM,SAAS;AACnC,SAAO,eAAe,OAAO,MAAM,MAAM,IAAI,OAAO;AACxD;AAMO,MAAM,gBAAmD,OAAO,OAAO;AAAA,EAC1E,QAAQD;AAAAA,EACR,SAAS,OAAO,OAAO,CAAC,kBAAkB,aAAa,SAAS,SAAS,eAAe,CAAC;AAAA,EACzF,YAAY,OAAO,OAAO,CAAC,QAAQ,MAAM,CAAC;AAAA,EAC1C,WAAW,OAAO,OAAO,CAAC,YAAY,2BAA2B,CAAC;AAAA,EAClE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQP,MAAM,OACF,OACA,MACA,SACqB;AACrB,UAAM,SAAS,qBAAqB,SAAS,EAAE,KAAK,aAAa,iBAAiB,MAAM,YAAY,UAAU;AAC9G,UAAM,SAAS,oBAAoB,OAAO;AAC1C,UAAM,SAAS,IAAI,oBAAoBA,SAAO,OAAO,UAAU;AAC/D,sBAAkB,MAAM,SAAS,MAAM;AAGvC,wBAAoB,SAAS,QAAQ,YAAY;AACjD,UAAM,UAAU,IAAI,mBAAmB,MAAM,QAAQ,QAAQ,MAAM;AACnE,UAAM,QAAQ,IAAI;AAAA,MACd,EAAE,OAAO,MAAM,KAAA;AAAA,MACf,GAAG,OAAO,MAAM,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,MAAM,OAAA,EAAkB;AAAA,MACtE,GAAG,OAAO,cAAc,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,MAAM,iBAA0B;AAAA,IAAA,CACzF;AACD,QAAI,QAAQ,mBAAmB,MAAM;AACjC,WAAK,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,QAAQ,eAAA,EAAe,GAAK;AAAA,IACjF;AACA,mBAAe,OAAO,MAAM;AAC5B,WAAO,OAAO,OAAA;AAAA,EAClB;AACJ,CAAC;AC9oDM,MAAM,kBAAkB;AAMxB,MAAM,oBAAoB;AAM1B,MAAM,yBAAyB;AAM/B,MAAM,2BAA2B;AAMjC,MAAM,uBAAuB;AAM7B,MAAM,8BAA8B;AAMpC,MAAM,6BAA6B;AAMnC,MAAM,uBAAuB;AAGpC,MAAM,aAAkC,oBAAI,IAAI,CAAC,QAAQ,UAAU,SAAS,CAAC;AAE7E,MAAM,QAAQ;AACd,MAAM,UAAU;AAGhB,MAAM,wBAAwB;AAG9B,MAAM,aAA+C,OAAO,OAAO;AAAA,EAC/D,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AACb,CAAC;AASM,MAAM,qBAAyC,aAAa;AAAA,EAC/D,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,SAAS;AAAA,EACT,WAAW;AAAA,EACX,QAAQ,CAAC,OAAO,OAAO,OAAO,QAAQ,QAAQ;AAAA,EAC9C,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,KAAK;AACT,CAAC;AAGD,MAAM,oCAAyC,IAAI;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAGD,MAAM,sCAA2C,IAAI;AAAA,EACjD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL;AAAA,EACA;AACJ,CAAC;AAGD,MAAM,sCAA2C,IAAI;AAAA,EACjD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAED,MAAM,iBAAsC,oBAAI,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC;AACnE,MAAM,QAA6B,oBAAI,IAAI,CAAC,OAAO,SAAS,eAAe,CAAC;AAsC5E,SAAS,0BACL,SACA,UAC0B;AAC1B,QAAM,IAAwB,WAAW,CAAA;AACzC,QAAM,OAAO,EAAE,QAAQ;AACvB,MAAI,CAAC,MAAM,IAAI,IAAI,GAAG;AAClB,UAAM,IAAI;AAAA,MACN;AAAA,MACA,gBAAgB,KAAK,UAAU,IAAI,CAAC;AAAA,MACpC;AAAA,QACI,QAAQ;AAAA,QACR,OAAO;AAAA,MAAA;AAAA,IACX;AAAA,EAER;AACA,QAAM,iBAAiB,EAAE,kBAAkB;AAC3C,MAAI,CAAC,eAAe,IAAI,cAAc,GAAG;AACrC,UAAM,IAAI;AAAA,MACN;AAAA,MACA,0BAA0B,KAAK,UAAU,cAAc,CAAC;AAAA,MACxD,EAAE,QAAQ,kBAAkB,OAAO,eAAA;AAAA,IAAe;AAAA,EAE1D;AACA,QAAM,YAAY,EAAE,aAAa;AACjC,QAAM,SAAS,EAAE,GAAG,kBAAkB,EAAE,WAAW,OAAO,EAAE,SAAS,IAAA,CAAK,GAAG,UAAA;AAC7E,MAAI,OAAO,cAAc,gBAAgB;AACrC,UAAM,IAAI;AAAA,MACN;AAAA,MACA,8DAA8D,KAAK,UAAU,cAAc,CAAC;AAAA,MAC5F;AAAA,QACI,QAAQ;AAAA,QACR,OAAO;AAAA,MAAA;AAAA,IACX;AAAA,EAER;AACA,QAAM,eAAe,EAAE,iBAAiB,SAAa,YAAY,WAAY,EAAE;AAC/E,MAAI,iBAAiB,SAAS,OAAO,iBAAiB,YAAY,aAAa,WAAW,IAAI;AAC1F,UAAM,IAAI,iBAAiB,iBAAiB,0DAA0D;AAAA,MAClG,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA,CACV;AAAA,EACL;AACA,QAAM,WAAW,EAAE,YAAY;AAC/B,MAAI,aAAa,SAAS,OAAO,aAAa,YAAY,SAAS,WAAW,IAAI;AAC9E,UAAM,IAAI,iBAAiB,iBAAiB,sDAAsD;AAAA,MAC9F,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA,CACV;AAAA,EACL;AACA,SAAO,EAAE,MAAM,QAAQ,gBAAgB,cAAc,SAAA;AACzD;AAMA,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiDb,YAAY,UAAyB,SAAqC,QAA+B;AAzCzG,SAAS,QAAoB,CAAA;AAG7B,SAAiB,WAAuB,CAAA;AAGxC,SAAQ,aAAsC;AAG9C,SAAQ,aAAsC;AAG9C,SAAQ,WAAoC;AAE5C,SAAS,cAA4B,CAAA;AAErC,SAAS,cAA4B,CAAA;AAGrC,SAAS,YAAsB,CAAA;AAuB3B,SAAK,WAAW;AAChB,SAAK,UAAU;AACf,SAAK,SAAS;AACd,SAAK,UAAU,SAAS,MAAM,OAAO,SAAS;AAC9C,SAAK,aAAa,CAAC,GAAG,SAAS,KAAK,EAAE,KAAK,CAAC,WAAW,SAAS,OAAO,IAAI,CAAC,KAAK;AACjF,SAAK,SAAS,SAAS,MAAM,OAAO,QAAQ;AAC5C,SAAK,OAAO,SAAS,MAAM,OAAO,MAAM;AACxC,eAAW,UAAU,SAAS,OAAO;AACjC,UAAI,WAAW,OAAO,IAAI,GAAG;AACzB,aAAK,UAAU,KAAK,MAAM;AAAA,MAC9B;AAAA,IACJ;AACA,UAAM,UAAU,kBAAkB,UAAU,oBAAoB,QAAQ;AAAA,MACpE,OAAO;AAAA,MACP,WAAW;AAAA,MACX,cAAc;AAAA,MACd,SAAS,QAAQ,iBAAiB;AAAA,IAAA,CACrC;AACD,SAAK,YAAY,QAAQ,SAAS,OAAO,KAAK,WAAW;AACzD,SAAK,YAAY,QAAQ,SAAS,OAAO,KAAK,WAAW;AACzD,SAAK,UAAU,KAAK,iBAAA;AACpB,SAAK,UAAU,YAAY,QAAQ;AACnC,SAAK,SAAA;AACL,SAAK,cAAA;AACL,SAAK,eAAA;AACL,SAAK,eAAA;AACL,UAAM,QAAQ,IAAI,IAAI,CAAC,KAAK,MAAM,KAAK,QAAQ,KAAK,OAAO,EAAE,QAAQ,CAAC,MAAO,MAAM,OAAO,CAAA,IAAK,CAAC,EAAE,KAAK,IAAI,CAAE,CAAC;AAC9G,SAAK,gBAAgB,SAAS,KAAK;AACnC,SAAK,MAAM,KAAK,GAAG,KAAK,QAAQ;AAChC,SAAK,kBAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAgB,SAA+C,OAAkC;AACrG,eAAW,OAAO,SAAS;AACvB,UAAI,IAAI,SAAS,KAAK,QAAQ,IAAI,WAAW,QAAQ,KAAK,eAAe,IAAI,MAAM,GAAG;AAClF;AAAA,MACJ;AACA,UAAI,IAAI,SAAS,KAAK,SAAS,IAAI,WAAW,QAAQ,MAAM,IAAI,IAAI,MAAM,GAAG;AAEzE;AAAA,MACJ;AACA,UAAI,IAAI,SAAS,KAAK,yBAAyB,KAAK,eAAe,MAAM;AACrE,aAAK,aAAa,IAAI,iBAAiB,cAAc,IAAI,SAAS,EAAE,QAAQ,mBAAmB;AAAA,MACnG;AACA,WAAK,IAAI,SAAS,KAAK,aAAa,IAAI,SAAS,KAAK,QAAQ,IAAI,WAAW,MAAM;AAG/E,aAAK,MAAM;AAAA,UACP,OAAO,OAAO;AAAA,YACV,MAAM,IAAI;AAAA,YACV,SAAS,gBAAgB,IAAI,MAAM;AAAA,YACnC,QAAQ,IAAI;AAAA,YACZ,OAAO,IAAI;AAAA,UAAA,CACd;AAAA,QAAA;AAEL;AAAA,MACJ;AACA,WAAK,MAAM,KAAK,GAAG;AAAA,IACvB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,iBAAuB;AAC3B,UAAM,EAAE,UAAU,QAAA,IAAY;AAC9B,QAAI,CAAC,SAAS,UAAU;AACpB,WAAK;AAAA,QACD;AAAA,QACA,iFAAiF,SAAS,SAAS,QAAQ,OAAO,SAAS,SAAS,CAAC;AAAA,QACrI;AAAA,QACA,SAAS;AAAA,MAAA;AAAA,IAEjB,WAAW,KAAK,OAAO,qBAAqB,SAAS;AACjD,UAAI,aAAa;AACjB,eAAS,IAAI,GAAG,IAAI,SAAS,WAAW,KAAK;AACzC,YAAI,CAAC,QAAQ,OAAO,CAAC,KAAK,CAAC,QAAQ,eAAe,CAAC,GAAG;AAClD;AAAA,QACJ;AAAA,MACJ;AACA,UAAI,aAAa,GAAG;AAChB,aAAK;AAAA,UACD;AAAA,UACA,GAAG,UAAU,mBAAmB,OAAO,UAAU,CAAC,IAAI,MAAM,YAAY,MAAM,KAAK,CAAC;AAAA,UACpF;AAAA,UACA;AAAA,QAAA;AAAA,MAER;AAAA,IACJ;AACA,QAAI,QAAQ,cAAc,GAAG;AACzB,WAAK;AAAA,QACD,KAAK;AAAA,QACL,GAAG,QAAQ,WAAW,eAAe,OAAO,QAAQ,WAAW,CAAC,IAAI,MAAM,QAAQ,aAAa,MAAM,KAAK,CAAC;AAAA,QAC3G;AAAA,QACA,QAAQ;AAAA,MAAA;AAAA,IAEhB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,KAAK,MAAc,SAAiB,SAAwB,MAAM,QAAuB,MAAY;AACzG,SAAK,SAAS,KAAK,OAAO,OAAO,EAAE,MAAM,SAAS,QAAQ,MAAA,CAAO,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,YAAY,QAAyB,OAAyB,KAAyB;AAC3F,UAAM,MAAM,CAAC,GAAG,KAAK;AACrB,UAAM,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC,WAAW,OAAO,KAAK,IAAI,CAAC;AAC3D,UAAM,mCAAmB,IAAA;AACzB,UAAM,iCAAiB,IAAA;AACvB,eAAW,UAAU,KAAK;AACtB,YAAM,SAAS,OAAO,KAAK,MAAM;AACjC,UAAI,OAAO,UAAU,YAAY,OAAO,WAAW,YAAY,MAAM,IAAI,MAAM,GAAG;AAC9E,qBAAa,IAAI,QAAQ,MAAM;AAC/B,mBAAW,IAAI,MAAM;AAAA,MACzB;AAAA,IACJ;AACA,eAAW,UAAU,KAAK;AACtB,YAAM,EAAE,SAAS;AACjB,YAAM,EAAE,SAAS;AACjB,UAAI,WAAW,IAAI,MAAM,KAAM,SAAS,QAAQ,cAAc,IAAI,IAAI,GAAI;AACtE;AAAA,MACJ;AACA,UACI,WAAW,WACV,WAAW,IAAI,KAAK,WAAW,KAAK,WAAW,WAAW,KAAK,UAAU,WAAW,KAAK,aAC5F;AACE;AAAA,MACJ;AACA,UAAI,WAAW,WAAW,SAAS,QAAQ,WAAW,KAAK,OAAO;AAC9D;AAAA,MACJ;AACA,UAAI,KAAK,KAAK,WAAW,QAAQ,aAAa,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC;AAAA,IACzE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,WAAW,QAAgB,WAAsC;AACrE,UAAM,EAAE,SAAS;AACjB,UAAM,WAAW,KAAK,QAAQ,QAAQ;AACtC,UAAM,SAAS,aAAa,OAAO,OAAO,gBAAgB,OAAO,UAAU,KAAK;AAChF,UAAM,QAAQ,GAAG,KAAK,MAAM,YAAY,KAAK,IAAI;AACjD,QAAI,KAAK,UAAU,QAAQ;AACvB,YAAM,YAAY,KAAK,aAAa;AACpC,YAAME,cACF,WAAW,QAAQ,OAAO,QAAQ,OAAO,cAAc,aAAa,OAAO,SAAS;AACxF,UAAIC,UAASD,cACP,EAAE,MAAM,eAAe,QAAkB,GAAG,MAAM,OAAO,MAAM,GAAG,UAAU,OAAO,SAAA,IACnF,cAAc,SAAS;AAC7B,UAAI,WAAW,QAAQ,OAAO,QAAQ,OAAO,SAAS,UAAU,cAAc,OAAO;AACjFC,kBAAS,KAAK,iBAAiB,QAAQ,eAAe,QAAkB,GAAG,KAAK;AAAA,MACpF;AACA,YAAM,iBAAiB,KAAK,kBAAkB;AAC9C,UAAI,iBAAiB,GAAG;AACpB,aAAK;AAAA,UACD,KAAK;AAAA,UACL,GAAG,KAAK,mBAAmB,cAAc;AAAA,UACzC,KAAK;AAAA,UACL,OAAO,SAAS,OAAO;AAAA,QAAA;AAAA,MAE/B;AACA,WAAK,gBAAgB,QAAQA,SAAQ,KAAK;AAC1C,aAAO;AAAA,QACH;AAAA,QACA,QAAQ,kBAAkB,KAAK,MAAM,GAAGA,QAAO,IAAI,MAAM,IAAI;AAAA,QAC7D,QAAAA;AAAAA,QACA,MAAM;AAAA,QACN;AAAA,MAAA;AAAA,IAER;AACA,QAAI;AACJ,UAAM,aAAa,WAAW,QAAQ,CAAC,OAAO,QAAQ,OAAO,UAAU,KAAK;AAC5E,QAAI,cAAc,OAAO,SAAS,QAAQ;AACtC,eAAS,KAAK,iBAAiB,QAAQ,UAAoB,KAAK;AAAA,IACpE,WAAW,YAAY;AACnB,eAAS,EAAE,MAAM,UAAoB,MAAM,OAAO,MAAM,GAAG,UAAU,OAAO,SAAA;AAAA,IAChF,OAAO;AACH,eAAS,cAAc,KAAK,KAAK;AAAA,IACrC;AAGA,UAAM,SAAS,KAAK,SAAS,cAAe,KAAK,SAAS,QAAQ,UAAU,KAAK,IAAI;AACrF,QAAI,UAAU,KAAK,UAAU,UAAU,OAAO,SAAS,SAAS;AAC5D,WAAK;AAAA,QACD,KAAK;AAAA,QACL,GAAG,KAAK;AAAA,QACR,KAAK;AAAA,QACL,OAAO,SAAS,OAAO;AAAA,MAAA;AAAA,IAE/B,WAAW,UAAU,KAAK,UAAU,UAAU,CAAC,mBAAmB,OAAO,SAAS,KAAK,KAAK,GAAG;AAC3F,WAAK;AAAA,QACD,KAAK;AAAA,QACL,GAAG,KAAK,OAAO,KAAK,KAAK;AAAA,QACzB,KAAK;AAAA,QACL,OAAO,SAAS,OAAO;AAAA,MAAA;AAAA,IAE/B;AACA,QAAI,KAAK,aAAa,GAAG;AACrB,UAAI,QAAQ;AACR,aAAK;AAAA,UACD,KAAK;AAAA,UACL,GAAG,KAAK,QAAQ,KAAK,UAAU;AAAA,UAC/B,KAAK;AAAA,UACL,OAAO,SAAS,OAAO;AAAA,QAAA;AAAA,MAE/B;AACA,aAAO;AAAA,QACH;AAAA,QACA,QAAQ,kBAAkB,KAAK,MAAM,GAAG,OAAO,IAAI,MAAM,IAAI;AAAA,QAC7D;AAAA,QACA,MAAM;AAAA,QACN;AAAA,MAAA;AAAA,IAER;AAEA,UAAM,UAAU,aAAa,QAAQ,KAAK,QAAQ,WAAW,SAAS,KAAK,UAAU;AACrF,UAAM,SAAS,UAAU,KAAK,OAAO,kBAAkB,KAAK,MAAM,OAAO,MAAM,IAAI;AACnF,WAAO,EAAE,QAAQ,QAAQ,QAAQ,MAAM,OAAO,UAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,iBAAiB,QAAgB,UAAkB,OAA2B;AAClF,QAAI,kBAAkB,MAAM,GAAG;AAC3B,aAAO,EAAE,MAAM,UAAU,MAAM,WAAW,UAAU,KAAA;AAAA,IACxD;AACA,SAAK;AAAA,MACD;AAAA,MACA,GAAG,KAAK,gBAAgB,QAAQ;AAAA,MAChC,OAAO,KAAK;AAAA,MACZ;AAAA,IAAA;AAEJ,WAAO,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,KAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,gBAAgB,QAAgB,QAAoB,OAAqB;AAC7E,QACI,OAAO,UAAU,UAChB,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU,OAAO,SAAS,SACzE;AACE;AAAA,IACJ;AACA,UAAM,EAAE,mBAAmB,KAAK;AAChC,QAAI,OAAO;AACX,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACpC,UAAI,CAAC,OAAO,MAAM,CAAC,GAAG;AAClB;AAAA,MACJ;AACA,iBAAW,QAAQ,OAAO,QAAQ,CAAC,GAAG;AAClC,YAAI,aAAa,MAAM,QAAQ,IAAI,EAAE,SAAS,cAAc,GAAG;AAC3D;AACA;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,OAAO,GAAG;AACV,WAAK;AAAA,QACD;AAAA,QACA,GAAG,KAAK,KAAK,IAAI,OAAO,OAAO,IAAI,CAAC,IAAI,MAAM,MAAM,SAAS,MAAM,CAAC,4CAA4C,cAAc;AAAA,QAC9H,OAAO,KAAK;AAAA,QACZ;AAAA,MAAA;AAAA,IAER;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAA2C;AAC/C,UAAM,EAAE,aAAa;AACrB,UAAM,OAAO,KAAK,QAAQ;AAC1B,QAAI,SAAS,MAAM;AACf,aAAO;AAAA,IACX;AACA,UAAM,UAAU,gBAAgB,QAAQ;AACxC,UAAM,QAAQ,KAAK,YAAY,KAAK,CAACC,UAASA,MAAK,OAAO,KAAK,SAAS,IAAI;AAC5E,QAAI,UAAU,UAAa,QAAQ,UAAU;AACzC,WAAK;AAAA,QACD;AAAA,QACA,gBAAgB,IAAI,4EAA4E,IAAI;AAAA,QACpG;AAAA,QACA;AAAA,MAAA;AAEJ,UAAI,KAAK,eAAe,MAAM;AAC1B,aAAK,aAAa,IAAI;AAAA,UAClB;AAAA,UACA,gBAAgB,IAAI;AAAA,UACpB,EAAE,QAAQ,MAAM,QAAQ,OAAA;AAAA,QAAO;AAAA,MAEvC;AAAA,IACJ,WAAW,UAAU,UAAa,SAAS,uBAAuB;AAC9D,WAAK;AAAA,QACD,KAAK;AAAA,QACL,gBAAgB,IAAI,qFAAqF,IAAI;AAAA,QAC7G;AAAA,QACA,MAAM,OAAO,SAAS,MAAM,OAAO;AAAA,MAAA;AAAA,IAE3C;AACA,WAAO,QAAQ,WAAW,UAAU;AAAA,EACxC;AAAA;AAAA,EAGQ,WAAiB;AACrB,UAAM,EAAE,QAAQ,KAAK;AACrB,QAAI,cAAc;AAClB,QAAI,aAAa;AACjB,YAAQ,IAAI,MAAA;AAAA,MACR,KAAK;AAAA,MACL,KAAK;AACD;AAAA,MACJ,KAAK;AACD,iBAAS,IAAI,GAAG,IAAI,IAAI,MAAM,KAAK;AAC/B,cAAI,CAAC,OAAO,cAAc,IAAI,KAAK,CAAC,CAAC,GAAG;AACpC;AAAA,UACJ;AAAA,QACJ;AACA;AAAA,MACJ,KAAK;AACD,iBAAS,IAAI,GAAG,IAAI,IAAI,MAAM,KAAK;AAC/B,cAAI,uBAAuB,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG;AAC7C;AAAA,UACJ;AAAA,QACJ;AACA;AAAA,MACJ,KAAK,SAAS;AACV,cAAM,2BAAW,IAAA;AACjB,iBAAS,IAAI,GAAG,IAAI,IAAI,MAAM,KAAK;AAC/B,gBAAM,KAAK,IAAI,KAAK,CAAC;AACrB,gBAAM,OAAO,OAAO,EAAE;AACtB,cAAI,OAAO,OAAO,WAAW,CAAC,OAAO,cAAc,EAAE,IAAI,uBAAuB,IAAI,GAAG;AACnF;AAAA,UACJ;AACA,cAAI,KAAK,IAAI,IAAI,GAAG;AAChB;AAAA,UACJ,OAAO;AACH,iBAAK,IAAI,IAAI;AAAA,UACjB;AAAA,QACJ;AACA;AAAA,MACJ;AAAA,MACA,SAAS;AACL,cAAM,OAAe,IAAI;AACzB,cAAM,IAAI,iBAAiB,iBAAiB,uBAAuB,IAAI,IAAI,EAAE,MAAM,MAAM;AAAA,MAC7F;AAAA,IAAA;AAEJ,QAAI,cAAc,GAAG;AACjB,WAAK;AAAA,QACD;AAAA,QACA,GAAG,WAAW,WAAW,OAAO,WAAW,CAAC;AAAA,QAC5C;AAAA,QACA;AAAA,MAAA;AAAA,IAER;AACA,QAAI,aAAa,GAAG;AAChB,WAAK;AAAA,QACD;AAAA,QACA,GAAG,UAAU,WAAW,OAAO,UAAU,CAAC,IAAI,MAAM,YAAY,UAAU,OAAO,CAAC;AAAA,QAClF;AAAA,QACA;AAAA,MAAA;AAEJ,WAAK,WAAW,IAAI;AAAA,QAChB;AAAA,QACA,GAAG,UAAU,WAAW,OAAO,UAAU,CAAC,IAAI,MAAM,YAAY,UAAU,OAAO,CAAC;AAAA,QAClF,EAAE,QAAQ,kBAAkB,OAAO,WAAA;AAAA,MAAW;AAAA,IAEtD;AAAA,EACJ;AAAA;AAAA,EAGQ,gBAAsB;AAC1B,UAAM,OAAO,KAAK,QAAQ;AAC1B,QAAI,SAAS,MAAM;AACf;AAAA,IACJ;AACA,UAAM,QACF,KAAK,YAAY,KAAK,CAACA,UAASA,MAAK,OAAO,KAAK,SAAS,IAAI,KAC9D,KAAK,UAAU,KAAK,CAAC,WAAW,OAAO,KAAK,SAAS,IAAI;AAC7D,QAAI,CAAC,OAAO;AACR;AAAA,IACJ;AACA,SAAK;AAAA,MACD;AAAA,MACA,gBAAgB,IAAI,8DAA8D,IAAI;AAAA,MACtF;AAAA,MACA;AAAA,IAAA;AAEJ,QAAI,KAAK,eAAe,MAAM;AAC1B,WAAK,aAAa,IAAI;AAAA,QAClB;AAAA,QACA,gBAAgB,IAAI;AAAA,QACpB,EAAE,QAAQ,MAAM,QAAQ,OAAA;AAAA,MAAO;AAAA,IAEvC;AAAA,EACJ;AAAA;AAAA,EAGQ,iBAAuB;AAC3B,QAAI,KAAK,UAAU,SAAS,GAAG;AAC3B;AAAA,IACJ;AACA,QAAI,QAAQ;AACZ,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,WAAW,KAAK;AAC9C,UAAI,MAAM;AACV,iBAAW,UAAU,KAAK,WAAW;AACjC,YAAI,OAAO,MAAM,CAAC,GAAG;AACjB;AAAA,QACJ;AAAA,MACJ;AACA,UAAI,MAAM,GAAG;AACT;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,QAAQ,GAAG;AACX,WAAK;AAAA,QACD;AAAA,QACA,GAAG,KAAK,QAAQ,OAAO,KAAK,CAAC,IAAI,MAAM,OAAO,OAAO,MAAM,CAAC;AAAA,QAC5D;AAAA,QACA;AAAA,MAAA;AAAA,IAER;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,eAAe,MAAuB;AAC1C,eAAWA,SAAQ,CAAC,GAAG,KAAK,aAAa,GAAG,KAAK,WAAW,GAAG;AAC3D,UAAIA,MAAK,OAAO,KAAK,SAAS,QAAQA,MAAK,OAAO,SAAS,SAAS;AAChE,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA,EAGQ,oBAA0B;AAC9B,UAAM,EAAE,SAAS,KAAK;AACtB,QAAI,SAAS,OAAO;AAChB;AAAA,IACJ;AACA,UAAM,EAAE,aAAa;AACrB,UAAM,OAAO,KAAK,MAAM,OAAO,CAAC,MAAM;AAClC,UAAI,SAAS,SAAS;AAClB,YAAI,gBAAgB,IAAI,EAAE,IAAI,GAAG;AAC7B,iBAAO;AAAA,QACX;AACA,eAAO,EAAE,WAAW,QAAQ,CAAC,SAAS,MAAM,IAAI,EAAE,MAAM,KAAK,SAAS,MAAM,IAAI,EAAE,MAAM;AAAA,MAC5F;AACA,UAAI,gBAAgB,IAAI,EAAE,IAAI,GAAG;AAC7B,eAAO;AAAA,MACX;AACA,aAAO,EAAE,WAAW,QAAQ,CAAC,SAAS,MAAM,IAAI,EAAE,MAAM,KAAK,SAAS,MAAM,IAAI,EAAE,MAAM;AAAA,IAC5F,CAAC;AACD,SAAK,MAAM,SAAS;AACpB,SAAK,MAAM,KAAK,GAAG,IAAI;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,QAAiC;AACjC,QAAI,KAAK,aAAa,MAAM;AACxB,aAAO,KAAK;AAAA,IAChB;AACA,UAAM,EAAE,SAAS,KAAK;AACtB,QAAI,SAAS,mBAAmB,KAAK,eAAe,MAAM;AACtD,aAAO,KAAK;AAAA,IAChB;AACA,WAAO,SAAS,UAAU,OAAO,KAAK;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,OAA8B;AAClC,UAAM,EAAE,YAAY;AACpB,QAAI,CAAC,SAAS,MAAM,KAAK,GAAG;AACxB,aAAO;AAAA,IACX;AACA,UAAM,QAAQ,QAAQ,MAAM,KAAK;AACjC,WAAO,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAS,OAAuB;AAC5B,UAAM,EAAE,eAAe;AACvB,QAAI,eAAe,QAAQ,WAAW,MAAM,KAAK,KAAK,KAAK,QAAQ,KAAK,MAAM,MAAM;AAChF,aAAO,OAAO,YAAY,KAAK;AAAA,IACnC;AACA,WAAO,OAAO,KAAK,SAAS,IAAI,KAAK,KAAK,CAAC;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,OAA8B;AACrC,eAAW,UAAU,KAAK,WAAW;AACjC,UAAI,OAAO,MAAM,KAAK,GAAG;AACrB,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,CAAC,QAA4C;AACzC,eAAW,OAAO,KAAK,QAAQ;AAC3B,YAAM,IAAI;AAAA,IACd;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,CAAC,OAAgD;AAC7C,QAAI,KAAK,UAAU,MAAM;AACrB,YAAM,KAAK;AAAA,IACf;AACA,UAAM,EAAE,SAAS,KAAK;AACtB,QAAI,SAAS,iBAAiB;AAC1B,aAAO,KAAK,UAAA;AAAA,IAChB;AACA,QAAI,SAAS,SAAS;AAClB,aAAO,KAAK,kBAAA;AAAA,IAChB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAqB;AAEjB,UAAM,4BAAY,IAAA;AAClB,UAAM,4BAAY,IAAA;AAClB,QAAI,UAAqC;AACzC,eAAW,OAAO,KAAK,QAAQ;AAC3B,UAAI,IAAI,SAAS,MAAM;AACnB,YAAI,OAAO,MAAM,IAAI,IAAI,IAAI;AAC7B,YAAI,SAAS,QAAW;AACpB,cAAI,OAAO,GAAG,IAAI,KAAK,IAAI;AAC3B,cAAI,IAAI;AACR,iBAAO,MAAM,IAAI,IAAI,GAAG;AACpB,mBAAO,GAAG,IAAI,KAAK,IAAI,IAAI,CAAC;AAC5B;AAAA,UACJ;AACA,gBAAM,IAAI,IAAI;AACd,iBAAO,EAAE,MAAM,MAAM,IAAI,KAAK,MAAM,MAAM,GAAC;AAC3C,gBAAM,IAAI,IAAI,MAAM,IAAI;AAAA,QAC5B;AACA,kBAAU;AAAA,MACd,WAAW,YAAY,MAAM;AACzB,gBAAQ,KAAK,KAAK,IAAI,IAAI;AAAA,MAC9B;AAAA,IACJ;AAEA,UAAM,UAAU,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,CAAA,EAAG,CAAC,GAAG,MAAM,EAAE,KAAK,SAAS,KAAM,MAAM,KAAK,MAAM,SAAS,CAAE;AAClG,WAAO,QAAQ;AAAA,MAAI,CAAC,CAAC,QAAQ,CAAC,MAC1B,OAAO,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,MAAM,SAAS,EAAE,KAAK,KAAK,EAAE,EAAA,CAAG;AAAA,IAAA;AAAA,EAEpF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,CAAS,YAAqD;AAC1D,UAAM,EAAE,aAAa;AACrB,QAAI,WAAW;AACf,QAAI,eAA8B;AAClC,QAAI,gBAA+B;AACnC,aAAS,IAAI,GAAG,IAAI,SAAS,WAAW,KAAK;AACzC,YAAM,QAAQ,KAAK,QAAQ,CAAC;AAC5B,YAAM,SAAS,KAAK,WAAW,CAAC;AAChC,YAAM,SAAS,WAAW,OAAQ,KAAK,QAAQ,YAAY,KAAM,OAAO,KAAK;AAC7E,UAAI,aAAa,KAAK,UAAU,gBAAgB,WAAW,eAAe;AACtE;AACA,uBAAe;AACf,wBAAgB;AAChB,cAAM,KAAK,WAAW,QAAQ,OAAO,SAAS,MAAM;AAAA,MACxD;AACA,YAAM,EAAE,MAAM,KAAK,QAAQ,CAAC,GAAG,MAAM,KAAA;AAAA,IACzC;AACA,QAAI,aAAa,GAAG;AAEhB,YAAM,KAAK,WAAW,KAAK,QAAQ,YAAY,IAAI,MAAM,IAAI;AAAA,IACjE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,WAAW,QAAgB,OAAsB,SAAqC;AAC1F,UAAM,EAAE,UAAA,IAAc,KAAK,QAAQ;AACnC,UAAM,SAAS,CAAC,kBAAkB,QAAQ,SAAS,KAAK,CAAC;AACzD,QAAI,KAAK,WAAW,MAAM;AACtB,aAAO,KAAK,QAAQ;AAAA,IACxB;AACA,UAAM,aAAa,KAAK,YAAY,IAAI,CAACA,UAASA,MAAK,MAAM,EAAE,KAAK,SAAS;AAC7E,QAAI,WAAW,SAAS,GAAG;AACvB,aAAO,KAAK,UAAU;AAAA,IAC1B;AACA,WAAO,EAAE,MAAM,GAAG,OAAO,KAAK,SAAS,CAAC;AAAA,GAAM,MAAM,EAAE,MAAM,SAAS,MAAM,SAAS,SAAS,SAAS,IAAI,IAAE;AAAA,EAChH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,QAAQ,GAAmB;AAC/B,UAAM,QAAQ,CAAC,KAAK,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC;AAC1C,QAAI,KAAK,WAAW,MAAM;AACtB,YAAM,KAAK,KAAK,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC;AAAA,IAC5C;AACA,eAAWA,SAAQ,KAAK,aAAa;AACjC,YAAM,KAAK,KAAK,KAAK,KAAK,UAAUA,OAAM,CAAC,CAAC,CAAC;AAAA,IACjD;AACA,WAAO,GAAG,MAAM,KAAK,KAAK,QAAQ,OAAO,SAAS,CAAC;AAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,CAAS,oBAA6D;AAClE,UAAM,EAAE,UAAU,QAAA,IAAY;AAC9B,UAAM,OAAO,SAAS,SAAA;AACtB,QAAI,WAAW;AACf,QAAI,eAA8B;AAClC,QAAI,aAA4B;AAChC,aAAS,IAAI,GAAG,IAAI,SAAS,WAAW,KAAK;AACzC,UAAI,QAAQ,OAAO,CAAC,GAAG;AACnB;AAAA,MACJ;AACA,YAAM,IAAI,KAAK,IAAI,CAAC;AACpB,YAAM,IAAI,KAAK,IAAI,CAAC;AACpB,YAAM,aAAa,KAAK,QAAQ,CAAC;AACjC,YAAM,WAAW,KAAK,QAAQ,CAAC;AAC/B,UAAI,aAAa,KAAK,eAAe,gBAAgB,aAAa,YAAY;AAC1E;AACA,uBAAe;AACf,qBAAa;AACb,cAAM,KAAK,mBAAmB,YAAY,QAAQ;AAAA,MACtD;AACA,YAAM,EAAE,MAAM,KAAK,gBAAgB,GAAG,GAAG,CAAC,GAAG,MAAM,KAAA;AAAA,IACvD;AACA,QAAI,aAAa,GAAG;AAChB,YAAM,KAAK,mBAAmB,MAAM,IAAI;AAAA,IAC5C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,mBAAmB,YAA2B,UAAsC;AACxF,UAAM,EAAE,UAAA,IAAc,KAAK,QAAQ;AACnC,UAAM,SAAS,CAAC,kBAAkB,IAAI,YAAY,UAAU,GAAG,kBAAkB,IAAI,UAAU,QAAQ,CAAC;AACxG,QAAI,KAAK,SAAS,MAAM;AACpB,aAAO,KAAK,OAAO;AAAA,IACvB;AACA,QAAI,KAAK,YAAY,MAAM;AACvB,aAAO,KAAK,kBAAkB,KAAK,QAAQ,gBAAgB,UAAU,UAAU,IAAI,CAAC;AAAA,IACxF;AACA,UAAM,aAAa,KAAK,YAAY,IAAI,CAACA,UAASA,MAAK,MAAM,EAAE,KAAK,SAAS;AAC7E,QAAI,WAAW,SAAS,GAAG;AACvB,aAAO,KAAK,UAAU;AAAA,IAC1B;AACA,WAAO;AAAA,MACH,MAAM,GAAG,OAAO,KAAK,SAAS,CAAC;AAAA;AAAA,MAC/B,MAAM,EAAE,MAAM,iBAAiB,MAAM,SAAS,iBAAiB,YAAY,QAAQ,EAAA;AAAA,IAAE;AAAA,EAE7F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,gBAAgB,GAAW,GAAW,GAAmB;AAC7D,UAAM,EAAE,MAAM,QAAA,IAAY;AAC1B,UAAM,QAAQ,CAAC,KAAK,KAAK,KAAK,SAAS,CAAC,CAAC,GAAG,KAAK,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC;AACvE,QAAI,SAAS,MAAM;AACf,YAAM,KAAK,KAAK,KAAK,KAAK,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,IAAI,CAAC;AAAA,IAChE;AACA,QAAI,YAAY,MAAM;AAClB,YAAM,KAAK,KAAK,KAAK,QAAQ,KAAK,CAAC,CAAC,CAAC;AAAA,IACzC;AACA,eAAWA,SAAQ,KAAK,aAAa;AACjC,YAAM,KAAK,KAAK,KAAK,KAAK,UAAUA,OAAM,CAAC,CAAC,CAAC;AAAA,IACjD;AACA,WAAO,GAAG,MAAM,KAAK,KAAK,QAAQ,OAAO,SAAS,CAAC;AAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,KAAK,MAA6B;AACtC,QAAI,SAAS,MAAM;AACf,aAAO;AAAA,IACX;AACA,UAAM,EAAE,MAAA,IAAU,KAAK,QAAQ;AAC/B,QAAI,KAAK,WAAW,GAAG;AACnB,aAAO,QAAQ;AAAA,IACnB;AACA,WAAO,aAAa,MAAM,KAAK,QAAQ,OAAO,WAAW,KAAK;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,WAAW,OAA8B;AAC7C,UAAM,EAAE,WAAW;AACnB,QAAI,CAAC,QAAQ,MAAM,KAAK,GAAG;AACvB,aAAO;AAAA,IACX;AACA,QAAI,OAAO,UAAU,QAAQ;AACzB,aAAO,OAAO,QAAQ,KAAK,EAAE,IAAI,MAAM,EAAE,KAAK,KAAK,QAAQ,cAAc;AAAA,IAC7E;AACA,WAAO,OAAO,QAAQ,KAAK;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,UAAUA,OAAkB,KAA4B;AAC5D,UAAM,EAAE,QAAQ,QAAQ,UAAA,IAAcA;AACtC,QAAI,CAAC,OAAO,MAAM,GAAG,GAAG;AACpB,aAAO;AAAA,IACX;AACA,QAAIA,MAAK,MAAM;AACX,aAAO,KAAK,SAASA,OAAM,GAAG;AAAA,IAClC;AACA,UAAM,OAAO,WAAW,MAAM,GAAG,IAAI,OAAO,WAAW,GAAG,IAAI;AAC9D,WAAO,aAAa,OAAO,UAAU,SAAS,OAAO,OAAO,GAAG,IAAI,OAAO,MAAM,GAAG,GAAG,QAAQ,IAAI;AAAA,EACtG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,SAASA,OAAkB,KAAqB;AACpD,UAAM,EAAE,QAAQ,OAAA,IAAWA;AAC3B,UAAM,QAAQ,OAAO,UAAU,SAAS,OAAO,QAAQ,GAAG,IAAK,OAAO,MAAM,GAAG;AAC/E,UAAM,QAAkB,CAAA;AACxB,eAAW,QAAQ,MAAM,KAAK,KAAK,GAAG;AAElC,UAAI,MAAM,QAAQ,IAAI,KAAK,YAAY,OAAO,IAAI,GAAG;AACjD,mBAAW,aAAa,MAAM,KAAK,IAA0B,GAAG;AAC5D,gBAAM,KAAK,aAAa,WAAW,QAAQ,IAAI,CAAC;AAAA,QACpD;AAAA,MACJ,OAAO;AACH,cAAM,KAAK,aAAa,MAAM,QAAQ,IAAI,CAAC;AAAA,MAC/C;AAAA,IACJ;AACA,WAAO,MAAM,KAAK,KAAK,QAAQ,cAAc;AAAA,EACjD;AACJ;AAOA,SAAS,SAAS,MAA2B;AACzC,SACI,KAAK,SAAS,QACd,KAAK,UAAU,YACf,KAAK,WAAW,QAChB,KAAK,OAAO,WAAW,SACvB,KAAK,OAAO,OAAO,SACnB,KAAK,OAAO,SAAS;AAE7B;AAOA,SAAS,WAAW,MAA2B;AAC3C,SACI,KAAK,SAAS,QACd,KAAK,UAAU,YACf,KAAK,WAAW,QAChB,KAAK,OAAO,WAAW,SACvB,KAAK,OAAO,SAAS;AAE7B;AAOA,SAAS,UAAU,MAAuB;AACtC,SAAO,SAAS,WAAW,SAAS,UAAU,SAAS,WAAW,SAAS;AAC/E;AAOA,SAAS,eAAe,UAA0B;AAC9C,QAAM,UAAU,SAAS,KAAA;AACzB,SAAO,QAAQ,SAAS,IAAI,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AAC3D;AAOA,SAAS,OAAO,MAAkC;AAC9C,UAAQ,KAAK,MAAA;AAAA,IACT,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,SAAS;AACL,YAAM,OAAe,KAAK;AAC1B,YAAM,IAAI,iBAAiB,iBAAiB,sBAAsB,IAAI,IAAI,EAAE,MAAM,MAAM;AAAA,IAC5F;AAAA,EAAA;AAER;AAOA,SAAS,cAAc,OAAwC;AAC3D,UAAQ,OAAA;AAAA,IACJ,KAAK;AACD,aAAO,EAAE,MAAM,SAAS,MAAM,SAAS,UAAU,KAAA;AAAA,IACrD,KAAK;AACD,aAAO,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,KAAA;AAAA,IACvD,KAAK;AAAA,IACL,KAAK;AACD,aAAO,EAAE,MAAM,OAAO,MAAM,WAAW,UAAU,KAAA;AAAA,IACrD,KAAK;AACD,aAAO,EAAE,MAAM,QAAQ,MAAM,WAAW,UAAU,KAAA;AAAA,IACtD,KAAK;AACD,aAAO,EAAE,MAAM,WAAW,MAAM,WAAW,UAAU,KAAA;AAAA,IACzD,KAAK;AAAA,IACL,KAAK;AACD,aAAO,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,KAAA;AAAA,IACvD,KAAK;AACD,aAAO,EAAE,MAAM,UAAU,MAAM,QAAQ,UAAU,KAAA;AAAA,IACrD,KAAK;AACD,aAAO,EAAE,MAAM,UAAU,MAAM,QAAQ,UAAU,KAAA;AAAA,IACrD,SAAS;AACL,YAAM,OAAe;AACrB,YAAM,IAAI,iBAAiB,iBAAiB,iBAAiB,IAAI,IAAI,EAAE,OAAO,MAAM;AAAA,IACxF;AAAA,EAAA;AAER;AAQA,SAAS,eAAe,OAAgB,QAAuC;AAC3E,SAAO,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI,OAAO,KAAK;AACnE;AASA,SAAS,aAAa,OAAgB,QAAoB,MAA6B;AACnF,UAAQ,OAAO,MAAA;AAAA,IACX,KAAK;AACD,aAAO,eAAe,OAAO,aAAa;AAAA,IAC9C,KAAK;AACD,aAAO,eAAe,OAAO,SAAS;AAAA,IAC1C,KAAK;AACD,aAAO,eAAe,OAAO,SAAS;AAAA,IAC1C,KAAK;AACD,aAAO,UAAU,OAAO,SAAS;AAAA,IACrC,KAAK;AACD,aAAO,OAAO,KAAK;AAAA,IACvB,KAAK;AACD,aACI,QACA;AAAA,QAAe;AAAA,QAAO,CAAC,MACnB,OAAO,aAAa,OAAO,OAAO,CAAC,IAAI,eAAe,GAAG,OAAO,QAAQ;AAAA,MAAA;AAAA,IAGpF,KAAK;AACD,aAAO,YAAY,KAAK;AAAA,IAC5B,KAAK;AACD,aAAO,KAAK,UAAU,KAAK,KAAK;AAAA,IACpC,SAAS;AACL,YAAM,OAAe,OAAO;AAC5B,YAAM,IAAI,iBAAiB,iBAAiB,qBAAqB,IAAI,IAAI,EAAE,MAAM,MAAM;AAAA,IAC3F;AAAA,EAAA;AAER;AAQA,SAAS,YAAY,OAAwB;AACzC,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AACrE,WAAO,KAAK,UAAU,KAAK,KAAK;AAAA,EACpC;AACA,QAAM,QAAkB,CAAA;AACxB,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAgC,GAAG;AACxE,QAAI,OAAO,SAAS,UAAU;AAC1B,YAAM,KAAK,GAAG,GAAG,IAAI,UAAU,IAAI,CAAC,EAAE;AAAA,IAC1C,WAAW,OAAO,SAAS,UAAU;AACjC,YAAM,KAAK,GAAG,GAAG,KAAK,KAAK,WAAW,KAAK,EAAE,CAAC,GAAG;AAAA,IACrD,OAAO;AACH,aAAO,KAAK,UAAU,KAAK,KAAK;AAAA,IACpC;AAAA,EACJ;AACA,SAAO,IAAI,MAAM,KAAK,IAAI,CAAC;AAC/B;AAOA,SAAS,OAAO,IAAoB;AAChC,MAAI,OAAO,OAAO,UAAU;AACxB,WAAO;AAAA,EACX;AACA,SAAO,OAAO,UAAU,EAAE,IAAI,cAAc,EAAE,IAAI,OAAO,EAAE;AAC/D;AAQA,SAAS,OAAO,QAAgB,KAAqB;AACjD,UAAQ,OAAO,OAAA;AAAA,IACX,KAAK;AACD,aAAO,OAAO,QAAQ,GAAG;AAAA,IAC7B,KAAK;AACD,aAAO,OAAO,OAAO,MAAM,GAAG,CAAC;AAAA,IACnC,KAAK;AACD,aAAO,OAAO,QAAQ,GAAG,EAAE,IAAI,MAAM,EAAE,KAAK,GAAG;AAAA,IACnD,KAAK;AACD,aAAO,KAAK,UAAU,OAAO,OAAO,GAAG,CAAC,KAAK;AAAA,IACjD,KAAK;AACD,aAAO,OAAO,MAAM,GAAG,MAAM,OAAO,SAAS;AAAA,IACjD,SAAS;AACL,YAAM,QAAQ,OAAO,MAAM,GAAG;AAC9B,aAAO,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI,MAAM,KAAK,KAA0B,EAAE,KAAK,GAAG;AAAA,IACtG;AAAA,EAAA;AAER;AAMO,MAAM,gBAAmD,OAAO,OAAO;AAAA,EAC1E,QAAQ;AAAA,EACR,SAAS,OAAO,OAAO,CAAC,kBAAkB,aAAa,YAAY,QAAQ,SAAS,cAAc,CAAC;AAAA,EACnG,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOd,MAAM,UAAyB,SAAyE;AACpG,WAAO,OAAO,OAAO,CAAC,GAAG,KAAK,UAAU,OAAO,EAAE,KAAK,CAAC;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,UAAyB,SAA+E;AAC3G,WAAO,aAAa,KAAK,UAAU,OAAO,EAAE,OAAO;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,UAAyB,SAAqE;AACzG,WAAO,SAAS,KAAK,UAAU,OAAO,EAAE,OAAO;AAAA,EACnD;AACJ,CAAC;AA4BD,SAAS,SAAS,MAAc,OAAsB,QAA+B;AACjF,QAAM,QAAQ,CAAC,MAAM,SAAS,IAAI,UAAU,EAAE,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AACtE,SAAO,MAAM,KAAK,GAAG,EAAE,WAAW,YAAY,GAAG;AACrD;AAsBO,SAAS,iBACZ,UACA,SACoB;AACpB,MAAI;AACA,WAAO,QAAQ,QAAQ,KAAK,UAAU,OAAO,EAAE,OAAO;AAAA,EAC1D,SAAS,KAAK;AACV,WAAO,QAAQ,OAAO,GAAG;AAAA,EAC7B;AACJ;AAQA,SAAS,KAAK,UAAyB,SAA6E;AAChH,SAAO,IAAI;AAAA,IACP;AAAA,IACA,0BAA0B,SAAS,iBAAiB,QAAQ,CAAC;AAAA,IAC7D,qBAAqB,OAAO;AAAA,EAAA;AAEpC;AAOA,SAAS,iBAAiB,UAAwC;AAC9D,QAAM,QAAS,SAAS,KAAK,OAA2D;AACxF,QAAM,OAAO,OAAO;AACpB,SAAO,OAAO,SAAS,YAAY,SAAS,KAAK,OAAO;AAC5D;AAOA,SAAS,kBAAkB,QAAyB;AAChD,MAAI,OAAO,UAAU,OAAO;AACxB,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACpC,UAAI,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,UAAU,OAAO,KAAK,CAAC,CAAC,GAAG;AACtD,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,EACJ,WAAW,OAAO,UAAU,UAAU,OAAO,MAAM,UAAU,OAAO;AAChE,UAAM,EAAE,SAAS,OAAO;AACxB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,UAAI,CAAC,OAAO,UAAU,KAAK,CAAC,CAAC,GAAG;AAC5B,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,EACJ;AACA,SAAO;AACX;ACj+CO,MAAM,cAAc,OAAO,OAAO;AAAA,EACrC,GAAG;AAAA,EACH,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA,EAKH,aAAa;AAAA;AAAA,EAEb,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA,EAKd,kBAAkB;AAAA;AAAA,EAElB,mBAAmB;AAAA;AAAA,EAEnB,kBAAkB;AAAA;AAAA,EAElB,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpB,WAAW;AAAA;AAAA,EAEX,QAAQ;AAAA;AAAA,EAER,cAAc;AAAA;AAAA,EAEd,YAAY;AAAA;AAAA,EAEZ,kBAAkB;AAAA;AAAA,EAElB,gBAAgB;AAAA;AAAA,EAEhB,oBAAoB;AAAA;AAAA,EAEpB,gBAAgB;AAAA;AAAA,EAEhB,WAAW;AAAA;AAAA,EAEX,uBAAuB;AAAA;AAAA,EAEvB,mBAAmB;AAAA;AAAA,EAEnB,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,EAKX,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKhB,YAAY;AAAA;AAAA,EAEZ,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKhB,aAAa;AAAA;AAAA,EAEb,cAAc;AAAA;AAAA,EAEd,cAAc;AAAA;AAAA,EAEd,oBAAoB;AACxB,CAAC;AAOM,MAAM,aAAa,OAAO,OAAO;AAAA;AAAA,EAEpC,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjB,wBAAwB;AAAA;AAAA,EAExB,iBAAiB;AAAA;AAAA,EAEjB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA,EAKd,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKlB,cAAc;AAAA;AAAA,EAEd,mBAAmB;AAAA;AAAA,EAEnB,qBAAqB;AAAA;AAAA,EAErB,iBAAiB;AAAA;AAAA,EAEjB,wBAAwB;AAAA;AAAA,EAExB,uBAAuB;AAAA;AAAA,EAEvB,iBAAiB;AACrB,CAAC;"}
|
|
1
|
+
{"version":3,"file":"neo4j.js","sources":["../src/formats/neo4j/header.ts","../src/formats/neo4j/importer.ts","../src/formats/neo4j/exporter.ts","../src/formats/neo4j/index.ts"],"sourcesContent":["/**\n * The neo4j-admin import header grammar (research note 07 section 2.6): every header cell is\n * `<name>:<field type>(<id space>){<options>}` where the name and every later part are optional.\n * The field types `ID`, `LABEL`, `START_ID`, `END_ID`, `TYPE` and `IGNORE` are structural; any\n * other field type is a property type of design section 5.1 (`int`, `long`, `float`, `double`,\n * `boolean`, `byte`, `short`, `char`, `string`, `point`, `date`, `localtime`, `time`,\n * `localdatetime`, `datetime`, `duration`, each with an optional `[]` suffix); a cell without a\n * colon is a string property. An id space may follow `ID`, `START_ID` and `END_ID`; brace options\n * (`label`, `id-type`) may follow any structural type.\n */\n\nimport { GraphFormatError } from \"@graphty/graph-format\";\n\n/**\n * The structural field types and the marker for a property column.\n * @category Plugin helpers\n */\nexport type FieldKind = \"ID\" | \"LABEL\" | \"START_ID\" | \"END_ID\" | \"TYPE\" | \"IGNORE\" | \"PROPERTY\";\n\n/**\n * One parsed header cell.\n * @category Plugin helpers\n */\nexport interface HeaderField {\n /** The cell text as written. */\n readonly text: string;\n /** The property name (the id property name for `name:ID`); empty when none. */\n readonly name: string;\n /** The field kind. */\n readonly kind: FieldKind;\n /** The property type text for a PROPERTY field (null when the cell declares none); null otherwise. */\n readonly type: string | null;\n /** The id space of an ID / START_ID / END_ID field, or null. */\n readonly space: string | null;\n /** The brace options, keys lower-cased. */\n readonly options: ReadonlyMap<string, string>;\n}\n\nconst STRUCTURAL: ReadonlySet<string> = new Set([\"ID\", \"LABEL\", \"START_ID\", \"END_ID\", \"TYPE\", \"IGNORE\"]);\nconst SPACE_KINDS: ReadonlySet<string> = new Set([\"ID\", \"START_ID\", \"END_ID\"]);\nconst HEADER_MARKER = /^[^:{}()]*:\\s*(ID|START_ID|END_ID)\\s*(\\(|\\{|$)/i;\nconst CELL = /^([^:(){}]*)(?::([^:(){}]*))?(?:\\(([^)]*)\\))?(?:\\{([^}]*)\\})?$/;\n\n/**\n * Whether a record looks like a section header: some cell declares an `ID`, `START_ID` or `END_ID`\n * field. The neo4j-admin convention allows several files, each with its own header; graphty's\n * single-file convention (the CSVDataSource of graphty-element) concatenates sections, so a header\n * may appear anywhere. Mid-file, a quoted marker cell (`\"ref:id\"`) is data unless the whole record\n * is quoted (a QUOTE_ALL export writes its headers that way) and every cell is a valid header cell.\n * ponytail: a fully quoted data row whose every cell is a valid header cell and one of them a marker\n * (`\"1\",\"ref:id\"`) still reads as a header; telling them apart would need the section's column names.\n * @param cells - the record's cells\n * @param count - how many cells are valid\n * @param quoted - which cells were quoted, or undefined to look at every cell (the first record)\n * @returns true when the record is a header\n * @category Plugin helpers\n */\nexport function isHeaderRecord(cells: readonly string[], count: number, quoted?: readonly boolean[]): boolean {\n let quotedMarker = false;\n for (let i = 0; i < count; i++) {\n const cell = cells[i];\n // every header marker holds a colon; the includes keeps the regex off the data rows\n if (cell.includes(\":\") && HEADER_MARKER.test(cell.trim())) {\n if (quoted?.[i] !== true) {\n return true;\n }\n quotedMarker = true;\n }\n }\n return quotedMarker && quoted !== undefined && isQuotedHeader(cells, count, quoted);\n}\n\n/**\n * Whether a record is fully quoted and every cell parses as a header cell.\n * @param cells - the record's cells\n * @param count - how many cells are valid\n * @param quoted - which cells were quoted\n * @returns true when the record reads as a quoted header\n */\nfunction isQuotedHeader(cells: readonly string[], count: number, quoted: readonly boolean[]): boolean {\n for (let i = 0; i < count; i++) {\n if (!quoted[i]) {\n return false;\n }\n try {\n parseHeaderField(cells[i]);\n } catch {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Parse one header cell.\n * @param text - the cell text\n * @returns the field; E_UNSUPPORTED (reason \"header\") for a cell outside the grammar\n * @category Plugin helpers\n */\nexport function parseHeaderField(text: string): HeaderField {\n const trimmed = text.trim();\n const m = CELL.exec(trimmed);\n if (m === null) {\n throw headerError(text, \"not a neo4j header cell\");\n }\n const name = m[1].trim();\n const rawType = m[2] === undefined ? null : m[2].trim();\n const space = m[3] === undefined ? null : m[3].trim();\n const options = parseOptions(text, m[4]);\n if (rawType === null) {\n return untypedField(text, name, space, options);\n }\n if (rawType.length === 0) {\n throw headerError(text, \"an empty field type\");\n }\n const upper = rawType.toUpperCase();\n if (STRUCTURAL.has(upper)) {\n return structuralField(text, name, upper as Exclude<FieldKind, \"PROPERTY\">, space, options);\n }\n if (name.length === 0) {\n throw headerError(text, \"a property column needs a name\");\n }\n if (space !== null) {\n throw headerError(text, \"an id space is only allowed on ID, START_ID and END_ID\");\n }\n return { text, name, kind: \"PROPERTY\", type: rawType, space: null, options };\n}\n\n/**\n * The field of a cell with no type: `name` alone is a string property.\n * @param text - the whole cell, for errors\n * @param name - the property name\n * @param space - the id space, or null\n * @param options - the options\n * @returns the field\n */\nfunction untypedField(\n text: string,\n name: string,\n space: string | null,\n options: ReadonlyMap<string, string>,\n): HeaderField {\n if (name.length === 0) {\n throw headerError(text, \"an empty header cell\");\n }\n if (space !== null || options.size > 0) {\n throw headerError(text, \"an id space or options need a field type\");\n }\n return { text, name, kind: \"PROPERTY\", type: null, space: null, options };\n}\n\n/**\n * The field of a cell with a structural type (ID, START_ID, END_ID, LABEL, TYPE, IGNORE).\n * @param text - the whole cell, for errors\n * @param name - the property name, or empty\n * @param kind - the structural kind\n * @param space - the id space, or null\n * @param options - the options\n * @returns the field\n */\nfunction structuralField(\n text: string,\n name: string,\n kind: Exclude<FieldKind, \"PROPERTY\">,\n space: string | null,\n options: ReadonlyMap<string, string>,\n): HeaderField {\n if (space !== null && !SPACE_KINDS.has(kind)) {\n throw headerError(text, `an id space is only allowed on ID, START_ID and END_ID, not ${kind}`);\n }\n if (name.length > 0 && kind !== \"ID\" && kind !== \"IGNORE\") {\n throw headerError(text, `a ${kind} field cannot be stored as a property`);\n }\n return { text, name, kind, type: null, space: space === \"\" ? null : space, options };\n}\n\n/**\n * Parse the `{key:value, key:value}` options of a header cell.\n * @param text - the whole cell, for errors\n * @param body - the text between the braces, or undefined when absent\n * @returns the options with lower-cased keys\n */\nfunction parseOptions(text: string, body: string | undefined): ReadonlyMap<string, string> {\n const options = new Map<string, string>();\n if (body === undefined || body.trim().length === 0) {\n return options;\n }\n for (const part of body.split(\",\")) {\n const colon = part.indexOf(\":\");\n if (colon < 0) {\n throw headerError(text, `option \"${part.trim()}\" is not key:value`);\n }\n const key = part.slice(0, colon).trim().toLowerCase();\n const value = part.slice(colon + 1).trim();\n if (key.length === 0) {\n throw headerError(text, \"an option needs a key\");\n }\n options.set(key, value);\n }\n return options;\n}\n\n/**\n * The error of a malformed header cell.\n * @param text - the cell\n * @param reason - why\n * @returns the error\n */\nfunction headerError(text: string, reason: string): GraphFormatError {\n return new GraphFormatError(\"E_UNSUPPORTED\", `header cell \"${text}\": ${reason}`, {\n reason: \"header\",\n cell: text,\n detail: reason,\n });\n}\n\n/**\n * Write a header cell from its parts, the inverse of parseHeaderField.\n * @param name - the property name, or empty\n * @param type - the field type or property type\n * @param space - the id space, or null\n * @returns the cell text\n * @category Plugin helpers\n */\nexport function formatHeaderField(name: string, type: string, space: string | null): string {\n const base = `${name}:${type}`;\n return space === null ? base : `${base}(${space})`;\n}\n","/**\n * The Neo4j importer (design sections 8.4 and 5.1, research note 07 sections 2.6 and 2.10): reads\n * neo4j-admin import CSV -- node tables with `:ID`, `:LABEL` and typed property columns,\n * relationship tables with `:START_ID`, `:END_ID`, `:TYPE` and typed property columns -- and pushes\n * scalars into the sink one record at a time. Input is one or more files: the primary input plus the\n * `nodes` and `relationships` option inputs, each read in order; every input holds one or more\n * sections, each starting with its own header row (the single-file convention of graphty-element's\n * CSVDataSource, where a node table and a relationship table follow each other in one file).\n *\n * Mapping (design section 5.1 and decision Q27):\n * - Property columns are declared up front from the header types (`int` -> i32, `long` -> f64\n * with a precision issue beyond 2^53, `float` -> f32, `double` -> f64, `boolean` -> bool,\n * `string` / `char` / `duration` -> string, temporal types -> f64 milliseconds with a `.text`\n * companion when the source text is not canonical, `point` -> json, `type[]` -> list); an\n * untyped column is a string property. An unquoted empty cell is \"property not set\"; a quoted\n * empty cell is an empty string (or an empty list), as neo4j-admin stores it by default.\n * - `:LABEL` becomes the node list-of-dict column `labels` (role `labels`); `:TYPE` the edge dict\n * column `type` (role `kind`); an id space `:ID(Space)` the node dict column `idSpace` (role\n * `idSpace`), and a stored id `name:ID(Space)` also a string node column `name` whose\n * `origin.namespace` is the space. A property whose name collides with one of those is renamed\n * `<name>#<name>` (design section 5.6).\n * - Id spaces: neo4j-admin keeps one id space per `:ID(Space)` name, so `1` in `:ID(Product)` and\n * `1` in `:ID(Category)` are two nodes. The core has one id space, so a node of a spaced section\n * is stored under the string id `Space:id` (every row of the section, collision or not, so an id\n * never depends on file order), its id text goes into the node string column `originalId` and\n * its space into `idSpace`. The column has no role: the `originalId` role means an id rewritten by\n * `sanitizeIds: \"mangle\"`, which other importers restore as the node id. `:START_ID(Space)` /\n * `:END_ID(Space)` endpoints are qualified the same way before the lookup; an endpoint without a\n * space is looked up as written.\n * - Ids are text cells coerced by the `ids` option (\"canonical\" by default, so `1` is the number 1\n * and `007` stays a string; integers beyond 2^53 stay strings). Relationships are always directed\n * (\"In Neo4j, all relationships have a direction\"), so the sink is set directed before the first\n * edge and `onMixedDirection: \"undirected\"` is the way to read a file as undirected.\n * - `:IGNORE` columns are skipped and counted in a loss note.\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 {\n type AttributeDeclarationInput,\n declareAttribute,\n declareCompanion,\n type DeclaredAttribute,\n declareOn,\n losesPrecision,\n parseDeclaredTemporal,\n parseDeclaredValue,\n PRECISION_CODE,\n RENAMED_CODE,\n takenIn,\n uniqueColumnName,\n} from \"../../common/attributes.js\";\nimport {\n DANGLING_REFERENCE_CODE as SHARED_DANGLING_REFERENCE_CODE,\n DUPLICATE_NODE_CODE as SHARED_DUPLICATE_NODE_CODE,\n MISSING_ENDPOINT_CODE as SHARED_MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE as SHARED_MISSING_ID_CODE,\n ROLE_TAKEN_CODE as SHARED_ROLE_TAKEN_CODE,\n} from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec } from \"../../common/declared-types.js\";\nimport { DirectionResolver } from \"../../common/direction.js\";\nimport { ID_MERGED_CODE as SHARED_ID_MERGED_CODE, IdCoercer } from \"../../common/ids.js\";\nimport { inputLength, isImportInput, type ReadOptions, throwIfAborted } from \"../../common/input.js\";\nimport { type ListSyntax, splitListText } from \"../../common/lists.js\";\nimport {\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { agree, plural, withArticle } from \"../../common/plural.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { parseTemporal } from \"../../common/temporal.js\";\nimport { parseWeightText } from \"../../common/weights.js\";\nimport {\n type CommonImportOptions,\n type GraphImporter,\n ImportError,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport { checkRecordSyntax, RecordReader, type RecordSyntax } from \"../csv/records.js\";\nimport { type FieldKind, type HeaderField, isHeaderRecord, parseHeaderField } from \"./header.js\";\n\n/**\n * The format-specific options of the Neo4j importer.\n * @category Built-in formats\n */\nexport interface Neo4jImportOptions extends CommonImportOptions {\n /**\n * More node files, each a string, bytes or a stream with its own header row; read after the\n * main input.\n */\n nodes?: ImportInput | readonly ImportInput[] | undefined;\n /**\n * Relationship files, each a string, bytes or a stream with its own header row; read after the\n * node files.\n */\n relationships?: ImportInput | readonly ImportInput[] | undefined;\n /**\n * The field delimiter, one character (neo4j-admin's `--delimiter`). The default is to detect\n * \",\" or a tab from the first rows, so a `.tsv` file needs no option. It must differ from\n * `arrayDelimiter`: with `delimiter: \";\"`, also pass `arrayDelimiter: \",\"` or `\"|\"`.\n * @defaultValue detected\n */\n delimiter?: string | undefined;\n /**\n * The delimiter inside list values and `:LABEL` cells (neo4j-admin's `--array-delimiter`). It\n * must differ from `delimiter`.\n * @defaultValue \";\"\n */\n arrayDelimiter?: \";\" | \",\" | \"|\" | undefined;\n /**\n * The quote character, one character (neo4j-admin's `--quote`).\n * @defaultValue '\"'\n */\n quote?: string | undefined;\n}\n\n/**\n * The name of the node list column holding `:LABEL` values.\n * @category Built-in formats\n */\nexport const LABELS_COLUMN = \"labels\";\n\n/**\n * The name of the edge dict column holding `:TYPE` values.\n * @category Built-in formats\n */\nexport const TYPE_COLUMN = \"type\";\n\n/**\n * The name of the node dict column holding the id space of `:ID(Space)`.\n * @category Built-in formats\n */\nexport const ID_SPACE_COLUMN = \"idSpace\";\n\n/**\n * Neo4j CSV: the name of the node column that holds a node's id as the file wrote it, for a node of an id\n * space (`:ID(Person)`), whose node id is `Person:<id>`. It has nothing to do with the `originalId` role that\n * `sanitizeIds: \"mangle\"` uses.\n * @category Built-in formats\n */\nexport const ORIGINAL_ID_COLUMN = \"originalId\";\n\n/**\n * A header row (or a whole section) is malformed; the import aborts.\n * @category Issue and loss codes\n */\nexport const HEADER_CODE = \"E_NEO4J_HEADER\";\n\n/**\n * A row has a different number of cells than its header.\n * @category Issue and loss codes\n */\nexport const COLUMN_COUNT_CODE = \"E_NEO4J_COLUMN_COUNT\";\n\n/**\n * A node row has an unquoted empty `:ID` cell (a quoted empty cell is the id \"\").\n * @category Issue and loss codes\n */\nexport const MISSING_ID_CODE = SHARED_MISSING_ID_CODE;\n\n/**\n * A relationship row has an unquoted empty `:START_ID` or `:END_ID` cell.\n * @category Issue and loss codes\n */\nexport const MISSING_ENDPOINT_CODE = SHARED_MISSING_ENDPOINT_CODE;\n\n/**\n * A node id was declared twice (same id space); the later row's properties win.\n * @category Issue and loss codes\n */\nexport const DUPLICATE_NODE_CODE = SHARED_DUPLICATE_NODE_CODE;\n\n/**\n * A node id was declared in two id spaces -- a spaced id `Space:id` equals the text of an id declared without a space;\n * the later row is skipped.\n * @category Issue and loss codes\n */\nexport const ID_SPACE_COLLISION_CODE = \"E_NEO4J_ID_SPACE_COLLISION\";\n\n/**\n * A `:START_ID(Space)` / `:END_ID(Space)` endpoint's qualified id `Space:id` names a node a node row declared in\n * another id space (without a space); the row is skipped.\n * @category Issue and loss codes\n */\nexport const ENDPOINT_SPACE_CODE = \"E_NEO4J_ENDPOINT_SPACE\";\n\n/**\n * Two different id cells became one id under `ids: \"number\"`.\n * @category Issue and loss codes\n */\nexport const ID_MERGED_CODE = SHARED_ID_MERGED_CODE;\n\n/**\n * A header brace option the importer does not act on.\n * @category Issue and loss codes\n */\nexport const HEADER_OPTION_CODE = \"W_NEO4J_HEADER_OPTION_IGNORED\";\n\n/**\n * You read into a graph builder that already has the labels, type or id space attribute, so this file's one is kept\n * without its role.\n * @category Issue and loss codes\n */\nexport const ROLE_TAKEN_CODE = SHARED_ROLE_TAKEN_CODE;\n\n/**\n * A relationship row with an empty `:TYPE` cell (neo4j-admin requires a type); the relationship is kept.\n * @category Issue and loss codes\n */\nexport const MISSING_TYPE_CODE = \"W_NEO4J_MISSING_TYPE\";\n\n/**\n * A file given under the `nodes` option holds a relationship header, or the reverse.\n * @category Issue and loss codes\n */\nexport const SECTION_KIND_CODE = \"W_NEO4J_SECTION_KIND\";\n\n/**\n * Relationship endpoints that no node row declares became nodes (the shared W_DANGLING_REFERENCE).\n * @category Issue and loss codes\n */\nexport const DANGLING_REFERENCE_CODE = SHARED_DANGLING_REFERENCE_CODE;\n\n/**\n * `:IGNORE` columns were skipped.\n * @category Built-in formats\n */\nexport const IGNORED_COLUMNS_LOSS = \"W_NEO4J_IGNORED_COLUMNS\";\n\n/** The common options the Neo4j 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 \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\nconst NEO4J = \"neo4j\";\n\n/** Rows between two checks of the cancellation signal (a whole string input is one chunk). */\nconst ABORT_CHECK_INTERVAL = 64;\n\nconst LABELS_DECL: ColumnDecl = {\n name: LABELS_COLUMN,\n dtype: \"list\",\n itemDtype: \"dict\",\n nullable: true,\n role: \"labels\",\n origin: { format: NEO4J, id: \":LABEL\", title: null, type: \"LABEL\", namespace: null },\n};\n\nconst TYPE_DECL: ColumnDecl = {\n name: TYPE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n role: \"kind\",\n origin: { format: NEO4J, id: \":TYPE\", title: null, type: \"TYPE\", namespace: null },\n};\n\nconst ID_SPACE_DECL: ColumnDecl = {\n name: ID_SPACE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n role: \"idSpace\",\n origin: { format: NEO4J, id: \":ID\", title: null, type: \"ID\", namespace: null },\n};\n\nconst ORIGINAL_ID_DECL: ColumnDecl = {\n name: ORIGINAL_ID_COLUMN,\n dtype: \"string\",\n nullable: true,\n // origin.type stays null so the column is never mistaken for a stored id (`name:ID`)\n origin: { format: NEO4J, id: \":ID\", title: null, type: null, namespace: null },\n};\n\nconst ARRAY_DELIMITERS: Readonly<Record<string, ListSyntax>> = { \";\": \"semicolon\", \",\": \"comma\", \"|\": \"pipe\" };\n\n/** The resolved format-specific options. */\ninterface ResolvedNeo4jOptions {\n readonly nodes: readonly ImportInput[];\n readonly relationships: readonly ImportInput[];\n readonly syntax: RecordSyntax;\n readonly listSyntax: ListSyntax;\n}\n\n/** One property column of a section. */\ninterface PropertySlot {\n /** The cell index. */\n readonly cell: number;\n /** The column name (after any rename). */\n readonly name: string;\n /** The column handle. */\n readonly handle: ColumnHandle;\n /** How the cell text is parsed. */\n readonly spec: DeclaredTypeSpec;\n /** The declaration of the companion text column of a temporal property, or null. */\n readonly companionDecl: ColumnDecl | null;\n /** The companion's handle once a value needed it (design section 5.1); INVALID_INDEX before. */\n companion: ColumnHandle;\n}\n\n/** A node section: the header interpreted. */\ninterface NodeSection {\n readonly kind: \"node\";\n readonly width: number;\n readonly idCell: number;\n /** The column holding the id as a property (`name:ID`), or INVALID_INDEX. */\n readonly idHandle: ColumnHandle;\n readonly space: string | null;\n readonly spaceCode: number;\n readonly labelCells: readonly number[];\n readonly extraLabels: readonly string[];\n readonly properties: readonly PropertySlot[];\n}\n\n/** A relationship section: the header interpreted. */\ninterface RelationshipSection {\n readonly kind: \"relationship\";\n readonly width: number;\n readonly startCell: number;\n readonly endCell: number;\n /** The id space of `:START_ID` / `:END_ID`, or null when the header declares none. */\n readonly startSpace: string | null;\n readonly endSpace: string | null;\n /** The id space of `:START_ID` / `:END_ID` as a registry code, or 0 when the header declares none. */\n readonly startSpaceCode: number;\n readonly endSpaceCode: number;\n /** The `:TYPE` cell, or -1. */\n readonly typeCell: number;\n /** The cell of the property named by `weightFrom`, or -1. */\n readonly weightCell: number;\n readonly properties: readonly PropertySlot[];\n}\n\ntype Section = NodeSection | RelationshipSection;\n\n/** The delimiters sniffed between when none is given: neo4j-admin's default and the TSV tab. */\nconst NEO4J_DELIMITER_CANDIDATES: readonly string[] = Object.freeze([\",\", \"\\t\"]);\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the resolved options; E_UNSUPPORTED for an invalid value\n */\nfunction resolveNeo4jOptions(options: Neo4jImportOptions | undefined): ResolvedNeo4jOptions {\n const o: Neo4jImportOptions = options ?? {};\n const arrayDelimiter = o.arrayDelimiter ?? \";\";\n const listSyntax = ARRAY_DELIMITERS[arrayDelimiter];\n if (typeof arrayDelimiter !== \"string\" || listSyntax === undefined) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option arrayDelimiter: ${JSON.stringify(arrayDelimiter)} is not one of \";\", \",\", \"|\"`,\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n if (arrayDelimiter === \",\" && o.delimiter === undefined) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n 'option arrayDelimiter \",\" needs the delimiter option: the field delimiter is a comma unless another is given',\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n const syntax = checkRecordSyntax({\n delimiter: o.delimiter ?? null,\n quote: o.quote ?? '\"',\n candidates: NEO4J_DELIMITER_CANDIDATES.filter((d) => d !== arrayDelimiter),\n });\n if (syntax.delimiter === arrayDelimiter) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `options delimiter and arrayDelimiter must differ: both are ${JSON.stringify(arrayDelimiter)}; pass another arrayDelimiter (\";\", \",\" or \"|\")`,\n {\n option: \"arrayDelimiter\",\n found: arrayDelimiter,\n },\n );\n }\n return {\n nodes: inputList(\"nodes\", o.nodes),\n relationships: inputList(\"relationships\", o.relationships),\n syntax,\n listSyntax,\n };\n}\n\n/**\n * Normalize an input-list option.\n * @param name - the option name\n * @param value - one input, a list of inputs, or undefined\n * @returns the inputs; E_UNSUPPORTED for anything else\n */\nfunction inputList(name: string, value: unknown): readonly ImportInput[] {\n if (value === undefined || value === null) {\n return [];\n }\n const list: unknown[] = Array.isArray(value) ? (value as unknown[]) : [value];\n for (const item of list) {\n if (!isImportInput(item)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option ${name}: an entry is not an ImportInput`, {\n option: name,\n found: typeof item,\n });\n }\n }\n return list as ImportInput[];\n}\n\n/**\n * Which nodes were declared by a node row and in which id space, by node index, so a repeated id\n * is reported (a duplicate in one space, a collision across spaces).\n */\nclass NodeRegistry {\n private codes = new Uint32Array(1024);\n\n private readonly spaces = new Map<string | null, number>();\n\n /**\n * The code of an id space (1 for \"no space\").\n * @param space - the space name or null\n * @returns a code >= 1\n */\n codeOf(space: string | null): number {\n let code = this.spaces.get(space);\n if (code === undefined) {\n code = this.spaces.size + 1;\n this.spaces.set(space, code);\n }\n return code;\n }\n\n /**\n * Record that a node row declared a node.\n * @param index - the node index\n * @param code - the space code\n * @returns \"new\" for a first declaration, \"duplicate\" for a repeat in the same space, \"collision\" across spaces\n */\n declare(index: number, code: number): \"new\" | \"duplicate\" | \"collision\" {\n if (index >= this.codes.length) {\n let size = this.codes.length * 2;\n while (size <= index) {\n size *= 2;\n }\n const grown = new Uint32Array(size);\n grown.set(this.codes);\n this.codes = grown;\n }\n const previous = this.codes[index];\n if (previous === 0) {\n this.codes[index] = code;\n return \"new\";\n }\n return previous === code ? \"duplicate\" : \"collision\";\n }\n\n /**\n * The space code a node row declared a node in.\n * @param index - the node index\n * @returns the code, or 0 when no node row declared the node\n */\n codeAt(index: number): number {\n return index < this.codes.length ? this.codes[index] : 0;\n }\n}\n\n/**\n * Byte progress over several inputs as one sequence: each input's progress is offset by the bytes\n * of the inputs before it, and the total is known only when every input is in memory.\n */\nclass ProgressTracker {\n private readonly callback: ((bytesDone: number, bytesTotal?: number) => void) | null;\n\n private readonly total: number | undefined;\n\n private offset = 0;\n\n private lastDone = 0;\n\n /**\n * Create a tracker.\n * @param callback - the caller's onProgress, or null\n * @param inputs - every input in reading order\n */\n constructor(callback: ((bytesDone: number, bytesTotal?: number) => void) | null, inputs: readonly ImportInput[]) {\n this.callback = callback;\n let total: number | undefined = 0;\n for (const input of inputs) {\n const length = inputLength(input);\n if (length === null) {\n total = undefined;\n break;\n }\n total += length;\n }\n this.total = total;\n }\n\n /**\n * The read options for one input.\n * @param signal - the cancellation signal\n * @returns options whose onProgress reports cumulative bytes\n */\n optionsFor(signal: AbortSignal | null): ReadOptions {\n const { callback } = this;\n if (callback === null) {\n return { signal };\n }\n return {\n signal,\n onProgress: (done: number): void => {\n this.lastDone = done;\n callback(this.offset + done, this.total);\n },\n };\n }\n\n /** Move the offset past the input just finished. */\n finishInput(): void {\n this.offset += this.lastDone;\n this.lastDone = 0;\n }\n}\n\n/**\n * The state of one import call: the sink, the report, the resolved options, the reserved column\n * handles and the per-section row handlers.\n */\nclass Neo4jImportSession {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly common: ResolvedImportOptions;\n\n private readonly options: ResolvedNeo4jOptions;\n\n private readonly coercer: IdCoercer;\n\n private readonly direction: DirectionResolver;\n\n private readonly registry = new NodeRegistry();\n\n /** The relationship property the weights were read from, when it is not \"weight\"; the exporter writes it back under that name. */\n weightProperty: string | null = null;\n\n private labelsHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private typeHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private idSpaceHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private originalIdHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private ignoredColumns = 0;\n\n /** Whether the sink's direction was set (before the first relationship, design section 8.4 rule 1). */\n private headerSet = false;\n\n /** Scratch: the parsed value of every cell of the current row. */\n private values: unknown[] = [];\n\n /** Scratch: the companion text of every cell of the current row. */\n private texts: (string | null)[] = [];\n\n /** Scratch: the property slots of the current row that lost precision. */\n private readonly precisionSlots: PropertySlot[] = [];\n\n /** Scratch: the values of the current row that overflowed their float / double type. */\n private readonly overflows: string[] = [];\n\n /** The section kind the option of the input being read names, or null for the primary input. */\n private expectedKind: Section[\"kind\"] | null = null;\n\n /** Whether any node row was read. */\n private nodeRows = false;\n\n /** Nodes relationship endpoints created (no node row declared them yet), the first few by id. */\n private readonly placeholders: { readonly id: NodeId; readonly index: number }[] = [];\n\n /**\n * Create a session.\n * @param sink - the sink\n * @param report - the report\n * @param common - the resolved common options\n * @param options - the resolved format options\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n options: ResolvedNeo4jOptions,\n ) {\n this.sink = sink;\n this.report = report;\n this.common = common;\n this.options = options;\n this.coercer = new IdCoercer(common.ids);\n this.direction = new DirectionResolver(sink, report, common.onMixedDirection);\n }\n\n /**\n * Read every input. A header-only input lends its header to the headerless input after it (the\n * neo4j-admin convention `--nodes=header.csv,part1.csv`); an empty input is an error only when\n * it is the only one.\n * @param inputs - the inputs in reading order, each with the kind of section its option names (null for the primary input)\n */\n async run(\n inputs: readonly { readonly input: ImportInput; readonly kind: Section[\"kind\"] | null }[],\n ): Promise<void> {\n const progress = new ProgressTracker(\n this.common.onProgress,\n inputs.map((i) => i.input),\n );\n let carried: Section | null = null;\n for (const { input, kind } of inputs) {\n this.expectedKind = kind;\n if (carried !== null && kind !== null && carried.kind !== kind) {\n // a nodes header never lends itself to a relationships file, nor the reverse\n carried = null;\n }\n carried = await this.readInput(\n input,\n { ...progress.optionsFor(this.common.signal), encoding: this.common.encoding },\n carried,\n inputs.length > 1,\n );\n progress.finishInput();\n }\n if (this.ignoredColumns > 0) {\n this.report.loss(\n IGNORED_COLUMNS_LOSS,\n `${this.ignoredColumns} :IGNORE column${plural(this.ignoredColumns)} ${agree(this.ignoredColumns, \"was\", \"were\")} skipped as the header instructs`,\n null,\n this.ignoredColumns,\n );\n }\n this.reportDangling();\n }\n\n /**\n * Read one input: a header row, then data rows until the next header row.\n * @param input - the input\n * @param readOptions - cancellation and progress\n * @param carried - the section of a header-only input just before this one, or null\n * @param mayBeEmpty - whether an input without any record is allowed (other inputs exist)\n * @returns this input's section when it held a header and no data row (lent to the next input), else null\n */\n private async readInput(\n input: ImportInput,\n readOptions: ReadOptions,\n carried: Section | null,\n mayBeEmpty: boolean,\n ): Promise<Section | null> {\n const reader = new RecordReader(input, this.report, this.options.syntax, {\n ...readOptions,\n allowEmpty: mayBeEmpty,\n });\n let section: Section | null = carried;\n let records = 0;\n let rows = 0;\n let sinceCheck = 0;\n for await (const count of reader) {\n const { cells, quoted } = reader;\n if (records === 0 && count === 1 && !quoted[0] && cells[0].trim().length === 0) {\n // a whitespace-only line before anything else is a blank line, not an empty header\n continue;\n }\n records++;\n // a quoted marker cell is data (\"ref:id\") unless the whole record is a quoted header\n if (section === null || isHeaderRecord(cells, count, quoted)) {\n section = this.declareSection(reader, count);\n rows = 0;\n continue;\n }\n rows++;\n if (section.kind === \"node\") {\n this.nodeRow(section, reader, count);\n } else {\n this.relationshipRow(section, reader, count);\n }\n if (++sinceCheck >= ABORT_CHECK_INTERVAL) {\n sinceCheck = 0;\n throwIfAborted(readOptions.signal);\n }\n }\n if (records === 0 && carried === null && !mayBeEmpty) {\n this.report.fail(HEADER_CODE, \"the input has no header row\", { line: 1 });\n }\n // the header lent on: a header-only input's, or the one lent to this input when it had none\n if (section === carried) {\n return carried;\n }\n return rows === 0 ? section : null;\n }\n\n /**\n * Interpret a header row: parse every cell, check the section shape, declare its columns.\n * @param reader - the reader positioned on the header\n * @param count - the number of header cells\n * @returns the section\n */\n private declareSection(reader: RecordReader, count: number): Section {\n const { line } = reader;\n const fields: HeaderField[] = [];\n try {\n for (let i = 0; i < count; i++) {\n fields.push(parseHeaderField(reader.cells[i]));\n }\n const kinds = new Map<FieldKind, number[]>();\n fields.forEach((field, i) => {\n const list = kinds.get(field.kind);\n if (list === undefined) {\n kinds.set(field.kind, [i]);\n } else {\n list.push(i);\n }\n });\n const ids = kinds.get(\"ID\") ?? [];\n const starts = kinds.get(\"START_ID\") ?? [];\n const ends = kinds.get(\"END_ID\") ?? [];\n const isNode = ids.length > 0;\n const isRelationship = starts.length > 0 || ends.length > 0;\n if (isNode && isRelationship) {\n throw headerError(\"a header mixes :ID with :START_ID / :END_ID\");\n }\n if (!isNode && !isRelationship) {\n const apoc = fields.some((f) => f.name === \"_id\" || f.name === \"_start\");\n throw headerError(\n apoc\n ? \"a header needs an :ID column (nodes) or :START_ID and :END_ID columns (relationships); this is the apoc.export.csv layout (_id, _labels, _start, _end, _type), which is not the neo4j-admin import format\"\n : \"a header needs an :ID column (nodes) or :START_ID and :END_ID columns (relationships)\",\n );\n }\n if (this.expectedKind !== null && this.expectedKind !== (isNode ? \"node\" : \"relationship\")) {\n this.report.warning(\n \"validation-error\",\n SECTION_KIND_CODE,\n `a ${isNode ? \"node\" : \"relationship\"} header in a file given as ${this.expectedKind === \"node\" ? \"nodes\" : \"relationships\"}; read by its header`,\n { line },\n );\n }\n checkPropertyNames(fields);\n this.ignoredColumns += (kinds.get(\"IGNORE\") ?? []).length;\n if (isNode) {\n if (ids.length > 1) {\n throw headerError(\"a node header has more than one :ID column\");\n }\n if (kinds.has(\"TYPE\")) {\n throw headerError(\"a node header cannot have a :TYPE column\");\n }\n return this.declareNodeSection(fields, ids[0], kinds.get(\"LABEL\") ?? [], line);\n }\n if (starts.length !== 1 || ends.length !== 1) {\n throw headerError(\"a relationship header needs exactly one :START_ID and one :END_ID column\");\n }\n if (kinds.has(\"LABEL\")) {\n throw headerError(\"a relationship header cannot have a :LABEL column\");\n }\n const types = kinds.get(\"TYPE\") ?? [];\n if (types.length > 1) {\n throw headerError(\"a relationship header has more than one :TYPE column\");\n }\n return this.declareRelationshipSection(\n fields,\n starts[0],\n ends[0],\n types.length === 1 ? types[0] : -1,\n line,\n );\n } catch (err) {\n if (err instanceof GraphFormatError && !(err instanceof ImportError)) {\n // a header written with another delimiter reads as one cell holding it\n const other = [\";\", \"|\", \"\\t\", \",\"].find(\n (d) => d !== reader.delimiter && reader.cells.slice(0, count).some((c) => c.includes(d)),\n );\n const hint =\n other === undefined\n ? \"\"\n : `; if the file is delimited by ${JSON.stringify(other)}, pass the delimiter option`;\n this.report.fail(HEADER_CODE, `${err.message}${hint}`, { line }, { cause: err.code });\n }\n throw err;\n }\n }\n\n /**\n * Declare the columns of a node section.\n * @param fields - the parsed header\n * @param idCell - the `:ID` cell\n * @param labelCells - the `:LABEL` cells\n * @param line - the header line\n * @returns the section\n */\n private declareNodeSection(\n fields: readonly HeaderField[],\n idCell: number,\n labelCells: readonly number[],\n line: number,\n ): NodeSection {\n const idField = fields[idCell];\n const extraLabels: string[] = [];\n for (const field of fields) {\n for (const [key, value] of field.options) {\n if (key === \"label\" && field.kind === \"ID\") {\n extraLabels.push(value);\n } else {\n this.report.warning(\n \"unsupported\",\n HEADER_OPTION_CODE,\n `header option ${key}:${value} of \"${field.text}\" is ignored`,\n { line, element: field.text },\n );\n }\n }\n }\n if (labelCells.length > 0 || extraLabels.length > 0) {\n this.ensureLabels();\n }\n if (idField.space !== null) {\n this.ensureIdSpace();\n }\n let idHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n if (idField.name.length > 0) {\n idHandle = this.declareProperty(\n \"node\",\n { ...idField, type: null },\n idCell,\n { origin: { format: NEO4J, id: idField.name, title: null, type: \"ID\", namespace: idField.space } },\n line,\n ).handle;\n }\n const properties = this.declareProperties(\"node\", fields, line, null);\n return {\n kind: \"node\",\n width: fields.length,\n idCell,\n idHandle,\n space: idField.space,\n spaceCode: this.registry.codeOf(idField.space),\n labelCells,\n extraLabels,\n properties,\n };\n }\n\n /**\n * Declare the columns of a relationship section.\n * @param fields - the parsed header\n * @param startCell - the `:START_ID` cell\n * @param endCell - the `:END_ID` cell\n * @param typeCell - the `:TYPE` cell, or -1\n * @param line - the header line\n * @returns the section\n */\n private declareRelationshipSection(\n fields: readonly HeaderField[],\n startCell: number,\n endCell: number,\n typeCell: number,\n line: number,\n ): RelationshipSection {\n for (const field of fields) {\n for (const [key, value] of field.options) {\n this.report.warning(\n \"unsupported\",\n HEADER_OPTION_CODE,\n `header option ${key}:${value} of \"${field.text}\" is ignored`,\n { line, element: field.text },\n );\n }\n }\n if (typeCell >= 0) {\n this.ensureType();\n }\n const { weightFrom } = this.common;\n let weightCell = -1;\n if (weightFrom !== null) {\n weightCell = fields.findIndex((field) => field.kind === \"PROPERTY\" && field.name === weightFrom);\n if (weightCell >= 0 && weightFrom !== \"weight\") {\n this.weightProperty = weightFrom;\n }\n }\n const properties = this.declareProperties(\"edge\", fields, line, weightCell);\n const { space: startSpace } = fields[startCell];\n const { space: endSpace } = fields[endCell];\n return {\n kind: \"relationship\",\n width: fields.length,\n startCell,\n endCell,\n startSpace,\n endSpace,\n startSpaceCode: startSpace === null ? 0 : this.registry.codeOf(startSpace),\n endSpaceCode: endSpace === null ? 0 : this.registry.codeOf(endSpace),\n typeCell,\n weightCell,\n properties,\n };\n }\n\n /**\n * Declare every PROPERTY field of a header.\n * @param domain - node or edge\n * @param fields - the parsed header\n * @param line - the header line\n * @param skipCell - a cell to leave undeclared (the weight), or null\n * @returns the property slots\n */\n private declareProperties(\n domain: \"node\" | \"edge\",\n fields: readonly HeaderField[],\n line: number,\n skipCell: number | null,\n ): PropertySlot[] {\n const slots: PropertySlot[] = [];\n fields.forEach((field, cell) => {\n if (field.kind !== \"PROPERTY\" || cell === skipCell) {\n return;\n }\n slots.push(this.declareProperty(domain, field, cell, {}, line));\n });\n const width = fields.length;\n if (this.values.length < width) {\n this.values = new Array<unknown>(width);\n this.texts = new Array<string | null>(width);\n }\n return slots;\n }\n\n /**\n * Declare one property column on the sink: the same name and shape again shares the column;\n * a different shape under the same name is renamed `<name>#<name>` (design section 5.6).\n * @param domain - node or edge\n * @param field - the header field\n * @param cell - the field's cell index\n * @param patch - declaration fields to override (the id property's origin)\n * @param line - the header line\n * @returns the slot\n */\n private declareProperty(\n domain: \"node\" | \"edge\",\n field: HeaderField,\n cell: number,\n patch: Partial<ColumnDecl>,\n line: number,\n ): PropertySlot {\n const { sink, report } = this;\n const { listSyntax } = this.options;\n const input: AttributeDeclarationInput = {\n format: NEO4J,\n id: field.name,\n title: null,\n type: field.type,\n namespace: null,\n listSyntax,\n long: this.common.long,\n };\n let declared: DeclaredAttribute = declareAttribute(input);\n let decl: ColumnDecl = { ...declared.decl, ...patch };\n let handle: ColumnHandle;\n try {\n handle = declareOn(sink, domain, decl);\n } catch (err) {\n if (!(err instanceof GraphFormatError) || err.code !== \"E_COLUMN_EXISTS\") {\n throw err;\n }\n declared = declareAttribute({ ...input, taken: takenIn(sink, domain) });\n decl = { ...declared.decl, ...patch, name: declared.decl.name };\n handle = declareOn(sink, domain, decl);\n }\n for (const issue of declared.issues) {\n report.warning(issue.category, issue.code, issue.message, { line, element: field.text });\n }\n return {\n cell,\n name: decl.name,\n handle,\n spec: declared.spec,\n companionDecl: declared.companion,\n companion: INVALID_INDEX as ColumnHandle,\n };\n }\n\n /** Declare (or adopt) the labels column. */\n private ensureLabels(): void {\n if (this.labelsHandle === INVALID_INDEX) {\n this.labelsHandle = this.declareReserved(\"node\", LABELS_DECL);\n }\n }\n\n /** Declare (or adopt) the relationship type column. */\n private ensureType(): void {\n if (this.typeHandle === INVALID_INDEX) {\n this.typeHandle = this.declareReserved(\"edge\", TYPE_DECL);\n }\n }\n\n /** Declare (or adopt) the id space column. */\n private ensureIdSpace(): void {\n if (this.idSpaceHandle === INVALID_INDEX) {\n this.idSpaceHandle = this.declareReserved(\"node\", ID_SPACE_DECL);\n this.originalIdHandle = this.declareReserved(\"node\", ORIGINAL_ID_DECL);\n }\n }\n\n /**\n * Declare a reserved column: the same shape again shares it; a name taken by another shape is\n * renamed `<name>#<origin.id>` and reported; a role the sink already holds elsewhere is dropped\n * and reported.\n * @param domain - node or edge\n * @param decl - the reserved declaration\n * @returns the handle\n */\n private declareReserved(domain: \"node\" | \"edge\", decl: ColumnDecl): ColumnHandle {\n const { sink, report } = this;\n let current = decl;\n for (;;) {\n try {\n return declareOn(sink, domain, current);\n } catch (err) {\n if (!(err instanceof GraphFormatError)) {\n throw err;\n }\n if (err.code === \"E_COLUMN_EXISTS\") {\n const name = uniqueColumnName(current.name, current.origin?.id ?? null, takenIn(sink, domain));\n report.warning(\n \"coercion\",\n RENAMED_CODE,\n `column \"${current.name}\" renamed to \"${name}\": the name was taken`,\n { element: current.name },\n );\n current = { ...current, name };\n } else if (err.code === \"E_DUPLICATE_ROLE\") {\n report.warning(\n \"coercion\",\n ROLE_TAKEN_CODE,\n `column \"${current.name}\" declared without role \"${String(current.role)}\": the sink already holds that role`,\n { element: current.name },\n );\n const { role: _role, ...withoutRole } = current;\n current = withoutRole;\n } else {\n throw err;\n }\n }\n }\n }\n\n /**\n * Push one node row.\n * @param section - the section\n * @param reader - the reader positioned on the row\n * @param count - the row's cell count\n */\n private nodeRow(section: NodeSection, reader: RecordReader, count: number): void {\n const { sink, report } = this;\n const { cells, quoted, line } = reader;\n if (count !== section.width) {\n report.error(\n \"validation-error\",\n COLUMN_COUNT_CODE,\n `row has ${count} cell${plural(count)} but the header has ${section.width}`,\n { line },\n );\n report.counts.skippedNodes++;\n return;\n }\n const idText = cells[section.idCell];\n if (idText.length === 0 && !quoted[section.idCell]) {\n // a quoted empty cell is the id \"\" (neo4j-admin: an empty quoted field is an empty string)\n report.error(\"missing-value\", MISSING_ID_CODE, \"empty :ID cell\", { line });\n report.counts.skippedNodes++;\n return;\n }\n const coerced = this.coerceId(idText, line);\n if (coerced === null || !this.parseProperties(section.properties, cells, quoted, line, idText)) {\n report.counts.skippedNodes++;\n return;\n }\n const id = qualify(coerced, section.space);\n let labels: string[] | undefined;\n if (section.labelCells.length > 0 || section.extraLabels.length > 0) {\n labels = this.labelsOf(section, cells, quoted);\n }\n this.nodeRows = true;\n const existed = sink.indexOf(id) !== INVALID_INDEX;\n let index: number;\n try {\n index = sink.addNode(id);\n } catch (err) {\n report.recordError(err, { line, element: idText });\n report.counts.skippedNodes++;\n return;\n }\n const status = this.registry.declare(index, section.spaceCode);\n if (status === \"collision\") {\n report.error(\n \"validation-error\",\n ID_SPACE_COLLISION_CODE,\n `node ${idText} is declared in id space ${section.space ?? \"(none)\"} and in another id space; the core has one id space and this row is skipped`,\n { line, element: idText },\n );\n report.counts.skippedNodes++;\n return;\n }\n if (status === \"duplicate\") {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `node ${idText} is declared twice; the later properties win`,\n {\n line,\n element: idText,\n },\n );\n }\n // a write the sink refuses is recorded and the rest of the row is still written\n const set = (column: ColumnHandle, value: unknown): void => {\n this.guarded(line, idText, () => {\n sink.setNodeValue(column, index, value);\n });\n };\n if (section.idHandle !== INVALID_INDEX) {\n set(section.idHandle, idText);\n }\n if (section.space !== null) {\n set(this.idSpaceHandle, section.space);\n set(this.originalIdHandle, idText);\n }\n if (labels !== undefined) {\n set(this.labelsHandle, labels);\n }\n this.writeProperties(\"node\", section.properties, index, line, idText);\n this.reportPrecision(line, idText);\n // a node a relationship created before its row (or an earlier row) is counted once\n if (!existed) {\n report.counts.nodes++;\n }\n }\n\n /**\n * Run one sink write, recording a refusal (a GraphFormatError) on the row's line instead of\n * letting it escape the import.\n * @param line - the row's line\n * @param element - the row's element name\n * @param write - the write\n */\n private guarded(line: number, element: string, write: () => void): void {\n try {\n write();\n } catch (err) {\n if (!(err instanceof GraphFormatError) || err instanceof ImportError) {\n throw err;\n }\n this.report.recordError(err, { line, element });\n }\n }\n\n /**\n * Report the relationship endpoints no node row declared (the shared W_DANGLING_REFERENCE,\n * once) when the input has node rows: each became a node, where neo4j-admin refuses the\n * relationship.\n */\n private reportDangling(): void {\n const dangling = this.placeholders.filter((p) => this.registry.codeAt(p.index) === 0);\n // without any node row, every node comes from the relationships (a relationships-only file)\n if (dangling.length === 0 || !this.nodeRows) {\n return;\n }\n const shown = dangling\n .slice(0, 5)\n .map((p) => String(p.id))\n .join(\", \");\n this.report.warning(\n \"validation-error\",\n DANGLING_REFERENCE_CODE,\n `${dangling.length} relationship endpoint${plural(dangling.length)} ${agree(dangling.length, \"names\", \"name\")} no node row and became nodes: ${shown}${dangling.length > 5 ? \", ...\" : \"\"} (neo4j-admin refuses such relationships)`,\n { element: String(dangling[0].id) },\n );\n }\n\n /**\n * Push one relationship row.\n * @param section - the section\n * @param reader - the reader positioned on the row\n * @param count - the row's cell count\n */\n private relationshipRow(section: RelationshipSection, reader: RecordReader, count: number): void {\n const { sink, report } = this;\n const { cells, quoted, line } = reader;\n if (!this.headerSet) {\n // a Neo4j file is directed by definition (\"all relationships have a direction\"); the sink's\n // direction is set once, before the first relationship, so a node-only file leaves it alone\n this.headerSet = true;\n this.direction.setHeader(true, { line });\n }\n if (count !== section.width) {\n report.error(\n \"validation-error\",\n COLUMN_COUNT_CODE,\n `row has ${count} cell${plural(count)} but the header has ${section.width}`,\n { line },\n );\n report.counts.skippedEdges++;\n return;\n }\n const startText = cells[section.startCell];\n const endText = cells[section.endCell];\n const startMissing = startText.length === 0 && !quoted[section.startCell];\n if (startMissing || (endText.length === 0 && !quoted[section.endCell])) {\n report.error(\n \"missing-value\",\n MISSING_ENDPOINT_CODE,\n `empty ${startMissing ? \":START_ID\" : \":END_ID\"} cell`,\n {\n line,\n },\n );\n report.counts.skippedEdges++;\n return;\n }\n const element = `${startText}->${endText}`;\n const start = this.coerceId(startText, line);\n const end = start === null ? null : this.coerceId(endText, line);\n if (start === null || end === null) {\n report.counts.skippedEdges++;\n return;\n }\n const source = qualify(start, section.startSpace);\n const target = qualify(end, section.endSpace);\n let wrongSpace: string | null = null;\n if (this.wrongSpace(source, section.startSpaceCode)) {\n wrongSpace = startText;\n } else if (this.wrongSpace(target, section.endSpaceCode)) {\n wrongSpace = endText;\n }\n if (wrongSpace !== null) {\n report.error(\n \"missing-value\",\n ENDPOINT_SPACE_CODE,\n `endpoint ${wrongSpace} is not a node of its declared id space (a node of another id space has that id); the row is skipped`,\n { line, element },\n );\n report.counts.skippedEdges++;\n return;\n }\n let weight: number | undefined;\n if (section.weightCell >= 0) {\n try {\n weight = parseWeightText(cells[section.weightCell], this.report);\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n return;\n }\n }\n if (!this.parseProperties(section.properties, cells, quoted, line, element)) {\n report.counts.skippedEdges++;\n return;\n }\n const created = [source, target].filter(\n (id, k) => (k === 0 || id !== source) && sink.indexOf(id) === INVALID_INDEX,\n );\n let edge: number;\n try {\n edge = this.direction.addEdge(source, target, \"directed\", weight, { line, element });\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n return;\n }\n for (const id of created) {\n // a node no row declared yet: counted now; reported at the end unless a node row follows\n report.counts.nodes++;\n this.placeholders.push({ id, index: sink.indexOf(id) });\n }\n if (section.typeCell >= 0) {\n const type = cells[section.typeCell];\n if (type.length > 0) {\n this.guarded(line, element, () => {\n sink.setEdgeValue(this.typeHandle, edge, type);\n });\n } else {\n report.warning(\n \"missing-value\",\n MISSING_TYPE_CODE,\n \"empty :TYPE cell; neo4j-admin requires a relationship type, the relationship is kept without one\",\n { line, element },\n );\n }\n }\n this.writeProperties(\"edge\", section.properties, edge, line, element);\n this.reportPrecision(line, element);\n report.counts.edges++;\n }\n\n /**\n * Whether a qualified endpoint id belongs to a node a node row declared in another id space than\n * the endpoint's header declares (an unspaced node whose id text is `Space:id`). An endpoint\n * without a declared space, or a node no row declared yet, is looked up by id alone.\n * @param id - the endpoint id\n * @param spaceCode - the endpoint's space code, 0 for none\n * @returns true when the endpoint resolves to a node of another space\n */\n private wrongSpace(id: NodeId, spaceCode: number): boolean {\n if (spaceCode === 0) {\n return false;\n }\n const index = this.sink.indexOf(id);\n if (index < 0) {\n return false;\n }\n const declared = this.registry.codeAt(index);\n return declared !== 0 && declared !== spaceCode;\n }\n\n /**\n * Coerce an id cell, reporting a merge under `ids: \"number\"` and an invalid id as an error.\n * @param text - the cell\n * @param line - the row's line\n * @returns the id, or null when the cell was rejected (the error is recorded)\n */\n private coerceId(text: string, line: number): NodeId | null {\n const { coercer, report } = this;\n let id: NodeId;\n try {\n id = coercer.text(text);\n } catch (err) {\n report.recordError(err, { line, element: text });\n return null;\n }\n const merge = coercer.lastMerge;\n if (merge !== null) {\n report.warning(\n \"coercion\",\n ID_MERGED_CODE,\n `id \"${merge.text}\" merged with \"${merge.previousText}\" as ${merge.id} under ids: \"number\"`,\n { line, element: text },\n );\n }\n return id;\n }\n\n /**\n * Parse the property cells of a row into the scratch arrays.\n * @param slots - the section's property slots\n * @param cells - the row's cells\n * @param quoted - whether each cell was quoted\n * @param line - the row's line\n * @param element - the row's element name for issues\n * @returns true when every cell parsed; false after recording the first error\n */\n private parseProperties(\n slots: readonly PropertySlot[],\n cells: readonly string[],\n quoted: readonly boolean[],\n line: number,\n element: string,\n ): boolean {\n const { values, texts, precisionSlots } = this;\n precisionSlots.length = 0;\n this.overflows.length = 0;\n for (const slot of slots) {\n const text = cells[slot.cell];\n texts[slot.cell] = null;\n if (text.length === 0) {\n values[slot.cell] = quoted[slot.cell] ? emptyValue(slot.spec) : undefined;\n continue;\n }\n const { spec } = slot;\n try {\n this.parseCell(slot, text);\n } catch (err) {\n this.report.recordError(err, { line, element: `${element} ${slot.name}` });\n return false;\n }\n if (overflows(spec, values[slot.cell], text)) {\n this.overflows.push(slot.name);\n }\n if (spec.precision && losesPrecision(spec, text)) {\n precisionSlots.push(slot);\n }\n }\n return true;\n }\n\n /**\n * Parse one non-empty property cell into the scratch arrays; throws on a malformed value.\n * @param slot - the cell's property slot\n * @param text - the cell text\n */\n private parseCell(slot: PropertySlot, text: string): void {\n const { values, texts } = this;\n const { spec } = slot;\n if (spec.temporal !== null && !spec.list) {\n const zoned = withZoneOffset(text, spec);\n const parsed = parseDeclaredTemporal(zoned, spec);\n values[slot.cell] = parsed.value;\n // a zone name is kept in the companion text, the value is its instant\n texts[slot.cell] = zoned === text ? parsed.text : text;\n } else {\n values[slot.cell] = parseDeclaredValue(text, spec, this.options.listSyntax);\n checkNeo4jRange(spec, values[slot.cell], text);\n }\n }\n\n /**\n * Write the parsed property values of a row.\n * @param domain - node or edge\n * @param slots - the section's property slots\n * @param row - the node or edge index\n * @param line - the row's line\n * @param element - the row's element name for issues\n */\n private writeProperties(\n domain: \"node\" | \"edge\",\n slots: readonly PropertySlot[],\n row: number,\n line: number,\n element: string,\n ): void {\n const { sink, values, texts } = this;\n for (const slot of slots) {\n const value = values[slot.cell];\n if (value === undefined) {\n continue;\n }\n const text = texts[slot.cell];\n // a value the sink refuses is recorded on the row's line; the other properties are written\n this.guarded(line, `${element} ${slot.name}`, () => {\n if (text !== null && slot.companion === INVALID_INDEX && slot.companionDecl !== null) {\n slot.companion = declareCompanion(sink, domain, slot.companionDecl);\n }\n if (domain === \"node\") {\n sink.setNodeValue(slot.handle, row, value);\n if (text !== null) {\n sink.setNodeValue(slot.companion, row, text);\n }\n } else {\n sink.setEdgeValue(slot.handle, row, value);\n if (text !== null) {\n sink.setEdgeValue(slot.companion, row, text);\n }\n }\n });\n }\n }\n\n /**\n * Report the precision losses of the row just accepted.\n * @param line - the row's line\n * @param element - the row's element name\n */\n private reportPrecision(line: number, element: string): void {\n for (const slot of this.precisionSlots) {\n this.report.warning(\n \"precision\",\n PRECISION_CODE,\n `long value of \"${slot.name}\" is beyond 2^53 and was stored as the nearest f64`,\n { line, element },\n );\n }\n this.precisionSlots.length = 0;\n for (const name of this.overflows) {\n this.report.warning(\n \"precision\",\n PRECISION_CODE,\n `the value of \"${name}\" is beyond the range of its float / double type and was stored as the nearest representable value`,\n { line, element },\n );\n }\n this.overflows.length = 0;\n }\n\n /**\n * The labels of a node row: every `:LABEL` cell split by the array delimiter (empty items\n * dropped), plus the header's `{label:...}` options.\n * @param section - the section\n * @param cells - the row's cells\n * @param quoted - whether each cell was quoted\n * @returns the labels, or undefined when every label cell is unset and no extra label exists\n */\n private labelsOf(section: NodeSection, cells: readonly string[], quoted: readonly boolean[]): string[] | undefined {\n let labels: string[] | undefined;\n for (const cell of section.labelCells) {\n const text = cells[cell];\n if (text.length === 0 && !quoted[cell]) {\n continue;\n }\n if (labels === undefined) {\n labels = [];\n }\n for (const item of splitListText(text, this.options.listSyntax)) {\n if (item.length > 0) {\n labels.push(item);\n }\n }\n }\n if (section.extraLabels.length > 0) {\n if (labels === undefined) {\n labels = [];\n }\n labels.push(...section.extraLabels);\n }\n return labels;\n }\n}\n\n/**\n * The id a node of an id space is stored under: `Space:id`, so the same id in two spaces stays two\n * nodes (the core has one id space).\n * @param id - the coerced id cell\n * @param space - the id space, or null\n * @returns the id unchanged without a space, else the string `Space:id`\n */\nfunction qualify(id: NodeId, space: string | null): NodeId {\n return space === null ? id : `${space}:${String(id)}`;\n}\n\n/** The integer range of the narrow neo4j-admin types (Java byte and short). */\nconst INTEGER_RANGES: Readonly<Record<string, readonly [number, number]>> = {\n byte: [-128, 127],\n short: [-32768, 32767],\n};\n\n/**\n * A Cypher duration (ISO 8601): unit form `P14DT16H12M` / `PT0.75M` / `P2.5W` (components may be\n * signed or fractional) or the date-time form `P2012-02-02T14:37:21.545`.\n */\n/**\n * Whether a text is a Cypher duration (ISO 8601): unit form `P14DT16H12M` / `PT0.75M` / `P2.5W`\n * (components may be signed or fractional) or the date-time form `P2012-02-02T14:37:21.545`.\n * @param text - the text, trimmed\n * @returns true when it is\n */\nfunction isDuration(text: string): boolean {\n if (DURATION_DATE_TIME.test(text)) {\n return true;\n }\n const m = /^[+-]?P([^T]*)(?:T(.*))?$/i.exec(text);\n if (m === null || m[2] === \"\" || (m[1] === \"\" && m[2] === undefined)) {\n return false;\n }\n return unitsInOrder(m[1], \"YMWD\") && unitsInOrder(m[2] ?? \"\", \"HMS\");\n}\n\n/** The date-time form of a Cypher duration, `P2012-02-02T14:37:21.545`. */\nconst DURATION_DATE_TIME = /^[+-]?P\\d{4}-?\\d{2}-?\\d{2}T\\d{2}:?\\d{2}:?\\d{2}(?:\\.\\d+)?$/i;\n\n/**\n * Whether a run of duration components (`14D`, `-1.5H30M`) names its units in the order given,\n * each at most once.\n * @param text - the components\n * @param units - the unit letters in their order\n * @returns true when it does\n */\nfunction unitsInOrder(text: string, units: string): boolean {\n let rest = text.toUpperCase();\n let from = 0;\n while (rest !== \"\") {\n const m = /^[-+]?\\d+(?:\\.\\d+)?([A-Z])/.exec(rest);\n const at = m === null ? -1 : units.indexOf(m[1], from);\n if (m === null || at < 0) {\n return false;\n }\n from = at + 1;\n rest = rest.slice(m[0].length);\n }\n return true;\n}\n\n/**\n * Check the neo4j-admin types the shared parser maps to a wider dtype: byte and short values within\n * their Java range, a char of one character, a duration in Cypher's syntax.\n * @param spec - the declared type\n * @param value - the parsed value (a list of items for an array type)\n * @param text - the cell text, for the error\n */\nfunction checkNeo4jRange(spec: DeclaredTypeSpec, value: unknown, text: string): void {\n const base = spec.declared.trim().toLowerCase().replace(/\\[\\]$/, \"\");\n const items: unknown[] = spec.list && Array.isArray(value) ? value : [value];\n const range = INTEGER_RANGES[base];\n for (const item of items) {\n let bad = false;\n if (range !== undefined) {\n bad = typeof item === \"number\" && (item < range[0] || item > range[1]);\n } else if (base === \"char\") {\n // a Java char: one UTF-16 code unit\n bad = typeof item === \"string\" && item.length !== 1;\n } else if (base === \"duration\") {\n bad = typeof item === \"string\" && !isDuration(item.trim());\n }\n if (bad) {\n const span = range === undefined ? \"\" : ` (${range[0]} to ${range[1]})`;\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `\"${text}\" is not ${withArticle(base)}${span}`, {\n value: text,\n kind: base,\n });\n }\n }\n}\n\n/** The largest finite f32. */\nconst F32_MAX = 3.4028234663852886e38;\n\n/**\n * Whether a float / double cell overflowed: a finite literal read as an infinity, or a float beyond\n * the f32 range (Java's Double.parseDouble accepts both silently; the value changes).\n * @param spec - the declared type\n * @param value - the parsed value\n * @param text - the cell text\n * @returns true when the stored value is not the one written\n */\nfunction overflows(spec: DeclaredTypeSpec, value: unknown, text: string): boolean {\n if ((spec.kind !== \"float\" && spec.kind !== \"double\") || /inf|nan/i.test(text)) {\n return false;\n }\n const items: unknown[] = spec.list && Array.isArray(value) ? value : [value];\n return items.some(\n (v) => typeof v === \"number\" && (!Number.isFinite(v) || (spec.kind === \"float\" && Math.abs(v) > F32_MAX)),\n );\n}\n\n/**\n * A Cypher date-time with a zone name (`2020-01-01T00:00:00[Europe/Berlin]`) as one with a UTC\n * offset the temporal parser reads: the offset the text gives, else the zone's offset at that wall\n * time. Any other text is returned unchanged.\n * @param text - the cell text\n * @param spec - the declared type\n * @returns the text to parse\n */\nfunction withZoneOffset(text: string, spec: DeclaredTypeSpec): string {\n const trimmed = text.trim();\n const open = trimmed.lastIndexOf(\"[\");\n if (spec.temporal !== \"dateTime\" || open < 0 || !trimmed.endsWith(\"]\")) {\n return text;\n }\n const local = trimmed.slice(0, open);\n const zone = trimmed.slice(open + 1, -1);\n if (zone === \"\" || zone.includes(\"]\") || /[\\n\\r\\u2028\\u2029]/.test(local)) {\n return text;\n }\n let format: Intl.DateTimeFormat;\n try {\n format = new Intl.DateTimeFormat(\"en-US\", { timeZone: zone, timeZoneName: \"longOffset\" });\n } catch {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `\"${text}\" names an unknown time zone ${zone}`, { value: text });\n }\n if (/(Z|z|[+-]\\d{2}(:?\\d{2})?)$/.test(local)) {\n return local;\n }\n const wall = parseTemporal(local, \"localDateTime\").value;\n const offsetAt = (ms: number): number => {\n const name = format.formatToParts(new Date(ms)).find((p) => p.type === \"timeZoneName\")?.value ?? \"GMT\";\n const o = /GMT([+-])(\\d{2}):(\\d{2})/.exec(name);\n if (o === null) {\n return 0;\n }\n return (o[1] === \"-\" ? -1 : 1) * (Number(o[2]) * 60 + Number(o[3]));\n };\n // the offset at the instant the wall time names (twice, so a wall time near a transition settles)\n const minutes = offsetAt(wall - offsetAt(wall) * 60_000);\n const sign = minutes < 0 ? \"-\" : \"+\";\n const abs = Math.abs(minutes);\n return `${local}${sign}${String(Math.floor(abs / 60)).padStart(2, \"0\")}:${String(abs % 60).padStart(2, \"0\")}`;\n}\n\n/**\n * The value of a quoted empty cell: an empty string for a string-kind property, an empty list for\n * a list property, unset for anything else (neo4j-admin's default `--ignore-empty-strings=false`).\n * @param spec - the property's declared type\n * @returns the value, or undefined for unset\n */\nfunction emptyValue(spec: DeclaredTypeSpec): unknown {\n if (spec.list) {\n return [];\n }\n if (spec.kind === \"string\" || spec.kind === \"duration\") {\n return \"\";\n }\n return undefined;\n}\n\n/**\n * Check that no two PROPERTY (or stored-id) fields of one header share a name.\n * @param fields - the parsed header\n */\nfunction checkPropertyNames(fields: readonly HeaderField[]): void {\n const seen = new Set<string>();\n for (const field of fields) {\n if (field.name.length === 0 || field.kind === \"IGNORE\") {\n continue;\n }\n if (seen.has(field.name)) {\n throw headerError(`property \"${field.name}\" is declared twice`);\n }\n seen.add(field.name);\n }\n}\n\n/**\n * The error of a malformed section header.\n * @param reason - why\n * @returns the error\n */\nfunction headerError(reason: string): GraphFormatError {\n return new GraphFormatError(\"E_UNSUPPORTED\", reason, { reason: \"header\" });\n}\n\n/**\n * Confidence that a head of bytes is a neo4j-admin CSV: the first line holds an `:ID`,\n * `:START_ID` or `:END_ID` header cell.\n * @param head - the first bytes of the input\n * @returns 0.95 for a Neo4j header, 0 otherwise\n */\nfunction sniffNeo4j(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\", { fatal: false, ignoreBOM: false }).decode(head);\n const end = text.search(/[\\r\\n]/);\n const first = end < 0 ? text : text.slice(0, end);\n const cells = first.split(/[,;|\\t]/);\n return isHeaderRecord(cells, cells.length) ? 0.95 : 0;\n}\n\n/**\n * The Neo4j importer.\n * @category Built-in formats\n */\nexport const neo4jImporter: GraphImporter<Neo4jImportOptions> = Object.freeze({\n format: NEO4J,\n options: Object.freeze([\"arrayDelimiter\", \"delimiter\", \"nodes\", \"quote\", \"relationships\"]),\n extensions: Object.freeze([\".csv\", \".tsv\"]),\n mimeTypes: Object.freeze([\"text/csv\", \"text/tab-separated-values\"]),\n sniff: sniffNeo4j,\n /**\n * Read one or more neo4j-admin CSV inputs into the sink.\n * @param input - the primary input (a node table, a relationship table, or sections of both)\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report; ImportError beyond the error limit or on a malformed header\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: Neo4jImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const common = resolveImportOptions(options, { ids: \"canonical\", defaultDirected: true, weightFrom: \"weight\" });\n const format = resolveNeo4jOptions(options);\n const report = new ImportReportBuilder(NEO4J, common.errorLimit);\n reportSinkOptions(sink, options, report);\n // nodeIdFrom and defaultDirected are among the reported options: Neo4j ids are the :ID\n // column and every relationship is directed\n reportUnusedOptions(options, report, USED_OPTIONS);\n const session = new Neo4jImportSession(sink, report, common, format);\n await session.run([\n { input, kind: null },\n ...format.nodes.map((file) => ({ input: file, kind: \"node\" as const })),\n ...format.relationships.map((file) => ({ input: file, kind: \"relationship\" as const })),\n ]);\n if (session.weightProperty !== null) {\n sink.setMeta({ extra: { neo4j: { weightProperty: session.weightProperty } } });\n }\n throwIfAborted(common.signal);\n return report.finish();\n },\n});\n","/**\n * The Neo4j exporter (design section 8.5, research note 07 section 9): writes a snapshot as\n * neo4j-admin import CSV -- node sections with `:ID`, `:LABEL` and typed property columns,\n * relationship sections with `:START_ID`, `:END_ID`, `:TYPE`, the weight and typed property\n * columns -- as one document (node sections first) or as the node or relationship part alone.\n *\n * What a property graph cannot carry is reported by check() before anything is written: an\n * undirected snapshot (every edge becomes a directed relationship), expanded mixed direction (per\n * `onMixedDirection`), edge ids, hierarchy, element lifetimes, graph attributes, nested json (points\n * excepted), multi-component columns (flattened to arrays), u32 / u8 columns (written as `long` /\n * `int`), ids whose text would re-import as another type or collide, and list items that contain\n * the array delimiter.\n *\n * Column headers restore the declared Neo4j type from `origin.type` when it is compatible with the\n * column's dtype (`int`, `byte`, `short`, `long`, `char`, `duration`, the temporal types, `point`,\n * `type[]`), and derive it from the dtype otherwise. Temporal columns write their `.text`\n * companion when set and the canonical ISO form otherwise. Nodes are grouped into sections by\n * (id space, stored-id column) in index order, so a re-import restores the same node order;\n * relationships likewise by (start space, end space). A node of an id space is written under its\n * `originalId` value (the id text the importer stored it under as `Space:id`), so a round trip\n * reproduces the source file.\n */\n\nimport {\n type Column,\n type ColumnMeta,\n type Dtype,\n GraphFormatError,\n type GraphSnapshot,\n type NodeId,\n type ScalarDtype,\n} from \"@graphty/graph-format\";\n\nimport { ID_TEXT_COLLISION_CODE, ID_TEXT_TYPE_CODE } from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec, mapDeclaredType } from \"../../common/declared-types.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { quoteCsvCell } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, LOSS } from \"../../common/export.js\";\nimport { formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { isCanonicalIntegerText } from \"../../common/ids.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { formatTemporal, type TemporalKind } from \"../../common/temporal.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport { checkRecordSyntax, type RecordSyntax } from \"../csv/records.js\";\nimport { formatHeaderField } from \"./header.js\";\nimport { ID_SPACE_COLUMN, LABELS_COLUMN, TYPE_COLUMN } from \"./importer.js\";\n\n/**\n * The format-specific options of the Neo4j exporter.\n * @category Built-in formats\n */\nexport interface Neo4jExportOptions extends CommonExportOptions {\n /**\n * Which tables to write: \"all\" (the node sections, then the relationship sections), \"nodes\" or\n * \"relationships\".\n * @defaultValue \"all\"\n */\n part?: \"all\" | \"nodes\" | \"relationships\" | undefined;\n /**\n * The field delimiter, one character. It must differ from `arrayDelimiter`: with\n * `delimiter: \";\"`, also pass `arrayDelimiter: \",\"` or `\"|\"`.\n * @defaultValue \",\"\n */\n delimiter?: string | undefined;\n /**\n * The delimiter inside list values and `:LABEL` cells. It must differ from `delimiter`.\n * @defaultValue \";\"\n */\n arrayDelimiter?: \";\" | \",\" | \"|\" | undefined;\n /**\n * The quote character, one character. Cells that hold the delimiter, the quote character or a\n * line break are quoted with it. Pass the same value as the `quote` import option to read the\n * file back.\n * @defaultValue '\"'\n */\n quote?: string | undefined;\n /**\n * The relationship property that holds the edge weights, written as `<name>:double`; null\n * writes no weights (checkExport() then returns W_WEIGHTS_DROPPED). graph-io reads the\n * \"weight\" property back as the weight; for any other name, pass the same name as the\n * `weightFrom` import option to read the weights back (`weightColumn: \"strength\"` with\n * `weightFrom: \"strength\"`), or they come back as a plain edge attribute. A graph read from Neo4j\n * CSV with `weightFrom` writes its weights back under the property they were read from.\n * @defaultValue \"weight\", or the property a Neo4j import read the weights from\n */\n weightColumn?: string | null | undefined;\n /**\n * The property name of the `:ID` column (`<name>:ID`) for nodes that have no id property of\n * their own; null writes a bare `:ID`.\n * @defaultValue null\n */\n idColumn?: string | null | undefined;\n}\n\n/**\n * Neo4j relationships are always directed, so the edges of an undirected graph, and the undirected edges of a mixed\n * graph, read back as directed.\n * @category Built-in formats\n */\nexport const UNDIRECTED_LOSS = \"W_NEO4J_UNDIRECTED_AS_DIRECTED\";\n\n/**\n * Node ids that read back as a different type, such as the text \"7\" as the number 7.\n * @category Built-in formats\n */\nexport const ID_TEXT_TYPE_LOSS = ID_TEXT_TYPE_CODE;\n\n/**\n * Two node ids share one text; export() throws E_INVALID_ID.\n * @category Built-in formats\n */\nexport const ID_TEXT_COLLISION_LOSS = ID_TEXT_COLLISION_CODE;\n\n/**\n * The `weightColumn` name is already an edge attribute; the save fails.\n * @category Built-in formats\n */\nexport const WEIGHT_COLUMN_TAKEN_LOSS = \"E_NEO4J_WEIGHT_COLUMN_TAKEN\";\n\n/**\n * The `idColumn` name is already a node attribute; the save fails.\n * @category Built-in formats\n */\nexport const ID_COLUMN_TAKEN_LOSS = \"E_NEO4J_ID_COLUMN_TAKEN\";\n\n/**\n * A node has more than one stored-id column set; only the first is written.\n * @category Built-in formats\n */\nexport const MULTIPLE_ID_PROPERTIES_LOSS = \"W_NEO4J_MULTIPLE_ID_PROPERTIES\";\n\n/**\n * A declared integer type holds non-integral values and is written as double.\n * @category Built-in formats\n */\nexport const DECLARED_TYPE_CHANGED_LOSS = \"W_NEO4J_DECLARED_TYPE_CHANGED\";\n\n/**\n * A list item contains the array delimiter, which Neo4j cannot escape.\n * @category Built-in formats\n */\nexport const ARRAY_DELIMITER_LOSS = \"W_NEO4J_ARRAY_DELIMITER\";\n\n/** The roles Neo4j has a slot for: `:TYPE`, `:LABEL` and the id space of `:ID(Space)`. */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"kind\", \"labels\", \"idSpace\"]);\n\nconst NEO4J = \"neo4j\";\nconst ID_TYPE = \"ID\";\n\n/** The weight property the importer reads by default (its weightFrom default). */\nconst DEFAULT_WEIGHT_COLUMN = \"weight\";\n\n/** The names the importer gives the slot columns, for the name-change notes. */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n kind: TYPE_COLUMN,\n labels: LABELS_COLUMN,\n idSpace: ID_SPACE_COLUMN,\n});\n\n/**\n * The capabilities of neo4j-admin CSV: declared scalar types and\n * arrays; a dict column reads back as string (the header has no enumeration type); a position or\n * visual column is written as a plain property (a point for a 2- or 3-component position) and\n * reads back without its role.\n * @category Built-in formats\n */\nexport const NEO4J_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"none\",\n idCharset: \"any\",\n dtypes: [\"f32\", \"f64\", \"i32\", \"bool\", \"string\"],\n components: false,\n lists: true,\n json: false,\n defaults: false,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: false,\n positions: false,\n viz: false,\n});\n\n/** Roles whose columns are never written as properties. */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\n/** Notes about relationships only, dropped when only nodes are written. */\nconst EDGE_NOTE_CODES: ReadonlySet<string> = new Set([\n LOSS.MIXED_DIRECTION,\n LOSS.MIXED_DIRECTION_ERROR,\n LOSS.MULTI_EDGES,\n LOSS.SELF_LOOPS,\n LOSS.EDGE_IDS_GENERATED,\n LOSS.EDGE_IDS_DROPPED,\n UNDIRECTED_LOSS,\n WEIGHT_COLUMN_TAKEN_LOSS,\n]);\n\n/** Notes about nodes only, dropped when only relationships are written. */\nconst NODE_NOTE_CODES: ReadonlySet<string> = new Set([\n LOSS.ID_MANGLED,\n LOSS.ID_CHARSET,\n LOSS.ID_RENUMBERED,\n ID_TEXT_TYPE_LOSS,\n ID_COLUMN_TAKEN_LOSS,\n MULTIPLE_ID_PROPERTIES_LOSS,\n]);\n\nconst ARRAY_SYNTAXES: ReadonlySet<string> = new Set([\";\", \",\", \"|\"]);\nconst PARTS: ReadonlySet<string> = new Set([\"all\", \"nodes\", \"relationships\"]);\n\n/** The resolved format options. */\ninterface ResolvedNeo4jExportOptions {\n readonly part: \"all\" | \"nodes\" | \"relationships\";\n readonly syntax: RecordSyntax & { readonly delimiter: string };\n readonly arrayDelimiter: string;\n readonly weightColumn: string | null;\n readonly idColumn: string | null;\n}\n\n/** How one cell's value is written. */\ntype CellKind = \"integer\" | \"float\" | \"double\" | \"boolean\" | \"string\" | \"temporal\" | \"point\" | \"json\";\n\n/** The Neo4j type and cell kind of one scalar (a column or a list item). */\ninterface ScalarPlan {\n readonly type: string;\n readonly kind: CellKind;\n readonly temporal: TemporalKind | null;\n}\n\n/** One property column as it will be written. */\ninterface ColumnPlan {\n readonly column: Column;\n readonly header: string;\n readonly scalar: ScalarPlan;\n /** A list (or flattened vector) column: items are joined by the array delimiter. */\n readonly list: boolean;\n /** The companion text column of a temporal column, or null. */\n readonly companion: Column | null;\n}\n\n/**\n * Resolve the format options.\n * @param options - the caller's options\n * @param readFrom - the property a Neo4j import read the weights from, the default weightColumn\n * @returns the resolved options; E_UNSUPPORTED for an invalid value\n */\nfunction resolveNeo4jExportOptions(\n options: Neo4jExportOptions | undefined,\n readFrom: string | null,\n): ResolvedNeo4jExportOptions {\n const o: Neo4jExportOptions = options ?? {};\n const part = o.part ?? \"all\";\n if (!PARTS.has(part)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option part: ${JSON.stringify(part)} is not \"all\", \"nodes\" or \"relationships\"`,\n {\n option: \"part\",\n found: part,\n },\n );\n }\n const arrayDelimiter = o.arrayDelimiter ?? \";\";\n if (!ARRAY_SYNTAXES.has(arrayDelimiter)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option arrayDelimiter: ${JSON.stringify(arrayDelimiter)} is not one of \";\", \",\", \"|\"`,\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n const delimiter = o.delimiter ?? \",\";\n const syntax = { ...checkRecordSyntax({ delimiter, quote: o.quote ?? '\"' }), delimiter };\n if (syntax.delimiter === arrayDelimiter) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `options delimiter and arrayDelimiter must differ: both are ${JSON.stringify(arrayDelimiter)}; pass another arrayDelimiter (\";\", \",\" or \"|\")`,\n {\n option: \"arrayDelimiter\",\n found: arrayDelimiter,\n },\n );\n }\n const weightColumn = o.weightColumn === undefined ? (readFrom ?? \"weight\") : o.weightColumn;\n if (weightColumn !== null && (typeof weightColumn !== \"string\" || weightColumn.length === 0)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option weightColumn: expected a non-empty name or null\", {\n option: \"weightColumn\",\n found: weightColumn,\n });\n }\n const idColumn = o.idColumn ?? null;\n if (idColumn !== null && (typeof idColumn !== \"string\" || idColumn.length === 0)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option idColumn: expected a non-empty name or null\", {\n option: \"idColumn\",\n found: idColumn,\n });\n }\n return { part, syntax, arrayDelimiter, weightColumn, idColumn };\n}\n\n/**\n * Everything check() and export() share: the column plans, the section keys, the notes and the\n * error export() throws (if any), computed once from the snapshot and the options.\n */\nclass ExportPlan {\n readonly snapshot: GraphSnapshot;\n\n readonly options: ResolvedNeo4jExportOptions;\n\n readonly common: ResolvedExportOptions;\n\n /** The notes: the generic capability notes first, then the format's own, in that order. */\n readonly notes: LossNote[] = [];\n\n /** The format's own notes, appended after the generic ones. */\n private readonly ownNotes: LossNote[] = [];\n\n /** The error export() throws because of the node sections, or null. */\n private fatalNodes: GraphFormatError | null = null;\n\n /** The error export() throws because of the relationship sections, or null. */\n private fatalEdges: GraphFormatError | null = null;\n\n /** The error export() throws whatever the part (an id text collision), or null. */\n private fatalAll: GraphFormatError | null = null;\n\n readonly nodeColumns: ColumnPlan[] = [];\n\n readonly edgeColumns: ColumnPlan[] = [];\n\n /** Stored-id node columns (`name:ID`), in declaration order. */\n readonly idColumns: Column[] = [];\n\n readonly idSpace: Column | null;\n\n /** The id text of the nodes of an id space (the importer's `originalId` column), or null. */\n readonly originalId: Column | null;\n\n readonly labels: Column | null;\n\n readonly kind: Column | null;\n\n readonly weights: ExplicitWeights | null;\n\n /** The pair folding (design section 3.6): the mirror halves of undirected pairs are not written. */\n readonly folding: PairFolding;\n\n /**\n * Build the plan.\n * @param snapshot - the snapshot\n * @param options - the resolved format options\n * @param common - the resolved common options\n */\n constructor(snapshot: GraphSnapshot, options: ResolvedNeo4jExportOptions, common: ResolvedExportOptions) {\n this.snapshot = snapshot;\n this.options = options;\n this.common = common;\n this.idSpace = snapshot.nodes.byRole(\"idSpace\");\n this.originalId = [...snapshot.nodes].find((column) => isIdText(column.meta)) ?? null;\n this.labels = snapshot.nodes.byRole(\"labels\");\n this.kind = snapshot.edges.byRole(\"kind\");\n for (const column of snapshot.nodes) {\n if (isStoredId(column.meta)) {\n this.idColumns.push(column);\n }\n }\n const generic = checkCapabilities(snapshot, NEO4J_CAPABILITIES, common, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n temporalText: true,\n weights: options.weightColumn !== null,\n });\n this.planColumns(\"node\", snapshot.nodes, this.nodeColumns);\n this.planColumns(\"edge\", snapshot.edges, this.edgeColumns);\n this.weights = this.planWeightSource();\n this.folding = pairFolding(snapshot);\n this.checkIds();\n this.checkIdColumn();\n this.checkStoredIds();\n this.directionNotes();\n const slots = new Set([this.kind, this.labels, this.idSpace].flatMap((c) => (c === null ? [] : [c.meta.name])));\n this.addGenericNotes(generic, slots);\n this.notes.push(...this.ownNotes);\n this.filterNotesByPart();\n }\n\n /**\n * Add the generic capability notes, leaving out the ones this format reads back as they were.\n * @param generic - the notes the capability check found\n * @param slots - the names of the :TYPE, :LABEL and :ID(Space) columns\n */\n private addGenericNotes(generic: ReturnType<typeof checkCapabilities>, slots: ReadonlySet<string>): void {\n for (const gen of generic) {\n if (gen.code === LOSS.JSON && gen.column !== null && this.writtenAsPoint(gen.column)) {\n continue;\n }\n if (gen.code === LOSS.DTYPE && gen.column !== null && slots.has(gen.column)) {\n // :TYPE, :LABEL and :ID(Space) read back as the dict / list-of-dict columns they were\n continue;\n }\n if (gen.code === LOSS.MIXED_DIRECTION_ERROR && this.fatalEdges === null) {\n this.fatalEdges = new GraphFormatError(\"E_DIRECTED\", gen.message, { reason: \"mixed direction\" });\n }\n if ((gen.code === LOSS.POSITIONS || gen.code === LOSS.VIZ) && gen.column !== null) {\n // written as a plain property (a point for a position); the role is what is lost. Deprecated for\n // the style roles (next major): styles reach a file only through the style writer.\n this.notes.push(\n Object.freeze({\n code: gen.code,\n message: `node column \"${gen.column}\" is written as a plain property; its role is lost on re-import`,\n column: gen.column,\n count: gen.count,\n }),\n );\n continue;\n }\n this.notes.push(gen);\n }\n }\n\n /**\n * The direction notes: an undirected snapshot writes every edge as a directed relationship;\n * a mixed snapshot folds its undirected pairs to one directed relationship each under\n * \"directed\" or \"undirected\" (Neo4j has no undirected relationship, so both policies write\n * the same file and the generic W_MIXED_DIRECTION note names the policy); a mutual pair is\n * written as two relationships without its mark.\n */\n private directionNotes(): void {\n const { snapshot, folding } = this;\n if (!snapshot.directed) {\n this.note(\n UNDIRECTED_LOSS,\n `the snapshot is undirected; every edge is written as a directed relationship (${snapshot.edgeCount} edge${plural(snapshot.edgeCount)})`,\n null,\n snapshot.edgeCount,\n );\n } else if (this.common.onMixedDirection !== \"error\") {\n let undirected = 0;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (!folding.folded(e) && !folding.sourceDirected(e)) {\n undirected++;\n }\n }\n if (undirected > 0) {\n this.note(\n UNDIRECTED_LOSS,\n `${undirected} undirected edge${plural(undirected)} ${agree(undirected, \"is\", \"are\")} written as one directed relationship each (source to target, a pair folded to its primary); Neo4j has no undirected relationship`,\n null,\n undirected,\n );\n }\n }\n if (folding.mutualCount > 0) {\n this.note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, \"is\", \"are\")} written as two directed relationships; the mutual mark is lost`,\n null,\n folding.mutualCount,\n );\n }\n }\n\n /**\n * Record a note.\n * @param code - the code\n * @param message - the message\n * @param column - the column, or null\n * @param count - the count, or null\n */\n private note(code: string, message: string, column: string | null = null, count: number | null = null): void {\n this.ownNotes.push(Object.freeze({ code, message, column, count }));\n }\n\n /**\n * Plan the property columns of one table.\n * @param domain - node or edge\n * @param table - the table\n * @param out - receives the plans in declaration order\n */\n private planColumns(domain: \"node\" | \"edge\", table: Iterable<Column>, out: ColumnPlan[]): void {\n const all = [...table];\n const names = new Set(all.map((column) => column.meta.name));\n const companionFor = new Map<string, Column>();\n const companions = new Set<Column>();\n for (const column of all) {\n const target = column.meta.extra.for;\n if (column.dtype === \"string\" && typeof target === \"string\" && names.has(target)) {\n companionFor.set(target, column);\n companions.add(column);\n }\n }\n for (const column of all) {\n const { meta } = column;\n const { role } = meta;\n if (companions.has(column) || (role !== null && SKIPPED_ROLES.has(role))) {\n continue;\n }\n if (\n domain === \"node\" &&\n (isStoredId(meta) || column === this.idSpace || column === this.labels || column === this.originalId)\n ) {\n continue;\n }\n if (domain === \"edge\" && (role === \"id\" || column === this.kind)) {\n continue;\n }\n out.push(this.planColumn(column, companionFor.get(meta.name) ?? null));\n }\n }\n\n /**\n * Plan one property column: its header type, cell kind and notes.\n * @param column - the column\n * @param companion - its text companion, or null\n * @returns the plan\n */\n private planColumn(column: Column, companion: Column | null): ColumnPlan {\n const { meta } = column;\n const declared = meta.origin?.type ?? null;\n const mapped = declared === null ? null : mapDeclaredType(NEO4J, declared, \"f64\");\n const label = `${meta.domain} column \"${meta.name}\"`;\n if (meta.dtype === \"list\") {\n const itemDtype = meta.itemDtype ?? \"string\";\n const compatible =\n mapped !== null && mapped.list && mapped.itemDtype === itemDtype && mapped.kind !== \"long\";\n let scalar = compatible\n ? { type: declaredScalar(declared as string), kind: kindOf(mapped), temporal: mapped.temporal }\n : defaultScalar(itemDtype);\n if (mapped !== null && mapped.list && mapped.kind === \"long\" && itemDtype === \"f64\") {\n scalar = this.integralOrDouble(column, declaredScalar(declared as string), label);\n }\n const itemComponents = meta.itemComponents ?? 1;\n if (itemComponents > 1) {\n this.note(\n LOSS.COMPONENTS,\n `${label} holds items of ${itemComponents} components; they are flattened into one array`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n this.checkArrayItems(column, scalar, label);\n return {\n column,\n header: formatHeaderField(meta.name, `${scalar.type}[]`, null),\n scalar,\n list: true,\n companion,\n };\n }\n let scalar: ScalarPlan;\n const compatible = mapped !== null && !mapped.list && mapped.dtype === meta.dtype;\n if (compatible && mapped.kind === \"long\") {\n scalar = this.integralOrDouble(column, declared as string, label);\n } else if (compatible) {\n scalar = { type: declared as string, kind: kindOf(mapped), temporal: mapped.temporal };\n } else {\n scalar = defaultScalar(meta.dtype);\n }\n // the generic check treats position and visual columns by role only; their dtype and\n // stride are checked here so the notes match those of any other column\n const visual = meta.role === \"position\" || (meta.role !== null && isVizRole(meta.role));\n if (visual && meta.dtype === \"json\" && scalar.kind !== \"point\") {\n this.note(\n LOSS.JSON,\n `${label} holds nested values; the format has no nested values`,\n meta.name,\n column.length - column.nullCount,\n );\n } else if (visual && meta.dtype !== \"json\" && !NEO4J_CAPABILITIES.dtypes.includes(meta.dtype)) {\n this.note(\n LOSS.DTYPE,\n `${label} is ${meta.dtype}; the format cannot keep that dtype`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n if (meta.components > 1) {\n if (visual) {\n this.note(\n LOSS.COMPONENTS,\n `${label} has ${meta.components} components; the format has no strides`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n return {\n column,\n header: formatHeaderField(meta.name, `${scalar.type}[]`, null),\n scalar,\n list: true,\n companion,\n };\n }\n // an untyped Neo4j header (`name` alone) is a string property; restore it as written\n const untyped = declared === null && meta.origin?.format === NEO4J && meta.dtype === \"string\";\n const header = untyped ? meta.name : formatHeaderField(meta.name, scalar.type, null);\n return { column, header, scalar, list: false, companion };\n }\n\n /**\n * The plan of an f64 column declared with an integer type: kept when every set value is\n * integral, written as double (with a note) otherwise.\n * @param column - the column\n * @param declared - the declared type text\n * @param label - the column label for messages\n * @returns the scalar plan\n */\n private integralOrDouble(column: Column, declared: string, label: string): ScalarPlan {\n if (holdsOnlyIntegers(column)) {\n return { type: declared, kind: \"integer\", temporal: null };\n }\n this.note(\n DECLARED_TYPE_CHANGED_LOSS,\n `${label} is declared ${declared} but holds non-integral values; written as double`,\n column.meta.name,\n null,\n );\n return { type: \"double\", kind: \"double\", temporal: null };\n }\n\n /**\n * Count the rows of a list column with an item containing the array delimiter.\n * @param column - the list column\n * @param scalar - the item plan\n * @param label - the column label\n */\n private checkArrayItems(column: Column, scalar: ScalarPlan, label: string): void {\n if (\n column.dtype !== \"list\" ||\n (scalar.kind !== \"string\" && scalar.kind !== \"json\" && scalar.kind !== \"point\")\n ) {\n return;\n }\n const { arrayDelimiter } = this.options;\n let rows = 0;\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n for (const item of column.sliceOf(r)) {\n if (formatScalar(item, scalar, null).includes(arrayDelimiter)) {\n rows++;\n break;\n }\n }\n }\n if (rows > 0) {\n this.note(\n ARRAY_DELIMITER_LOSS,\n `${label}: ${rows} row${plural(rows)} ${agree(rows, \"holds\", \"hold\")} an item containing the array delimiter \"${arrayDelimiter}\", which Neo4j cannot escape`,\n column.meta.name,\n rows,\n );\n }\n }\n\n /**\n * The explicit weights (design section 3.7), and the weight-column name check.\n * @returns the weights, or null when no weights are written\n */\n private planWeightSource(): ExplicitWeights | null {\n const { snapshot } = this;\n const name = this.options.weightColumn;\n if (name === null) {\n return null;\n }\n const weights = explicitWeights(snapshot);\n const taken = this.edgeColumns.find((plan) => plan.column.meta.name === name);\n if (taken !== undefined && weights.weighted) {\n this.note(\n WEIGHT_COLUMN_TAKEN_LOSS,\n `edge column \"${name}\" already exists; explicit weights cannot be written under weightColumn \"${name}\"`,\n name,\n null,\n );\n if (this.fatalEdges === null) {\n this.fatalEdges = new GraphFormatError(\n \"E_COLUMN_EXISTS\",\n `edge column \"${name}\" already exists; choose another weightColumn`,\n { column: name, domain: \"edge\" },\n );\n }\n } else if (taken !== undefined && name === DEFAULT_WEIGHT_COLUMN) {\n this.note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${name}\" is written under the property the importer reads edge weights from (weightFrom \"${name}\"); it reads back as the weight, not as a column`,\n name,\n taken.column.length - taken.column.nullCount,\n );\n }\n return weights.weighted ? weights : null;\n }\n\n /** Check the node ids' text forms: type changes under the canonical rule and collisions. */\n private checkIds(): void {\n const { ids } = this.snapshot;\n let typeChanges = 0;\n let collisions = 0;\n switch (ids.kind) {\n case \"identity\":\n case \"dense\":\n break;\n case \"numeric\":\n for (let i = 0; i < ids.size; i++) {\n if (!Number.isSafeInteger(ids.idOf(i))) {\n typeChanges++;\n }\n }\n break;\n case \"string\":\n for (let i = 0; i < ids.size; i++) {\n if (isCanonicalIntegerText(String(ids.idOf(i)))) {\n typeChanges++;\n }\n }\n break;\n case \"mixed\": {\n const seen = new Set<string>();\n for (let i = 0; i < ids.size; i++) {\n const id = ids.idOf(i);\n const text = String(id);\n if (typeof id === \"number\" ? !Number.isSafeInteger(id) : isCanonicalIntegerText(text)) {\n typeChanges++;\n }\n if (seen.has(text)) {\n collisions++;\n } else {\n seen.add(text);\n }\n }\n break;\n }\n default: {\n const name: string = ids.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown id map kind ${name}`, { kind: name });\n }\n }\n if (typeChanges > 0) {\n this.note(\n ID_TEXT_TYPE_LOSS,\n `${typeChanges} node id${plural(typeChanges)} re-import as another type under the canonical id rule (a string of canonical integer text, or a non-integer number)`,\n null,\n typeChanges,\n );\n }\n if (collisions > 0) {\n this.note(\n ID_TEXT_COLLISION_LOSS,\n `${collisions} node id${plural(collisions)} ${agree(collisions, \"shares\", \"share\")} their text with another id (a number and a string); the save fails`,\n null,\n collisions,\n );\n this.fatalAll = new GraphFormatError(\n \"E_INVALID_ID\",\n `${collisions} node id${plural(collisions)} ${agree(collisions, \"shares\", \"share\")} their text with another id; Neo4j ids are text`,\n { reason: \"text collision\", count: collisions },\n );\n }\n }\n\n /** Check that the idColumn option does not name an existing node property. */\n private checkIdColumn(): void {\n const name = this.options.idColumn;\n if (name === null) {\n return;\n }\n const taken =\n this.nodeColumns.some((plan) => plan.column.meta.name === name) ||\n this.idColumns.some((column) => column.meta.name === name);\n if (!taken) {\n return;\n }\n this.note(\n ID_COLUMN_TAKEN_LOSS,\n `node column \"${name}\" already exists; the :ID column cannot be named idColumn \"${name}\"`,\n name,\n null,\n );\n if (this.fatalNodes === null) {\n this.fatalNodes = new GraphFormatError(\n \"E_COLUMN_EXISTS\",\n `node column \"${name}\" already exists; choose another idColumn`,\n { column: name, domain: \"node\" },\n );\n }\n }\n\n /** Count the nodes with more than one stored-id column set. */\n private checkStoredIds(): void {\n if (this.idColumns.length < 2) {\n return;\n }\n let count = 0;\n for (let i = 0; i < this.snapshot.nodeCount; i++) {\n let set = 0;\n for (const column of this.idColumns) {\n if (column.isSet(i)) {\n set++;\n }\n }\n if (set > 1) {\n count++;\n }\n }\n if (count > 0) {\n this.note(\n MULTIPLE_ID_PROPERTIES_LOSS,\n `${count} node${plural(count)} ${agree(count, \"has\", \"have\")} more than one stored-id column set; only the first in declaration order is written`,\n null,\n count,\n );\n }\n }\n\n /**\n * Whether a json column is written as Neo4j points (so the generic nested-value note does not apply).\n * @param name - the column name\n * @returns true when its plan writes point literals\n */\n private writtenAsPoint(name: string): boolean {\n for (const plan of [...this.nodeColumns, ...this.edgeColumns]) {\n if (plan.column.meta.name === name && plan.scalar.kind === \"point\") {\n return true;\n }\n }\n return false;\n }\n\n /** Drop the notes about the part that is not written. */\n private filterNotesByPart(): void {\n const { part } = this.options;\n if (part === \"all\") {\n return;\n }\n const { snapshot } = this;\n const keep = this.notes.filter((n) => {\n if (part === \"nodes\") {\n if (EDGE_NOTE_CODES.has(n.code)) {\n return false;\n }\n return n.column === null || !snapshot.edges.has(n.column) || snapshot.nodes.has(n.column);\n }\n if (NODE_NOTE_CODES.has(n.code)) {\n return false;\n }\n return n.column === null || !snapshot.nodes.has(n.column) || snapshot.edges.has(n.column);\n });\n this.notes.length = 0;\n this.notes.push(...keep);\n }\n\n /**\n * The error export() throws for the requested part, or null when the export can proceed.\n * @returns the error\n */\n get fatal(): GraphFormatError | null {\n if (this.fatalAll !== null) {\n return this.fatalAll;\n }\n const { part } = this.options;\n if (part !== \"relationships\" && this.fatalNodes !== null) {\n return this.fatalNodes;\n }\n return part === \"nodes\" ? null : this.fatalEdges;\n }\n\n /**\n * The id space of a node.\n * @param index - the node index\n * @returns the space name, or null\n */\n spaceOf(index: number): string | null {\n const { idSpace } = this;\n if (!idSpace?.isSet(index)) {\n return null;\n }\n const value = idSpace.value(index);\n return typeof value === \"string\" ? value : String(value);\n }\n\n /**\n * The `:ID` / `:START_ID` / `:END_ID` text of a node: its originalId value when it has an id\n * space (the importer stored it as `Space:id`), its id otherwise.\n * @param index - the node index\n * @returns the id text\n */\n idTextOf(index: number): string {\n const { originalId } = this;\n if (originalId !== null && originalId.isSet(index) && this.spaceOf(index) !== null) {\n return textOf(originalId, index);\n }\n return idText(this.snapshot.ids.idOf(index));\n }\n\n /**\n * The stored-id column of a node: the first one set in declaration order.\n * @param index - the node index\n * @returns the column, or null\n */\n storedIdOf(index: number): Column | null {\n for (const column of this.idColumns) {\n if (column.isSet(index)) {\n return column;\n }\n }\n return null;\n }\n\n /**\n * The node sections, then the relationship sections, as CSV lines.\n * @yields one line at a time (with its line break)\n * @returns nothing\n */\n *lines(): Generator<string, void, undefined> {\n for (const row of this.rows()) {\n yield row.line;\n }\n }\n\n /**\n * The lines of the requested part, each header line tagged with the file it starts.\n * @yields one line at a time, with the file name on a header line\n * @returns nothing\n */\n *rows(): Generator<SectionLine, void, undefined> {\n if (this.fatal !== null) {\n throw this.fatal;\n }\n const { part } = this.options;\n if (part !== \"relationships\") {\n yield* this.nodeLines();\n }\n if (part !== \"nodes\") {\n yield* this.relationshipLines();\n }\n }\n\n /**\n * The requested part as one file per section kind: a node file per id space (and stored-id\n * property), a relationship file per pair of endpoint id spaces, rows of one kind gathered\n * under one header.\n * @returns the files, node files first\n */\n files(): Neo4jFile[] {\n // keyed by the header row: sections with the same header are one file\n const files = new Map<string, { name: string; kind: \"nodes\" | \"relationships\"; rows: string[] }>();\n const names = new Set<string>();\n let current: { rows: string[] } | null = null;\n for (const row of this.rows()) {\n if (row.file !== null) {\n let file = files.get(row.line);\n if (file === undefined) {\n let name = `${row.file.name}.csv`;\n let k = 2;\n while (names.has(name)) {\n name = `${row.file.name}-${k}.csv`;\n k++;\n }\n names.add(name);\n file = { name, kind: row.file.kind, rows: [] };\n files.set(row.line, file);\n }\n current = file;\n } else if (current !== null) {\n current.rows.push(row.line);\n }\n }\n // a part with no rows (a graph without edges) is a header alone, which neo4j-admin does not need\n const written = [...files].filter(([, f], i) => f.rows.length > 0 || (i === 0 && files.size === 1));\n return written.map(([header, f]) =>\n Object.freeze({ name: f.name, kind: f.kind, text: header + f.rows.join(\"\") }),\n );\n }\n\n /**\n * The node sections.\n * @yields one line at a time\n * @returns nothing\n */\n private *nodeLines(): Generator<SectionLine, void, undefined> {\n const { snapshot } = this;\n let sections = 0;\n let sectionSpace: string | null = null;\n let sectionIdName: string | null = null;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const space = this.spaceOf(i);\n const stored = this.storedIdOf(i);\n const idName = stored === null ? (this.options.idColumn ?? \"\") : stored.meta.name;\n if (sections === 0 || space !== sectionSpace || idName !== sectionIdName) {\n sections++;\n sectionSpace = space;\n sectionIdName = idName;\n yield this.nodeHeader(idName, space, space ?? idName);\n }\n yield { line: this.nodeRow(i), file: null };\n }\n if (sections === 0) {\n // no nodes: one header so the section (and its columns) still exists\n yield this.nodeHeader(this.options.idColumn ?? \"\", null, null);\n }\n }\n\n /**\n * The header line of a node section, which starts its file.\n * @param idName - the id column's name\n * @param space - the id space, or null\n * @param fileKey - what names the file, or null for the default name\n * @returns the line\n */\n private nodeHeader(idName: string, space: string | null, fileKey: string | null): SectionLine {\n const { delimiter } = this.options.syntax;\n const header = [formatHeaderField(idName, ID_TYPE, space)];\n if (this.labels !== null) {\n header.push(\":LABEL\");\n }\n const properties = this.nodeColumns.map((plan) => plan.header).join(delimiter);\n if (properties.length > 0) {\n header.push(properties);\n }\n return { line: `${header.join(delimiter)}\\n`, file: { kind: \"nodes\", name: fileName(\"nodes\", fileKey, null) } };\n }\n\n /**\n * One node's line: the id, the labels, the properties.\n * @param i - the node\n * @returns the line\n */\n private nodeRow(i: number): string {\n const cells = [this.cell(this.idTextOf(i))];\n if (this.labels !== null) {\n cells.push(this.cell(this.labelsText(i)));\n }\n for (const plan of this.nodeColumns) {\n cells.push(this.cell(this.valueText(plan, i)));\n }\n return `${cells.join(this.options.syntax.delimiter)}\\n`;\n }\n\n /**\n * The relationship sections.\n * @yields one line at a time\n * @returns nothing\n */\n private *relationshipLines(): Generator<SectionLine, void, undefined> {\n const { snapshot, folding } = this;\n const list = snapshot.edgeList();\n let sections = 0;\n let sectionStart: string | null = null;\n let sectionEnd: string | null = null;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n const u = list.src[e];\n const v = list.dst[e];\n const startSpace = this.spaceOf(u);\n const endSpace = this.spaceOf(v);\n if (sections === 0 || startSpace !== sectionStart || endSpace !== sectionEnd) {\n sections++;\n sectionStart = startSpace;\n sectionEnd = endSpace;\n yield this.relationshipHeader(startSpace, endSpace);\n }\n yield { line: this.relationshipRow(e, u, v), file: null };\n }\n if (sections === 0) {\n yield this.relationshipHeader(null, null);\n }\n }\n\n /**\n * The header line of a relationship section, which starts its file.\n * @param startSpace - the id space of the start nodes, or null\n * @param endSpace - the id space of the end nodes, or null\n * @returns the line\n */\n private relationshipHeader(startSpace: string | null, endSpace: string | null): SectionLine {\n const { delimiter } = this.options.syntax;\n const header = [formatHeaderField(\"\", \"START_ID\", startSpace), formatHeaderField(\"\", \"END_ID\", endSpace)];\n if (this.kind !== null) {\n header.push(\":TYPE\");\n }\n if (this.weights !== null) {\n header.push(formatHeaderField(this.options.weightColumn ?? \"weight\", \"double\", null));\n }\n const properties = this.edgeColumns.map((plan) => plan.header).join(delimiter);\n if (properties.length > 0) {\n header.push(properties);\n }\n return {\n line: `${header.join(delimiter)}\\n`,\n file: { kind: \"relationships\", name: fileName(\"relationships\", startSpace, endSpace) },\n };\n }\n\n /**\n * One relationship's line: the ends, the type, the weight, the properties.\n * @param e - the edge\n * @param u - its source\n * @param v - its target\n * @returns the line\n */\n private relationshipRow(e: number, u: number, v: number): string {\n const { kind, weights } = this;\n const cells = [this.cell(this.idTextOf(u)), this.cell(this.idTextOf(v))];\n if (kind !== null) {\n cells.push(this.cell(kind.isSet(e) ? textOf(kind, e) : null));\n }\n if (weights !== null) {\n cells.push(this.cell(weights.text(e)));\n }\n for (const plan of this.edgeColumns) {\n cells.push(this.cell(this.valueText(plan, e)));\n }\n return `${cells.join(this.options.syntax.delimiter)}\\n`;\n }\n\n /**\n * A CSV cell: empty for an unset value, a quoted empty string for a set empty string, the\n * quoted text otherwise.\n * @param text - the value text, or null for unset\n * @returns the cell as written\n */\n private cell(text: string | null): string {\n if (text === null) {\n return \"\";\n }\n const { quote } = this.options.syntax;\n if (text.length === 0) {\n return quote + quote;\n }\n return quoteCsvCell(text, this.options.syntax.delimiter, quote);\n }\n\n /**\n * The `:LABEL` cell of a node.\n * @param index - the node index\n * @returns the labels joined by the array delimiter, or null when unset\n */\n private labelsText(index: number): string | null {\n const { labels } = this;\n if (!labels?.isSet(index)) {\n return null;\n }\n if (labels.dtype === \"list\") {\n return labels.sliceOf(index).map(String).join(this.options.arrayDelimiter);\n }\n return textOf(labels, index);\n }\n\n /**\n * The text of one property cell.\n * @param plan - the column plan\n * @param row - the row\n * @returns the text, or null when unset\n */\n private valueText(plan: ColumnPlan, row: number): string | null {\n const { column, scalar, companion } = plan;\n if (!column.isSet(row)) {\n return null;\n }\n if (plan.list) {\n return this.listText(plan, row);\n }\n const text = companion?.isSet(row) ? textOf(companion, row) : null;\n return formatScalar(column.dtype === \"json\" ? column.values[row] : column.value(row), scalar, text);\n }\n\n /**\n * The text of one list cell: its items joined by the array delimiter.\n * @param plan - the column plan\n * @param row - the row, which is set\n * @returns the text\n */\n private listText(plan: ColumnPlan, row: number): string {\n const { column, scalar } = plan;\n const items = column.dtype === \"list\" ? column.sliceOf(row) : (column.value(row) as ArrayLike<unknown>);\n const texts: string[] = [];\n for (const item of Array.from(items)) {\n // an item of several components (itemComponents > 1) is flattened into the array\n if (Array.isArray(item) || ArrayBuffer.isView(item)) {\n for (const component of Array.from(item as ArrayLike<unknown>)) {\n texts.push(formatScalar(component, scalar, null));\n }\n } else {\n texts.push(formatScalar(item, scalar, null));\n }\n }\n return texts.join(this.options.arrayDelimiter);\n }\n}\n\n/**\n * Whether a node column is the importer's id text of the nodes of an id space (`originalId`).\n * @param meta - the column metadata\n * @returns true for the role-less string column the Neo4j importer declares with origin id `:ID` and no type\n */\nfunction isIdText(meta: ColumnMeta): boolean {\n return (\n meta.role === null &&\n meta.dtype === \"string\" &&\n meta.origin !== null &&\n meta.origin.format === NEO4J &&\n meta.origin.id === \":ID\" &&\n meta.origin.type === null\n );\n}\n\n/**\n * Whether a node column is a stored id (`name:ID` on import).\n * @param meta - the column metadata\n * @returns true for a string column declared by the Neo4j importer as the id property\n */\nfunction isStoredId(meta: ColumnMeta): boolean {\n return (\n meta.role === null &&\n meta.dtype === \"string\" &&\n meta.origin !== null &&\n meta.origin.format === NEO4J &&\n meta.origin.type === ID_TYPE\n );\n}\n\n/**\n * Whether a role is one of the visual roles.\n * @param role - the role\n * @returns true for color, size, shape and thickness\n */\nfunction isVizRole(role: string): boolean {\n return role === \"color\" || role === \"size\" || role === \"shape\" || role === \"thickness\";\n}\n\n/**\n * The declared scalar type text of a list declaration (`string[]` -> `string`).\n * @param declared - the declared type text\n * @returns the text without its `[]` suffix\n */\nfunction declaredScalar(declared: string): string {\n const trimmed = declared.trim();\n return trimmed.endsWith(\"[]\") ? trimmed.slice(0, -2) : trimmed;\n}\n\n/**\n * The cell kind of a mapped declared type.\n * @param spec - the mapped type\n * @returns the kind\n */\nfunction kindOf(spec: DeclaredTypeSpec): CellKind {\n switch (spec.kind) {\n case \"boolean\":\n return \"boolean\";\n case \"integer\":\n case \"long\":\n return \"integer\";\n case \"float\":\n return \"float\";\n case \"double\":\n return \"double\";\n case \"string\":\n case \"duration\":\n return \"string\";\n case \"temporal\":\n return \"temporal\";\n case \"point\":\n return \"point\";\n case \"json\":\n return \"json\";\n default: {\n const name: string = spec.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown value kind ${name}`, { kind: name });\n }\n }\n}\n\n/**\n * The Neo4j type of a dtype without a compatible declaration.\n * @param dtype - the column or item dtype\n * @returns the type and cell kind\n */\nfunction defaultScalar(dtype: Dtype | ScalarDtype): ScalarPlan {\n switch (dtype) {\n case \"f32\":\n return { type: \"float\", kind: \"float\", temporal: null };\n case \"f64\":\n return { type: \"double\", kind: \"double\", temporal: null };\n case \"i32\":\n case \"u8\":\n return { type: \"int\", kind: \"integer\", temporal: null };\n case \"u32\":\n return { type: \"long\", kind: \"integer\", temporal: null };\n case \"bool\":\n return { type: \"boolean\", kind: \"boolean\", temporal: null };\n case \"dict\":\n case \"string\":\n return { type: \"string\", kind: \"string\", temporal: null };\n case \"json\":\n return { type: \"string\", kind: \"json\", temporal: null };\n case \"list\":\n return { type: \"string\", kind: \"json\", temporal: null };\n default: {\n const name: string = dtype;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dtype ${name}`, { dtype: name });\n }\n }\n}\n\n/**\n * Format a number with a formatter; any other value is written as String(value).\n * @param value - the value\n * @param format - the number formatter\n * @returns the text\n */\nfunction numberOrString(value: unknown, format: (n: number) => string): string {\n return typeof value === \"number\" ? format(value) : String(value);\n}\n\n/**\n * Format one scalar value for a cell.\n * @param value - the value\n * @param scalar - the plan\n * @param text - the companion text of a temporal value, or null\n * @returns the text\n */\nfunction formatScalar(value: unknown, scalar: ScalarPlan, text: string | null): string {\n switch (scalar.kind) {\n case \"integer\":\n return numberOrString(value, formatInteger);\n case \"float\":\n return numberOrString(value, formatF32);\n case \"double\":\n return numberOrString(value, formatF64);\n case \"boolean\":\n return value === true ? \"true\" : \"false\";\n case \"string\":\n return String(value);\n case \"temporal\":\n return (\n text ??\n numberOrString(value, (n) =>\n scalar.temporal === null ? String(n) : formatTemporal(n, scalar.temporal),\n )\n );\n case \"point\":\n return formatPoint(value);\n case \"json\":\n return JSON.stringify(value) ?? \"\";\n default: {\n const name: string = scalar.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown cell kind ${name}`, { kind: name });\n }\n }\n}\n\n/**\n * A Neo4j point literal `{x:1.5, y:2, crs:'cartesian'}` from a point object; any other value is\n * written as JSON text.\n * @param value - the json value\n * @returns the literal\n */\nfunction formatPoint(value: unknown): string {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return JSON.stringify(value) ?? \"\";\n }\n const parts: string[] = [];\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (typeof item === \"number\") {\n parts.push(`${key}:${formatF64(item)}`);\n } else if (typeof item === \"string\") {\n parts.push(`${key}:'${item.replaceAll(\"'\", \"\")}'`);\n } else {\n return JSON.stringify(value) ?? \"\";\n }\n }\n return `{${parts.join(\", \")}}`;\n}\n\n/**\n * The text of a node id.\n * @param id - the id\n * @returns String(id)\n */\nfunction idText(id: NodeId): string {\n if (typeof id === \"string\") {\n return id;\n }\n return Number.isInteger(id) ? formatInteger(id) : String(id);\n}\n\n/**\n * The text of a set cell of a dict / string (or any scalar) column.\n * @param column - the column\n * @param row - the row\n * @returns the value as text\n */\nfunction textOf(column: Column, row: number): string {\n switch (column.dtype) {\n case \"string\":\n return column.valueAt(row);\n case \"dict\":\n return String(column.value(row));\n case \"list\":\n return column.sliceOf(row).map(String).join(\",\");\n case \"json\":\n return JSON.stringify(column.values[row]) ?? \"\";\n case \"bool\":\n return column.value(row) === true ? \"true\" : \"false\";\n default: {\n const value = column.value(row);\n return typeof value === \"number\" ? String(value) : Array.from(value as ArrayLike<number>).join(\",\");\n }\n }\n}\n\n/**\n * The Neo4j exporter.\n * @category Built-in formats\n */\nexport const neo4jExporter: GraphExporter<Neo4jExportOptions> = Object.freeze({\n format: NEO4J,\n options: Object.freeze([\"arrayDelimiter\", \"delimiter\", \"idColumn\", \"part\", \"quote\", \"weightColumn\"]),\n capabilities: NEO4J_CAPABILITIES,\n /**\n * Pre-flight: what export() would lose.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the notes\n */\n check(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): readonly LossNote[] {\n return Object.freeze([...plan(snapshot, options).notes]);\n },\n /**\n * Write the snapshot as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(plan(snapshot, options).lines());\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): Promise<string> {\n return joinText(plan(snapshot, options).lines());\n },\n});\n\n/** One line of the export; a header line names the file it starts. */\ninterface SectionLine {\n readonly line: string;\n readonly file: { readonly kind: \"nodes\" | \"relationships\"; readonly name: string } | null;\n}\n\n/**\n * One file of exportNeo4jFiles(): the header row and the rows of one section kind.\n * @category Built-in formats\n */\nexport interface Neo4jFile {\n /** A file name made from the section: `nodes-Movie.csv`, `relationships-Person-Movie.csv`, or `nodes.csv` and `relationships.csv` without id spaces. */\n readonly name: string;\n /** Whether neo4j-admin takes the file with `--nodes` or with `--relationships`. */\n readonly kind: \"nodes\" | \"relationships\";\n /** The CSV text, one header row first. */\n readonly text: string;\n}\n\n/**\n * The file name of a section, without \".csv\": the kind, then the id spaces that set it apart.\n * @param kind - \"nodes\" or \"relationships\"\n * @param first - the id space or id property (nodes), or the start id space (relationships)\n * @param second - the end id space (relationships)\n * @returns the name, with characters outside letters, digits, \".\" , \"_\" and \"-\" replaced by \"_\"\n */\nfunction fileName(kind: string, first: string | null, second: string | null): string {\n const parts = [kind, first ?? \"\", second ?? \"\"].filter((p) => p !== \"\");\n return parts.join(\"-\").replaceAll(/[^\\w.-]/g, \"_\");\n}\n\n/**\n * Write a graph as the separate CSV files `neo4j-admin database import` takes: one node file per id\n * space and one relationship file per pair of endpoint id spaces, each with a single header row.\n * `exportGraph(snapshot, \"neo4j\")` writes the same sections into one file, which graph-io reads\n * back but neo4j-admin does not, since it reads one header per file. The options are the Neo4j\n * export options (`part` limits the result to the node or the relationship files), and\n * `checkExport(snapshot, \"neo4j\", options)` returns what the files lose.\n * @param snapshot - the graph to write\n * @param options - the Neo4j export options\n * @returns the files, node files first\n * @category Built-in formats\n * @example\n * ```ts\n * for (const file of await exportNeo4jFiles(snapshot)) {\n * await writeFile(file.name, file.text);\n * }\n * // neo4j-admin database import full --nodes=nodes-Movie.csv --nodes=nodes-Person.csv \\\n * // --relationships=relationships-Person-Movie.csv neo4j\n * ```\n */\nexport function exportNeo4jFiles(\n snapshot: GraphSnapshot,\n options?: Neo4jExportOptions & CommonExportOptions,\n): Promise<Neo4jFile[]> {\n try {\n return Promise.resolve(plan(snapshot, options).files());\n } catch (err) {\n return Promise.reject(err);\n }\n}\n\n/**\n * Build the export plan of a snapshot.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction plan(snapshot: GraphSnapshot, options: (Neo4jExportOptions & CommonExportOptions) | undefined): ExportPlan {\n return new ExportPlan(\n snapshot,\n resolveNeo4jExportOptions(options, weightPropertyOf(snapshot)),\n resolveExportOptions(options),\n );\n}\n\n/**\n * The relationship property a Neo4j import read the weights from, when it was not \"weight\".\n * @param snapshot - the snapshot\n * @returns the property name, or null\n */\nfunction weightPropertyOf(snapshot: GraphSnapshot): string | null {\n const neo4j = (snapshot.meta.extra as { neo4j?: { weightProperty?: unknown } } | null)?.neo4j;\n const name = neo4j?.weightProperty;\n return typeof name === \"string\" && name !== \"\" ? name : null;\n}\n\n/**\n * Whether every set value of an f64 column, or of an f64 list column's items, is integral.\n * @param column - the column\n * @returns false when a value is not an integer\n */\nfunction holdsOnlyIntegers(column: Column): boolean {\n if (column.dtype === \"f64\") {\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && !Number.isInteger(column.data[r])) {\n return false;\n }\n }\n } else if (column.dtype === \"list\" && column.child.dtype === \"f64\") {\n const { data } = column.child;\n for (let i = 0; i < data.length; i++) {\n if (!Number.isInteger(data[i])) {\n return false;\n }\n }\n }\n return true;\n}\n","/**\n * The `@graphty/graph-io/neo4j` subpath: the Neo4j importer and exporter with their option types,\n * the names of the reserved columns and the issue and loss-note codes\n * grouped in two tables.\n * @module @graphty/graph-io/neo4j\n */\n\nimport {\n COLUMN_RENAMED_CODE,\n COLUMN_TYPE_CODE,\n ELEMENT_ISSUE,\n ENCODING_FALLBACK_CODE,\n INPUT_ISSUE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MUTUAL_EXPANDED_CODE,\n OPTION_IGNORED_CODE,\n PRECISION_CODE,\n ROLE_DROPPED_CODE,\n SINK_OPTION_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ENCODING_CODE,\n WEIGHT_KEY_CLASH_CODE,\n} from \"../../common/codes.js\";\nimport { BAD_QUOTE_CODE, UNCLOSED_QUOTE_CODE } from \"../csv/records.js\";\nimport {\n ARRAY_DELIMITER_LOSS,\n DECLARED_TYPE_CHANGED_LOSS,\n ID_COLUMN_TAKEN_LOSS,\n ID_TEXT_COLLISION_LOSS,\n ID_TEXT_TYPE_LOSS,\n MULTIPLE_ID_PROPERTIES_LOSS,\n UNDIRECTED_LOSS,\n WEIGHT_COLUMN_TAKEN_LOSS,\n} from \"./exporter.js\";\nimport {\n COLUMN_COUNT_CODE,\n DANGLING_REFERENCE_CODE,\n DUPLICATE_NODE_CODE,\n ENDPOINT_SPACE_CODE,\n HEADER_CODE,\n HEADER_OPTION_CODE,\n ID_MERGED_CODE,\n ID_SPACE_COLLISION_CODE,\n IGNORED_COLUMNS_LOSS,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MISSING_TYPE_CODE,\n ROLE_TAKEN_CODE,\n SECTION_KIND_CODE,\n} from \"./importer.js\";\n\nexport {\n exportNeo4jFiles,\n NEO4J_CAPABILITIES,\n neo4jExporter,\n type Neo4jExportOptions,\n type Neo4jFile,\n} from \"./exporter.js\";\nexport {\n ID_SPACE_COLUMN,\n LABELS_COLUMN,\n neo4jImporter,\n type Neo4jImportOptions,\n ORIGINAL_ID_COLUMN,\n TYPE_COLUMN,\n} from \"./importer.js\";\n\n/**\n * The issue codes the Neo4j importer records, by name: the codes shared with\n * the other importers and the Neo4j-specific ones.\n * A key is the code without its severity and format prefixes.\n * @category Built-in formats\n */\nexport const NEO4J_ISSUE = Object.freeze({\n ...INPUT_ISSUE,\n ...ELEMENT_ISSUE,\n /**\n * A cell that does not parse as its column's declared type (\"x\" in an `:int` column, a `:byte` beyond 127). The\n * row is skipped.\n */\n COLUMN_TYPE: COLUMN_TYPE_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 quoted field is never closed. The import stops. */\n CSV_UNCLOSED_QUOTE: UNCLOSED_QUOTE_CODE,\n /**\n * There is text after a closing quote, such as `\"a\"b`. Inside a quoted field, write a quote as two quotes. The\n * import stops.\n */\n CSV_QUOTE: BAD_QUOTE_CODE,\n /** The file has no header, or a header neo4j-admin would refuse. The import stops. */\n HEADER: HEADER_CODE,\n /** A row with a different field count than the header. */\n COLUMN_COUNT: COLUMN_COUNT_CODE,\n /** A node row without an id. */\n MISSING_ID: MISSING_ID_CODE,\n /** A relationship row without a start or end id. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A node id repeated in one id space (last write wins). */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A spaced node id `Space:id` that equals the text of an id declared without a space. */\n ID_SPACE_COLLISION: ID_SPACE_COLLISION_CODE,\n /** A spaced relationship endpoint `Space:id` that names a node declared without a space; the row is skipped. */\n ENDPOINT_SPACE: ENDPOINT_SPACE_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 /** A header brace option the importer does not apply. */\n HEADER_OPTION_IGNORED: HEADER_OPTION_CODE,\n /** A declared type the format does not define (kept as string). */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: \"string\"` to keep every digit. */\n PRECISION: PRECISION_CODE,\n /**\n * An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example a\n * repeated column header.\n */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /**\n * You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as\n * a plain attribute.\n */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** You set an option this format does not use; it had no effect. The message names the option. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /**\n * You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,\n * `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.\n */\n SINK_OPTION: SINK_OPTION_CODE,\n /** A relationship with an empty :TYPE cell (neo4j-admin requires one); kept without a type. */\n MISSING_TYPE: MISSING_TYPE_CODE,\n /** A file under the nodes option holds a relationship header, or the reverse; read by its header. */\n SECTION_KIND: SECTION_KIND_CODE,\n /** Relationship endpoints no node row declares became nodes (neo4j-admin refuses them). */\n DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,\n});\n\n/**\n * The loss-note codes of the Neo4j importer (report.lossy) and exporter (check()), by name: the\n * Neo4j ones and, aliased, the shared ones it records (`LOSS` holds the generic pre-flight's).\n * @category Built-in formats\n */\nexport const NEO4J_LOSS = Object.freeze({\n /** `:IGNORE` columns skipped on import. */\n IGNORED_COLUMNS: IGNORED_COLUMNS_LOSS,\n /**\n * Neo4j relationships are always directed, so the edges of an undirected graph, and the undirected edges of a\n * mixed graph, read back as directed.\n */\n UNDIRECTED_AS_DIRECTED: UNDIRECTED_LOSS,\n /** A mutual pair written as two directed relationships without its mark. */\n MUTUAL_EXPANDED: MUTUAL_EXPANDED_CODE,\n /** An attribute with a role the format has no place for is written as a plain attribute; the role is lost. */\n ROLE_DROPPED: ROLE_DROPPED_CODE,\n /**\n * An edge attribute named `weight` that is not the graph's weight reads back as the edge weight, because the\n * Neo4j importer reads weights from the `weight` property by default.\n */\n WEIGHT_KEY_CLASH: WEIGHT_KEY_CLASH_CODE,\n /**\n * A node id that reads back as a different type, such as the text \"7\" as the number 7. Read the file with `ids:\n * \"string\"` or `ids: \"keep\"` to keep the type.\n */\n ID_TEXT_TYPE: ID_TEXT_TYPE_LOSS,\n /** Two node ids would be written as the same text (the number 5 and the text \"5\"); the save fails with E_INVALID_ID. */\n ID_TEXT_COLLISION: ID_TEXT_COLLISION_LOSS,\n /** The `weightColumn` name is already an edge attribute; the save fails. */\n WEIGHT_COLUMN_TAKEN: WEIGHT_COLUMN_TAKEN_LOSS,\n /** The `idColumn` name is already a node attribute; the save fails. */\n ID_COLUMN_TAKEN: ID_COLUMN_TAKEN_LOSS,\n /** Several stored-id properties; one becomes the `:ID` column. */\n MULTIPLE_ID_PROPERTIES: MULTIPLE_ID_PROPERTIES_LOSS,\n /** An integer-typed column with non-integral values written as double. */\n DECLARED_TYPE_CHANGED: DECLARED_TYPE_CHANGED_LOSS,\n /** A list item containing the array delimiter, which Neo4j cannot escape. */\n ARRAY_DELIMITER: ARRAY_DELIMITER_LOSS,\n});\n"],"names":["headerError","SHARED_MISSING_ID_CODE","SHARED_MISSING_ENDPOINT_CODE","SHARED_DUPLICATE_NODE_CODE","SHARED_ID_MERGED_CODE","SHARED_ROLE_TAKEN_CODE","SHARED_DANGLING_REFERENCE_CODE","NEO4J","idText","compatible","scalar","plan"],"mappings":"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"}
|