@neo4j-ndl/react-graph 1.3.32 → 1.3.34
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/lib/cjs/stories/graph-visualization-color-range-styling.story.js +82 -0
- package/lib/cjs/stories/graph-visualization-color-range-styling.story.js.map +1 -0
- package/lib/cjs/stories/index.js +5 -1
- package/lib/cjs/stories/index.js.map +1 -1
- package/lib/cjs/styling/color-interpolation.js +35 -0
- package/lib/cjs/styling/color-interpolation.js.map +1 -0
- package/lib/cjs/styling/compile-graph-styles.js +69 -2
- package/lib/cjs/styling/compile-graph-styles.js.map +1 -1
- package/lib/cjs/styling/style-types.js +17 -1
- package/lib/cjs/styling/style-types.js.map +1 -1
- package/lib/esm/stories/graph-visualization-color-range-styling.story.js +79 -0
- package/lib/esm/stories/graph-visualization-color-range-styling.story.js.map +1 -0
- package/lib/esm/stories/index.js +3 -0
- package/lib/esm/stories/index.js.map +1 -1
- package/lib/esm/styling/color-interpolation.js +31 -0
- package/lib/esm/styling/color-interpolation.js.map +1 -0
- package/lib/esm/styling/compile-graph-styles.js +69 -2
- package/lib/esm/styling/compile-graph-styles.js.map +1 -1
- package/lib/esm/styling/style-types.js +16 -0
- package/lib/esm/styling/style-types.js.map +1 -1
- package/lib/types/stories/graph-visualization-color-range-styling.story.d.ts +25 -0
- package/lib/types/stories/graph-visualization-color-range-styling.story.d.ts.map +1 -0
- package/lib/types/stories/index.d.ts +2 -0
- package/lib/types/stories/index.d.ts.map +1 -1
- package/lib/types/styling/color-interpolation.d.ts +24 -0
- package/lib/types/styling/color-interpolation.d.ts.map +1 -0
- package/lib/types/styling/compile-graph-styles.d.ts.map +1 -1
- package/lib/types/styling/style-types.d.ts +34 -0
- package/lib/types/styling/style-types.d.ts.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.colorRangeStyleRules = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) "Neo4j"
|
|
8
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
9
|
+
*
|
|
10
|
+
* This file is part of Neo4j.
|
|
11
|
+
*
|
|
12
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
13
|
+
* it under the terms of the GNU General Public License as published by
|
|
14
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
15
|
+
* (at your option) any later version.
|
|
16
|
+
*
|
|
17
|
+
* This program is distributed in the hope that it will be useful,
|
|
18
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20
|
+
* GNU General Public License for more details.
|
|
21
|
+
*
|
|
22
|
+
* You should have received a copy of the GNU General Public License
|
|
23
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
24
|
+
*/
|
|
25
|
+
const graph_visualization_1 = require("../graph-visualization");
|
|
26
|
+
const story_data_1 = require("./story-data");
|
|
27
|
+
const pokemonRules = [
|
|
28
|
+
{
|
|
29
|
+
match: { label: 'Pokemon' },
|
|
30
|
+
apply: {
|
|
31
|
+
colorRange: {
|
|
32
|
+
onProperty: 'level',
|
|
33
|
+
minValue: 1,
|
|
34
|
+
minColor: '#3498db',
|
|
35
|
+
midValue: 45,
|
|
36
|
+
midColor: '#f1c40f',
|
|
37
|
+
maxValue: 88,
|
|
38
|
+
maxColor: '#e74c3c',
|
|
39
|
+
},
|
|
40
|
+
captions: [
|
|
41
|
+
{ value: { property: 'name' }, styles: ['bold'] },
|
|
42
|
+
{ value: ' Lv', styles: [] },
|
|
43
|
+
{ value: { property: 'level' }, styles: [] },
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
const caughtRelRules = [
|
|
49
|
+
{
|
|
50
|
+
match: { reltype: 'CAUGHT' },
|
|
51
|
+
apply: {
|
|
52
|
+
colorRange: {
|
|
53
|
+
onProperty: 'level',
|
|
54
|
+
minValue: 1,
|
|
55
|
+
minColor: '#00d2ff',
|
|
56
|
+
maxValue: 40,
|
|
57
|
+
maxColor: '#ff2d78',
|
|
58
|
+
},
|
|
59
|
+
width: 4,
|
|
60
|
+
captions: [
|
|
61
|
+
{ value: 'Caught @ Lv', styles: [] },
|
|
62
|
+
{ value: { property: 'level' }, styles: ['bold'] },
|
|
63
|
+
],
|
|
64
|
+
captionSize: 1.5,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
const otherNodeRules = [
|
|
69
|
+
{ match: { label: 'Trainer' }, apply: { color: '#95a5a6' } },
|
|
70
|
+
{ match: { label: 'Type' }, apply: { color: '#bdc3c7' } },
|
|
71
|
+
{ match: { label: 'Gym' }, apply: { color: '#bdc3c7' } },
|
|
72
|
+
];
|
|
73
|
+
exports.colorRangeStyleRules = [
|
|
74
|
+
...pokemonRules,
|
|
75
|
+
...caughtRelRules,
|
|
76
|
+
...otherNodeRules,
|
|
77
|
+
];
|
|
78
|
+
const Component = () => {
|
|
79
|
+
return ((0, jsx_runtime_1.jsx)("div", { style: { height: '600px' }, children: (0, jsx_runtime_1.jsx)(graph_visualization_1.GraphVisualization, { nodes: story_data_1.advancedStoryGraph.nodes, rels: story_data_1.advancedStoryGraph.rels, className: story_data_1.containerClasses, nvlStyleRules: exports.colorRangeStyleRules }) }));
|
|
80
|
+
};
|
|
81
|
+
exports.default = Component;
|
|
82
|
+
//# sourceMappingURL=graph-visualization-color-range-styling.story.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-visualization-color-range-styling.story.js","sourceRoot":"","sources":["../../../src/stories/graph-visualization-color-range-styling.story.tsx"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,gEAA4D;AAE5D,6CAAoE;AAEpE,MAAM,YAAY,GAAgB;IAChC;QACE,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;QAC3B,KAAK,EAAE;YACL,UAAU,EAAE;gBACV,UAAU,EAAE,OAAO;gBACnB,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE,EAAE;gBACZ,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE,EAAE;gBACZ,QAAQ,EAAE,SAAS;aACpB;YACD,QAAQ,EAAE;gBACR,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;gBACjD,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC5B,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;aAC7C;SACF;KACF;CACF,CAAC;AAEF,MAAM,cAAc,GAAgB;IAClC;QACE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE;QAC5B,KAAK,EAAE;YACL,UAAU,EAAE;gBACV,UAAU,EAAE,OAAO;gBACnB,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE,EAAE;gBACZ,QAAQ,EAAE,SAAS;aACpB;YACD,KAAK,EAAE,CAAC;YACR,QAAQ,EAAE;gBACR,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE;gBACpC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;aACnD;YACD,WAAW,EAAE,GAAG;SACjB;KACF;CACF,CAAC;AAEF,MAAM,cAAc,GAAgB;IAClC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;IAC5D,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;IACzD,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;CACzD,CAAC;AAEW,QAAA,oBAAoB,GAAgB;IAC/C,GAAG,YAAY;IACf,GAAG,cAAc;IACjB,GAAG,cAAc;CAClB,CAAC;AAEF,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,CACL,gCAAK,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,YAC7B,uBAAC,wCAAkB,IACjB,KAAK,EAAE,+BAAkB,CAAC,KAAK,EAC/B,IAAI,EAAE,+BAAkB,CAAC,IAAI,EAC7B,SAAS,EAAE,6BAAgB,EAC3B,aAAa,EAAE,4BAAoB,GACnC,GACE,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,SAAS,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { GraphVisualization } from '../graph-visualization';\nimport { type StyleRule } from '../styling/style-types';\nimport { advancedStoryGraph, containerClasses } from './story-data';\n\nconst pokemonRules: StyleRule[] = [\n {\n match: { label: 'Pokemon' },\n apply: {\n colorRange: {\n onProperty: 'level',\n minValue: 1,\n minColor: '#3498db',\n midValue: 45,\n midColor: '#f1c40f',\n maxValue: 88,\n maxColor: '#e74c3c',\n },\n captions: [\n { value: { property: 'name' }, styles: ['bold'] },\n { value: ' Lv', styles: [] },\n { value: { property: 'level' }, styles: [] },\n ],\n },\n },\n];\n\nconst caughtRelRules: StyleRule[] = [\n {\n match: { reltype: 'CAUGHT' },\n apply: {\n colorRange: {\n onProperty: 'level',\n minValue: 1,\n minColor: '#00d2ff',\n maxValue: 40,\n maxColor: '#ff2d78',\n },\n width: 4,\n captions: [\n { value: 'Caught @ Lv', styles: [] },\n { value: { property: 'level' }, styles: ['bold'] },\n ],\n captionSize: 1.5,\n },\n },\n];\n\nconst otherNodeRules: StyleRule[] = [\n { match: { label: 'Trainer' }, apply: { color: '#95a5a6' } },\n { match: { label: 'Type' }, apply: { color: '#bdc3c7' } },\n { match: { label: 'Gym' }, apply: { color: '#bdc3c7' } },\n];\n\nexport const colorRangeStyleRules: StyleRule[] = [\n ...pokemonRules,\n ...caughtRelRules,\n ...otherNodeRules,\n];\n\nconst Component = () => {\n return (\n <div style={{ height: '600px' }}>\n <GraphVisualization\n nodes={advancedStoryGraph.nodes}\n rels={advancedStoryGraph.rels}\n className={containerClasses}\n nvlStyleRules={colorRangeStyleRules}\n />\n </div>\n );\n};\n\nexport default Component;\n"]}
|
package/lib/cjs/stories/index.js
CHANGED
|
@@ -23,7 +23,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
23
23
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.PreviewGraphVisualizationSrc = exports.GraphVisualizationRuleBasedStylingAdvancedSrc = exports.GraphVisualizationSearchSrc = exports.GraphVisualizationRuleBasedStylingSrc = exports.GraphVisualizationSimpleStylingSrc = exports.GraphVisualizationHighlightingSrc = exports.GraphVisualizationCustomSrc = exports.GraphVisualizationMaximalistSrc = exports.GraphVisualizationBarebonesSrc = exports.GraphVisualizationDefaultSrc = exports.PreviewGraphVisualization = exports.GraphVisualizationSimpleStyling = exports.GraphVisualizationSearch = exports.GraphVisualizationRuleBasedStyling = exports.GraphVisualizationRuleBasedStylingAdvanced = exports.GraphVisualizationMaximalist = exports.GraphVisualizationHighlighting = exports.GraphVisualizationDefault = exports.GraphVisualizationCustom = exports.GraphVisualizationBarebones = void 0;
|
|
26
|
+
exports.PreviewGraphVisualizationSrc = exports.GraphVisualizationColorRangeStylingSrc = exports.GraphVisualizationRuleBasedStylingAdvancedSrc = exports.GraphVisualizationSearchSrc = exports.GraphVisualizationRuleBasedStylingSrc = exports.GraphVisualizationSimpleStylingSrc = exports.GraphVisualizationHighlightingSrc = exports.GraphVisualizationCustomSrc = exports.GraphVisualizationMaximalistSrc = exports.GraphVisualizationBarebonesSrc = exports.GraphVisualizationDefaultSrc = exports.PreviewGraphVisualization = exports.GraphVisualizationSimpleStyling = exports.GraphVisualizationSearch = exports.GraphVisualizationRuleBasedStyling = exports.GraphVisualizationRuleBasedStylingAdvanced = exports.GraphVisualizationColorRangeStyling = exports.GraphVisualizationMaximalist = exports.GraphVisualizationHighlighting = exports.GraphVisualizationDefault = exports.GraphVisualizationCustom = exports.GraphVisualizationBarebones = void 0;
|
|
27
27
|
var graph_visualization_barebones_story_1 = require("./graph-visualization-barebones.story");
|
|
28
28
|
Object.defineProperty(exports, "GraphVisualizationBarebones", { enumerable: true, get: function () { return __importDefault(graph_visualization_barebones_story_1).default; } });
|
|
29
29
|
var graph_visualization_custom_story_1 = require("./graph-visualization-custom.story");
|
|
@@ -34,6 +34,8 @@ var graph_visualization_highlighting_story_1 = require("./graph-visualization-hi
|
|
|
34
34
|
Object.defineProperty(exports, "GraphVisualizationHighlighting", { enumerable: true, get: function () { return __importDefault(graph_visualization_highlighting_story_1).default; } });
|
|
35
35
|
var graph_visualization_maximalist_story_1 = require("./graph-visualization-maximalist.story");
|
|
36
36
|
Object.defineProperty(exports, "GraphVisualizationMaximalist", { enumerable: true, get: function () { return __importDefault(graph_visualization_maximalist_story_1).default; } });
|
|
37
|
+
var graph_visualization_color_range_styling_story_1 = require("./graph-visualization-color-range-styling.story");
|
|
38
|
+
Object.defineProperty(exports, "GraphVisualizationColorRangeStyling", { enumerable: true, get: function () { return __importDefault(graph_visualization_color_range_styling_story_1).default; } });
|
|
37
39
|
var graph_visualization_rule_based_styling_advanced_story_1 = require("./graph-visualization-rule-based-styling-advanced.story");
|
|
38
40
|
Object.defineProperty(exports, "GraphVisualizationRuleBasedStylingAdvanced", { enumerable: true, get: function () { return __importDefault(graph_visualization_rule_based_styling_advanced_story_1).default; } });
|
|
39
41
|
var graph_visualization_rule_based_styling_story_1 = require("./graph-visualization-rule-based-styling.story");
|
|
@@ -46,6 +48,7 @@ var preview_graph_visualization_story_1 = require("./preview-graph-visualization
|
|
|
46
48
|
Object.defineProperty(exports, "PreviewGraphVisualization", { enumerable: true, get: function () { return __importDefault(preview_graph_visualization_story_1).default; } });
|
|
47
49
|
const utils_1 = require("../utils");
|
|
48
50
|
const graph_visualization_barebones_story_raw_1 = __importDefault(require("./graph-visualization-barebones.story?raw"));
|
|
51
|
+
const graph_visualization_color_range_styling_story_raw_1 = __importDefault(require("./graph-visualization-color-range-styling.story?raw"));
|
|
49
52
|
const graph_visualization_custom_story_raw_1 = __importDefault(require("./graph-visualization-custom.story?raw"));
|
|
50
53
|
const graph_visualization_default_story_raw_1 = __importDefault(require("./graph-visualization-default.story?raw"));
|
|
51
54
|
const graph_visualization_highlighting_story_raw_1 = __importDefault(require("./graph-visualization-highlighting.story?raw"));
|
|
@@ -64,5 +67,6 @@ exports.GraphVisualizationSimpleStylingSrc = (0, utils_1.removeLicenseHeader)(gr
|
|
|
64
67
|
exports.GraphVisualizationRuleBasedStylingSrc = (0, utils_1.removeLicenseHeader)(graph_visualization_rule_based_styling_story_raw_1.default);
|
|
65
68
|
exports.GraphVisualizationSearchSrc = (0, utils_1.removeLicenseHeader)(graph_visualization_search_story_raw_1.default);
|
|
66
69
|
exports.GraphVisualizationRuleBasedStylingAdvancedSrc = (0, utils_1.removeLicenseHeader)(graph_visualization_rule_based_styling_advanced_story_raw_1.default);
|
|
70
|
+
exports.GraphVisualizationColorRangeStylingSrc = (0, utils_1.removeLicenseHeader)(graph_visualization_color_range_styling_story_raw_1.default);
|
|
67
71
|
exports.PreviewGraphVisualizationSrc = (0, utils_1.removeLicenseHeader)(preview_graph_visualization_story_raw_1.default);
|
|
68
72
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/stories/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;;;;AAEH,6FAA+F;AAAtF,mKAAA,OAAO,OAA+B;AAC/C,uFAAyF;AAAhF,6JAAA,OAAO,OAA4B;AAC5C,yFAA2F;AAAlF,+JAAA,OAAO,OAA6B;AAC7C,mGAAqG;AAA5F,yKAAA,OAAO,OAAkC;AAClD,+FAAiG;AAAxF,qKAAA,OAAO,OAAgC;AAChD,iIAAgI;AAAvH,oMAAA,OAAO,OAA8C;AAC9D,+GAA+G;AAAtG,mLAAA,OAAO,OAAsC;AACtD,uFAAyF;AAAhF,6JAAA,OAAO,OAA4B;AAC5C,uGAAwG;AAA/F,4KAAA,OAAO,OAAmC;AACnD,yFAA2F;AAAlF,+JAAA,OAAO,OAA6B;AAE7C,oCAA+C;AAC/C,wHAA0F;AAC1F,kHAAoF;AACpF,oHAAsF;AACtF,8HAAgG;AAChG,0HAA4F;AAC5F,0IAA0G;AAC1G,4JAA2H;AAC3H,kHAAoF;AACpF,kIAAmG;AACnG,oHAAsF;AAEzE,QAAA,4BAA4B,GAAG,IAAA,2BAAmB,EAC7D,+CAA+B,CAChC,CAAC;AAEW,QAAA,8BAA8B,GAAG,IAAA,2BAAmB,EAC/D,iDAAiC,CAClC,CAAC;AAEW,QAAA,+BAA+B,GAAG,IAAA,2BAAmB,EAChE,kDAAkC,CACnC,CAAC;AAEW,QAAA,2BAA2B,GAAG,IAAA,2BAAmB,EAC5D,8CAA8B,CAC/B,CAAC;AAEW,QAAA,iCAAiC,GAAG,IAAA,2BAAmB,EAClE,oDAAoC,CACrC,CAAC;AAEW,QAAA,kCAAkC,GAAG,IAAA,2BAAmB,EACnE,sDAAqC,CACtC,CAAC;AAEW,QAAA,qCAAqC,GAAG,IAAA,2BAAmB,EACtE,0DAAwC,CACzC,CAAC;AAEW,QAAA,2BAA2B,GAAG,IAAA,2BAAmB,EAC5D,8CAA8B,CAC/B,CAAC;AAEW,QAAA,6CAA6C,GACxD,IAAA,2BAAmB,EAAC,mEAAgD,CAAC,CAAC;AAE3D,QAAA,4BAA4B,GAAG,IAAA,2BAAmB,EAC7D,+CAA+B,CAChC,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nexport { default as GraphVisualizationBarebones } from './graph-visualization-barebones.story';\nexport { default as GraphVisualizationCustom } from './graph-visualization-custom.story';\nexport { default as GraphVisualizationDefault } from './graph-visualization-default.story';\nexport { default as GraphVisualizationHighlighting } from './graph-visualization-highlighting.story';\nexport { default as GraphVisualizationMaximalist } from './graph-visualization-maximalist.story';\nexport { default as GraphVisualizationRuleBasedStylingAdvanced } from './graph-visualization-rule-based-styling-advanced.story';\nexport { default as GraphVisualizationRuleBasedStyling } from './graph-visualization-rule-based-styling.story';\nexport { default as GraphVisualizationSearch } from './graph-visualization-search.story';\nexport { default as GraphVisualizationSimpleStyling } from './graph-visualization-simple-styling.story';\nexport { default as PreviewGraphVisualization } from './preview-graph-visualization.story';\n\nimport { removeLicenseHeader } from '../utils';\nimport GraphVisualizationBarebonesSrcRaw from './graph-visualization-barebones.story?raw';\nimport GraphVisualizationCustomSrcRaw from './graph-visualization-custom.story?raw';\nimport GraphVisualizationDefaultSrcRaw from './graph-visualization-default.story?raw';\nimport GraphVisualizationHighlightingSrcRaw from './graph-visualization-highlighting.story?raw';\nimport GraphVisualizationMaximalistSrcRaw from './graph-visualization-maximalist.story?raw';\nimport GraphVisualizationRuleBasedStylingSrcRaw from './graph-visualization-rule-based-styling.story?raw';\nimport GraphVisualizationRuleBasedStylingAdvancedSrcRaw from './graph-visualization-rule-based-styling-advanced.story?raw';\nimport GraphVisualizationSearchSrcRaw from './graph-visualization-search.story?raw';\nimport GraphVisualizationSimpleStylingSrcRaw from './graph-visualization-simple-styling.story?raw';\nimport PreviewGraphVisualizationSrcRaw from './preview-graph-visualization.story?raw';\n\nexport const GraphVisualizationDefaultSrc = removeLicenseHeader(\n GraphVisualizationDefaultSrcRaw,\n);\n\nexport const GraphVisualizationBarebonesSrc = removeLicenseHeader(\n GraphVisualizationBarebonesSrcRaw,\n);\n\nexport const GraphVisualizationMaximalistSrc = removeLicenseHeader(\n GraphVisualizationMaximalistSrcRaw,\n);\n\nexport const GraphVisualizationCustomSrc = removeLicenseHeader(\n GraphVisualizationCustomSrcRaw,\n);\n\nexport const GraphVisualizationHighlightingSrc = removeLicenseHeader(\n GraphVisualizationHighlightingSrcRaw,\n);\n\nexport const GraphVisualizationSimpleStylingSrc = removeLicenseHeader(\n GraphVisualizationSimpleStylingSrcRaw,\n);\n\nexport const GraphVisualizationRuleBasedStylingSrc = removeLicenseHeader(\n GraphVisualizationRuleBasedStylingSrcRaw,\n);\n\nexport const GraphVisualizationSearchSrc = removeLicenseHeader(\n GraphVisualizationSearchSrcRaw,\n);\n\nexport const GraphVisualizationRuleBasedStylingAdvancedSrc =\n removeLicenseHeader(GraphVisualizationRuleBasedStylingAdvancedSrcRaw);\n\nexport const PreviewGraphVisualizationSrc = removeLicenseHeader(\n PreviewGraphVisualizationSrcRaw,\n);\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/stories/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;;;;AAEH,6FAA+F;AAAtF,mKAAA,OAAO,OAA+B;AAC/C,uFAAyF;AAAhF,6JAAA,OAAO,OAA4B;AAC5C,yFAA2F;AAAlF,+JAAA,OAAO,OAA6B;AAC7C,mGAAqG;AAA5F,yKAAA,OAAO,OAAkC;AAClD,+FAAiG;AAAxF,qKAAA,OAAO,OAAgC;AAChD,iHAAiH;AAAxG,qLAAA,OAAO,OAAuC;AACvD,iIAAgI;AAAvH,oMAAA,OAAO,OAA8C;AAC9D,+GAA+G;AAAtG,mLAAA,OAAO,OAAsC;AACtD,uFAAyF;AAAhF,6JAAA,OAAO,OAA4B;AAC5C,uGAAwG;AAA/F,4KAAA,OAAO,OAAmC;AACnD,yFAA2F;AAAlF,+JAAA,OAAO,OAA6B;AAE7C,oCAA+C;AAC/C,wHAA0F;AAC1F,4IAAyG;AACzG,kHAAoF;AACpF,oHAAsF;AACtF,8HAAgG;AAChG,0HAA4F;AAC5F,0IAA0G;AAC1G,4JAA2H;AAC3H,kHAAoF;AACpF,kIAAmG;AACnG,oHAAsF;AAEzE,QAAA,4BAA4B,GAAG,IAAA,2BAAmB,EAC7D,+CAA+B,CAChC,CAAC;AAEW,QAAA,8BAA8B,GAAG,IAAA,2BAAmB,EAC/D,iDAAiC,CAClC,CAAC;AAEW,QAAA,+BAA+B,GAAG,IAAA,2BAAmB,EAChE,kDAAkC,CACnC,CAAC;AAEW,QAAA,2BAA2B,GAAG,IAAA,2BAAmB,EAC5D,8CAA8B,CAC/B,CAAC;AAEW,QAAA,iCAAiC,GAAG,IAAA,2BAAmB,EAClE,oDAAoC,CACrC,CAAC;AAEW,QAAA,kCAAkC,GAAG,IAAA,2BAAmB,EACnE,sDAAqC,CACtC,CAAC;AAEW,QAAA,qCAAqC,GAAG,IAAA,2BAAmB,EACtE,0DAAwC,CACzC,CAAC;AAEW,QAAA,2BAA2B,GAAG,IAAA,2BAAmB,EAC5D,8CAA8B,CAC/B,CAAC;AAEW,QAAA,6CAA6C,GACxD,IAAA,2BAAmB,EAAC,mEAAgD,CAAC,CAAC;AAE3D,QAAA,sCAAsC,GAAG,IAAA,2BAAmB,EACvE,2DAAsC,CACvC,CAAC;AAEW,QAAA,4BAA4B,GAAG,IAAA,2BAAmB,EAC7D,+CAA+B,CAChC,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nexport { default as GraphVisualizationBarebones } from './graph-visualization-barebones.story';\nexport { default as GraphVisualizationCustom } from './graph-visualization-custom.story';\nexport { default as GraphVisualizationDefault } from './graph-visualization-default.story';\nexport { default as GraphVisualizationHighlighting } from './graph-visualization-highlighting.story';\nexport { default as GraphVisualizationMaximalist } from './graph-visualization-maximalist.story';\nexport { default as GraphVisualizationColorRangeStyling } from './graph-visualization-color-range-styling.story';\nexport { default as GraphVisualizationRuleBasedStylingAdvanced } from './graph-visualization-rule-based-styling-advanced.story';\nexport { default as GraphVisualizationRuleBasedStyling } from './graph-visualization-rule-based-styling.story';\nexport { default as GraphVisualizationSearch } from './graph-visualization-search.story';\nexport { default as GraphVisualizationSimpleStyling } from './graph-visualization-simple-styling.story';\nexport { default as PreviewGraphVisualization } from './preview-graph-visualization.story';\n\nimport { removeLicenseHeader } from '../utils';\nimport GraphVisualizationBarebonesSrcRaw from './graph-visualization-barebones.story?raw';\nimport GraphVisualizationColorRangeStylingRaw from './graph-visualization-color-range-styling.story?raw';\nimport GraphVisualizationCustomSrcRaw from './graph-visualization-custom.story?raw';\nimport GraphVisualizationDefaultSrcRaw from './graph-visualization-default.story?raw';\nimport GraphVisualizationHighlightingSrcRaw from './graph-visualization-highlighting.story?raw';\nimport GraphVisualizationMaximalistSrcRaw from './graph-visualization-maximalist.story?raw';\nimport GraphVisualizationRuleBasedStylingSrcRaw from './graph-visualization-rule-based-styling.story?raw';\nimport GraphVisualizationRuleBasedStylingAdvancedSrcRaw from './graph-visualization-rule-based-styling-advanced.story?raw';\nimport GraphVisualizationSearchSrcRaw from './graph-visualization-search.story?raw';\nimport GraphVisualizationSimpleStylingSrcRaw from './graph-visualization-simple-styling.story?raw';\nimport PreviewGraphVisualizationSrcRaw from './preview-graph-visualization.story?raw';\n\nexport const GraphVisualizationDefaultSrc = removeLicenseHeader(\n GraphVisualizationDefaultSrcRaw,\n);\n\nexport const GraphVisualizationBarebonesSrc = removeLicenseHeader(\n GraphVisualizationBarebonesSrcRaw,\n);\n\nexport const GraphVisualizationMaximalistSrc = removeLicenseHeader(\n GraphVisualizationMaximalistSrcRaw,\n);\n\nexport const GraphVisualizationCustomSrc = removeLicenseHeader(\n GraphVisualizationCustomSrcRaw,\n);\n\nexport const GraphVisualizationHighlightingSrc = removeLicenseHeader(\n GraphVisualizationHighlightingSrcRaw,\n);\n\nexport const GraphVisualizationSimpleStylingSrc = removeLicenseHeader(\n GraphVisualizationSimpleStylingSrcRaw,\n);\n\nexport const GraphVisualizationRuleBasedStylingSrc = removeLicenseHeader(\n GraphVisualizationRuleBasedStylingSrcRaw,\n);\n\nexport const GraphVisualizationSearchSrc = removeLicenseHeader(\n GraphVisualizationSearchSrcRaw,\n);\n\nexport const GraphVisualizationRuleBasedStylingAdvancedSrc =\n removeLicenseHeader(GraphVisualizationRuleBasedStylingAdvancedSrcRaw);\n\nexport const GraphVisualizationColorRangeStylingSrc = removeLicenseHeader(\n GraphVisualizationColorRangeStylingRaw,\n);\n\nexport const PreviewGraphVisualizationSrc = removeLicenseHeader(\n PreviewGraphVisualizationSrcRaw,\n);\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) "Neo4j"
|
|
5
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
6
|
+
*
|
|
7
|
+
* This file is part of Neo4j.
|
|
8
|
+
*
|
|
9
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
10
|
+
* it under the terms of the GNU General Public License as published by
|
|
11
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
* (at your option) any later version.
|
|
13
|
+
*
|
|
14
|
+
* This program is distributed in the hope that it will be useful,
|
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
* GNU General Public License for more details.
|
|
18
|
+
*
|
|
19
|
+
* You should have received a copy of the GNU General Public License
|
|
20
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.getWeight = getWeight;
|
|
24
|
+
exports.lerpColor = lerpColor;
|
|
25
|
+
function getWeight(startValue, endValue, value) {
|
|
26
|
+
return (value - startValue) / (endValue - startValue);
|
|
27
|
+
}
|
|
28
|
+
function lerpColor(startColor, endColor, weight) {
|
|
29
|
+
return {
|
|
30
|
+
r: Math.round(startColor.r * (1 - weight) + endColor.r * weight),
|
|
31
|
+
g: Math.round(startColor.g * (1 - weight) + endColor.g * weight),
|
|
32
|
+
b: Math.round(startColor.b * (1 - weight) + endColor.b * weight),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=color-interpolation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-interpolation.js","sourceRoot":"","sources":["../../../src/styling/color-interpolation.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;AAIH,8BAMC;AAED,8BAUC;AAlBD,SAAgB,SAAS,CACvB,UAAkB,EAClB,QAAgB,EAChB,KAAa;IAEb,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC;AACxD,CAAC;AAED,SAAgB,SAAS,CACvB,UAAoB,EACpB,QAAkB,EAClB,MAAc;IAEd,OAAO;QACL,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC;QAChE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC;QAChE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC;KACjE,CAAC;AACJ,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type RgbColor } from '@uiw/react-color';\n\nexport function getWeight(\n startValue: number,\n endValue: number,\n value: number,\n): number {\n return (value - startValue) / (endValue - startValue);\n}\n\nexport function lerpColor(\n startColor: RgbColor,\n endColor: RgbColor,\n weight: number,\n): RgbColor {\n return {\n r: Math.round(startColor.r * (1 - weight) + endColor.r * weight),\n g: Math.round(startColor.g * (1 - weight) + endColor.g * weight),\n b: Math.round(startColor.b * (1 - weight) + endColor.b * weight),\n };\n}\n"]}
|
|
@@ -35,6 +35,8 @@ exports.DEFAULT_REL_COLOR = void 0;
|
|
|
35
35
|
exports.compileStyleRules = compileStyleRules;
|
|
36
36
|
const word_color_1 = require("@neo4j-devtools/word-color");
|
|
37
37
|
const base_1 = require("@neo4j-ndl/base");
|
|
38
|
+
const react_color_1 = require("@uiw/react-color");
|
|
39
|
+
const color_interpolation_1 = require("./color-interpolation");
|
|
38
40
|
function compareByPriorityAscending(a, b) {
|
|
39
41
|
return a.priority - b.priority;
|
|
40
42
|
}
|
|
@@ -96,6 +98,57 @@ function collectStyleMatchers(styles) {
|
|
|
96
98
|
rulesByType,
|
|
97
99
|
};
|
|
98
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Interpolates a color from a ColorRange based on a graph item's property value.
|
|
103
|
+
* Returns a #rrggbb hex string, or null if the colorRange config is invalid
|
|
104
|
+
* (bad hex colors, invalid value range, missing/non-numeric property).
|
|
105
|
+
*/
|
|
106
|
+
function getInterpolatedColor(colorRange, graphItem) {
|
|
107
|
+
const { onProperty, minValue, minColor, maxValue, maxColor, midValue, midColor, } = colorRange;
|
|
108
|
+
if (!(0, react_color_1.validHex)(minColor) || !(0, react_color_1.validHex)(maxColor)) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const minRgb = (0, react_color_1.color)(minColor).rgb;
|
|
112
|
+
const maxRgb = (0, react_color_1.color)(maxColor).rgb;
|
|
113
|
+
// min/max can be inverted, we need to now which one is bigger
|
|
114
|
+
const actualMinValue = Math.min(minValue, maxValue);
|
|
115
|
+
const actualMaxValue = Math.max(minValue, maxValue);
|
|
116
|
+
// Validate mid stop if provided
|
|
117
|
+
let midRgb = undefined;
|
|
118
|
+
if (midValue !== undefined && midColor !== undefined) {
|
|
119
|
+
const isMidInRange = actualMinValue <= midValue && midValue <= actualMaxValue;
|
|
120
|
+
if (!isMidInRange || !(0, react_color_1.validHex)(midColor)) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
midRgb = (0, react_color_1.color)(midColor).rgb;
|
|
124
|
+
}
|
|
125
|
+
const prop = graphItem.properties[onProperty];
|
|
126
|
+
if (prop === undefined) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
const rawValue = extractPropertyValue(prop);
|
|
130
|
+
if (typeof rawValue !== 'number') {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
const clampedValue = Math.max(actualMinValue, Math.min(actualMaxValue, rawValue));
|
|
134
|
+
let rgb;
|
|
135
|
+
if (midRgb !== undefined && midValue !== undefined) {
|
|
136
|
+
const t = (0, color_interpolation_1.getWeight)(minValue, midValue, clampedValue);
|
|
137
|
+
const isBetweenMinAndMid = t <= 1;
|
|
138
|
+
if (isBetweenMinAndMid) {
|
|
139
|
+
rgb = (0, color_interpolation_1.lerpColor)(minRgb, midRgb, t);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
const t = (0, color_interpolation_1.getWeight)(midValue, maxValue, clampedValue);
|
|
143
|
+
rgb = (0, color_interpolation_1.lerpColor)(midRgb, maxRgb, t);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const t = (0, color_interpolation_1.getWeight)(minValue, maxValue, clampedValue);
|
|
148
|
+
rgb = (0, color_interpolation_1.lerpColor)(minRgb, maxRgb, t);
|
|
149
|
+
}
|
|
150
|
+
return (0, react_color_1.rgbToHex)(rgb);
|
|
151
|
+
}
|
|
99
152
|
function extractPropertyValue(prop) {
|
|
100
153
|
switch (prop.type) {
|
|
101
154
|
case 'string':
|
|
@@ -233,7 +286,7 @@ function evaluateWhere(node, where) {
|
|
|
233
286
|
}
|
|
234
287
|
function evaluateRelStyle(apply, rel) {
|
|
235
288
|
var _a;
|
|
236
|
-
|
|
289
|
+
const result = Object.assign(Object.assign({}, apply), { captions: (_a = apply.captions) === null || _a === void 0 ? void 0 : _a.map((caption) => {
|
|
237
290
|
const { value, styles } = caption;
|
|
238
291
|
if (typeof value === 'string' || value === undefined) {
|
|
239
292
|
return { styles, value };
|
|
@@ -253,6 +306,13 @@ function evaluateRelStyle(apply, rel) {
|
|
|
253
306
|
}
|
|
254
307
|
return { styles, value: rel.id };
|
|
255
308
|
}) });
|
|
309
|
+
if (apply.colorRange !== undefined) {
|
|
310
|
+
const interpolated = getInterpolatedColor(apply.colorRange, rel);
|
|
311
|
+
if (interpolated !== null) {
|
|
312
|
+
result.color = interpolated;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return result;
|
|
256
316
|
}
|
|
257
317
|
/**
|
|
258
318
|
* Safely compare two values using Cypher's three-valued logic.
|
|
@@ -348,7 +408,7 @@ function getDefaultNodeCaption(node) {
|
|
|
348
408
|
}
|
|
349
409
|
function evaluateNodeStyle(apply, node) {
|
|
350
410
|
var _a;
|
|
351
|
-
|
|
411
|
+
const result = Object.assign(Object.assign({}, apply), { captions: ((_a = apply.captions) !== null && _a !== void 0 ? _a : [getDefaultNodeCaption(node)]).map((caption) => {
|
|
352
412
|
const { value, styles } = caption;
|
|
353
413
|
if (typeof value === 'string' || value === undefined) {
|
|
354
414
|
return { styles, value };
|
|
@@ -368,6 +428,13 @@ function evaluateNodeStyle(apply, node) {
|
|
|
368
428
|
}
|
|
369
429
|
return { styles, value: node.labelsSorted[0] };
|
|
370
430
|
}) });
|
|
431
|
+
if (apply.colorRange !== undefined) {
|
|
432
|
+
const interpolated = getInterpolatedColor(apply.colorRange, node);
|
|
433
|
+
if (interpolated !== null) {
|
|
434
|
+
result.color = interpolated;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return result;
|
|
371
438
|
}
|
|
372
439
|
function createRelStyleFunction(rules) {
|
|
373
440
|
return (rel) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile-graph-styles.js","sourceRoot":"","sources":["../../../src/styling/compile-graph-styles.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;;;;;;;;;;;;AAikBH,8CA2BC;AA1lBD,2DAAwE;AACxE,0CAAyC;AAyBzC,SAAS,0BAA0B,CAAC,CAAY,EAAE,CAAY;IAC5D,OAAO,CAAC,CAAC,QAAS,GAAG,CAAC,CAAC,QAAS,CAAC;AACnC,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAAsC;IAEtC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAuB,CAAC;IACpD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAC;IACnD,MAAM,gBAAgB,GAAgB,EAAE,CAAC;IACzC,MAAM,kBAAkB,GAAgB,EAAE,CAAC;IAE3C,0CAA0C;IAC1C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO;YACL,gBAAgB;YAChB,kBAAkB;YAClB,YAAY;YACZ,WAAW;SACZ,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IAEjC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;;QAC9B,IAAI,MAAA,KAAK,CAAC,QAAQ,mCAAI,KAAK,EAAE,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CACb,wCAAwC,KAAK,CAAC,QAAQ,kDAAkD,CACzG,CAAC;QACJ,CAAC;QAED,wEAAwE;QACxE,MAAM,EAAE,QAAQ,KAAc,KAAK,EAAd,IAAI,UAAK,KAAK,EAA7B,YAAqB,CAAQ,CAAC;QACpC,MAAM,gBAAgB,mCACjB,IAAI,KACP,QAAQ,EAAE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,KAAK,GAAG,UAAU,GACzC,CAAC;QAEF,kBAAkB;QAClB,IAAI,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC3B,8DAA8D;YAC9D,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;gBAC/B,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,sBAAsB;gBACtB,MAAM,QAAQ,GAAG,MAAA,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,mCAAI,EAAE,CAAC;gBAC3D,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,IAAI,SAAS,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBACjC,iDAAiD;gBACjD,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,wBAAwB;gBACxB,MAAM,QAAQ,GAAG,MAAA,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,mCAAI,EAAE,CAAC;gBAC5D,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,gBAAgB;QAChB,kBAAkB;QAClB,YAAY;QACZ,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,IAAsB;IAEtB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtC,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS,CAAC;QACf,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,KAAK,SAAS,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,IAAI,CAAC,WAAW,KAAK,MAAM,CAAC;QACrC,KAAK,MAAM;YACT,OAAO,IAAI,CAAC;QACd;YACE,OAAO,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;AACH,CAAC;AAYD;;;;;;;;;;;;;;GAcG;AACH,SAAS,aAAa,CAAC,IAAwB,EAAE,KAAa;IAC5D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;QAClC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5C,2CAA2C;QAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,OAAO,KAAK,QAAQ,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,0BAA0B;QAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5C,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrC,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,iBAAiB,IAAI,KAAK,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC;QAC5C,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,aAAa,IAAI,KAAK,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;QACxC,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,oBAAoB,IAAI,KAAK,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC;QAC/C,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrC,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;QACvC,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrC,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QACtB,0CAA0C;QAC1C,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChD,OAAO,KAAK,KAAK,IAAI,CAAC;IACxB,CAAC;IAED,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,2BAA2B;QAC3B,4BAA4B;QAC5B,+BAA+B;QAC/B,gBAAgB;QAChB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACvC,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;gBACtB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QAClB,0BAA0B;QAC1B,0BAA0B;QAC1B,+BAA+B;QAC/B,iBAAiB;QACjB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACvC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAChC,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACrB,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC,OAAO,KAAK,IAAI,IAAK,IAAgB,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,CAAC;QAC5E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC;IACtE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAY,EACZ,GAAY;;IAEZ,uCACK,KAAK,KACR,QAAQ,EAAE,MAAA,KAAK,CAAC,QAAQ,0CAAE,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YACxC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;YAElC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YAC3B,CAAC;YAED,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;gBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;YACrC,CAAC;YAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC5C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;gBAC/B,CAAC;gBAED,MAAM,aAAa,GACjB,IAAI,CAAC,IAAI,KAAK,QAAQ;oBACpB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC/B,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;gBAEvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;YAC1C,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;QACnC,CAAC,CAAC,IACF;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,WAAW,CAClB,IAAW,EACX,KAAY,EACZ,SAA6B,EAC7B,SAGY;IAEZ,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CACxB,IAAW,EACX,KAAY,EACZ,SAA6B,EAC7B,SAA4C;IAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACjD,mEAAmE;IACnE,IACE,OAAO,KAAK,IAAI;QAChB,QAAQ,KAAK,IAAI;QACjB,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,QAAQ,KAAK,QAAQ,EAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,aAAa,CACpB,KAAY,EACZ,SAA6B;IAE7B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC5B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YACrB,IAAI,cAAc,IAAI,SAAS,EAAE,CAAC;gBAChC,OAAO,CACL,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CACrE,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;gBACxB,OAAO,CACL,KAAK,CAAC,OAAO,KAAK,IAAI;oBACrB,SAAqB,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,CAC9C,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kCAAkC;AAClC,MAAM,oBAAoB,GAAG;IAC3B,SAAS;IACT,UAAU;IACV,UAAU;IACV,QAAQ;IACR,eAAe;IACf,KAAK;CACN,CAAC;AAEF,SAAS,qBAAqB,CAAC,IAAc;IAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAElD,KAAK,MAAM,KAAK,IAAI,oBAAoB,EAAE,CAAC;QACzC,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YAC1C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACvC,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAY,EACZ,IAAc;;IAEd,uCACK,KAAK,KACR,QAAQ,EAAE,CAAC,MAAA,KAAK,CAAC,QAAQ,mCAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAC7D,CAAC,OAAO,EAAE,EAAE;YACV,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;YAElC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YAC3B,CAAC;YAED,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;gBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,CAAC;YAED,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC7C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;gBAC/B,CAAC;gBAED,MAAM,aAAa,GACjB,IAAI,CAAC,IAAI,KAAK,QAAQ;oBACpB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC/B,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;gBAEvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;YAC1C,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,CAAC,CACF,IACD;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,KAAkB;IAElB,OAAO,CAAC,GAAY,EAAE,EAAE;QACtB,MAAM,KAAK,GAAU,EAAE,CAAC;QAExB,wEAAwE;QACxE,uEAAuE;QACvE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,iDAAiD;YACjD,IAAI,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC5B,MAAM,cAAc,GAClB,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;gBAEjE,IAAI,cAAc,IAAI,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;oBAC9D,iEAAiE;oBACjE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC,CAAC;AACJ,CAAC;AAQY,QAAA,iBAAiB,GAAG,aAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9D,MAAM,uBAAuB,GAAG,aAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7D,SAAS,wBAAwB,CAC/B,aAA4B;IAE5B,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;IACxD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAiB,CAAC;IAElD,OAAO,CAAC,IAAc,EAAE,EAAE;;QACxB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEjD,6DAA6D;QAC7D,qEAAqE;QACrE,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACtD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,iBAAiB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC;QAED,uCAAuC;QACvC,MAAM,oBAAoB,GAAG,MAAA,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,mCAAI,IAAI,CAAC;QAC1D,IAAI,YAAoB,CAAC;QACzB,IAAI,oBAAoB,KAAK,IAAI,EAAE,CAAC;YAClC,YAAY,GAAG,uBAAuB,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,IAAI,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YACzD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM;oBACJ,IAAA,uCAA0B,EAAC,oBAAoB,CAAC,CAAC,eAAe,CAAC;gBACnE,iBAAiB,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;YACtD,CAAC;YACD,YAAY,GAAG,MAAM,CAAC;QACxB,CAAC;QAED,sEAAsE;QACtE,IAAI,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,aAAa,GAAgB,CAAC,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACvE,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtC,MAAM,UAAU,GAAG,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACzD,IAAI,UAAU,EAAE,CAAC;oBACf,aAAa,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;YACD,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;YACjE,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACjD,CAAC;QAED,sDAAsD;QACtD,MAAM,aAAa,GAAU,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QACrD,IAAI,cAAc,GAAG,IAAI,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC7B,cAAc,GAAG,KAAK,CAAC;gBACvB,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;oBAC7C,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,0EAA0E;QAC1E,4EAA4E;QAC5E,IAAI,cAAc,EAAE,CAAC;YACnB,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,iBAAiB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAChD,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,iBAAiB,GAAc;IACnC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;IACxB,KAAK,EAAE;QACL,KAAK,EAAE,yBAAiB;QACxB,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;KACzC;CACF,CAAC;AAEF,SAAgB,iBAAiB,CAC/B,UAA0C;IAE1C,MAAM,aAAa,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAEvD,gEAAgE;IAChE,MAAM,KAAK,GAAG,IAAI,GAAG,EAGlB,CAAC;IACJ,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;;QAC9B,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,MAAA,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAI,EAAE,CAAC;YACxD,EAAE,GAAG,sBAAsB,CAAC;gBAC1B,iBAAiB;gBACjB,GAAG,aAAa,CAAC,kBAAkB;gBACnC,GAAG,KAAK;aACT,CAAC,CAAC;YACH,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,wBAAwB,CAAC,aAAa,CAAC,CAAC;IAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AAC/C,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { calculateDefaultNodeColors } from '@neo4j-devtools/word-color';\nimport { tokens } from '@neo4j-ndl/base';\n\nimport {\n type NodeData,\n type PortableProperty,\n type RelData,\n} from '../graph-visualization-context';\nimport {\n type Caption,\n type CypherValue,\n type EvaluatedNvlNodeStyle,\n type EvaluatedNvlRelationshipStyle,\n type Style,\n type StyleRule,\n type Value,\n type Where,\n} from './style-types';\n\ntype StyleMatchers = {\n globalLabelRules: StyleRule[];\n globalReltypeRules: StyleRule[];\n rulesByLabel: Map<string, StyleRule[]>;\n rulesByType: Map<string, StyleRule[]>;\n};\n\nfunction compareByPriorityAscending(a: StyleRule, b: StyleRule): number {\n return a.priority! - b.priority!;\n}\n\nfunction collectStyleMatchers(\n styles: StyleRule[] | null | undefined,\n): StyleMatchers {\n const rulesByLabel = new Map<string, StyleRule[]>();\n const rulesByType = new Map<string, StyleRule[]>();\n const globalLabelRules: StyleRule[] = [];\n const globalReltypeRules: StyleRule[] = [];\n\n // Handle null/undefined styles gracefully\n if (!styles || styles.length === 0) {\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n }\n\n const totalRules = styles.length;\n\n styles.forEach((style, index) => {\n if (style.disabled ?? false) {\n return;\n }\n\n if (style.priority !== undefined && style.priority < 0) {\n throw new Error(\n `StyleRule priority must be >= 0, got ${style.priority}. Negative values are reserved for internal use.`,\n );\n }\n\n // Fill in priority if not set (negative values preserve original order)\n const { priority, ...rest } = style;\n const ruleWithPriority: StyleRule = {\n ...rest,\n priority: priority ?? index - totalRules,\n };\n\n // style for nodes\n if ('label' in style.match) {\n // if the label is null, it's a global rule (matches any node)\n if (style.match.label === null) {\n globalLabelRules.push(ruleWithPriority);\n } else {\n // Specific label rule\n const existing = rulesByLabel.get(style.match.label) ?? [];\n rulesByLabel.set(style.match.label, [...existing, ruleWithPriority]);\n }\n }\n\n // style for relationships\n if ('reltype' in style.match) {\n if (style.match.reltype === null) {\n // Global reltype rule (matches any relationship)\n globalReltypeRules.push(ruleWithPriority);\n } else {\n // Specific reltype rule\n const existing = rulesByType.get(style.match.reltype) ?? [];\n rulesByType.set(style.match.reltype, [...existing, ruleWithPriority]);\n }\n }\n });\n\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n}\n\nfunction extractPropertyValue(\n prop: PortableProperty,\n): string | number | boolean | null {\n switch (prop.type) {\n case 'string':\n return JSON.parse(prop.stringified);\n case 'number':\n case 'integer':\n case 'float':\n return Number(prop.stringified);\n case 'boolean':\n case 'Boolean':\n return prop.stringified === 'true';\n case 'null':\n return null;\n default:\n return prop.stringified;\n }\n}\n\n/**\n * Three-valued logic type matching Cypher/SQL semantics.\n * - `true`: condition is satisfied\n * - `false`: condition is not satisfied\n * - `null`: condition is unknown (e.g., comparing with null/missing property)\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\ntype Ternary = boolean | null;\n\n/**\n * Evaluates a WHERE clause using three-valued logic matching Cypher semantics.\n *\n * From Neo4j Cypher Manual:\n * - Comparing any value to `null` results in `null`, not `true` or `false`\n * - Accessing a non-existent property returns `null`\n * - In WHERE clauses, only `true` passes; both `false` and `null` exclude the row\n *\n * Three-valued logic rules:\n * - NOT null → null\n * - true AND null → null, false AND null → false\n * - true OR null → true, false OR null → null\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction evaluateWhere(node: NodeData | RelData, where?: Where): Ternary {\n if (!where) {\n return true;\n }\n\n if ('equal' in where) {\n const [left, right] = where.equal;\n const leftVal = evaluateValue(left, node);\n const rightVal = evaluateValue(right, node);\n // In Cypher, null = null → null (not true)\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return leftVal === rightVal;\n }\n\n if ('not' in where) {\n // Cypher: NOT null → null\n const isMatch = evaluateWhere(node, where.not);\n return isMatch === null ? null : !isMatch;\n }\n\n if ('lessThan' in where) {\n const [left, right] = where.lessThan;\n return safeCompare(left, right, node, (a, b) => a < b);\n }\n\n if ('lessThanOrEqual' in where) {\n const [left, right] = where.lessThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a <= b);\n }\n\n if ('greaterThan' in where) {\n const [left, right] = where.greaterThan;\n return safeCompare(left, right, node, (a, b) => a > b);\n }\n\n if ('greaterThanOrEqual' in where) {\n const [left, right] = where.greaterThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a >= b);\n }\n\n if ('contains' in where) {\n const [left, right] = where.contains;\n return safeStringCompare(left, right, node, (a, b) => a.includes(b));\n }\n\n if ('startsWith' in where) {\n const [left, right] = where.startsWith;\n return safeStringCompare(left, right, node, (a, b) => a.startsWith(b));\n }\n\n if ('endsWith' in where) {\n const [left, right] = where.endsWith;\n return safeStringCompare(left, right, node, (a, b) => a.endsWith(b));\n }\n\n if ('isNull' in where) {\n // IS NULL returns true/false (never null)\n const value = evaluateValue(where.isNull, node);\n return value === null;\n }\n\n if ('and' in where) {\n // Cypher three-valued AND:\n // - If any is false → false\n // - Else if any is null → null\n // - Else → true\n let hasNull = false;\n for (const r of where.and) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === false) {\n return false;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : true;\n }\n\n if ('or' in where) {\n // Cypher three-valued OR:\n // - If any is true → true\n // - Else if any is null → null\n // - Else → false\n let hasNull = false;\n for (const r of where.or) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === true) {\n return true;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : false;\n }\n\n if ('label' in where) {\n if ('labelsSorted' in node) {\n return where.label === null || node.labelsSorted.includes(where.label);\n }\n return false;\n }\n\n if ('reltype' in where) {\n if ('type' in node) {\n return where.reltype === null || (node as RelData).type === where.reltype;\n }\n return false;\n }\n\n if ('property' in where) {\n return where.property === null || where.property in node.properties;\n }\n\n return false;\n}\n\nfunction evaluateRelStyle(\n apply: Style,\n rel: RelData,\n): EvaluatedNvlRelationshipStyle {\n return {\n ...apply,\n captions: apply.captions?.map((caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: rel.type };\n }\n\n if ('property' in value) {\n const prop = rel.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: rel.id };\n }),\n };\n}\n\n/**\n * Safely compare two values using Cypher's three-valued logic.\n * Returns `null` if either operand is null (matching Cypher semantics).\n *\n * From Neo4j Cypher Manual:\n * \"Comparing any value to `null` using `=` or `<>` results in `null`\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction safeCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (\n a: NonNullable<CypherValue>,\n b: NonNullable<CypherValue>,\n ) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\n/**\n * String comparison using Cypher semantics.\n * Returns `null` if either operand is null OR not a string.\n *\n * From Neo4j Cypher Manual:\n * \"When these operators are applied to non-string values, they return `null`\n * instead of attempting type coercion.\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/expressions/predicates/string-operators/\n */\nfunction safeStringCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (a: string, b: string) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n // Return null if either is null or not a string (no type coercion)\n if (\n leftVal === null ||\n rightVal === null ||\n typeof leftVal !== 'string' ||\n typeof rightVal !== 'string'\n ) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\nfunction evaluateValue(\n value: Value,\n graphItem: NodeData | RelData,\n): CypherValue {\n if (typeof value === 'object' && value !== null) {\n if ('property' in value) {\n if (value.property === null) {\n return null;\n }\n const prop = graphItem.properties[value.property];\n if (prop === undefined) {\n return null;\n }\n return extractPropertyValue(prop);\n }\n if ('label' in value) {\n if ('labelsSorted' in graphItem) {\n return (\n value.label === null || graphItem.labelsSorted.includes(value.label)\n );\n }\n return false;\n }\n if ('reltype' in value) {\n if ('type' in graphItem) {\n return (\n value.reltype === null ||\n (graphItem as RelData).type === value.reltype\n );\n }\n return false;\n }\n }\n\n return value;\n}\n\n// Default caption selection logic\nconst captionPriorityOrder = [\n /^name$/i,\n /^title$/i,\n /^label$/i,\n /name$/i,\n /description$/i,\n /^.+/,\n];\n\nfunction getDefaultNodeCaption(node: NodeData): Caption {\n const propertyKeys = Object.keys(node.properties);\n\n for (const regex of captionPriorityOrder) {\n const matchingKey = propertyKeys.find((key) => regex.test(key));\n if (matchingKey !== undefined) {\n const prop = node.properties[matchingKey];\n if (prop !== undefined) {\n return { value: { property: matchingKey } };\n }\n }\n }\n\n if (node.labelsSorted[0] !== undefined) {\n return { value: { useType: true } };\n }\n\n return { value: node.id };\n}\n\nfunction evaluateNodeStyle(\n apply: Style,\n node: NodeData,\n): EvaluatedNvlNodeStyle {\n return {\n ...apply,\n captions: (apply.captions ?? [getDefaultNodeCaption(node)]).map(\n (caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: node.labelsSorted[0] };\n }\n\n if ('property' in value) {\n const prop = node.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: node.labelsSorted[0] };\n },\n ),\n };\n}\n\nfunction createRelStyleFunction(\n rules: StyleRule[],\n): (rel: RelData) => EvaluatedNvlRelationshipStyle {\n return (rel: RelData) => {\n const style: Style = {};\n\n // evaluateWhere uses Cypher-style three-valued logic (true/false/null).\n // Only `true` passes; both `false` and `null` (unknown) skip the rule.\n for (const rule of rules) {\n // Check if the rule applies to this relationship\n if ('reltype' in rule.match) {\n const isReltypeMatch =\n rule.match.reltype === null || rel.type === rule.match.reltype;\n\n if (isReltypeMatch && evaluateWhere(rel, rule.where) === true) {\n // Merge the style properties (later rules override earlier ones)\n Object.assign(style, rule.apply);\n }\n }\n }\n\n return evaluateRelStyle(style, rel);\n };\n}\n\nexport type CompiledStyleRules = {\n byType: (type: string) => (rel: RelData) => EvaluatedNvlRelationshipStyle;\n styleMatchers: StyleMatchers;\n byLabelSet: (node: NodeData) => EvaluatedNvlNodeStyle;\n};\n\nexport const DEFAULT_REL_COLOR = tokens.palette.neutral['40'];\nconst NO_LABEL_FALLBACK_COLOR = tokens.palette.neutral['40'];\n\nfunction createByLabelSetFunction(\n styleMatchers: StyleMatchers,\n): (node: NodeData) => EvaluatedNvlNodeStyle {\n const defaultColorCache = new Map<string, string>();\n const sortedRulesCache = new Map<string, StyleRule[]>();\n const mergedStyleCache = new Map<string, Style>();\n\n return (node: NodeData) => {\n const labelSetKey = node.labelsSorted.join('\\0');\n\n // Fast path: if all rules for this label set are where-free,\n // the merged style is identical for every node with the same labels.\n const cachedStyle = mergedStyleCache.get(labelSetKey);\n if (cachedStyle !== undefined) {\n return evaluateNodeStyle(cachedStyle, node);\n }\n\n // Memoize default color by first label\n const labelForDefaultColor = node.labelsSorted[0] ?? null;\n let defaultColor: string;\n if (labelForDefaultColor === null) {\n defaultColor = NO_LABEL_FALLBACK_COLOR;\n } else {\n let cached = defaultColorCache.get(labelForDefaultColor);\n if (cached === undefined) {\n cached =\n calculateDefaultNodeColors(labelForDefaultColor).backgroundColor;\n defaultColorCache.set(labelForDefaultColor, cached);\n }\n defaultColor = cached;\n }\n\n // Cache sorted rules by label set (avoids repeated allocation + sort)\n let sortedRules = sortedRulesCache.get(labelSetKey);\n if (sortedRules === undefined) {\n const matchingRules: StyleRule[] = [...styleMatchers.globalLabelRules];\n for (const label of node.labelsSorted) {\n const labelRules = styleMatchers.rulesByLabel.get(label);\n if (labelRules) {\n matchingRules.push(...labelRules);\n }\n }\n sortedRules = matchingRules.toSorted(compareByPriorityAscending);\n sortedRulesCache.set(labelSetKey, sortedRules);\n }\n\n // Evaluate rules, tracking whether all are where-free\n const collectStyles: Style = { color: defaultColor };\n let isAllWhereFree = true;\n for (const rule of sortedRules) {\n if (rule.where !== undefined) {\n isAllWhereFree = false;\n if (evaluateWhere(node, rule.where) === true) {\n Object.assign(collectStyles, rule.apply);\n }\n } else {\n Object.assign(collectStyles, rule.apply);\n }\n }\n\n // When all rules are where-free, the merged style depends only on labels.\n // Cache it so subsequent nodes with the same label set skip rule iteration.\n if (isAllWhereFree) {\n mergedStyleCache.set(labelSetKey, collectStyles);\n }\n\n return evaluateNodeStyle(collectStyles, node);\n };\n}\n\nconst DEFAULT_REL_STYLE: StyleRule = {\n match: { reltype: null },\n apply: {\n color: DEFAULT_REL_COLOR,\n captions: [{ value: { useType: true } }],\n },\n};\n\nexport function compileStyleRules(\n styleRules: StyleRule[] | null | undefined,\n): CompiledStyleRules {\n const styleMatchers = collectStyleMatchers(styleRules);\n\n // Lazily build and cache a style function per relationship type\n const cache = new Map<\n string,\n (rel: RelData) => EvaluatedNvlRelationshipStyle\n >();\n const byType = (type: string) => {\n let fn = cache.get(type);\n if (fn === undefined) {\n const rules = styleMatchers.rulesByType.get(type) ?? [];\n fn = createRelStyleFunction([\n DEFAULT_REL_STYLE,\n ...styleMatchers.globalReltypeRules,\n ...rules,\n ]);\n cache.set(type, fn);\n }\n return fn;\n };\n\n const byLabelSet = createByLabelSetFunction(styleMatchers);\n\n return { byLabelSet, byType, styleMatchers };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"compile-graph-styles.js","sourceRoot":"","sources":["../../../src/styling/compile-graph-styles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { calculateDefaultNodeColors } from '@neo4j-devtools/word-color';\nimport { tokens } from '@neo4j-ndl/base';\nimport { color, type RgbColor, rgbToHex, validHex } from '@uiw/react-color';\n\nimport {\n type NodeData,\n type PortableProperty,\n type RelData,\n} from '../graph-visualization-context';\nimport { getWeight, lerpColor } from './color-interpolation';\nimport {\n type Caption,\n type ColorRange,\n type CypherValue,\n type EvaluatedNvlNodeStyle,\n type EvaluatedNvlRelationshipStyle,\n type Style,\n type StyleRule,\n type Value,\n type Where,\n} from './style-types';\n\ntype StyleMatchers = {\n globalLabelRules: StyleRule[];\n globalReltypeRules: StyleRule[];\n rulesByLabel: Map<string, StyleRule[]>;\n rulesByType: Map<string, StyleRule[]>;\n};\n\nfunction compareByPriorityAscending(a: StyleRule, b: StyleRule): number {\n return a.priority! - b.priority!;\n}\n\nfunction collectStyleMatchers(\n styles: StyleRule[] | null | undefined,\n): StyleMatchers {\n const rulesByLabel = new Map<string, StyleRule[]>();\n const rulesByType = new Map<string, StyleRule[]>();\n const globalLabelRules: StyleRule[] = [];\n const globalReltypeRules: StyleRule[] = [];\n\n // Handle null/undefined styles gracefully\n if (!styles || styles.length === 0) {\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n }\n\n const totalRules = styles.length;\n\n styles.forEach((style, index) => {\n if (style.disabled ?? false) {\n return;\n }\n\n if (style.priority !== undefined && style.priority < 0) {\n throw new Error(\n `StyleRule priority must be >= 0, got ${style.priority}. Negative values are reserved for internal use.`,\n );\n }\n\n // Fill in priority if not set (negative values preserve original order)\n const { priority, ...rest } = style;\n const ruleWithPriority: StyleRule = {\n ...rest,\n priority: priority ?? index - totalRules,\n };\n\n // style for nodes\n if ('label' in style.match) {\n // if the label is null, it's a global rule (matches any node)\n if (style.match.label === null) {\n globalLabelRules.push(ruleWithPriority);\n } else {\n // Specific label rule\n const existing = rulesByLabel.get(style.match.label) ?? [];\n rulesByLabel.set(style.match.label, [...existing, ruleWithPriority]);\n }\n }\n\n // style for relationships\n if ('reltype' in style.match) {\n if (style.match.reltype === null) {\n // Global reltype rule (matches any relationship)\n globalReltypeRules.push(ruleWithPriority);\n } else {\n // Specific reltype rule\n const existing = rulesByType.get(style.match.reltype) ?? [];\n rulesByType.set(style.match.reltype, [...existing, ruleWithPriority]);\n }\n }\n });\n\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n}\n\n/**\n * Interpolates a color from a ColorRange based on a graph item's property value.\n * Returns a #rrggbb hex string, or null if the colorRange config is invalid\n * (bad hex colors, invalid value range, missing/non-numeric property).\n */\nfunction getInterpolatedColor(\n colorRange: ColorRange,\n graphItem: NodeData | RelData,\n): string | null {\n const {\n onProperty,\n minValue,\n minColor,\n maxValue,\n maxColor,\n midValue,\n midColor,\n } = colorRange;\n\n if (!validHex(minColor) || !validHex(maxColor)) {\n return null;\n }\n const minRgb = color(minColor).rgb;\n const maxRgb = color(maxColor).rgb;\n // min/max can be inverted, we need to now which one is bigger\n const actualMinValue = Math.min(minValue, maxValue);\n const actualMaxValue = Math.max(minValue, maxValue);\n\n // Validate mid stop if provided\n let midRgb: RgbColor | undefined = undefined;\n if (midValue !== undefined && midColor !== undefined) {\n const isMidInRange =\n actualMinValue <= midValue && midValue <= actualMaxValue;\n if (!isMidInRange || !validHex(midColor)) {\n return null;\n }\n midRgb = color(midColor).rgb;\n }\n\n const prop = graphItem.properties[onProperty];\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (typeof rawValue !== 'number') {\n return null;\n }\n\n const clampedValue = Math.max(\n actualMinValue,\n Math.min(actualMaxValue, rawValue),\n );\n\n let rgb: RgbColor;\n\n if (midRgb !== undefined && midValue !== undefined) {\n const t = getWeight(minValue, midValue, clampedValue);\n const isBetweenMinAndMid = t <= 1;\n if (isBetweenMinAndMid) {\n rgb = lerpColor(minRgb, midRgb, t);\n } else {\n const t = getWeight(midValue, maxValue, clampedValue);\n rgb = lerpColor(midRgb, maxRgb, t);\n }\n } else {\n const t = getWeight(minValue, maxValue, clampedValue);\n rgb = lerpColor(minRgb, maxRgb, t);\n }\n\n return rgbToHex(rgb);\n}\n\nfunction extractPropertyValue(\n prop: PortableProperty,\n): string | number | boolean | null {\n switch (prop.type) {\n case 'string':\n return JSON.parse(prop.stringified);\n case 'number':\n case 'integer':\n case 'float':\n return Number(prop.stringified);\n case 'boolean':\n case 'Boolean':\n return prop.stringified === 'true';\n case 'null':\n return null;\n default:\n return prop.stringified;\n }\n}\n\n/**\n * Three-valued logic type matching Cypher/SQL semantics.\n * - `true`: condition is satisfied\n * - `false`: condition is not satisfied\n * - `null`: condition is unknown (e.g., comparing with null/missing property)\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\ntype Ternary = boolean | null;\n\n/**\n * Evaluates a WHERE clause using three-valued logic matching Cypher semantics.\n *\n * From Neo4j Cypher Manual:\n * - Comparing any value to `null` results in `null`, not `true` or `false`\n * - Accessing a non-existent property returns `null`\n * - In WHERE clauses, only `true` passes; both `false` and `null` exclude the row\n *\n * Three-valued logic rules:\n * - NOT null → null\n * - true AND null → null, false AND null → false\n * - true OR null → true, false OR null → null\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction evaluateWhere(node: NodeData | RelData, where?: Where): Ternary {\n if (!where) {\n return true;\n }\n\n if ('equal' in where) {\n const [left, right] = where.equal;\n const leftVal = evaluateValue(left, node);\n const rightVal = evaluateValue(right, node);\n // In Cypher, null = null → null (not true)\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return leftVal === rightVal;\n }\n\n if ('not' in where) {\n // Cypher: NOT null → null\n const isMatch = evaluateWhere(node, where.not);\n return isMatch === null ? null : !isMatch;\n }\n\n if ('lessThan' in where) {\n const [left, right] = where.lessThan;\n return safeCompare(left, right, node, (a, b) => a < b);\n }\n\n if ('lessThanOrEqual' in where) {\n const [left, right] = where.lessThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a <= b);\n }\n\n if ('greaterThan' in where) {\n const [left, right] = where.greaterThan;\n return safeCompare(left, right, node, (a, b) => a > b);\n }\n\n if ('greaterThanOrEqual' in where) {\n const [left, right] = where.greaterThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a >= b);\n }\n\n if ('contains' in where) {\n const [left, right] = where.contains;\n return safeStringCompare(left, right, node, (a, b) => a.includes(b));\n }\n\n if ('startsWith' in where) {\n const [left, right] = where.startsWith;\n return safeStringCompare(left, right, node, (a, b) => a.startsWith(b));\n }\n\n if ('endsWith' in where) {\n const [left, right] = where.endsWith;\n return safeStringCompare(left, right, node, (a, b) => a.endsWith(b));\n }\n\n if ('isNull' in where) {\n // IS NULL returns true/false (never null)\n const value = evaluateValue(where.isNull, node);\n return value === null;\n }\n\n if ('and' in where) {\n // Cypher three-valued AND:\n // - If any is false → false\n // - Else if any is null → null\n // - Else → true\n let hasNull = false;\n for (const r of where.and) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === false) {\n return false;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : true;\n }\n\n if ('or' in where) {\n // Cypher three-valued OR:\n // - If any is true → true\n // - Else if any is null → null\n // - Else → false\n let hasNull = false;\n for (const r of where.or) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === true) {\n return true;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : false;\n }\n\n if ('label' in where) {\n if ('labelsSorted' in node) {\n return where.label === null || node.labelsSorted.includes(where.label);\n }\n return false;\n }\n\n if ('reltype' in where) {\n if ('type' in node) {\n return where.reltype === null || (node as RelData).type === where.reltype;\n }\n return false;\n }\n\n if ('property' in where) {\n return where.property === null || where.property in node.properties;\n }\n\n return false;\n}\n\nfunction evaluateRelStyle(\n apply: Style,\n rel: RelData,\n): EvaluatedNvlRelationshipStyle {\n const result: EvaluatedNvlRelationshipStyle = {\n ...apply,\n captions: apply.captions?.map((caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: rel.type };\n }\n\n if ('property' in value) {\n const prop = rel.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: rel.id };\n }),\n };\n\n if (apply.colorRange !== undefined) {\n const interpolated = getInterpolatedColor(apply.colorRange, rel);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n return result;\n}\n\n/**\n * Safely compare two values using Cypher's three-valued logic.\n * Returns `null` if either operand is null (matching Cypher semantics).\n *\n * From Neo4j Cypher Manual:\n * \"Comparing any value to `null` using `=` or `<>` results in `null`\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction safeCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (\n a: NonNullable<CypherValue>,\n b: NonNullable<CypherValue>,\n ) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\n/**\n * String comparison using Cypher semantics.\n * Returns `null` if either operand is null OR not a string.\n *\n * From Neo4j Cypher Manual:\n * \"When these operators are applied to non-string values, they return `null`\n * instead of attempting type coercion.\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/expressions/predicates/string-operators/\n */\nfunction safeStringCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (a: string, b: string) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n // Return null if either is null or not a string (no type coercion)\n if (\n leftVal === null ||\n rightVal === null ||\n typeof leftVal !== 'string' ||\n typeof rightVal !== 'string'\n ) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\nfunction evaluateValue(\n value: Value,\n graphItem: NodeData | RelData,\n): CypherValue {\n if (typeof value === 'object' && value !== null) {\n if ('property' in value) {\n if (value.property === null) {\n return null;\n }\n const prop = graphItem.properties[value.property];\n if (prop === undefined) {\n return null;\n }\n return extractPropertyValue(prop);\n }\n if ('label' in value) {\n if ('labelsSorted' in graphItem) {\n return (\n value.label === null || graphItem.labelsSorted.includes(value.label)\n );\n }\n return false;\n }\n if ('reltype' in value) {\n if ('type' in graphItem) {\n return (\n value.reltype === null ||\n (graphItem as RelData).type === value.reltype\n );\n }\n return false;\n }\n }\n\n return value;\n}\n\n// Default caption selection logic\nconst captionPriorityOrder = [\n /^name$/i,\n /^title$/i,\n /^label$/i,\n /name$/i,\n /description$/i,\n /^.+/,\n];\n\nfunction getDefaultNodeCaption(node: NodeData): Caption {\n const propertyKeys = Object.keys(node.properties);\n\n for (const regex of captionPriorityOrder) {\n const matchingKey = propertyKeys.find((key) => regex.test(key));\n if (matchingKey !== undefined) {\n const prop = node.properties[matchingKey];\n if (prop !== undefined) {\n return { value: { property: matchingKey } };\n }\n }\n }\n\n if (node.labelsSorted[0] !== undefined) {\n return { value: { useType: true } };\n }\n\n return { value: node.id };\n}\n\nfunction evaluateNodeStyle(\n apply: Style,\n node: NodeData,\n): EvaluatedNvlNodeStyle {\n const result: EvaluatedNvlNodeStyle = {\n ...apply,\n captions: (apply.captions ?? [getDefaultNodeCaption(node)]).map(\n (caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: node.labelsSorted[0] };\n }\n\n if ('property' in value) {\n const prop = node.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: node.labelsSorted[0] };\n },\n ),\n };\n\n if (apply.colorRange !== undefined) {\n const interpolated = getInterpolatedColor(apply.colorRange, node);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n return result;\n}\n\nfunction createRelStyleFunction(\n rules: StyleRule[],\n): (rel: RelData) => EvaluatedNvlRelationshipStyle {\n return (rel: RelData) => {\n const style: Style = {};\n\n // evaluateWhere uses Cypher-style three-valued logic (true/false/null).\n // Only `true` passes; both `false` and `null` (unknown) skip the rule.\n for (const rule of rules) {\n // Check if the rule applies to this relationship\n if ('reltype' in rule.match) {\n const isReltypeMatch =\n rule.match.reltype === null || rel.type === rule.match.reltype;\n\n if (isReltypeMatch && evaluateWhere(rel, rule.where) === true) {\n // Merge the style properties (later rules override earlier ones)\n Object.assign(style, rule.apply);\n }\n }\n }\n\n return evaluateRelStyle(style, rel);\n };\n}\n\nexport type CompiledStyleRules = {\n byType: (type: string) => (rel: RelData) => EvaluatedNvlRelationshipStyle;\n styleMatchers: StyleMatchers;\n byLabelSet: (node: NodeData) => EvaluatedNvlNodeStyle;\n};\n\nexport const DEFAULT_REL_COLOR = tokens.palette.neutral['40'];\nconst NO_LABEL_FALLBACK_COLOR = tokens.palette.neutral['40'];\n\nfunction createByLabelSetFunction(\n styleMatchers: StyleMatchers,\n): (node: NodeData) => EvaluatedNvlNodeStyle {\n const defaultColorCache = new Map<string, string>();\n const sortedRulesCache = new Map<string, StyleRule[]>();\n const mergedStyleCache = new Map<string, Style>();\n\n return (node: NodeData) => {\n const labelSetKey = node.labelsSorted.join('\\0');\n\n // Fast path: if all rules for this label set are where-free,\n // the merged style is identical for every node with the same labels.\n const cachedStyle = mergedStyleCache.get(labelSetKey);\n if (cachedStyle !== undefined) {\n return evaluateNodeStyle(cachedStyle, node);\n }\n\n // Memoize default color by first label\n const labelForDefaultColor = node.labelsSorted[0] ?? null;\n let defaultColor: string;\n if (labelForDefaultColor === null) {\n defaultColor = NO_LABEL_FALLBACK_COLOR;\n } else {\n let cached = defaultColorCache.get(labelForDefaultColor);\n if (cached === undefined) {\n cached =\n calculateDefaultNodeColors(labelForDefaultColor).backgroundColor;\n defaultColorCache.set(labelForDefaultColor, cached);\n }\n defaultColor = cached;\n }\n\n // Cache sorted rules by label set (avoids repeated allocation + sort)\n let sortedRules = sortedRulesCache.get(labelSetKey);\n if (sortedRules === undefined) {\n const matchingRules: StyleRule[] = [...styleMatchers.globalLabelRules];\n for (const label of node.labelsSorted) {\n const labelRules = styleMatchers.rulesByLabel.get(label);\n if (labelRules) {\n matchingRules.push(...labelRules);\n }\n }\n sortedRules = matchingRules.toSorted(compareByPriorityAscending);\n sortedRulesCache.set(labelSetKey, sortedRules);\n }\n\n // Evaluate rules, tracking whether all are where-free\n const collectStyles: Style = { color: defaultColor };\n let isAllWhereFree = true;\n for (const rule of sortedRules) {\n if (rule.where !== undefined) {\n isAllWhereFree = false;\n if (evaluateWhere(node, rule.where) === true) {\n Object.assign(collectStyles, rule.apply);\n }\n } else {\n Object.assign(collectStyles, rule.apply);\n }\n }\n\n // When all rules are where-free, the merged style depends only on labels.\n // Cache it so subsequent nodes with the same label set skip rule iteration.\n if (isAllWhereFree) {\n mergedStyleCache.set(labelSetKey, collectStyles);\n }\n\n return evaluateNodeStyle(collectStyles, node);\n };\n}\n\nconst DEFAULT_REL_STYLE: StyleRule = {\n match: { reltype: null },\n apply: {\n color: DEFAULT_REL_COLOR,\n captions: [{ value: { useType: true } }],\n },\n};\n\nexport function compileStyleRules(\n styleRules: StyleRule[] | null | undefined,\n): CompiledStyleRules {\n const styleMatchers = collectStyleMatchers(styleRules);\n\n // Lazily build and cache a style function per relationship type\n const cache = new Map<\n string,\n (rel: RelData) => EvaluatedNvlRelationshipStyle\n >();\n const byType = (type: string) => {\n let fn = cache.get(type);\n if (fn === undefined) {\n const rules = styleMatchers.rulesByType.get(type) ?? [];\n fn = createRelStyleFunction([\n DEFAULT_REL_STYLE,\n ...styleMatchers.globalReltypeRules,\n ...rules,\n ]);\n cache.set(type, fn);\n }\n return fn;\n };\n\n const byLabelSet = createByLabelSetFunction(styleMatchers);\n\n return { byLabelSet, byType, styleMatchers };\n}\n"]}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
21
21
|
*/
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.StyleRuleSchema = exports.StyleSchema = exports.NvlCaptionSchema = exports.CaptionVariationSchema = exports.CaptionValueSchema = exports.WhereSchema = exports.ValueSchema = exports.CypherValueSchema = exports.MatchSchema = exports.SelectorSchema = void 0;
|
|
23
|
+
exports.StyleRuleSchema = exports.StyleSchema = exports.ColorRangeSchema = exports.NvlCaptionSchema = exports.CaptionVariationSchema = exports.CaptionValueSchema = exports.WhereSchema = exports.ValueSchema = exports.CypherValueSchema = exports.MatchSchema = exports.SelectorSchema = void 0;
|
|
24
24
|
exports.pickConsumerNodeStyles = pickConsumerNodeStyles;
|
|
25
25
|
exports.pickConsumerRelationshipStyles = pickConsumerRelationshipStyles;
|
|
26
26
|
const zod_1 = require("zod");
|
|
@@ -101,11 +101,27 @@ const NvlOverlayIconSchema = zod_1.z.object({
|
|
|
101
101
|
position: zod_1.z.array(zod_1.z.number()).optional(),
|
|
102
102
|
size: zod_1.z.number().optional(),
|
|
103
103
|
});
|
|
104
|
+
/**
|
|
105
|
+
* Gradient coloring based on a continuous numeric property value.
|
|
106
|
+
* Colors must be a standard hex string (#rrggbb).
|
|
107
|
+
* If the property is missing, non-numeric, or any color is invalid, the
|
|
108
|
+
* colorRange is silently ignored — other style properties still apply.
|
|
109
|
+
*/
|
|
110
|
+
exports.ColorRangeSchema = zod_1.z.object({
|
|
111
|
+
onProperty: zod_1.z.string(),
|
|
112
|
+
minValue: zod_1.z.number(),
|
|
113
|
+
minColor: zod_1.z.string(),
|
|
114
|
+
maxValue: zod_1.z.number(),
|
|
115
|
+
maxColor: zod_1.z.string(),
|
|
116
|
+
midValue: zod_1.z.number().optional(),
|
|
117
|
+
midColor: zod_1.z.string().optional(),
|
|
118
|
+
});
|
|
104
119
|
exports.StyleSchema = zod_1.z.object({
|
|
105
120
|
captionAlign: zod_1.z.enum(['top', 'bottom', 'center']).optional(),
|
|
106
121
|
captionSize: zod_1.z.number().optional(),
|
|
107
122
|
captions: zod_1.z.array(exports.NvlCaptionSchema).optional(),
|
|
108
123
|
color: zod_1.z.string().optional(),
|
|
124
|
+
colorRange: exports.ColorRangeSchema.optional(),
|
|
109
125
|
icon: zod_1.z.string().optional(),
|
|
110
126
|
overlayIcon: NvlOverlayIconSchema.optional(),
|
|
111
127
|
size: zod_1.z.number().optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style-types.js","sourceRoot":"","sources":["../../../src/styling/style-types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type Node, type Relationship } from '@neo4j-nvl/base';\nimport { z } from 'zod';\n\n/*\n * Style types defined in Zod, so that we can use the schemas to generate JSON Schema.\n * This is useful for generating documentation, importing and for future integration into editors.\n *\n * Some simple examples of rules:\n * - Match all nodes with label \"Person\" and apply red color\n * { match: { label: \"Person\" }, apply: { color: \"red\" } }\n *\n * - Match all relationships with type \"KNOWS\" which have the property \"name\" equal to \"John\" and apply width 10\n * { match: { reltype: \"KNOWS\" }, where: { equal: [{ property: \"name\" }, \"John\"] }, apply: { width: 10 } }\n */\n\n// Selector schemas. This is what can go under the `match` key.\nconst LabelSelectorSchema = z.object({\n label: z.string().nullable(),\n});\n\nconst ReltypeSelectorSchema = z.object({\n reltype: z.string().nullable(),\n});\n\nconst PropertySelectorSchema = z.object({\n property: z.string(),\n});\n\nexport const SelectorSchema = z.union([\n LabelSelectorSchema,\n ReltypeSelectorSchema,\n PropertySelectorSchema,\n]);\ntype Selector = z.infer<typeof SelectorSchema>;\n\nexport const MatchSchema = z.union([\n LabelSelectorSchema,\n ReltypeSelectorSchema,\n PropertySelectorSchema,\n]);\n\n// Schemas for the values that can go under the `where` key. Starts with defining the literal values.\nexport const CypherValueSchema = z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n]);\nexport type CypherValue = z.infer<typeof CypherValueSchema>;\n\nexport const ValueSchema = z\n .union([SelectorSchema, CypherValueSchema])\n .describe(\n 'Either a property/label/reltype selector (e.g., {property: \"name\"}) or a literal value (string, number, boolean, null).',\n );\nexport type Value = z.infer<typeof ValueSchema>;\n\n/**\n * Where clause - recursive type for conditional expressions\n * The type is manually defined for the export, since zod doesn't support exporting inferred recursive types.\n */\n\nexport type Where =\n // Selector is useful for finding nodes with multiple labels.\n // for example: {match: {label: \"Person\"}, where: {label: \"Actor\"}}\n // matches nodes with label Person AND Actor\n | Selector\n | { not: Where }\n | { and: Where[] }\n | { or: Where[] }\n | { equal: [Value, Value] }\n | { lessThan: [Value, Value] }\n | { lessThanOrEqual: [Value, Value] }\n | { greaterThan: [Value, Value] }\n | { greaterThanOrEqual: [Value, Value] }\n | { contains: [Value, Value] }\n | { startsWith: [Value, Value] }\n | { endsWith: [Value, Value] }\n\n // Null check matching Cypher's IS NULL\n // Returns true/false (not null), making it safe for null checking\n // Use { not: { isNull: ... } } for IS NOT NULL\n // @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n | { isNull: Value };\n\nexport const WhereSchema: z.ZodType<Where> = z.lazy(() =>\n z.union([\n SelectorSchema,\n z.object({ not: WhereSchema }),\n z.object({ and: z.array(WhereSchema) }),\n z.object({ or: z.array(WhereSchema) }),\n z.object({ equal: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ lessThan: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ lessThanOrEqual: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ greaterThan: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ greaterThanOrEqual: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ contains: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ startsWith: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ endsWith: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ isNull: ValueSchema }),\n ]),\n);\n\n// Schemas that go under the `apply` key.\nexport const CaptionValueSchema = z.union([\n z.string(),\n z.object({ property: z.string() }),\n z.object({ useType: z.literal(true) }),\n]);\nexport type CaptionValue = z.infer<typeof CaptionValueSchema>;\n\nexport const CaptionVariationSchema = z.enum(['bold', 'italic', 'underline']);\nexport type CaptionVariation = z.infer<typeof CaptionVariationSchema>;\n\nexport const NvlCaptionSchema = z.object({\n styles: z.array(z.string()).optional(),\n value: CaptionValueSchema.optional(),\n key: z.string().optional(),\n});\nexport type Caption = z.infer<typeof NvlCaptionSchema>;\n\n/**\n * OverlayIcon from NVL - icon displayed on top of a graph element\n * @see @neo4j-nvl/base Node.overlayIcon\n */\nconst NvlOverlayIconSchema = z.object({\n url: z.string(),\n position: z.array(z.number()).optional(),\n size: z.number().optional(),\n});\n\nexport const StyleSchema = z.object({\n captionAlign: z.enum(['top', 'bottom', 'center']).optional(),\n captionSize: z.number().optional(),\n captions: z.array(NvlCaptionSchema).optional(),\n color: z.string().optional(),\n icon: z.string().optional(),\n overlayIcon: NvlOverlayIconSchema.optional(),\n size: z.number().optional(),\n width: z.number().optional(),\n});\nexport type Style = z.infer<typeof StyleSchema>;\n\nexport const StyleRuleSchema = z.object({\n match: MatchSchema,\n where: WhereSchema.optional(),\n apply: StyleSchema,\n disabled: z.boolean().optional(),\n priority: z.number().optional(),\n});\nexport type StyleRule = z.infer<typeof StyleRuleSchema>;\n\n// Evaluated style values that NVL expects\ntype NodeStyleKey =\n | 'icon'\n | 'overlayIcon'\n | 'color'\n | 'size'\n | 'captions'\n | 'captionSize'\n | 'captionAlign';\n\ntype RelStyleKey =\n | 'width'\n | 'color'\n | 'captions'\n | 'captionSize'\n | 'captionAlign'\n | 'overlayIcon';\n\nexport type EvaluatedNvlNodeStyle = Pick<Node, NodeStyleKey>;\nexport type EvaluatedNvlRelationshipStyle = Pick<Relationship, RelStyleKey>;\n\nconst NODE_STYLE_KEYS: readonly NodeStyleKey[] = [\n 'color',\n 'size',\n 'icon',\n 'overlayIcon',\n 'captions',\n 'captionSize',\n 'captionAlign',\n];\n\nconst REL_STYLE_KEYS: readonly RelStyleKey[] = [\n 'color',\n 'width',\n 'captions',\n 'captionSize',\n 'captionAlign',\n 'overlayIcon',\n];\n\n/**\n * Extract consumer-set style properties from a node.\n * Only includes properties that are explicitly defined (not undefined),\n * so they can be spread over rule-derived styles to take precedence.\n */\nexport function pickConsumerNodeStyles(\n node: Partial<EvaluatedNvlNodeStyle>,\n): Partial<EvaluatedNvlNodeStyle> {\n const result: Record<string, unknown> = {};\n for (const key of NODE_STYLE_KEYS) {\n if (node[key] !== undefined) {\n result[key] = node[key];\n }\n }\n return result as Partial<EvaluatedNvlNodeStyle>;\n}\n\n/**\n * Extract consumer-set style properties from a relationship.\n * Only includes properties that are explicitly defined (not undefined),\n * so they can be spread over rule-derived styles to take precedence.\n */\nexport function pickConsumerRelationshipStyles(\n rel: Partial<EvaluatedNvlRelationshipStyle>,\n): Partial<EvaluatedNvlRelationshipStyle> {\n const result: Record<string, unknown> = {};\n for (const key of REL_STYLE_KEYS) {\n if (rel[key] !== undefined) {\n result[key] = rel[key];\n }\n }\n return result as Partial<EvaluatedNvlRelationshipStyle>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"style-types.js","sourceRoot":"","sources":["../../../src/styling/style-types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type Node, type Relationship } from '@neo4j-nvl/base';\nimport { z } from 'zod';\n\n/*\n * Style types defined in Zod, so that we can use the schemas to generate JSON Schema.\n * This is useful for generating documentation, importing and for future integration into editors.\n *\n * Some simple examples of rules:\n * - Match all nodes with label \"Person\" and apply red color\n * { match: { label: \"Person\" }, apply: { color: \"red\" } }\n *\n * - Match all relationships with type \"KNOWS\" which have the property \"name\" equal to \"John\" and apply width 10\n * { match: { reltype: \"KNOWS\" }, where: { equal: [{ property: \"name\" }, \"John\"] }, apply: { width: 10 } }\n */\n\n// Selector schemas. This is what can go under the `match` key.\nconst LabelSelectorSchema = z.object({\n label: z.string().nullable(),\n});\n\nconst ReltypeSelectorSchema = z.object({\n reltype: z.string().nullable(),\n});\n\nconst PropertySelectorSchema = z.object({\n property: z.string(),\n});\n\nexport const SelectorSchema = z.union([\n LabelSelectorSchema,\n ReltypeSelectorSchema,\n PropertySelectorSchema,\n]);\ntype Selector = z.infer<typeof SelectorSchema>;\n\nexport const MatchSchema = z.union([\n LabelSelectorSchema,\n ReltypeSelectorSchema,\n PropertySelectorSchema,\n]);\n\n// Schemas for the values that can go under the `where` key. Starts with defining the literal values.\nexport const CypherValueSchema = z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n]);\nexport type CypherValue = z.infer<typeof CypherValueSchema>;\n\nexport const ValueSchema = z\n .union([SelectorSchema, CypherValueSchema])\n .describe(\n 'Either a property/label/reltype selector (e.g., {property: \"name\"}) or a literal value (string, number, boolean, null).',\n );\nexport type Value = z.infer<typeof ValueSchema>;\n\n/**\n * Where clause - recursive type for conditional expressions\n * The type is manually defined for the export, since zod doesn't support exporting inferred recursive types.\n */\n\nexport type Where =\n // Selector is useful for finding nodes with multiple labels.\n // for example: {match: {label: \"Person\"}, where: {label: \"Actor\"}}\n // matches nodes with label Person AND Actor\n | Selector\n | { not: Where }\n | { and: Where[] }\n | { or: Where[] }\n | { equal: [Value, Value] }\n | { lessThan: [Value, Value] }\n | { lessThanOrEqual: [Value, Value] }\n | { greaterThan: [Value, Value] }\n | { greaterThanOrEqual: [Value, Value] }\n | { contains: [Value, Value] }\n | { startsWith: [Value, Value] }\n | { endsWith: [Value, Value] }\n\n // Null check matching Cypher's IS NULL\n // Returns true/false (not null), making it safe for null checking\n // Use { not: { isNull: ... } } for IS NOT NULL\n // @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n | { isNull: Value };\n\nexport const WhereSchema: z.ZodType<Where> = z.lazy(() =>\n z.union([\n SelectorSchema,\n z.object({ not: WhereSchema }),\n z.object({ and: z.array(WhereSchema) }),\n z.object({ or: z.array(WhereSchema) }),\n z.object({ equal: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ lessThan: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ lessThanOrEqual: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ greaterThan: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ greaterThanOrEqual: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ contains: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ startsWith: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ endsWith: z.tuple([ValueSchema, ValueSchema]) }),\n z.object({ isNull: ValueSchema }),\n ]),\n);\n\n// Schemas that go under the `apply` key.\nexport const CaptionValueSchema = z.union([\n z.string(),\n z.object({ property: z.string() }),\n z.object({ useType: z.literal(true) }),\n]);\nexport type CaptionValue = z.infer<typeof CaptionValueSchema>;\n\nexport const CaptionVariationSchema = z.enum(['bold', 'italic', 'underline']);\nexport type CaptionVariation = z.infer<typeof CaptionVariationSchema>;\n\nexport const NvlCaptionSchema = z.object({\n styles: z.array(z.string()).optional(),\n value: CaptionValueSchema.optional(),\n key: z.string().optional(),\n});\nexport type Caption = z.infer<typeof NvlCaptionSchema>;\n\n/**\n * OverlayIcon from NVL - icon displayed on top of a graph element\n * @see @neo4j-nvl/base Node.overlayIcon\n */\nconst NvlOverlayIconSchema = z.object({\n url: z.string(),\n position: z.array(z.number()).optional(),\n size: z.number().optional(),\n});\n\n/**\n * Gradient coloring based on a continuous numeric property value.\n * Colors must be a standard hex string (#rrggbb).\n * If the property is missing, non-numeric, or any color is invalid, the\n * colorRange is silently ignored — other style properties still apply.\n */\nexport const ColorRangeSchema = z.object({\n onProperty: z.string(),\n minValue: z.number(),\n minColor: z.string(),\n maxValue: z.number(),\n maxColor: z.string(),\n midValue: z.number().optional(),\n midColor: z.string().optional(),\n});\nexport type ColorRange = z.infer<typeof ColorRangeSchema>;\n\nexport const StyleSchema = z.object({\n captionAlign: z.enum(['top', 'bottom', 'center']).optional(),\n captionSize: z.number().optional(),\n captions: z.array(NvlCaptionSchema).optional(),\n color: z.string().optional(),\n colorRange: ColorRangeSchema.optional(),\n icon: z.string().optional(),\n overlayIcon: NvlOverlayIconSchema.optional(),\n size: z.number().optional(),\n width: z.number().optional(),\n});\nexport type Style = z.infer<typeof StyleSchema>;\n\nexport const StyleRuleSchema = z.object({\n match: MatchSchema,\n where: WhereSchema.optional(),\n apply: StyleSchema,\n disabled: z.boolean().optional(),\n priority: z.number().optional(),\n});\nexport type StyleRule = z.infer<typeof StyleRuleSchema>;\n\n// Evaluated style values that NVL expects\ntype NodeStyleKey =\n | 'icon'\n | 'overlayIcon'\n | 'color'\n | 'size'\n | 'captions'\n | 'captionSize'\n | 'captionAlign';\n\ntype RelStyleKey =\n | 'width'\n | 'color'\n | 'captions'\n | 'captionSize'\n | 'captionAlign'\n | 'overlayIcon';\n\nexport type EvaluatedNvlNodeStyle = Pick<Node, NodeStyleKey>;\nexport type EvaluatedNvlRelationshipStyle = Pick<Relationship, RelStyleKey>;\n\nconst NODE_STYLE_KEYS: readonly NodeStyleKey[] = [\n 'color',\n 'size',\n 'icon',\n 'overlayIcon',\n 'captions',\n 'captionSize',\n 'captionAlign',\n];\n\nconst REL_STYLE_KEYS: readonly RelStyleKey[] = [\n 'color',\n 'width',\n 'captions',\n 'captionSize',\n 'captionAlign',\n 'overlayIcon',\n];\n\n/**\n * Extract consumer-set style properties from a node.\n * Only includes properties that are explicitly defined (not undefined),\n * so they can be spread over rule-derived styles to take precedence.\n */\nexport function pickConsumerNodeStyles(\n node: Partial<EvaluatedNvlNodeStyle>,\n): Partial<EvaluatedNvlNodeStyle> {\n const result: Record<string, unknown> = {};\n for (const key of NODE_STYLE_KEYS) {\n if (node[key] !== undefined) {\n result[key] = node[key];\n }\n }\n return result as Partial<EvaluatedNvlNodeStyle>;\n}\n\n/**\n * Extract consumer-set style properties from a relationship.\n * Only includes properties that are explicitly defined (not undefined),\n * so they can be spread over rule-derived styles to take precedence.\n */\nexport function pickConsumerRelationshipStyles(\n rel: Partial<EvaluatedNvlRelationshipStyle>,\n): Partial<EvaluatedNvlRelationshipStyle> {\n const result: Record<string, unknown> = {};\n for (const key of REL_STYLE_KEYS) {\n if (rel[key] !== undefined) {\n result[key] = rel[key];\n }\n }\n return result as Partial<EvaluatedNvlRelationshipStyle>;\n}\n"]}
|