data-navigator 2.2.4 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-FP25I6TN.js +1 -0
- package/dist/chunk-RGY6OTGO.js +1 -0
- package/dist/consts.cjs +1 -1
- package/dist/consts.js +1 -1
- package/dist/index.cjs +1832 -1364
- package/dist/index.js +611 -48
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/rendering.cjs +1 -1
- package/dist/rendering.js +1 -1
- package/dist/structure.cjs +1 -1
- package/dist/structure.js +1 -1
- package/dist/text-chat.cjs +21 -0
- package/dist/text-chat.js +21 -0
- package/dist/utilities.cjs +1 -1
- package/dist/utilities.js +1 -1
- package/package.json +5 -3
- package/text-chat.css +98 -0
package/dist/index.cjs
CHANGED
|
@@ -1,1453 +1,1921 @@
|
|
|
1
|
-
function _array_like_to_array(arr, len) {
|
|
2
|
-
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
-
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
-
return arr2;
|
|
5
|
-
}
|
|
6
|
-
function _array_without_holes(arr) {
|
|
7
|
-
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
8
|
-
}
|
|
9
|
-
function _define_property(obj, key, value) {
|
|
10
|
-
if (key in obj) {
|
|
11
|
-
Object.defineProperty(obj, key, {
|
|
12
|
-
value: value,
|
|
13
|
-
enumerable: true,
|
|
14
|
-
configurable: true,
|
|
15
|
-
writable: true
|
|
16
|
-
});
|
|
17
|
-
} else {
|
|
18
|
-
obj[key] = value;
|
|
19
|
-
}
|
|
20
|
-
return obj;
|
|
21
|
-
}
|
|
22
|
-
function _iterable_to_array(iter) {
|
|
23
|
-
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
24
|
-
}
|
|
25
|
-
function _non_iterable_spread() {
|
|
26
|
-
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
27
|
-
}
|
|
28
|
-
function _object_spread(target) {
|
|
29
|
-
for(var i = 1; i < arguments.length; i++){
|
|
30
|
-
var source = arguments[i] != null ? arguments[i] : {};
|
|
31
|
-
var ownKeys = Object.keys(source);
|
|
32
|
-
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
33
|
-
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
34
|
-
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
35
|
-
}));
|
|
36
|
-
}
|
|
37
|
-
ownKeys.forEach(function(key) {
|
|
38
|
-
_define_property(target, key, source[key]);
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
return target;
|
|
42
|
-
}
|
|
43
|
-
function ownKeys(object, enumerableOnly) {
|
|
44
|
-
var keys = Object.keys(object);
|
|
45
|
-
if (Object.getOwnPropertySymbols) {
|
|
46
|
-
var symbols = Object.getOwnPropertySymbols(object);
|
|
47
|
-
if (enumerableOnly) {
|
|
48
|
-
symbols = symbols.filter(function(sym) {
|
|
49
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
keys.push.apply(keys, symbols);
|
|
53
|
-
}
|
|
54
|
-
return keys;
|
|
55
|
-
}
|
|
56
|
-
function _object_spread_props(target, source) {
|
|
57
|
-
source = source != null ? source : {};
|
|
58
|
-
if (Object.getOwnPropertyDescriptors) {
|
|
59
|
-
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
60
|
-
} else {
|
|
61
|
-
ownKeys(Object(source)).forEach(function(key) {
|
|
62
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
return target;
|
|
66
|
-
}
|
|
67
|
-
function _to_consumable_array(arr) {
|
|
68
|
-
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
69
|
-
}
|
|
70
|
-
function _type_of(obj) {
|
|
71
|
-
"@swc/helpers - typeof";
|
|
72
|
-
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
73
|
-
}
|
|
74
|
-
function _unsupported_iterable_to_array(o, minLen) {
|
|
75
|
-
if (!o) return;
|
|
76
|
-
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
77
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
78
|
-
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
79
|
-
if (n === "Map" || n === "Set") return Array.from(n);
|
|
80
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
81
|
-
}
|
|
82
1
|
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
83
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
84
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
85
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
86
|
-
var
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
var _loop = function() {
|
|
97
|
-
var key = _step.value;
|
|
98
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
99
|
-
get: function get() {
|
|
100
|
-
return from[key];
|
|
101
|
-
},
|
|
102
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
103
|
-
});
|
|
104
|
-
};
|
|
105
|
-
for(var _iterator = __getOwnPropNames(from)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
|
|
106
|
-
} catch (err) {
|
|
107
|
-
_didIteratorError = true;
|
|
108
|
-
_iteratorError = err;
|
|
109
|
-
} finally{
|
|
110
|
-
try {
|
|
111
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
112
|
-
_iterator.return();
|
|
113
|
-
}
|
|
114
|
-
} finally{
|
|
115
|
-
if (_didIteratorError) {
|
|
116
|
-
throw _iteratorError;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
8
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
9
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
10
|
+
var __spreadValues = (a, b) => {
|
|
11
|
+
for (var prop in b || (b = {}))
|
|
12
|
+
if (__hasOwnProp.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
if (__getOwnPropSymbols)
|
|
15
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
16
|
+
if (__propIsEnum.call(b, prop))
|
|
17
|
+
__defNormalProp(a, prop, b[prop]);
|
|
120
18
|
}
|
|
121
|
-
|
|
19
|
+
return a;
|
|
20
|
+
};
|
|
21
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
22
|
+
var __export = (target, all) => {
|
|
23
|
+
for (var name in all)
|
|
24
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
25
|
+
};
|
|
26
|
+
var __copyProps = (to, from, except, desc) => {
|
|
27
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
28
|
+
for (let key of __getOwnPropNames(from))
|
|
29
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
30
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
31
|
+
}
|
|
32
|
+
return to;
|
|
122
33
|
};
|
|
123
|
-
var __toCommonJS =
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
34
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
35
|
+
var __async = (__this, __arguments, generator) => {
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
var fulfilled = (value) => {
|
|
38
|
+
try {
|
|
39
|
+
step(generator.next(value));
|
|
40
|
+
} catch (e) {
|
|
41
|
+
reject(e);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var rejected = (value) => {
|
|
45
|
+
try {
|
|
46
|
+
step(generator.throw(value));
|
|
47
|
+
} catch (e) {
|
|
48
|
+
reject(e);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
52
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
53
|
+
});
|
|
127
54
|
};
|
|
55
|
+
|
|
128
56
|
// src/index.ts
|
|
129
57
|
var src_exports = {};
|
|
130
58
|
__export(src_exports, {
|
|
131
|
-
|
|
132
|
-
return src_default;
|
|
133
|
-
}
|
|
59
|
+
default: () => src_default
|
|
134
60
|
});
|
|
135
61
|
module.exports = __toCommonJS(src_exports);
|
|
62
|
+
|
|
136
63
|
// src/consts.ts
|
|
137
64
|
var SemanticKeys = {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
65
|
+
Escape: true,
|
|
66
|
+
Enter: true,
|
|
67
|
+
Backspace: true,
|
|
68
|
+
ArrowLeft: true,
|
|
69
|
+
ArrowRight: true,
|
|
70
|
+
ArrowUp: true,
|
|
71
|
+
ArrowDown: true
|
|
145
72
|
};
|
|
146
73
|
var defaultKeyBindings = {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
74
|
+
ArrowLeft: "left",
|
|
75
|
+
ArrowRight: "right",
|
|
76
|
+
ArrowUp: "up",
|
|
77
|
+
ArrowDown: "down",
|
|
78
|
+
Period: "forward",
|
|
79
|
+
Comma: "backward",
|
|
80
|
+
Escape: "parent",
|
|
81
|
+
Enter: "child"
|
|
155
82
|
};
|
|
156
|
-
var TypicallyUnreservedKeys = [
|
|
157
|
-
"KeyW",
|
|
158
|
-
"KeyJ",
|
|
159
|
-
"LeftBracket",
|
|
160
|
-
"RightBracket",
|
|
161
|
-
"Slash",
|
|
162
|
-
"Backslash"
|
|
163
|
-
];
|
|
83
|
+
var TypicallyUnreservedKeys = ["KeyW", "KeyJ", "LeftBracket", "RightBracket", "Slash", "Backslash"];
|
|
164
84
|
var TypicallyUnreservedKeyPairs = [
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
"RightBracket"
|
|
168
|
-
],
|
|
169
|
-
[
|
|
170
|
-
"Slash",
|
|
171
|
-
"Backslash"
|
|
172
|
-
]
|
|
85
|
+
["LeftBracket", "RightBracket"],
|
|
86
|
+
["Slash", "Backslash"]
|
|
173
87
|
];
|
|
174
88
|
var GenericFullNavigationRules = {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
89
|
+
left: {
|
|
90
|
+
key: "ArrowLeft",
|
|
91
|
+
direction: "source"
|
|
92
|
+
},
|
|
93
|
+
right: {
|
|
94
|
+
key: "ArrowRight",
|
|
95
|
+
direction: "target"
|
|
96
|
+
},
|
|
97
|
+
up: {
|
|
98
|
+
key: "ArrowUp",
|
|
99
|
+
direction: "source"
|
|
100
|
+
},
|
|
101
|
+
down: {
|
|
102
|
+
key: "ArrowDown",
|
|
103
|
+
direction: "target"
|
|
104
|
+
},
|
|
105
|
+
child: {
|
|
106
|
+
key: "Enter",
|
|
107
|
+
direction: "target"
|
|
108
|
+
},
|
|
109
|
+
parent: {
|
|
110
|
+
key: "Backspace",
|
|
111
|
+
direction: "source"
|
|
112
|
+
},
|
|
113
|
+
backward: {
|
|
114
|
+
key: "Comma",
|
|
115
|
+
direction: "source"
|
|
116
|
+
},
|
|
117
|
+
forward: {
|
|
118
|
+
key: "Period",
|
|
119
|
+
direction: "target"
|
|
120
|
+
},
|
|
121
|
+
previous: {
|
|
122
|
+
key: "Semicolon",
|
|
123
|
+
direction: "source"
|
|
124
|
+
},
|
|
125
|
+
next: {
|
|
126
|
+
key: "Quote",
|
|
127
|
+
direction: "target"
|
|
128
|
+
},
|
|
129
|
+
exit: {
|
|
130
|
+
key: "Escape",
|
|
131
|
+
direction: "target"
|
|
132
|
+
},
|
|
133
|
+
help: {
|
|
134
|
+
key: "KeyY",
|
|
135
|
+
direction: "target"
|
|
136
|
+
},
|
|
137
|
+
undo: {
|
|
138
|
+
key: "KeyZ",
|
|
139
|
+
direction: "target"
|
|
140
|
+
}
|
|
227
141
|
};
|
|
228
142
|
var GenericFullNavigationDimensions = [
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
[
|
|
234
|
-
"up",
|
|
235
|
-
"down"
|
|
236
|
-
],
|
|
237
|
-
[
|
|
238
|
-
"backward",
|
|
239
|
-
"forward"
|
|
240
|
-
],
|
|
241
|
-
[
|
|
242
|
-
"previous",
|
|
243
|
-
"next"
|
|
244
|
-
]
|
|
143
|
+
["left", "right"],
|
|
144
|
+
["up", "down"],
|
|
145
|
+
["backward", "forward"],
|
|
146
|
+
["previous", "next"]
|
|
245
147
|
];
|
|
246
148
|
var GenericLimitedNavigationRules = {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
149
|
+
right: {
|
|
150
|
+
key: "ArrowRight",
|
|
151
|
+
direction: "target"
|
|
152
|
+
},
|
|
153
|
+
left: {
|
|
154
|
+
key: "ArrowLeft",
|
|
155
|
+
direction: "source"
|
|
156
|
+
},
|
|
157
|
+
down: {
|
|
158
|
+
key: "ArrowDown",
|
|
159
|
+
direction: "target"
|
|
160
|
+
},
|
|
161
|
+
up: {
|
|
162
|
+
key: "ArrowUp",
|
|
163
|
+
direction: "source"
|
|
164
|
+
},
|
|
165
|
+
child: {
|
|
166
|
+
key: "Enter",
|
|
167
|
+
direction: "target"
|
|
168
|
+
},
|
|
169
|
+
parent: {
|
|
170
|
+
key: "Backspace",
|
|
171
|
+
direction: "source"
|
|
172
|
+
},
|
|
173
|
+
exit: {
|
|
174
|
+
key: "Escape",
|
|
175
|
+
direction: "target"
|
|
176
|
+
},
|
|
177
|
+
undo: {
|
|
178
|
+
key: "Period",
|
|
179
|
+
direction: "target"
|
|
180
|
+
},
|
|
181
|
+
legend: {
|
|
182
|
+
key: "KeyL",
|
|
183
|
+
direction: "target"
|
|
184
|
+
}
|
|
283
185
|
};
|
|
284
186
|
var NodeElementDefaults = {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
187
|
+
cssClass: void 0,
|
|
188
|
+
spatialProperties: {
|
|
189
|
+
x: 0,
|
|
190
|
+
y: 0,
|
|
191
|
+
width: 0,
|
|
192
|
+
height: 0,
|
|
193
|
+
path: ""
|
|
194
|
+
},
|
|
195
|
+
semantics: {
|
|
196
|
+
label: "",
|
|
197
|
+
elementType: "div",
|
|
198
|
+
role: "image",
|
|
199
|
+
attributes: void 0
|
|
200
|
+
},
|
|
201
|
+
parentSemantics: {
|
|
202
|
+
label: "",
|
|
203
|
+
elementType: "figure",
|
|
204
|
+
role: "figure",
|
|
205
|
+
attributes: void 0
|
|
206
|
+
},
|
|
207
|
+
existingElement: {
|
|
208
|
+
useForSpatialProperties: false,
|
|
209
|
+
spatialProperties: void 0
|
|
210
|
+
}
|
|
309
211
|
};
|
|
212
|
+
|
|
310
213
|
// src/utilities.ts
|
|
311
|
-
var describeNode =
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
214
|
+
var describeNode = (d, descriptionOptions) => {
|
|
215
|
+
const keys = Object.keys(d);
|
|
216
|
+
let description = "";
|
|
217
|
+
keys.forEach((key) => {
|
|
218
|
+
description += `${descriptionOptions && descriptionOptions.omitKeyNames ? "" : key + ": "}${d[key]}. `;
|
|
219
|
+
});
|
|
220
|
+
description += descriptionOptions && descriptionOptions.semanticLabel || "Data point.";
|
|
221
|
+
return description;
|
|
319
222
|
};
|
|
320
|
-
var createValidId =
|
|
321
|
-
|
|
223
|
+
var createValidId = (s) => {
|
|
224
|
+
return "_" + s.replace(/[^a-zA-Z0-9_-]+/g, "_");
|
|
322
225
|
};
|
|
226
|
+
|
|
323
227
|
// src/structure.ts
|
|
324
|
-
var structure_default =
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
228
|
+
var structure_default = (options) => {
|
|
229
|
+
if (options.dataType === "vega-lite" || options.dataType === "vl" || options.dataType === "Vega-Lite") {
|
|
230
|
+
return buildNodeStructureFromVegaLite(options);
|
|
231
|
+
} else {
|
|
232
|
+
return buildStructure(options);
|
|
233
|
+
}
|
|
330
234
|
};
|
|
331
|
-
var buildNodeStructureFromVegaLite =
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
if (!edges[previousEdge]) {
|
|
370
|
-
edges[previousEdge] = {
|
|
371
|
-
source: previousId,
|
|
372
|
-
target: node.id,
|
|
373
|
-
navigationRules: [
|
|
374
|
-
"left",
|
|
375
|
-
"right"
|
|
376
|
-
]
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
var next = parent.items[index + 1];
|
|
382
|
-
if (next) {
|
|
383
|
-
var nextId = idBuilder(next, level);
|
|
384
|
-
if (nodes[nextId]) {
|
|
385
|
-
var nextEdge = "".concat(node.id, "-").concat(nextId);
|
|
386
|
-
edgeList.push(nextEdge);
|
|
387
|
-
if (!edges[nextEdge]) {
|
|
388
|
-
edges[nextEdge] = {
|
|
389
|
-
source: node.id,
|
|
390
|
-
target: nextId,
|
|
391
|
-
navigationRules: [
|
|
392
|
-
"left",
|
|
393
|
-
"right"
|
|
394
|
-
]
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
if (level === "group" && parent.items[index].items) {
|
|
400
|
-
var g = parent.items[index].items[0].mark.items[0].items || parent.items[index].items;
|
|
401
|
-
var firstChild = g[0];
|
|
402
|
-
var firstChildId = idBuilder(firstChild, "item");
|
|
403
|
-
if (nodes[firstChildId]) {
|
|
404
|
-
var firstChildEdge = "".concat(node.id, "-").concat(firstChildId);
|
|
405
|
-
edgeList.push(firstChildEdge);
|
|
406
|
-
if (!edges[firstChildEdge]) {
|
|
407
|
-
edges[firstChildEdge] = {
|
|
408
|
-
source: node.id,
|
|
409
|
-
target: firstChildId,
|
|
410
|
-
navigationRules: [
|
|
411
|
-
"parent",
|
|
412
|
-
"child"
|
|
413
|
-
]
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
} else if (level === "item") {
|
|
418
|
-
var parentId = idBuilder(parent, "group");
|
|
419
|
-
if (nodes[parentId]) {
|
|
420
|
-
var parentEdge = "".concat(parentId, "-").concat(node.id);
|
|
421
|
-
edgeList.push(parentEdge);
|
|
422
|
-
if (!edges[parentEdge]) {
|
|
423
|
-
edges[parentEdge] = {
|
|
424
|
-
source: parentId,
|
|
425
|
-
target: node.id,
|
|
426
|
-
navigationRules: [
|
|
427
|
-
"parent",
|
|
428
|
-
"child"
|
|
429
|
-
]
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
}
|
|
235
|
+
var buildNodeStructureFromVegaLite = (options) => {
|
|
236
|
+
let navigationRules = GenericLimitedNavigationRules;
|
|
237
|
+
let nodes = {};
|
|
238
|
+
let edges = {};
|
|
239
|
+
let elementData = {};
|
|
240
|
+
let total = 0;
|
|
241
|
+
const includeGroup = options.groupInclusionCriteria ? options.groupInclusionCriteria : () => true;
|
|
242
|
+
const includeItem = options.itemInclusionCriteria ? options.itemInclusionCriteria : () => true;
|
|
243
|
+
const includeDataProperties = options.datumInclusionCriteria ? options.datumInclusionCriteria : () => true;
|
|
244
|
+
const offset = options.vegaLiteView._renderer._origin;
|
|
245
|
+
const groupParent = options.vegaLiteView._scenegraph.root.items[0].mark.items[0];
|
|
246
|
+
const idBuilder = (i2, level) => {
|
|
247
|
+
if (i2["data-navigator-id"]) {
|
|
248
|
+
return i2["data-navigator-id"];
|
|
249
|
+
}
|
|
250
|
+
const id = `dn-node-${level}-${total}`;
|
|
251
|
+
total++;
|
|
252
|
+
i2["data-navigator-id"] = id;
|
|
253
|
+
return id;
|
|
254
|
+
};
|
|
255
|
+
const edgeBuilder = (id) => {
|
|
256
|
+
const node = nodes[id];
|
|
257
|
+
const index = node.index;
|
|
258
|
+
const level = node.level;
|
|
259
|
+
const parent = node.parent;
|
|
260
|
+
const edgeList = [];
|
|
261
|
+
const previous = parent.items[index - 1];
|
|
262
|
+
if (previous) {
|
|
263
|
+
const previousId = idBuilder(previous, level);
|
|
264
|
+
if (nodes[previousId]) {
|
|
265
|
+
const previousEdge = `${previousId}-${node.id}`;
|
|
266
|
+
edgeList.push(previousEdge);
|
|
267
|
+
if (!edges[previousEdge]) {
|
|
268
|
+
edges[previousEdge] = {
|
|
269
|
+
source: previousId,
|
|
270
|
+
target: node.id,
|
|
271
|
+
navigationRules: ["left", "right"]
|
|
272
|
+
};
|
|
433
273
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const next = parent.items[index + 1];
|
|
277
|
+
if (next) {
|
|
278
|
+
const nextId = idBuilder(next, level);
|
|
279
|
+
if (nodes[nextId]) {
|
|
280
|
+
const nextEdge = `${node.id}-${nextId}`;
|
|
281
|
+
edgeList.push(nextEdge);
|
|
282
|
+
if (!edges[nextEdge]) {
|
|
283
|
+
edges[nextEdge] = {
|
|
284
|
+
source: node.id,
|
|
285
|
+
target: nextId,
|
|
286
|
+
navigationRules: ["left", "right"]
|
|
287
|
+
};
|
|
445
288
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
if (level === "group" && parent.items[index].items) {
|
|
292
|
+
const g = parent.items[index].items[0].mark.items[0].items || parent.items[index].items;
|
|
293
|
+
const firstChild = g[0];
|
|
294
|
+
const firstChildId = idBuilder(firstChild, "item");
|
|
295
|
+
if (nodes[firstChildId]) {
|
|
296
|
+
const firstChildEdge = `${node.id}-${firstChildId}`;
|
|
297
|
+
edgeList.push(firstChildEdge);
|
|
298
|
+
if (!edges[firstChildEdge]) {
|
|
299
|
+
edges[firstChildEdge] = {
|
|
300
|
+
source: node.id,
|
|
301
|
+
target: firstChildId,
|
|
302
|
+
navigationRules: ["parent", "child"]
|
|
303
|
+
};
|
|
455
304
|
}
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
nodes[id].renderId = renderId;
|
|
469
|
-
nodes[id].index = index;
|
|
470
|
-
nodes[id].level = level;
|
|
471
|
-
nodes[id].parent = parent;
|
|
472
|
-
elementData[renderId] = {};
|
|
473
|
-
elementData[renderId].renderId = renderId;
|
|
474
|
-
elementData[renderId].spatialProperties = {};
|
|
475
|
-
elementData[renderId].spatialProperties.x = item.bounds.x1 + o[0];
|
|
476
|
-
elementData[renderId].spatialProperties.y = item.bounds.y1 + o[1];
|
|
477
|
-
elementData[renderId].spatialProperties.width = item.bounds.x2 - item.bounds.x1;
|
|
478
|
-
elementData[renderId].spatialProperties.height = item.bounds.y2 - item.bounds.y1;
|
|
479
|
-
elementData[renderId].cssClass = "dn-vega-lite-node";
|
|
480
|
-
if (item.datum) {
|
|
481
|
-
Object.keys(item.datum).forEach(function(key) {
|
|
482
|
-
var value = item.datum[key];
|
|
483
|
-
if (includeDataProperties(key, value, item.datum, level, options.vegaLiteSpec)) {
|
|
484
|
-
nodes[id].d[options.keyRenamingHash && options.keyRenamingHash[key] ? options.keyRenamingHash[key] : key] = value;
|
|
485
|
-
}
|
|
486
|
-
});
|
|
305
|
+
}
|
|
306
|
+
} else if (level === "item") {
|
|
307
|
+
const parentId = idBuilder(parent, "group");
|
|
308
|
+
if (nodes[parentId]) {
|
|
309
|
+
const parentEdge = `${parentId}-${node.id}`;
|
|
310
|
+
edgeList.push(parentEdge);
|
|
311
|
+
if (!edges[parentEdge]) {
|
|
312
|
+
edges[parentEdge] = {
|
|
313
|
+
source: parentId,
|
|
314
|
+
target: node.id,
|
|
315
|
+
navigationRules: ["parent", "child"]
|
|
316
|
+
};
|
|
487
317
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (options.exitFunction) {
|
|
321
|
+
edgeList.push("any-exit");
|
|
322
|
+
if (!edges["any-exit"]) {
|
|
323
|
+
edges["any-exit"] = {
|
|
324
|
+
source: options.getCurrent,
|
|
325
|
+
target: options.exitFunction,
|
|
326
|
+
navigationRules: ["exit"]
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
edgeList.push("any-undo");
|
|
331
|
+
if (!edges["any-undo"]) {
|
|
332
|
+
edges["any-undo"] = {
|
|
333
|
+
source: options.getCurrent,
|
|
334
|
+
target: options.getPrevious,
|
|
335
|
+
navigationRules: ["undo"]
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
return edgeList;
|
|
339
|
+
};
|
|
340
|
+
const nodeBuilder = (item, level, offset2, index, parent) => {
|
|
341
|
+
const id = idBuilder(item, level);
|
|
342
|
+
const renderId = "render-" + id;
|
|
343
|
+
const o = offset2 || [0, 0];
|
|
344
|
+
nodes[id] = {};
|
|
345
|
+
nodes[id].d = {};
|
|
346
|
+
nodes[id].id = id;
|
|
347
|
+
nodes[id].renderId = renderId;
|
|
348
|
+
nodes[id].index = index;
|
|
349
|
+
nodes[id].level = level;
|
|
350
|
+
nodes[id].parent = parent;
|
|
351
|
+
elementData[renderId] = {};
|
|
352
|
+
elementData[renderId].renderId = renderId;
|
|
353
|
+
elementData[renderId].spatialProperties = {};
|
|
354
|
+
elementData[renderId].spatialProperties.x = item.bounds.x1 + o[0];
|
|
355
|
+
elementData[renderId].spatialProperties.y = item.bounds.y1 + o[1];
|
|
356
|
+
elementData[renderId].spatialProperties.width = item.bounds.x2 - item.bounds.x1;
|
|
357
|
+
elementData[renderId].spatialProperties.height = item.bounds.y2 - item.bounds.y1;
|
|
358
|
+
elementData[renderId].cssClass = "dn-vega-lite-node";
|
|
359
|
+
if (item.datum) {
|
|
360
|
+
Object.keys(item.datum).forEach((key) => {
|
|
361
|
+
const value = item.datum[key];
|
|
362
|
+
if (includeDataProperties(key, value, item.datum, level, options.vegaLiteSpec)) {
|
|
363
|
+
nodes[id].d[options.keyRenamingHash && options.keyRenamingHash[key] ? options.keyRenamingHash[key] : key] = value;
|
|
504
364
|
}
|
|
505
|
-
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
options.data.forEach(function(d) {
|
|
521
|
-
var id = typeof options.idKey === "function" ? options.idKey(d) : options.idKey;
|
|
522
|
-
d[id] = "_" + i;
|
|
523
|
-
if (options.keysForIdGeneration) {
|
|
524
|
-
options.keysForIdGeneration.forEach(function(k) {
|
|
525
|
-
if (k in d) {
|
|
526
|
-
if (typeof d[k] === "string") {
|
|
527
|
-
if (!keyCounter[k]) {
|
|
528
|
-
keyCounter[k] = 0;
|
|
529
|
-
}
|
|
530
|
-
if (!keyCounter[d[k]]) {
|
|
531
|
-
keyCounter[d[k]] = 0;
|
|
532
|
-
}
|
|
533
|
-
d[id] += "_" + k + keyCounter[k] + "_" + d[k] + keyCounter[d[k]];
|
|
534
|
-
keyCounter[k]++;
|
|
535
|
-
keyCounter[d[k]]++;
|
|
536
|
-
} else {
|
|
537
|
-
if (!keyCounter[k]) {
|
|
538
|
-
keyCounter[k] = 0;
|
|
539
|
-
}
|
|
540
|
-
d[id] += "_" + k + keyCounter[k];
|
|
541
|
-
keyCounter[k]++;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
});
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
elementData[renderId].semantics = {};
|
|
368
|
+
elementData[renderId].semantics.label = options.nodeDescriber ? options.nodeDescriber(nodes[id].d, item, level) : describeNode(nodes[id].d);
|
|
369
|
+
};
|
|
370
|
+
let i = 0;
|
|
371
|
+
const groups = groupParent.items;
|
|
372
|
+
groups.forEach((group) => {
|
|
373
|
+
if (includeGroup(group, i, options.vegaLiteSpec)) {
|
|
374
|
+
nodeBuilder(group, "group", offset, i, groupParent);
|
|
375
|
+
let j = 0;
|
|
376
|
+
const g = group.items[0].mark.items[0].items ? group.items[0].mark.items[0] : group;
|
|
377
|
+
g.items.forEach((item) => {
|
|
378
|
+
if (includeItem(item, j, group, options.vegaLiteSpec)) {
|
|
379
|
+
nodeBuilder(item, "item", offset, j, g);
|
|
545
380
|
}
|
|
546
|
-
|
|
547
|
-
|
|
381
|
+
j++;
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
i++;
|
|
385
|
+
});
|
|
386
|
+
Object.keys(nodes).forEach((n) => {
|
|
387
|
+
nodes[n].edges = edgeBuilder(n);
|
|
388
|
+
});
|
|
389
|
+
return {
|
|
390
|
+
nodes,
|
|
391
|
+
edges,
|
|
392
|
+
elementData,
|
|
393
|
+
navigationRules
|
|
394
|
+
};
|
|
548
395
|
};
|
|
549
|
-
var
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
if (
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
396
|
+
var addSimpleDataIDs = (options) => {
|
|
397
|
+
let i = 0;
|
|
398
|
+
let keyCounter = {};
|
|
399
|
+
options.data.forEach((d) => {
|
|
400
|
+
const id = typeof options.idKey === "function" ? options.idKey(d) : options.idKey;
|
|
401
|
+
d[id] = "_" + i;
|
|
402
|
+
if (options.keysForIdGeneration) {
|
|
403
|
+
options.keysForIdGeneration.forEach((k) => {
|
|
404
|
+
if (k in d) {
|
|
405
|
+
if (typeof d[k] === "string") {
|
|
406
|
+
if (!keyCounter[k]) {
|
|
407
|
+
keyCounter[k] = 0;
|
|
408
|
+
}
|
|
409
|
+
if (!keyCounter[d[k]]) {
|
|
410
|
+
keyCounter[d[k]] = 0;
|
|
411
|
+
}
|
|
412
|
+
d[id] += "_" + k + keyCounter[k] + "_" + d[k] + keyCounter[d[k]];
|
|
413
|
+
keyCounter[k]++;
|
|
414
|
+
keyCounter[d[k]]++;
|
|
415
|
+
} else {
|
|
416
|
+
if (!keyCounter[k]) {
|
|
417
|
+
keyCounter[k] = 0;
|
|
418
|
+
}
|
|
419
|
+
d[id] += "_" + k + keyCounter[k];
|
|
420
|
+
keyCounter[k]++;
|
|
421
|
+
}
|
|
572
422
|
}
|
|
573
|
-
|
|
574
|
-
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
i++;
|
|
426
|
+
});
|
|
575
427
|
};
|
|
576
|
-
var
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
if (
|
|
580
|
-
|
|
581
|
-
nodes
|
|
582
|
-
|
|
583
|
-
});
|
|
428
|
+
var buildNodes = (options) => {
|
|
429
|
+
let nodes = {};
|
|
430
|
+
options.data.forEach((d) => {
|
|
431
|
+
if (!options.idKey) {
|
|
432
|
+
console.error(
|
|
433
|
+
`Building nodes. A key string must be supplied in options.idKey to specify the id keys of every node.`
|
|
434
|
+
);
|
|
584
435
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
436
|
+
const idKey = typeof options.idKey === "function" ? options.idKey(d) : options.idKey;
|
|
437
|
+
const id = d[idKey];
|
|
438
|
+
if (!id) {
|
|
439
|
+
console.error(
|
|
440
|
+
`Building nodes. Each datum in options.data must contain an id. When matching the id key string ${idKey}, this datum has no id: ${JSON.stringify(
|
|
441
|
+
d
|
|
442
|
+
)}.`
|
|
443
|
+
);
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (!nodes[id]) {
|
|
447
|
+
const renderIdKey = typeof options.renderIdKey === "function" ? options.renderIdKey(d) : options.renderIdKey;
|
|
448
|
+
nodes[id] = {
|
|
449
|
+
id,
|
|
450
|
+
edges: [],
|
|
451
|
+
renderId: renderIdKey ? d[renderIdKey] || "" : d.renderIdKey || "",
|
|
452
|
+
data: d
|
|
453
|
+
};
|
|
454
|
+
} else {
|
|
455
|
+
console.error(
|
|
456
|
+
`Building nodes. Each id for data in options.data must be unique. This id is not unique: ${id}.`
|
|
457
|
+
);
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
return nodes;
|
|
462
|
+
};
|
|
463
|
+
var scaffoldDimensions = (options, nodes) => {
|
|
464
|
+
var _a, _b;
|
|
465
|
+
let dimensions = {};
|
|
466
|
+
if ((_b = (_a = options.dimensions) == null ? void 0 : _a.parentOptions) == null ? void 0 : _b.addLevel0) {
|
|
467
|
+
let level0 = options.dimensions.parentOptions.addLevel0;
|
|
468
|
+
nodes[level0.id] = __spreadProps(__spreadValues({}, level0), { dimensionLevel: 0 });
|
|
469
|
+
}
|
|
470
|
+
let rules = [...GenericFullNavigationDimensions];
|
|
471
|
+
const setExtents = (val, dim) => {
|
|
472
|
+
let min = dim.numericalExtents[0];
|
|
473
|
+
let max = dim.numericalExtents[1];
|
|
474
|
+
dim.numericalExtents[0] = min < val ? min : val;
|
|
475
|
+
dim.numericalExtents[1] = max > val ? max : val;
|
|
476
|
+
};
|
|
477
|
+
options.data.forEach((d) => {
|
|
478
|
+
let ods = options.dimensions.values || [];
|
|
479
|
+
let i = 0;
|
|
480
|
+
ods.forEach((dim) => {
|
|
481
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h;
|
|
482
|
+
if (!dim.dimensionKey) {
|
|
483
|
+
console.error(
|
|
484
|
+
`Building nodes, parsing dimensions. Each dimension in options.dimensions must contain a dimensionKey. This dimension has no key: ${JSON.stringify(
|
|
485
|
+
dim
|
|
486
|
+
)}.`
|
|
487
|
+
);
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
if (dim.dimensionKey in d) {
|
|
491
|
+
let value = d[dim.dimensionKey];
|
|
492
|
+
let keepValue = typeof ((_a2 = dim.operations) == null ? void 0 : _a2.filterFunction) === "function" ? dim.operations.filterFunction(d, dim) : true;
|
|
493
|
+
if (value !== void 0 && keepValue) {
|
|
494
|
+
if (!dim.type) {
|
|
495
|
+
dim.type = typeof value === "bigint" || typeof value === "number" ? "numerical" : "categorical";
|
|
496
|
+
}
|
|
497
|
+
if (!dimensions[dim.dimensionKey]) {
|
|
498
|
+
let id2 = typeof dim.nodeId === "function" ? dim.nodeId(dim, options.data) : dim.nodeId || createValidId(dim.dimensionKey);
|
|
499
|
+
let renderId = typeof dim.renderId === "function" ? dim.renderId(dim, options.data) : dim.renderId || id2;
|
|
500
|
+
dimensions[dim.dimensionKey] = {
|
|
501
|
+
dimensionKey: dim.dimensionKey,
|
|
502
|
+
nodeId: id2,
|
|
503
|
+
divisions: {},
|
|
504
|
+
numericalExtents: [Infinity, -Infinity],
|
|
505
|
+
type: dim.type,
|
|
506
|
+
operations: {
|
|
507
|
+
compressSparseDivisions: ((_b2 = dim.operations) == null ? void 0 : _b2.compressSparseDivisions) || false,
|
|
508
|
+
sortFunction: ((_c = dim.operations) == null ? void 0 : _c.sortFunction) || void 0
|
|
509
|
+
},
|
|
510
|
+
behavior: dim.behavior || {
|
|
511
|
+
extents: "circular"
|
|
512
|
+
},
|
|
513
|
+
navigationRules: dim.navigationRules || {
|
|
514
|
+
sibling_sibling: rules.length ? [...rules.shift()] : ["previous_" + dim.dimensionKey, "next_" + dim.dimensionKey],
|
|
515
|
+
parent_child: ["parent_" + dim.dimensionKey, "child"]
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
nodes[id2] = {
|
|
519
|
+
id: id2,
|
|
520
|
+
renderId,
|
|
521
|
+
derivedNode: dim.dimensionKey,
|
|
522
|
+
edges: [],
|
|
523
|
+
dimensionLevel: 1,
|
|
524
|
+
data: dimensions[dim.dimensionKey],
|
|
525
|
+
renderingStrategy: dim.renderingStrategy || "singleSquare"
|
|
526
|
+
// not sure what defaults we want yet
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
let dimension = dimensions[dim.dimensionKey];
|
|
530
|
+
let targetDivision = null;
|
|
531
|
+
if (dim.type === "categorical") {
|
|
532
|
+
let divisionId = typeof ((_d = dim.divisionOptions) == null ? void 0 : _d.divisionNodeIds) === "function" ? dim.divisionOptions.divisionNodeIds(dim.dimensionKey, value, i) : createValidId(dimension.nodeId + "_" + value);
|
|
533
|
+
targetDivision = dimension.divisions[divisionId];
|
|
534
|
+
if (!targetDivision) {
|
|
535
|
+
targetDivision = dimension.divisions[divisionId] = {
|
|
536
|
+
id: divisionId,
|
|
537
|
+
sortFunction: ((_e = dim.divisionOptions) == null ? void 0 : _e.sortFunction) || void 0,
|
|
538
|
+
values: {}
|
|
539
|
+
};
|
|
540
|
+
let divisionRenderId = typeof ((_f = dim.divisionOptions) == null ? void 0 : _f.divisionRenderIds) === "function" ? dim.divisionOptions.divisionRenderIds(dim.dimensionKey, value, i) : divisionId;
|
|
541
|
+
nodes[divisionId] = {
|
|
542
|
+
id: divisionId,
|
|
543
|
+
renderId: divisionRenderId,
|
|
544
|
+
derivedNode: dim.dimensionKey,
|
|
545
|
+
edges: [],
|
|
546
|
+
dimensionLevel: 2,
|
|
547
|
+
data: __spreadValues({}, targetDivision),
|
|
548
|
+
renderingStrategy: ((_g = dim.divisionOptions) == null ? void 0 : _g.renderingStrategy) || "singleSquare"
|
|
549
|
+
// not sure what defaults we want yet
|
|
550
|
+
};
|
|
551
|
+
nodes[divisionId].data[dim.dimensionKey] = value;
|
|
599
552
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
if (!dimensions[dim.dimensionKey]) {
|
|
609
|
-
var _dim_operations1, _dim_operations2;
|
|
610
|
-
var id2 = typeof dim.nodeId === "function" ? dim.nodeId(dim, options.data) : dim.nodeId || createValidId(dim.dimensionKey);
|
|
611
|
-
var renderId = typeof dim.renderId === "function" ? dim.renderId(dim, options.data) : dim.renderId || id2;
|
|
612
|
-
dimensions[dim.dimensionKey] = {
|
|
613
|
-
dimensionKey: dim.dimensionKey,
|
|
614
|
-
nodeId: id2,
|
|
615
|
-
divisions: {},
|
|
616
|
-
numericalExtents: [
|
|
617
|
-
Infinity,
|
|
618
|
-
-Infinity
|
|
619
|
-
],
|
|
620
|
-
type: dim.type,
|
|
621
|
-
operations: {
|
|
622
|
-
compressSparseDivisions: ((_dim_operations1 = dim.operations) === null || _dim_operations1 === void 0 ? void 0 : _dim_operations1.compressSparseDivisions) || false,
|
|
623
|
-
sortFunction: ((_dim_operations2 = dim.operations) === null || _dim_operations2 === void 0 ? void 0 : _dim_operations2.sortFunction) || void 0
|
|
624
|
-
},
|
|
625
|
-
behavior: dim.behavior || {
|
|
626
|
-
extents: "circular"
|
|
627
|
-
},
|
|
628
|
-
navigationRules: dim.navigationRules || {
|
|
629
|
-
sibling_sibling: rules.length ? _to_consumable_array(rules.shift()) : [
|
|
630
|
-
"previous_" + dim.dimensionKey,
|
|
631
|
-
"next_" + dim.dimensionKey
|
|
632
|
-
],
|
|
633
|
-
parent_child: [
|
|
634
|
-
"parent_" + dim.dimensionKey,
|
|
635
|
-
"child"
|
|
636
|
-
]
|
|
637
|
-
}
|
|
638
|
-
};
|
|
639
|
-
nodes[id2] = {
|
|
640
|
-
id: id2,
|
|
641
|
-
renderId: renderId,
|
|
642
|
-
derivedNode: dim.dimensionKey,
|
|
643
|
-
edges: [],
|
|
644
|
-
dimensionLevel: 1,
|
|
645
|
-
data: dimensions[dim.dimensionKey],
|
|
646
|
-
renderingStrategy: dim.renderingStrategy || "singleSquare"
|
|
647
|
-
};
|
|
648
|
-
}
|
|
649
|
-
var dimension = dimensions[dim.dimensionKey];
|
|
650
|
-
var targetDivision = null;
|
|
651
|
-
if (dim.type === "categorical") {
|
|
652
|
-
var _dim_divisionOptions;
|
|
653
|
-
var divisionId = typeof ((_dim_divisionOptions = dim.divisionOptions) === null || _dim_divisionOptions === void 0 ? void 0 : _dim_divisionOptions.divisionNodeIds) === "function" ? dim.divisionOptions.divisionNodeIds(dim.dimensionKey, value, i) : createValidId(dimension.nodeId + "_" + value);
|
|
654
|
-
targetDivision = dimension.divisions[divisionId];
|
|
655
|
-
if (!targetDivision) {
|
|
656
|
-
var _dim_divisionOptions1, _dim_divisionOptions2, _dim_divisionOptions3;
|
|
657
|
-
targetDivision = dimension.divisions[divisionId] = {
|
|
658
|
-
id: divisionId,
|
|
659
|
-
sortFunction: ((_dim_divisionOptions1 = dim.divisionOptions) === null || _dim_divisionOptions1 === void 0 ? void 0 : _dim_divisionOptions1.sortFunction) || void 0,
|
|
660
|
-
values: {}
|
|
661
|
-
};
|
|
662
|
-
var divisionRenderId = typeof ((_dim_divisionOptions2 = dim.divisionOptions) === null || _dim_divisionOptions2 === void 0 ? void 0 : _dim_divisionOptions2.divisionRenderIds) === "function" ? dim.divisionOptions.divisionRenderIds(dim.dimensionKey, value, i) : divisionId;
|
|
663
|
-
nodes[divisionId] = {
|
|
664
|
-
id: divisionId,
|
|
665
|
-
renderId: divisionRenderId,
|
|
666
|
-
derivedNode: dim.dimensionKey,
|
|
667
|
-
edges: [],
|
|
668
|
-
dimensionLevel: 2,
|
|
669
|
-
data: _object_spread({}, targetDivision),
|
|
670
|
-
renderingStrategy: ((_dim_divisionOptions3 = dim.divisionOptions) === null || _dim_divisionOptions3 === void 0 ? void 0 : _dim_divisionOptions3.renderingStrategy) || "singleSquare"
|
|
671
|
-
};
|
|
672
|
-
nodes[divisionId].data[dim.dimensionKey] = value;
|
|
673
|
-
}
|
|
674
|
-
} else {
|
|
675
|
-
targetDivision = dimension.divisions[dimension.nodeId];
|
|
676
|
-
if (!targetDivision) {
|
|
677
|
-
var _dim_divisionOptions4;
|
|
678
|
-
targetDivision = dimension.divisions[dimension.nodeId] = {
|
|
679
|
-
id: dimension.nodeId,
|
|
680
|
-
sortFunction: ((_dim_divisionOptions4 = dim.divisionOptions) === null || _dim_divisionOptions4 === void 0 ? void 0 : _dim_divisionOptions4.sortFunction) || void 0,
|
|
681
|
-
values: {}
|
|
682
|
-
};
|
|
683
|
-
}
|
|
684
|
-
if (!dim.operations) {
|
|
685
|
-
dim.operations = {};
|
|
686
|
-
}
|
|
687
|
-
var subdivs = dim.operations.createNumericalSubdivisions;
|
|
688
|
-
dimension.subdivisions = typeof subdivs === "number" && subdivs < 1 ? 1 : subdivs || 1;
|
|
689
|
-
if (subdivs !== 1) {
|
|
690
|
-
if (!dimension.divisionOptions) {
|
|
691
|
-
dimension.divisionOptions = dim.divisionOptions;
|
|
692
|
-
}
|
|
693
|
-
setExtents(value, dimension);
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
var id = typeof options.idKey === "function" ? options.idKey(d) : options.idKey;
|
|
697
|
-
targetDivision.values[d[id]] = d;
|
|
698
|
-
}
|
|
553
|
+
} else {
|
|
554
|
+
targetDivision = dimension.divisions[dimension.nodeId];
|
|
555
|
+
if (!targetDivision) {
|
|
556
|
+
targetDivision = dimension.divisions[dimension.nodeId] = {
|
|
557
|
+
id: dimension.nodeId,
|
|
558
|
+
sortFunction: ((_h = dim.divisionOptions) == null ? void 0 : _h.sortFunction) || void 0,
|
|
559
|
+
values: {}
|
|
560
|
+
};
|
|
699
561
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
});
|
|
703
|
-
Object.keys(dimensions).forEach(function(s) {
|
|
704
|
-
var _dimension_operations;
|
|
705
|
-
var dimension = dimensions[s];
|
|
706
|
-
var divisions = dimension.divisions;
|
|
707
|
-
if (dimension.type === "numerical") {
|
|
708
|
-
divisions[dimension.nodeId].values = Object.fromEntries(Object.entries(divisions[dimension.nodeId].values).sort(function(a, b) {
|
|
709
|
-
var _dimension_operations;
|
|
710
|
-
return typeof ((_dimension_operations = dimension.operations) === null || _dimension_operations === void 0 ? void 0 : _dimension_operations.sortFunction) === "function" ? dimension.operations.sortFunction(a[1], b[1], dimension) : a[1][s] - b[1][s];
|
|
711
|
-
}));
|
|
712
|
-
var values = divisions[dimension.nodeId].values;
|
|
713
|
-
if (dimension.numericalExtents[0] !== Infinity && dimension.subdivisions !== 1) {
|
|
714
|
-
var valueKeys = Object.keys(values);
|
|
715
|
-
var subDivisions = typeof dimension.subdivisions === "function" ? dimension.subdivisions(s, values) : dimension.subdivisions;
|
|
716
|
-
var range = dimension.numericalExtents[1] - dimension.numericalExtents[0];
|
|
717
|
-
var interval = range / subDivisions;
|
|
718
|
-
var i = dimension.numericalExtents[0] + interval;
|
|
719
|
-
var divisionCount = 0;
|
|
720
|
-
var index = 0;
|
|
721
|
-
for(i = dimension.numericalExtents[0] + interval; i <= dimension.numericalExtents[1]; i += interval){
|
|
722
|
-
var _dimension_divisionOptions, _dimension_divisionOptions1, _dimension_divisionOptions2, _dimension_divisionOptions3;
|
|
723
|
-
var divisionId = typeof ((_dimension_divisionOptions = dimension.divisionOptions) === null || _dimension_divisionOptions === void 0 ? void 0 : _dimension_divisionOptions.divisionNodeIds) === "function" ? dimension.divisionOptions.divisionNodeIds(s, i, i) : dimension.nodeId + "_" + i;
|
|
724
|
-
dimension.divisions[divisionId] = {
|
|
725
|
-
id: divisionId,
|
|
726
|
-
sortFunction: ((_dimension_divisionOptions1 = dimension.divisionOptions) === null || _dimension_divisionOptions1 === void 0 ? void 0 : _dimension_divisionOptions1.sortFunction) || void 0,
|
|
727
|
-
values: {}
|
|
728
|
-
};
|
|
729
|
-
var divisionRenderId = typeof ((_dimension_divisionOptions2 = dimension.divisionOptions) === null || _dimension_divisionOptions2 === void 0 ? void 0 : _dimension_divisionOptions2.divisionRenderIds) === "function" ? dimension.divisionOptions.divisionRenderIds(s, i, i) : divisionId;
|
|
730
|
-
nodes[divisionId] = {
|
|
731
|
-
id: divisionId,
|
|
732
|
-
renderId: divisionRenderId,
|
|
733
|
-
derivedNode: s,
|
|
734
|
-
edges: [],
|
|
735
|
-
data: dimension.divisions[divisionId],
|
|
736
|
-
dimensionLevel: 2,
|
|
737
|
-
renderingStrategy: ((_dimension_divisionOptions3 = dimension.divisionOptions) === null || _dimension_divisionOptions3 === void 0 ? void 0 : _dimension_divisionOptions3.renderingStrategy) || "singleSquare"
|
|
738
|
-
};
|
|
739
|
-
var limit = false;
|
|
740
|
-
while(!limit && index < valueKeys.length){
|
|
741
|
-
var node = values[valueKeys[index]];
|
|
742
|
-
var value = node[s];
|
|
743
|
-
if (value <= i) {
|
|
744
|
-
dimension.divisions[divisionId].values[node.id] = node;
|
|
745
|
-
} else {
|
|
746
|
-
i += interval;
|
|
747
|
-
limit = true;
|
|
748
|
-
}
|
|
749
|
-
index++;
|
|
750
|
-
}
|
|
751
|
-
divisionCount++;
|
|
752
|
-
}
|
|
753
|
-
delete divisions[s];
|
|
562
|
+
if (!dim.operations) {
|
|
563
|
+
dim.operations = {};
|
|
754
564
|
}
|
|
755
|
-
|
|
756
|
-
dimension.
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
var division = dimension.divisions[d];
|
|
763
|
-
if (typeof division.sortFunction === "function") {
|
|
764
|
-
division.values = Object.fromEntries(Object.entries(division.values).sort(function(a, b) {
|
|
765
|
-
return division.sortFunction(a[1], b[1], division);
|
|
766
|
-
}));
|
|
565
|
+
let subdivs = dim.operations.createNumericalSubdivisions;
|
|
566
|
+
dimension.subdivisions = typeof subdivs === "number" && subdivs < 1 ? 1 : subdivs || 1;
|
|
567
|
+
if (subdivs !== 1) {
|
|
568
|
+
if (!dimension.divisionOptions) {
|
|
569
|
+
dimension.divisionOptions = dim.divisionOptions;
|
|
570
|
+
}
|
|
571
|
+
setExtents(value, dimension);
|
|
767
572
|
}
|
|
768
|
-
|
|
573
|
+
}
|
|
574
|
+
const id = typeof options.idKey === "function" ? options.idKey(d) : options.idKey;
|
|
575
|
+
targetDivision.values[d[id]] = d;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
i++;
|
|
769
579
|
});
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
580
|
+
});
|
|
581
|
+
Object.keys(dimensions).forEach((s) => {
|
|
582
|
+
var _a2, _b2, _c, _d, _e;
|
|
583
|
+
let dimension = dimensions[s];
|
|
584
|
+
let divisions = dimension.divisions;
|
|
585
|
+
if (dimension.type === "numerical") {
|
|
586
|
+
divisions[dimension.nodeId].values = Object.fromEntries(
|
|
587
|
+
Object.entries(divisions[dimension.nodeId].values).sort((a, b) => {
|
|
588
|
+
var _a3;
|
|
589
|
+
return typeof ((_a3 = dimension.operations) == null ? void 0 : _a3.sortFunction) === "function" ? dimension.operations.sortFunction(a[1], b[1], dimension) : a[1][s] - b[1][s];
|
|
590
|
+
})
|
|
591
|
+
);
|
|
592
|
+
let values = divisions[dimension.nodeId].values;
|
|
593
|
+
if (dimension.numericalExtents[0] !== Infinity && dimension.subdivisions !== 1) {
|
|
594
|
+
let valueKeys = Object.keys(values);
|
|
595
|
+
let subDivisions = typeof dimension.subdivisions === "function" ? dimension.subdivisions(s, values) : dimension.subdivisions;
|
|
596
|
+
let range = dimension.numericalExtents[1] - dimension.numericalExtents[0];
|
|
597
|
+
let interval = range / subDivisions;
|
|
598
|
+
let i = dimension.numericalExtents[0] + interval;
|
|
599
|
+
let divisionCount = 0;
|
|
600
|
+
let index = 0;
|
|
601
|
+
for (i = dimension.numericalExtents[0] + interval; i <= dimension.numericalExtents[1]; i += interval) {
|
|
602
|
+
let divisionId = typeof ((_a2 = dimension.divisionOptions) == null ? void 0 : _a2.divisionNodeIds) === "function" ? dimension.divisionOptions.divisionNodeIds(s, i, i) : dimension.nodeId + "_" + i;
|
|
603
|
+
dimension.divisions[divisionId] = {
|
|
604
|
+
id: divisionId,
|
|
605
|
+
sortFunction: ((_b2 = dimension.divisionOptions) == null ? void 0 : _b2.sortFunction) || void 0,
|
|
606
|
+
values: {}
|
|
607
|
+
};
|
|
608
|
+
let divisionRenderId = typeof ((_c = dimension.divisionOptions) == null ? void 0 : _c.divisionRenderIds) === "function" ? dimension.divisionOptions.divisionRenderIds(s, i, i) : divisionId;
|
|
609
|
+
nodes[divisionId] = {
|
|
610
|
+
id: divisionId,
|
|
611
|
+
renderId: divisionRenderId,
|
|
612
|
+
derivedNode: s,
|
|
613
|
+
edges: [],
|
|
614
|
+
data: dimension.divisions[divisionId],
|
|
615
|
+
dimensionLevel: 2,
|
|
616
|
+
renderingStrategy: ((_d = dimension.divisionOptions) == null ? void 0 : _d.renderingStrategy) || "singleSquare"
|
|
617
|
+
// not sure what defaults we want yet
|
|
618
|
+
};
|
|
619
|
+
let limit = false;
|
|
620
|
+
while (!limit && index < valueKeys.length) {
|
|
621
|
+
let node = values[valueKeys[index]];
|
|
622
|
+
let value = node[s];
|
|
623
|
+
if (value <= i) {
|
|
624
|
+
dimension.divisions[divisionId].values[node.id] = node;
|
|
625
|
+
} else {
|
|
626
|
+
i += interval;
|
|
627
|
+
limit = true;
|
|
797
628
|
}
|
|
629
|
+
index++;
|
|
630
|
+
}
|
|
631
|
+
divisionCount++;
|
|
798
632
|
}
|
|
633
|
+
delete divisions[s];
|
|
634
|
+
}
|
|
635
|
+
} else if (typeof ((_e = dimension.operations) == null ? void 0 : _e.sortFunction) === "function") {
|
|
636
|
+
dimension.divisions = Object.fromEntries(
|
|
637
|
+
Object.entries(divisions).sort((a, b) => {
|
|
638
|
+
return dimension.operations.sortFunction(a[1], b[1], dimension);
|
|
639
|
+
})
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
let divisionKeys = Object.keys(dimension.divisions);
|
|
643
|
+
divisionKeys.forEach((d) => {
|
|
644
|
+
let division = dimension.divisions[d];
|
|
645
|
+
if (typeof division.sortFunction === "function") {
|
|
646
|
+
division.values = Object.fromEntries(
|
|
647
|
+
Object.entries(division.values).sort((a, b) => {
|
|
648
|
+
return division.sortFunction(a[1], b[1], division);
|
|
649
|
+
})
|
|
650
|
+
);
|
|
651
|
+
}
|
|
799
652
|
});
|
|
800
|
-
|
|
801
|
-
|
|
653
|
+
});
|
|
654
|
+
Object.keys(dimensions).forEach((s) => {
|
|
655
|
+
let dimension = dimensions[s];
|
|
656
|
+
if (dimension.operations.compressSparseDivisions) {
|
|
657
|
+
const divisionKeys = Object.keys(dimension.divisions);
|
|
658
|
+
const values = {};
|
|
659
|
+
let sparse = true;
|
|
660
|
+
divisionKeys.forEach((d) => {
|
|
661
|
+
const division = dimension.divisions[d];
|
|
662
|
+
const valueKeys = Object.keys(division.values);
|
|
663
|
+
if (valueKeys.length <= 1) {
|
|
664
|
+
valueKeys.forEach((vk) => {
|
|
665
|
+
values[vk] = __spreadValues({}, division.values[vk]);
|
|
666
|
+
});
|
|
667
|
+
} else {
|
|
668
|
+
sparse = false;
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
if (sparse) {
|
|
672
|
+
const newDivision = {
|
|
673
|
+
id: dimension.nodeId,
|
|
674
|
+
values
|
|
675
|
+
};
|
|
676
|
+
divisionKeys.forEach((d) => {
|
|
677
|
+
delete nodes[d];
|
|
678
|
+
});
|
|
679
|
+
dimension.divisions = {};
|
|
680
|
+
dimension.divisions[dimension.nodeId] = newDivision;
|
|
681
|
+
}
|
|
802
682
|
}
|
|
803
|
-
|
|
683
|
+
});
|
|
684
|
+
if (options.dimensions.adjustDimensions) {
|
|
685
|
+
dimensions = options.dimensions.adjustDimensions(dimensions);
|
|
686
|
+
}
|
|
687
|
+
return dimensions;
|
|
804
688
|
};
|
|
805
|
-
var buildEdges =
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
};
|
|
827
|
-
}
|
|
689
|
+
var buildEdges = (options, nodes, dimensions) => {
|
|
690
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
691
|
+
let edges = {};
|
|
692
|
+
const addEdgeToNode = (nodeId, edgeId) => {
|
|
693
|
+
if (nodes[nodeId].edges.indexOf(edgeId) === -1) {
|
|
694
|
+
nodes[nodeId].edges.push(edgeId);
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
const createEdge = (source, target, rules, addTo) => {
|
|
698
|
+
const id = `${source}-${target}`;
|
|
699
|
+
let targetId = !options.useDirectedEdges ? id : `${target}-${id}`;
|
|
700
|
+
let addToSource = !addTo || addTo === "source";
|
|
701
|
+
let addToTarget = !addTo || addTo === "target";
|
|
702
|
+
const checkEdgeRules = (eId) => {
|
|
703
|
+
if (edges[eId]) {
|
|
704
|
+
edges[eId].navigationRules.push(...rules || []);
|
|
705
|
+
} else {
|
|
706
|
+
edges[eId] = {
|
|
707
|
+
source,
|
|
708
|
+
target,
|
|
709
|
+
navigationRules: rules ? [...rules] : []
|
|
828
710
|
};
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
checkEdgeRules(id);
|
|
714
|
+
if (options.useDirectedEdges && addToTarget) {
|
|
715
|
+
checkEdgeRules(targetId);
|
|
716
|
+
}
|
|
717
|
+
if (addToSource) {
|
|
718
|
+
addEdgeToNode(source, id);
|
|
719
|
+
}
|
|
720
|
+
if (addToTarget) {
|
|
721
|
+
addEdgeToNode(target, targetId);
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
if (dimensions && Object.keys(dimensions).length) {
|
|
725
|
+
const dimensionKeys = Object.keys(dimensions);
|
|
726
|
+
const hasOrder = (_c = (_b = (_a = options.dimensions) == null ? void 0 : _a.parentOptions) == null ? void 0 : _b.level1Options) == null ? void 0 : _c.order;
|
|
727
|
+
let order = hasOrder || dimensionKeys;
|
|
728
|
+
let l = 0;
|
|
729
|
+
let po = ((_d = options.dimensions) == null ? void 0 : _d.parentOptions) || {};
|
|
730
|
+
let extents = ((_f = (_e = po.level1Options) == null ? void 0 : _e.behavior) == null ? void 0 : _f.extents) || "terminal";
|
|
731
|
+
let level0 = po.addLevel0;
|
|
732
|
+
let parentRules = level0 ? ((_h = (_g = po.level1Options) == null ? void 0 : _g.navigationRules) == null ? void 0 : _h.parent_child) || ["parent", "child"] : [];
|
|
733
|
+
let siblingRules = ((_j = (_i = po.level1Options) == null ? void 0 : _i.navigationRules) == null ? void 0 : _j.sibling_sibling) || ["left", "right"];
|
|
734
|
+
let firstLevel1Node = typeof order[0] === "string" ? hasOrder ? nodes[order[0]] : nodes[dimensions[order[0]].nodeId] : order[0];
|
|
735
|
+
if (level0) {
|
|
736
|
+
createEdge(level0.id, firstLevel1Node.id, parentRules, "source");
|
|
737
|
+
}
|
|
738
|
+
order.forEach((n) => {
|
|
739
|
+
let level1Node = typeof n === "string" ? hasOrder ? nodes[n] : nodes[dimensions[n].nodeId] : n;
|
|
740
|
+
if (level1Node === n && !nodes[level1Node.id]) {
|
|
741
|
+
nodes[level1Node.id] = level1Node;
|
|
742
|
+
}
|
|
743
|
+
if (level0) {
|
|
744
|
+
if (!options.useDirectedEdges) {
|
|
745
|
+
createEdge(level0.id, level1Node.id, parentRules, "target");
|
|
746
|
+
} else {
|
|
747
|
+
createEdge(level1Node.id, level0.id, parentRules, "source");
|
|
835
748
|
}
|
|
836
|
-
|
|
837
|
-
|
|
749
|
+
}
|
|
750
|
+
if (l === order.length - 1 && extents === "circular") {
|
|
751
|
+
createEdge(level1Node.id, firstLevel1Node.id, siblingRules);
|
|
752
|
+
} else if (l === order.length - 1 && extents === "bridgedCustom") {
|
|
753
|
+
createEdge(level1Node.id, po.level1Options.behavior.customBridgePost, siblingRules);
|
|
754
|
+
} else if (l < order.length - 1) {
|
|
755
|
+
let nextLevel1Node = typeof order[l + 1] === "string" ? hasOrder ? (
|
|
756
|
+
// @ts-ignore: for some reason the same use of conditional check works above for order[0] (firstLevel1Node) but not for l+1 here
|
|
757
|
+
nodes[order[l + 1]]
|
|
758
|
+
) : (
|
|
759
|
+
// @ts-ignore: for some reason the same use of conditional check works above for order[0] (firstLevel1Node) but not for l+1 here
|
|
760
|
+
nodes[dimensions[order[l + 1]].nodeId]
|
|
761
|
+
) : order[l + 1];
|
|
762
|
+
createEdge(level1Node.id, nextLevel1Node.id, siblingRules);
|
|
763
|
+
}
|
|
764
|
+
if (!l && extents === "bridgedCustom") {
|
|
765
|
+
createEdge(po.level1Options.behavior.customBridgePost, level1Node.id, siblingRules);
|
|
766
|
+
}
|
|
767
|
+
l++;
|
|
768
|
+
});
|
|
769
|
+
dimensionKeys.forEach((s) => {
|
|
770
|
+
var _a2, _b2, _c2, _d2;
|
|
771
|
+
const dimension = dimensions[s];
|
|
772
|
+
const strat = ((_a2 = dimension.behavior) == null ? void 0 : _a2.childmostNavigation) || "within";
|
|
773
|
+
const matchByIndex = (i, _a3, _b3, c) => {
|
|
774
|
+
return c.values[Object.keys(c.values)[i]] || void 0;
|
|
775
|
+
};
|
|
776
|
+
const match = strat === "across" && ((_b2 = dimension.behavior) == null ? void 0 : _b2.childmostMatching) ? (_c2 = dimension.behavior) == null ? void 0 : _c2.childmostMatching : matchByIndex;
|
|
777
|
+
let extents2 = ((_d2 = dimension.behavior) == null ? void 0 : _d2.extents) || "circular";
|
|
778
|
+
if (!dimension.divisions) {
|
|
779
|
+
console.error(
|
|
780
|
+
`Parsing dimensions. The dimension using the key ${s} is missing the divisions property. dimension.divisions should be supplied. ${JSON.stringify(
|
|
781
|
+
dimension
|
|
782
|
+
)}.`
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
let divisionKeys = Object.keys(dimension.divisions);
|
|
786
|
+
const firstDivision = dimension.divisions[divisionKeys[0]];
|
|
787
|
+
if (divisionKeys.length !== 1) {
|
|
788
|
+
createEdge(dimension.nodeId, firstDivision.id, dimension.navigationRules.parent_child, "source");
|
|
789
|
+
} else {
|
|
790
|
+
let valueKeys = Object.keys(firstDivision.values);
|
|
791
|
+
let firstChildId = typeof options.idKey === "function" ? options.idKey(firstDivision.values[valueKeys[0]]) : options.idKey;
|
|
792
|
+
createEdge(
|
|
793
|
+
dimension.nodeId,
|
|
794
|
+
firstDivision.values[valueKeys[0]][firstChildId],
|
|
795
|
+
dimension.navigationRules.parent_child,
|
|
796
|
+
"source"
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
let j = 0;
|
|
800
|
+
divisionKeys.forEach((d) => {
|
|
801
|
+
let division = dimension.divisions[d];
|
|
802
|
+
if (j === divisionKeys.length - 1 && (extents2 === "circular" || extents2 === "bridgedCousins" || extents2 === "bridgedCustom")) {
|
|
803
|
+
createEdge(
|
|
804
|
+
division.id,
|
|
805
|
+
dimension.divisions[divisionKeys[0]].id,
|
|
806
|
+
dimension.navigationRules.sibling_sibling
|
|
807
|
+
);
|
|
808
|
+
} else if (j < divisionKeys.length - 1) {
|
|
809
|
+
createEdge(
|
|
810
|
+
division.id,
|
|
811
|
+
dimension.divisions[divisionKeys[j + 1]].id,
|
|
812
|
+
dimension.navigationRules.sibling_sibling
|
|
813
|
+
);
|
|
838
814
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
var order = hasOrder || dimensionKeys;
|
|
845
|
-
var l = 0;
|
|
846
|
-
var po = ((_options_dimensions1 = options.dimensions) === null || _options_dimensions1 === void 0 ? void 0 : _options_dimensions1.parentOptions) || {};
|
|
847
|
-
var extents = ((_po_level1Options = po.level1Options) === null || _po_level1Options === void 0 ? void 0 : (_po_level1Options_behavior = _po_level1Options.behavior) === null || _po_level1Options_behavior === void 0 ? void 0 : _po_level1Options_behavior.extents) || "terminal";
|
|
848
|
-
var level0 = po.addLevel0;
|
|
849
|
-
var parentRules = level0 ? ((_po_level1Options1 = po.level1Options) === null || _po_level1Options1 === void 0 ? void 0 : (_po_level1Options_navigationRules = _po_level1Options1.navigationRules) === null || _po_level1Options_navigationRules === void 0 ? void 0 : _po_level1Options_navigationRules.parent_child) || [
|
|
850
|
-
"parent",
|
|
851
|
-
"child"
|
|
852
|
-
] : [];
|
|
853
|
-
var siblingRules = ((_po_level1Options2 = po.level1Options) === null || _po_level1Options2 === void 0 ? void 0 : (_po_level1Options_navigationRules1 = _po_level1Options2.navigationRules) === null || _po_level1Options_navigationRules1 === void 0 ? void 0 : _po_level1Options_navigationRules1.sibling_sibling) || [
|
|
854
|
-
"left",
|
|
855
|
-
"right"
|
|
856
|
-
];
|
|
857
|
-
var firstLevel1Node = typeof order[0] === "string" ? hasOrder ? nodes[order[0]] : nodes[dimensions[order[0]].nodeId] : order[0];
|
|
858
|
-
if (level0) {
|
|
859
|
-
createEdge(level0.id, firstLevel1Node.id, parentRules, "source");
|
|
815
|
+
let valueKeys = Object.keys(division.values);
|
|
816
|
+
if (!options.useDirectedEdges) {
|
|
817
|
+
createEdge(dimension.nodeId, division.id, dimension.navigationRules.parent_child, "target");
|
|
818
|
+
} else {
|
|
819
|
+
createEdge(division.id, dimension.nodeId, dimension.navigationRules.parent_child, "source");
|
|
860
820
|
}
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
createEdge(level1Node.id, po.level1Options.behavior.customBridgePost, siblingRules);
|
|
877
|
-
} else if (l < order.length - 1) {
|
|
878
|
-
var nextLevel1Node = typeof order[l + 1] === "string" ? hasOrder ? // @ts-ignore: for some reason the same use of conditional check works above for order[0] (firstLevel1Node) but not for l+1 here
|
|
879
|
-
nodes[order[l + 1]] : // @ts-ignore: for some reason the same use of conditional check works above for order[0] (firstLevel1Node) but not for l+1 here
|
|
880
|
-
nodes[dimensions[order[l + 1]].nodeId] : order[l + 1];
|
|
881
|
-
createEdge(level1Node.id, nextLevel1Node.id, siblingRules);
|
|
882
|
-
}
|
|
883
|
-
if (!l && extents === "bridgedCustom") {
|
|
884
|
-
createEdge(po.level1Options.behavior.customBridgePost, level1Node.id, siblingRules);
|
|
885
|
-
}
|
|
886
|
-
l++;
|
|
887
|
-
});
|
|
888
|
-
dimensionKeys.forEach(function(s) {
|
|
889
|
-
var _dimension_behavior, _dimension_behavior1, _dimension_behavior2, _dimension_behavior3;
|
|
890
|
-
var dimension = dimensions[s];
|
|
891
|
-
var strat = ((_dimension_behavior = dimension.behavior) === null || _dimension_behavior === void 0 ? void 0 : _dimension_behavior.childmostNavigation) || "within";
|
|
892
|
-
var matchByIndex = function matchByIndex(i, _a, _b, c) {
|
|
893
|
-
return c.values[Object.keys(c.values)[i]] || void 0;
|
|
894
|
-
};
|
|
895
|
-
var match = strat === "across" && ((_dimension_behavior1 = dimension.behavior) === null || _dimension_behavior1 === void 0 ? void 0 : _dimension_behavior1.childmostMatching) ? (_dimension_behavior2 = dimension.behavior) === null || _dimension_behavior2 === void 0 ? void 0 : _dimension_behavior2.childmostMatching : matchByIndex;
|
|
896
|
-
var extents2 = ((_dimension_behavior3 = dimension.behavior) === null || _dimension_behavior3 === void 0 ? void 0 : _dimension_behavior3.extents) || "circular";
|
|
897
|
-
if (!dimension.divisions) {
|
|
898
|
-
console.error("Parsing dimensions. The dimension using the key ".concat(s, " is missing the divisions property. dimension.divisions should be supplied. ").concat(JSON.stringify(dimension), "."));
|
|
899
|
-
}
|
|
900
|
-
var divisionKeys = Object.keys(dimension.divisions);
|
|
901
|
-
var firstDivision = dimension.divisions[divisionKeys[0]];
|
|
902
|
-
if (divisionKeys.length !== 1) {
|
|
903
|
-
createEdge(dimension.nodeId, firstDivision.id, dimension.navigationRules.parent_child, "source");
|
|
821
|
+
const firstChildId = typeof options.idKey === "function" ? options.idKey(division.values[valueKeys[0]]) : options.idKey;
|
|
822
|
+
createEdge(
|
|
823
|
+
division.id,
|
|
824
|
+
division.values[valueKeys[0]][firstChildId],
|
|
825
|
+
dimension.navigationRules.parent_child,
|
|
826
|
+
"source"
|
|
827
|
+
);
|
|
828
|
+
let i = 0;
|
|
829
|
+
if (valueKeys.length >= 1) {
|
|
830
|
+
valueKeys.forEach((vk) => {
|
|
831
|
+
let v = division.values[vk];
|
|
832
|
+
const id = typeof options.idKey === "function" ? options.idKey(v) : options.idKey;
|
|
833
|
+
let parentId = divisionKeys.length !== 1 ? division.id : dimension.nodeId;
|
|
834
|
+
if (!options.useDirectedEdges) {
|
|
835
|
+
createEdge(parentId, v[id], dimension.navigationRules.parent_child, "target");
|
|
904
836
|
} else {
|
|
905
|
-
|
|
906
|
-
var firstChildId = typeof options.idKey === "function" ? options.idKey(firstDivision.values[valueKeys[0]]) : options.idKey;
|
|
907
|
-
createEdge(dimension.nodeId, firstDivision.values[valueKeys[0]][firstChildId], dimension.navigationRules.parent_child, "source");
|
|
837
|
+
createEdge(v[id], parentId, dimension.navigationRules.parent_child, "source");
|
|
908
838
|
}
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
if (
|
|
919
|
-
|
|
839
|
+
if (strat === "within") {
|
|
840
|
+
if (i === valueKeys.length - 1 && extents2 === "circular") {
|
|
841
|
+
const targetId = typeof options.idKey === "function" ? options.idKey(division.values[valueKeys[0]]) : options.idKey;
|
|
842
|
+
createEdge(
|
|
843
|
+
v[id],
|
|
844
|
+
division.values[valueKeys[0]][targetId],
|
|
845
|
+
dimension.navigationRules.sibling_sibling
|
|
846
|
+
);
|
|
847
|
+
} else if (i === valueKeys.length - 1 && extents2 === "bridgedCousins") {
|
|
848
|
+
if (j !== divisionKeys.length - 1) {
|
|
849
|
+
const targetId = typeof options.idKey === "function" ? options.idKey(
|
|
850
|
+
dimension.divisions[divisionKeys[j + 1]].values[valueKeys[0]]
|
|
851
|
+
) : options.idKey;
|
|
852
|
+
createEdge(
|
|
853
|
+
v[id],
|
|
854
|
+
dimension.divisions[divisionKeys[j + 1]].values[valueKeys[0]][targetId],
|
|
855
|
+
dimension.navigationRules.sibling_sibling
|
|
856
|
+
);
|
|
920
857
|
} else {
|
|
921
|
-
|
|
858
|
+
const targetId = typeof options.idKey === "function" ? options.idKey(dimension.divisions[divisionKeys[0]].values[valueKeys[0]]) : options.idKey;
|
|
859
|
+
createEdge(
|
|
860
|
+
v[id],
|
|
861
|
+
dimension.divisions[divisionKeys[0]].values[valueKeys[0]][targetId],
|
|
862
|
+
dimension.navigationRules.sibling_sibling
|
|
863
|
+
);
|
|
922
864
|
}
|
|
923
|
-
|
|
924
|
-
createEdge(
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
var targetId4 = typeof options.idKey === "function" ? options.idKey(dimension.divisions[divisionKeys[j - 1]].values[valueKeys[valueKeys.length - 1]]) : options.idKey;
|
|
957
|
-
createEdge(dimension.divisions[divisionKeys[j - 1]].values[valueKeys[valueKeys.length - 1]][targetId4], v[id], dimension.navigationRules.sibling_sibling);
|
|
958
|
-
} else {
|
|
959
|
-
var targetId5 = typeof options.idKey === "function" ? options.idKey(dimension.divisions[divisionKeys[divisionKeys.length - 1]].values[valueKeys[valueKeys.length - 1]]) : options.idKey;
|
|
960
|
-
createEdge(dimension.divisions[divisionKeys[divisionKeys.length - 1]].values[valueKeys[valueKeys.length - 1]][targetId5], v[id], dimension.navigationRules.sibling_sibling);
|
|
961
|
-
}
|
|
962
|
-
} else if (!i && extents2 === "bridgedCustom") {
|
|
963
|
-
createEdge(dimension.behavior.customBridgePrevious, v[id], dimension.navigationRules.sibling_sibling);
|
|
964
|
-
}
|
|
965
|
-
} else {
|
|
966
|
-
if (j === divisionKeys.length - 1 && extents2 === "bridgedCustom") {
|
|
967
|
-
createEdge(v[id], dimension.behavior.customBridgePost, dimension.navigationRules.sibling_sibling);
|
|
968
|
-
} else if (!j && extents2 === "bridgedCustom") {
|
|
969
|
-
createEdge(dimension.behavior.customBridgePrevious, v[id], dimension.navigationRules.sibling_sibling);
|
|
970
|
-
} else {
|
|
971
|
-
var targetDivision = j === divisionKeys.length - 1 && extents2 === "circular" ? dimension.divisions[divisionKeys[0]] : dimension.divisions[divisionKeys[j + 1]];
|
|
972
|
-
if (targetDivision) {
|
|
973
|
-
var target = match(i, v[id], division, targetDivision);
|
|
974
|
-
if (target) {
|
|
975
|
-
var targetId6 = typeof options.idKey === "function" ? options.idKey(target) : options.idKey;
|
|
976
|
-
createEdge(v[id], target[targetId6], dimension.navigationRules.sibling_sibling);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
i++;
|
|
982
|
-
});
|
|
983
|
-
}
|
|
984
|
-
j++;
|
|
985
|
-
});
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
Object.keys(nodes).forEach(function(nodeKey) {
|
|
989
|
-
var _options_genericEdges;
|
|
990
|
-
var node = nodes[nodeKey];
|
|
991
|
-
if ((_options_genericEdges = options.genericEdges) === null || _options_genericEdges === void 0 ? void 0 : _options_genericEdges.length) {
|
|
992
|
-
options.genericEdges.forEach(function(e) {
|
|
993
|
-
if (!edges[e.edgeId]) {
|
|
994
|
-
edges[e.edgeId] = e.edge;
|
|
865
|
+
} else if (i === valueKeys.length - 1 && extents2 === "bridgedCustom") {
|
|
866
|
+
createEdge(
|
|
867
|
+
v[id],
|
|
868
|
+
dimension.behavior.customBridgePost,
|
|
869
|
+
dimension.navigationRules.sibling_sibling
|
|
870
|
+
);
|
|
871
|
+
} else if (i < valueKeys.length - 1) {
|
|
872
|
+
const targetId = typeof options.idKey === "function" ? options.idKey(division.values[valueKeys[i + 1]]) : options.idKey;
|
|
873
|
+
createEdge(
|
|
874
|
+
v[id],
|
|
875
|
+
division.values[valueKeys[i + 1]][targetId],
|
|
876
|
+
dimension.navigationRules.sibling_sibling
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
if (!i && extents2 === "bridgedCousins") {
|
|
880
|
+
if (j !== 0) {
|
|
881
|
+
const targetId = typeof options.idKey === "function" ? options.idKey(
|
|
882
|
+
dimension.divisions[divisionKeys[j - 1]].values[valueKeys[valueKeys.length - 1]]
|
|
883
|
+
) : options.idKey;
|
|
884
|
+
createEdge(
|
|
885
|
+
dimension.divisions[divisionKeys[j - 1]].values[valueKeys[valueKeys.length - 1]][targetId],
|
|
886
|
+
v[id],
|
|
887
|
+
dimension.navigationRules.sibling_sibling
|
|
888
|
+
);
|
|
889
|
+
} else {
|
|
890
|
+
const targetId = typeof options.idKey === "function" ? options.idKey(
|
|
891
|
+
dimension.divisions[divisionKeys[divisionKeys.length - 1]].values[valueKeys[valueKeys.length - 1]]
|
|
892
|
+
) : options.idKey;
|
|
893
|
+
createEdge(
|
|
894
|
+
dimension.divisions[divisionKeys[divisionKeys.length - 1]].values[valueKeys[valueKeys.length - 1]][targetId],
|
|
895
|
+
v[id],
|
|
896
|
+
dimension.navigationRules.sibling_sibling
|
|
897
|
+
);
|
|
995
898
|
}
|
|
996
|
-
|
|
997
|
-
|
|
899
|
+
} else if (!i && extents2 === "bridgedCustom") {
|
|
900
|
+
createEdge(
|
|
901
|
+
dimension.behavior.customBridgePrevious,
|
|
902
|
+
v[id],
|
|
903
|
+
dimension.navigationRules.sibling_sibling
|
|
904
|
+
);
|
|
905
|
+
}
|
|
906
|
+
} else {
|
|
907
|
+
if (j === divisionKeys.length - 1 && extents2 === "bridgedCustom") {
|
|
908
|
+
createEdge(
|
|
909
|
+
v[id],
|
|
910
|
+
dimension.behavior.customBridgePost,
|
|
911
|
+
dimension.navigationRules.sibling_sibling
|
|
912
|
+
);
|
|
913
|
+
} else if (!j && extents2 === "bridgedCustom") {
|
|
914
|
+
createEdge(
|
|
915
|
+
dimension.behavior.customBridgePrevious,
|
|
916
|
+
v[id],
|
|
917
|
+
dimension.navigationRules.sibling_sibling
|
|
918
|
+
);
|
|
919
|
+
} else {
|
|
920
|
+
const targetDivision = j === divisionKeys.length - 1 && extents2 === "circular" ? dimension.divisions[divisionKeys[0]] : dimension.divisions[divisionKeys[j + 1]];
|
|
921
|
+
if (targetDivision) {
|
|
922
|
+
const target = match(i, v[id], division, targetDivision);
|
|
923
|
+
if (target) {
|
|
924
|
+
const targetId = typeof options.idKey === "function" ? options.idKey(target) : options.idKey;
|
|
925
|
+
createEdge(v[id], target[targetId], dimension.navigationRules.sibling_sibling);
|
|
926
|
+
}
|
|
998
927
|
}
|
|
999
|
-
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
i++;
|
|
931
|
+
});
|
|
1000
932
|
}
|
|
933
|
+
j++;
|
|
934
|
+
});
|
|
1001
935
|
});
|
|
1002
|
-
|
|
936
|
+
}
|
|
937
|
+
Object.keys(nodes).forEach((nodeKey) => {
|
|
938
|
+
var _a2;
|
|
939
|
+
const node = nodes[nodeKey];
|
|
940
|
+
if ((_a2 = options.genericEdges) == null ? void 0 : _a2.length) {
|
|
941
|
+
options.genericEdges.forEach((e) => {
|
|
942
|
+
if (!edges[e.edgeId]) {
|
|
943
|
+
edges[e.edgeId] = e.edge;
|
|
944
|
+
}
|
|
945
|
+
if (!e.conditional || e.conditional && e.conditional(node, e)) {
|
|
946
|
+
node.edges.push(e.edgeId);
|
|
947
|
+
}
|
|
948
|
+
});
|
|
949
|
+
}
|
|
950
|
+
});
|
|
951
|
+
return edges;
|
|
1003
952
|
};
|
|
1004
|
-
var buildRules =
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
953
|
+
var buildRules = (options, edges, dimensions) => {
|
|
954
|
+
var _a, _b, _c, _d;
|
|
955
|
+
let rules = options.navigationRules;
|
|
956
|
+
if (!rules) {
|
|
957
|
+
let dimKeys = Object.keys(dimensions || {});
|
|
958
|
+
if (dimKeys.length > 6) {
|
|
959
|
+
console.error(
|
|
960
|
+
`Building navigationRules. Dimension count is too high to automatically generate key commands. It is recommend you reduce your dimensions to 6 or fewer for end-user experience. If not, you must provide your own navigation rules in options.navigationRules. Details: Count is ${dimKeys.length}. Dimensions counted: ${dimKeys.join(", ")}.`
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
let importedRules = {};
|
|
964
|
+
let used = {};
|
|
965
|
+
let needsKeys = {};
|
|
966
|
+
let sparePairs = [...TypicallyUnreservedKeyPairs];
|
|
967
|
+
let spareKeys = [...TypicallyUnreservedKeys];
|
|
968
|
+
const checkKeys = (k1, k2) => {
|
|
969
|
+
let isPair = k1 && k2;
|
|
970
|
+
let k1Assigned = false;
|
|
971
|
+
let k2Assigned = false;
|
|
972
|
+
if (importedRules[k1] || used[k1]) {
|
|
973
|
+
used[k1] = __spreadValues({}, importedRules[k1]);
|
|
974
|
+
k1Assigned = true;
|
|
975
|
+
}
|
|
976
|
+
if (k2 && (importedRules[k2] || used[k2])) {
|
|
977
|
+
used[k2] = __spreadValues({}, importedRules[k2]);
|
|
978
|
+
k2Assigned = true;
|
|
979
|
+
}
|
|
980
|
+
if (isPair && !k1Assigned && !k2Assigned) {
|
|
981
|
+
if (!sparePairs.length) {
|
|
982
|
+
console.error(
|
|
983
|
+
`Building navigationRules. Dimension count is too high to automatically generate key commands, we have run out of keyboard key pairs to assign. You must either provide your own navigation rules in options.navigationRules, provide rules when generating dimensions, or reduce dimension count.`
|
|
984
|
+
);
|
|
1010
985
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
var isPair = k1 && k2;
|
|
1018
|
-
var k1Assigned = false;
|
|
1019
|
-
var k2Assigned = false;
|
|
1020
|
-
if (importedRules[k1] || used[k1]) {
|
|
1021
|
-
used[k1] = _object_spread({}, importedRules[k1]);
|
|
1022
|
-
k1Assigned = true;
|
|
1023
|
-
}
|
|
1024
|
-
if (k2 && (importedRules[k2] || used[k2])) {
|
|
1025
|
-
used[k2] = _object_spread({}, importedRules[k2]);
|
|
1026
|
-
k2Assigned = true;
|
|
1027
|
-
}
|
|
1028
|
-
if (isPair && !k1Assigned && !k2Assigned) {
|
|
1029
|
-
if (!sparePairs.length) {
|
|
1030
|
-
console.error("Building navigationRules. Dimension count is too high to automatically generate key commands, we have run out of keyboard key pairs to assign. You must either provide your own navigation rules in options.navigationRules, provide rules when generating dimensions, or reduce dimension count.");
|
|
1031
|
-
}
|
|
1032
|
-
var pair = _to_consumable_array(sparePairs.shift());
|
|
1033
|
-
spareKeys.splice(spareKeys.indexOf(pair[0]), 1);
|
|
1034
|
-
spareKeys.splice(spareKeys.indexOf(pair[1]), 1);
|
|
1035
|
-
used[k1] = {
|
|
1036
|
-
direction: options.useDirectedEdges ? "target" : "source",
|
|
1037
|
-
key: pair[0]
|
|
1038
|
-
};
|
|
1039
|
-
used[k2] = {
|
|
1040
|
-
direction: "target",
|
|
1041
|
-
key: pair[1]
|
|
1042
|
-
};
|
|
1043
|
-
} else {
|
|
1044
|
-
if (!used[k1] && spareKeys.length) {
|
|
1045
|
-
var key = spareKeys.shift();
|
|
1046
|
-
var newPairs = [];
|
|
1047
|
-
sparePairs.forEach(function(p) {
|
|
1048
|
-
if (key !== p[0] && key !== p[1]) {
|
|
1049
|
-
newPairs.push(p);
|
|
1050
|
-
}
|
|
1051
|
-
});
|
|
1052
|
-
sparePairs = newPairs;
|
|
1053
|
-
used[k1] = {
|
|
1054
|
-
direction: options.useDirectedEdges ? "target" : "source",
|
|
1055
|
-
key: key
|
|
1056
|
-
};
|
|
1057
|
-
}
|
|
1058
|
-
if (k2 && !used[k2] && spareKeys.length) {
|
|
1059
|
-
var key1 = spareKeys.shift();
|
|
1060
|
-
var newPairs1 = [];
|
|
1061
|
-
sparePairs.forEach(function(p) {
|
|
1062
|
-
if (key1 !== p[0] && key1 !== p[1]) {
|
|
1063
|
-
newPairs1.push(p);
|
|
1064
|
-
}
|
|
1065
|
-
});
|
|
1066
|
-
sparePairs = newPairs1;
|
|
1067
|
-
used[k2] = {
|
|
1068
|
-
direction: "target",
|
|
1069
|
-
key: key1
|
|
1070
|
-
};
|
|
1071
|
-
}
|
|
1072
|
-
if (!spareKeys.length) {
|
|
1073
|
-
if (!used[k1]) {
|
|
1074
|
-
needsKeys[k1] = k1;
|
|
1075
|
-
}
|
|
1076
|
-
if (k2 && !used[k2]) {
|
|
1077
|
-
needsKeys[k2] = k2;
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
986
|
+
let pair = [...sparePairs.shift()];
|
|
987
|
+
spareKeys.splice(spareKeys.indexOf(pair[0]), 1);
|
|
988
|
+
spareKeys.splice(spareKeys.indexOf(pair[1]), 1);
|
|
989
|
+
used[k1] = {
|
|
990
|
+
direction: options.useDirectedEdges ? "target" : "source",
|
|
991
|
+
key: pair[0]
|
|
1081
992
|
};
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
if (
|
|
1092
|
-
|
|
1093
|
-
var rules2 = ((_options_dimensions_parentOptions_level1Options = options.dimensions.parentOptions.level1Options) === null || _options_dimensions_parentOptions_level1Options === void 0 ? void 0 : (_options_dimensions_parentOptions_level1Options_navigationRules = _options_dimensions_parentOptions_level1Options.navigationRules) === null || _options_dimensions_parentOptions_level1Options_navigationRules === void 0 ? void 0 : _options_dimensions_parentOptions_level1Options_navigationRules.parent_child) || [
|
|
1094
|
-
"parent",
|
|
1095
|
-
"child"
|
|
1096
|
-
];
|
|
1097
|
-
checkKeys(rules2[0], rules2[1]);
|
|
993
|
+
used[k2] = {
|
|
994
|
+
direction: "target",
|
|
995
|
+
key: pair[1]
|
|
996
|
+
};
|
|
997
|
+
} else {
|
|
998
|
+
if (!used[k1] && spareKeys.length) {
|
|
999
|
+
let key = spareKeys.shift();
|
|
1000
|
+
let newPairs = [];
|
|
1001
|
+
sparePairs.forEach((p) => {
|
|
1002
|
+
if (key !== p[0] && key !== p[1]) {
|
|
1003
|
+
newPairs.push(p);
|
|
1098
1004
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1005
|
+
});
|
|
1006
|
+
sparePairs = newPairs;
|
|
1007
|
+
used[k1] = {
|
|
1008
|
+
direction: options.useDirectedEdges ? "target" : "source",
|
|
1009
|
+
key
|
|
1010
|
+
};
|
|
1105
1011
|
}
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
});
|
|
1113
|
-
if (Object.keys(needsKeys).length) {
|
|
1114
|
-
var usedKeys = {};
|
|
1115
|
-
Object.keys(used).forEach(function(k) {
|
|
1116
|
-
usedKeys[used[k].key] = used[k].key;
|
|
1117
|
-
});
|
|
1118
|
-
Object.keys(importedRules).forEach(function(r) {
|
|
1119
|
-
if (!usedKeys[importedRules[r].key] && !SemanticKeys[importedRules[r].key]) {
|
|
1120
|
-
spareKeys.push(importedRules[r].key);
|
|
1121
|
-
}
|
|
1122
|
-
});
|
|
1123
|
-
var recheckKeys = _object_spread({}, needsKeys);
|
|
1124
|
-
needsKeys = {};
|
|
1125
|
-
Object.keys(recheckKeys).forEach(function(key) {
|
|
1126
|
-
checkKeys(key);
|
|
1127
|
-
});
|
|
1128
|
-
if (Object.keys(needsKeys).length) {
|
|
1129
|
-
console.error("Building navigationRules. There are no more keys left to assign automatically. Recommended fixes: use fewer dimensions, use fewer GenericEdges, or build your own navigationRules. Rules remaining without keyboard keys: ".concat(Object.keys(needsKeys).join(", "), "."));
|
|
1012
|
+
if (k2 && !used[k2] && spareKeys.length) {
|
|
1013
|
+
let key = spareKeys.shift();
|
|
1014
|
+
let newPairs = [];
|
|
1015
|
+
sparePairs.forEach((p) => {
|
|
1016
|
+
if (key !== p[0] && key !== p[1]) {
|
|
1017
|
+
newPairs.push(p);
|
|
1130
1018
|
}
|
|
1019
|
+
});
|
|
1020
|
+
sparePairs = newPairs;
|
|
1021
|
+
used[k2] = {
|
|
1022
|
+
direction: "target",
|
|
1023
|
+
key
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
if (!spareKeys.length) {
|
|
1027
|
+
if (!used[k1]) {
|
|
1028
|
+
needsKeys[k1] = k1;
|
|
1029
|
+
}
|
|
1030
|
+
if (k2 && !used[k2]) {
|
|
1031
|
+
needsKeys[k2] = k2;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
};
|
|
1036
|
+
Object.keys(GenericFullNavigationRules).forEach((r) => {
|
|
1037
|
+
let rule = __spreadValues({}, GenericFullNavigationRules[r]);
|
|
1038
|
+
if (options.useDirectedEdges) {
|
|
1039
|
+
rule.direction = "target";
|
|
1040
|
+
}
|
|
1041
|
+
importedRules[r] = rule;
|
|
1042
|
+
});
|
|
1043
|
+
if (dimKeys.length) {
|
|
1044
|
+
if ((_b = (_a = options.dimensions) == null ? void 0 : _a.parentOptions) == null ? void 0 : _b.addLevel0) {
|
|
1045
|
+
let rules2 = ((_d = (_c = options.dimensions.parentOptions.level1Options) == null ? void 0 : _c.navigationRules) == null ? void 0 : _d.parent_child) || [
|
|
1046
|
+
"parent",
|
|
1047
|
+
"child"
|
|
1048
|
+
];
|
|
1049
|
+
checkKeys(rules2[0], rules2[1]);
|
|
1050
|
+
}
|
|
1051
|
+
dimKeys.forEach((d) => {
|
|
1052
|
+
let pc = dimensions[d].navigationRules.parent_child;
|
|
1053
|
+
let ss = dimensions[d].navigationRules.sibling_sibling;
|
|
1054
|
+
checkKeys(pc[0], pc[1]);
|
|
1055
|
+
checkKeys(ss[0], ss[1]);
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
Object.keys(edges).forEach((e) => {
|
|
1059
|
+
edges[e].navigationRules.forEach((rule) => {
|
|
1060
|
+
if (!used[rule]) {
|
|
1061
|
+
checkKeys(rule);
|
|
1131
1062
|
}
|
|
1132
|
-
|
|
1063
|
+
});
|
|
1064
|
+
});
|
|
1065
|
+
if (Object.keys(needsKeys).length) {
|
|
1066
|
+
let usedKeys = {};
|
|
1067
|
+
Object.keys(used).forEach((k) => {
|
|
1068
|
+
usedKeys[used[k].key] = used[k].key;
|
|
1069
|
+
});
|
|
1070
|
+
Object.keys(importedRules).forEach((r) => {
|
|
1071
|
+
if (!usedKeys[importedRules[r].key] && !SemanticKeys[importedRules[r].key]) {
|
|
1072
|
+
spareKeys.push(importedRules[r].key);
|
|
1073
|
+
}
|
|
1074
|
+
});
|
|
1075
|
+
let recheckKeys = __spreadValues({}, needsKeys);
|
|
1076
|
+
needsKeys = {};
|
|
1077
|
+
Object.keys(recheckKeys).forEach((key) => {
|
|
1078
|
+
checkKeys(key);
|
|
1079
|
+
});
|
|
1080
|
+
if (Object.keys(needsKeys).length) {
|
|
1081
|
+
console.error(
|
|
1082
|
+
`Building navigationRules. There are no more keys left to assign automatically. Recommended fixes: use fewer dimensions, use fewer GenericEdges, or build your own navigationRules. Rules remaining without keyboard keys: ${Object.keys(
|
|
1083
|
+
needsKeys
|
|
1084
|
+
).join(", ")}.`
|
|
1085
|
+
);
|
|
1086
|
+
}
|
|
1133
1087
|
}
|
|
1134
|
-
|
|
1088
|
+
rules = used;
|
|
1089
|
+
}
|
|
1090
|
+
return rules;
|
|
1135
1091
|
};
|
|
1136
|
-
var buildStructure =
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1092
|
+
var buildStructure = (options) => {
|
|
1093
|
+
if (options.addIds) {
|
|
1094
|
+
addSimpleDataIDs(options);
|
|
1095
|
+
}
|
|
1096
|
+
let nodes = buildNodes(options);
|
|
1097
|
+
let dimensions = scaffoldDimensions(options, nodes);
|
|
1098
|
+
let edges = buildEdges(options, nodes, dimensions);
|
|
1099
|
+
let navigationRules = buildRules(options, edges, dimensions);
|
|
1100
|
+
return {
|
|
1101
|
+
nodes,
|
|
1102
|
+
edges,
|
|
1103
|
+
dimensions,
|
|
1104
|
+
navigationRules
|
|
1105
|
+
};
|
|
1150
1106
|
};
|
|
1107
|
+
|
|
1151
1108
|
// src/input.ts
|
|
1152
|
-
var input_default =
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1109
|
+
var input_default = (options) => {
|
|
1110
|
+
let inputHandler = {};
|
|
1111
|
+
let keyBindings = defaultKeyBindings;
|
|
1112
|
+
let directions = GenericFullNavigationRules;
|
|
1113
|
+
inputHandler.moveTo = (id) => {
|
|
1114
|
+
const target = options.structure.nodes[id];
|
|
1115
|
+
if (target) {
|
|
1116
|
+
return target;
|
|
1117
|
+
}
|
|
1118
|
+
return;
|
|
1119
|
+
};
|
|
1120
|
+
inputHandler.move = (currentFocus, direction) => {
|
|
1121
|
+
if (currentFocus) {
|
|
1122
|
+
const d = options.structure.nodes[currentFocus];
|
|
1123
|
+
if (d.edges) {
|
|
1124
|
+
let target = null;
|
|
1125
|
+
let i = 0;
|
|
1126
|
+
const navRule = directions[direction];
|
|
1127
|
+
if (!navRule) {
|
|
1128
|
+
return;
|
|
1160
1129
|
}
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
}
|
|
1177
|
-
};
|
|
1178
|
-
var target = null;
|
|
1179
|
-
var i = 0;
|
|
1180
|
-
var navRule = directions[direction];
|
|
1181
|
-
if (!navRule) {
|
|
1182
|
-
return;
|
|
1183
|
-
}
|
|
1184
|
-
var findTarget = function findTarget(rule, edge) {
|
|
1185
|
-
if (!(rule === direction)) {
|
|
1186
|
-
return null;
|
|
1187
|
-
}
|
|
1188
|
-
var resolvedNodes = {
|
|
1189
|
-
target: typeof edge.target === "string" ? edge.target : edge.target(d, currentFocus),
|
|
1190
|
-
source: typeof edge.source === "string" ? edge.source : edge.source(d, currentFocus)
|
|
1191
|
-
};
|
|
1192
|
-
return !(resolvedNodes[navRule.direction] === currentFocus) ? resolvedNodes[navRule.direction] : null;
|
|
1193
|
-
};
|
|
1194
|
-
for(i = 0; i < d.edges.length; i++){
|
|
1195
|
-
var _ret = _loop();
|
|
1196
|
-
if (_ret === "break") break;
|
|
1197
|
-
}
|
|
1198
|
-
if (target) {
|
|
1199
|
-
return inputHandler.moveTo(target);
|
|
1200
|
-
}
|
|
1201
|
-
return void 0;
|
|
1130
|
+
const findTarget = (rule, edge) => {
|
|
1131
|
+
if (!(rule === direction)) {
|
|
1132
|
+
return null;
|
|
1133
|
+
}
|
|
1134
|
+
let resolvedNodes = {
|
|
1135
|
+
target: typeof edge.target === "string" ? edge.target : edge.target(d, currentFocus),
|
|
1136
|
+
source: typeof edge.source === "string" ? edge.source : edge.source(d, currentFocus)
|
|
1137
|
+
};
|
|
1138
|
+
return !(resolvedNodes[navRule.direction] === currentFocus) ? resolvedNodes[navRule.direction] : null;
|
|
1139
|
+
};
|
|
1140
|
+
for (i = 0; i < d.edges.length; i++) {
|
|
1141
|
+
const edge = options.structure.edges[d.edges[i]];
|
|
1142
|
+
edge.navigationRules.forEach((rule) => {
|
|
1143
|
+
if (!target) {
|
|
1144
|
+
target = findTarget(rule, edge);
|
|
1202
1145
|
}
|
|
1146
|
+
});
|
|
1147
|
+
if (target) {
|
|
1148
|
+
break;
|
|
1149
|
+
}
|
|
1203
1150
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
if (options.entryPoint) {
|
|
1207
|
-
return inputHandler.moveTo(options.entryPoint);
|
|
1208
|
-
} else {
|
|
1209
|
-
console.error("No entry point was specified in InputOptions, returning undefined");
|
|
1210
|
-
return;
|
|
1211
|
-
}
|
|
1212
|
-
};
|
|
1213
|
-
inputHandler.exit = function() {
|
|
1214
|
-
if (options.exitPoint) {
|
|
1215
|
-
return options.exitPoint;
|
|
1216
|
-
} else {
|
|
1217
|
-
console.error("No exit point was specified in InputOptions, returning undefined");
|
|
1218
|
-
return;
|
|
1219
|
-
}
|
|
1220
|
-
};
|
|
1221
|
-
inputHandler.keydownValidator = function(e) {
|
|
1222
|
-
var direction = keyBindings[e.code];
|
|
1223
|
-
if (direction) {
|
|
1224
|
-
return direction;
|
|
1225
|
-
}
|
|
1226
|
-
};
|
|
1227
|
-
inputHandler.focus = function(renderId) {
|
|
1228
|
-
var node = document.getElementById(renderId);
|
|
1229
|
-
if (node) {
|
|
1230
|
-
node.focus();
|
|
1231
|
-
}
|
|
1232
|
-
};
|
|
1233
|
-
inputHandler.setNavigationKeyBindings = function(navKeyBindings) {
|
|
1234
|
-
if (!navKeyBindings) {
|
|
1235
|
-
keyBindings = defaultKeyBindings;
|
|
1236
|
-
directions = GenericFullNavigationRules;
|
|
1237
|
-
} else {
|
|
1238
|
-
keyBindings = {};
|
|
1239
|
-
directions = navKeyBindings;
|
|
1240
|
-
Object.keys(navKeyBindings).forEach(function(direction) {
|
|
1241
|
-
var navOption = navKeyBindings[direction];
|
|
1242
|
-
keyBindings[navOption.key] = direction;
|
|
1243
|
-
});
|
|
1151
|
+
if (target) {
|
|
1152
|
+
return inputHandler.moveTo(target);
|
|
1244
1153
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1154
|
+
return void 0;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
};
|
|
1158
|
+
inputHandler.enter = () => {
|
|
1159
|
+
if (options.entryPoint) {
|
|
1160
|
+
return inputHandler.moveTo(options.entryPoint);
|
|
1161
|
+
} else {
|
|
1162
|
+
console.error("No entry point was specified in InputOptions, returning undefined");
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
inputHandler.exit = () => {
|
|
1167
|
+
if (options.exitPoint) {
|
|
1168
|
+
return options.exitPoint;
|
|
1169
|
+
} else {
|
|
1170
|
+
console.error("No exit point was specified in InputOptions, returning undefined");
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
inputHandler.keydownValidator = (e) => {
|
|
1175
|
+
const direction = keyBindings[e.code];
|
|
1176
|
+
if (direction) {
|
|
1177
|
+
return direction;
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
inputHandler.focus = (renderId) => {
|
|
1181
|
+
const node = document.getElementById(renderId);
|
|
1182
|
+
if (node) {
|
|
1183
|
+
node.focus();
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
inputHandler.setNavigationKeyBindings = (navKeyBindings) => {
|
|
1187
|
+
if (!navKeyBindings) {
|
|
1188
|
+
keyBindings = defaultKeyBindings;
|
|
1189
|
+
directions = GenericFullNavigationRules;
|
|
1190
|
+
} else {
|
|
1191
|
+
keyBindings = {};
|
|
1192
|
+
directions = navKeyBindings;
|
|
1193
|
+
Object.keys(navKeyBindings).forEach((direction) => {
|
|
1194
|
+
const navOption = navKeyBindings[direction];
|
|
1195
|
+
keyBindings[navOption.key] = direction;
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
};
|
|
1199
|
+
inputHandler.setNavigationKeyBindings(options.navigationRules);
|
|
1200
|
+
return inputHandler;
|
|
1248
1201
|
};
|
|
1202
|
+
|
|
1249
1203
|
// src/rendering.ts
|
|
1250
|
-
var rendering_default =
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1204
|
+
var rendering_default = (options) => {
|
|
1205
|
+
const setActiveDescendant = (e) => {
|
|
1206
|
+
renderer.wrapper.setAttribute("aria-activedescendant", e.srcElement.id);
|
|
1207
|
+
};
|
|
1208
|
+
const removeActiveDescendant = () => {
|
|
1209
|
+
renderer.wrapper.setAttribute("aria-activedescendant", "");
|
|
1210
|
+
};
|
|
1211
|
+
let renderer = {};
|
|
1212
|
+
let initialized = false;
|
|
1213
|
+
let defaults = {
|
|
1214
|
+
cssClass: NodeElementDefaults.cssClass,
|
|
1215
|
+
spatialProperties: __spreadValues({}, NodeElementDefaults.spatialProperties),
|
|
1216
|
+
semantics: __spreadValues({}, NodeElementDefaults.semantics),
|
|
1217
|
+
parentSemantics: __spreadValues({}, NodeElementDefaults.parentSemantics),
|
|
1218
|
+
existingElement: __spreadValues({}, NodeElementDefaults.existingElement)
|
|
1219
|
+
};
|
|
1220
|
+
if (options.defaults) {
|
|
1221
|
+
defaults.cssClass = options.defaults.cssClass || defaults.cssClass;
|
|
1222
|
+
defaults.spatialProperties = options.defaults.spatialProperties ? __spreadValues(__spreadValues({}, defaults.spatialProperties), options.defaults.spatialProperties) : defaults.spatialProperties;
|
|
1223
|
+
defaults.semantics = options.defaults.semantics ? __spreadValues(__spreadValues({}, defaults.semantics), options.defaults.semantics) : defaults.semantics;
|
|
1224
|
+
defaults.parentSemantics = options.defaults.parentSemantics ? __spreadValues(__spreadValues({}, defaults.parentSemantics), options.defaults.parentSemantics) : defaults.parentSemantics;
|
|
1225
|
+
defaults.existingElement = options.defaults.existingElement ? __spreadValues(__spreadValues({}, defaults.existingElement), options.defaults.existingElement) : defaults.existingElement;
|
|
1226
|
+
}
|
|
1227
|
+
renderer.initialize = () => {
|
|
1228
|
+
var _a;
|
|
1229
|
+
if (initialized) {
|
|
1230
|
+
console.error(
|
|
1231
|
+
`The renderer wrapper has already been initialized successfully, RenderingOptions.suffixId is: ${options.suffixId}. No further action was taken.`
|
|
1232
|
+
);
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
if (options.root && document.getElementById(options.root.id)) {
|
|
1236
|
+
renderer.root = document.getElementById(options.root.id);
|
|
1237
|
+
} else {
|
|
1238
|
+
console.error(
|
|
1239
|
+
"No root element found, cannot build: RenderingOptions.root.id must reference an existing DOM element in order to render children."
|
|
1240
|
+
);
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1243
|
+
renderer.root.style.position = "relative";
|
|
1244
|
+
renderer.root.classList.add("dn-root");
|
|
1245
|
+
if (!options.suffixId) {
|
|
1246
|
+
console.error("No suffix id found: options.suffixId must be specified.");
|
|
1247
|
+
return;
|
|
1248
|
+
}
|
|
1249
|
+
renderer.wrapper = document.createElement("div");
|
|
1250
|
+
renderer.wrapper.id = "dn-wrapper-" + options.suffixId;
|
|
1251
|
+
renderer.wrapper.setAttribute("role", "application");
|
|
1252
|
+
renderer.wrapper.setAttribute("aria-label", options.root.description || "Data navigation structure");
|
|
1253
|
+
renderer.wrapper.setAttribute("aria-activedescendant", "");
|
|
1254
|
+
renderer.wrapper.classList.add("dn-wrapper");
|
|
1255
|
+
renderer.wrapper.style.width = options.root && options.root.width ? options.root.width : "100%";
|
|
1256
|
+
if (options.root && options.root.height) {
|
|
1257
|
+
renderer.wrapper.style.height = options.root.height;
|
|
1258
|
+
}
|
|
1259
|
+
if (options.entryButton && options.entryButton.include) {
|
|
1260
|
+
renderer.entryButton = document.createElement("button");
|
|
1261
|
+
renderer.entryButton.id = "dn-entry-button-" + options.suffixId;
|
|
1262
|
+
renderer.entryButton.classList.add("dn-entry-button");
|
|
1263
|
+
renderer.entryButton.innerText = `Enter navigation area`;
|
|
1264
|
+
if (options.entryButton.callbacks && options.entryButton.callbacks.click) {
|
|
1265
|
+
renderer.entryButton.addEventListener("click", options.entryButton.callbacks.click);
|
|
1266
|
+
}
|
|
1267
|
+
if (options.entryButton.callbacks && options.entryButton.callbacks.focus) {
|
|
1268
|
+
renderer.entryButton.addEventListener("focus", options.entryButton.callbacks.focus);
|
|
1269
|
+
}
|
|
1270
|
+
renderer.wrapper.appendChild(renderer.entryButton);
|
|
1271
|
+
}
|
|
1272
|
+
renderer.root.appendChild(renderer.wrapper);
|
|
1273
|
+
if ((_a = options.exitElement) == null ? void 0 : _a.include) {
|
|
1274
|
+
renderer.exitElement = document.createElement("div");
|
|
1275
|
+
renderer.exitElement.id = "dn-exit-" + options.suffixId;
|
|
1276
|
+
renderer.exitElement.classList.add("dn-exit-position");
|
|
1277
|
+
renderer.exitElement.innerText = `End of data structure.`;
|
|
1278
|
+
renderer.exitElement.setAttribute("aria-label", `End of data structure.`);
|
|
1279
|
+
renderer.exitElement.setAttribute("role", "note");
|
|
1280
|
+
renderer.exitElement.setAttribute("tabindex", "-1");
|
|
1281
|
+
renderer.exitElement.style.display = "none";
|
|
1282
|
+
renderer.exitElement.addEventListener("focus", (e) => {
|
|
1283
|
+
var _a2, _b;
|
|
1284
|
+
renderer.exitElement.style.display = "block";
|
|
1285
|
+
renderer.clearStructure();
|
|
1286
|
+
if ((_b = (_a2 = options.exitElement) == null ? void 0 : _a2.callbacks) == null ? void 0 : _b.focus) {
|
|
1287
|
+
options.exitElement.callbacks.focus(e);
|
|
1300
1288
|
}
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
renderer.entryButton.addEventListener("click", options.entryButton.callbacks.click);
|
|
1308
|
-
}
|
|
1309
|
-
if (options.entryButton.callbacks && options.entryButton.callbacks.focus) {
|
|
1310
|
-
renderer.entryButton.addEventListener("focus", options.entryButton.callbacks.focus);
|
|
1311
|
-
}
|
|
1312
|
-
renderer.wrapper.appendChild(renderer.entryButton);
|
|
1289
|
+
});
|
|
1290
|
+
renderer.exitElement.addEventListener("blur", (e) => {
|
|
1291
|
+
var _a2, _b;
|
|
1292
|
+
renderer.exitElement.style.display = "none";
|
|
1293
|
+
if ((_b = (_a2 = options.exitElement) == null ? void 0 : _a2.callbacks) == null ? void 0 : _b.blur) {
|
|
1294
|
+
options.exitElement.callbacks.blur(e);
|
|
1313
1295
|
}
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
renderer.root.appendChild(renderer.exitElement);
|
|
1340
|
-
}
|
|
1341
|
-
initialized = true;
|
|
1342
|
-
return renderer.root;
|
|
1296
|
+
});
|
|
1297
|
+
renderer.root.appendChild(renderer.exitElement);
|
|
1298
|
+
}
|
|
1299
|
+
initialized = true;
|
|
1300
|
+
return renderer.root;
|
|
1301
|
+
};
|
|
1302
|
+
renderer.render = (nodeData) => {
|
|
1303
|
+
const id = nodeData.renderId + "";
|
|
1304
|
+
let d = options.elementData[id];
|
|
1305
|
+
if (!d) {
|
|
1306
|
+
console.warn(`Render data not found with renderId: ${id}. Failed to render.`);
|
|
1307
|
+
return;
|
|
1308
|
+
}
|
|
1309
|
+
if (!initialized) {
|
|
1310
|
+
console.error("render() was called before initialize(), renderer must be initialized first.");
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
let useExisting = false;
|
|
1314
|
+
let existingSpatialProperties = {};
|
|
1315
|
+
const resolveProp = (prop, subprop, checkExisting) => {
|
|
1316
|
+
var _a;
|
|
1317
|
+
const p1 = d[prop] || defaults[prop];
|
|
1318
|
+
const s1 = !(checkExisting && useExisting) ? p1 == null ? void 0 : p1[subprop] : existingSpatialProperties[subprop];
|
|
1319
|
+
const s2 = (_a = defaults[prop]) == null ? void 0 : _a[subprop];
|
|
1320
|
+
return typeof p1 === "function" ? p1(d, nodeData.datum) : typeof s1 === "function" ? s1(d, nodeData.datum) : s1 || s2 || (!subprop ? p1 : void 0);
|
|
1343
1321
|
};
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1322
|
+
useExisting = resolveProp("existingElement", "useForSpatialProperties");
|
|
1323
|
+
existingSpatialProperties = resolveProp("existingElement", "spatialProperties");
|
|
1324
|
+
const width = parseFloat(resolveProp("spatialProperties", "width", true) || 0);
|
|
1325
|
+
const height = parseFloat(resolveProp("spatialProperties", "height", true) || 0);
|
|
1326
|
+
const x = parseFloat(resolveProp("spatialProperties", "x", true) || 0);
|
|
1327
|
+
const y = parseFloat(resolveProp("spatialProperties", "y", true) || 0);
|
|
1328
|
+
const node = document.createElement(resolveProp("parentSemantics", "elementType"));
|
|
1329
|
+
const wrapperAttrs = resolveProp("parentSemantics", "attributes");
|
|
1330
|
+
if (typeof wrapperAttrs === "object") {
|
|
1331
|
+
Object.keys(wrapperAttrs).forEach((wrapperAttr) => {
|
|
1332
|
+
node.setAttribute(wrapperAttr, wrapperAttrs[wrapperAttr]);
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
node.setAttribute("role", resolveProp("parentSemantics", "role"));
|
|
1336
|
+
node.id = id;
|
|
1337
|
+
node.classList.add("dn-node");
|
|
1338
|
+
node.classList.add(resolveProp("cssClass"));
|
|
1339
|
+
node.style.width = width + "px";
|
|
1340
|
+
node.style.height = height + "px";
|
|
1341
|
+
node.style.left = x + "px";
|
|
1342
|
+
node.style.top = y + "px";
|
|
1343
|
+
node.setAttribute("tabindex", "0");
|
|
1344
|
+
node.addEventListener("focus", setActiveDescendant);
|
|
1345
|
+
node.addEventListener("blur", removeActiveDescendant);
|
|
1346
|
+
const nodeText = document.createElement(resolveProp("semantics", "elementType"));
|
|
1347
|
+
const attributes = resolveProp("semantics", "attributes");
|
|
1348
|
+
if (typeof attributes === "object") {
|
|
1349
|
+
Object.keys(attributes).forEach((attribute) => {
|
|
1350
|
+
node.setAttribute(attribute, attributes[attribute]);
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
nodeText.setAttribute("role", resolveProp("semantics", "role"));
|
|
1354
|
+
nodeText.classList.add("dn-node-text");
|
|
1355
|
+
if (d.showText) {
|
|
1356
|
+
nodeText.innerText = d.semantics.label;
|
|
1357
|
+
}
|
|
1358
|
+
const label = resolveProp("semantics", "label");
|
|
1359
|
+
if (!label) {
|
|
1360
|
+
console.error(
|
|
1361
|
+
"Accessibility error: a label must be supplied to every rendered element using semantics.label."
|
|
1362
|
+
);
|
|
1363
|
+
}
|
|
1364
|
+
nodeText.setAttribute("aria-label", label);
|
|
1365
|
+
node.appendChild(nodeText);
|
|
1366
|
+
const hasPath = resolveProp("spatialProperties", "path");
|
|
1367
|
+
if (hasPath) {
|
|
1368
|
+
const totalWidth = width + x + 10;
|
|
1369
|
+
const totalHeight = height + y + 10;
|
|
1370
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
1371
|
+
svg.setAttribute("width", totalWidth + "");
|
|
1372
|
+
svg.setAttribute("height", totalHeight + "");
|
|
1373
|
+
svg.setAttribute("viewBox", `0 0 ${totalWidth} ${totalHeight}`);
|
|
1374
|
+
svg.style.left = -x + "px";
|
|
1375
|
+
svg.style.top = -y + "px";
|
|
1376
|
+
svg.classList.add("dn-node-svg");
|
|
1377
|
+
svg.setAttribute("role", "presentation");
|
|
1378
|
+
svg.setAttribute("focusable", "false");
|
|
1379
|
+
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
1380
|
+
path.setAttribute("d", hasPath);
|
|
1381
|
+
path.classList.add("dn-node-path");
|
|
1382
|
+
svg.appendChild(path);
|
|
1383
|
+
node.appendChild(svg);
|
|
1384
|
+
}
|
|
1385
|
+
renderer.wrapper.appendChild(node);
|
|
1386
|
+
return node;
|
|
1387
|
+
};
|
|
1388
|
+
renderer.remove = (renderId) => {
|
|
1389
|
+
const node = document.getElementById(renderId);
|
|
1390
|
+
if (renderer.wrapper.getAttribute("aria-activedescendant") === renderId) {
|
|
1391
|
+
renderer.wrapper.setAttribute("aria-activedescendant", "");
|
|
1392
|
+
}
|
|
1393
|
+
if (node) {
|
|
1394
|
+
node.removeEventListener("focus", setActiveDescendant);
|
|
1395
|
+
node.removeEventListener("blur", removeActiveDescendant);
|
|
1396
|
+
node.remove();
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
renderer.clearStructure = () => {
|
|
1400
|
+
[...renderer.wrapper.children].forEach((child) => {
|
|
1401
|
+
if (!(renderer.entryButton && renderer.entryButton === child)) {
|
|
1402
|
+
renderer.remove(child.id);
|
|
1403
|
+
}
|
|
1404
|
+
});
|
|
1405
|
+
};
|
|
1406
|
+
return renderer;
|
|
1407
|
+
};
|
|
1408
|
+
|
|
1409
|
+
// src/text-chat.ts
|
|
1410
|
+
var defaultDescribeNode = (node) => {
|
|
1411
|
+
var _a, _b, _c, _d, _e;
|
|
1412
|
+
if ((_a = node.semantics) == null ? void 0 : _a.label) {
|
|
1413
|
+
const label = typeof node.semantics.label === "function" ? node.semantics.label() : node.semantics.label;
|
|
1414
|
+
if (label)
|
|
1415
|
+
return label;
|
|
1416
|
+
}
|
|
1417
|
+
if (!node.derivedNode) {
|
|
1418
|
+
if (node.data) {
|
|
1419
|
+
return Object.keys(node.data).map((key) => `${key}: ${node.data[key]}`).join(". ") + ". Data point.";
|
|
1420
|
+
}
|
|
1421
|
+
return node.id;
|
|
1422
|
+
}
|
|
1423
|
+
if ((_b = node.data) == null ? void 0 : _b.dimensionKey) {
|
|
1424
|
+
let count = 0;
|
|
1425
|
+
const divisions = Object.keys(node.data.divisions || {});
|
|
1426
|
+
divisions.forEach((div) => {
|
|
1427
|
+
count += Object.keys(node.data.divisions[div].values || {}).length;
|
|
1428
|
+
});
|
|
1429
|
+
let label = `${node.derivedNode}.`;
|
|
1430
|
+
label += divisions.length && count ? ` ${divisions.length} division${divisions.length > 1 ? "s" : ""}, ${count} datapoint${count > 1 ? "s" : ""}.` : " No child data points.";
|
|
1431
|
+
label += ` ${node.data.type} dimension.`;
|
|
1432
|
+
return label;
|
|
1433
|
+
}
|
|
1434
|
+
return `${node.derivedNode}: ${(_c = node.data) == null ? void 0 : _c[node.derivedNode]}. ${Object.keys(((_d = node.data) == null ? void 0 : _d.values) || {}).length} child data point${Object.keys(((_e = node.data) == null ? void 0 : _e.values) || {}).length > 1 ? "s" : ""}. Division.`;
|
|
1435
|
+
};
|
|
1436
|
+
var getAvailableRules = (nodeId, node, structure) => {
|
|
1437
|
+
const available = /* @__PURE__ */ new Set();
|
|
1438
|
+
const navRules = structure.navigationRules || {};
|
|
1439
|
+
if (node.edges) {
|
|
1440
|
+
node.edges.forEach((edgeId) => {
|
|
1441
|
+
const edge = structure.edges[edgeId];
|
|
1442
|
+
if (!edge)
|
|
1443
|
+
return;
|
|
1444
|
+
edge.navigationRules.forEach((ruleName) => {
|
|
1445
|
+
const navRule = navRules[ruleName];
|
|
1446
|
+
if (!navRule)
|
|
1447
|
+
return;
|
|
1448
|
+
const endpoint = navRule.direction === "target" ? edge.target : edge.source;
|
|
1449
|
+
const resolved = typeof endpoint === "function" ? endpoint(node, nodeId) : endpoint;
|
|
1450
|
+
if (resolved && resolved !== nodeId) {
|
|
1451
|
+
available.add(ruleName);
|
|
1424
1452
|
}
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1453
|
+
});
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
return Array.from(available);
|
|
1457
|
+
};
|
|
1458
|
+
var getAllRuleNames = (structure) => {
|
|
1459
|
+
if (!structure.navigationRules)
|
|
1460
|
+
return [];
|
|
1461
|
+
return Object.keys(structure.navigationRules);
|
|
1462
|
+
};
|
|
1463
|
+
var damerauLevenshtein = (a, b) => {
|
|
1464
|
+
const m = a.length;
|
|
1465
|
+
const n = b.length;
|
|
1466
|
+
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
1467
|
+
for (let i = 0; i <= m; i++)
|
|
1468
|
+
dp[i][0] = i;
|
|
1469
|
+
for (let j = 0; j <= n; j++)
|
|
1470
|
+
dp[0][j] = j;
|
|
1471
|
+
for (let i = 1; i <= m; i++) {
|
|
1472
|
+
for (let j = 1; j <= n; j++) {
|
|
1473
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
1474
|
+
dp[i][j] = Math.min(
|
|
1475
|
+
dp[i - 1][j] + 1,
|
|
1476
|
+
// deletion
|
|
1477
|
+
dp[i][j - 1] + 1,
|
|
1478
|
+
// insertion
|
|
1479
|
+
dp[i - 1][j - 1] + cost
|
|
1480
|
+
// substitution
|
|
1481
|
+
);
|
|
1482
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
1483
|
+
dp[i][j] = Math.min(dp[i][j], dp[i - 2][j - 2] + cost);
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
return dp[m][n];
|
|
1488
|
+
};
|
|
1489
|
+
var maxTypoDistance = (len) => len <= 4 ? 1 : 2;
|
|
1490
|
+
var fuzzyMatch = (input, candidates, labels = {}) => {
|
|
1491
|
+
const lower = input.toLowerCase().trim();
|
|
1492
|
+
const exactName = candidates.find((c) => c.toLowerCase() === lower);
|
|
1493
|
+
if (exactName)
|
|
1494
|
+
return { match: exactName, ambiguous: [] };
|
|
1495
|
+
const exactLabel = candidates.find(
|
|
1496
|
+
(c) => labels[c] && labels[c].toLowerCase() === lower
|
|
1497
|
+
);
|
|
1498
|
+
if (exactLabel)
|
|
1499
|
+
return { match: exactLabel, ambiguous: [] };
|
|
1500
|
+
const namePrefix = candidates.filter((c) => c.toLowerCase().startsWith(lower));
|
|
1501
|
+
if (namePrefix.length === 1)
|
|
1502
|
+
return { match: namePrefix[0], ambiguous: [] };
|
|
1503
|
+
const labelMatches = candidates.filter((c) => {
|
|
1504
|
+
if (!labels[c])
|
|
1505
|
+
return false;
|
|
1506
|
+
const labelLower = labels[c].toLowerCase();
|
|
1507
|
+
if (labelLower.startsWith(lower))
|
|
1508
|
+
return true;
|
|
1509
|
+
return labelLower.split(/\s+/).some((word) => word.startsWith(lower));
|
|
1510
|
+
});
|
|
1511
|
+
const combined = /* @__PURE__ */ new Set([...namePrefix, ...labelMatches]);
|
|
1512
|
+
const all = Array.from(combined);
|
|
1513
|
+
if (all.length === 1)
|
|
1514
|
+
return { match: all[0], ambiguous: [] };
|
|
1515
|
+
if (all.length > 1)
|
|
1516
|
+
return { match: null, ambiguous: all };
|
|
1517
|
+
const threshold = maxTypoDistance(lower.length);
|
|
1518
|
+
const typoMatches = [];
|
|
1519
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
1520
|
+
const c = candidates[i];
|
|
1521
|
+
const nameDist = damerauLevenshtein(lower, c.toLowerCase());
|
|
1522
|
+
if (nameDist <= threshold) {
|
|
1523
|
+
typoMatches.push({ candidate: c, dist: nameDist });
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1526
|
+
if (labels[c]) {
|
|
1527
|
+
const words = labels[c].toLowerCase().split(/\s+/);
|
|
1528
|
+
for (let w = 0; w < words.length; w++) {
|
|
1529
|
+
if (damerauLevenshtein(lower, words[w]) <= threshold) {
|
|
1530
|
+
typoMatches.push({ candidate: c, dist: damerauLevenshtein(lower, words[w]) });
|
|
1531
|
+
break;
|
|
1432
1532
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
if (typoMatches.length === 1)
|
|
1537
|
+
return { match: typoMatches[0].candidate, ambiguous: [] };
|
|
1538
|
+
if (typoMatches.length > 1) {
|
|
1539
|
+
typoMatches.sort((a, b) => a.dist - b.dist);
|
|
1540
|
+
if (typoMatches[0].dist < typoMatches[1].dist) {
|
|
1541
|
+
return { match: typoMatches[0].candidate, ambiguous: [] };
|
|
1542
|
+
}
|
|
1543
|
+
return { match: null, ambiguous: typoMatches.map((t) => t.candidate) };
|
|
1544
|
+
}
|
|
1545
|
+
return { match: null, ambiguous: [] };
|
|
1546
|
+
};
|
|
1547
|
+
var formatRule = (ruleName, labels) => {
|
|
1548
|
+
if (labels[ruleName])
|
|
1549
|
+
return `${labels[ruleName]} (${ruleName})`;
|
|
1550
|
+
return ruleName;
|
|
1551
|
+
};
|
|
1552
|
+
var searchNodes = (query, structure, describeFn, limit = 10) => {
|
|
1553
|
+
const lower = query.toLowerCase();
|
|
1554
|
+
const results = [];
|
|
1555
|
+
const nodeIds = Object.keys(structure.nodes);
|
|
1556
|
+
for (let i = 0; i < nodeIds.length && results.length < limit; i++) {
|
|
1557
|
+
const nodeId = nodeIds[i];
|
|
1558
|
+
const node = structure.nodes[nodeId];
|
|
1559
|
+
let matched = false;
|
|
1560
|
+
if (node.data && !matched) {
|
|
1561
|
+
const dataKeys = Object.keys(node.data);
|
|
1562
|
+
for (let j = 0; j < dataKeys.length && !matched; j++) {
|
|
1563
|
+
const val = node.data[dataKeys[j]];
|
|
1564
|
+
if (val != null && typeof val !== "object" && String(val).toLowerCase().includes(lower)) {
|
|
1565
|
+
matched = true;
|
|
1437
1566
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
}
|
|
1446
|
-
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
if (!matched && node.derivedNode && node.derivedNode.toLowerCase().includes(lower)) {
|
|
1570
|
+
matched = true;
|
|
1571
|
+
}
|
|
1572
|
+
if (!matched && nodeId.toLowerCase().includes(lower)) {
|
|
1573
|
+
matched = true;
|
|
1574
|
+
}
|
|
1575
|
+
if (matched) {
|
|
1576
|
+
results.push({ nodeId, description: describeFn(node) });
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
return results;
|
|
1447
1580
|
};
|
|
1448
|
-
|
|
1449
|
-
var
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1581
|
+
var text_chat_default = (options) => {
|
|
1582
|
+
var _a;
|
|
1583
|
+
const {
|
|
1584
|
+
structure,
|
|
1585
|
+
container,
|
|
1586
|
+
entryPoint,
|
|
1587
|
+
describeNode: describeNode2 = defaultDescribeNode,
|
|
1588
|
+
commandLabels = {},
|
|
1589
|
+
onNavigate,
|
|
1590
|
+
onExit,
|
|
1591
|
+
llm,
|
|
1592
|
+
data
|
|
1593
|
+
} = options;
|
|
1594
|
+
const rootEl = typeof container === "string" ? document.getElementById(container) : container;
|
|
1595
|
+
if (!rootEl) {
|
|
1596
|
+
throw new Error(`textChat: container "${container}" not found`);
|
|
1597
|
+
}
|
|
1598
|
+
const resolvedEntryPoint = entryPoint || (structure.dimensions ? (_a = structure.dimensions[Object.keys(structure.dimensions)[0]]) == null ? void 0 : _a.nodeId : Object.keys(structure.nodes)[0]);
|
|
1599
|
+
const inputHandler = input_default({
|
|
1600
|
+
structure,
|
|
1601
|
+
navigationRules: structure.navigationRules || {},
|
|
1602
|
+
entryPoint: resolvedEntryPoint
|
|
1603
|
+
});
|
|
1604
|
+
let currentNodeId = null;
|
|
1605
|
+
const uid = Math.random().toString(36).slice(2, 8);
|
|
1606
|
+
const history = [];
|
|
1607
|
+
let historyIndex = -1;
|
|
1608
|
+
let pendingChoices = null;
|
|
1609
|
+
const llmHistory = [];
|
|
1610
|
+
const buildSystemPrompt = () => {
|
|
1611
|
+
let prompt = "You are a data assistant helping a user explore a dataset through a text-based navigation interface.\n\n";
|
|
1612
|
+
if (data && data.length > 0) {
|
|
1613
|
+
const columns = Object.keys(data[0]);
|
|
1614
|
+
const sampleRows = data.slice(0, 3).map((r) => JSON.stringify(r)).join("\n ");
|
|
1615
|
+
prompt += `DATASET SUMMARY:
|
|
1616
|
+
- Columns: ${columns.join(", ")}
|
|
1617
|
+
- Rows: ${data.length}
|
|
1618
|
+
- Sample (first 3):
|
|
1619
|
+
${sampleRows}
|
|
1620
|
+
|
|
1621
|
+
`;
|
|
1622
|
+
prompt += "FULL DATASET (JSON):\n" + JSON.stringify(data) + "\n\n";
|
|
1623
|
+
}
|
|
1624
|
+
if (currentNodeId) {
|
|
1625
|
+
const node = structure.nodes[currentNodeId];
|
|
1626
|
+
prompt += `CURRENT POSITION: ${node ? describeNode2(node) : currentNodeId}
|
|
1627
|
+
|
|
1628
|
+
`;
|
|
1629
|
+
} else {
|
|
1630
|
+
prompt += "CURRENT POSITION: Not yet navigated into the structure.\n\n";
|
|
1631
|
+
}
|
|
1632
|
+
prompt += "PRIORITY: Always prefer answers that can be verified against the dataset. For any statistical or quantitative claim (averages, comparisons, trends, extremes), briefly describe the method you used. Avoid open-ended or contextual claims that go beyond what the data can support \u2014 if the user asks something that cannot be checked against the dataset, say so and suggest they verify externally.\n\n";
|
|
1633
|
+
prompt += "VERIFICATION: When the user asks you to verify a claim, write a short Python script (using the dataset as a JSON array) that computes the answer, and show the expected output. If the claim is too open-ended to verify with code, explain why and recommend external verification.\n\n";
|
|
1634
|
+
prompt += 'IMPORTANT: Your responses may contain errors. The user has been told they can ask you to "verify" any answer, and you will attempt to provide a Python script to check it.';
|
|
1635
|
+
return prompt;
|
|
1636
|
+
};
|
|
1637
|
+
const chatEl = document.createElement("div");
|
|
1638
|
+
chatEl.className = "dn-text-chat";
|
|
1639
|
+
const logEl = document.createElement("div");
|
|
1640
|
+
logEl.className = "dn-text-chat-log";
|
|
1641
|
+
logEl.setAttribute("role", "log");
|
|
1642
|
+
logEl.setAttribute("aria-live", "polite");
|
|
1643
|
+
chatEl.appendChild(logEl);
|
|
1644
|
+
const controlsEl = document.createElement("div");
|
|
1645
|
+
controlsEl.className = "dn-text-chat-controls";
|
|
1646
|
+
const announceLabel = document.createElement("label");
|
|
1647
|
+
const announceCheckbox = document.createElement("input");
|
|
1648
|
+
announceCheckbox.type = "checkbox";
|
|
1649
|
+
announceCheckbox.checked = true;
|
|
1650
|
+
announceCheckbox.addEventListener("change", () => {
|
|
1651
|
+
logEl.setAttribute("aria-live", announceCheckbox.checked ? "polite" : "off");
|
|
1652
|
+
});
|
|
1653
|
+
announceLabel.appendChild(announceCheckbox);
|
|
1654
|
+
announceLabel.appendChild(document.createTextNode(" Automatically announce to screen readers"));
|
|
1655
|
+
controlsEl.appendChild(announceLabel);
|
|
1656
|
+
chatEl.appendChild(controlsEl);
|
|
1657
|
+
const formEl = document.createElement("form");
|
|
1658
|
+
formEl.className = "dn-text-chat-form";
|
|
1659
|
+
const inputLabel = document.createElement("label");
|
|
1660
|
+
inputLabel.setAttribute("for", `dn-text-chat-input-${uid}`);
|
|
1661
|
+
inputLabel.className = "dn-text-chat-sr-only";
|
|
1662
|
+
inputLabel.textContent = "Navigation command";
|
|
1663
|
+
const inputEl = document.createElement("input");
|
|
1664
|
+
inputEl.type = "text";
|
|
1665
|
+
inputEl.id = `dn-text-chat-input-${uid}`;
|
|
1666
|
+
inputEl.autocomplete = "off";
|
|
1667
|
+
inputEl.setAttribute("placeholder", "Type a command...");
|
|
1668
|
+
const submitBtn = document.createElement("button");
|
|
1669
|
+
submitBtn.type = "submit";
|
|
1670
|
+
submitBtn.textContent = "Send";
|
|
1671
|
+
formEl.appendChild(inputLabel);
|
|
1672
|
+
formEl.appendChild(inputEl);
|
|
1673
|
+
formEl.appendChild(submitBtn);
|
|
1674
|
+
chatEl.appendChild(formEl);
|
|
1675
|
+
rootEl.appendChild(chatEl);
|
|
1676
|
+
let savedInput = "";
|
|
1677
|
+
inputEl.addEventListener("keydown", (e) => {
|
|
1678
|
+
if (e.key === "ArrowUp") {
|
|
1679
|
+
e.preventDefault();
|
|
1680
|
+
if (history.length === 0)
|
|
1681
|
+
return;
|
|
1682
|
+
if (historyIndex === -1) {
|
|
1683
|
+
savedInput = inputEl.value;
|
|
1684
|
+
historyIndex = history.length - 1;
|
|
1685
|
+
} else if (historyIndex > 0) {
|
|
1686
|
+
historyIndex--;
|
|
1687
|
+
}
|
|
1688
|
+
inputEl.value = history[historyIndex];
|
|
1689
|
+
} else if (e.key === "ArrowDown") {
|
|
1690
|
+
e.preventDefault();
|
|
1691
|
+
if (historyIndex === -1)
|
|
1692
|
+
return;
|
|
1693
|
+
if (historyIndex < history.length - 1) {
|
|
1694
|
+
historyIndex++;
|
|
1695
|
+
inputEl.value = history[historyIndex];
|
|
1696
|
+
} else {
|
|
1697
|
+
historyIndex = -1;
|
|
1698
|
+
inputEl.value = savedInput;
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
});
|
|
1702
|
+
const addMessage = (text, className) => {
|
|
1703
|
+
const msg = document.createElement("div");
|
|
1704
|
+
msg.className = `dn-text-chat-message ${className}`;
|
|
1705
|
+
msg.textContent = text;
|
|
1706
|
+
logEl.appendChild(msg);
|
|
1707
|
+
logEl.scrollTop = logEl.scrollHeight;
|
|
1708
|
+
};
|
|
1709
|
+
const addSystemMessage = (text) => addMessage(text, "dn-text-chat-system");
|
|
1710
|
+
const addEcho = (text) => addMessage(`> ${text}`, "dn-text-chat-input-echo");
|
|
1711
|
+
const addResponse = (text) => addMessage(text, "dn-text-chat-response");
|
|
1712
|
+
const addResponseWithList = (intro, items) => {
|
|
1713
|
+
const wrapper = document.createElement("div");
|
|
1714
|
+
wrapper.className = "dn-text-chat-message dn-text-chat-response";
|
|
1715
|
+
const p = document.createElement("span");
|
|
1716
|
+
p.textContent = intro;
|
|
1717
|
+
wrapper.appendChild(p);
|
|
1718
|
+
const ol = document.createElement("ol");
|
|
1719
|
+
ol.className = "dn-text-chat-choices";
|
|
1720
|
+
items.forEach((item) => {
|
|
1721
|
+
const li = document.createElement("li");
|
|
1722
|
+
li.textContent = item;
|
|
1723
|
+
ol.appendChild(li);
|
|
1724
|
+
});
|
|
1725
|
+
wrapper.appendChild(ol);
|
|
1726
|
+
logEl.appendChild(wrapper);
|
|
1727
|
+
logEl.scrollTop = logEl.scrollHeight;
|
|
1728
|
+
};
|
|
1729
|
+
const askLLM = (question) => __async(void 0, null, function* () {
|
|
1730
|
+
const systemMsg = { role: "system", content: buildSystemPrompt() };
|
|
1731
|
+
llmHistory.push({ role: "user", content: question });
|
|
1732
|
+
const thinkingMsg = document.createElement("div");
|
|
1733
|
+
thinkingMsg.className = "dn-text-chat-message dn-text-chat-llm-thinking";
|
|
1734
|
+
thinkingMsg.textContent = "Thinking...";
|
|
1735
|
+
logEl.appendChild(thinkingMsg);
|
|
1736
|
+
logEl.scrollTop = logEl.scrollHeight;
|
|
1737
|
+
try {
|
|
1738
|
+
const response = yield llm([systemMsg, ...llmHistory]);
|
|
1739
|
+
logEl.removeChild(thinkingMsg);
|
|
1740
|
+
if (response === null) {
|
|
1741
|
+
llmHistory.pop();
|
|
1742
|
+
return null;
|
|
1743
|
+
}
|
|
1744
|
+
llmHistory.push({ role: "assistant", content: response });
|
|
1745
|
+
addResponse(response);
|
|
1746
|
+
return response;
|
|
1747
|
+
} catch (err) {
|
|
1748
|
+
logEl.removeChild(thinkingMsg);
|
|
1749
|
+
llmHistory.pop();
|
|
1750
|
+
addResponse(`Error: ${err.message || "Could not get a response."}`);
|
|
1751
|
+
return "";
|
|
1752
|
+
}
|
|
1753
|
+
});
|
|
1754
|
+
if (llm) {
|
|
1755
|
+
addSystemMessage('Text navigation ready. Type "enter" to begin navigating, "help" for commands, or ask a question about the data.');
|
|
1756
|
+
addSystemMessage('Note: AI-generated answers may be inaccurate. You can ask the model to "verify" any answer \u2014 it will attempt to provide a Python script that checks the claim against the dataset. If a claim cannot be verified with code, it should be verified externally.');
|
|
1757
|
+
} else {
|
|
1758
|
+
addSystemMessage('Text navigation ready. Type "enter" to begin or "help" for available commands.');
|
|
1759
|
+
}
|
|
1760
|
+
const specialCommands = ["enter", "help", "more", "more help", "clear"];
|
|
1761
|
+
const moveToNode = (nodeId) => {
|
|
1762
|
+
const node = inputHandler.moveTo(nodeId);
|
|
1763
|
+
if (node) {
|
|
1764
|
+
currentNodeId = node.id;
|
|
1765
|
+
if (onNavigate)
|
|
1766
|
+
onNavigate(node);
|
|
1767
|
+
addResponse(`Moved to: ${describeNode2(node)}`);
|
|
1768
|
+
} else {
|
|
1769
|
+
addResponse("Could not move to that node.");
|
|
1770
|
+
}
|
|
1771
|
+
};
|
|
1772
|
+
const handleCommand = (raw) => __async(void 0, null, function* () {
|
|
1773
|
+
const trimmed = raw.trim();
|
|
1774
|
+
if (!trimmed)
|
|
1775
|
+
return;
|
|
1776
|
+
addEcho(trimmed);
|
|
1777
|
+
const lower = trimmed.toLowerCase();
|
|
1778
|
+
if (pendingChoices) {
|
|
1779
|
+
const num = parseInt(trimmed, 10);
|
|
1780
|
+
if (!isNaN(num) && num >= 1 && num <= pendingChoices.length) {
|
|
1781
|
+
const choice = pendingChoices[num - 1];
|
|
1782
|
+
pendingChoices = null;
|
|
1783
|
+
moveToNode(choice.nodeId);
|
|
1784
|
+
return;
|
|
1785
|
+
}
|
|
1786
|
+
pendingChoices = null;
|
|
1787
|
+
}
|
|
1788
|
+
if (lower === "clear") {
|
|
1789
|
+
logEl.innerHTML = "";
|
|
1790
|
+
addSystemMessage('Chat cleared. Type "help" for available commands.');
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
if (lower === "enter") {
|
|
1794
|
+
if (currentNodeId) {
|
|
1795
|
+
addResponse('Already in the structure. Type "help" to see available commands.');
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
1798
|
+
const entryNode = inputHandler.enter();
|
|
1799
|
+
if (!entryNode) {
|
|
1800
|
+
addResponse("Could not enter the structure. No entry point found.");
|
|
1801
|
+
return;
|
|
1802
|
+
}
|
|
1803
|
+
currentNodeId = entryNode.id;
|
|
1804
|
+
if (onNavigate)
|
|
1805
|
+
onNavigate(entryNode);
|
|
1806
|
+
addResponse(`Entered: ${describeNode2(entryNode)}`);
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
if (lower === "help") {
|
|
1810
|
+
const llmHint = llm ? " You can also type any question about the data." : "";
|
|
1811
|
+
if (!currentNodeId) {
|
|
1812
|
+
addResponse(
|
|
1813
|
+
'Not yet in the structure. Type "enter" to begin navigating, or "move to <search>" to jump to a node.' + llmHint
|
|
1814
|
+
);
|
|
1815
|
+
} else {
|
|
1816
|
+
const node = structure.nodes[currentNodeId];
|
|
1817
|
+
const available = getAvailableRules(currentNodeId, node, structure);
|
|
1818
|
+
const formatted = available.map((r) => formatRule(r, commandLabels));
|
|
1819
|
+
addResponse(`Available: ${formatted.join(", ")}, move to <search>.` + llmHint);
|
|
1820
|
+
}
|
|
1821
|
+
return;
|
|
1822
|
+
}
|
|
1823
|
+
if (lower.startsWith("move to ")) {
|
|
1824
|
+
const query = trimmed.slice("move to ".length).trim();
|
|
1825
|
+
if (!query) {
|
|
1826
|
+
addResponse("Usage: move to <search term>");
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
const results = searchNodes(query, structure, describeNode2);
|
|
1830
|
+
if (results.length === 0) {
|
|
1831
|
+
addResponse(`No nodes found matching "${query}".`);
|
|
1832
|
+
} else if (results.length === 1) {
|
|
1833
|
+
moveToNode(results[0].nodeId);
|
|
1834
|
+
} else {
|
|
1835
|
+
pendingChoices = results;
|
|
1836
|
+
addResponseWithList(
|
|
1837
|
+
`Found ${results.length} matches. Type a number to move there:`,
|
|
1838
|
+
results.map((r) => r.description)
|
|
1839
|
+
);
|
|
1840
|
+
}
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1843
|
+
if (lower === "more" || lower === "more help") {
|
|
1844
|
+
const allRules2 = getAllRuleNames(structure);
|
|
1845
|
+
const formatted = allRules2.map((r) => formatRule(r, commandLabels));
|
|
1846
|
+
addResponse(`All navigation rules: ${formatted.join(", ")}.`);
|
|
1847
|
+
return;
|
|
1848
|
+
}
|
|
1849
|
+
if (!currentNodeId) {
|
|
1850
|
+
if (llm) {
|
|
1851
|
+
const response = yield askLLM(trimmed);
|
|
1852
|
+
if (response !== null)
|
|
1853
|
+
return;
|
|
1854
|
+
}
|
|
1855
|
+
const llmHint = llm ? " Enter an API key above to ask questions about the data." : "";
|
|
1856
|
+
addResponse('Type "enter" to begin navigating the structure, or "move to <search>" to jump to a node.' + llmHint);
|
|
1857
|
+
return;
|
|
1858
|
+
}
|
|
1859
|
+
const allRules = getAllRuleNames(structure);
|
|
1860
|
+
const { match, ambiguous } = fuzzyMatch(lower, [...allRules, ...specialCommands], commandLabels);
|
|
1861
|
+
if (match && specialCommands.includes(match)) {
|
|
1862
|
+
yield handleCommand(match);
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
if (!match && ambiguous.length > 0) {
|
|
1866
|
+
const formatted = ambiguous.map((r) => formatRule(r, commandLabels));
|
|
1867
|
+
addResponse(`Did you mean: ${formatted.join(", ")}?`);
|
|
1868
|
+
return;
|
|
1869
|
+
}
|
|
1870
|
+
if (!match) {
|
|
1871
|
+
if (llm) {
|
|
1872
|
+
const response = yield askLLM(trimmed);
|
|
1873
|
+
if (response !== null)
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1876
|
+
const llmHint = llm ? " Enter an API key above to ask questions about the data." : "";
|
|
1877
|
+
addResponse(`Unknown command "${trimmed}". Type "help" for available commands.` + llmHint);
|
|
1878
|
+
return;
|
|
1879
|
+
}
|
|
1880
|
+
const direction = match;
|
|
1881
|
+
const label = commandLabels[direction] || direction;
|
|
1882
|
+
if (direction === "exit") {
|
|
1883
|
+
currentNodeId = null;
|
|
1884
|
+
if (onExit)
|
|
1885
|
+
onExit();
|
|
1886
|
+
addResponse('Exited the structure. Type "enter" to re-enter.');
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
const nextNode = inputHandler.move(currentNodeId, direction);
|
|
1890
|
+
if (nextNode) {
|
|
1891
|
+
currentNodeId = nextNode.id;
|
|
1892
|
+
if (onNavigate)
|
|
1893
|
+
onNavigate(nextNode);
|
|
1894
|
+
addResponse(`${label}: ${describeNode2(nextNode)}`);
|
|
1895
|
+
} else {
|
|
1896
|
+
addResponse(`Cannot move "${direction}" from here.`);
|
|
1897
|
+
}
|
|
1898
|
+
});
|
|
1899
|
+
formEl.addEventListener("submit", (e) => __async(void 0, null, function* () {
|
|
1900
|
+
e.preventDefault();
|
|
1901
|
+
const value = inputEl.value.trim();
|
|
1902
|
+
if (value) {
|
|
1903
|
+
history.push(value);
|
|
1904
|
+
historyIndex = -1;
|
|
1905
|
+
}
|
|
1906
|
+
yield handleCommand(inputEl.value);
|
|
1907
|
+
inputEl.value = "";
|
|
1908
|
+
inputEl.focus();
|
|
1909
|
+
}));
|
|
1910
|
+
return {
|
|
1911
|
+
destroy() {
|
|
1912
|
+
rootEl.removeChild(chatEl);
|
|
1913
|
+
},
|
|
1914
|
+
getCurrentNode() {
|
|
1915
|
+
return currentNodeId ? structure.nodes[currentNodeId] || null : null;
|
|
1916
|
+
}
|
|
1917
|
+
};
|
|
1453
1918
|
};
|
|
1919
|
+
|
|
1920
|
+
// src/index.ts
|
|
1921
|
+
var src_default = { structure: structure_default, input: input_default, rendering: rendering_default, textChat: text_chat_default };
|