@graphty/graph-io 0.3.39 → 0.3.41
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/{choose-CS3fvGT1.js → choose-CwFQamH9.js} +2 -2
- package/dist/chunks/{choose-CS3fvGT1.js.map → choose-CwFQamH9.js.map} +1 -1
- package/dist/chunks/{constants-DqKZT6cH.js → constants-Cf4Nn6tw.js} +2 -2
- package/dist/chunks/{constants-DqKZT6cH.js.map → constants-Cf4Nn6tw.js.map} +1 -1
- package/dist/chunks/{escape-BpYMQZVa.js → escape-DBb8zuNE.js} +4 -3
- package/dist/chunks/escape-DBb8zuNE.js.map +1 -0
- package/dist/chunks/{export-B-aVCwyG.js → export-DD3Lvw-F.js} +173 -116
- package/dist/chunks/export-DD3Lvw-F.js.map +1 -0
- package/dist/chunks/{exporter-CNJZF_BN.js → exporter-BqtmlxNr.js} +545 -459
- package/dist/chunks/exporter-BqtmlxNr.js.map +1 -0
- package/dist/chunks/{exporter-BqKs1Q12.js → exporter-CS35R6Fg.js} +6 -5
- package/dist/chunks/exporter-CS35R6Fg.js.map +1 -0
- package/dist/chunks/{exporter-DXqCPNrI.js → exporter-D8r1N2dU.js} +67 -42
- package/dist/chunks/exporter-D8r1N2dU.js.map +1 -0
- package/dist/chunks/{exporter-SFYkDzD0.js → exporter-NMplSnYn.js} +23 -20
- package/dist/chunks/{exporter-SFYkDzD0.js.map → exporter-NMplSnYn.js.map} +1 -1
- package/dist/chunks/{importer-CSt-gaYE.js → importer-BKC7AmCA.js} +42 -29
- package/dist/chunks/importer-BKC7AmCA.js.map +1 -0
- package/dist/chunks/{importer-DvFznt5-.js → importer-BdWHmlmG.js} +112 -62
- package/dist/chunks/importer-BdWHmlmG.js.map +1 -0
- package/dist/chunks/{importer-CqgYq4Ld.js → importer-BfbzWk6k.js} +202 -181
- package/dist/chunks/importer-BfbzWk6k.js.map +1 -0
- package/dist/chunks/{importer-PVXkeoaS.js → importer-BmaZcskq.js} +79 -66
- package/dist/chunks/importer-BmaZcskq.js.map +1 -0
- package/dist/chunks/{importer-B7Ir269L.js → importer-DviEsHy4.js} +118 -72
- package/dist/chunks/importer-DviEsHy4.js.map +1 -0
- package/dist/chunks/{importer--tQQsY4W.js → importer-S-abxJHn.js} +5 -5
- package/dist/chunks/{importer--tQQsY4W.js.map → importer-S-abxJHn.js.map} +1 -1
- package/dist/chunks/{importer-BfJ1jnNr.js → importer-r29cWnEf.js} +28 -13
- package/dist/chunks/importer-r29cWnEf.js.map +1 -0
- package/dist/chunks/{json-elements-CXs4z1iL.js → json-elements-DdF-etPT.js} +7 -5
- package/dist/chunks/{json-elements-CXs4z1iL.js.map → json-elements-DdF-etPT.js.map} +1 -1
- package/dist/chunks/{ontology-export-50L9DOV4.js → ontology-export-BC0zyPhj.js} +2 -2
- package/dist/chunks/{ontology-export-50L9DOV4.js.map → ontology-export-BC0zyPhj.js.map} +1 -1
- package/dist/chunks/{records-C9jd7yLD.js → records-Uc3LkABx.js} +150 -106
- package/dist/chunks/records-Uc3LkABx.js.map +1 -0
- package/dist/chunks/{text-Bjfa1xYL.js → text-Bh9SaAob.js} +20 -11
- package/dist/chunks/text-Bh9SaAob.js.map +1 -0
- package/dist/csv.js +67 -49
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +1 -1
- package/dist/gexf.js +199 -99
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +170 -149
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +26 -26
- package/dist/graphml.js +2 -2
- package/dist/json.js +1 -1
- package/dist/neo4j.js +103 -65
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/src/common/attributes.d.ts.map +1 -1
- package/dist/src/common/attributes.js +34 -9
- package/dist/src/common/attributes.js.map +1 -1
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +180 -102
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/json-elements.d.ts.map +1 -1
- package/dist/src/common/json-elements.js +4 -2
- package/dist/src/common/json-elements.js.map +1 -1
- package/dist/src/common/text.d.ts +7 -0
- package/dist/src/common/text.d.ts.map +1 -1
- package/dist/src/common/text.js +15 -7
- package/dist/src/common/text.js.map +1 -1
- package/dist/src/common/xml.d.ts.map +1 -1
- package/dist/src/common/xml.js +2 -1
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/common/zip.d.ts.map +1 -1
- package/dist/src/common/zip.js +36 -19
- package/dist/src/common/zip.js.map +1 -1
- package/dist/src/formats/csv/exporter.d.ts.map +1 -1
- package/dist/src/formats/csv/exporter.js +77 -25
- package/dist/src/formats/csv/exporter.js.map +1 -1
- package/dist/src/formats/csv/importer.d.ts.map +1 -1
- package/dist/src/formats/csv/importer.js +16 -6
- package/dist/src/formats/csv/importer.js.map +1 -1
- package/dist/src/formats/csv/records.d.ts.map +1 -1
- package/dist/src/formats/csv/records.js +156 -110
- package/dist/src/formats/csv/records.js.map +1 -1
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +108 -53
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +2 -1
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +28 -6
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cys/tables.d.ts.map +1 -1
- package/dist/src/formats/cys/tables.js +11 -8
- package/dist/src/formats/cys/tables.js.map +1 -1
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +69 -39
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +138 -50
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +51 -35
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +103 -58
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/syntax.d.ts.map +1 -1
- package/dist/src/formats/gml/syntax.js +17 -8
- package/dist/src/formats/gml/syntax.js.map +1 -1
- package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
- package/dist/src/formats/graphml/exporter.js +36 -25
- package/dist/src/formats/graphml/exporter.js.map +1 -1
- package/dist/src/formats/graphml/importer.d.ts.map +1 -1
- package/dist/src/formats/graphml/importer.js +20 -15
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/graphml/tree.js +23 -14
- package/dist/src/formats/graphml/tree.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +22 -10
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +38 -21
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +536 -343
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/obographs.js +29 -17
- package/dist/src/formats/json/obographs.js.map +1 -1
- package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
- package/dist/src/formats/neo4j/exporter.js +73 -43
- package/dist/src/formats/neo4j/exporter.js.map +1 -1
- package/dist/src/formats/neo4j/header.d.ts.map +1 -1
- package/dist/src/formats/neo4j/header.js +37 -16
- package/dist/src/formats/neo4j/header.js.map +1 -1
- package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
- package/dist/src/formats/neo4j/importer.js +21 -11
- package/dist/src/formats/neo4j/importer.js.map +1 -1
- package/dist/src/formats/obo/exporter.d.ts.map +1 -1
- package/dist/src/formats/obo/exporter.js +18 -7
- package/dist/src/formats/obo/exporter.js.map +1 -1
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +142 -73
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +26 -15
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +85 -58
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts +13 -0
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +112 -50
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
- package/dist/src/formats/xgmml/exporter.js +92 -34
- package/dist/src/formats/xgmml/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
- package/dist/src/formats/xgmml/importer.js +38 -18
- package/dist/src/formats/xgmml/importer.js.map +1 -1
- package/dist/src/sniff.js +109 -57
- package/dist/src/sniff.js.map +1 -1
- package/dist/xgmml.js +2 -2
- package/package.json +2 -2
- package/src/common/attributes.ts +59 -19
- package/src/common/input.ts +216 -102
- package/src/common/json-elements.ts +4 -2
- package/src/common/text.ts +24 -15
- package/src/common/xml.ts +2 -1
- package/src/common/zip.ts +47 -18
- package/src/formats/csv/exporter.ts +103 -39
- package/src/formats/csv/importer.ts +17 -6
- package/src/formats/csv/records.ts +162 -109
- package/src/formats/cx/importer.ts +140 -58
- package/src/formats/cx2/exporter.ts +2 -1
- package/src/formats/cx2/importer.ts +34 -10
- package/src/formats/cys/tables.ts +11 -10
- package/src/formats/gexf/exporter.ts +71 -38
- package/src/formats/gexf/importer.ts +173 -63
- package/src/formats/gml/exporter.ts +78 -82
- package/src/formats/gml/importer.ts +119 -68
- package/src/formats/gml/syntax.ts +18 -8
- package/src/formats/graphml/exporter.ts +46 -27
- package/src/formats/graphml/importer.ts +21 -13
- package/src/formats/graphml/tree.ts +22 -12
- package/src/formats/graphml/yfiles.ts +23 -10
- package/src/formats/json/exporter.ts +40 -21
- package/src/formats/json/importer.ts +701 -385
- package/src/formats/json/obographs.ts +35 -15
- package/src/formats/neo4j/exporter.ts +79 -41
- package/src/formats/neo4j/header.ts +50 -16
- package/src/formats/neo4j/importer.ts +21 -10
- package/src/formats/obo/exporter.ts +34 -17
- package/src/formats/pajek/exporter.ts +180 -117
- package/src/formats/pajek/importer.ts +27 -15
- package/src/formats/pajek/syntax.ts +99 -58
- package/src/formats/xgmml/emit.ts +122 -50
- package/src/formats/xgmml/exporter.ts +103 -35
- package/src/formats/xgmml/importer.ts +45 -23
- package/src/sniff.ts +115 -59
- package/dist/chunks/escape-BpYMQZVa.js.map +0 -1
- package/dist/chunks/export-B-aVCwyG.js.map +0 -1
- package/dist/chunks/exporter-BqKs1Q12.js.map +0 -1
- package/dist/chunks/exporter-CNJZF_BN.js.map +0 -1
- package/dist/chunks/exporter-DXqCPNrI.js.map +0 -1
- package/dist/chunks/importer-B7Ir269L.js.map +0 -1
- package/dist/chunks/importer-BfJ1jnNr.js.map +0 -1
- package/dist/chunks/importer-CSt-gaYE.js.map +0 -1
- package/dist/chunks/importer-CqgYq4Ld.js.map +0 -1
- package/dist/chunks/importer-DvFznt5-.js.map +0 -1
- package/dist/chunks/importer-PVXkeoaS.js.map +0 -1
- package/dist/chunks/records-C9jd7yLD.js.map +0 -1
- package/dist/chunks/text-Bjfa1xYL.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
|
|
2
|
-
import { c as capabilities, R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, o as DUPLICATE_ATTRIBUTE_CODE, g as UNKNOWN_ELEMENT_CODE, b5 as EMPTY_COLUMN_DROPPED_CODE, ai as PARENT_CYCLE_CODE, P as PRECISION_CODE, w as UNKNOWN_ENCODING_CODE, a2 as JSON_NONSTANDARD_NUMBER_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, O as OPTION_IGNORED_CODE, S as SINK_OPTION_CODE, H as HYPEREDGE_CODE, ad as TOO_LARGE_CODE, i as DANGLING_REFERENCE_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, l as MULTIPLE_GRAPHS_CODE, I as ID_MERGED_CODE, m as DUPLICATE_EDGE_ID_CODE, n as DUPLICATE_NODE_CODE, q as UNKNOWN_PARENT_CODE, a3 as BAD_VALUE_CODE, s as MISSING_ENDPOINT_CODE, t as MISSING_ID_CODE, ak as SYNTAX_CODE, E as EMPTY_INPUT_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, al as resolveImportOptions, a8 as ImportReportBuilder, bB as readText, b as plural, ao as reportSinkOptions, an as reportUnusedOptions, am as throwIfAborted, ar as IdCoercer, aq as DirectionResolver, $ as agree, as as weightFromValue, a0 as uniqueColumnName, a7 as chooseGraph, ap as graphChosen, a1 as declareResolved, aB as GRAPH_COLUMN_AS_METADATA_CODE, aC as TYPEDEF_NODES_CODE, aD as RELATION_ASSUMED_CODE, at as COLUMN_AS_PROPERTY_VALUE_CODE, p as pairFolding, e as explicitWeights, bd as NONFINITE_AS_NULL_CODE, L as LOSS, b3 as DIRECTION_DROPPED_CODE, aA as NODE_ORDER_CODE, r as resolveExportOptions, b_ as otherFormatDialect, a as checkCapabilities, bD as countMixedEdges, aa as formatF32, ab as formatF64 } from "./export-
|
|
3
|
-
import { M as MAYBE_UNSAFE_INTEGER, j as MAYBE_INEXACT_EXPONENT, l as rewriteNumbers, m as findDuplicateKeys, f as flipY } from "./json-elements-
|
|
2
|
+
import { c as capabilities, R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, o as DUPLICATE_ATTRIBUTE_CODE, g as UNKNOWN_ELEMENT_CODE, b5 as EMPTY_COLUMN_DROPPED_CODE, ai as PARENT_CYCLE_CODE, P as PRECISION_CODE, w as UNKNOWN_ENCODING_CODE, a2 as JSON_NONSTANDARD_NUMBER_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, O as OPTION_IGNORED_CODE, S as SINK_OPTION_CODE, H as HYPEREDGE_CODE, ad as TOO_LARGE_CODE, i as DANGLING_REFERENCE_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, l as MULTIPLE_GRAPHS_CODE, I as ID_MERGED_CODE, m as DUPLICATE_EDGE_ID_CODE, n as DUPLICATE_NODE_CODE, q as UNKNOWN_PARENT_CODE, a3 as BAD_VALUE_CODE, s as MISSING_ENDPOINT_CODE, t as MISSING_ID_CODE, ak as SYNTAX_CODE, E as EMPTY_INPUT_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, al as resolveImportOptions, a8 as ImportReportBuilder, bB as readText, b as plural, ao as reportSinkOptions, an as reportUnusedOptions, am as throwIfAborted, ar as IdCoercer, aq as DirectionResolver, $ as agree, as as weightFromValue, a0 as uniqueColumnName, a7 as chooseGraph, ap as graphChosen, a1 as declareResolved, aB as GRAPH_COLUMN_AS_METADATA_CODE, aC as TYPEDEF_NODES_CODE, aD as RELATION_ASSUMED_CODE, at as COLUMN_AS_PROPERTY_VALUE_CODE, p as pairFolding, e as explicitWeights, bd as NONFINITE_AS_NULL_CODE, L as LOSS, b3 as DIRECTION_DROPPED_CODE, aA as NODE_ORDER_CODE, r as resolveExportOptions, b_ as otherFormatDialect, a as checkCapabilities, bD as countMixedEdges, aa as formatF32, ab as formatF64 } from "./export-DD3Lvw-F.js";
|
|
3
|
+
import { M as MAYBE_UNSAFE_INTEGER, j as MAYBE_INEXACT_EXPONENT, l as rewriteNumbers, m as findDuplicateKeys, f as flipY } from "./json-elements-DdF-etPT.js";
|
|
4
4
|
import { j as joinText, e as encodeChunks, i as indentUnit } from "./writer-DxjgHwSe.js";
|
|
5
|
-
import { t as trimTrailingZeros } from "./text-
|
|
6
|
-
import { d as OBOGRAPHS_PREDICATE_TAGS, g as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, h as synonymScopeOf, O as OBO_NODE_COLUMNS, c as capabilityNotes, s as slotColumn, e as emptyColumnNotes, j as OBO_PURL, f as framelessNodes, m as movedNodes, U as UNWRITTEN_ROLES, n as notePropertyColumn, a as cellOf, v as valuesOf, k as OBO_IN_OWL, b as fitsVocabulary, t as textOf, S as SYNONYM_SCOPES } from "./ontology-export-
|
|
5
|
+
import { t as trimTrailingZeros } from "./text-Bh9SaAob.js";
|
|
6
|
+
import { d as OBOGRAPHS_PREDICATE_TAGS, g as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, h as synonymScopeOf, O as OBO_NODE_COLUMNS, c as capabilityNotes, s as slotColumn, e as emptyColumnNotes, j as OBO_PURL, f as framelessNodes, m as movedNodes, U as UNWRITTEN_ROLES, n as notePropertyColumn, a as cellOf, v as valuesOf, k as OBO_IN_OWL, b as fitsVocabulary, t as textOf, S as SYNONYM_SCOPES } from "./ontology-export-BC0zyPhj.js";
|
|
7
7
|
const JSON_DIALECTS = Object.freeze([
|
|
8
8
|
"node-link",
|
|
9
9
|
"d3",
|
|
@@ -373,38 +373,42 @@ function skeletonOf(text) {
|
|
|
373
373
|
}
|
|
374
374
|
const root = {};
|
|
375
375
|
for (const key of rootKeys) {
|
|
376
|
-
|
|
377
|
-
case "graph":
|
|
378
|
-
case "options":
|
|
379
|
-
root[key] = objectOf(keys.get(key));
|
|
380
|
-
break;
|
|
381
|
-
case "graphs": {
|
|
382
|
-
const nodes = keys.get("graphs[0].nodes[]");
|
|
383
|
-
const edges = keys.get("graphs[0].edges[]");
|
|
384
|
-
const graph = {};
|
|
385
|
-
if (nodes !== void 0) {
|
|
386
|
-
graph.nodes = [objectOf(nodes)];
|
|
387
|
-
}
|
|
388
|
-
if (edges !== void 0) {
|
|
389
|
-
graph.edges = [objectOf(edges)];
|
|
390
|
-
}
|
|
391
|
-
root[key] = nodes === void 0 && edges === void 0 ? [] : [graph];
|
|
392
|
-
break;
|
|
393
|
-
}
|
|
394
|
-
case "nodes":
|
|
395
|
-
case "edges":
|
|
396
|
-
case "links": {
|
|
397
|
-
const first = keys.get(`${key}[0]`);
|
|
398
|
-
root[key] = first === void 0 ? [] : [objectOf(first)];
|
|
399
|
-
break;
|
|
400
|
-
}
|
|
401
|
-
default:
|
|
402
|
-
root[key] = true;
|
|
403
|
-
break;
|
|
404
|
-
}
|
|
376
|
+
root[key] = placeholderOf(key, keys);
|
|
405
377
|
}
|
|
406
378
|
return root;
|
|
407
379
|
}
|
|
380
|
+
function placeholderOf(key, keys) {
|
|
381
|
+
switch (key) {
|
|
382
|
+
case "graph":
|
|
383
|
+
case "options":
|
|
384
|
+
return objectOf(keys.get(key));
|
|
385
|
+
case "graphs":
|
|
386
|
+
return graphsPlaceholder(keys);
|
|
387
|
+
case "nodes":
|
|
388
|
+
case "edges":
|
|
389
|
+
case "links": {
|
|
390
|
+
const first = keys.get(`${key}[0]`);
|
|
391
|
+
return first === void 0 ? [] : [objectOf(first)];
|
|
392
|
+
}
|
|
393
|
+
default:
|
|
394
|
+
return true;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function graphsPlaceholder(keys) {
|
|
398
|
+
const nodes = keys.get("graphs[0].nodes[]");
|
|
399
|
+
const edges = keys.get("graphs[0].edges[]");
|
|
400
|
+
if (nodes === void 0 && edges === void 0) {
|
|
401
|
+
return [];
|
|
402
|
+
}
|
|
403
|
+
const graph = {};
|
|
404
|
+
if (nodes !== void 0) {
|
|
405
|
+
graph.nodes = [objectOf(nodes)];
|
|
406
|
+
}
|
|
407
|
+
if (edges !== void 0) {
|
|
408
|
+
graph.edges = [objectOf(edges)];
|
|
409
|
+
}
|
|
410
|
+
return [graph];
|
|
411
|
+
}
|
|
408
412
|
function objectOf(names) {
|
|
409
413
|
const out = {};
|
|
410
414
|
if (names !== void 0) {
|
|
@@ -421,28 +425,6 @@ function scanKeys(text) {
|
|
|
421
425
|
const counts = [];
|
|
422
426
|
let pendingKey = null;
|
|
423
427
|
let expectingKey = false;
|
|
424
|
-
const pathOf = () => {
|
|
425
|
-
const depth = kinds.length;
|
|
426
|
-
if (depth === 1) {
|
|
427
|
-
return kinds[0] === "object" ? "" : null;
|
|
428
|
-
}
|
|
429
|
-
if (depth === 2 && kinds[0] === "array" && kinds[1] === "object" && labels[1] === "0") {
|
|
430
|
-
return "nodes[0]";
|
|
431
|
-
}
|
|
432
|
-
if (depth === 2 && kinds[0] === "object" && kinds[1] === "object") {
|
|
433
|
-
return labels[1] === "graph" || labels[1] === "options" ? labels[1] : null;
|
|
434
|
-
}
|
|
435
|
-
if (depth === 5 && kinds.join() === "object,array,object,array,object" && labels[1] === "graphs" && labels[2] === "0" && (labels[3] === "nodes" || labels[3] === "edges")) {
|
|
436
|
-
return labels[3] === "nodes" ? "graphs[0].nodes[]" : "graphs[0].edges[]";
|
|
437
|
-
}
|
|
438
|
-
if (depth === 3 && kinds[0] === "object" && kinds[1] === "array" && kinds[2] === "object") {
|
|
439
|
-
const section = labels[1];
|
|
440
|
-
if ((section === "nodes" || section === "edges" || section === "links") && labels[2] === "0") {
|
|
441
|
-
return `${section}[0]`;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
return null;
|
|
445
|
-
};
|
|
446
428
|
let i = 0;
|
|
447
429
|
const n = text.length;
|
|
448
430
|
while (i < n) {
|
|
@@ -478,7 +460,7 @@ function scanKeys(text) {
|
|
|
478
460
|
pendingKey = null;
|
|
479
461
|
} else if (ch === ":") {
|
|
480
462
|
if (pendingKey !== null) {
|
|
481
|
-
const path =
|
|
463
|
+
const path = keyPathOf(kinds, labels);
|
|
482
464
|
if (path !== null) {
|
|
483
465
|
let set = found.get(path);
|
|
484
466
|
if (set === void 0) {
|
|
@@ -500,6 +482,45 @@ function scanKeys(text) {
|
|
|
500
482
|
}
|
|
501
483
|
return found;
|
|
502
484
|
}
|
|
485
|
+
function keyPathOf(kinds, labels) {
|
|
486
|
+
switch (kinds.length) {
|
|
487
|
+
case 1:
|
|
488
|
+
return kinds[0] === "object" ? "" : null;
|
|
489
|
+
case 2:
|
|
490
|
+
return nestedObjectPath(kinds, labels);
|
|
491
|
+
case 3:
|
|
492
|
+
return sectionElementPath(kinds, labels);
|
|
493
|
+
case 5:
|
|
494
|
+
return graphsMemberPath(kinds, labels);
|
|
495
|
+
default:
|
|
496
|
+
return null;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function nestedObjectPath(kinds, labels) {
|
|
500
|
+
if (kinds[0] === "array" && kinds[1] === "object" && labels[1] === "0") {
|
|
501
|
+
return "nodes[0]";
|
|
502
|
+
}
|
|
503
|
+
if (kinds[0] === "object" && kinds[1] === "object") {
|
|
504
|
+
return labels[1] === "graph" || labels[1] === "options" ? labels[1] : null;
|
|
505
|
+
}
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
function sectionElementPath(kinds, labels) {
|
|
509
|
+
if (kinds[0] !== "object" || kinds[1] !== "array" || kinds[2] !== "object" || labels[2] !== "0") {
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
const section = labels[1];
|
|
513
|
+
return section === "nodes" || section === "edges" || section === "links" ? `${section}[0]` : null;
|
|
514
|
+
}
|
|
515
|
+
function graphsMemberPath(kinds, labels) {
|
|
516
|
+
if (kinds.join() !== "object,array,object,array,object" || labels[1] !== "graphs" || labels[2] !== "0") {
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
if (labels[3] === "nodes") {
|
|
520
|
+
return "graphs[0].nodes[]";
|
|
521
|
+
}
|
|
522
|
+
return labels[3] === "edges" ? "graphs[0].edges[]" : null;
|
|
523
|
+
}
|
|
503
524
|
function scanString(text, from) {
|
|
504
525
|
let i = from;
|
|
505
526
|
while (i < text.length) {
|
|
@@ -2076,18 +2097,7 @@ function importAdjacency(ctx, root) {
|
|
|
2076
2097
|
const multigraph = hasKey(root, "multigraph") ? flagOf(root.multigraph, "multigraph", false, report) : null;
|
|
2077
2098
|
ctx.setHeader(directed);
|
|
2078
2099
|
ctx.writeGraphDict(isPairList(root.graph) ? Object.fromEntries(root.graph) : root.graph, "graph");
|
|
2079
|
-
|
|
2080
|
-
if (key !== "nodes" && key !== "adjacency" && key !== "directed" && key !== "multigraph" && key !== "graph") {
|
|
2081
|
-
report.warning(
|
|
2082
|
-
"unsupported",
|
|
2083
|
-
JSON_ISSUE.UNREAD_KEY,
|
|
2084
|
-
`top-level key ${key} (${describe(root[key])}) is not read; dropped`,
|
|
2085
|
-
{
|
|
2086
|
-
element: key
|
|
2087
|
-
}
|
|
2088
|
-
);
|
|
2089
|
-
}
|
|
2090
|
-
}
|
|
2100
|
+
reportUnreadAdjacencyKeys(ctx, root);
|
|
2091
2101
|
const lists = adjacency ?? [];
|
|
2092
2102
|
ctx.sink.reserve(
|
|
2093
2103
|
nodes.length,
|
|
@@ -2095,90 +2105,120 @@ function importAdjacency(ctx, root) {
|
|
|
2095
2105
|
);
|
|
2096
2106
|
const idKey = ctx.json.nodeIdKey ?? "id";
|
|
2097
2107
|
ctx.reportNodeIdFrom("adjacency", `the ${JSON.stringify(idKey)} key`);
|
|
2098
|
-
const owners = [];
|
|
2099
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
2100
|
-
const element = `nodes[${i}]`;
|
|
2101
|
-
const record = nodes[i];
|
|
2102
|
-
let pushed = null;
|
|
2103
|
-
if (!isJsonObject(record)) {
|
|
2104
|
-
ctx.badElement("node", element);
|
|
2105
|
-
} else {
|
|
2106
|
-
const id = ctx.coerceId(hasKey(record, idKey) ? record[idKey] : void 0, element);
|
|
2107
|
-
if (id === null) {
|
|
2108
|
-
ctx.countSkipped("node");
|
|
2109
|
-
} else {
|
|
2110
|
-
const index = ctx.pushNode(id, element);
|
|
2111
|
-
if (index >= 0) {
|
|
2112
|
-
pushed = id;
|
|
2113
|
-
writeFlat(ctx.nodes, index, record, id, (key) => key !== idKey);
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
}
|
|
2117
|
-
owners.push(pushed);
|
|
2118
|
-
}
|
|
2108
|
+
const owners = nodes.map((record, i) => pushAdjacencyNode(ctx, record, `nodes[${i}]`, idKey));
|
|
2119
2109
|
throwIfAborted(ctx.options.signal);
|
|
2120
|
-
const
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2110
|
+
const reading = {
|
|
2111
|
+
owners,
|
|
2112
|
+
nodeCount: nodes.length,
|
|
2113
|
+
directed,
|
|
2114
|
+
kind: ctx.uniformKind(),
|
|
2115
|
+
idKey,
|
|
2116
|
+
// undirected: entries read once whose mirror is still to come, by pair and key, with their attributes
|
|
2117
|
+
pending: /* @__PURE__ */ new Map(),
|
|
2118
|
+
disagreeing: 0
|
|
2119
|
+
};
|
|
2124
2120
|
for (let i = 0; i < lists.length; i++) {
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2121
|
+
readAdjacencyList(ctx, reading, i, lists[i]);
|
|
2122
|
+
}
|
|
2123
|
+
reportAdjacencyShape(
|
|
2124
|
+
ctx,
|
|
2125
|
+
nodes.length,
|
|
2126
|
+
adjacency === null ? null : lists.length,
|
|
2127
|
+
reading.disagreeing,
|
|
2128
|
+
reading.pending
|
|
2129
|
+
);
|
|
2130
|
+
ctx.setMeta({}, { declaredMultigraph: multigraph, ...ctx.weightOriginPatch() });
|
|
2131
|
+
}
|
|
2132
|
+
const ADJACENCY_DOCUMENT_KEYS = /* @__PURE__ */ new Set(["nodes", "adjacency", "directed", "multigraph", "graph"]);
|
|
2133
|
+
function reportUnreadAdjacencyKeys(ctx, root) {
|
|
2134
|
+
for (const key of Object.keys(root)) {
|
|
2135
|
+
if (!ADJACENCY_DOCUMENT_KEYS.has(key)) {
|
|
2136
|
+
ctx.report.warning(
|
|
2137
|
+
"unsupported",
|
|
2138
|
+
JSON_ISSUE.UNREAD_KEY,
|
|
2139
|
+
`top-level key ${key} (${describe(root[key])}) is not read; dropped`,
|
|
2138
2140
|
{
|
|
2139
|
-
element
|
|
2141
|
+
element: key
|
|
2140
2142
|
}
|
|
2141
2143
|
);
|
|
2142
|
-
report.counts.skippedEdges += list.length;
|
|
2143
|
-
continue;
|
|
2144
2144
|
}
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
function pushAdjacencyNode(ctx, record, element, idKey) {
|
|
2148
|
+
if (!isJsonObject(record)) {
|
|
2149
|
+
ctx.badElement("node", element);
|
|
2150
|
+
return null;
|
|
2151
|
+
}
|
|
2152
|
+
const id = ctx.coerceId(hasKey(record, idKey) ? record[idKey] : void 0, element);
|
|
2153
|
+
if (id === null) {
|
|
2154
|
+
ctx.countSkipped("node");
|
|
2155
|
+
return null;
|
|
2156
|
+
}
|
|
2157
|
+
const index = ctx.pushNode(id, element);
|
|
2158
|
+
if (index < 0) {
|
|
2159
|
+
return null;
|
|
2160
|
+
}
|
|
2161
|
+
writeFlat(ctx.nodes, index, record, id, (key) => key !== idKey);
|
|
2162
|
+
return id;
|
|
2163
|
+
}
|
|
2164
|
+
function readAdjacencyList(ctx, reading, i, list) {
|
|
2165
|
+
const { report } = ctx;
|
|
2166
|
+
const element = `adjacency[${i}]`;
|
|
2167
|
+
if (!Array.isArray(list)) {
|
|
2168
|
+
report.error("validation-error", JSON_ISSUE.BAD_ELEMENT, `${element} is not an array`, { element });
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2171
|
+
const source = i < reading.owners.length ? reading.owners[i] : null;
|
|
2172
|
+
if (source === null) {
|
|
2173
|
+
const why = i < reading.nodeCount ? `nodes[${i}] was skipped` : `there is no nodes[${i}]`;
|
|
2174
|
+
report.error(
|
|
2175
|
+
"missing-value",
|
|
2176
|
+
JSON_ISSUE.BAD_INDEX,
|
|
2177
|
+
`${element}: ${why}; its ${list.length} edge${plural(list.length)} ${agree(list.length, "is", "are")} skipped`,
|
|
2178
|
+
{
|
|
2179
|
+
element
|
|
2151
2180
|
}
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2181
|
+
);
|
|
2182
|
+
report.counts.skippedEdges += list.length;
|
|
2183
|
+
return;
|
|
2184
|
+
}
|
|
2185
|
+
for (let j = 0; j < list.length; j++) {
|
|
2186
|
+
readAdjacencyEntry(ctx, reading, source, list[j], element, `${element}[${j}]`);
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
function readAdjacencyEntry(ctx, reading, source, record, element, entry) {
|
|
2190
|
+
const { idKey } = reading;
|
|
2191
|
+
if (!isJsonObject(record)) {
|
|
2192
|
+
ctx.badElement("edge", entry);
|
|
2193
|
+
return;
|
|
2194
|
+
}
|
|
2195
|
+
if (!hasKey(record, idKey)) {
|
|
2196
|
+
ctx.missingEndpoint(entry, idKey);
|
|
2197
|
+
return;
|
|
2198
|
+
}
|
|
2199
|
+
try {
|
|
2200
|
+
const target = ctx.coerceId(record[idKey], `${entry}.${idKey}`);
|
|
2201
|
+
if (target === null) {
|
|
2202
|
+
ctx.countSkipped("edge");
|
|
2203
|
+
return;
|
|
2204
|
+
}
|
|
2205
|
+
if (!reading.directed) {
|
|
2206
|
+
const mirror = mirroredEntry(reading.pending, source, target, record, idKey);
|
|
2207
|
+
reading.disagreeing += mirror === "disagrees" ? 1 : 0;
|
|
2208
|
+
if (mirror !== "new") {
|
|
2209
|
+
return;
|
|
2155
2210
|
}
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
if (!directed) {
|
|
2163
|
-
const mirror = mirroredEntry(pending, source, target, record, idKey);
|
|
2164
|
-
disagreeing += mirror === "disagrees" ? 1 : 0;
|
|
2165
|
-
if (mirror !== "new") {
|
|
2166
|
-
continue;
|
|
2167
|
-
}
|
|
2168
|
-
}
|
|
2169
|
-
const edge = ctx.pushEdge(source, target, kind, ctx.weightOf(record), entry);
|
|
2170
|
-
for (const key of Object.keys(record)) {
|
|
2171
|
-
if (key !== idKey && key !== weightFrom) {
|
|
2172
|
-
ctx.edges.write(edge, key, record[key], SUFFIX.data, element);
|
|
2173
|
-
}
|
|
2174
|
-
}
|
|
2175
|
-
} catch (err) {
|
|
2176
|
-
ctx.skip(err, "edge", entry);
|
|
2211
|
+
}
|
|
2212
|
+
const edge = ctx.pushEdge(source, target, reading.kind, ctx.weightOf(record), entry);
|
|
2213
|
+
const { weightFrom } = ctx.options;
|
|
2214
|
+
for (const key of Object.keys(record)) {
|
|
2215
|
+
if (key !== idKey && key !== weightFrom) {
|
|
2216
|
+
ctx.edges.write(edge, key, record[key], SUFFIX.data, element);
|
|
2177
2217
|
}
|
|
2178
2218
|
}
|
|
2219
|
+
} catch (err) {
|
|
2220
|
+
ctx.skip(err, "edge", entry);
|
|
2179
2221
|
}
|
|
2180
|
-
reportAdjacencyShape(ctx, nodes.length, adjacency === null ? null : lists.length, disagreeing, pending);
|
|
2181
|
-
ctx.setMeta({}, { declaredMultigraph: multigraph, ...ctx.weightOriginPatch() });
|
|
2182
2222
|
}
|
|
2183
2223
|
function reportAdjacencyShape(ctx, nodes, lists, disagreeing, pending) {
|
|
2184
2224
|
const { report } = ctx;
|
|
@@ -2298,107 +2338,120 @@ function importGraphology(ctx, root) {
|
|
|
2298
2338
|
element: "options"
|
|
2299
2339
|
});
|
|
2300
2340
|
}
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
({ type } = options);
|
|
2304
|
-
} else {
|
|
2305
|
-
if (options.type !== void 0 && options.type !== null) {
|
|
2306
|
-
report.warning(
|
|
2307
|
-
"validation-error",
|
|
2308
|
-
JSON_ISSUE.BAD_FLAG,
|
|
2309
|
-
`options.type ${describe(options.type)} is not directed, undirected or mixed; mixed assumed`,
|
|
2310
|
-
{ element: "options.type" }
|
|
2311
|
-
);
|
|
2312
|
-
}
|
|
2313
|
-
type = "mixed";
|
|
2314
|
-
}
|
|
2315
|
-
let directed;
|
|
2316
|
-
if (type === "mixed") {
|
|
2317
|
-
const objects = edges.filter((edge) => isJsonObject(edge));
|
|
2318
|
-
const undirectedEdges = objects.filter((edge) => edge.undirected === true).length;
|
|
2319
|
-
directed = objects.length === 0 ? ctx.defaultDirected("graphology") : undirectedEdges < objects.length;
|
|
2320
|
-
} else {
|
|
2321
|
-
directed = type === "directed";
|
|
2322
|
-
}
|
|
2323
|
-
ctx.setHeader(directed);
|
|
2341
|
+
const type = graphologyType(ctx, options);
|
|
2342
|
+
ctx.setHeader(graphologyDirected(ctx, type, edges));
|
|
2324
2343
|
const multi = hasKey(options, "multi") ? flagOf(options.multi, "options.multi", false, report) : null;
|
|
2325
2344
|
const allowSelfLoops = hasKey(options, "allowSelfLoops") ? flagOf(options.allowSelfLoops, "options.allowSelfLoops", true, report) : void 0;
|
|
2326
2345
|
ctx.writeGraphDict(root.attributes, "attributes");
|
|
2327
2346
|
ctx.reportNodeIdFrom("graphology", "the node key");
|
|
2328
2347
|
ctx.sink.reserve(nodes.length, edges.length);
|
|
2329
2348
|
for (let i = 0; i < nodes.length; i++) {
|
|
2330
|
-
|
|
2331
|
-
const record = nodes[i];
|
|
2332
|
-
if (!isJsonObject(record)) {
|
|
2333
|
-
ctx.badElement("node", element);
|
|
2334
|
-
continue;
|
|
2335
|
-
}
|
|
2336
|
-
const id = ctx.coerceId(hasKey(record, "key") ? record.key : void 0, element);
|
|
2337
|
-
if (id === null) {
|
|
2338
|
-
ctx.countSkipped("node");
|
|
2339
|
-
continue;
|
|
2340
|
-
}
|
|
2341
|
-
pushNestedNode(ctx, id, record, "attributes", GRAPHOLOGY_NODE_KEYS, element);
|
|
2349
|
+
pushGraphologyNode(ctx, nodes[i], `nodes[${i}]`);
|
|
2342
2350
|
}
|
|
2343
2351
|
throwIfAborted(ctx.options.signal);
|
|
2344
|
-
const
|
|
2345
|
-
|
|
2346
|
-
|
|
2352
|
+
const reading = {
|
|
2353
|
+
ids: ctx.declareEdgeIds(edges, (edge) => edge.key, "key", true),
|
|
2354
|
+
type,
|
|
2355
|
+
allowSelfLoops,
|
|
2356
|
+
// what the edges do against the declared options: graphology itself refuses such a document
|
|
2357
|
+
violations: { selfLoops: 0, parallels: 0, flags: 0 },
|
|
2358
|
+
pairs: multi === false ? /* @__PURE__ */ new Set() : null
|
|
2359
|
+
};
|
|
2347
2360
|
for (let i = 0; i < edges.length; i++) {
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2361
|
+
readGraphologyEdge(ctx, reading, edges[i], `edges[${i}]`);
|
|
2362
|
+
}
|
|
2363
|
+
reportGraphologyViolations(ctx, reading.violations, type);
|
|
2364
|
+
ctx.setMeta({ dialect: "graphology", allowSelfLoops }, { declaredMultigraph: multi, ...ctx.weightOriginPatch() });
|
|
2365
|
+
}
|
|
2366
|
+
function graphologyType(ctx, options) {
|
|
2367
|
+
if (options.type === "directed" || options.type === "undirected" || options.type === "mixed") {
|
|
2368
|
+
return options.type;
|
|
2369
|
+
}
|
|
2370
|
+
if (options.type !== void 0 && options.type !== null) {
|
|
2371
|
+
ctx.report.warning(
|
|
2372
|
+
"validation-error",
|
|
2373
|
+
JSON_ISSUE.BAD_FLAG,
|
|
2374
|
+
`options.type ${describe(options.type)} is not directed, undirected or mixed; mixed assumed`,
|
|
2375
|
+
{ element: "options.type" }
|
|
2376
|
+
);
|
|
2377
|
+
}
|
|
2378
|
+
return "mixed";
|
|
2379
|
+
}
|
|
2380
|
+
function graphologyDirected(ctx, type, edges) {
|
|
2381
|
+
if (type !== "mixed") {
|
|
2382
|
+
return type === "directed";
|
|
2383
|
+
}
|
|
2384
|
+
const objects = edges.filter((edge) => isJsonObject(edge));
|
|
2385
|
+
const undirectedEdges = objects.filter((edge) => edge.undirected === true).length;
|
|
2386
|
+
return objects.length === 0 ? ctx.defaultDirected("graphology") : undirectedEdges < objects.length;
|
|
2387
|
+
}
|
|
2388
|
+
function pushGraphologyNode(ctx, record, element) {
|
|
2389
|
+
if (!isJsonObject(record)) {
|
|
2390
|
+
ctx.badElement("node", element);
|
|
2391
|
+
return;
|
|
2392
|
+
}
|
|
2393
|
+
const id = ctx.coerceId(hasKey(record, "key") ? record.key : void 0, element);
|
|
2394
|
+
if (id === null) {
|
|
2395
|
+
ctx.countSkipped("node");
|
|
2396
|
+
return;
|
|
2397
|
+
}
|
|
2398
|
+
pushNestedNode(ctx, id, record, "attributes", GRAPHOLOGY_NODE_KEYS, element);
|
|
2399
|
+
}
|
|
2400
|
+
function readGraphologyEdge(ctx, reading, record, element) {
|
|
2401
|
+
if (!isJsonObject(record)) {
|
|
2402
|
+
ctx.badElement("edge", element);
|
|
2403
|
+
return;
|
|
2404
|
+
}
|
|
2405
|
+
if (!present(record, "source") || !present(record, "target")) {
|
|
2406
|
+
ctx.missingEndpoint(element, present(record, "source") ? "target" : "source");
|
|
2407
|
+
return;
|
|
2408
|
+
}
|
|
2409
|
+
try {
|
|
2410
|
+
const u = ctx.coerceId(record.source, `${element}.source`);
|
|
2411
|
+
const v = ctx.coerceId(record.target, `${element}.target`);
|
|
2412
|
+
if (u === null || v === null) {
|
|
2413
|
+
ctx.countSkipped("edge");
|
|
2414
|
+
return;
|
|
2353
2415
|
}
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2416
|
+
const kind = graphologyEdgeKind(ctx, reading, record, element);
|
|
2417
|
+
const attributes = graphologyEdgeAttributes(ctx, record, element);
|
|
2418
|
+
const idValue = ctx.edgeIdValue(reading.ids, record.key);
|
|
2419
|
+
const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(attributes), element);
|
|
2420
|
+
ctx.setEdgeId(reading.ids, edge, idValue);
|
|
2421
|
+
ctx.writeNested(ctx.edges, edge, record, attributes, GRAPHOLOGY_EDGE_KEYS, ctx.options.weightFrom, element);
|
|
2422
|
+
if (reading.allowSelfLoops === false && u === v) {
|
|
2423
|
+
reading.violations.selfLoops++;
|
|
2357
2424
|
}
|
|
2358
|
-
|
|
2359
|
-
const
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
ctx.countSkipped("edge");
|
|
2363
|
-
continue;
|
|
2364
|
-
}
|
|
2365
|
-
let kind;
|
|
2366
|
-
if (type === "mixed") {
|
|
2367
|
-
kind = flagOf(record.undirected, `${element}.undirected`, false, report) ? "undirected" : "directed";
|
|
2368
|
-
} else {
|
|
2369
|
-
kind = type;
|
|
2370
|
-
if (typeof record.undirected === "boolean" && record.undirected !== (type === "undirected")) {
|
|
2371
|
-
violations.flags++;
|
|
2372
|
-
}
|
|
2373
|
-
}
|
|
2374
|
-
const { attributes: rawAttributes } = record;
|
|
2375
|
-
if (rawAttributes !== void 0 && rawAttributes !== null && !isJsonObject(rawAttributes)) {
|
|
2376
|
-
report.error(
|
|
2377
|
-
"validation-error",
|
|
2378
|
-
JSON_ISSUE.BAD_VALUE,
|
|
2379
|
-
`${element}: attributes must be an object, found ${describe(rawAttributes)}`,
|
|
2380
|
-
{ element }
|
|
2381
|
-
);
|
|
2382
|
-
}
|
|
2383
|
-
const attributes = isJsonObject(rawAttributes) ? rawAttributes : {};
|
|
2384
|
-
const idValue = ctx.edgeIdValue(ids, record.key);
|
|
2385
|
-
const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(attributes), element);
|
|
2386
|
-
ctx.setEdgeId(ids, edge, idValue);
|
|
2387
|
-
ctx.writeNested(ctx.edges, edge, record, attributes, GRAPHOLOGY_EDGE_KEYS, ctx.options.weightFrom, element);
|
|
2388
|
-
if (allowSelfLoops === false && u === v) {
|
|
2389
|
-
violations.selfLoops++;
|
|
2390
|
-
}
|
|
2391
|
-
if (pairs !== null) {
|
|
2392
|
-
const pair = `${kind} ${pairKey(u, v, kind === "directed")}`;
|
|
2393
|
-
violations.parallels += pairs.has(pair) ? 1 : 0;
|
|
2394
|
-
pairs.add(pair);
|
|
2395
|
-
}
|
|
2396
|
-
} catch (err) {
|
|
2397
|
-
ctx.skip(err, "edge", element);
|
|
2425
|
+
if (reading.pairs !== null) {
|
|
2426
|
+
const pair = `${kind} ${pairKey(u, v, kind === "directed")}`;
|
|
2427
|
+
reading.violations.parallels += reading.pairs.has(pair) ? 1 : 0;
|
|
2428
|
+
reading.pairs.add(pair);
|
|
2398
2429
|
}
|
|
2430
|
+
} catch (err) {
|
|
2431
|
+
ctx.skip(err, "edge", element);
|
|
2399
2432
|
}
|
|
2400
|
-
|
|
2401
|
-
|
|
2433
|
+
}
|
|
2434
|
+
function graphologyEdgeKind(ctx, reading, record, element) {
|
|
2435
|
+
const { type } = reading;
|
|
2436
|
+
if (type === "mixed") {
|
|
2437
|
+
return flagOf(record.undirected, `${element}.undirected`, false, ctx.report) ? "undirected" : "directed";
|
|
2438
|
+
}
|
|
2439
|
+
if (typeof record.undirected === "boolean" && record.undirected !== (type === "undirected")) {
|
|
2440
|
+
reading.violations.flags++;
|
|
2441
|
+
}
|
|
2442
|
+
return type;
|
|
2443
|
+
}
|
|
2444
|
+
function graphologyEdgeAttributes(ctx, record, element) {
|
|
2445
|
+
const { attributes } = record;
|
|
2446
|
+
if (attributes !== void 0 && attributes !== null && !isJsonObject(attributes)) {
|
|
2447
|
+
ctx.report.error(
|
|
2448
|
+
"validation-error",
|
|
2449
|
+
JSON_ISSUE.BAD_VALUE,
|
|
2450
|
+
`${element}: attributes must be an object, found ${describe(attributes)}`,
|
|
2451
|
+
{ element }
|
|
2452
|
+
);
|
|
2453
|
+
}
|
|
2454
|
+
return isJsonObject(attributes) ? attributes : {};
|
|
2402
2455
|
}
|
|
2403
2456
|
function reportGraphologyViolations(ctx, violations, type) {
|
|
2404
2457
|
const notes = [];
|
|
@@ -2457,23 +2510,7 @@ function importJgf(ctx, root) {
|
|
|
2457
2510
|
);
|
|
2458
2511
|
}
|
|
2459
2512
|
const nodeRecords = Array.isArray(nodesRaw) ? nodesRaw : Object.values(nodesRaw ?? {});
|
|
2460
|
-
|
|
2461
|
-
if (typeof graph.directed === "boolean") {
|
|
2462
|
-
({ directed } = graph);
|
|
2463
|
-
} else if (ctx.explicitDefaultDirected) {
|
|
2464
|
-
directed = ctx.options.defaultDirected;
|
|
2465
|
-
} else {
|
|
2466
|
-
if (graph.directed !== void 0 && graph.directed !== null) {
|
|
2467
|
-
report.warning(
|
|
2468
|
-
"validation-error",
|
|
2469
|
-
JSON_ISSUE.BAD_FLAG,
|
|
2470
|
-
`graph.directed is ${describe(graph.directed)}, not a boolean`,
|
|
2471
|
-
{ element: "graph.directed" }
|
|
2472
|
-
);
|
|
2473
|
-
}
|
|
2474
|
-
const objects = edges.filter((edge) => isJsonObject(edge));
|
|
2475
|
-
directed = objects.length === 0 || !objects.every((edge) => edge.directed === false);
|
|
2476
|
-
}
|
|
2513
|
+
const directed = jgfDirected(ctx, graph, edges);
|
|
2477
2514
|
ctx.setHeader(directed);
|
|
2478
2515
|
ctx.writeGraphDict(graph.metadata, "graph.metadata");
|
|
2479
2516
|
const shape = {
|
|
@@ -2490,44 +2527,73 @@ function importJgf(ctx, root) {
|
|
|
2490
2527
|
);
|
|
2491
2528
|
if (isJsonObject(nodesRaw)) {
|
|
2492
2529
|
for (const key of Object.keys(nodesRaw)) {
|
|
2493
|
-
|
|
2494
|
-
const record = nodesRaw[key];
|
|
2495
|
-
if (record !== null && !isJsonObject(record)) {
|
|
2496
|
-
ctx.badElement("node", element);
|
|
2497
|
-
continue;
|
|
2498
|
-
}
|
|
2499
|
-
const id = ctx.coerceId(key, element);
|
|
2500
|
-
if (id === null) {
|
|
2501
|
-
ctx.countSkipped("node");
|
|
2502
|
-
continue;
|
|
2503
|
-
}
|
|
2504
|
-
if (record !== null && hasKey(record, "id") && record.id !== key) {
|
|
2505
|
-
report.warning(
|
|
2506
|
-
"validation-error",
|
|
2507
|
-
JSON_ISSUE.INCONSISTENT,
|
|
2508
|
-
`${element}: the inner id ${describe(record.id)} differs from the key; the key is the id, the inner one is kept as id${SUFFIX.element}`,
|
|
2509
|
-
{ element }
|
|
2510
|
-
);
|
|
2511
|
-
}
|
|
2512
|
-
pushJgfNode(ctx, id, record ?? {}, labelColumn, element);
|
|
2530
|
+
pushJgfKeyedNode(ctx, key, nodesRaw[key], labelColumn);
|
|
2513
2531
|
}
|
|
2514
2532
|
} else {
|
|
2515
2533
|
for (let i = 0; i < nodeRecords.length; i++) {
|
|
2516
|
-
|
|
2517
|
-
const record = nodeRecords[i];
|
|
2518
|
-
if (!isJsonObject(record)) {
|
|
2519
|
-
ctx.badElement("node", element);
|
|
2520
|
-
continue;
|
|
2521
|
-
}
|
|
2522
|
-
const id = ctx.coerceId(hasKey(record, "id") ? record.id : void 0, element);
|
|
2523
|
-
if (id === null) {
|
|
2524
|
-
ctx.countSkipped("node");
|
|
2525
|
-
continue;
|
|
2526
|
-
}
|
|
2527
|
-
pushJgfNode(ctx, id, record, labelColumn, element);
|
|
2534
|
+
pushJgfListedNode(ctx, nodeRecords[i], labelColumn, `nodes[${i}]`);
|
|
2528
2535
|
}
|
|
2529
2536
|
}
|
|
2530
2537
|
throwIfAborted(ctx.options.signal);
|
|
2538
|
+
const writeJgfEdge = jgfEdgeWriter(ctx, edges, hyperedges);
|
|
2539
|
+
for (let i = 0; i < edges.length; i++) {
|
|
2540
|
+
readJgfEdge(ctx, edges[i], `edges[${i}]`, directed, writeJgfEdge);
|
|
2541
|
+
}
|
|
2542
|
+
importHyperedges(ctx, hyperedges, directed, writeJgfEdge);
|
|
2543
|
+
ctx.setMeta(shape, { name: label, ...ctx.weightOriginPatch() });
|
|
2544
|
+
}
|
|
2545
|
+
function jgfDirected(ctx, graph, edges) {
|
|
2546
|
+
if (typeof graph.directed === "boolean") {
|
|
2547
|
+
return graph.directed;
|
|
2548
|
+
}
|
|
2549
|
+
if (ctx.explicitDefaultDirected) {
|
|
2550
|
+
return ctx.options.defaultDirected;
|
|
2551
|
+
}
|
|
2552
|
+
if (graph.directed !== void 0 && graph.directed !== null) {
|
|
2553
|
+
ctx.report.warning(
|
|
2554
|
+
"validation-error",
|
|
2555
|
+
JSON_ISSUE.BAD_FLAG,
|
|
2556
|
+
`graph.directed is ${describe(graph.directed)}, not a boolean`,
|
|
2557
|
+
{ element: "graph.directed" }
|
|
2558
|
+
);
|
|
2559
|
+
}
|
|
2560
|
+
const objects = edges.filter((edge) => isJsonObject(edge));
|
|
2561
|
+
return objects.length === 0 || !objects.every((edge) => edge.directed === false);
|
|
2562
|
+
}
|
|
2563
|
+
function pushJgfKeyedNode(ctx, key, record, labelColumn) {
|
|
2564
|
+
const element = `nodes[${JSON.stringify(key)}]`;
|
|
2565
|
+
if (record !== null && !isJsonObject(record)) {
|
|
2566
|
+
ctx.badElement("node", element);
|
|
2567
|
+
return;
|
|
2568
|
+
}
|
|
2569
|
+
const id = ctx.coerceId(key, element);
|
|
2570
|
+
if (id === null) {
|
|
2571
|
+
ctx.countSkipped("node");
|
|
2572
|
+
return;
|
|
2573
|
+
}
|
|
2574
|
+
if (record !== null && hasKey(record, "id") && record.id !== key) {
|
|
2575
|
+
ctx.report.warning(
|
|
2576
|
+
"validation-error",
|
|
2577
|
+
JSON_ISSUE.INCONSISTENT,
|
|
2578
|
+
`${element}: the inner id ${describe(record.id)} differs from the key; the key is the id, the inner one is kept as id${SUFFIX.element}`,
|
|
2579
|
+
{ element }
|
|
2580
|
+
);
|
|
2581
|
+
}
|
|
2582
|
+
pushJgfNode(ctx, id, record ?? {}, labelColumn, element);
|
|
2583
|
+
}
|
|
2584
|
+
function pushJgfListedNode(ctx, record, labelColumn, element) {
|
|
2585
|
+
if (!isJsonObject(record)) {
|
|
2586
|
+
ctx.badElement("node", element);
|
|
2587
|
+
return;
|
|
2588
|
+
}
|
|
2589
|
+
const id = ctx.coerceId(hasKey(record, "id") ? record.id : void 0, element);
|
|
2590
|
+
if (id === null) {
|
|
2591
|
+
ctx.countSkipped("node");
|
|
2592
|
+
return;
|
|
2593
|
+
}
|
|
2594
|
+
pushJgfNode(ctx, id, record, labelColumn, element);
|
|
2595
|
+
}
|
|
2596
|
+
function jgfEdgeWriter(ctx, edges, hyperedges) {
|
|
2531
2597
|
const ids = ctx.declareEdgeIds([...edges, ...hyperedges], (edge) => edge.id, "id", false);
|
|
2532
2598
|
const relationColumn = ctx.edges.declareIf(
|
|
2533
2599
|
{ name: "relation", dtype: "string", role: "kind", nullable: true },
|
|
@@ -2537,7 +2603,7 @@ function importJgf(ctx, root) {
|
|
|
2537
2603
|
{ name: "label", dtype: "string", role: "label", nullable: true },
|
|
2538
2604
|
anyHas(edges, "label") || anyHas(hyperedges, "label")
|
|
2539
2605
|
);
|
|
2540
|
-
|
|
2606
|
+
return (record, u, v, kind, element, structural = JGF_EDGE_KEYS) => {
|
|
2541
2607
|
const { metadata } = record;
|
|
2542
2608
|
const dict = isJsonObject(metadata) ? metadata : {};
|
|
2543
2609
|
const idValue = ctx.edgeIdValue(ids, record.id);
|
|
@@ -2546,38 +2612,34 @@ function importJgf(ctx, root) {
|
|
|
2546
2612
|
ctx.writeStringField(ctx.edges, relationColumn, edge, record.relation, "relation", element);
|
|
2547
2613
|
ctx.writeStringField(ctx.edges, edgeLabelColumn, edge, record.label, "label", element);
|
|
2548
2614
|
if (metadata !== void 0 && metadata !== null && !isJsonObject(metadata)) {
|
|
2549
|
-
report.error("validation-error", JSON_ISSUE.BAD_VALUE, `${element}: metadata must be an object`, {
|
|
2615
|
+
ctx.report.error("validation-error", JSON_ISSUE.BAD_VALUE, `${element}: metadata must be an object`, {
|
|
2550
2616
|
element
|
|
2551
2617
|
});
|
|
2552
2618
|
}
|
|
2553
2619
|
ctx.writeNested(ctx.edges, edge, record, dict, structural, ctx.options.weightFrom, element);
|
|
2554
2620
|
};
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
continue;
|
|
2572
|
-
}
|
|
2573
|
-
const edgeDirected = flagOf(record.directed, `${element}.directed`, directed, report);
|
|
2574
|
-
writeJgfEdge(record, u, v, edgeDirected ? "directed" : "undirected", element);
|
|
2575
|
-
} catch (err) {
|
|
2576
|
-
ctx.skip(err, "edge", element);
|
|
2621
|
+
}
|
|
2622
|
+
function readJgfEdge(ctx, record, element, directed, writeJgfEdge) {
|
|
2623
|
+
if (!isJsonObject(record)) {
|
|
2624
|
+
ctx.badElement("edge", element);
|
|
2625
|
+
return;
|
|
2626
|
+
}
|
|
2627
|
+
if (!present(record, "source") || !present(record, "target")) {
|
|
2628
|
+
ctx.missingEndpoint(element, present(record, "source") ? "target" : "source");
|
|
2629
|
+
return;
|
|
2630
|
+
}
|
|
2631
|
+
try {
|
|
2632
|
+
const u = ctx.coerceId(record.source, `${element}.source`);
|
|
2633
|
+
const v = ctx.coerceId(record.target, `${element}.target`);
|
|
2634
|
+
if (u === null || v === null) {
|
|
2635
|
+
ctx.countSkipped("edge");
|
|
2636
|
+
return;
|
|
2577
2637
|
}
|
|
2638
|
+
const edgeDirected = flagOf(record.directed, `${element}.directed`, directed, ctx.report);
|
|
2639
|
+
writeJgfEdge(record, u, v, edgeDirected ? "directed" : "undirected", element);
|
|
2640
|
+
} catch (err) {
|
|
2641
|
+
ctx.skip(err, "edge", element);
|
|
2578
2642
|
}
|
|
2579
|
-
importHyperedges(ctx, hyperedges, directed, writeJgfEdge);
|
|
2580
|
-
ctx.setMeta(shape, { name: label, ...ctx.weightOriginPatch() });
|
|
2581
2643
|
}
|
|
2582
2644
|
function jgfGraphOf(ctx, root) {
|
|
2583
2645
|
const single = isJsonObject(root.graph);
|
|
@@ -2832,49 +2894,34 @@ function distinctMembers(ctx, members, element) {
|
|
|
2832
2894
|
return distinct;
|
|
2833
2895
|
}
|
|
2834
2896
|
function importCytoscape(ctx, root) {
|
|
2835
|
-
const {
|
|
2836
|
-
let elements;
|
|
2837
|
-
let extra;
|
|
2838
|
-
if (Array.isArray(root)) {
|
|
2839
|
-
elements = root;
|
|
2840
|
-
} else if (isJsonObject(root)) {
|
|
2841
|
-
({ elements } = root);
|
|
2842
|
-
ctx.writeGraphDict(root.data, "data");
|
|
2843
|
-
const rest = {};
|
|
2844
|
-
for (const key of Object.keys(root)) {
|
|
2845
|
-
if (key !== "elements" && key !== "data") {
|
|
2846
|
-
rest[key] = root[key];
|
|
2847
|
-
}
|
|
2848
|
-
}
|
|
2849
|
-
if (Object.keys(rest).length > 0) {
|
|
2850
|
-
extra = rest;
|
|
2851
|
-
}
|
|
2852
|
-
} else {
|
|
2853
|
-
report.fail(JSON_ISSUE.SHAPE, `a Cytoscape document must be an object or an array, found ${describe(root)}`);
|
|
2854
|
-
}
|
|
2897
|
+
const { elements, extra } = cytoscapeRoot(ctx, root);
|
|
2855
2898
|
const { nodes, edges } = cytoscapeSections(ctx, elements);
|
|
2856
2899
|
ctx.setHeader(ctx.defaultDirected("cytoscape"));
|
|
2857
2900
|
ctx.reportNodeIdFrom("cytoscape", "data.id");
|
|
2858
2901
|
ctx.sink.reserve(nodes.length, edges.length);
|
|
2859
2902
|
const dataHas = (items, key) => items.some((item) => isJsonObject(item) && isJsonObject(item.data) && item.data[key] !== void 0);
|
|
2860
|
-
const
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2903
|
+
const reading = {
|
|
2904
|
+
positionColumn: ctx.nodes.declareIf(
|
|
2905
|
+
{
|
|
2906
|
+
name: POSITION_COLUMN,
|
|
2907
|
+
dtype: "f64",
|
|
2908
|
+
components: 3,
|
|
2909
|
+
role: "position",
|
|
2910
|
+
mutable: true,
|
|
2911
|
+
nullable: true,
|
|
2912
|
+
// 3D layouts written by Cytoscape-compatible tools carry a z
|
|
2913
|
+
extra: { sourceDims: nodes.some(hasPositionZ) ? 3 : 2, units: "file" },
|
|
2914
|
+
origin: { format: "json", namespace: "cytoscape" }
|
|
2915
|
+
},
|
|
2916
|
+
anyHas(nodes, "position")
|
|
2917
|
+
),
|
|
2918
|
+
classesColumn: ctx.nodes.declareIf(
|
|
2919
|
+
{ name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
|
|
2920
|
+
anyHas(nodes, "classes")
|
|
2921
|
+
),
|
|
2922
|
+
parents: [],
|
|
2923
|
+
point: [0, 0, 0]
|
|
2924
|
+
};
|
|
2878
2925
|
const parentColumn = ctx.nodes.declareIf(
|
|
2879
2926
|
{ name: PARENT_COLUMN, dtype: "u32", role: "parent", refersTo: "node", nullable: true },
|
|
2880
2927
|
dataHas(nodes, "parent")
|
|
@@ -2883,77 +2930,104 @@ function importCytoscape(ctx, root) {
|
|
|
2883
2930
|
{ name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
|
|
2884
2931
|
anyHas(edges, "classes")
|
|
2885
2932
|
);
|
|
2886
|
-
const parents = [];
|
|
2887
|
-
const point = [0, 0, 0];
|
|
2888
2933
|
for (let i = 0; i < nodes.length; i++) {
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2934
|
+
readCytoscapeNode(ctx, reading, nodes[i], `nodes[${i}]`);
|
|
2935
|
+
}
|
|
2936
|
+
resolveCytoscapeParents(ctx, reading.parents, parentColumn);
|
|
2937
|
+
throwIfAborted(ctx.options.signal);
|
|
2938
|
+
importCytoscapeEdges(ctx, edges, edgeClassesColumn);
|
|
2939
|
+
ctx.setMeta({ dialect: "cytoscape", cytoscape: extra }, ctx.weightOriginPatch());
|
|
2940
|
+
}
|
|
2941
|
+
function cytoscapeRoot(ctx, root) {
|
|
2942
|
+
if (Array.isArray(root)) {
|
|
2943
|
+
return { elements: root };
|
|
2944
|
+
}
|
|
2945
|
+
if (!isJsonObject(root)) {
|
|
2946
|
+
ctx.report.fail(
|
|
2947
|
+
JSON_ISSUE.SHAPE,
|
|
2948
|
+
`a Cytoscape document must be an object or an array, found ${describe(root)}`
|
|
2949
|
+
);
|
|
2950
|
+
}
|
|
2951
|
+
ctx.writeGraphDict(root.data, "data");
|
|
2952
|
+
const rest = {};
|
|
2953
|
+
for (const key of Object.keys(root)) {
|
|
2954
|
+
if (key !== "elements" && key !== "data") {
|
|
2955
|
+
rest[key] = root[key];
|
|
2894
2956
|
}
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2957
|
+
}
|
|
2958
|
+
return Object.keys(rest).length > 0 ? { elements: root.elements, extra: rest } : { elements: root.elements };
|
|
2959
|
+
}
|
|
2960
|
+
function readCytoscapeNode(ctx, reading, record, element) {
|
|
2961
|
+
const { report } = ctx;
|
|
2962
|
+
if (!isJsonObject(record) || !isJsonObject(record.data)) {
|
|
2963
|
+
ctx.badElement("node", element, "an element with a data object");
|
|
2964
|
+
return;
|
|
2965
|
+
}
|
|
2966
|
+
const { data } = record;
|
|
2967
|
+
const id = ctx.coerceId(hasKey(data, "id") ? data.id : void 0, element);
|
|
2968
|
+
if (id === null) {
|
|
2969
|
+
ctx.countSkipped("node");
|
|
2970
|
+
return;
|
|
2971
|
+
}
|
|
2972
|
+
const index = ctx.pushNode(id, element);
|
|
2973
|
+
if (index < 0) {
|
|
2974
|
+
return;
|
|
2975
|
+
}
|
|
2976
|
+
if (present(data, "source") && present(data, "target")) {
|
|
2977
|
+
report.warning(
|
|
2978
|
+
"validation-error",
|
|
2979
|
+
JSON_ISSUE.INCONSISTENT,
|
|
2980
|
+
`${element} has data.source and data.target, the shape of an edge, but its section or group says node; read as a node`,
|
|
2981
|
+
{ element }
|
|
2982
|
+
);
|
|
2983
|
+
}
|
|
2984
|
+
try {
|
|
2985
|
+
writeCytoscapeData(ctx, reading, index, data, element);
|
|
2986
|
+
writeCytoscapePosition$1(ctx, reading, index, record.position, element);
|
|
2987
|
+
writeClasses(ctx, ctx.nodes, reading.classesColumn, index, record.classes, element);
|
|
2988
|
+
writeElementKeys(ctx.nodes, index, record, element);
|
|
2989
|
+
} catch (err) {
|
|
2990
|
+
report.recordError(err, { element: String(id) });
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
function writeCytoscapeData(ctx, reading, index, data, element) {
|
|
2994
|
+
for (const key of Object.keys(data)) {
|
|
2995
|
+
if (key === "id") {
|
|
2899
2996
|
continue;
|
|
2900
2997
|
}
|
|
2901
|
-
|
|
2902
|
-
|
|
2998
|
+
if (key !== "parent") {
|
|
2999
|
+
ctx.nodes.write(index, key, data[key], SUFFIX.data, element);
|
|
2903
3000
|
continue;
|
|
2904
3001
|
}
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
JSON_ISSUE.INCONSISTENT,
|
|
2909
|
-
`${element} has data.source and data.target, the shape of an edge, but its section or group says node; read as a node`,
|
|
2910
|
-
{ element }
|
|
2911
|
-
);
|
|
3002
|
+
const raw = data.parent;
|
|
3003
|
+
if (raw === void 0 || raw === null) {
|
|
3004
|
+
continue;
|
|
2912
3005
|
}
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
continue;
|
|
2917
|
-
}
|
|
2918
|
-
if (key === "parent") {
|
|
2919
|
-
const raw = data.parent;
|
|
2920
|
-
if (raw !== void 0 && raw !== null) {
|
|
2921
|
-
const parent = ctx.coerceId(raw, `${element}.data.parent`);
|
|
2922
|
-
if (parent !== null) {
|
|
2923
|
-
parents.push({ index, parent, element });
|
|
2924
|
-
}
|
|
2925
|
-
}
|
|
2926
|
-
continue;
|
|
2927
|
-
}
|
|
2928
|
-
ctx.nodes.write(index, key, data[key], SUFFIX.data, element);
|
|
2929
|
-
}
|
|
2930
|
-
const { position } = record;
|
|
2931
|
-
if (position !== void 0 && position !== null) {
|
|
2932
|
-
const z = isJsonObject(position) ? position.z ?? 0 : 0;
|
|
2933
|
-
if (isJsonObject(position) && isCoordinate(position.x) && isCoordinate(position.y) && isCoordinate(z)) {
|
|
2934
|
-
point[0] = position.x;
|
|
2935
|
-
point[1] = flipY(position.y);
|
|
2936
|
-
point[2] = z;
|
|
2937
|
-
ctx.nodes.set(positionColumn, index, point);
|
|
2938
|
-
} else {
|
|
2939
|
-
report.error(
|
|
2940
|
-
"validation-error",
|
|
2941
|
-
JSON_ISSUE.BAD_VALUE,
|
|
2942
|
-
`${element}: position must be an object with numeric x and y (and z) that are finite numbers`,
|
|
2943
|
-
{ element }
|
|
2944
|
-
);
|
|
2945
|
-
}
|
|
2946
|
-
}
|
|
2947
|
-
writeClasses(ctx, ctx.nodes, classesColumn, index, record.classes, element);
|
|
2948
|
-
writeElementKeys(ctx.nodes, index, record, element);
|
|
2949
|
-
} catch (err) {
|
|
2950
|
-
report.recordError(err, { element: String(id) });
|
|
3006
|
+
const parent = ctx.coerceId(raw, `${element}.data.parent`);
|
|
3007
|
+
if (parent !== null) {
|
|
3008
|
+
reading.parents.push({ index, parent, element });
|
|
2951
3009
|
}
|
|
2952
3010
|
}
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
3011
|
+
}
|
|
3012
|
+
function writeCytoscapePosition$1(ctx, reading, index, position, element) {
|
|
3013
|
+
if (position === void 0 || position === null) {
|
|
3014
|
+
return;
|
|
3015
|
+
}
|
|
3016
|
+
const z = isJsonObject(position) ? position.z ?? 0 : 0;
|
|
3017
|
+
if (isJsonObject(position) && isCoordinate(position.x) && isCoordinate(position.y) && isCoordinate(z)) {
|
|
3018
|
+
const { point } = reading;
|
|
3019
|
+
point[0] = position.x;
|
|
3020
|
+
point[1] = flipY(position.y);
|
|
3021
|
+
point[2] = z;
|
|
3022
|
+
ctx.nodes.set(reading.positionColumn, index, point);
|
|
3023
|
+
} else {
|
|
3024
|
+
ctx.report.error(
|
|
3025
|
+
"validation-error",
|
|
3026
|
+
JSON_ISSUE.BAD_VALUE,
|
|
3027
|
+
`${element}: position must be an object with numeric x and y (and z) that are finite numbers`,
|
|
3028
|
+
{ element }
|
|
3029
|
+
);
|
|
3030
|
+
}
|
|
2957
3031
|
}
|
|
2958
3032
|
function resolveCytoscapeParents(ctx, parents, parentColumn) {
|
|
2959
3033
|
const { report } = ctx;
|
|
@@ -3028,27 +3102,31 @@ function importCytoscapeEdges(ctx, edges, edgeClassesColumn) {
|
|
|
3028
3102
|
ctx.missingEndpoint(element, `data.${present(data, "source") ? "target" : "source"}`);
|
|
3029
3103
|
continue;
|
|
3030
3104
|
}
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
ctx.
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3105
|
+
importCytoscapeEdge(ctx, { ids, kind, edgeClassesColumn }, record, data, element);
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
3108
|
+
function importCytoscapeEdge(ctx, shared, record, data, element) {
|
|
3109
|
+
const { ids, kind, edgeClassesColumn } = shared;
|
|
3110
|
+
try {
|
|
3111
|
+
const u = ctx.coerceId(data.source, `${element}.data.source`);
|
|
3112
|
+
const v = ctx.coerceId(data.target, `${element}.data.target`);
|
|
3113
|
+
if (u === null || v === null) {
|
|
3114
|
+
ctx.countSkipped("edge");
|
|
3115
|
+
return;
|
|
3116
|
+
}
|
|
3117
|
+
const idValue = ctx.edgeIdValue(ids, data.id);
|
|
3118
|
+
const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(data), element);
|
|
3119
|
+
ctx.setEdgeId(ids, edge, idValue);
|
|
3120
|
+
const { weightFrom } = ctx.options;
|
|
3121
|
+
for (const key of Object.keys(data)) {
|
|
3122
|
+
if (key !== "id" && key !== "source" && key !== "target" && key !== weightFrom) {
|
|
3123
|
+
ctx.edges.write(edge, key, data[key], SUFFIX.data, element);
|
|
3046
3124
|
}
|
|
3047
|
-
writeClasses(ctx, ctx.edges, edgeClassesColumn, edge, record.classes, element);
|
|
3048
|
-
writeElementKeys(ctx.edges, edge, record, element);
|
|
3049
|
-
} catch (err) {
|
|
3050
|
-
ctx.skip(err, "edge", element);
|
|
3051
3125
|
}
|
|
3126
|
+
writeClasses(ctx, ctx.edges, edgeClassesColumn, edge, record.classes, element);
|
|
3127
|
+
writeElementKeys(ctx.edges, edge, record, element);
|
|
3128
|
+
} catch (err) {
|
|
3129
|
+
ctx.skip(err, "edge", element);
|
|
3052
3130
|
}
|
|
3053
3131
|
}
|
|
3054
3132
|
function cytoscapeSections(ctx, elements) {
|
|
@@ -3566,21 +3644,7 @@ function writeNode(ctx, columns, vocabulary, record, row, element) {
|
|
|
3566
3644
|
}
|
|
3567
3645
|
function writeMeta(ctx, columns, vocabulary, meta, row, unrecognized, element) {
|
|
3568
3646
|
const path = `${element}.meta`;
|
|
3569
|
-
|
|
3570
|
-
if (isJsonObject(definition)) {
|
|
3571
|
-
const xrefs2 = strings$1(ctx, definition.xrefs, `${path}.definition.xrefs`);
|
|
3572
|
-
if (typeof definition.val === "string") {
|
|
3573
|
-
columns.node("def", row, definition.val);
|
|
3574
|
-
columns.node("def.xrefs", row, xrefs2);
|
|
3575
|
-
} else {
|
|
3576
|
-
badValue(ctx, `${path}.definition has no string val; it is dropped`, `${path}.definition.val`);
|
|
3577
|
-
}
|
|
3578
|
-
if (definition.meta !== void 0) {
|
|
3579
|
-
unrecognized["meta.definition.meta"] = definition.meta;
|
|
3580
|
-
}
|
|
3581
|
-
} else if (definition !== void 0 && definition !== null) {
|
|
3582
|
-
badValue(ctx, `${path}.definition must be an object with a val; it is dropped`, `${path}.definition`);
|
|
3583
|
-
}
|
|
3647
|
+
writeDefinition(ctx, columns, meta.definition, row, unrecognized, path);
|
|
3584
3648
|
const comments = strings$1(ctx, meta.comments, `${path}.comments`);
|
|
3585
3649
|
if (comments.length > 0) {
|
|
3586
3650
|
columns.node("comment", row, comments.join("\n"));
|
|
@@ -3609,6 +3673,22 @@ function writeMeta(ctx, columns, vocabulary, meta, row, unrecognized, element) {
|
|
|
3609
3673
|
}
|
|
3610
3674
|
}
|
|
3611
3675
|
}
|
|
3676
|
+
function writeDefinition(ctx, columns, definition, row, unrecognized, path) {
|
|
3677
|
+
if (isJsonObject(definition)) {
|
|
3678
|
+
const xrefs = strings$1(ctx, definition.xrefs, `${path}.definition.xrefs`);
|
|
3679
|
+
if (typeof definition.val === "string") {
|
|
3680
|
+
columns.node("def", row, definition.val);
|
|
3681
|
+
columns.node("def.xrefs", row, xrefs);
|
|
3682
|
+
} else {
|
|
3683
|
+
badValue(ctx, `${path}.definition has no string val; it is dropped`, `${path}.definition.val`);
|
|
3684
|
+
}
|
|
3685
|
+
if (definition.meta !== void 0) {
|
|
3686
|
+
unrecognized["meta.definition.meta"] = definition.meta;
|
|
3687
|
+
}
|
|
3688
|
+
} else if (definition !== void 0 && definition !== null) {
|
|
3689
|
+
badValue(ctx, `${path}.definition must be an object with a val; it is dropped`, `${path}.definition`);
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3612
3692
|
function synonymsOf(ctx, vocabulary, value, path) {
|
|
3613
3693
|
if (value === void 0 || value === null) {
|
|
3614
3694
|
return [];
|
|
@@ -5782,7 +5862,6 @@ function* writeCytoscape(snapshot, p) {
|
|
|
5782
5862
|
const c = { w: new JsonWriter(resolved.indent), ids: snapshot.ids, nonfinite: { count: 0 } };
|
|
5783
5863
|
const { w } = c;
|
|
5784
5864
|
const parentSlots = /* @__PURE__ */ new Set(["parent"]);
|
|
5785
|
-
const positionSlots = /* @__PURE__ */ new Set(["cytoscapePosition"]);
|
|
5786
5865
|
w.open("{");
|
|
5787
5866
|
w.key("elements");
|
|
5788
5867
|
w.open("{");
|
|
@@ -5798,17 +5877,7 @@ function* writeCytoscape(snapshot, p) {
|
|
|
5798
5877
|
writeSlots(c, p.nodes, i, parentSlots);
|
|
5799
5878
|
writeSlots(c, p.nodes, i, ATTRIBUTE_SLOTS);
|
|
5800
5879
|
w.close("}");
|
|
5801
|
-
|
|
5802
|
-
if (positionSlots.has(item.slot) && item.column.isSet(i)) {
|
|
5803
|
-
const value = item.column.value(i);
|
|
5804
|
-
const f32 = item.column.dtype === "f32";
|
|
5805
|
-
w.key("position");
|
|
5806
|
-
w.open("{");
|
|
5807
|
-
w.member("x", numberText(value[0], f32, c.nonfinite));
|
|
5808
|
-
w.member("y", numberText(flipY(value[1]), f32, c.nonfinite));
|
|
5809
|
-
w.close("}");
|
|
5810
|
-
}
|
|
5811
|
-
}
|
|
5880
|
+
writeCytoscapePosition(c, p.nodes, i);
|
|
5812
5881
|
writeSlots(c, p.nodes, i, ELEMENT_SLOTS);
|
|
5813
5882
|
w.close("}");
|
|
5814
5883
|
yield w.take();
|
|
@@ -5845,17 +5914,34 @@ function* writeCytoscape(snapshot, p) {
|
|
|
5845
5914
|
w.key("data");
|
|
5846
5915
|
writeGraphObject(c, p);
|
|
5847
5916
|
}
|
|
5848
|
-
|
|
5849
|
-
if (extra !== void 0) {
|
|
5850
|
-
for (const key of Object.keys(extra)) {
|
|
5851
|
-
if (key !== "elements" && key !== "data") {
|
|
5852
|
-
w.member(key, valueText(extra[key], false, c.nonfinite));
|
|
5853
|
-
}
|
|
5854
|
-
}
|
|
5855
|
-
}
|
|
5917
|
+
writeCytoscapeExtra(c, resolved.shape.cytoscape);
|
|
5856
5918
|
w.close("}");
|
|
5857
5919
|
yield w.take();
|
|
5858
5920
|
}
|
|
5921
|
+
function writeCytoscapePosition(c, items, i) {
|
|
5922
|
+
const { w } = c;
|
|
5923
|
+
for (const item of items) {
|
|
5924
|
+
if (item.slot === "cytoscapePosition" && item.column.isSet(i)) {
|
|
5925
|
+
const value = item.column.value(i);
|
|
5926
|
+
const f32 = item.column.dtype === "f32";
|
|
5927
|
+
w.key("position");
|
|
5928
|
+
w.open("{");
|
|
5929
|
+
w.member("x", numberText(value[0], f32, c.nonfinite));
|
|
5930
|
+
w.member("y", numberText(flipY(value[1]), f32, c.nonfinite));
|
|
5931
|
+
w.close("}");
|
|
5932
|
+
}
|
|
5933
|
+
}
|
|
5934
|
+
}
|
|
5935
|
+
function writeCytoscapeExtra(c, extra) {
|
|
5936
|
+
if (extra === void 0) {
|
|
5937
|
+
return;
|
|
5938
|
+
}
|
|
5939
|
+
for (const key of Object.keys(extra)) {
|
|
5940
|
+
if (key !== "elements" && key !== "data") {
|
|
5941
|
+
c.w.member(key, valueText(extra[key], false, c.nonfinite));
|
|
5942
|
+
}
|
|
5943
|
+
}
|
|
5944
|
+
}
|
|
5859
5945
|
function edgeIdGenerator(snapshot, p) {
|
|
5860
5946
|
const used = /* @__PURE__ */ new Set();
|
|
5861
5947
|
for (let i = 0; i < snapshot.nodeCount; i++) {
|
|
@@ -5946,4 +6032,4 @@ export {
|
|
|
5946
6032
|
rankFormats as r,
|
|
5947
6033
|
sniffFormat as s
|
|
5948
6034
|
};
|
|
5949
|
-
//# sourceMappingURL=exporter-
|
|
6035
|
+
//# sourceMappingURL=exporter-BqtmlxNr.js.map
|