@graphty/graph-io 0.3.47 → 0.3.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{approximations-wWjCRzKj.js → approximations-C2riR4NT.js} +2 -2
- package/dist/chunks/{approximations-wWjCRzKj.js.map → approximations-C2riR4NT.js.map} +1 -1
- package/dist/chunks/{block-DiGq58c3.js → block-Cu22ewuS.js} +92 -21
- package/dist/chunks/block-Cu22ewuS.js.map +1 -0
- package/dist/chunks/{choose--jM0yYCo.js → choose-Cdx6Enl2.js} +3 -3
- package/dist/chunks/{choose--jM0yYCo.js.map → choose-Cdx6Enl2.js.map} +1 -1
- package/dist/chunks/codes-CV_Bhcyi.js +153 -0
- package/dist/chunks/codes-CV_Bhcyi.js.map +1 -0
- package/dist/chunks/{constants-BKwqelYD.js → constants-D0LqcsLJ.js} +2 -2
- package/dist/chunks/{constants-BKwqelYD.js.map → constants-D0LqcsLJ.js.map} +1 -1
- package/dist/chunks/context-cgmmOxZ2.js +663 -0
- package/dist/chunks/context-cgmmOxZ2.js.map +1 -0
- package/dist/chunks/credentials-BiQsnMTb.js +347 -0
- package/dist/chunks/credentials-BiQsnMTb.js.map +1 -0
- package/dist/chunks/cx-export-BEeF6ymo.js +259 -0
- package/dist/chunks/cx-export-BEeF6ymo.js.map +1 -0
- package/dist/chunks/descriptor-BJ-W0Jd-.js +137 -0
- package/dist/chunks/descriptor-BJ-W0Jd-.js.map +1 -0
- package/dist/chunks/descriptor-C-YDhtsn.js +48 -0
- package/dist/chunks/descriptor-C-YDhtsn.js.map +1 -0
- package/dist/chunks/{emit-CwU8cUmG.js → emit-CD8xnY8s.js} +70 -10
- package/dist/chunks/emit-CD8xnY8s.js.map +1 -0
- package/dist/chunks/{escape-CgzxiYPg.js → escape-DH2Egt-l.js} +12 -12
- package/dist/chunks/{escape-CgzxiYPg.js.map → escape-DH2Egt-l.js.map} +1 -1
- package/dist/chunks/{export-BvqAXCKh.js → export-CZ7VRm4I.js} +53 -1443
- package/dist/chunks/export-CZ7VRm4I.js.map +1 -0
- package/dist/chunks/{exporter-DndFlGSa.js → exporter-BIdaoIgh.js} +7 -6
- package/dist/chunks/{exporter-DndFlGSa.js.map → exporter-BIdaoIgh.js.map} +1 -1
- package/dist/chunks/{exporter-CJgfhF-l.js → exporter-ChjL5fmP.js} +8 -7
- package/dist/chunks/{exporter-CJgfhF-l.js.map → exporter-ChjL5fmP.js.map} +1 -1
- package/dist/chunks/{exporter--Mk9gXCJ.js → exporter-Dcw7Ldtq.js} +6 -4
- package/dist/chunks/{exporter--Mk9gXCJ.js.map → exporter-Dcw7Ldtq.js.map} +1 -1
- package/dist/chunks/exporter-DtVU80Fa.js +1008 -0
- package/dist/chunks/exporter-DtVU80Fa.js.map +1 -0
- package/dist/chunks/{exporter-CrDWIyiq.js → exporter-bxxjOrDZ.js} +11 -9
- package/dist/chunks/{exporter-CrDWIyiq.js.map → exporter-bxxjOrDZ.js.map} +1 -1
- package/dist/chunks/format-BMS-1Nxb.js +64 -0
- package/dist/chunks/format-BMS-1Nxb.js.map +1 -0
- package/dist/chunks/{generic-Dq1ntt9q.js → generic-CP6YD34u.js} +4 -4
- package/dist/chunks/{generic-Dq1ntt9q.js.map → generic-CP6YD34u.js.map} +1 -1
- package/dist/chunks/{importer-DiZRmOQG.js → importer-B87_fmVx.js} +13 -17
- package/dist/chunks/importer-B87_fmVx.js.map +1 -0
- package/dist/chunks/{importer-BSvfrX_h.js → importer-Bji2MeWr.js} +18 -1014
- package/dist/chunks/importer-Bji2MeWr.js.map +1 -0
- package/dist/chunks/{importer-COTK9Tsl.js → importer-CB_zV5_L.js} +14 -11
- package/dist/chunks/importer-CB_zV5_L.js.map +1 -0
- package/dist/chunks/{importer-e6LGpqHB.js → importer-CVT-JyDE.js} +12 -9
- package/dist/chunks/importer-CVT-JyDE.js.map +1 -0
- package/dist/chunks/{importer-yh_aBCU6.js → importer-Cyy6UseH.js} +7 -6
- package/dist/chunks/{importer-yh_aBCU6.js.map → importer-Cyy6UseH.js.map} +1 -1
- package/dist/chunks/{importer-iFYPEKaJ.js → importer-DPZDN40-.js} +14 -10
- package/dist/chunks/{importer-iFYPEKaJ.js.map → importer-DPZDN40-.js.map} +1 -1
- package/dist/chunks/{importer-CMmeMWlC.js → importer-e3huMZbm.js} +8 -260
- package/dist/chunks/importer-e3huMZbm.js.map +1 -0
- package/dist/chunks/input-Ccg9I22A.js +1397 -0
- package/dist/chunks/input-Ccg9I22A.js.map +1 -0
- package/dist/chunks/{json-elements-DJZRZ6jd.js → json-elements-By172SVq.js} +4 -4
- package/dist/chunks/{json-elements-DJZRZ6jd.js.map → json-elements-By172SVq.js.map} +1 -1
- package/dist/chunks/{lexicon-CT69Kd87.js → lexicon-u2SI5xcx.js} +19 -5
- package/dist/chunks/lexicon-u2SI5xcx.js.map +1 -0
- package/dist/chunks/{ontology-export-G4MqRdux.js → ontology-export-BwgMyuF0.js} +4 -3
- package/dist/chunks/{ontology-export-G4MqRdux.js.map → ontology-export-BwgMyuF0.js.map} +1 -1
- package/dist/chunks/{records-CiaWZrFH.js → records-Cgvxz-Vx.js} +2 -2
- package/dist/chunks/{records-CiaWZrFH.js.map → records-Cgvxz-Vx.js.map} +1 -1
- package/dist/chunks/{format-BpQBx8MZ.js → report-CgdsL9Hb.js} +72 -129
- package/dist/chunks/report-CgdsL9Hb.js.map +1 -0
- package/dist/chunks/sigv4-LkAzsLAu.js +247 -0
- package/dist/chunks/sigv4-LkAzsLAu.js.map +1 -0
- package/dist/chunks/{styles-BQnsga7p.js → styles-CaABMoO1.js} +76 -43
- package/dist/chunks/styles-CaABMoO1.js.map +1 -0
- package/dist/chunks/{styles-D3fRphrO.js → styles-P_gmFAOi.js} +101 -21
- package/dist/chunks/styles-P_gmFAOi.js.map +1 -0
- package/dist/chunks/{styles-yed-BF5x3_Y5.js → styles-yed-Cs1nmrjn.js} +60 -20
- package/dist/chunks/styles-yed-Cs1nmrjn.js.map +1 -0
- package/dist/chunks/{text-CzJNFOS9.js → text-BuKQVMz2.js} +2 -2
- package/dist/chunks/{text-CzJNFOS9.js.map → text-BuKQVMz2.js.map} +1 -1
- package/dist/chunks/{writer-DMKvthQE.js → writer-DvHTl36J.js} +5 -4
- package/dist/chunks/writer-DvHTl36J.js.map +1 -0
- package/dist/csv.js +7 -5
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +5 -4
- package/dist/cx.js.map +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +2 -2
- package/dist/gexf.js +7 -5
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +16 -13
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +1181 -224
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +3 -3
- package/dist/json.js +1 -1
- package/dist/neo4j.js +6 -4
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/sources-cypher.d.ts +1 -0
- package/dist/sources-cypher.js +1236 -0
- package/dist/sources-cypher.js.map +1 -0
- package/dist/sources-ndex.d.ts +1 -0
- package/dist/sources-ndex.js +278 -0
- package/dist/sources-ndex.js.map +1 -0
- package/dist/sources-rest.d.ts +1 -0
- package/dist/sources-rest.js +1367 -0
- package/dist/sources-rest.js.map +1 -0
- package/dist/src/common/report.d.ts +6 -3
- package/dist/src/common/report.d.ts.map +1 -1
- package/dist/src/common/report.js +15 -9
- package/dist/src/common/report.js.map +1 -1
- package/dist/src/formats/cx/styles.d.ts.map +1 -1
- package/dist/src/formats/cx/styles.js +1 -0
- package/dist/src/formats/cx/styles.js.map +1 -1
- package/dist/src/formats/dot/styles.d.ts.map +1 -1
- package/dist/src/formats/dot/styles.js +3 -1
- package/dist/src/formats/dot/styles.js.map +1 -1
- package/dist/src/formats/gexf/styles.d.ts +29 -12
- package/dist/src/formats/gexf/styles.d.ts.map +1 -1
- package/dist/src/formats/gexf/styles.js +160 -31
- package/dist/src/formats/gexf/styles.js.map +1 -1
- package/dist/src/formats/gml/styles.d.ts.map +1 -1
- package/dist/src/formats/gml/styles.js +5 -4
- package/dist/src/formats/gml/styles.js.map +1 -1
- package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-plain.js +3 -3
- package/dist/src/formats/graphml/styles-plain.js.map +1 -1
- package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-yed.js +89 -19
- package/dist/src/formats/graphml/styles-yed.js.map +1 -1
- package/dist/src/formats/pajek/styles.d.ts.map +1 -1
- package/dist/src/formats/pajek/styles.js +1 -0
- package/dist/src/formats/pajek/styles.js.map +1 -1
- package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
- package/dist/src/formats/xgmml/styles.js +1 -0
- package/dist/src/formats/xgmml/styles.js.map +1 -1
- package/dist/src/index.d.ts +8 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts +173 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +196 -1
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sources/builtins.d.ts +11 -0
- package/dist/src/sources/builtins.d.ts.map +1 -0
- package/dist/src/sources/builtins.js +47 -0
- package/dist/src/sources/builtins.js.map +1 -0
- package/dist/src/sources/codes.d.ts +230 -0
- package/dist/src/sources/codes.d.ts.map +1 -0
- package/dist/src/sources/codes.js +58 -0
- package/dist/src/sources/codes.js.map +1 -0
- package/dist/src/sources/context.d.ts +112 -0
- package/dist/src/sources/context.d.ts.map +1 -0
- package/dist/src/sources/context.js +739 -0
- package/dist/src/sources/context.js.map +1 -0
- package/dist/src/sources/credentials.d.ts +179 -0
- package/dist/src/sources/credentials.d.ts.map +1 -0
- package/dist/src/sources/credentials.js +301 -0
- package/dist/src/sources/credentials.js.map +1 -0
- package/dist/src/sources/cypher/descriptor.d.ts +21 -0
- package/dist/src/sources/cypher/descriptor.d.ts.map +1 -0
- package/dist/src/sources/cypher/descriptor.js +119 -0
- package/dist/src/sources/cypher/descriptor.js.map +1 -0
- package/dist/src/sources/cypher/flatten.d.ts +72 -0
- package/dist/src/sources/cypher/flatten.d.ts.map +1 -0
- package/dist/src/sources/cypher/flatten.js +279 -0
- package/dist/src/sources/cypher/flatten.js.map +1 -0
- package/dist/src/sources/cypher/index.d.ts +33 -0
- package/dist/src/sources/cypher/index.d.ts.map +1 -0
- package/dist/src/sources/cypher/index.js +405 -0
- package/dist/src/sources/cypher/index.js.map +1 -0
- package/dist/src/sources/cypher/params.d.ts +40 -0
- package/dist/src/sources/cypher/params.d.ts.map +1 -0
- package/dist/src/sources/cypher/params.js +6 -0
- package/dist/src/sources/cypher/params.js.map +1 -0
- package/dist/src/sources/cypher/profiles.d.ts +44 -0
- package/dist/src/sources/cypher/profiles.d.ts.map +1 -0
- package/dist/src/sources/cypher/profiles.js +61 -0
- package/dist/src/sources/cypher/profiles.js.map +1 -0
- package/dist/src/sources/cypher/query-builder.d.ts +106 -0
- package/dist/src/sources/cypher/query-builder.d.ts.map +1 -0
- package/dist/src/sources/cypher/query-builder.js +236 -0
- package/dist/src/sources/cypher/query-builder.js.map +1 -0
- package/dist/src/sources/cypher/transports/bolt.d.ts +21 -0
- package/dist/src/sources/cypher/transports/bolt.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/bolt.js +185 -0
- package/dist/src/sources/cypher/transports/bolt.js.map +1 -0
- package/dist/src/sources/cypher/transports/neptune-analytics.d.ts +15 -0
- package/dist/src/sources/cypher/transports/neptune-analytics.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/neptune-analytics.js +38 -0
- package/dist/src/sources/cypher/transports/neptune-analytics.js.map +1 -0
- package/dist/src/sources/cypher/transports/neptune-https.d.ts +31 -0
- package/dist/src/sources/cypher/transports/neptune-https.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/neptune-https.js +104 -0
- package/dist/src/sources/cypher/transports/neptune-https.js.map +1 -0
- package/dist/src/sources/cypher/transports/query-api.d.ts +14 -0
- package/dist/src/sources/cypher/transports/query-api.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/query-api.js +80 -0
- package/dist/src/sources/cypher/transports/query-api.js.map +1 -0
- package/dist/src/sources/cypher/transports/transport.d.ts +78 -0
- package/dist/src/sources/cypher/transports/transport.d.ts.map +1 -0
- package/dist/src/sources/cypher/transports/transport.js +77 -0
- package/dist/src/sources/cypher/transports/transport.js.map +1 -0
- package/dist/src/sources/cypher/types-map.d.ts +91 -0
- package/dist/src/sources/cypher/types-map.d.ts.map +1 -0
- package/dist/src/sources/cypher/types-map.js +306 -0
- package/dist/src/sources/cypher/types-map.js.map +1 -0
- package/dist/src/sources/define.d.ts +47 -0
- package/dist/src/sources/define.d.ts.map +1 -0
- package/dist/src/sources/define.js +173 -0
- package/dist/src/sources/define.js.map +1 -0
- package/dist/src/sources/fail.d.ts +33 -0
- package/dist/src/sources/fail.d.ts.map +1 -0
- package/dist/src/sources/fail.js +49 -0
- package/dist/src/sources/fail.js.map +1 -0
- package/dist/src/sources/ids.d.ts +64 -0
- package/dist/src/sources/ids.d.ts.map +1 -0
- package/dist/src/sources/ids.js +64 -0
- package/dist/src/sources/ids.js.map +1 -0
- package/dist/src/sources/ndex/client.d.ts +31 -0
- package/dist/src/sources/ndex/client.d.ts.map +1 -0
- package/dist/src/sources/ndex/client.js +90 -0
- package/dist/src/sources/ndex/client.js.map +1 -0
- package/dist/src/sources/ndex/descriptor.d.ts +10 -0
- package/dist/src/sources/ndex/descriptor.d.ts.map +1 -0
- package/dist/src/sources/ndex/descriptor.js +55 -0
- package/dist/src/sources/ndex/descriptor.js.map +1 -0
- package/dist/src/sources/ndex/expand.d.ts +20 -0
- package/dist/src/sources/ndex/expand.d.ts.map +1 -0
- package/dist/src/sources/ndex/expand.js +87 -0
- package/dist/src/sources/ndex/expand.js.map +1 -0
- package/dist/src/sources/ndex/index.d.ts +25 -0
- package/dist/src/sources/ndex/index.d.ts.map +1 -0
- package/dist/src/sources/ndex/index.js +191 -0
- package/dist/src/sources/ndex/index.js.map +1 -0
- package/dist/src/sources/ndex/params.d.ts +17 -0
- package/dist/src/sources/ndex/params.d.ts.map +1 -0
- package/dist/src/sources/ndex/params.js +6 -0
- package/dist/src/sources/ndex/params.js.map +1 -0
- package/dist/src/sources/ndex/share-url.d.ts +40 -0
- package/dist/src/sources/ndex/share-url.d.ts.map +1 -0
- package/dist/src/sources/ndex/share-url.js +64 -0
- package/dist/src/sources/ndex/share-url.js.map +1 -0
- package/dist/src/sources/params.d.ts +28 -0
- package/dist/src/sources/params.d.ts.map +1 -0
- package/dist/src/sources/params.js +6 -0
- package/dist/src/sources/params.js.map +1 -0
- package/dist/src/sources/registry.d.ts +118 -0
- package/dist/src/sources/registry.d.ts.map +1 -0
- package/dist/src/sources/registry.js +193 -0
- package/dist/src/sources/registry.js.map +1 -0
- package/dist/src/sources/rest/descriptor.d.ts +16 -0
- package/dist/src/sources/rest/descriptor.d.ts.map +1 -0
- package/dist/src/sources/rest/descriptor.js +71 -0
- package/dist/src/sources/rest/descriptor.js.map +1 -0
- package/dist/src/sources/rest/index.d.ts +14 -0
- package/dist/src/sources/rest/index.d.ts.map +1 -0
- package/dist/src/sources/rest/index.js +13 -0
- package/dist/src/sources/rest/index.js.map +1 -0
- package/dist/src/sources/rest/mapping.d.ts +30 -0
- package/dist/src/sources/rest/mapping.d.ts.map +1 -0
- package/dist/src/sources/rest/mapping.js +362 -0
- package/dist/src/sources/rest/mapping.js.map +1 -0
- package/dist/src/sources/rest/openalex.d.ts +27 -0
- package/dist/src/sources/rest/openalex.d.ts.map +1 -0
- package/dist/src/sources/rest/openalex.js +269 -0
- package/dist/src/sources/rest/openalex.js.map +1 -0
- package/dist/src/sources/rest/paging.d.ts +53 -0
- package/dist/src/sources/rest/paging.d.ts.map +1 -0
- package/dist/src/sources/rest/paging.js +138 -0
- package/dist/src/sources/rest/paging.js.map +1 -0
- package/dist/src/sources/rest/params.d.ts +216 -0
- package/dist/src/sources/rest/params.d.ts.map +1 -0
- package/dist/src/sources/rest/params.js +7 -0
- package/dist/src/sources/rest/params.js.map +1 -0
- package/dist/src/sources/rest/records.d.ts +41 -0
- package/dist/src/sources/rest/records.d.ts.map +1 -0
- package/dist/src/sources/rest/records.js +240 -0
- package/dist/src/sources/rest/records.js.map +1 -0
- package/dist/src/sources/rest/samples/deps-dev.d.ts +10 -0
- package/dist/src/sources/rest/samples/deps-dev.d.ts.map +1 -0
- package/dist/src/sources/rest/samples/deps-dev.js +47 -0
- package/dist/src/sources/rest/samples/deps-dev.js.map +1 -0
- package/dist/src/sources/rest/samples/string.d.ts +9 -0
- package/dist/src/sources/rest/samples/string.d.ts.map +1 -0
- package/dist/src/sources/rest/samples/string.js +42 -0
- package/dist/src/sources/rest/samples/string.js.map +1 -0
- package/dist/src/sources/rest/selectors.d.ts +41 -0
- package/dist/src/sources/rest/selectors.d.ts.map +1 -0
- package/dist/src/sources/rest/selectors.js +81 -0
- package/dist/src/sources/rest/selectors.js.map +1 -0
- package/dist/src/sources/rest/source.d.ts +67 -0
- package/dist/src/sources/rest/source.d.ts.map +1 -0
- package/dist/src/sources/rest/source.js +635 -0
- package/dist/src/sources/rest/source.js.map +1 -0
- package/dist/src/sources/rest/templates.d.ts +38 -0
- package/dist/src/sources/rest/templates.d.ts.map +1 -0
- package/dist/src/sources/rest/templates.js +125 -0
- package/dist/src/sources/rest/templates.js.map +1 -0
- package/dist/src/sources/run.d.ts +93 -0
- package/dist/src/sources/run.d.ts.map +1 -0
- package/dist/src/sources/run.js +673 -0
- package/dist/src/sources/run.js.map +1 -0
- package/dist/src/sources/sha256.d.ts +12 -0
- package/dist/src/sources/sha256.d.ts.map +1 -0
- package/dist/src/sources/sha256.js +95 -0
- package/dist/src/sources/sha256.js.map +1 -0
- package/dist/src/sources/sigv4.d.ts +24 -0
- package/dist/src/sources/sigv4.d.ts.map +1 -0
- package/dist/src/sources/sigv4.js +182 -0
- package/dist/src/sources/sigv4.js.map +1 -0
- package/dist/src/sources/testing.d.ts +96 -0
- package/dist/src/sources/testing.d.ts.map +1 -0
- package/dist/src/sources/testing.js +138 -0
- package/dist/src/sources/testing.js.map +1 -0
- package/dist/src/sources/types.d.ts +665 -0
- package/dist/src/sources/types.d.ts.map +1 -0
- package/dist/src/sources/types.js +10 -0
- package/dist/src/sources/types.js.map +1 -0
- package/dist/src/styles/canon/enums.d.ts.map +1 -1
- package/dist/src/styles/canon/enums.js +1 -0
- package/dist/src/styles/canon/enums.js.map +1 -1
- package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
- package/dist/src/styles/cyjs/cascade.js +68 -2
- package/dist/src/styles/cyjs/cascade.js.map +1 -1
- package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
- package/dist/src/styles/cyjs/defaults-table.js +2 -0
- package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
- package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
- package/dist/src/styles/cyjs/emit.js +18 -7
- package/dist/src/styles/cyjs/emit.js.map +1 -1
- package/dist/src/styles/cyjs/mappers.d.ts +4 -1
- package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
- package/dist/src/styles/cyjs/mappers.js +2 -0
- package/dist/src/styles/cyjs/mappers.js.map +1 -1
- package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/emit.js +59 -7
- package/dist/src/styles/cytoscape/emit.js.map +1 -1
- package/dist/src/styles/cytoscape/lexicon.d.ts +6 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/lexicon.js +26 -2
- package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
- package/dist/src/styles/cytoscape/resolve.d.ts +4 -1
- package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/resolve.js +10 -6
- package/dist/src/styles/cytoscape/resolve.js.map +1 -1
- package/dist/src/styles/cytoscape/translate.d.ts.map +1 -1
- package/dist/src/styles/cytoscape/translate.js +10 -10
- package/dist/src/styles/cytoscape/translate.js.map +1 -1
- package/dist/src/styles/defaults.d.ts +30 -0
- package/dist/src/styles/defaults.d.ts.map +1 -1
- package/dist/src/styles/defaults.js +45 -4
- package/dist/src/styles/defaults.js.map +1 -1
- package/dist/src/styles/io/block.d.ts.map +1 -1
- package/dist/src/styles/io/block.js +9 -0
- package/dist/src/styles/io/block.js.map +1 -1
- package/dist/src/styles/io/writer.d.ts.map +1 -1
- package/dist/src/styles/io/writer.js +7 -3
- package/dist/src/styles/io/writer.js.map +1 -1
- package/dist/src/styles/plan/resolve.d.ts +2 -1
- package/dist/src/styles/plan/resolve.d.ts.map +1 -1
- package/dist/src/styles/plan/resolve.js +13 -2
- package/dist/src/styles/plan/resolve.js.map +1 -1
- package/dist/src/styles/types.d.ts +19 -2
- package/dist/src/styles/types.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.js +15 -1
- package/dist/src/styles/vocabulary.js.map +1 -1
- package/dist/src/types.d.ts +19 -5
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/styles.js +11 -11
- package/dist/xgmml.js +3 -3
- package/docs/samples/people.json +6 -0
- package/package.json +29 -4
- package/src/common/report.ts +27 -7
- package/src/formats/cx/styles.ts +1 -0
- package/src/formats/dot/styles.ts +3 -1
- package/src/formats/gexf/styles.ts +185 -37
- package/src/formats/gml/styles.ts +5 -4
- package/src/formats/graphml/styles-plain.ts +3 -9
- package/src/formats/graphml/styles-yed.ts +93 -20
- package/src/formats/pajek/styles.ts +1 -0
- package/src/formats/xgmml/styles.ts +1 -0
- package/src/index.ts +90 -0
- package/src/registry.ts +326 -1
- package/src/sources/builtins.ts +56 -0
- package/src/sources/codes.ts +235 -0
- package/src/sources/context.ts +893 -0
- package/src/sources/credentials.ts +409 -0
- package/src/sources/cypher/descriptor.ts +125 -0
- package/src/sources/cypher/flatten.ts +323 -0
- package/src/sources/cypher/index.ts +498 -0
- package/src/sources/cypher/params.ts +41 -0
- package/src/sources/cypher/profiles.ts +78 -0
- package/src/sources/cypher/query-builder.ts +294 -0
- package/src/sources/cypher/transports/bolt.ts +228 -0
- package/src/sources/cypher/transports/neptune-analytics.ts +41 -0
- package/src/sources/cypher/transports/neptune-https.ts +122 -0
- package/src/sources/cypher/transports/query-api.ts +100 -0
- package/src/sources/cypher/transports/transport.ts +139 -0
- package/src/sources/cypher/types-map.ts +418 -0
- package/src/sources/define.ts +195 -0
- package/src/sources/fail.ts +70 -0
- package/src/sources/ids.ts +74 -0
- package/src/sources/ndex/client.ts +102 -0
- package/src/sources/ndex/descriptor.ts +64 -0
- package/src/sources/ndex/expand.ts +100 -0
- package/src/sources/ndex/index.ts +235 -0
- package/src/sources/ndex/params.ts +17 -0
- package/src/sources/ndex/share-url.ts +84 -0
- package/src/sources/params.ts +29 -0
- package/src/sources/registry.ts +325 -0
- package/src/sources/rest/descriptor.ts +74 -0
- package/src/sources/rest/index.ts +22 -0
- package/src/sources/rest/mapping.ts +401 -0
- package/src/sources/rest/openalex.ts +288 -0
- package/src/sources/rest/paging.ts +180 -0
- package/src/sources/rest/params.ts +243 -0
- package/src/sources/rest/records.ts +289 -0
- package/src/sources/rest/samples/deps-dev.ts +49 -0
- package/src/sources/rest/samples/string.ts +44 -0
- package/src/sources/rest/selectors.ts +91 -0
- package/src/sources/rest/source.ts +760 -0
- package/src/sources/rest/templates.ts +151 -0
- package/src/sources/run.ts +793 -0
- package/src/sources/sha256.ts +99 -0
- package/src/sources/sigv4.ts +207 -0
- package/src/sources/testing.ts +210 -0
- package/src/sources/types.ts +741 -0
- package/src/styles/canon/enums.ts +1 -0
- package/src/styles/cyjs/cascade.ts +81 -2
- package/src/styles/cyjs/defaults-table.ts +2 -0
- package/src/styles/cyjs/emit.ts +18 -7
- package/src/styles/cyjs/mappers.ts +6 -1
- package/src/styles/cytoscape/emit.ts +61 -7
- package/src/styles/cytoscape/lexicon.ts +28 -2
- package/src/styles/cytoscape/resolve.ts +22 -6
- package/src/styles/cytoscape/translate.ts +11 -11
- package/src/styles/defaults.ts +93 -4
- package/src/styles/io/block.ts +10 -0
- package/src/styles/io/writer.ts +8 -3
- package/src/styles/plan/resolve.ts +14 -2
- package/src/styles/types.ts +28 -2
- package/src/styles/vocabulary.ts +15 -1
- package/src/types.ts +19 -5
- package/dist/chunks/block-DiGq58c3.js.map +0 -1
- package/dist/chunks/emit-CwU8cUmG.js.map +0 -1
- package/dist/chunks/export-BvqAXCKh.js.map +0 -1
- package/dist/chunks/format-BpQBx8MZ.js.map +0 -1
- package/dist/chunks/importer-BSvfrX_h.js.map +0 -1
- package/dist/chunks/importer-CMmeMWlC.js.map +0 -1
- package/dist/chunks/importer-COTK9Tsl.js.map +0 -1
- package/dist/chunks/importer-DiZRmOQG.js.map +0 -1
- package/dist/chunks/importer-e6LGpqHB.js.map +0 -1
- package/dist/chunks/lexicon-CT69Kd87.js.map +0 -1
- package/dist/chunks/styles-BQnsga7p.js.map +0 -1
- package/dist/chunks/styles-D3fRphrO.js.map +0 -1
- package/dist/chunks/styles-yed-BF5x3_Y5.js.map +0 -1
- package/dist/chunks/writer-DMKvthQE.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic-Dq1ntt9q.js","sources":["../../src/styles/plan/families.ts","../../src/styles/plan/discrete.ts","../../src/styles/plan/classes.ts","../../src/styles/plan/continuous.ts","../../src/styles/plan/plan.ts","../../src/styles/io/generic.ts"],"sourcesContent":["/**\n * Exact equivalence classes: every property's values partition the elements (null is a block of its own), and\n * properties with identical partitions form one family, explained once.\n */\n\nimport type { StyleValue } from \"../types.js\";\n\n/**\n * A group of properties that partition the elements the same way.\n */\nexport interface Family {\n /** The properties, in the order they were given. */\n readonly props: string[];\n /** Each element's block: 0 for null, 1.. by first appearance. */\n readonly blocks: Int32Array;\n /** The number of non-null blocks. */\n readonly k: number;\n /** The elements with a value (block above 0), ascending. */\n readonly styled: number[];\n}\n\n/**\n * The text a value is compared by.\n * @param v - the value\n * @returns a key unique per value and type\n */\nexport function valueKey(v: string | number | boolean | null | undefined): string {\n return v === null || v === undefined ? \"\\u0000null\" : `${typeof v}:${String(v)}`;\n}\n\n/**\n * The partition of the elements by a property's values.\n * @param values - the values by element\n * @returns each element's block (0 for null, then by first appearance) and the number of non-null blocks\n */\nfunction partition(values: readonly (StyleValue | null)[]): { blocks: Int32Array; k: number } {\n const ids = new Map<string, number>();\n const blocks = new Int32Array(values.length);\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (v === null) {\n continue;\n }\n const key = valueKey(v);\n let id = ids.get(key);\n if (id === undefined) {\n id = ids.size + 1;\n ids.set(key, id);\n }\n blocks[i] = id;\n }\n return { blocks, k: ids.size };\n}\n\n/**\n * A hash of a block array.\n * @param blocks - the blocks\n * @returns its hash\n */\nfunction hashBlocks(blocks: Int32Array): number {\n let h = 0x811c9dc5;\n for (const b of blocks) {\n h = Math.imul(h ^ b, 0x01000193);\n }\n return h >>> 0;\n}\n\n/**\n * Whether two block arrays are equal.\n * @param a - one\n * @param b - the other\n * @returns true when equal\n */\nfunction sameBlocks(a: Int32Array, b: Int32Array): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Groups properties by identical partitions.\n * @param props - the properties, each with its values\n * @returns the families, in the order of their first property\n */\nexport function familiesOf(props: readonly (readonly [string, readonly (StyleValue | null)[]])[]): Family[] {\n const byHash = new Map<number, Family[]>();\n const out: Family[] = [];\n for (const [p, values] of props) {\n const { blocks, k } = partition(values);\n const h = hashBlocks(blocks);\n const list = byHash.get(h) ?? [];\n const hit = list.find((f) => sameBlocks(f.blocks, blocks));\n if (hit !== undefined) {\n hit.props.push(p);\n continue;\n }\n const styled: number[] = [];\n for (let i = 0; i < blocks.length; i++) {\n if (blocks[i] !== 0) {\n styled.push(i);\n }\n }\n const fam: Family = { props: [p], blocks, k, styled };\n list.push(fam);\n byHash.set(h, list);\n out.push(fam);\n }\n return out;\n}\n","/**\n * A discrete mapping on one categorical feature: the feature's values fall inside the family's blocks, up to 20% of\n * the styled elements excepted, and the elements missing the feature may form their own group.\n */\n\nimport { type Family, valueKey } from \"./families.js\";\nimport type { FeatureInfo } from \"./features.js\";\n\n/** Below this many styled elements anything explains anything: no mapping is tried. */\nexport const MIN_MAPPED = 8;\n/** The most keys a discrete table may hold. */\nconst MAX_KEYS = 256;\n/** The share of styled elements a mapping may get wrong; the replay moves them into the exceptions. */\nconst MAX_EXCEPTION_SHARE = 0.2;\n\n/** A key of a discrete table, as the feature holds it. */\ntype KeyValue = string | number | boolean;\n\n/**\n * A discrete mapping that explains a family.\n */\nexport interface DiscreteCandidate {\n /** The kind of candidate. */\n readonly type: \"discrete\";\n /** The feature the table reads. */\n readonly info: FeatureInfo;\n /** Each key (by its value key) with its raw value and the block it maps to. */\n readonly table: Map<string, { readonly raw: KeyValue; readonly block: number }>;\n /** The block the elements missing the feature share, or null. */\n readonly bucket: number | null;\n /** The description cost. */\n readonly cost: number;\n}\n\n/**\n * Tests a discrete mapping on one feature.\n * @param fam - the family\n * @param info - the feature\n * @param n - the element count\n * @param spend - spends work from the budget\n * @returns the candidate, or null when the feature does not explain the family\n */\nexport function discreteCandidate(\n fam: Family,\n info: FeatureInfo,\n n: number,\n spend: (ops: number) => void,\n): DiscreteCandidate | null {\n const nF = fam.styled.length;\n if (!info.categorical || info.raw || nF < MIN_MAPPED) {\n return null;\n }\n if (info.distinct < 2 || info.distinct > Math.min(MAX_KEYS, nF / 2) || info.distinct >= 0.9 * n) {\n return null;\n }\n spend(n);\n const { values } = info.feature;\n const { votes, nullBlocks } = votesOf(fam, values);\n const { table, exceptions: wrong } = tableOf(votes);\n let exceptions = wrong;\n // never paint an element the file left unstyled\n const unstyledMissing = unstyledOf(fam, values, table, n);\n if (unstyledMissing === null) {\n return null;\n }\n // the elements missing the key form one group when they share one style (Gephi's \"null\" partition)\n let bucket: number | null = null;\n if (nullBlocks.size === 1 && !unstyledMissing) {\n bucket = nullBlocks.keys().next().value ?? null;\n } else {\n for (const c of nullBlocks.values()) {\n exceptions += c;\n }\n }\n if (exceptions > Math.max(2, MAX_EXCEPTION_SHARE * nF)) {\n return null;\n }\n const cost =\n 50 + table.size * fam.props.length + (exceptions > 0 ? 50 + exceptions : 0) + (bucket === null ? 0 : 50);\n return { type: \"discrete\", info, table, bucket, cost };\n}\n\n/** How the styled elements of each key fall into the family's blocks. */\ntype Votes = Map<string, { raw: KeyValue; counts: Map<number, number> }>;\n\n/**\n * Counts, per key of the feature, the styled elements in each block; and per block, those missing the feature.\n * @param fam - the family\n * @param values - the feature's values\n * @returns the votes, and the blocks of the elements missing the feature\n */\nfunction votesOf(fam: Family, values: readonly (KeyValue | null)[]): { votes: Votes; nullBlocks: Map<number, number> } {\n const votes: Votes = new Map();\n const nullBlocks = new Map<number, number>();\n for (const i of fam.styled) {\n const b = fam.blocks[i];\n const kv = values[i];\n if (kv === null) {\n nullBlocks.set(b, (nullBlocks.get(b) ?? 0) + 1);\n continue;\n }\n const key = valueKey(kv);\n let vote = votes.get(key);\n if (vote === undefined) {\n vote = { raw: kv, counts: new Map() };\n votes.set(key, vote);\n }\n vote.counts.set(b, (vote.counts.get(b) ?? 0) + 1);\n }\n return { votes, nullBlocks };\n}\n\n/**\n * The table: each key maps to the block most of its elements are in; the others are exceptions.\n * @param votes - the votes\n * @returns the table and how many elements it gets wrong\n */\nfunction tableOf(votes: Votes): { table: Map<string, { raw: KeyValue; block: number }>; exceptions: number } {\n const table = new Map<string, { raw: KeyValue; block: number }>();\n let exceptions = 0;\n for (const [key, { raw, counts }] of votes) {\n let best = -1;\n let bestCount = -1;\n let total = 0;\n for (const [b, c] of counts) {\n total += c;\n if (c > bestCount) {\n bestCount = c;\n best = b;\n }\n }\n table.set(key, { raw, block: best });\n exceptions += total - bestCount;\n }\n return { table, exceptions };\n}\n\n/**\n * Whether an element the file left unstyled misses the feature (or holds false, which a missing-key group's \"not has\"\n * also matches).\n * @param fam - the family\n * @param values - the feature's values\n * @param table - the table\n * @param n - the element count\n * @returns the answer, or null when the table would paint an unstyled element\n */\nfunction unstyledOf(\n fam: Family,\n values: readonly (KeyValue | null)[],\n table: ReadonlyMap<string, unknown>,\n n: number,\n): boolean | null {\n let missing = false;\n for (let i = 0; i < n; i++) {\n const v = values[i];\n if (fam.blocks[i] !== 0) {\n continue;\n }\n if (v !== null && table.has(valueKey(v))) {\n return null;\n }\n missing ||= v === null || v === false;\n }\n return missing;\n}\n","/**\n * The opaque pool: the families nothing explains. Over their non-text, non-size properties each distinct joint tuple\n * of values is a style class, numbered 1..k by frequency in the style column `class`; a few classes become one group\n * rule each, more become one table keyed by the class. What is left is copied per element.\n */\n\nimport type { StyleRule, StyleTarget, StyleValue } from \"../types.js\";\nimport { STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { MIN_MAPPED } from \"./discrete.js\";\nimport { valueKey } from \"./families.js\";\n\n/** The most style classes; more distinct tuples are copied per element. */\nconst MAX_CLASSES = 64;\n/** At most this many classes become one group rule each. */\nconst MAX_CLASS_RULES = 4;\n/** Sizes vary per element by nature and are never joined into a class. */\nconst SIZES: ReadonlySet<string> = new Set([\"width\", \"height\"]);\n/** The style column holding each element's class. */\nexport const CLASS_COLUMN = \"class\";\n\n/**\n * The style classes of an opaque pool.\n */\ninterface StyleClasses {\n /** The properties the classes explain. */\n readonly classed: readonly string[];\n /** The class of each element, 1..k, or null. */\n readonly column: (number | null)[];\n /** One group rule per class, or one mapping rule keyed by the class. */\n readonly rules: StyleRule[];\n}\n\n/**\n * Whether a property's values have few enough distinct values to be part of a class.\n * @param values - the values\n * @returns true when they do\n */\nfunction fewValues(values: readonly (StyleValue | null)[]): boolean {\n const seen = new Set<string>();\n for (const v of values) {\n seen.add(valueKey(v));\n if (seen.size > MAX_CLASSES + 1) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * One element's combination of values of the classable properties, as a key; null when it has none.\n * @param classable - the properties\n * @param truth - the values per property\n * @param i - the element\n * @returns the key\n */\nfunction tupleKey(\n classable: readonly string[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n i: number,\n): string | null {\n let key = \"\";\n let any = false;\n for (const p of classable) {\n const v = (truth.get(p) ?? [])[i] ?? null;\n any ||= v !== null;\n key += `${valueKey(v)}\\u0001`;\n }\n return any ? key : null;\n}\n\n/**\n * Finds the style classes of the opaque properties.\n * @param target - nodes or edges\n * @param props - the opaque properties\n * @param truth - the values per property\n * @param n - the element count\n * @param spend - spends work from the budget\n * @returns the classes, or null when the values have too many combinations\n */\nexport function styleClasses(\n target: StyleTarget,\n props: readonly string[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n n: number,\n spend: (ops: number) => void,\n): StyleClasses | null {\n const classable = props.filter(\n (p) => STYLE_PROPERTIES[target].get(p) !== \"text\" && !SIZES.has(p) && fewValues(truth.get(p) ?? []),\n );\n if (classable.length === 0) {\n return null;\n }\n spend(n * (classable.length + 1));\n const counts = new Map<string, { count: number; rep: number }>();\n const tupleOf = new Array<string | null>(n).fill(null);\n let withTuple = 0;\n for (let i = 0; i < n; i++) {\n const key = tupleKey(classable, truth, i);\n if (key === null) {\n continue;\n }\n withTuple++;\n tupleOf[i] = key;\n const c = counts.get(key);\n if (c === undefined) {\n counts.set(key, { count: 1, rep: i });\n if (counts.size > MAX_CLASSES) {\n return null;\n }\n } else {\n c.count++;\n }\n }\n if (counts.size === 0 || withTuple < MIN_MAPPED || counts.size * 2 > withTuple) {\n return null;\n }\n // classes by frequency, ties by first appearance (a stable sort)\n const order = Array.from(counts.entries()).sort((a, b) => b[1].count - a[1].count);\n const rank = new Map(order.map(([key], j) => [key, j + 1]));\n const column = tupleOf.map((t) => (t === null ? null : (rank.get(t) ?? null)));\n const ref = { style: CLASS_COLUMN };\n const valueOf = (p: string, rep: number): StyleValue | null => (truth.get(p) ?? [])[rep] ?? null;\n const rules: StyleRule[] = [];\n if (order.length <= Math.min(MAX_CLASS_RULES, Math.floor(withTuple / 4))) {\n order.forEach(([, { count, rep }], j) => {\n const set: Record<string, StyleValue> = {};\n for (const p of classable) {\n const v = valueOf(p, rep);\n if (v !== null) {\n set[p] = v;\n }\n }\n rules.push({\n id: `${target}.class.${String(j + 1)}`,\n target,\n role: \"group\",\n origin: \"inferred\",\n where: { eq: [ref, j + 1] },\n set,\n facts: { elements: count, reason: \"STYLE_CLASS\" },\n });\n });\n } else {\n const map: Record<string, { kind: \"discrete\"; by: { style: string }; table: [number, StyleValue][] }> = {};\n for (const p of classable) {\n const table: [number, StyleValue][] = [];\n order.forEach(([, { rep }], j) => {\n const v = valueOf(p, rep);\n if (v !== null) {\n table.push([j + 1, v]);\n }\n });\n map[p] = { kind: \"discrete\", by: ref, table };\n }\n rules.push({\n id: `${target}.classes`,\n target,\n role: \"mapping\",\n origin: \"inferred\",\n where: { all: true },\n map,\n facts: { classes: order.length, elements: withTuple, reason: \"STYLE_CLASS\" },\n });\n }\n return { classed: classable, column, rules };\n}\n","/**\n * A continuous mapping on one numeric feature: the fewest linear pieces (at most 8, each explaining at least 3\n * distinct inputs), exact first, else within the rounding the writing tool did per element.\n */\n\nimport type { ContinuousPoint, StyleValue } from \"../types.js\";\nimport { MIN_MAPPED } from \"./discrete.js\";\nimport type { Family } from \"./families.js\";\nimport type { FeatureInfo } from \"./features.js\";\nimport { interpolate, within } from \"./resolve.js\";\n\n/** The most linear pieces a ramp may have. */\nconst MAX_PIECES = 8;\n/** The most distinct inputs a ramp is fitted over. */\nconst MAX_DISTINCT_X = 4096;\nconst HEX6 = /^#[0-9a-f]{6}$/;\n\n/**\n * A continuous mapping that explains a family.\n */\nexport interface ContinuousCandidate {\n /** The kind of candidate. */\n readonly type: \"continuous\";\n /** The feature the ramp reads. */\n readonly info: FeatureInfo;\n /** The points per property. */\n readonly points: ReadonlyMap<string, ContinuousPoint[]>;\n /** Whether the ramp matches only within the tool's rounding. */\n readonly tolerant: boolean;\n /** The description cost. */\n readonly cost: number;\n}\n\n/**\n * Whether a value can be interpolated: a number or a canonical color.\n * @param v - the value\n * @returns true when it can\n */\nfunction interpolable(v: StyleValue | null): v is number | string {\n return typeof v === \"number\" || (typeof v === \"string\" && HEX6.test(v));\n}\n\n/**\n * The fewest linear pieces over sorted distinct points, or null when more than `MAX_PIECES` are needed.\n * @param xs - the inputs, ascending\n * @param ys - the outputs\n * @param tolerant - whether a piece may miss a point by the tool's rounding\n * @param spend - spends work from the budget\n * @returns each piece's first and last point index, or null\n */\nfunction fitPieces(\n xs: readonly number[],\n ys: readonly StyleValue[],\n tolerant: boolean,\n spend: (ops: number) => void,\n): [number, number][] | null {\n const pieces: [number, number][] = [];\n let a = 0;\n while (a < xs.length) {\n let b = a;\n // extend while the line from a to b + 1 reproduces every point between\n while (b + 1 < xs.length) {\n const ok = lineFits(xs, ys, a, b + 1, tolerant);\n spend(b + 1 - a);\n if (!ok) {\n break;\n }\n b++;\n }\n pieces.push([a, b]);\n if (pieces.length > MAX_PIECES) {\n return null;\n }\n a = b + 1;\n }\n return pieces;\n}\n\n/**\n * Whether the line from point a to point c reproduces every point between.\n * @param xs - the inputs, ascending\n * @param ys - the outputs\n * @param a - the first point\n * @param c - the last point\n * @param tolerant - whether the line may miss a point by the tool's rounding\n * @returns true when it does\n */\nfunction lineFits(xs: readonly number[], ys: readonly StyleValue[], a: number, c: number, tolerant: boolean): boolean {\n for (let j = a + 1; j < c; j++) {\n const v = interpolate(ys[a], ys[c], (xs[j] - xs[a]) / (xs[c] - xs[a]));\n if (tolerant ? !within(v, ys[j]) : v !== ys[j]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * The points of a fitted ramp.\n * @param xs - the inputs\n * @param ys - the outputs\n * @param pieces - the pieces\n * @returns the points, ascending\n */\nfunction piecesToPoints(\n xs: readonly number[],\n ys: readonly StyleValue[],\n pieces: [number, number][],\n): ContinuousPoint[] {\n const out: ContinuousPoint[] = [];\n for (const [a, b] of pieces) {\n out.push({ at: xs[a], below: ys[a], value: ys[a], above: ys[a] });\n if (b !== a) {\n out.push({ at: xs[b], below: ys[b], value: ys[b], above: ys[b] });\n }\n }\n return out;\n}\n\n/**\n * Tests a continuous mapping on one feature.\n * @param fam - the family\n * @param info - the feature\n * @param truth - the values per property\n * @param spend - spends work from the budget\n * @returns the candidate, or null when the feature does not explain the family\n */\nexport function continuousCandidate(\n fam: Family,\n info: FeatureInfo,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n spend: (ops: number) => void,\n): ContinuousCandidate | null {\n if (!info.numeric || info.raw || fam.styled.length < MIN_MAPPED) {\n return null;\n }\n const { values } = info.feature;\n spend(values.length);\n // the feature must be a number exactly where the family has a value\n if (values.some((v, i) => (fam.blocks[i] === 0) === (typeof v === \"number\"))) {\n return null;\n }\n for (const tolerant of [false, true]) {\n const points = rampsOf(fam, values, truth, tolerant, spend);\n if (points !== null) {\n const entries = Array.from(points.values()).reduce((sum, pts) => sum + pts.length, 0);\n return { type: \"continuous\", info, points, tolerant, cost: 50 + entries + (tolerant ? 10 : 0) };\n }\n }\n return null;\n}\n\n/**\n * The ramp of every property of the family over the feature, or null when one has none.\n * @param fam - the family\n * @param values - the feature's values\n * @param truth - the values per property\n * @param tolerant - whether a ramp may miss a value by the tool's rounding\n * @param spend - spends work from the budget\n * @returns the points per property, or null\n */\nfunction rampsOf(\n fam: Family,\n values: readonly unknown[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n tolerant: boolean,\n spend: (ops: number) => void,\n): Map<string, ContinuousPoint[]> | null {\n const points = new Map<string, ContinuousPoint[]>();\n for (const p of fam.props) {\n const pts = rampOf(fam, values, truth.get(p) ?? [], tolerant, spend);\n if (pts === null) {\n return null;\n }\n points.set(p, pts);\n }\n return points;\n}\n\n/**\n * The ramp of one property over the feature, or null when none explains it.\n * @param fam - the family\n * @param values - the feature's values\n * @param ys0 - the property's values\n * @param tolerant - whether the ramp may miss a value by the tool's rounding\n * @param spend - spends work from the budget\n * @returns the points, or null\n */\nfunction rampOf(\n fam: Family,\n values: readonly unknown[],\n ys0: readonly (StyleValue | null)[],\n tolerant: boolean,\n spend: (ops: number) => void,\n): ContinuousPoint[] | null {\n const byX = new Map<number, StyleValue>();\n let good = true;\n for (const i of fam.styled) {\n const y = ys0[i];\n const x = values[i] as number;\n const seen = byX.get(x);\n if (!interpolable(y) || (seen !== undefined && seen !== y)) {\n good = false;\n break;\n }\n byX.set(x, y);\n }\n spend(fam.styled.length);\n // a ramp needs at least 3 distinct outputs: two values over a number are a threshold, not a mapping\n if (!good || byX.size < 2 || byX.size > MAX_DISTINCT_X || new Set(byX.values()).size < 3) {\n return null;\n }\n const xs = Array.from(byX.keys()).sort((a, b) => a - b);\n const ys = xs.map((x) => byX.get(x) as StyleValue);\n const pieces = fitPieces(xs, ys, tolerant, spend);\n // every piece must explain at least 3 distinct inputs, or a few points fit anything\n return pieces === null || pieces.length * 3 > xs.length ? null : piecesToPoints(xs, ys, pieces);\n}\n","/**\n * The planner: turns a file's per-element style values into a few readable rules that reproduce them exactly. It\n * groups properties into families, explains each family by a discrete or continuous mapping on one feature, a\n * passthrough on an existing column, style classes or a copy, orders the rules, caps them at 15 per target and\n * replays them: every element whose resolved value differs from the file's goes into one sparse exceptions column\n * per property on top. One counted budget bounds the work; when it runs out the rest is copied.\n */\n\nimport { StyleBudget } from \"../budget.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport { toolDefaults } from \"../defaults.js\";\nimport { StyleNotes } from \"../notes.js\";\nimport type {\n ExtractedStyles,\n GraphStyle,\n Mapping,\n ReaderOutput,\n StyleColumn,\n StyleDialect,\n StyleFeature,\n StyleFeatures,\n StyleFingerprint,\n StyleRule,\n StyleRuleFacts,\n StyleTarget,\n StyleTool,\n StyleValue,\n StyleWorkBudget,\n} from \"../types.js\";\nimport { isStyleValue, STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { CLASS_COLUMN, styleClasses } from \"./classes.js\";\nimport { type ContinuousCandidate, continuousCandidate } from \"./continuous.js\";\nimport { type DiscreteCandidate, discreteCandidate } from \"./discrete.js\";\nimport { familiesOf, type Family } from \"./families.js\";\nimport { describeFeature, type FeatureInfo } from \"./features.js\";\nimport {\n canonicalFor,\n evalContinuous,\n isShortPredicate,\n matches,\n numberOf,\n refSource,\n resolveRules,\n within,\n} from \"./resolve.js\";\n\n/**\n * The most rules per target: the planner keeps at most 15 plus the exceptions rule.\n * @category Styles\n */\nexport const MAX_STYLE_RULES = 16;\n/** The most candidate features tested per target, fewest distinct values first. */\nconst MAX_FEATURES = 64;\n/** Lengths a tool states in its own unit; they are left out when the file's unit differs. */\nconst LENGTHS: ReadonlySet<string> = new Set([\"width\", \"height\", \"borderWidth\", \"labelSize\"]);\n\n/**\n * What the planner is given: the canonical per-element values a style reader produced, the rules the file declares,\n * and the graph they belong to.\n * @category Styles\n */\nexport interface StyleValues {\n /** The graph-io format id. */\n readonly format: string;\n /** How the file spelled its values. */\n readonly dialect?: StyleDialect | null;\n /** The program that wrote the file, whose defaults fill in what the file leaves unset; null when unknown. */\n readonly tool?: StyleTool | null;\n /** The unit of every length; defaults to pixels. */\n readonly units?: \"px\" | \"relative\";\n /** The graph's own style. */\n readonly graph?: GraphStyle;\n /** Node values, declared rules, reader columns and extra features. */\n readonly node?: ReaderOutput;\n /** Edge values, declared rules, reader columns and extra features. */\n readonly edge?: ReaderOutput;\n /** The graph the values belong to; its counts give the number of elements. */\n readonly fingerprint: StyleFingerprint;\n}\n\n/**\n * Options of `planStyles()`.\n * @category Styles\n */\nexport interface PlanOptions {\n /** Whether to add the writing tool's defaults as a rule at the bottom; defaults to true. */\n readonly toolDefaults?: boolean;\n /** The counted work budget; defaults to a fresh `StyleBudget`. */\n readonly budget?: StyleWorkBudget;\n /**\n * Where notes are collected; the reader's notes, when it used the same collector, are kept.\n * @internal\n */\n readonly notes?: StyleNotes;\n /** Data columns the reader read the values from: they are never offered as explanations of themselves. */\n readonly rawColumns?: {\n /** Node columns. */\n readonly node?: readonly string[];\n /** Edge columns. */\n readonly edge?: readonly string[];\n };\n /** Cancels the planning. */\n readonly signal?: AbortSignal;\n}\n\n/** A rule being built. */\ninterface Draft {\n id: string;\n readonly target: StyleTarget;\n readonly role: string;\n readonly origin: string;\n where: StyleRule[\"where\"];\n set?: Record<string, StyleValue>;\n map?: Record<string, Mapping>;\n facts?: StyleRuleFacts;\n readonly ext?: Readonly<Record<string, unknown>>;\n}\n\n/** The planning state of one target. */\ninterface TargetPlan {\n readonly target: StyleTarget;\n readonly n: number;\n readonly notes: StyleNotes;\n readonly budget: StyleWorkBudget;\n readonly spend: (ops: number) => void;\n readonly columns: Map<string, StyleColumn>;\n readonly ids: Set<string>;\n}\n\n/**\n * Plans a file's styles: the rules that reproduce its per-element values, with the columns they read.\n * @param values - the canonical values, the declared rules and the graph they belong to\n * @param features - the candidate explaining columns per target (`featuresOf()` of the snapshot)\n * @param options - tool defaults, the budget, the notes collector, the raw columns and a cancel signal\n * @returns the styles, exact for every element\n * @category Styles\n */\nexport function planStyles(values: StyleValues, features: StyleFeatures, options: PlanOptions = {}): ExtractedStyles {\n const notes = options.notes ?? new StyleNotes();\n const budget = options.budget ?? new StyleBudget();\n const defaults =\n options.toolDefaults !== false && values.tool !== undefined && values.tool !== null\n ? toolDefaults(values.tool)\n : null;\n const units = values.units ?? \"px\";\n const rules: StyleRule[] = [];\n const columns = { node: new Map<string, StyleColumn>(), edge: new Map<string, StyleColumn>() };\n const allFeatures = { node: [] as StyleFeature[], edge: [] as StyleFeature[] };\n for (const target of [\"node\", \"edge\"] as const) {\n const given = values[target];\n // a reader's own tool-default rules (Gephi's arrows on directed edges) go with the tool's constants\n const out =\n options.toolDefaults === false && given?.rules !== undefined\n ? { ...given, rules: given.rules.filter((r) => r.origin !== \"tool\") }\n : given;\n allFeatures[target] = [...features[target], ...(out?.features ?? [])];\n const toolSet = defaults === null ? null : toolSetOf(defaults, target, units);\n const plan: TargetPlan = {\n target,\n n: target === \"node\" ? values.fingerprint.nodes : values.fingerprint.edges,\n notes,\n budget,\n spend: (ops) => {\n budget.spend(target, ops);\n },\n columns: columns[target],\n ids: new Set(),\n };\n rules.push(\n ...planTarget(\n plan,\n out,\n allFeatures[target],\n new Set(options.rawColumns?.[target] ?? []),\n toolSet,\n options.signal,\n ),\n );\n }\n const graph = graphStyles(defaults, values.graph ?? {});\n return {\n styles: {\n version: 1,\n source: {\n format: values.format,\n dialect: values.dialect ?? null,\n tool: defaults === null ? null : defaults.tool,\n },\n units: { length: units },\n graph: graph,\n rules,\n notes: notes.list(),\n },\n columns,\n features: allFeatures,\n fingerprint: values.fingerprint,\n };\n}\n\n/**\n * The tool's default values of a target, as one defaults rule sets them; a length in other units than the file's is\n * left out.\n * @param defaults - the tool's defaults\n * @param target - nodes or edges\n * @param units - the file's length units\n * @returns the values, or null when none applies\n */\nfunction toolSetOf(\n defaults: NonNullable<ReturnType<typeof toolDefaults>>,\n target: StyleTarget,\n units: string,\n): Record<string, StyleValue> | null {\n const toolSet: Record<string, StyleValue> = {};\n for (const [p, d] of Object.entries(defaults[target]) as [string, { value: unknown } | undefined][]) {\n const fits = d !== undefined && isStyleValue(target, p, d.value);\n if (fits && !(LENGTHS.has(p) && defaults.units !== units)) {\n toolSet[p] = d.value as StyleValue;\n }\n }\n return Object.keys(toolSet).length === 0 ? null : toolSet;\n}\n\n/**\n * The graph's styles: the tool's defaults, then the file's own values over them.\n * @param defaults - the tool's defaults, or null\n * @param given - the file's graph values\n * @returns the values\n */\nfunction graphStyles(\n defaults: ReturnType<typeof toolDefaults> | null,\n given: Readonly<Record<string, unknown>>,\n): Record<string, StyleValue> {\n const graph: Record<string, StyleValue> = {};\n const own = Object.entries(defaults?.graph ?? {}) as [string, { value: unknown } | undefined][];\n for (const [p, d] of own) {\n if (d !== undefined && isStyleValue(\"graph\", p, d.value)) {\n graph[p] = d.value as StyleValue;\n }\n }\n for (const [p, v] of Object.entries(given)) {\n if (isStyleValue(\"graph\", p, v)) {\n graph[p] = v as StyleValue;\n }\n }\n return graph;\n}\n\n/**\n * A rule id not used yet in this target.\n * @param plan - the target's state\n * @param base - the wanted id\n * @returns the id, suffixed when taken\n */\nfunction uniqueId(plan: TargetPlan, base: string): string {\n let id = base;\n let k = 2;\n while (plan.ids.has(id)) {\n id = `${base}#${String(k)}`;\n k++;\n }\n plan.ids.add(id);\n return id;\n}\n\n/**\n * Sets one property's mapping of a rule, making the rule's mappings on first use.\n * @param rule - the rule, changed in place\n * @param property - the property\n * @param mapping - the mapping\n */\nfunction setMapping(rule: Draft, property: string, mapping: Mapping): void {\n rule.map ??= {};\n rule.map[property] = mapping;\n}\n\n/**\n * The type-checked per-element values of a target: a value of the wrong kind is noted and dropped.\n * @param plan - the target's state\n * @param out - the reader's output\n * @returns the values per property that have at least one value\n */\nfunction checkedTruth(plan: TargetPlan, out: ReaderOutput | undefined): Map<string, (StyleValue | null)[]> {\n const truth = new Map<string, (StyleValue | null)[]>();\n for (const [p, arr] of Object.entries<StyleColumn | undefined>(out?.values ?? {})) {\n if (arr === undefined) {\n continue;\n }\n if (!STYLE_PROPERTIES[plan.target].has(p) && !p.startsWith(\"graphty:\")) {\n plan.notes.add(STYLE_ISSUE.NOT_CARRIED, plan.target, p, { sample: p });\n continue;\n }\n const vals = checkedValues(plan, p, arr);\n plan.spend(plan.n);\n if (vals.some((v) => v !== null)) {\n truth.set(p, vals);\n }\n }\n return truth;\n}\n\n/**\n * One property's values, a value of the wrong kind noted and dropped.\n * @param plan - the target's state\n * @param p - the property\n * @param arr - the reader's values\n * @returns the values, one per element\n */\nfunction checkedValues(plan: TargetPlan, p: string, arr: StyleColumn): (StyleValue | null)[] {\n const vals = new Array<StyleValue | null>(plan.n).fill(null);\n for (let i = 0; i < plan.n && i < arr.length; i++) {\n const v = arr[i] ?? null;\n if (v !== null && isStyleValue(plan.target, p, v)) {\n vals[i] = v;\n } else if (v !== null) {\n plan.notes.add(STYLE_ISSUE.BAD_VALUE, plan.target, p, { sample: v, element: i });\n }\n }\n return vals;\n}\n\n/**\n * A copy of a property record without its undefined entries.\n * @param o - the record\n * @returns the copy, or undefined\n */\nfunction defined<T>(o: Readonly<Record<string, T | undefined>> | undefined): Record<string, T> | undefined {\n if (o === undefined) {\n return undefined;\n }\n const out: Record<string, T> = {};\n for (const [k, v] of Object.entries(o)) {\n if (v !== undefined) {\n out[k] = v;\n }\n }\n return out;\n}\n\n/**\n * The properties a rule writes.\n * @param r - the rule\n * @returns the property names\n */\nfunction writes(r: Draft | StyleRule): string[] {\n return [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})];\n}\n\n/**\n * The declared rules, with every predicate longer than a short one evaluated into a membership style column and\n * runs of rules that set values on every element merged into one defaults rule.\n * @param plan - the target's state\n * @param declared - the reader's rules\n * @param features - the features, for evaluating predicates over data columns\n * @returns the rules to keep\n */\nfunction prepareDeclared(plan: TargetPlan, declared: readonly StyleRule[], features: readonly StyleFeature[]): Draft[] {\n const src = refSource(plan.target, plan.n, plan.columns, features);\n const drafts: Draft[] = [];\n for (const r of declared.filter((x) => x.target === plan.target)) {\n const d: Draft = { ...r, set: defined(r.set), map: defined(r.map) };\n if (d.set === undefined) {\n delete d.set;\n }\n if (d.map === undefined) {\n delete d.map;\n }\n if (!isShortPredicate(r.where)) {\n asMembership(plan, d, r, src);\n }\n drafts.push(d);\n }\n const merged = mergedDefaults(plan.target, drafts);\n for (const d of merged) {\n d.id = uniqueId(plan, d.id);\n }\n return merged;\n}\n\n/**\n * Evaluates a long predicate into a membership style column the rule selects instead.\n * @param plan - the target's state\n * @param d - the rule's draft, changed in place\n * @param r - the declared rule\n * @param src - the reference source\n */\nfunction asMembership(plan: TargetPlan, d: Draft, r: StyleRule, src: ReturnType<typeof refSource>): void {\n let member = 1;\n while (plan.columns.has(`member.${String(member)}`)) {\n member++;\n }\n const key = `member.${String(member)}`;\n const col = new Array<StyleValue | null>(plan.n).fill(null);\n let count = 0;\n for (let i = 0; i < plan.n; i++) {\n if (matches(r.where, src, i)) {\n col[i] = true;\n count++;\n }\n }\n plan.spend(plan.n * 8);\n plan.columns.set(key, col);\n d.where = { has: { style: key } };\n d.facts = { ...r.facts, elements: count, reason: r.facts?.reason ?? \"SELECTOR\" };\n plan.notes.add(STYLE_ISSUE.SELECTOR_AS_COLUMN, plan.target, r.id, { count });\n}\n\n/**\n * Consecutive declared rules that select everything and only set values, as one defaults rule (later wins).\n * @param target - nodes or edges\n * @param drafts - the declared rules\n * @returns the rules, runs merged\n */\nfunction mergedDefaults(target: StyleTarget, drafts: readonly Draft[]): Draft[] {\n const merged: Draft[] = [];\n const plain = (x: Draft): boolean => \"all\" in x.where && x.set !== undefined && x.map === undefined;\n let i = 0;\n while (i < drafts.length) {\n let j = i + 1;\n while (plain(drafts[i]) && j < drafts.length && plain(drafts[j])) {\n j++;\n }\n if (j - i >= 2) {\n merged.push({\n id: drafts[i].id,\n target,\n role: \"defaults\",\n origin: \"declared\",\n where: { all: true },\n set: Object.assign({}, ...drafts.slice(i, j).map((x) => x.set)) as Record<string, StyleValue>,\n });\n } else {\n merged.push(drafts[i]);\n }\n i = j;\n }\n return merged;\n}\n\n/** A passthrough on existing columns that explains a family. */\ninterface PassCandidate {\n readonly type: \"passdata\";\n readonly cols: ReadonlyMap<string, FeatureInfo>;\n readonly raw: boolean;\n readonly cost: number;\n}\n\n/** The floor: classes or a copy. */\ninterface OpaqueCandidate {\n readonly type: \"opaque\";\n readonly cost: number;\n}\n\ntype Candidate = DiscreteCandidate | ContinuousCandidate | PassCandidate | OpaqueCandidate;\nconst ORDER = [\"passdata\", \"discrete\", \"continuous\", \"opaque\"];\n\n/**\n * Tests a passthrough on existing data columns: one column per property whose canonical value equals the style on\n * every element.\n * @param plan - the target's state\n * @param fam - the family\n * @param truth - the values per property\n * @param infos - the features\n * @returns the candidate, or null\n */\nfunction passCandidate(\n plan: TargetPlan,\n fam: Family,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n infos: readonly FeatureInfo[],\n): PassCandidate | null {\n const cols = new Map<string, FeatureInfo>();\n for (const p of fam.props) {\n const canon = canonicalFor(plan.target, p);\n const isColor = STYLE_PROPERTIES[plan.target].get(p) === \"color\";\n const t = truth.get(p) ?? [];\n const hit = infos.find((f) => {\n if (!(\"data\" in f.feature.ref)) {\n return false;\n }\n plan.spend(plan.n);\n for (let i = 0; i < plan.n; i++) {\n const raw = f.feature.values[i];\n // a color column is reused only when it already holds \"#rrggbb\": other spellings read differently\n if (isColor && raw !== null && !(typeof raw === \"string\" && /^#[0-9a-fA-F]{6}$/.test(raw))) {\n return false;\n }\n if ((raw === null ? null : canon(raw)) !== t[i]) {\n return false;\n }\n }\n return true;\n });\n if (hit === undefined) {\n return null;\n }\n cols.set(p, hit);\n }\n const raw = Array.from(cols.values()).some((f) => f.raw);\n // a passthrough on the raw style column itself recovers nothing: nearly as opaque as a copy\n return { type: \"passdata\", cols, raw, cost: raw ? 240 : 50 };\n}\n\n/**\n * Plans one target.\n * @param plan - the target's state\n * @param out - the reader's output\n * @param features - the candidate features\n * @param rawNames - the data columns the values were read from\n * @param toolSet - the tool's default values, or null\n * @param signal - cancels the planning\n * @returns the target's rules, bottom to top\n */\nfunction planTarget(\n plan: TargetPlan,\n out: ReaderOutput | undefined,\n features: readonly StyleFeature[],\n rawNames: ReadonlySet<string>,\n toolSet: Record<string, StyleValue> | null,\n signal: AbortSignal | undefined,\n): StyleRule[] {\n const { target, n } = plan;\n for (const [k, v] of out?.columns ?? []) {\n plan.columns.set(k, v);\n }\n const truth = checkedTruth(plan, out);\n const toolRule: Draft[] =\n toolSet === null\n ? []\n : [\n {\n id: uniqueId(plan, `${target}.tool`),\n target,\n role: \"defaults\",\n origin: \"tool\",\n where: { all: true },\n set: toolSet,\n },\n ];\n const declared = prepareDeclared(plan, out?.rules ?? [], features);\n const declaredProps = new Set(declared.flatMap(writes));\n\n const { defaults, rest } = splitDefaults(n, truth, declaredProps);\n plan.spend(n * truth.size);\n const inferred: Draft[] = [];\n if (Object.keys(defaults).length > 0) {\n inferred.push({\n id: uniqueId(plan, `${target}.defaults`),\n target,\n role: \"defaults\",\n origin: \"inferred\",\n where: { all: true },\n set: defaults,\n });\n }\n\n const families = familiesOf(rest);\n plan.spend(n * rest.length);\n const infos = features\n .map((f) => describeFeature(f, \"data\" in f.ref && rawNames.has(f.ref.data)))\n .sort((a, b) => a.distinct - b.distinct);\n plan.spend(n * features.length);\n const testable = infos.filter((f) => f.categorical || f.numeric).slice(0, MAX_FEATURES);\n\n const groups: Draft[] = [];\n const mappings = new Map<string, Draft>();\n const passData: Draft = {\n id: `${target}.passthrough`,\n target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n };\n const passRaw: Draft = {\n id: `${target}.passthrough.raw`,\n target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n facts: { reason: \"NO_EXPLANATION\" },\n };\n const copy: Draft = {\n id: `${target}.copy`,\n target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n facts: { reason: \"NO_EXPLANATION\" },\n };\n const opaque: { fam: Family; raw: ReadonlyMap<string, FeatureInfo> | null }[] = [];\n const tolerated = new Map<string, Set<number>>();\n let budgetHit = 0;\n\n const st: Inference = { groups, mappings, passData, passRaw, copy, opaque, tolerated };\n for (const fam of families) {\n signal?.throwIfAborted();\n if (plan.budget.exhausted(target)) {\n budgetHit++;\n opaque.push({ fam, raw: null });\n continue;\n }\n applyChoice(plan, st, fam, chooseCandidate(plan, fam, testable, infos, truth), truth);\n }\n if (budgetHit > 0) {\n plan.notes.add(STYLE_ISSUE.BUDGET, target, null, { count: budgetHit });\n }\n poolOpaque(plan, st, budgetHit, truth);\n\n const nonEmpty = (r: Draft): boolean => Object.keys(r.map ?? {}).length > 0;\n const sortedMappings = Array.from(mappings.values()).sort((a, b) => compareText(a.id, b.id));\n const drafts: Draft[] = [\n ...toolRule,\n ...declared,\n ...inferred,\n ...groups,\n ...sortedMappings,\n ...[passData, passRaw, copy].filter(nonEmpty),\n ];\n for (const d of drafts.slice(toolRule.length + declared.length + inferred.length)) {\n d.id = uniqueId(plan, d.id);\n }\n\n const src = refSource(target, n, plan.columns, features);\n enforceCap(plan, drafts, truth, src);\n const exceptions = replay(plan, drafts, truth, toolSet, tolerated, src);\n if (exceptions !== null) {\n drafts.push(exceptions);\n }\n return drafts.map(finish);\n}\n\n/**\n * The inferred defaults: each property non-null and equal on every element; the others are left to explain. A\n * property a declared rule writes is the declared rule's.\n * @param n - the element count\n * @param truth - the values per property\n * @param declaredProps - the properties the declared rules write\n * @returns the defaults, and the properties left\n */\nfunction splitDefaults(\n n: number,\n truth: ReadonlyMap<string, (StyleValue | null)[]>,\n declaredProps: ReadonlySet<string>,\n): { defaults: Record<string, StyleValue>; rest: [string, (StyleValue | null)[]][] } {\n const defaults: Record<string, StyleValue> = {};\n const rest: [string, (StyleValue | null)[]][] = [];\n for (const [p, a] of truth) {\n const first = a[0];\n if (declaredProps.has(p)) {\n continue;\n }\n if (n > 0 && first !== null && a.every((v) => v === first)) {\n defaults[p] = first;\n } else {\n rest.push([p, a]);\n }\n }\n return { defaults, rest };\n}\n\n/** What the inference of one target collects. */\ninterface Inference {\n readonly groups: Draft[];\n readonly mappings: Map<string, Draft>;\n readonly passData: Draft;\n readonly passRaw: Draft;\n readonly copy: Draft;\n readonly opaque: { fam: Family; raw: ReadonlyMap<string, FeatureInfo> | null }[];\n readonly tolerated: Map<string, Set<number>>;\n}\n\n/**\n * The cheapest explanation of one family: a discrete or continuous mapping over a feature, a passthrough over existing\n * columns, or the opaque floor.\n * @param plan - the target's state\n * @param fam - the family\n * @param testable - the features worth testing\n * @param infos - every feature\n * @param truth - the values per property\n * @returns the chosen candidate\n */\nfunction chooseCandidate(\n plan: TargetPlan,\n fam: Family,\n testable: readonly FeatureInfo[],\n infos: readonly FeatureInfo[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): Candidate {\n const { target, n } = plan;\n const cands: Candidate[] = [];\n // text is per element by nature: a label is never explained by another column's table\n const textual = fam.props.some((p) => STYLE_PROPERTIES[target].get(p) === \"text\");\n if (!textual) {\n for (const f of testable) {\n const d = discreteCandidate(fam, f, n, plan.spend);\n if (d !== null) {\n cands.push(d);\n }\n const c = continuousCandidate(fam, f, truth, plan.spend);\n if (c !== null) {\n cands.push(c);\n }\n if (plan.budget.exhausted(target)) {\n break;\n }\n }\n }\n const pass = passCandidate(plan, fam, truth, infos);\n if (pass !== null) {\n cands.push(pass);\n }\n cands.push({ type: \"opaque\", cost: 250 });\n cands.sort((a, b) => a.cost - b.cost || ORDER.indexOf(a.type) - ORDER.indexOf(b.type));\n return cands[0];\n}\n\n/**\n * Records a family's chosen explanation in the target's inference.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param fam - the family\n * @param c - the chosen candidate\n * @param truth - the values per property\n */\nfunction applyChoice(\n plan: TargetPlan,\n st: Inference,\n fam: Family,\n c: Candidate,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n if (c.type === \"discrete\") {\n applyDiscrete(plan, st, fam, c, truth);\n } else if (c.type === \"continuous\") {\n applyContinuous(plan, st, fam, c, truth);\n } else if (c.type === \"passdata\" && !c.raw) {\n for (const p of fam.props) {\n setMapping(st.passData, p, { kind: \"passthrough\", by: (c.cols.get(p) as FeatureInfo).feature.ref });\n }\n } else {\n // the raw style column recovers nothing: the family joins the opaque pool, where it may become part\n // of a style class, and otherwise reads the raw column\n st.opaque.push({ fam, raw: c.type === \"passdata\" ? c.cols : null });\n }\n}\n\n/**\n * The mapping rule of a feature, made on first use; one rule holds every family the feature explains.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param key - the rule's key among the mappings\n * @param id - its id\n * @returns the rule\n */\nfunction mappingRule(plan: TargetPlan, st: Inference, key: string, id: string): Draft {\n let r = st.mappings.get(key);\n if (r === undefined) {\n r = { id, target: plan.target, role: \"mapping\", origin: \"inferred\", where: { all: true }, map: {} };\n st.mappings.set(key, r);\n }\n return r;\n}\n\n/**\n * Makes a feature computed for the inference (a style column) a column of the styles.\n * @param plan - the target's state\n * @param info - the feature\n */\nfunction materialize(plan: TargetPlan, info: FeatureInfo): void {\n if (\"style\" in info.feature.ref) {\n plan.columns.set(info.feature.ref.style, info.feature.values);\n }\n}\n\n/**\n * Records a discrete mapping: one table per property, and a group for the elements the feature gives no value.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param fam - the family\n * @param c - the candidate\n * @param truth - the values per property\n */\nfunction applyDiscrete(\n plan: TargetPlan,\n st: Inference,\n fam: Family,\n c: DiscreteCandidate,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n const { target } = plan;\n materialize(plan, c.info);\n const rule = mappingRule(plan, st, `discrete|${c.info.name}`, `${target}.by.${c.info.name}`);\n // the first element of each block stands for the block\n const rep = new Map<number, number>();\n for (const i of fam.styled) {\n if (!rep.has(fam.blocks[i])) {\n rep.set(fam.blocks[i], i);\n }\n }\n for (const p of fam.props) {\n const t = truth.get(p) ?? [];\n const table = Array.from(c.table.values(), ({ raw, block }): [string | number | boolean, StyleValue] => [\n raw,\n t[rep.get(block) ?? -1] as StyleValue,\n ]);\n setMapping(rule, p, { kind: \"discrete\", by: c.info.feature.ref, table });\n }\n if (c.bucket === null) {\n return;\n }\n const set: Record<string, StyleValue> = {};\n for (const p of fam.props) {\n set[p] = (truth.get(p) ?? [])[rep.get(c.bucket) ?? -1] as StyleValue;\n }\n st.groups.push({\n id: `${target}.missing.${c.info.name}`,\n target,\n role: \"group\",\n origin: \"inferred\",\n where: { not: { has: c.info.feature.ref } },\n set,\n });\n}\n\n/**\n * Records a continuous mapping: one ramp per property; a ramp that matches only within the tool's rounding tolerates\n * those elements, noted.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param fam - the family\n * @param c - the candidate\n * @param truth - the values per property\n */\nfunction applyContinuous(\n plan: TargetPlan,\n st: Inference,\n fam: Family,\n c: ContinuousCandidate,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n const { target } = plan;\n materialize(plan, c.info);\n const rule = mappingRule(plan, st, `continuous|${c.info.name}`, `${target}.ramp.${c.info.name}`);\n for (const p of fam.props) {\n const points = c.points.get(p) ?? [];\n setMapping(rule, p, { kind: \"continuous\", by: c.info.feature.ref, points });\n if (!c.tolerant) {\n continue;\n }\n const t = truth.get(p) ?? [];\n const set = new Set<number>();\n for (const i of fam.styled) {\n if (evalContinuous(points, numberOf(c.info.feature.values[i])) !== t[i]) {\n set.add(i);\n plan.notes.add(STYLE_ISSUE.RAMP_ROUNDED, target, p, { element: i, sample: t[i] });\n }\n }\n st.tolerated.set(p, set);\n }\n}\n\n/**\n * The opaque pool: style classes when the file uses few combinations, else one copy per property.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param budgetHit - how many families the budget sent to the pool\n * @param truth - the values per property\n */\nfunction poolOpaque(\n plan: TargetPlan,\n st: Inference,\n budgetHit: number,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n const { target, n } = plan;\n if (st.opaque.length === 0) {\n return;\n }\n const props = st.opaque.flatMap((o) => o.fam.props);\n const classes = budgetHit > 0 ? null : styleClasses(target, props, truth, n, plan.spend);\n const classed = new Set(classes?.classed ?? []);\n if (classes !== null) {\n addClassRules(plan, st, classes);\n }\n let distinct = 0;\n for (const { fam, raw } of st.opaque) {\n for (const p of fam.props.filter((x) => !classed.has(x))) {\n const viaRaw = raw?.get(p);\n if (viaRaw === undefined) {\n distinct = Math.max(distinct, copyProperty(plan, st.copy, p, truth.get(p) ?? []));\n } else {\n setMapping(st.passRaw, p, { kind: \"passthrough\", by: viaRaw.feature.ref });\n }\n }\n }\n st.copy.facts = { reason: budgetHit > 0 ? \"BUDGET\" : \"NO_EXPLANATION\", distinctValues: distinct };\n}\n\n/**\n * Adds the style classes' column and rules.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param classes - the style classes\n */\nfunction addClassRules(plan: TargetPlan, st: Inference, classes: NonNullable<ReturnType<typeof styleClasses>>): void {\n plan.columns.set(CLASS_COLUMN, classes.column);\n for (const r of classes.rules) {\n if (r.role === \"group\") {\n st.groups.push({ ...r, id: r.id, set: { ...r.set } } as Draft);\n } else {\n st.mappings.set(r.id, { ...r, map: { ...r.map } } as Draft);\n }\n }\n}\n\n/**\n * Copies a property's values into a style column the copy rule passes through.\n * @param plan - the target's state\n * @param copy - the copy rule, changed in place\n * @param p - the property\n * @param t - its values\n * @returns how many distinct values it holds\n */\nfunction copyProperty(plan: TargetPlan, copy: Draft, p: string, t: readonly (StyleValue | null)[]): number {\n plan.columns.set(`copy.${p}`, t.slice());\n setMapping(copy, p, { kind: \"passthrough\", by: { style: `copy.${p}` } });\n plan.spend(plan.n);\n return new Set(t.filter((v) => v !== null)).size;\n}\n\n/**\n * The rule as a plain JSON-stable object.\n * @param d - the draft\n * @returns the rule\n */\nfunction finish(d: Draft): StyleRule {\n const r: Record<string, unknown> = { id: d.id, target: d.target, role: d.role, origin: d.origin, where: d.where };\n if (d.set !== undefined && Object.keys(d.set).length > 0) {\n r.set = d.set;\n }\n if (d.map !== undefined && Object.keys(d.map).length > 0) {\n r.map = d.map;\n }\n if (d.facts !== undefined) {\n r.facts = Object.fromEntries(Object.entries(d.facts).filter(([, v]) => v !== undefined));\n }\n if (d.ext !== undefined) {\n r.ext = d.ext;\n }\n return r as unknown as StyleRule;\n}\n\n/**\n * Compares two texts by code unit, the same everywhere.\n * @param a - one text\n * @param b - the other\n * @returns negative, zero or positive\n */\nfunction compareText(a: string, b: string): number {\n if (a === b) {\n return 0;\n }\n return a < b ? -1 : 1;\n}\n\n/**\n * The entries a person would edit in a rule.\n * @param r - the rule\n * @returns its size\n */\nfunction ruleSize(r: Draft): number {\n let size = Object.keys(r.set ?? {}).length;\n for (const m of Object.values(r.map ?? {})) {\n if (m.kind === \"discrete\") {\n size += m.table.length;\n } else if (m.kind === \"continuous\") {\n size += m.points.length;\n } else {\n size += 1;\n }\n }\n return size;\n}\n\n/** The order in which rules are folded into the copy: inferred first, the tool's defaults last. */\nconst FOLD_ORDER: Readonly<Record<string, number>> = { inferred: 0, declared: 1, tool: 2 };\n\n/**\n * Keeps at most 15 rules (the exceptions rule makes 16) by moving the least readable rules into the copy, with each\n * property's values as they resolved: exact, never a silent delete.\n * @param plan - the target's state\n * @param drafts - the rules, bottom to top; changed in place\n * @param truth - the file's values per property\n * @param src - the reference source\n */\nfunction enforceCap(\n plan: TargetPlan,\n drafts: Draft[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n src: ReturnType<typeof refSource>,\n): void {\n const cap = MAX_STYLE_RULES - 1;\n const copyId = `${plan.target}.copy`;\n let folded = 0;\n while (drafts.length > cap) {\n const cands = drafts.filter((r) => r.id !== copyId);\n if (cands.length === 0) {\n break;\n }\n cands.sort((a, b) => {\n const pa = a.role === \"passthrough\" ? 1 : 0;\n const pb = b.role === \"passthrough\" ? 1 : 0;\n return (\n pa - pb ||\n (FOLD_ORDER[a.origin] ?? 1) - (FOLD_ORDER[b.origin] ?? 1) ||\n ruleSize(b) - ruleSize(a) ||\n drafts.indexOf(b) - drafts.indexOf(a)\n );\n });\n const victim = cands[0];\n const before = drafts.map(finish);\n drafts.splice(drafts.indexOf(victim), 1);\n let copy = drafts.find((r) => r.id === copyId);\n if (copy === undefined) {\n copy = {\n id: copyId,\n target: plan.target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n };\n plan.ids.add(copyId);\n } else {\n drafts.splice(drafts.indexOf(copy), 1);\n }\n for (const p of new Set(writes(victim))) {\n // the property's values as the whole stack resolved them, supplied on top for every element\n const t = truth.get(p);\n const vals = t === undefined ? resolveRules(before, plan.target, p, src, plan.budget) : t.slice();\n plan.columns.set(`copy.${p}`, vals);\n setMapping(copy, p, { kind: \"passthrough\", by: { style: `copy.${p}` } });\n }\n copy.facts = { ...copy.facts, reason: \"LAYER_CAP\" };\n drafts.push(copy);\n folded++;\n }\n if (folded > 0) {\n plan.notes.add(STYLE_ISSUE.LAYER_CAP, plan.target, null, { count: folded });\n }\n}\n\n/**\n * The elements whose resolved value is not the one wanted, with the wanted value; none where nothing is wanted, and\n * none where a ramp is tolerated within the tool's rounding.\n * @param n - the element count\n * @param got - the resolved values\n * @param want - the value wanted for an element, or null for none\n * @param tolerated - the elements a ramp matches only within the tool's rounding\n * @returns the wanted values where they differ, or null when none does\n */\nfunction differences(\n n: number,\n got: readonly (StyleValue | null)[],\n want: (i: number) => StyleValue | null,\n tolerated: ReadonlySet<number> | undefined,\n): (StyleValue | null)[] | null {\n let col: (StyleValue | null)[] | null = null;\n for (let i = 0; i < n; i++) {\n const w = want(i);\n const differs = w !== null && got[i] !== w && !(tolerated?.has(i) === true && within(got[i], w));\n if (differs) {\n col ??= new Array<StyleValue | null>(n).fill(null);\n col[i] = w;\n }\n }\n return col;\n}\n\n/**\n * The replay: resolves every property the file gives and compares it with the file's value, or the tool's default\n * where the file gives none. Each difference goes into one sparse exceptions column per property.\n * @param plan - the target's state\n * @param drafts - the rules, bottom to top\n * @param truth - the file's values per property\n * @param toolSet - the tool's default values, or null\n * @param tolerated - per property, the elements a ramp matches only within the tool's rounding\n * @param src - the reference source\n * @returns the exceptions rule, or null when nothing differs\n */\nfunction replay(\n plan: TargetPlan,\n drafts: readonly Draft[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n toolSet: Record<string, StyleValue> | null,\n tolerated: ReadonlyMap<string, ReadonlySet<number>>,\n src: ReturnType<typeof refSource>,\n): Draft | null {\n const rules = drafts.map(finish);\n // where the file gives no value, the tool draws its default: its constants, and where a reader adds tool rules\n // of its own (Graphviz's target arrow on directed edges), what those rules give over the constants\n const toolRules = rules.filter((r) => r.origin === \"tool\");\n const ownToolRules = toolRules.length > (toolSet === null ? 0 : 1);\n const map: Record<string, Mapping> = {};\n for (const [p, t] of truth) {\n const got = resolveRules(rules, plan.target, p, src, plan.budget);\n const perElement = ownToolRules ? resolveRules(toolRules, plan.target, p, src, plan.budget) : null;\n const constant = toolSet?.[p] ?? null;\n const want = (i: number): StyleValue | null => t[i] ?? (perElement === null ? constant : perElement[i]);\n const col = differences(plan.n, got, want, tolerated.get(p));\n if (col !== null) {\n plan.columns.set(`exceptions.${p}`, col);\n map[p] = { kind: \"passthrough\", by: { style: `exceptions.${p}` } };\n }\n }\n if (Object.keys(map).length === 0) {\n return null;\n }\n return {\n id: uniqueId(plan, `${plan.target}.exceptions`),\n target: plan.target,\n role: \"exceptions\",\n origin: \"inferred\",\n where: { all: true },\n map,\n };\n}\n","/**\n * Reading a file's styles after an import: the importer's own `styles()` (the simple path, canonicalized and planned\n * here, or the advanced path), the generic reader of the style roles (`color`, `size`, `shape`, `thickness`,\n * `hidden`) for an importer without one, and the `graphty.styles` block when a file graphty wrote carries it as a\n * graph attribute.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { keptForStyles } from \"../../common/report.js\";\nimport type { GraphImporter, ImportReport } from \"../../types.js\";\nimport { StyleBudget } from \"../budget.js\";\nimport { canonColor, colorOpacity } from \"../canon/color.js\";\nimport { canonEnum, type StyleEnumKind } from \"../canon/enums.js\";\nimport { canonBoolean, canonNumber, canonOpacity, DOT_POINTS_PER_INCH, styleLengthUnit } from \"../canon/number.js\";\nimport type { CanonSite } from \"../canon/site.js\";\nimport { canonText } from \"../canon/text.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport { StyleNotes } from \"../notes.js\";\nimport { featuresOf, styleFingerprint } from \"../plan/features.js\";\nimport { planStyles } from \"../plan/plan.js\";\nimport { plainCell } from \"../plan/resolve.js\";\nimport type {\n ExtractedStyles,\n GraphStyle,\n ImporterStyles,\n ReaderOutput,\n StyleColumn,\n StyleDialect,\n StyleNote,\n StyleProperty,\n StyleTarget,\n StyleTool,\n StyleValue,\n} from \"../types.js\";\nimport { STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { blockStyles, parseStyleBlock, STYLE_BLOCK_NAME } from \"./block.js\";\n\n/**\n * The `styles` option of `importGraph()` given as an object.\n * @category Styles\n */\nexport interface StyleImportOptions {\n /**\n * Whether a property the file leaves to its writing program's default gets that program's default (Cytoscape's,\n * Graphviz's, Gephi's ...), so the graph looks as it does there. Defaults to true.\n */\n readonly toolDefaults?: boolean;\n}\n\n/**\n * Options of `extractStyles()`.\n * @category Styles\n */\nexport interface ExtractStylesOptions extends StyleImportOptions {\n /** Cancels the extraction. */\n readonly signal?: AbortSignal | null;\n /**\n * The counted work budget to spend (and read back after: `budget.used(\"node\")`); a new one of\n * `STYLE_WORK_BUDGET` operations per target when absent.\n * @internal\n */\n readonly budget?: StyleBudget;\n}\n\nconst TARGETS: readonly StyleTarget[] = [\"node\", \"edge\"];\nconst ENUM_KINDS: ReadonlySet<string> = new Set([\"shape\", \"borderStyle\", \"lineStyle\", \"arrow\", \"weight\", \"position\"]);\n\n/** What the readers here produce before planning: canonical values and the data columns they came from. */\ninterface StyleTruth {\n readonly dialect: StyleDialect | null;\n readonly tool: StyleTool | null;\n readonly units: \"px\" | \"relative\";\n readonly graph: GraphStyle;\n readonly node: ReaderOutput;\n readonly edge: ReaderOutput;\n readonly raw: { readonly node: readonly string[]; readonly edge: readonly string[] };\n readonly notes: readonly StyleNote[];\n /** A `graphty.styles` block the importer found outside the graph attributes, or null. */\n readonly block?: string | null;\n /** Whether the format writes an opacity as its color's alpha (see `ImporterStyles`). */\n readonly opacityInColor?: boolean;\n}\n\n/**\n * Reads the styles of a file after its import: the reading importer's own `styles()` (with what its `import()` kept\n * for it), or the columns whose role is a style role when it has none; a `graphty.styles` block carried as a graph\n * attribute gives the rules, with the importer's values as the truth. Called by `importGraph()` when styles are\n * requested; a caller that drives an importer itself (into its own builder) calls it with the report `import()`\n * returned.\n * @param importer - the importer that read the file\n * @param snapshot - the graph it built\n * @param report - the report its `import()` returned\n * @param options - tool defaults and a cancel signal\n * @returns the styles, or null when the file has none\n * @category Styles\n */\nexport function extractStyles(\n importer: GraphImporter,\n snapshot: GraphSnapshot,\n report: ImportReport,\n options: ExtractStylesOptions = {},\n): ExtractedStyles | null {\n const signal = options.signal ?? undefined;\n const notes = new StyleNotes();\n const budget = options.budget ?? new StyleBudget();\n const canonical = readStyleValues(importer, snapshot, report, { notes, budget, signal });\n const fingerprint = styleFingerprint(snapshot);\n const blockText = canonical?.block ?? graphValue(snapshot, STYLE_BLOCK_NAME);\n if (blockText !== undefined) {\n const parsed = parseStyleBlock(blockText, fingerprint);\n if (parsed.ok) {\n const truth = canonical === null ? {} : { node: canonical.node.values, edge: canonical.edge.values };\n const fromBlock = blockStyles(\n parsed.block,\n snapshot,\n importer.format,\n truth,\n canonical?.notes ?? [],\n canonical?.tool ?? null,\n canonical?.opacityInColor === true,\n );\n if (fromBlock !== null) {\n return fromBlock;\n }\n notes.add(STYLE_ISSUE.BLOCK_IGNORED, null, null, { sample: \"INVALID\" });\n } else {\n notes.add(STYLE_ISSUE.BLOCK_IGNORED, null, null, { sample: parsed.reason });\n }\n }\n if (canonical === null) {\n const list = notes.list();\n return list.length === 0 ? null : emptyStyles(importer.format, list, snapshot, fingerprint);\n }\n const raw = { node: new Set(canonical.raw.node), edge: new Set(canonical.raw.edge) };\n const features = {\n node: featuresOf(snapshot, \"node\").filter((f) => !(\"data\" in f.ref && raw.node.has(f.ref.data))),\n edge: featuresOf(snapshot, \"edge\").filter((f) => !(\"data\" in f.ref && raw.edge.has(f.ref.data))),\n };\n const planned = planStyles(\n {\n format: importer.format,\n dialect: canonical.dialect,\n tool: canonical.tool,\n units: canonical.units,\n graph: canonical.graph,\n node: canonical.node,\n edge: canonical.edge,\n fingerprint,\n },\n features,\n {\n toolDefaults: options.toolDefaults,\n budget,\n notes,\n rawColumns: { node: canonical.raw.node, edge: canonical.raw.edge },\n signal,\n },\n );\n if (canonical.notes.length === 0) {\n return planned;\n }\n return { ...planned, styles: { ...planned.styles, notes: [...canonical.notes, ...planned.styles.notes] } };\n}\n\n/**\n * What a file's styles are before planning: each element's canonical value per property, as the importer's own\n * `styles()` gives them (the simple path canonicalized) or, for an importer without one, as the generic reader reads\n * the columns with a style role. The truth the planned rules must reproduce; not part of the published entry.\n * @param importer - the importer that read the file\n * @param snapshot - the graph it built\n * @param report - the report its `import()` returned\n * @param context - where problems are noted, the work budget and a cancel signal\n * @param context.notes - where problems are noted\n * @param context.budget - the work budget\n * @param context.signal - cancels the work\n * @returns the canonical values, or null when the file has no styles\n */\nexport function readStyleValues(\n importer: GraphImporter,\n snapshot: GraphSnapshot,\n report: ImportReport,\n context: { readonly notes: StyleNotes; readonly budget: StyleBudget; readonly signal?: AbortSignal | undefined },\n): StyleTruth | null {\n const { notes, budget, signal } = context;\n signal?.throwIfAborted();\n let canonical: StyleTruth | null;\n if (importer.styles === undefined) {\n canonical = roleStyles(snapshot, importer.format, notes, budget);\n } else {\n const got = importer.styles(snapshot, { signal, budget, kept: keptForStyles(report) });\n canonical = got === null ? null : canonicalOf(got, snapshot, notes, budget, signal);\n }\n signal?.throwIfAborted();\n return canonical === null ? null : withPairedHalves(canonical, snapshot);\n}\n\n/**\n * The values with the second half of each undirected edge of a directed graph given its first half's value: the file\n * holds the edge once, its program draws it once, and the import read the element's values onto the first half.\n * @param truth - the values read\n * @param snapshot - the graph\n * @returns the values\n */\nfunction withPairedHalves(truth: StyleTruth, snapshot: GraphSnapshot): StyleTruth {\n const pair = snapshot.edges.byRole(\"pair\");\n if (pair === null) {\n return truth;\n }\n const values: Partial<Record<StyleProperty, StyleColumn>> = {};\n for (const [property, col] of Object.entries(truth.edge.values) as [StyleProperty, StyleColumn | undefined][]) {\n if (col === undefined) {\n continue;\n }\n const out = [...col];\n for (let e = 0; e < out.length; e++) {\n const first = pair.isSet(e) ? (pair.value(e) as number) : e;\n if (first < e) {\n out[e] = col[first] ?? null;\n }\n }\n values[property] = out;\n }\n return { ...truth, edge: { ...truth.edge, values } };\n}\n\n/**\n * A graph attribute's value, or undefined.\n * @param snapshot - the graph\n * @param name - the attribute\n * @returns its value\n */\nfunction graphValue(snapshot: GraphSnapshot, name: string): unknown {\n return snapshot.graph.has(name) ? plainCell(snapshot.graph.value(name, 0)) : undefined;\n}\n\n/**\n * Styles holding nothing but notes.\n * @param format - the format\n * @param notes - the notes\n * @param snapshot - the graph\n * @param fingerprint - its fingerprint\n * @returns the styles\n */\nfunction emptyStyles(\n format: string,\n notes: readonly StyleNote[],\n snapshot: GraphSnapshot,\n fingerprint: ExtractedStyles[\"fingerprint\"],\n): ExtractedStyles {\n return {\n styles: {\n version: 1,\n source: { format, dialect: null, tool: null },\n units: { length: \"px\" },\n graph: {},\n rules: [],\n notes,\n },\n columns: { node: new Map(), edge: new Map() },\n features: { node: featuresOf(snapshot, \"node\"), edge: featuresOf(snapshot, \"edge\") },\n fingerprint,\n };\n}\n\n/**\n * An importer's styles as canonical values: the advanced path as it is, the simple path read and canonicalized.\n * @param got - what the importer's `styles()` returned\n * @param snapshot - the graph\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @param signal - cancels the work\n * @returns the canonical values\n */\nfunction canonicalOf(\n got: ImporterStyles,\n snapshot: GraphSnapshot,\n notes: StyleNotes,\n budget: StyleBudget,\n signal: AbortSignal | undefined,\n): StyleTruth {\n if (\"canonical\" in got) {\n return {\n dialect: got.dialect ?? null,\n tool: got.tool ?? null,\n units: got.units ?? \"px\",\n graph: got.graph ?? {},\n node: got.node ?? { values: {} },\n edge: got.edge ?? { values: {} },\n raw: { node: got.readFrom?.node ?? [], edge: got.readFrom?.edge ?? [] },\n notes: got.notes ?? [],\n block: got.block ?? null,\n opacityInColor: got.opacityInColor === true,\n };\n }\n const { dialect } = got;\n const raw = { node: [] as string[], edge: [] as string[] };\n const out = { node: { values: {} } as ReaderOutput, edge: { values: {} } as ReaderOutput };\n for (const target of TARGETS) {\n const given = got[target];\n if (given === undefined) {\n continue;\n }\n const columns = new Map<string, readonly unknown[]>();\n for (const [property, source] of Object.entries(given)) {\n signal?.throwIfAborted();\n const values = rawValues(snapshot, target, property, source, notes, raw[target]);\n if (values !== null) {\n columns.set(property, values);\n }\n }\n out[target] = { values: canonicalize(target, columns, dialect, count(snapshot, target), notes, budget) };\n }\n return {\n dialect,\n tool: null,\n units: styleLengthUnit(dialect),\n graph: {},\n node: out.node,\n edge: out.edge,\n raw,\n notes: [],\n };\n}\n\n/**\n * The element count of a target.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @returns the count\n */\nfunction count(snapshot: GraphSnapshot, target: StyleTarget): number {\n return target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n}\n\n/**\n * The raw values of one property on the simple path: a snapshot column by name, or an array by element index.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @param property - the property\n * @param source - `{ data: \"<column>\" }` or an array\n * @param notes - where a missing column is noted\n * @param raw - collects the names of the columns read\n * @returns the values, or null\n */\nfunction rawValues(\n snapshot: GraphSnapshot,\n target: StyleTarget,\n property: string,\n source: unknown,\n notes: StyleNotes,\n raw: string[],\n): readonly unknown[] | null {\n if (Array.isArray(source)) {\n return source as unknown[];\n }\n if (source === null || typeof source !== \"object\" || typeof (source as { data?: unknown }).data !== \"string\") {\n notes.add(STYLE_ISSUE.BAD_MAPPING, target, property, { sample: source });\n return null;\n }\n const name = (source as { data: string }).data;\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n if (!table.has(name)) {\n notes.add(STYLE_ISSUE.MAPPING_COLUMN_MISSING, target, property, { sample: name });\n return null;\n }\n raw.push(name);\n const n = count(snapshot, target);\n const out = new Array<unknown>(n);\n for (let i = 0; i < n; i++) {\n out[i] = plainCell(table.value(name, i));\n }\n return out;\n}\n\n/**\n * Canonical values of every property of one target. A list value is read as its first item. A color's alpha moves\n * into the fill's or the edge's opacity (multiplied with an opacity the file also states) or is dropped with a note.\n * @param target - nodes or edges\n * @param columns - the raw values per property\n * @param dialect - how they are spelled\n * @param n - the element count\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @returns the canonical values per property\n */\nfunction canonicalize(\n target: StyleTarget,\n columns: ReadonlyMap<string, readonly unknown[]>,\n dialect: StyleDialect,\n n: number,\n notes: StyleNotes,\n budget: StyleBudget,\n): Record<string, StyleColumn> {\n const cx: CanonContext = { target, dialect, n, notes, budget };\n // keyed by the importer's property names: no prototype, so `__proto__` is a property like any other\n const out: Record<string, (StyleValue | null)[]> = Object.create(null) as Record<string, (StyleValue | null)[]>;\n const alphas = new Map<string, (number | null)[]>();\n for (const [property, raws] of columns) {\n const { col, alpha } = canonicalColumn(cx, property, raws);\n out[property] = col;\n if (alpha !== null) {\n alphas.set(property, alpha);\n }\n }\n for (const [property, alpha] of alphas) {\n moveAlpha(cx, out, property, alpha);\n }\n return out;\n}\n\n/** What canonicalize() reads one target's values with. */\ninterface CanonContext {\n readonly target: StyleTarget;\n readonly dialect: StyleDialect;\n /** The element count. */\n readonly n: number;\n readonly notes: StyleNotes;\n readonly budget: StyleBudget;\n}\n\n/**\n * Canonical values of one property; a color's alpha below 1 is kept apart.\n * @param cx - the target being read\n * @param property - the property\n * @param raws - its raw values\n * @returns the values, and the alphas (null when every color is opaque)\n */\nfunction canonicalColumn(\n cx: CanonContext,\n property: string,\n raws: readonly unknown[],\n): { col: (StyleValue | null)[]; alpha: (number | null)[] | null } {\n const { target, dialect, n, notes, budget } = cx;\n const kind = STYLE_PROPERTIES[target].get(property);\n const col = new Array<StyleValue | null>(n).fill(null);\n let alpha: (number | null)[] | null = null;\n for (let i = 0; i < n && i < raws.length; i++) {\n const site: CanonSite = { notes, target, property, element: i, budget };\n const v = firstItem(raws[i], site);\n if (v === null || v === undefined) {\n continue;\n }\n if (kind !== \"color\") {\n col[i] = canonValue(kind, property, v, dialect, site);\n continue;\n }\n const c = canonColor(v, dialect, site, { use: colorUse(target, property) });\n col[i] = c?.color ?? null;\n if (c !== null && c.alpha < 1) {\n alpha ??= new Array<number | null>(n).fill(null);\n alpha[i] = c.alpha;\n }\n }\n return { col, alpha };\n}\n\n/**\n * A raw value, a list read as its first item (a longer list noted).\n * @param v - the raw value\n * @param site - where it was read\n * @returns the value\n */\nfunction firstItem(v: unknown, site: CanonSite): unknown {\n if (!Array.isArray(v)) {\n return v;\n }\n if (v.length > 1) {\n site.notes.add(STYLE_ISSUE.BAD_VALUE, site.target, site.property, { sample: v, element: site.element });\n }\n return v.length === 0 ? null : v[0];\n}\n\n/**\n * Moves a color property's alphas into its opacity (multiplied with an opacity the file also states), or drops them\n * with a note where the property has none.\n * @param cx - the target being read\n * @param out - the canonical values, changed in place\n * @param property - the color property\n * @param alpha - its alphas\n */\nfunction moveAlpha(\n cx: CanonContext,\n out: Record<string, (StyleValue | null)[]>,\n property: string,\n alpha: readonly (number | null)[],\n): void {\n const { target, n, notes, budget } = cx;\n const carrier = OPACITY_OF.get(`${target}.${property}`) ?? null;\n let opacity: (StyleValue | null)[] | null = null;\n if (carrier !== null) {\n out[carrier] ??= new Array<StyleValue | null>(n).fill(null);\n opacity = out[carrier];\n }\n for (let i = 0; i < n; i++) {\n const a = alpha[i];\n if (a === null) {\n continue;\n }\n const site: CanonSite = { notes, target, property, element: i, budget };\n const stated = opacity === null ? null : (opacity[i] as number | null);\n const merged = colorOpacity(\n { color: out[property][i] as `#${string}`, alpha: a },\n stated,\n site,\n opacity !== null,\n );\n if (opacity !== null) {\n opacity[i] = merged;\n }\n }\n}\n\n/** The opacity property that carries a color's alpha: a node's fill and an edge's line. */\nconst OPACITY_OF: ReadonlyMap<string, string> = new Map([\n [\"node.fill\", \"fillOpacity\"],\n [\"edge.color\", \"opacity\"],\n]);\n\n/**\n * How a color is drawn, which decides how a Graphviz color list is read.\n * @param target - nodes or edges\n * @param property - the property\n * @returns the use\n */\nfunction colorUse(target: StyleTarget, property: string): \"fill\" | \"edge\" | \"line\" {\n if (property === \"fill\") {\n return \"fill\";\n }\n return target === \"edge\" && property === \"color\" ? \"edge\" : \"line\";\n}\n\n/**\n * The canonical value of a property that is not a color.\n * @param kind - the property's value kind, or undefined for a property outside the vocabulary\n * @param property - the property\n * @param raw - the raw value\n * @param dialect - how it is spelled\n * @param site - where it was read\n * @returns the value, or null\n */\nfunction canonValue(\n kind: string | undefined,\n property: string,\n raw: unknown,\n dialect: StyleDialect,\n site: CanonSite,\n): StyleValue | null {\n switch (kind) {\n case \"number\":\n return canonNumber(\n raw,\n site,\n dialect === \"graphviz\" && (property === \"width\" || property === \"height\") ? DOT_POINTS_PER_INCH : 1,\n );\n case \"opacity\":\n return canonOpacity(raw, dialect, site);\n case \"boolean\":\n return canonBoolean(raw, site);\n case \"text\":\n return canonText(raw, site);\n case undefined:\n // a property only one consumer draws (graphty:<channel>) is carried as it is\n return typeof raw === \"string\" ||\n typeof raw === \"boolean\" ||\n (typeof raw === \"number\" && Number.isFinite(raw))\n ? raw\n : null;\n default:\n return ENUM_KINDS.has(kind) ? canonEnum(kind as StyleEnumKind, raw, dialect, site) : null;\n }\n}\n\n/** The style roles and the property each sets, per target; `size` sets a node's width and height. */\nconst ROLE_PROPERTIES: Readonly<Record<StyleTarget, readonly (readonly [string, readonly string[]])[]>> = {\n node: [\n [\"color\", [\"fill\"]],\n [\"size\", [\"width\", \"height\"]],\n [\"shape\", [\"shape\"]],\n [\"hidden\", [\"visible\"]],\n ],\n edge: [\n [\"color\", [\"color\"]],\n [\"thickness\", [\"width\"]],\n [\"shape\", [\"lineStyle\"]],\n [\"hidden\", [\"visible\"]],\n ],\n};\n\n/**\n * The generic reader: the styles of the columns whose role is `color`, `size`, `shape`, `thickness` or `hidden`, so a\n * format that tags its style columns needs no reader of its own. A color column holds CSS text or channel numbers\n * (0..1 in a float column, 0..255 otherwise, with an optional alpha); a hidden column holds booleans.\n * @param snapshot - the graph\n * @param dialect - how text values are spelled (the format's name; CSS for a format with no dialect of its own)\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @returns the canonical values, or null when no column has a style role\n */\nfunction roleStyles(\n snapshot: GraphSnapshot,\n dialect: StyleDialect,\n notes: StyleNotes,\n budget: StyleBudget,\n): StyleTruth | null {\n const raw = { node: [] as string[], edge: [] as string[] };\n const out = { node: { values: {} } as ReaderOutput, edge: { values: {} } as ReaderOutput };\n for (const target of TARGETS) {\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = count(snapshot, target);\n const columns = new Map<string, readonly unknown[]>();\n for (const [role, properties] of ROLE_PROPERTIES[target]) {\n const col = table.byRole(role);\n if (col === null) {\n continue;\n }\n raw[target].push(col.meta.name);\n const vals = roleValues(table, col.meta, role, n);\n for (const p of properties) {\n columns.set(p, vals);\n }\n }\n out[target] = { values: canonicalize(target, columns, dialect, n, notes, budget) };\n }\n if (raw.node.length === 0 && raw.edge.length === 0) {\n return null;\n }\n return {\n dialect,\n tool: null,\n units: styleLengthUnit(dialect),\n graph: {},\n node: out.node,\n edge: out.edge,\n raw,\n notes: [],\n };\n}\n\n/**\n * A role column's raw values: a color as text, a hidden flag as the visibility it says the opposite of.\n * @param table - the node or edge table\n * @param meta - the column's name and dtype\n * @param meta.name - the column's name\n * @param meta.dtype - its dtype\n * @param role - its role\n * @param n - the element count\n * @returns the values\n */\nfunction roleValues(\n table: GraphSnapshot[\"nodes\"],\n meta: { readonly name: string; readonly dtype: string },\n role: string,\n n: number,\n): unknown[] {\n return Array.from({ length: n }, (_, i) => {\n const v = plainCell(table.value(meta.name, i));\n if (role === \"color\") {\n return channelsColor(v, meta.dtype);\n }\n if (role === \"hidden\") {\n return typeof v === \"boolean\" ? !v : null;\n }\n return v;\n });\n}\n\n/**\n * A color cell as text: channel numbers become `rgba()` (floats 0..1, integers 0..255); text stays as it is.\n * @param v - the cell\n * @param dtype - the column's dtype\n * @returns the color's text, or the cell unchanged\n */\nfunction channelsColor(v: unknown, dtype: string): unknown {\n if (\n !Array.isArray(v) ||\n (v.length !== 3 && v.length !== 4) ||\n !v.every((x) => typeof x === \"number\" && Number.isFinite(x))\n ) {\n return v;\n }\n const scale = dtype === \"f32\" || dtype === \"f64\" ? 255 : 1;\n const [r, g, b] = (v as number[]).map((x) => Math.round(x * scale));\n const alphaScale = scale === 255 ? 1 : 255;\n const a = v.length === 4 ? (v[3] as number) / alphaScale : 1;\n return `rgba(${String(r)}, ${String(g)}, ${String(b)}, ${String(a)})`;\n}\n"],"names":["count","raw"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"generic-CP6YD34u.js","sources":["../../src/styles/plan/families.ts","../../src/styles/plan/discrete.ts","../../src/styles/plan/classes.ts","../../src/styles/plan/continuous.ts","../../src/styles/plan/plan.ts","../../src/styles/io/generic.ts"],"sourcesContent":["/**\n * Exact equivalence classes: every property's values partition the elements (null is a block of its own), and\n * properties with identical partitions form one family, explained once.\n */\n\nimport type { StyleValue } from \"../types.js\";\n\n/**\n * A group of properties that partition the elements the same way.\n */\nexport interface Family {\n /** The properties, in the order they were given. */\n readonly props: string[];\n /** Each element's block: 0 for null, 1.. by first appearance. */\n readonly blocks: Int32Array;\n /** The number of non-null blocks. */\n readonly k: number;\n /** The elements with a value (block above 0), ascending. */\n readonly styled: number[];\n}\n\n/**\n * The text a value is compared by.\n * @param v - the value\n * @returns a key unique per value and type\n */\nexport function valueKey(v: string | number | boolean | null | undefined): string {\n return v === null || v === undefined ? \"\\u0000null\" : `${typeof v}:${String(v)}`;\n}\n\n/**\n * The partition of the elements by a property's values.\n * @param values - the values by element\n * @returns each element's block (0 for null, then by first appearance) and the number of non-null blocks\n */\nfunction partition(values: readonly (StyleValue | null)[]): { blocks: Int32Array; k: number } {\n const ids = new Map<string, number>();\n const blocks = new Int32Array(values.length);\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (v === null) {\n continue;\n }\n const key = valueKey(v);\n let id = ids.get(key);\n if (id === undefined) {\n id = ids.size + 1;\n ids.set(key, id);\n }\n blocks[i] = id;\n }\n return { blocks, k: ids.size };\n}\n\n/**\n * A hash of a block array.\n * @param blocks - the blocks\n * @returns its hash\n */\nfunction hashBlocks(blocks: Int32Array): number {\n let h = 0x811c9dc5;\n for (const b of blocks) {\n h = Math.imul(h ^ b, 0x01000193);\n }\n return h >>> 0;\n}\n\n/**\n * Whether two block arrays are equal.\n * @param a - one\n * @param b - the other\n * @returns true when equal\n */\nfunction sameBlocks(a: Int32Array, b: Int32Array): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Groups properties by identical partitions.\n * @param props - the properties, each with its values\n * @returns the families, in the order of their first property\n */\nexport function familiesOf(props: readonly (readonly [string, readonly (StyleValue | null)[]])[]): Family[] {\n const byHash = new Map<number, Family[]>();\n const out: Family[] = [];\n for (const [p, values] of props) {\n const { blocks, k } = partition(values);\n const h = hashBlocks(blocks);\n const list = byHash.get(h) ?? [];\n const hit = list.find((f) => sameBlocks(f.blocks, blocks));\n if (hit !== undefined) {\n hit.props.push(p);\n continue;\n }\n const styled: number[] = [];\n for (let i = 0; i < blocks.length; i++) {\n if (blocks[i] !== 0) {\n styled.push(i);\n }\n }\n const fam: Family = { props: [p], blocks, k, styled };\n list.push(fam);\n byHash.set(h, list);\n out.push(fam);\n }\n return out;\n}\n","/**\n * A discrete mapping on one categorical feature: the feature's values fall inside the family's blocks, up to 20% of\n * the styled elements excepted, and the elements missing the feature may form their own group.\n */\n\nimport { type Family, valueKey } from \"./families.js\";\nimport type { FeatureInfo } from \"./features.js\";\n\n/** Below this many styled elements anything explains anything: no mapping is tried. */\nexport const MIN_MAPPED = 8;\n/** The most keys a discrete table may hold. */\nconst MAX_KEYS = 256;\n/** The share of styled elements a mapping may get wrong; the replay moves them into the exceptions. */\nconst MAX_EXCEPTION_SHARE = 0.2;\n\n/** A key of a discrete table, as the feature holds it. */\ntype KeyValue = string | number | boolean;\n\n/**\n * A discrete mapping that explains a family.\n */\nexport interface DiscreteCandidate {\n /** The kind of candidate. */\n readonly type: \"discrete\";\n /** The feature the table reads. */\n readonly info: FeatureInfo;\n /** Each key (by its value key) with its raw value and the block it maps to. */\n readonly table: Map<string, { readonly raw: KeyValue; readonly block: number }>;\n /** The block the elements missing the feature share, or null. */\n readonly bucket: number | null;\n /** The description cost. */\n readonly cost: number;\n}\n\n/**\n * Tests a discrete mapping on one feature.\n * @param fam - the family\n * @param info - the feature\n * @param n - the element count\n * @param spend - spends work from the budget\n * @returns the candidate, or null when the feature does not explain the family\n */\nexport function discreteCandidate(\n fam: Family,\n info: FeatureInfo,\n n: number,\n spend: (ops: number) => void,\n): DiscreteCandidate | null {\n const nF = fam.styled.length;\n if (!info.categorical || info.raw || nF < MIN_MAPPED) {\n return null;\n }\n if (info.distinct < 2 || info.distinct > Math.min(MAX_KEYS, nF / 2) || info.distinct >= 0.9 * n) {\n return null;\n }\n spend(n);\n const { values } = info.feature;\n const { votes, nullBlocks } = votesOf(fam, values);\n const { table, exceptions: wrong } = tableOf(votes);\n let exceptions = wrong;\n // never paint an element the file left unstyled\n const unstyledMissing = unstyledOf(fam, values, table, n);\n if (unstyledMissing === null) {\n return null;\n }\n // the elements missing the key form one group when they share one style (Gephi's \"null\" partition)\n let bucket: number | null = null;\n if (nullBlocks.size === 1 && !unstyledMissing) {\n bucket = nullBlocks.keys().next().value ?? null;\n } else {\n for (const c of nullBlocks.values()) {\n exceptions += c;\n }\n }\n if (exceptions > Math.max(2, MAX_EXCEPTION_SHARE * nF)) {\n return null;\n }\n const cost =\n 50 + table.size * fam.props.length + (exceptions > 0 ? 50 + exceptions : 0) + (bucket === null ? 0 : 50);\n return { type: \"discrete\", info, table, bucket, cost };\n}\n\n/** How the styled elements of each key fall into the family's blocks. */\ntype Votes = Map<string, { raw: KeyValue; counts: Map<number, number> }>;\n\n/**\n * Counts, per key of the feature, the styled elements in each block; and per block, those missing the feature.\n * @param fam - the family\n * @param values - the feature's values\n * @returns the votes, and the blocks of the elements missing the feature\n */\nfunction votesOf(fam: Family, values: readonly (KeyValue | null)[]): { votes: Votes; nullBlocks: Map<number, number> } {\n const votes: Votes = new Map();\n const nullBlocks = new Map<number, number>();\n for (const i of fam.styled) {\n const b = fam.blocks[i];\n const kv = values[i];\n if (kv === null) {\n nullBlocks.set(b, (nullBlocks.get(b) ?? 0) + 1);\n continue;\n }\n const key = valueKey(kv);\n let vote = votes.get(key);\n if (vote === undefined) {\n vote = { raw: kv, counts: new Map() };\n votes.set(key, vote);\n }\n vote.counts.set(b, (vote.counts.get(b) ?? 0) + 1);\n }\n return { votes, nullBlocks };\n}\n\n/**\n * The table: each key maps to the block most of its elements are in; the others are exceptions.\n * @param votes - the votes\n * @returns the table and how many elements it gets wrong\n */\nfunction tableOf(votes: Votes): { table: Map<string, { raw: KeyValue; block: number }>; exceptions: number } {\n const table = new Map<string, { raw: KeyValue; block: number }>();\n let exceptions = 0;\n for (const [key, { raw, counts }] of votes) {\n let best = -1;\n let bestCount = -1;\n let total = 0;\n for (const [b, c] of counts) {\n total += c;\n if (c > bestCount) {\n bestCount = c;\n best = b;\n }\n }\n table.set(key, { raw, block: best });\n exceptions += total - bestCount;\n }\n return { table, exceptions };\n}\n\n/**\n * Whether an element the file left unstyled misses the feature (or holds false, which a missing-key group's \"not has\"\n * also matches).\n * @param fam - the family\n * @param values - the feature's values\n * @param table - the table\n * @param n - the element count\n * @returns the answer, or null when the table would paint an unstyled element\n */\nfunction unstyledOf(\n fam: Family,\n values: readonly (KeyValue | null)[],\n table: ReadonlyMap<string, unknown>,\n n: number,\n): boolean | null {\n let missing = false;\n for (let i = 0; i < n; i++) {\n const v = values[i];\n if (fam.blocks[i] !== 0) {\n continue;\n }\n if (v !== null && table.has(valueKey(v))) {\n return null;\n }\n missing ||= v === null || v === false;\n }\n return missing;\n}\n","/**\n * The opaque pool: the families nothing explains. Over their non-text, non-size properties each distinct joint tuple\n * of values is a style class, numbered 1..k by frequency in the style column `class`; a few classes become one group\n * rule each, more become one table keyed by the class. What is left is copied per element.\n */\n\nimport type { StyleRule, StyleTarget, StyleValue } from \"../types.js\";\nimport { STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { MIN_MAPPED } from \"./discrete.js\";\nimport { valueKey } from \"./families.js\";\n\n/** The most style classes; more distinct tuples are copied per element. */\nconst MAX_CLASSES = 64;\n/** At most this many classes become one group rule each. */\nconst MAX_CLASS_RULES = 4;\n/** Sizes vary per element by nature and are never joined into a class. */\nconst SIZES: ReadonlySet<string> = new Set([\"width\", \"height\"]);\n/** The style column holding each element's class. */\nexport const CLASS_COLUMN = \"class\";\n\n/**\n * The style classes of an opaque pool.\n */\ninterface StyleClasses {\n /** The properties the classes explain. */\n readonly classed: readonly string[];\n /** The class of each element, 1..k, or null. */\n readonly column: (number | null)[];\n /** One group rule per class, or one mapping rule keyed by the class. */\n readonly rules: StyleRule[];\n}\n\n/**\n * Whether a property's values have few enough distinct values to be part of a class.\n * @param values - the values\n * @returns true when they do\n */\nfunction fewValues(values: readonly (StyleValue | null)[]): boolean {\n const seen = new Set<string>();\n for (const v of values) {\n seen.add(valueKey(v));\n if (seen.size > MAX_CLASSES + 1) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * One element's combination of values of the classable properties, as a key; null when it has none.\n * @param classable - the properties\n * @param truth - the values per property\n * @param i - the element\n * @returns the key\n */\nfunction tupleKey(\n classable: readonly string[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n i: number,\n): string | null {\n let key = \"\";\n let any = false;\n for (const p of classable) {\n const v = (truth.get(p) ?? [])[i] ?? null;\n any ||= v !== null;\n key += `${valueKey(v)}\\u0001`;\n }\n return any ? key : null;\n}\n\n/**\n * Finds the style classes of the opaque properties.\n * @param target - nodes or edges\n * @param props - the opaque properties\n * @param truth - the values per property\n * @param n - the element count\n * @param spend - spends work from the budget\n * @returns the classes, or null when the values have too many combinations\n */\nexport function styleClasses(\n target: StyleTarget,\n props: readonly string[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n n: number,\n spend: (ops: number) => void,\n): StyleClasses | null {\n const classable = props.filter(\n (p) => STYLE_PROPERTIES[target].get(p) !== \"text\" && !SIZES.has(p) && fewValues(truth.get(p) ?? []),\n );\n if (classable.length === 0) {\n return null;\n }\n spend(n * (classable.length + 1));\n const counts = new Map<string, { count: number; rep: number }>();\n const tupleOf = new Array<string | null>(n).fill(null);\n let withTuple = 0;\n for (let i = 0; i < n; i++) {\n const key = tupleKey(classable, truth, i);\n if (key === null) {\n continue;\n }\n withTuple++;\n tupleOf[i] = key;\n const c = counts.get(key);\n if (c === undefined) {\n counts.set(key, { count: 1, rep: i });\n if (counts.size > MAX_CLASSES) {\n return null;\n }\n } else {\n c.count++;\n }\n }\n if (counts.size === 0 || withTuple < MIN_MAPPED || counts.size * 2 > withTuple) {\n return null;\n }\n // classes by frequency, ties by first appearance (a stable sort)\n const order = Array.from(counts.entries()).sort((a, b) => b[1].count - a[1].count);\n const rank = new Map(order.map(([key], j) => [key, j + 1]));\n const column = tupleOf.map((t) => (t === null ? null : (rank.get(t) ?? null)));\n const ref = { style: CLASS_COLUMN };\n const valueOf = (p: string, rep: number): StyleValue | null => (truth.get(p) ?? [])[rep] ?? null;\n const rules: StyleRule[] = [];\n if (order.length <= Math.min(MAX_CLASS_RULES, Math.floor(withTuple / 4))) {\n order.forEach(([, { count, rep }], j) => {\n const set: Record<string, StyleValue> = {};\n for (const p of classable) {\n const v = valueOf(p, rep);\n if (v !== null) {\n set[p] = v;\n }\n }\n rules.push({\n id: `${target}.class.${String(j + 1)}`,\n target,\n role: \"group\",\n origin: \"inferred\",\n where: { eq: [ref, j + 1] },\n set,\n facts: { elements: count, reason: \"STYLE_CLASS\" },\n });\n });\n } else {\n const map: Record<string, { kind: \"discrete\"; by: { style: string }; table: [number, StyleValue][] }> = {};\n for (const p of classable) {\n const table: [number, StyleValue][] = [];\n order.forEach(([, { rep }], j) => {\n const v = valueOf(p, rep);\n if (v !== null) {\n table.push([j + 1, v]);\n }\n });\n map[p] = { kind: \"discrete\", by: ref, table };\n }\n rules.push({\n id: `${target}.classes`,\n target,\n role: \"mapping\",\n origin: \"inferred\",\n where: { all: true },\n map,\n facts: { classes: order.length, elements: withTuple, reason: \"STYLE_CLASS\" },\n });\n }\n return { classed: classable, column, rules };\n}\n","/**\n * A continuous mapping on one numeric feature: the fewest linear pieces (at most 8, each explaining at least 3\n * distinct inputs), exact first, else within the rounding the writing tool did per element.\n */\n\nimport type { ContinuousPoint, StyleValue } from \"../types.js\";\nimport { MIN_MAPPED } from \"./discrete.js\";\nimport type { Family } from \"./families.js\";\nimport type { FeatureInfo } from \"./features.js\";\nimport { interpolate, within } from \"./resolve.js\";\n\n/** The most linear pieces a ramp may have. */\nconst MAX_PIECES = 8;\n/** The most distinct inputs a ramp is fitted over. */\nconst MAX_DISTINCT_X = 4096;\nconst HEX6 = /^#[0-9a-f]{6}$/;\n\n/**\n * A continuous mapping that explains a family.\n */\nexport interface ContinuousCandidate {\n /** The kind of candidate. */\n readonly type: \"continuous\";\n /** The feature the ramp reads. */\n readonly info: FeatureInfo;\n /** The points per property. */\n readonly points: ReadonlyMap<string, ContinuousPoint[]>;\n /** Whether the ramp matches only within the tool's rounding. */\n readonly tolerant: boolean;\n /** The description cost. */\n readonly cost: number;\n}\n\n/**\n * Whether a value can be interpolated: a number or a canonical color.\n * @param v - the value\n * @returns true when it can\n */\nfunction interpolable(v: StyleValue | null): v is number | string {\n return typeof v === \"number\" || (typeof v === \"string\" && HEX6.test(v));\n}\n\n/**\n * The fewest linear pieces over sorted distinct points, or null when more than `MAX_PIECES` are needed.\n * @param xs - the inputs, ascending\n * @param ys - the outputs\n * @param tolerant - whether a piece may miss a point by the tool's rounding\n * @param spend - spends work from the budget\n * @returns each piece's first and last point index, or null\n */\nfunction fitPieces(\n xs: readonly number[],\n ys: readonly StyleValue[],\n tolerant: boolean,\n spend: (ops: number) => void,\n): [number, number][] | null {\n const pieces: [number, number][] = [];\n let a = 0;\n while (a < xs.length) {\n let b = a;\n // extend while the line from a to b + 1 reproduces every point between\n while (b + 1 < xs.length) {\n const ok = lineFits(xs, ys, a, b + 1, tolerant);\n spend(b + 1 - a);\n if (!ok) {\n break;\n }\n b++;\n }\n pieces.push([a, b]);\n if (pieces.length > MAX_PIECES) {\n return null;\n }\n a = b + 1;\n }\n return pieces;\n}\n\n/**\n * Whether the line from point a to point c reproduces every point between.\n * @param xs - the inputs, ascending\n * @param ys - the outputs\n * @param a - the first point\n * @param c - the last point\n * @param tolerant - whether the line may miss a point by the tool's rounding\n * @returns true when it does\n */\nfunction lineFits(xs: readonly number[], ys: readonly StyleValue[], a: number, c: number, tolerant: boolean): boolean {\n for (let j = a + 1; j < c; j++) {\n const v = interpolate(ys[a], ys[c], (xs[j] - xs[a]) / (xs[c] - xs[a]));\n if (tolerant ? !within(v, ys[j]) : v !== ys[j]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * The points of a fitted ramp.\n * @param xs - the inputs\n * @param ys - the outputs\n * @param pieces - the pieces\n * @returns the points, ascending\n */\nfunction piecesToPoints(\n xs: readonly number[],\n ys: readonly StyleValue[],\n pieces: [number, number][],\n): ContinuousPoint[] {\n const out: ContinuousPoint[] = [];\n for (const [a, b] of pieces) {\n out.push({ at: xs[a], below: ys[a], value: ys[a], above: ys[a] });\n if (b !== a) {\n out.push({ at: xs[b], below: ys[b], value: ys[b], above: ys[b] });\n }\n }\n return out;\n}\n\n/**\n * Tests a continuous mapping on one feature.\n * @param fam - the family\n * @param info - the feature\n * @param truth - the values per property\n * @param spend - spends work from the budget\n * @returns the candidate, or null when the feature does not explain the family\n */\nexport function continuousCandidate(\n fam: Family,\n info: FeatureInfo,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n spend: (ops: number) => void,\n): ContinuousCandidate | null {\n if (!info.numeric || info.raw || fam.styled.length < MIN_MAPPED) {\n return null;\n }\n const { values } = info.feature;\n spend(values.length);\n // the feature must be a number exactly where the family has a value\n if (values.some((v, i) => (fam.blocks[i] === 0) === (typeof v === \"number\"))) {\n return null;\n }\n for (const tolerant of [false, true]) {\n const points = rampsOf(fam, values, truth, tolerant, spend);\n if (points !== null) {\n const entries = Array.from(points.values()).reduce((sum, pts) => sum + pts.length, 0);\n return { type: \"continuous\", info, points, tolerant, cost: 50 + entries + (tolerant ? 10 : 0) };\n }\n }\n return null;\n}\n\n/**\n * The ramp of every property of the family over the feature, or null when one has none.\n * @param fam - the family\n * @param values - the feature's values\n * @param truth - the values per property\n * @param tolerant - whether a ramp may miss a value by the tool's rounding\n * @param spend - spends work from the budget\n * @returns the points per property, or null\n */\nfunction rampsOf(\n fam: Family,\n values: readonly unknown[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n tolerant: boolean,\n spend: (ops: number) => void,\n): Map<string, ContinuousPoint[]> | null {\n const points = new Map<string, ContinuousPoint[]>();\n for (const p of fam.props) {\n const pts = rampOf(fam, values, truth.get(p) ?? [], tolerant, spend);\n if (pts === null) {\n return null;\n }\n points.set(p, pts);\n }\n return points;\n}\n\n/**\n * The ramp of one property over the feature, or null when none explains it.\n * @param fam - the family\n * @param values - the feature's values\n * @param ys0 - the property's values\n * @param tolerant - whether the ramp may miss a value by the tool's rounding\n * @param spend - spends work from the budget\n * @returns the points, or null\n */\nfunction rampOf(\n fam: Family,\n values: readonly unknown[],\n ys0: readonly (StyleValue | null)[],\n tolerant: boolean,\n spend: (ops: number) => void,\n): ContinuousPoint[] | null {\n const byX = new Map<number, StyleValue>();\n let good = true;\n for (const i of fam.styled) {\n const y = ys0[i];\n const x = values[i] as number;\n const seen = byX.get(x);\n if (!interpolable(y) || (seen !== undefined && seen !== y)) {\n good = false;\n break;\n }\n byX.set(x, y);\n }\n spend(fam.styled.length);\n // a ramp needs at least 3 distinct outputs: two values over a number are a threshold, not a mapping\n if (!good || byX.size < 2 || byX.size > MAX_DISTINCT_X || new Set(byX.values()).size < 3) {\n return null;\n }\n const xs = Array.from(byX.keys()).sort((a, b) => a - b);\n const ys = xs.map((x) => byX.get(x) as StyleValue);\n const pieces = fitPieces(xs, ys, tolerant, spend);\n // every piece must explain at least 3 distinct inputs, or a few points fit anything\n return pieces === null || pieces.length * 3 > xs.length ? null : piecesToPoints(xs, ys, pieces);\n}\n","/**\n * The planner: turns a file's per-element style values into a few readable rules that reproduce them exactly. It\n * groups properties into families, explains each family by a discrete or continuous mapping on one feature, a\n * passthrough on an existing column, style classes or a copy, orders the rules, caps them at 15 per target and\n * replays them: every element whose resolved value differs from the file's goes into one sparse exceptions column\n * per property on top. One counted budget bounds the work; when it runs out the rest is copied.\n */\n\nimport { StyleBudget } from \"../budget.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport { toolDefaults } from \"../defaults.js\";\nimport { StyleNotes } from \"../notes.js\";\nimport type {\n ExtractedStyles,\n GraphStyle,\n Mapping,\n ReaderOutput,\n StyleColumn,\n StyleDialect,\n StyleFeature,\n StyleFeatures,\n StyleFingerprint,\n StyleRule,\n StyleRuleFacts,\n StyleTarget,\n StyleTool,\n StyleValue,\n StyleWorkBudget,\n} from \"../types.js\";\nimport { isStyleValue, STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { CLASS_COLUMN, styleClasses } from \"./classes.js\";\nimport { type ContinuousCandidate, continuousCandidate } from \"./continuous.js\";\nimport { type DiscreteCandidate, discreteCandidate } from \"./discrete.js\";\nimport { familiesOf, type Family } from \"./families.js\";\nimport { describeFeature, type FeatureInfo } from \"./features.js\";\nimport {\n canonicalFor,\n evalContinuous,\n isShortPredicate,\n matches,\n numberOf,\n refSource,\n resolveRules,\n within,\n} from \"./resolve.js\";\n\n/**\n * The most rules per target: the planner keeps at most 15 plus the exceptions rule.\n * @category Styles\n */\nexport const MAX_STYLE_RULES = 16;\n/** The most candidate features tested per target, fewest distinct values first. */\nconst MAX_FEATURES = 64;\n/** Lengths a tool states in its own unit; they are left out when the file's unit differs. */\nconst LENGTHS: ReadonlySet<string> = new Set([\"width\", \"height\", \"borderWidth\", \"labelSize\"]);\n\n/**\n * What the planner is given: the canonical per-element values a style reader produced, the rules the file declares,\n * and the graph they belong to.\n * @category Styles\n */\nexport interface StyleValues {\n /** The graph-io format id. */\n readonly format: string;\n /** How the file spelled its values. */\n readonly dialect?: StyleDialect | null;\n /** The program that wrote the file, whose defaults fill in what the file leaves unset; null when unknown. */\n readonly tool?: StyleTool | null;\n /** The unit of every length; defaults to pixels. */\n readonly units?: \"px\" | \"relative\";\n /** The graph's own style. */\n readonly graph?: GraphStyle;\n /** Node values, declared rules, reader columns and extra features. */\n readonly node?: ReaderOutput;\n /** Edge values, declared rules, reader columns and extra features. */\n readonly edge?: ReaderOutput;\n /** The graph the values belong to; its counts give the number of elements. */\n readonly fingerprint: StyleFingerprint;\n}\n\n/**\n * Options of `planStyles()`.\n * @category Styles\n */\nexport interface PlanOptions {\n /** Whether to add the writing tool's defaults as a rule at the bottom; defaults to true. */\n readonly toolDefaults?: boolean;\n /** The counted work budget; defaults to a fresh `StyleBudget`. */\n readonly budget?: StyleWorkBudget;\n /**\n * Where notes are collected; the reader's notes, when it used the same collector, are kept.\n * @internal\n */\n readonly notes?: StyleNotes;\n /** Data columns the reader read the values from: they are never offered as explanations of themselves. */\n readonly rawColumns?: {\n /** Node columns. */\n readonly node?: readonly string[];\n /** Edge columns. */\n readonly edge?: readonly string[];\n };\n /** Cancels the planning. */\n readonly signal?: AbortSignal;\n}\n\n/** A rule being built. */\ninterface Draft {\n id: string;\n readonly target: StyleTarget;\n readonly role: string;\n readonly origin: string;\n where: StyleRule[\"where\"];\n set?: Record<string, StyleValue>;\n map?: Record<string, Mapping>;\n facts?: StyleRuleFacts;\n readonly ext?: Readonly<Record<string, unknown>>;\n}\n\n/** The planning state of one target. */\ninterface TargetPlan {\n readonly target: StyleTarget;\n readonly n: number;\n readonly notes: StyleNotes;\n readonly budget: StyleWorkBudget;\n readonly spend: (ops: number) => void;\n readonly columns: Map<string, StyleColumn>;\n readonly ids: Set<string>;\n}\n\n/**\n * Plans a file's styles: the rules that reproduce its per-element values, with the columns they read.\n * @param values - the canonical values, the declared rules and the graph they belong to\n * @param features - the candidate explaining columns per target (`featuresOf()` of the snapshot)\n * @param options - tool defaults, the budget, the notes collector, the raw columns and a cancel signal\n * @returns the styles, exact for every element\n * @category Styles\n */\nexport function planStyles(values: StyleValues, features: StyleFeatures, options: PlanOptions = {}): ExtractedStyles {\n const notes = options.notes ?? new StyleNotes();\n const budget = options.budget ?? new StyleBudget();\n const defaults =\n options.toolDefaults !== false && values.tool !== undefined && values.tool !== null\n ? toolDefaults(values.tool)\n : null;\n const units = values.units ?? \"px\";\n const rules: StyleRule[] = [];\n const columns = { node: new Map<string, StyleColumn>(), edge: new Map<string, StyleColumn>() };\n const allFeatures = { node: [] as StyleFeature[], edge: [] as StyleFeature[] };\n for (const target of [\"node\", \"edge\"] as const) {\n const given = values[target];\n // a reader's own tool-default rules (Gephi's arrows on directed edges) go with the tool's constants\n const out =\n options.toolDefaults === false && given?.rules !== undefined\n ? { ...given, rules: given.rules.filter((r) => r.origin !== \"tool\") }\n : given;\n allFeatures[target] = [...features[target], ...(out?.features ?? [])];\n const toolSet = defaults === null ? null : toolSetOf(defaults, target, units);\n const plan: TargetPlan = {\n target,\n n: target === \"node\" ? values.fingerprint.nodes : values.fingerprint.edges,\n notes,\n budget,\n spend: (ops) => {\n budget.spend(target, ops);\n },\n columns: columns[target],\n ids: new Set(),\n };\n rules.push(\n ...planTarget(\n plan,\n out,\n allFeatures[target],\n new Set(options.rawColumns?.[target] ?? []),\n toolSet,\n options.signal,\n ),\n );\n }\n const graph = graphStyles(defaults, values.graph ?? {});\n return {\n styles: {\n version: 1,\n source: {\n format: values.format,\n dialect: values.dialect ?? null,\n tool: defaults === null ? null : defaults.tool,\n },\n units: { length: units },\n graph: graph,\n rules,\n notes: notes.list(),\n },\n columns,\n features: allFeatures,\n fingerprint: values.fingerprint,\n };\n}\n\n/**\n * The tool's default values of a target, as one defaults rule sets them; a length in other units than the file's is\n * left out.\n * @param defaults - the tool's defaults\n * @param target - nodes or edges\n * @param units - the file's length units\n * @returns the values, or null when none applies\n */\nfunction toolSetOf(\n defaults: NonNullable<ReturnType<typeof toolDefaults>>,\n target: StyleTarget,\n units: string,\n): Record<string, StyleValue> | null {\n const toolSet: Record<string, StyleValue> = {};\n for (const [p, d] of Object.entries(defaults[target]) as [string, { value: unknown } | undefined][]) {\n const fits = d !== undefined && isStyleValue(target, p, d.value);\n if (fits && !(LENGTHS.has(p) && defaults.units !== units)) {\n toolSet[p] = d.value as StyleValue;\n }\n }\n return Object.keys(toolSet).length === 0 ? null : toolSet;\n}\n\n/**\n * The graph's styles: the tool's defaults, then the file's own values over them.\n * @param defaults - the tool's defaults, or null\n * @param given - the file's graph values\n * @returns the values\n */\nfunction graphStyles(\n defaults: ReturnType<typeof toolDefaults> | null,\n given: Readonly<Record<string, unknown>>,\n): Record<string, StyleValue> {\n const graph: Record<string, StyleValue> = {};\n const own = Object.entries(defaults?.graph ?? {}) as [string, { value: unknown } | undefined][];\n for (const [p, d] of own) {\n if (d !== undefined && isStyleValue(\"graph\", p, d.value)) {\n graph[p] = d.value as StyleValue;\n }\n }\n for (const [p, v] of Object.entries(given)) {\n if (isStyleValue(\"graph\", p, v)) {\n graph[p] = v as StyleValue;\n }\n }\n return graph;\n}\n\n/**\n * A rule id not used yet in this target.\n * @param plan - the target's state\n * @param base - the wanted id\n * @returns the id, suffixed when taken\n */\nfunction uniqueId(plan: TargetPlan, base: string): string {\n let id = base;\n let k = 2;\n while (plan.ids.has(id)) {\n id = `${base}#${String(k)}`;\n k++;\n }\n plan.ids.add(id);\n return id;\n}\n\n/**\n * Sets one property's mapping of a rule, making the rule's mappings on first use.\n * @param rule - the rule, changed in place\n * @param property - the property\n * @param mapping - the mapping\n */\nfunction setMapping(rule: Draft, property: string, mapping: Mapping): void {\n rule.map ??= {};\n rule.map[property] = mapping;\n}\n\n/**\n * The type-checked per-element values of a target: a value of the wrong kind is noted and dropped.\n * @param plan - the target's state\n * @param out - the reader's output\n * @returns the values per property that have at least one value\n */\nfunction checkedTruth(plan: TargetPlan, out: ReaderOutput | undefined): Map<string, (StyleValue | null)[]> {\n const truth = new Map<string, (StyleValue | null)[]>();\n for (const [p, arr] of Object.entries<StyleColumn | undefined>(out?.values ?? {})) {\n if (arr === undefined) {\n continue;\n }\n if (!STYLE_PROPERTIES[plan.target].has(p) && !p.startsWith(\"graphty:\")) {\n plan.notes.add(STYLE_ISSUE.NOT_CARRIED, plan.target, p, { sample: p });\n continue;\n }\n const vals = checkedValues(plan, p, arr);\n plan.spend(plan.n);\n if (vals.some((v) => v !== null)) {\n truth.set(p, vals);\n }\n }\n return truth;\n}\n\n/**\n * One property's values, a value of the wrong kind noted and dropped.\n * @param plan - the target's state\n * @param p - the property\n * @param arr - the reader's values\n * @returns the values, one per element\n */\nfunction checkedValues(plan: TargetPlan, p: string, arr: StyleColumn): (StyleValue | null)[] {\n const vals = new Array<StyleValue | null>(plan.n).fill(null);\n for (let i = 0; i < plan.n && i < arr.length; i++) {\n const v = arr[i] ?? null;\n if (v !== null && isStyleValue(plan.target, p, v)) {\n vals[i] = v;\n } else if (v !== null) {\n plan.notes.add(STYLE_ISSUE.BAD_VALUE, plan.target, p, { sample: v, element: i });\n }\n }\n return vals;\n}\n\n/**\n * A copy of a property record without its undefined entries.\n * @param o - the record\n * @returns the copy, or undefined\n */\nfunction defined<T>(o: Readonly<Record<string, T | undefined>> | undefined): Record<string, T> | undefined {\n if (o === undefined) {\n return undefined;\n }\n const out: Record<string, T> = {};\n for (const [k, v] of Object.entries(o)) {\n if (v !== undefined) {\n out[k] = v;\n }\n }\n return out;\n}\n\n/**\n * The properties a rule writes.\n * @param r - the rule\n * @returns the property names\n */\nfunction writes(r: Draft | StyleRule): string[] {\n return [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})];\n}\n\n/**\n * The declared rules, with every predicate longer than a short one evaluated into a membership style column and\n * runs of rules that set values on every element merged into one defaults rule.\n * @param plan - the target's state\n * @param declared - the reader's rules\n * @param features - the features, for evaluating predicates over data columns\n * @returns the rules to keep\n */\nfunction prepareDeclared(plan: TargetPlan, declared: readonly StyleRule[], features: readonly StyleFeature[]): Draft[] {\n const src = refSource(plan.target, plan.n, plan.columns, features);\n const drafts: Draft[] = [];\n for (const r of declared.filter((x) => x.target === plan.target)) {\n const d: Draft = { ...r, set: defined(r.set), map: defined(r.map) };\n if (d.set === undefined) {\n delete d.set;\n }\n if (d.map === undefined) {\n delete d.map;\n }\n if (!isShortPredicate(r.where)) {\n asMembership(plan, d, r, src);\n }\n drafts.push(d);\n }\n const merged = mergedDefaults(plan.target, drafts);\n for (const d of merged) {\n d.id = uniqueId(plan, d.id);\n }\n return merged;\n}\n\n/**\n * Evaluates a long predicate into a membership style column the rule selects instead.\n * @param plan - the target's state\n * @param d - the rule's draft, changed in place\n * @param r - the declared rule\n * @param src - the reference source\n */\nfunction asMembership(plan: TargetPlan, d: Draft, r: StyleRule, src: ReturnType<typeof refSource>): void {\n let member = 1;\n while (plan.columns.has(`member.${String(member)}`)) {\n member++;\n }\n const key = `member.${String(member)}`;\n const col = new Array<StyleValue | null>(plan.n).fill(null);\n let count = 0;\n for (let i = 0; i < plan.n; i++) {\n if (matches(r.where, src, i)) {\n col[i] = true;\n count++;\n }\n }\n plan.spend(plan.n * 8);\n plan.columns.set(key, col);\n d.where = { has: { style: key } };\n d.facts = { ...r.facts, elements: count, reason: r.facts?.reason ?? \"SELECTOR\" };\n plan.notes.add(STYLE_ISSUE.SELECTOR_AS_COLUMN, plan.target, r.id, { count });\n}\n\n/**\n * Consecutive declared rules that select everything and only set values, as one defaults rule (later wins).\n * @param target - nodes or edges\n * @param drafts - the declared rules\n * @returns the rules, runs merged\n */\nfunction mergedDefaults(target: StyleTarget, drafts: readonly Draft[]): Draft[] {\n const merged: Draft[] = [];\n const plain = (x: Draft): boolean => \"all\" in x.where && x.set !== undefined && x.map === undefined;\n let i = 0;\n while (i < drafts.length) {\n let j = i + 1;\n while (plain(drafts[i]) && j < drafts.length && plain(drafts[j])) {\n j++;\n }\n if (j - i >= 2) {\n merged.push({\n id: drafts[i].id,\n target,\n role: \"defaults\",\n origin: \"declared\",\n where: { all: true },\n set: Object.assign({}, ...drafts.slice(i, j).map((x) => x.set)) as Record<string, StyleValue>,\n });\n } else {\n merged.push(drafts[i]);\n }\n i = j;\n }\n return merged;\n}\n\n/** A passthrough on existing columns that explains a family. */\ninterface PassCandidate {\n readonly type: \"passdata\";\n readonly cols: ReadonlyMap<string, FeatureInfo>;\n readonly raw: boolean;\n readonly cost: number;\n}\n\n/** The floor: classes or a copy. */\ninterface OpaqueCandidate {\n readonly type: \"opaque\";\n readonly cost: number;\n}\n\ntype Candidate = DiscreteCandidate | ContinuousCandidate | PassCandidate | OpaqueCandidate;\nconst ORDER = [\"passdata\", \"discrete\", \"continuous\", \"opaque\"];\n\n/**\n * Tests a passthrough on existing data columns: one column per property whose canonical value equals the style on\n * every element.\n * @param plan - the target's state\n * @param fam - the family\n * @param truth - the values per property\n * @param infos - the features\n * @returns the candidate, or null\n */\nfunction passCandidate(\n plan: TargetPlan,\n fam: Family,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n infos: readonly FeatureInfo[],\n): PassCandidate | null {\n const cols = new Map<string, FeatureInfo>();\n for (const p of fam.props) {\n const canon = canonicalFor(plan.target, p);\n const isColor = STYLE_PROPERTIES[plan.target].get(p) === \"color\";\n const t = truth.get(p) ?? [];\n const hit = infos.find((f) => {\n if (!(\"data\" in f.feature.ref)) {\n return false;\n }\n plan.spend(plan.n);\n for (let i = 0; i < plan.n; i++) {\n const raw = f.feature.values[i];\n // a color column is reused only when it already holds \"#rrggbb\": other spellings read differently\n if (isColor && raw !== null && !(typeof raw === \"string\" && /^#[0-9a-fA-F]{6}$/.test(raw))) {\n return false;\n }\n if ((raw === null ? null : canon(raw)) !== t[i]) {\n return false;\n }\n }\n return true;\n });\n if (hit === undefined) {\n return null;\n }\n cols.set(p, hit);\n }\n const raw = Array.from(cols.values()).some((f) => f.raw);\n // a passthrough on the raw style column itself recovers nothing: nearly as opaque as a copy\n return { type: \"passdata\", cols, raw, cost: raw ? 240 : 50 };\n}\n\n/**\n * Plans one target.\n * @param plan - the target's state\n * @param out - the reader's output\n * @param features - the candidate features\n * @param rawNames - the data columns the values were read from\n * @param toolSet - the tool's default values, or null\n * @param signal - cancels the planning\n * @returns the target's rules, bottom to top\n */\nfunction planTarget(\n plan: TargetPlan,\n out: ReaderOutput | undefined,\n features: readonly StyleFeature[],\n rawNames: ReadonlySet<string>,\n toolSet: Record<string, StyleValue> | null,\n signal: AbortSignal | undefined,\n): StyleRule[] {\n const { target, n } = plan;\n for (const [k, v] of out?.columns ?? []) {\n plan.columns.set(k, v);\n }\n const truth = checkedTruth(plan, out);\n const toolRule: Draft[] =\n toolSet === null\n ? []\n : [\n {\n id: uniqueId(plan, `${target}.tool`),\n target,\n role: \"defaults\",\n origin: \"tool\",\n where: { all: true },\n set: toolSet,\n },\n ];\n const declared = prepareDeclared(plan, out?.rules ?? [], features);\n const declaredProps = new Set(declared.flatMap(writes));\n\n const { defaults, rest } = splitDefaults(n, truth, declaredProps);\n plan.spend(n * truth.size);\n const inferred: Draft[] = [];\n if (Object.keys(defaults).length > 0) {\n inferred.push({\n id: uniqueId(plan, `${target}.defaults`),\n target,\n role: \"defaults\",\n origin: \"inferred\",\n where: { all: true },\n set: defaults,\n });\n }\n\n const families = familiesOf(rest);\n plan.spend(n * rest.length);\n const infos = features\n .map((f) => describeFeature(f, \"data\" in f.ref && rawNames.has(f.ref.data)))\n .sort((a, b) => a.distinct - b.distinct);\n plan.spend(n * features.length);\n const testable = infos.filter((f) => f.categorical || f.numeric).slice(0, MAX_FEATURES);\n\n const groups: Draft[] = [];\n const mappings = new Map<string, Draft>();\n const passData: Draft = {\n id: `${target}.passthrough`,\n target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n };\n const passRaw: Draft = {\n id: `${target}.passthrough.raw`,\n target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n facts: { reason: \"NO_EXPLANATION\" },\n };\n const copy: Draft = {\n id: `${target}.copy`,\n target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n facts: { reason: \"NO_EXPLANATION\" },\n };\n const opaque: { fam: Family; raw: ReadonlyMap<string, FeatureInfo> | null }[] = [];\n const tolerated = new Map<string, Set<number>>();\n let budgetHit = 0;\n\n const st: Inference = { groups, mappings, passData, passRaw, copy, opaque, tolerated };\n for (const fam of families) {\n signal?.throwIfAborted();\n if (plan.budget.exhausted(target)) {\n budgetHit++;\n opaque.push({ fam, raw: null });\n continue;\n }\n applyChoice(plan, st, fam, chooseCandidate(plan, fam, testable, infos, truth), truth);\n }\n if (budgetHit > 0) {\n plan.notes.add(STYLE_ISSUE.BUDGET, target, null, { count: budgetHit });\n }\n poolOpaque(plan, st, budgetHit, truth);\n\n const nonEmpty = (r: Draft): boolean => Object.keys(r.map ?? {}).length > 0;\n const sortedMappings = Array.from(mappings.values()).sort((a, b) => compareText(a.id, b.id));\n const drafts: Draft[] = [\n ...toolRule,\n ...declared,\n ...inferred,\n ...groups,\n ...sortedMappings,\n ...[passData, passRaw, copy].filter(nonEmpty),\n ];\n for (const d of drafts.slice(toolRule.length + declared.length + inferred.length)) {\n d.id = uniqueId(plan, d.id);\n }\n\n const src = refSource(target, n, plan.columns, features);\n enforceCap(plan, drafts, truth, src);\n const exceptions = replay(plan, drafts, truth, toolSet, tolerated, src);\n if (exceptions !== null) {\n drafts.push(exceptions);\n }\n return drafts.map(finish);\n}\n\n/**\n * The inferred defaults: each property non-null and equal on every element; the others are left to explain. A\n * property a declared rule writes is the declared rule's.\n * @param n - the element count\n * @param truth - the values per property\n * @param declaredProps - the properties the declared rules write\n * @returns the defaults, and the properties left\n */\nfunction splitDefaults(\n n: number,\n truth: ReadonlyMap<string, (StyleValue | null)[]>,\n declaredProps: ReadonlySet<string>,\n): { defaults: Record<string, StyleValue>; rest: [string, (StyleValue | null)[]][] } {\n const defaults: Record<string, StyleValue> = {};\n const rest: [string, (StyleValue | null)[]][] = [];\n for (const [p, a] of truth) {\n const first = a[0];\n if (declaredProps.has(p)) {\n continue;\n }\n if (n > 0 && first !== null && a.every((v) => v === first)) {\n defaults[p] = first;\n } else {\n rest.push([p, a]);\n }\n }\n return { defaults, rest };\n}\n\n/** What the inference of one target collects. */\ninterface Inference {\n readonly groups: Draft[];\n readonly mappings: Map<string, Draft>;\n readonly passData: Draft;\n readonly passRaw: Draft;\n readonly copy: Draft;\n readonly opaque: { fam: Family; raw: ReadonlyMap<string, FeatureInfo> | null }[];\n readonly tolerated: Map<string, Set<number>>;\n}\n\n/**\n * The cheapest explanation of one family: a discrete or continuous mapping over a feature, a passthrough over existing\n * columns, or the opaque floor.\n * @param plan - the target's state\n * @param fam - the family\n * @param testable - the features worth testing\n * @param infos - every feature\n * @param truth - the values per property\n * @returns the chosen candidate\n */\nfunction chooseCandidate(\n plan: TargetPlan,\n fam: Family,\n testable: readonly FeatureInfo[],\n infos: readonly FeatureInfo[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): Candidate {\n const { target, n } = plan;\n const cands: Candidate[] = [];\n // text is per element by nature: a label is never explained by another column's table\n const textual = fam.props.some((p) => STYLE_PROPERTIES[target].get(p) === \"text\");\n if (!textual) {\n for (const f of testable) {\n const d = discreteCandidate(fam, f, n, plan.spend);\n if (d !== null) {\n cands.push(d);\n }\n const c = continuousCandidate(fam, f, truth, plan.spend);\n if (c !== null) {\n cands.push(c);\n }\n if (plan.budget.exhausted(target)) {\n break;\n }\n }\n }\n const pass = passCandidate(plan, fam, truth, infos);\n if (pass !== null) {\n cands.push(pass);\n }\n cands.push({ type: \"opaque\", cost: 250 });\n cands.sort((a, b) => a.cost - b.cost || ORDER.indexOf(a.type) - ORDER.indexOf(b.type));\n return cands[0];\n}\n\n/**\n * Records a family's chosen explanation in the target's inference.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param fam - the family\n * @param c - the chosen candidate\n * @param truth - the values per property\n */\nfunction applyChoice(\n plan: TargetPlan,\n st: Inference,\n fam: Family,\n c: Candidate,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n if (c.type === \"discrete\") {\n applyDiscrete(plan, st, fam, c, truth);\n } else if (c.type === \"continuous\") {\n applyContinuous(plan, st, fam, c, truth);\n } else if (c.type === \"passdata\" && !c.raw) {\n for (const p of fam.props) {\n setMapping(st.passData, p, { kind: \"passthrough\", by: (c.cols.get(p) as FeatureInfo).feature.ref });\n }\n } else {\n // the raw style column recovers nothing: the family joins the opaque pool, where it may become part\n // of a style class, and otherwise reads the raw column\n st.opaque.push({ fam, raw: c.type === \"passdata\" ? c.cols : null });\n }\n}\n\n/**\n * The mapping rule of a feature, made on first use; one rule holds every family the feature explains.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param key - the rule's key among the mappings\n * @param id - its id\n * @returns the rule\n */\nfunction mappingRule(plan: TargetPlan, st: Inference, key: string, id: string): Draft {\n let r = st.mappings.get(key);\n if (r === undefined) {\n r = { id, target: plan.target, role: \"mapping\", origin: \"inferred\", where: { all: true }, map: {} };\n st.mappings.set(key, r);\n }\n return r;\n}\n\n/**\n * Makes a feature computed for the inference (a style column) a column of the styles.\n * @param plan - the target's state\n * @param info - the feature\n */\nfunction materialize(plan: TargetPlan, info: FeatureInfo): void {\n if (\"style\" in info.feature.ref) {\n plan.columns.set(info.feature.ref.style, info.feature.values);\n }\n}\n\n/**\n * Records a discrete mapping: one table per property, and a group for the elements the feature gives no value.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param fam - the family\n * @param c - the candidate\n * @param truth - the values per property\n */\nfunction applyDiscrete(\n plan: TargetPlan,\n st: Inference,\n fam: Family,\n c: DiscreteCandidate,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n const { target } = plan;\n materialize(plan, c.info);\n const rule = mappingRule(plan, st, `discrete|${c.info.name}`, `${target}.by.${c.info.name}`);\n // the first element of each block stands for the block\n const rep = new Map<number, number>();\n for (const i of fam.styled) {\n if (!rep.has(fam.blocks[i])) {\n rep.set(fam.blocks[i], i);\n }\n }\n for (const p of fam.props) {\n const t = truth.get(p) ?? [];\n const table = Array.from(c.table.values(), ({ raw, block }): [string | number | boolean, StyleValue] => [\n raw,\n t[rep.get(block) ?? -1] as StyleValue,\n ]);\n setMapping(rule, p, { kind: \"discrete\", by: c.info.feature.ref, table });\n }\n if (c.bucket === null) {\n return;\n }\n const set: Record<string, StyleValue> = {};\n for (const p of fam.props) {\n set[p] = (truth.get(p) ?? [])[rep.get(c.bucket) ?? -1] as StyleValue;\n }\n st.groups.push({\n id: `${target}.missing.${c.info.name}`,\n target,\n role: \"group\",\n origin: \"inferred\",\n where: { not: { has: c.info.feature.ref } },\n set,\n });\n}\n\n/**\n * Records a continuous mapping: one ramp per property; a ramp that matches only within the tool's rounding tolerates\n * those elements, noted.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param fam - the family\n * @param c - the candidate\n * @param truth - the values per property\n */\nfunction applyContinuous(\n plan: TargetPlan,\n st: Inference,\n fam: Family,\n c: ContinuousCandidate,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n const { target } = plan;\n materialize(plan, c.info);\n const rule = mappingRule(plan, st, `continuous|${c.info.name}`, `${target}.ramp.${c.info.name}`);\n for (const p of fam.props) {\n const points = c.points.get(p) ?? [];\n setMapping(rule, p, { kind: \"continuous\", by: c.info.feature.ref, points });\n if (!c.tolerant) {\n continue;\n }\n const t = truth.get(p) ?? [];\n const set = new Set<number>();\n for (const i of fam.styled) {\n if (evalContinuous(points, numberOf(c.info.feature.values[i])) !== t[i]) {\n set.add(i);\n plan.notes.add(STYLE_ISSUE.RAMP_ROUNDED, target, p, { element: i, sample: t[i] });\n }\n }\n st.tolerated.set(p, set);\n }\n}\n\n/**\n * The opaque pool: style classes when the file uses few combinations, else one copy per property.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param budgetHit - how many families the budget sent to the pool\n * @param truth - the values per property\n */\nfunction poolOpaque(\n plan: TargetPlan,\n st: Inference,\n budgetHit: number,\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n): void {\n const { target, n } = plan;\n if (st.opaque.length === 0) {\n return;\n }\n const props = st.opaque.flatMap((o) => o.fam.props);\n const classes = budgetHit > 0 ? null : styleClasses(target, props, truth, n, plan.spend);\n const classed = new Set(classes?.classed ?? []);\n if (classes !== null) {\n addClassRules(plan, st, classes);\n }\n let distinct = 0;\n for (const { fam, raw } of st.opaque) {\n for (const p of fam.props.filter((x) => !classed.has(x))) {\n const viaRaw = raw?.get(p);\n if (viaRaw === undefined) {\n distinct = Math.max(distinct, copyProperty(plan, st.copy, p, truth.get(p) ?? []));\n } else {\n setMapping(st.passRaw, p, { kind: \"passthrough\", by: viaRaw.feature.ref });\n }\n }\n }\n st.copy.facts = { reason: budgetHit > 0 ? \"BUDGET\" : \"NO_EXPLANATION\", distinctValues: distinct };\n}\n\n/**\n * Adds the style classes' column and rules.\n * @param plan - the target's state\n * @param st - the inference so far; changed in place\n * @param classes - the style classes\n */\nfunction addClassRules(plan: TargetPlan, st: Inference, classes: NonNullable<ReturnType<typeof styleClasses>>): void {\n plan.columns.set(CLASS_COLUMN, classes.column);\n for (const r of classes.rules) {\n if (r.role === \"group\") {\n st.groups.push({ ...r, id: r.id, set: { ...r.set } } as Draft);\n } else {\n st.mappings.set(r.id, { ...r, map: { ...r.map } } as Draft);\n }\n }\n}\n\n/**\n * Copies a property's values into a style column the copy rule passes through.\n * @param plan - the target's state\n * @param copy - the copy rule, changed in place\n * @param p - the property\n * @param t - its values\n * @returns how many distinct values it holds\n */\nfunction copyProperty(plan: TargetPlan, copy: Draft, p: string, t: readonly (StyleValue | null)[]): number {\n plan.columns.set(`copy.${p}`, t.slice());\n setMapping(copy, p, { kind: \"passthrough\", by: { style: `copy.${p}` } });\n plan.spend(plan.n);\n return new Set(t.filter((v) => v !== null)).size;\n}\n\n/**\n * The rule as a plain JSON-stable object.\n * @param d - the draft\n * @returns the rule\n */\nfunction finish(d: Draft): StyleRule {\n const r: Record<string, unknown> = { id: d.id, target: d.target, role: d.role, origin: d.origin, where: d.where };\n if (d.set !== undefined && Object.keys(d.set).length > 0) {\n r.set = d.set;\n }\n if (d.map !== undefined && Object.keys(d.map).length > 0) {\n r.map = d.map;\n }\n if (d.facts !== undefined) {\n r.facts = Object.fromEntries(Object.entries(d.facts).filter(([, v]) => v !== undefined));\n }\n if (d.ext !== undefined) {\n r.ext = d.ext;\n }\n return r as unknown as StyleRule;\n}\n\n/**\n * Compares two texts by code unit, the same everywhere.\n * @param a - one text\n * @param b - the other\n * @returns negative, zero or positive\n */\nfunction compareText(a: string, b: string): number {\n if (a === b) {\n return 0;\n }\n return a < b ? -1 : 1;\n}\n\n/**\n * The entries a person would edit in a rule.\n * @param r - the rule\n * @returns its size\n */\nfunction ruleSize(r: Draft): number {\n let size = Object.keys(r.set ?? {}).length;\n for (const m of Object.values(r.map ?? {})) {\n if (m.kind === \"discrete\") {\n size += m.table.length;\n } else if (m.kind === \"continuous\") {\n size += m.points.length;\n } else {\n size += 1;\n }\n }\n return size;\n}\n\n/** The order in which rules are folded into the copy: inferred first, the tool's defaults last. */\nconst FOLD_ORDER: Readonly<Record<string, number>> = { inferred: 0, declared: 1, tool: 2 };\n\n/**\n * Keeps at most 15 rules (the exceptions rule makes 16) by moving the least readable rules into the copy, with each\n * property's values as they resolved: exact, never a silent delete.\n * @param plan - the target's state\n * @param drafts - the rules, bottom to top; changed in place\n * @param truth - the file's values per property\n * @param src - the reference source\n */\nfunction enforceCap(\n plan: TargetPlan,\n drafts: Draft[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n src: ReturnType<typeof refSource>,\n): void {\n const cap = MAX_STYLE_RULES - 1;\n const copyId = `${plan.target}.copy`;\n let folded = 0;\n while (drafts.length > cap) {\n const cands = drafts.filter((r) => r.id !== copyId);\n if (cands.length === 0) {\n break;\n }\n cands.sort((a, b) => {\n const pa = a.role === \"passthrough\" ? 1 : 0;\n const pb = b.role === \"passthrough\" ? 1 : 0;\n return (\n pa - pb ||\n (FOLD_ORDER[a.origin] ?? 1) - (FOLD_ORDER[b.origin] ?? 1) ||\n ruleSize(b) - ruleSize(a) ||\n drafts.indexOf(b) - drafts.indexOf(a)\n );\n });\n const victim = cands[0];\n const before = drafts.map(finish);\n drafts.splice(drafts.indexOf(victim), 1);\n let copy = drafts.find((r) => r.id === copyId);\n if (copy === undefined) {\n copy = {\n id: copyId,\n target: plan.target,\n role: \"passthrough\",\n origin: \"inferred\",\n where: { all: true },\n map: {},\n };\n plan.ids.add(copyId);\n } else {\n drafts.splice(drafts.indexOf(copy), 1);\n }\n for (const p of new Set(writes(victim))) {\n // the property's values as the whole stack resolved them, supplied on top for every element\n const t = truth.get(p);\n const vals = t === undefined ? resolveRules(before, plan.target, p, src, plan.budget) : t.slice();\n plan.columns.set(`copy.${p}`, vals);\n setMapping(copy, p, { kind: \"passthrough\", by: { style: `copy.${p}` } });\n }\n copy.facts = { ...copy.facts, reason: \"LAYER_CAP\" };\n drafts.push(copy);\n folded++;\n }\n if (folded > 0) {\n plan.notes.add(STYLE_ISSUE.LAYER_CAP, plan.target, null, { count: folded });\n }\n}\n\n/**\n * The elements whose resolved value is not the one wanted, with the wanted value; none where nothing is wanted, and\n * none where a ramp is tolerated within the tool's rounding.\n * @param n - the element count\n * @param got - the resolved values\n * @param want - the value wanted for an element, or null for none\n * @param tolerated - the elements a ramp matches only within the tool's rounding\n * @returns the wanted values where they differ, or null when none does\n */\nfunction differences(\n n: number,\n got: readonly (StyleValue | null)[],\n want: (i: number) => StyleValue | null,\n tolerated: ReadonlySet<number> | undefined,\n): (StyleValue | null)[] | null {\n let col: (StyleValue | null)[] | null = null;\n for (let i = 0; i < n; i++) {\n const w = want(i);\n const differs = w !== null && got[i] !== w && !(tolerated?.has(i) === true && within(got[i], w));\n if (differs) {\n col ??= new Array<StyleValue | null>(n).fill(null);\n col[i] = w;\n }\n }\n return col;\n}\n\n/**\n * The replay: resolves every property the file gives and compares it with the file's value, or the tool's default\n * where the file gives none. Each difference goes into one sparse exceptions column per property.\n * @param plan - the target's state\n * @param drafts - the rules, bottom to top\n * @param truth - the file's values per property\n * @param toolSet - the tool's default values, or null\n * @param tolerated - per property, the elements a ramp matches only within the tool's rounding\n * @param src - the reference source\n * @returns the exceptions rule, or null when nothing differs\n */\nfunction replay(\n plan: TargetPlan,\n drafts: readonly Draft[],\n truth: ReadonlyMap<string, readonly (StyleValue | null)[]>,\n toolSet: Record<string, StyleValue> | null,\n tolerated: ReadonlyMap<string, ReadonlySet<number>>,\n src: ReturnType<typeof refSource>,\n): Draft | null {\n const rules = drafts.map(finish);\n // where the file gives no value, the tool draws its default: its constants, and where a reader adds tool rules\n // of its own (Graphviz's target arrow on directed edges), what those rules give over the constants\n const toolRules = rules.filter((r) => r.origin === \"tool\");\n const ownToolRules = toolRules.length > (toolSet === null ? 0 : 1);\n const map: Record<string, Mapping> = {};\n for (const [p, t] of truth) {\n const got = resolveRules(rules, plan.target, p, src, plan.budget);\n const perElement = ownToolRules ? resolveRules(toolRules, plan.target, p, src, plan.budget) : null;\n const constant = toolSet?.[p] ?? null;\n const want = (i: number): StyleValue | null => t[i] ?? (perElement === null ? constant : perElement[i]);\n const col = differences(plan.n, got, want, tolerated.get(p));\n if (col !== null) {\n plan.columns.set(`exceptions.${p}`, col);\n map[p] = { kind: \"passthrough\", by: { style: `exceptions.${p}` } };\n }\n }\n if (Object.keys(map).length === 0) {\n return null;\n }\n return {\n id: uniqueId(plan, `${plan.target}.exceptions`),\n target: plan.target,\n role: \"exceptions\",\n origin: \"inferred\",\n where: { all: true },\n map,\n };\n}\n","/**\n * Reading a file's styles after an import: the importer's own `styles()` (the simple path, canonicalized and planned\n * here, or the advanced path), the generic reader of the style roles (`color`, `size`, `shape`, `thickness`,\n * `hidden`) for an importer without one, and the `graphty.styles` block when a file graphty wrote carries it as a\n * graph attribute.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { keptForStyles } from \"../../common/report.js\";\nimport type { GraphImporter, ImportReport } from \"../../types.js\";\nimport { StyleBudget } from \"../budget.js\";\nimport { canonColor, colorOpacity } from \"../canon/color.js\";\nimport { canonEnum, type StyleEnumKind } from \"../canon/enums.js\";\nimport { canonBoolean, canonNumber, canonOpacity, DOT_POINTS_PER_INCH, styleLengthUnit } from \"../canon/number.js\";\nimport type { CanonSite } from \"../canon/site.js\";\nimport { canonText } from \"../canon/text.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport { StyleNotes } from \"../notes.js\";\nimport { featuresOf, styleFingerprint } from \"../plan/features.js\";\nimport { planStyles } from \"../plan/plan.js\";\nimport { plainCell } from \"../plan/resolve.js\";\nimport type {\n ExtractedStyles,\n GraphStyle,\n ImporterStyles,\n ReaderOutput,\n StyleColumn,\n StyleDialect,\n StyleNote,\n StyleProperty,\n StyleTarget,\n StyleTool,\n StyleValue,\n} from \"../types.js\";\nimport { STYLE_PROPERTIES } from \"../vocabulary.js\";\nimport { blockStyles, parseStyleBlock, STYLE_BLOCK_NAME } from \"./block.js\";\n\n/**\n * The `styles` option of `importGraph()` given as an object.\n * @category Styles\n */\nexport interface StyleImportOptions {\n /**\n * Whether a property the file leaves to its writing program's default gets that program's default (Cytoscape's,\n * Graphviz's, Gephi's ...), so the graph looks as it does there. Defaults to true.\n */\n readonly toolDefaults?: boolean;\n}\n\n/**\n * Options of `extractStyles()`.\n * @category Styles\n */\nexport interface ExtractStylesOptions extends StyleImportOptions {\n /** Cancels the extraction. */\n readonly signal?: AbortSignal | null;\n /**\n * The counted work budget to spend (and read back after: `budget.used(\"node\")`); a new one of\n * `STYLE_WORK_BUDGET` operations per target when absent.\n * @internal\n */\n readonly budget?: StyleBudget;\n}\n\nconst TARGETS: readonly StyleTarget[] = [\"node\", \"edge\"];\nconst ENUM_KINDS: ReadonlySet<string> = new Set([\"shape\", \"borderStyle\", \"lineStyle\", \"arrow\", \"weight\", \"position\"]);\n\n/** What the readers here produce before planning: canonical values and the data columns they came from. */\ninterface StyleTruth {\n readonly dialect: StyleDialect | null;\n readonly tool: StyleTool | null;\n readonly units: \"px\" | \"relative\";\n readonly graph: GraphStyle;\n readonly node: ReaderOutput;\n readonly edge: ReaderOutput;\n readonly raw: { readonly node: readonly string[]; readonly edge: readonly string[] };\n readonly notes: readonly StyleNote[];\n /** A `graphty.styles` block the importer found outside the graph attributes, or null. */\n readonly block?: string | null;\n /** Whether the format writes an opacity as its color's alpha (see `ImporterStyles`). */\n readonly opacityInColor?: boolean;\n}\n\n/**\n * Reads the styles of a file after its import: the reading importer's own `styles()` (with what its `import()` kept\n * for it), or the columns whose role is a style role when it has none; a `graphty.styles` block carried as a graph\n * attribute gives the rules, with the importer's values as the truth. Called by `importGraph()` when styles are\n * requested; a caller that drives an importer itself (into its own builder) calls it with the report `import()`\n * returned.\n * @param importer - the importer that read the file\n * @param snapshot - the graph it built\n * @param report - the report its `import()` returned\n * @param options - tool defaults and a cancel signal\n * @returns the styles, or null when the file has none\n * @category Styles\n */\nexport function extractStyles(\n importer: GraphImporter,\n snapshot: GraphSnapshot,\n report: ImportReport,\n options: ExtractStylesOptions = {},\n): ExtractedStyles | null {\n const signal = options.signal ?? undefined;\n const notes = new StyleNotes();\n const budget = options.budget ?? new StyleBudget();\n const canonical = readStyleValues(importer, snapshot, report, { notes, budget, signal });\n const fingerprint = styleFingerprint(snapshot);\n const blockText = canonical?.block ?? graphValue(snapshot, STYLE_BLOCK_NAME);\n if (blockText !== undefined) {\n const parsed = parseStyleBlock(blockText, fingerprint);\n if (parsed.ok) {\n const truth = canonical === null ? {} : { node: canonical.node.values, edge: canonical.edge.values };\n const fromBlock = blockStyles(\n parsed.block,\n snapshot,\n importer.format,\n truth,\n canonical?.notes ?? [],\n canonical?.tool ?? null,\n canonical?.opacityInColor === true,\n );\n if (fromBlock !== null) {\n return fromBlock;\n }\n notes.add(STYLE_ISSUE.BLOCK_IGNORED, null, null, { sample: \"INVALID\" });\n } else {\n notes.add(STYLE_ISSUE.BLOCK_IGNORED, null, null, { sample: parsed.reason });\n }\n }\n if (canonical === null) {\n const list = notes.list();\n return list.length === 0 ? null : emptyStyles(importer.format, list, snapshot, fingerprint);\n }\n const raw = { node: new Set(canonical.raw.node), edge: new Set(canonical.raw.edge) };\n const features = {\n node: featuresOf(snapshot, \"node\").filter((f) => !(\"data\" in f.ref && raw.node.has(f.ref.data))),\n edge: featuresOf(snapshot, \"edge\").filter((f) => !(\"data\" in f.ref && raw.edge.has(f.ref.data))),\n };\n const planned = planStyles(\n {\n format: importer.format,\n dialect: canonical.dialect,\n tool: canonical.tool,\n units: canonical.units,\n graph: canonical.graph,\n node: canonical.node,\n edge: canonical.edge,\n fingerprint,\n },\n features,\n {\n toolDefaults: options.toolDefaults,\n budget,\n notes,\n rawColumns: { node: canonical.raw.node, edge: canonical.raw.edge },\n signal,\n },\n );\n if (canonical.notes.length === 0) {\n return planned;\n }\n return { ...planned, styles: { ...planned.styles, notes: [...canonical.notes, ...planned.styles.notes] } };\n}\n\n/**\n * What a file's styles are before planning: each element's canonical value per property, as the importer's own\n * `styles()` gives them (the simple path canonicalized) or, for an importer without one, as the generic reader reads\n * the columns with a style role. The truth the planned rules must reproduce; not part of the published entry.\n * @param importer - the importer that read the file\n * @param snapshot - the graph it built\n * @param report - the report its `import()` returned\n * @param context - where problems are noted, the work budget and a cancel signal\n * @param context.notes - where problems are noted\n * @param context.budget - the work budget\n * @param context.signal - cancels the work\n * @returns the canonical values, or null when the file has no styles\n */\nexport function readStyleValues(\n importer: GraphImporter,\n snapshot: GraphSnapshot,\n report: ImportReport,\n context: { readonly notes: StyleNotes; readonly budget: StyleBudget; readonly signal?: AbortSignal | undefined },\n): StyleTruth | null {\n const { notes, budget, signal } = context;\n signal?.throwIfAborted();\n let canonical: StyleTruth | null;\n if (importer.styles === undefined) {\n canonical = roleStyles(snapshot, importer.format, notes, budget);\n } else {\n const got = importer.styles(snapshot, { signal, budget, kept: keptForStyles(report) });\n canonical = got === null ? null : canonicalOf(got, snapshot, notes, budget, signal);\n }\n signal?.throwIfAborted();\n return canonical === null ? null : withPairedHalves(canonical, snapshot);\n}\n\n/**\n * The values with the second half of each undirected edge of a directed graph given its first half's value: the file\n * holds the edge once, its program draws it once, and the import read the element's values onto the first half.\n * @param truth - the values read\n * @param snapshot - the graph\n * @returns the values\n */\nfunction withPairedHalves(truth: StyleTruth, snapshot: GraphSnapshot): StyleTruth {\n const pair = snapshot.edges.byRole(\"pair\");\n if (pair === null) {\n return truth;\n }\n const values: Partial<Record<StyleProperty, StyleColumn>> = {};\n for (const [property, col] of Object.entries(truth.edge.values) as [StyleProperty, StyleColumn | undefined][]) {\n if (col === undefined) {\n continue;\n }\n const out = [...col];\n for (let e = 0; e < out.length; e++) {\n const first = pair.isSet(e) ? (pair.value(e) as number) : e;\n if (first < e) {\n out[e] = col[first] ?? null;\n }\n }\n values[property] = out;\n }\n return { ...truth, edge: { ...truth.edge, values } };\n}\n\n/**\n * A graph attribute's value, or undefined.\n * @param snapshot - the graph\n * @param name - the attribute\n * @returns its value\n */\nfunction graphValue(snapshot: GraphSnapshot, name: string): unknown {\n return snapshot.graph.has(name) ? plainCell(snapshot.graph.value(name, 0)) : undefined;\n}\n\n/**\n * Styles holding nothing but notes.\n * @param format - the format\n * @param notes - the notes\n * @param snapshot - the graph\n * @param fingerprint - its fingerprint\n * @returns the styles\n */\nfunction emptyStyles(\n format: string,\n notes: readonly StyleNote[],\n snapshot: GraphSnapshot,\n fingerprint: ExtractedStyles[\"fingerprint\"],\n): ExtractedStyles {\n return {\n styles: {\n version: 1,\n source: { format, dialect: null, tool: null },\n units: { length: \"px\" },\n graph: {},\n rules: [],\n notes,\n },\n columns: { node: new Map(), edge: new Map() },\n features: { node: featuresOf(snapshot, \"node\"), edge: featuresOf(snapshot, \"edge\") },\n fingerprint,\n };\n}\n\n/**\n * An importer's styles as canonical values: the advanced path as it is, the simple path read and canonicalized.\n * @param got - what the importer's `styles()` returned\n * @param snapshot - the graph\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @param signal - cancels the work\n * @returns the canonical values\n */\nfunction canonicalOf(\n got: ImporterStyles,\n snapshot: GraphSnapshot,\n notes: StyleNotes,\n budget: StyleBudget,\n signal: AbortSignal | undefined,\n): StyleTruth {\n if (\"canonical\" in got) {\n return {\n dialect: got.dialect ?? null,\n tool: got.tool ?? null,\n units: got.units ?? \"px\",\n graph: got.graph ?? {},\n node: got.node ?? { values: {} },\n edge: got.edge ?? { values: {} },\n raw: { node: got.readFrom?.node ?? [], edge: got.readFrom?.edge ?? [] },\n notes: got.notes ?? [],\n block: got.block ?? null,\n opacityInColor: got.opacityInColor === true,\n };\n }\n const { dialect } = got;\n const raw = { node: [] as string[], edge: [] as string[] };\n const out = { node: { values: {} } as ReaderOutput, edge: { values: {} } as ReaderOutput };\n for (const target of TARGETS) {\n const given = got[target];\n if (given === undefined) {\n continue;\n }\n const columns = new Map<string, readonly unknown[]>();\n for (const [property, source] of Object.entries(given)) {\n signal?.throwIfAborted();\n const values = rawValues(snapshot, target, property, source, notes, raw[target]);\n if (values !== null) {\n columns.set(property, values);\n }\n }\n out[target] = { values: canonicalize(target, columns, dialect, count(snapshot, target), notes, budget) };\n }\n return {\n dialect,\n tool: null,\n units: styleLengthUnit(dialect),\n graph: {},\n node: out.node,\n edge: out.edge,\n raw,\n notes: [],\n };\n}\n\n/**\n * The element count of a target.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @returns the count\n */\nfunction count(snapshot: GraphSnapshot, target: StyleTarget): number {\n return target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n}\n\n/**\n * The raw values of one property on the simple path: a snapshot column by name, or an array by element index.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @param property - the property\n * @param source - `{ data: \"<column>\" }` or an array\n * @param notes - where a missing column is noted\n * @param raw - collects the names of the columns read\n * @returns the values, or null\n */\nfunction rawValues(\n snapshot: GraphSnapshot,\n target: StyleTarget,\n property: string,\n source: unknown,\n notes: StyleNotes,\n raw: string[],\n): readonly unknown[] | null {\n if (Array.isArray(source)) {\n return source as unknown[];\n }\n if (source === null || typeof source !== \"object\" || typeof (source as { data?: unknown }).data !== \"string\") {\n notes.add(STYLE_ISSUE.BAD_MAPPING, target, property, { sample: source });\n return null;\n }\n const name = (source as { data: string }).data;\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n if (!table.has(name)) {\n notes.add(STYLE_ISSUE.MAPPING_COLUMN_MISSING, target, property, { sample: name });\n return null;\n }\n raw.push(name);\n const n = count(snapshot, target);\n const out = new Array<unknown>(n);\n for (let i = 0; i < n; i++) {\n out[i] = plainCell(table.value(name, i));\n }\n return out;\n}\n\n/**\n * Canonical values of every property of one target. A list value is read as its first item. A color's alpha moves\n * into the fill's or the edge's opacity (multiplied with an opacity the file also states) or is dropped with a note.\n * @param target - nodes or edges\n * @param columns - the raw values per property\n * @param dialect - how they are spelled\n * @param n - the element count\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @returns the canonical values per property\n */\nfunction canonicalize(\n target: StyleTarget,\n columns: ReadonlyMap<string, readonly unknown[]>,\n dialect: StyleDialect,\n n: number,\n notes: StyleNotes,\n budget: StyleBudget,\n): Record<string, StyleColumn> {\n const cx: CanonContext = { target, dialect, n, notes, budget };\n // keyed by the importer's property names: no prototype, so `__proto__` is a property like any other\n const out: Record<string, (StyleValue | null)[]> = Object.create(null) as Record<string, (StyleValue | null)[]>;\n const alphas = new Map<string, (number | null)[]>();\n for (const [property, raws] of columns) {\n const { col, alpha } = canonicalColumn(cx, property, raws);\n out[property] = col;\n if (alpha !== null) {\n alphas.set(property, alpha);\n }\n }\n for (const [property, alpha] of alphas) {\n moveAlpha(cx, out, property, alpha);\n }\n return out;\n}\n\n/** What canonicalize() reads one target's values with. */\ninterface CanonContext {\n readonly target: StyleTarget;\n readonly dialect: StyleDialect;\n /** The element count. */\n readonly n: number;\n readonly notes: StyleNotes;\n readonly budget: StyleBudget;\n}\n\n/**\n * Canonical values of one property; a color's alpha below 1 is kept apart.\n * @param cx - the target being read\n * @param property - the property\n * @param raws - its raw values\n * @returns the values, and the alphas (null when every color is opaque)\n */\nfunction canonicalColumn(\n cx: CanonContext,\n property: string,\n raws: readonly unknown[],\n): { col: (StyleValue | null)[]; alpha: (number | null)[] | null } {\n const { target, dialect, n, notes, budget } = cx;\n const kind = STYLE_PROPERTIES[target].get(property);\n const col = new Array<StyleValue | null>(n).fill(null);\n let alpha: (number | null)[] | null = null;\n for (let i = 0; i < n && i < raws.length; i++) {\n const site: CanonSite = { notes, target, property, element: i, budget };\n const v = firstItem(raws[i], site);\n if (v === null || v === undefined) {\n continue;\n }\n if (kind !== \"color\") {\n col[i] = canonValue(kind, property, v, dialect, site);\n continue;\n }\n const c = canonColor(v, dialect, site, { use: colorUse(target, property) });\n col[i] = c?.color ?? null;\n if (c !== null && c.alpha < 1) {\n alpha ??= new Array<number | null>(n).fill(null);\n alpha[i] = c.alpha;\n }\n }\n return { col, alpha };\n}\n\n/**\n * A raw value, a list read as its first item (a longer list noted).\n * @param v - the raw value\n * @param site - where it was read\n * @returns the value\n */\nfunction firstItem(v: unknown, site: CanonSite): unknown {\n if (!Array.isArray(v)) {\n return v;\n }\n if (v.length > 1) {\n site.notes.add(STYLE_ISSUE.BAD_VALUE, site.target, site.property, { sample: v, element: site.element });\n }\n return v.length === 0 ? null : v[0];\n}\n\n/**\n * Moves a color property's alphas into its opacity (multiplied with an opacity the file also states), or drops them\n * with a note where the property has none.\n * @param cx - the target being read\n * @param out - the canonical values, changed in place\n * @param property - the color property\n * @param alpha - its alphas\n */\nfunction moveAlpha(\n cx: CanonContext,\n out: Record<string, (StyleValue | null)[]>,\n property: string,\n alpha: readonly (number | null)[],\n): void {\n const { target, n, notes, budget } = cx;\n const carrier = OPACITY_OF.get(`${target}.${property}`) ?? null;\n let opacity: (StyleValue | null)[] | null = null;\n if (carrier !== null) {\n out[carrier] ??= new Array<StyleValue | null>(n).fill(null);\n opacity = out[carrier];\n }\n for (let i = 0; i < n; i++) {\n const a = alpha[i];\n if (a === null) {\n continue;\n }\n const site: CanonSite = { notes, target, property, element: i, budget };\n const stated = opacity === null ? null : (opacity[i] as number | null);\n const merged = colorOpacity(\n { color: out[property][i] as `#${string}`, alpha: a },\n stated,\n site,\n opacity !== null,\n );\n if (opacity !== null) {\n opacity[i] = merged;\n }\n }\n}\n\n/** The opacity property that carries a color's alpha: a node's fill and an edge's line. */\nconst OPACITY_OF: ReadonlyMap<string, string> = new Map([\n [\"node.fill\", \"fillOpacity\"],\n [\"edge.color\", \"opacity\"],\n]);\n\n/**\n * How a color is drawn, which decides how a Graphviz color list is read.\n * @param target - nodes or edges\n * @param property - the property\n * @returns the use\n */\nfunction colorUse(target: StyleTarget, property: string): \"fill\" | \"edge\" | \"line\" {\n if (property === \"fill\") {\n return \"fill\";\n }\n return target === \"edge\" && property === \"color\" ? \"edge\" : \"line\";\n}\n\n/**\n * The canonical value of a property that is not a color.\n * @param kind - the property's value kind, or undefined for a property outside the vocabulary\n * @param property - the property\n * @param raw - the raw value\n * @param dialect - how it is spelled\n * @param site - where it was read\n * @returns the value, or null\n */\nfunction canonValue(\n kind: string | undefined,\n property: string,\n raw: unknown,\n dialect: StyleDialect,\n site: CanonSite,\n): StyleValue | null {\n switch (kind) {\n case \"number\":\n return canonNumber(\n raw,\n site,\n dialect === \"graphviz\" && (property === \"width\" || property === \"height\") ? DOT_POINTS_PER_INCH : 1,\n );\n case \"opacity\":\n return canonOpacity(raw, dialect, site);\n case \"boolean\":\n return canonBoolean(raw, site);\n case \"text\":\n return canonText(raw, site);\n case undefined:\n // a property only one consumer draws (graphty:<channel>) is carried as it is\n return typeof raw === \"string\" ||\n typeof raw === \"boolean\" ||\n (typeof raw === \"number\" && Number.isFinite(raw))\n ? raw\n : null;\n default:\n return ENUM_KINDS.has(kind) ? canonEnum(kind as StyleEnumKind, raw, dialect, site) : null;\n }\n}\n\n/** The style roles and the property each sets, per target; `size` sets a node's width and height. */\nconst ROLE_PROPERTIES: Readonly<Record<StyleTarget, readonly (readonly [string, readonly string[]])[]>> = {\n node: [\n [\"color\", [\"fill\"]],\n [\"size\", [\"width\", \"height\"]],\n [\"shape\", [\"shape\"]],\n [\"hidden\", [\"visible\"]],\n ],\n edge: [\n [\"color\", [\"color\"]],\n [\"thickness\", [\"width\"]],\n [\"shape\", [\"lineStyle\"]],\n [\"hidden\", [\"visible\"]],\n ],\n};\n\n/**\n * The generic reader: the styles of the columns whose role is `color`, `size`, `shape`, `thickness` or `hidden`, so a\n * format that tags its style columns needs no reader of its own. A color column holds CSS text or channel numbers\n * (0..1 in a float column, 0..255 otherwise, with an optional alpha); a hidden column holds booleans.\n * @param snapshot - the graph\n * @param dialect - how text values are spelled (the format's name; CSS for a format with no dialect of its own)\n * @param notes - where problems are noted\n * @param budget - the work budget\n * @returns the canonical values, or null when no column has a style role\n */\nfunction roleStyles(\n snapshot: GraphSnapshot,\n dialect: StyleDialect,\n notes: StyleNotes,\n budget: StyleBudget,\n): StyleTruth | null {\n const raw = { node: [] as string[], edge: [] as string[] };\n const out = { node: { values: {} } as ReaderOutput, edge: { values: {} } as ReaderOutput };\n for (const target of TARGETS) {\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = count(snapshot, target);\n const columns = new Map<string, readonly unknown[]>();\n for (const [role, properties] of ROLE_PROPERTIES[target]) {\n const col = table.byRole(role);\n if (col === null) {\n continue;\n }\n raw[target].push(col.meta.name);\n const vals = roleValues(table, col.meta, role, n);\n for (const p of properties) {\n columns.set(p, vals);\n }\n }\n out[target] = { values: canonicalize(target, columns, dialect, n, notes, budget) };\n }\n if (raw.node.length === 0 && raw.edge.length === 0) {\n return null;\n }\n return {\n dialect,\n tool: null,\n units: styleLengthUnit(dialect),\n graph: {},\n node: out.node,\n edge: out.edge,\n raw,\n notes: [],\n };\n}\n\n/**\n * A role column's raw values: a color as text, a hidden flag as the visibility it says the opposite of.\n * @param table - the node or edge table\n * @param meta - the column's name and dtype\n * @param meta.name - the column's name\n * @param meta.dtype - its dtype\n * @param role - its role\n * @param n - the element count\n * @returns the values\n */\nfunction roleValues(\n table: GraphSnapshot[\"nodes\"],\n meta: { readonly name: string; readonly dtype: string },\n role: string,\n n: number,\n): unknown[] {\n return Array.from({ length: n }, (_, i) => {\n const v = plainCell(table.value(meta.name, i));\n if (role === \"color\") {\n return channelsColor(v, meta.dtype);\n }\n if (role === \"hidden\") {\n return typeof v === \"boolean\" ? !v : null;\n }\n return v;\n });\n}\n\n/**\n * A color cell as text: channel numbers become `rgba()` (floats 0..1, integers 0..255); text stays as it is.\n * @param v - the cell\n * @param dtype - the column's dtype\n * @returns the color's text, or the cell unchanged\n */\nfunction channelsColor(v: unknown, dtype: string): unknown {\n if (\n !Array.isArray(v) ||\n (v.length !== 3 && v.length !== 4) ||\n !v.every((x) => typeof x === \"number\" && Number.isFinite(x))\n ) {\n return v;\n }\n const scale = dtype === \"f32\" || dtype === \"f64\" ? 255 : 1;\n const [r, g, b] = (v as number[]).map((x) => Math.round(x * scale));\n const alphaScale = scale === 255 ? 1 : 255;\n const a = v.length === 4 ? (v[3] as number) / alphaScale : 1;\n return `rgba(${String(r)}, ${String(g)}, ${String(b)}, ${String(a)})`;\n}\n"],"names":["count","raw"],"mappings":"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"}
|