@rxflow/manhattan 0.0.2-alpha.8 → 0.0.3
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/README.md +214 -10
- package/cjs/getManHattanPath.d.ts.map +1 -1
- package/cjs/getManHattanPath.js +77 -46
- package/cjs/obstacle/ObstacleMap.d.ts +41 -9
- package/cjs/obstacle/ObstacleMap.d.ts.map +1 -1
- package/cjs/obstacle/ObstacleMap.js +201 -96
- package/cjs/obstacle/QuadTree.d.ts +119 -0
- package/cjs/obstacle/QuadTree.d.ts.map +1 -0
- package/cjs/obstacle/QuadTree.js +334 -0
- package/cjs/options/defaults.d.ts +1 -1
- package/cjs/options/defaults.d.ts.map +1 -1
- package/cjs/options/resolver.d.ts.map +1 -1
- package/cjs/options/resolver.js +145 -17
- package/cjs/options/types.d.ts +41 -0
- package/cjs/options/types.d.ts.map +1 -1
- package/cjs/pathfinder/PathCache.d.ts +92 -0
- package/cjs/pathfinder/PathCache.d.ts.map +1 -0
- package/cjs/pathfinder/PathCache.js +249 -0
- package/cjs/pathfinder/findRoute.d.ts.map +1 -1
- package/cjs/pathfinder/findRoute.js +96 -31
- package/cjs/pathfinder/index.d.ts +1 -0
- package/cjs/pathfinder/index.d.ts.map +1 -1
- package/cjs/pathfinder/index.js +26 -1
- package/cjs/svg/pathConverter.d.ts +13 -0
- package/cjs/svg/pathConverter.d.ts.map +1 -1
- package/cjs/svg/pathConverter.js +170 -1
- package/cjs/utils/AdaptiveStepCalculator.d.ts +90 -0
- package/cjs/utils/AdaptiveStepCalculator.d.ts.map +1 -0
- package/cjs/utils/AdaptiveStepCalculator.js +224 -0
- package/cjs/utils/ErrorRecovery.d.ts +182 -0
- package/cjs/utils/ErrorRecovery.d.ts.map +1 -0
- package/cjs/utils/ErrorRecovery.js +413 -0
- package/cjs/utils/GlobalGrid.d.ts +99 -0
- package/cjs/utils/GlobalGrid.d.ts.map +1 -0
- package/cjs/utils/GlobalGrid.js +224 -0
- package/cjs/utils/PerformanceMonitor.d.ts +139 -0
- package/cjs/utils/PerformanceMonitor.d.ts.map +1 -0
- package/cjs/utils/PerformanceMonitor.js +305 -0
- package/cjs/utils/getAnchorPoints.d.ts.map +1 -1
- package/cjs/utils/getAnchorPoints.js +0 -4
- package/cjs/utils/grid.d.ts +15 -0
- package/cjs/utils/grid.d.ts.map +1 -1
- package/cjs/utils/grid.js +19 -12
- package/cjs/utils/heuristics.d.ts +61 -0
- package/cjs/utils/heuristics.d.ts.map +1 -0
- package/cjs/utils/heuristics.js +141 -0
- package/cjs/utils/index.d.ts +6 -0
- package/cjs/utils/index.d.ts.map +1 -1
- package/cjs/utils/index.js +66 -0
- package/cjs/utils/pathProcessing.d.ts +45 -0
- package/cjs/utils/pathProcessing.d.ts.map +1 -0
- package/cjs/utils/pathProcessing.js +270 -0
- package/cjs/utils/pathValidation.d.ts.map +1 -1
- package/cjs/utils/pathValidation.js +0 -1
- package/cjs/utils/rect.d.ts.map +1 -1
- package/cjs/utils/rect.js +7 -0
- package/cjs/utils/route.d.ts.map +1 -1
- package/cjs/utils/route.js +18 -2
- package/esm/getManHattanPath.d.ts.map +1 -1
- package/esm/getManHattanPath.js +92 -69
- package/esm/obstacle/ObstacleMap.d.ts +41 -9
- package/esm/obstacle/ObstacleMap.d.ts.map +1 -1
- package/esm/obstacle/ObstacleMap.js +218 -99
- package/esm/obstacle/QuadTree.d.ts +119 -0
- package/esm/obstacle/QuadTree.d.ts.map +1 -0
- package/esm/obstacle/QuadTree.js +488 -0
- package/esm/options/defaults.d.ts +1 -1
- package/esm/options/defaults.d.ts.map +1 -1
- package/esm/options/resolver.d.ts.map +1 -1
- package/esm/options/resolver.js +147 -18
- package/esm/options/types.d.ts +41 -0
- package/esm/options/types.d.ts.map +1 -1
- package/esm/pathfinder/PathCache.d.ts +92 -0
- package/esm/pathfinder/PathCache.d.ts.map +1 -0
- package/esm/pathfinder/PathCache.js +278 -0
- package/esm/pathfinder/findRoute.d.ts.map +1 -1
- package/esm/pathfinder/findRoute.js +98 -44
- package/esm/pathfinder/index.d.ts +1 -0
- package/esm/pathfinder/index.d.ts.map +1 -1
- package/esm/pathfinder/index.js +2 -1
- package/esm/svg/pathConverter.d.ts +13 -0
- package/esm/svg/pathConverter.d.ts.map +1 -1
- package/esm/svg/pathConverter.js +170 -1
- package/esm/utils/AdaptiveStepCalculator.d.ts +90 -0
- package/esm/utils/AdaptiveStepCalculator.d.ts.map +1 -0
- package/esm/utils/AdaptiveStepCalculator.js +252 -0
- package/esm/utils/ErrorRecovery.d.ts +182 -0
- package/esm/utils/ErrorRecovery.d.ts.map +1 -0
- package/esm/utils/ErrorRecovery.js +499 -0
- package/esm/utils/GlobalGrid.d.ts +99 -0
- package/esm/utils/GlobalGrid.d.ts.map +1 -0
- package/esm/utils/GlobalGrid.js +259 -0
- package/esm/utils/PerformanceMonitor.d.ts +139 -0
- package/esm/utils/PerformanceMonitor.d.ts.map +1 -0
- package/esm/utils/PerformanceMonitor.js +360 -0
- package/esm/utils/getAnchorPoints.d.ts.map +1 -1
- package/esm/utils/getAnchorPoints.js +0 -4
- package/esm/utils/grid.d.ts +15 -0
- package/esm/utils/grid.d.ts.map +1 -1
- package/esm/utils/grid.js +18 -13
- package/esm/utils/heuristics.d.ts +61 -0
- package/esm/utils/heuristics.d.ts.map +1 -0
- package/esm/utils/heuristics.js +144 -0
- package/esm/utils/index.d.ts +6 -0
- package/esm/utils/index.d.ts.map +1 -1
- package/esm/utils/index.js +7 -1
- package/esm/utils/pathProcessing.d.ts +45 -0
- package/esm/utils/pathProcessing.d.ts.map +1 -0
- package/esm/utils/pathProcessing.js +270 -0
- package/esm/utils/pathValidation.d.ts.map +1 -1
- package/esm/utils/pathValidation.js +0 -1
- package/esm/utils/rect.d.ts.map +1 -1
- package/esm/utils/rect.js +11 -4
- package/esm/utils/route.d.ts.map +1 -1
- package/esm/utils/route.js +18 -2
- package/package.json +10 -2
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.QuadTree = void 0;
|
|
7
|
+
exports.createQuadTreeFromRects = createQuadTreeFromRects;
|
|
8
|
+
var _geometry = require("../geometry");
|
|
9
|
+
/**
|
|
10
|
+
* QuadTree implementation for efficient spatial queries
|
|
11
|
+
* Feature: manhattan-optimization
|
|
12
|
+
*
|
|
13
|
+
* A QuadTree is a tree data structure that recursively subdivides 2D space
|
|
14
|
+
* into four quadrants. This enables O(log n) spatial queries instead of O(n).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Item stored in the QuadTree
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* QuadTree configuration
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Default QuadTree configuration
|
|
27
|
+
*/
|
|
28
|
+
const DEFAULT_CONFIG = {
|
|
29
|
+
maxItems: 8,
|
|
30
|
+
maxDepth: 8,
|
|
31
|
+
minSize: 10
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* QuadTree node for spatial partitioning
|
|
36
|
+
*/
|
|
37
|
+
class QuadTree {
|
|
38
|
+
bounds;
|
|
39
|
+
items;
|
|
40
|
+
children;
|
|
41
|
+
depth;
|
|
42
|
+
config;
|
|
43
|
+
constructor(bounds, config = {}, depth = 0) {
|
|
44
|
+
this.bounds = bounds;
|
|
45
|
+
this.items = [];
|
|
46
|
+
this.children = null;
|
|
47
|
+
this.depth = depth;
|
|
48
|
+
this.config = {
|
|
49
|
+
...DEFAULT_CONFIG,
|
|
50
|
+
...config
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Insert an item into the QuadTree
|
|
56
|
+
*/
|
|
57
|
+
insert(item) {
|
|
58
|
+
// Check if item intersects this node's bounds
|
|
59
|
+
if (!this.intersects(item.bounds)) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// If we have children, try to insert into them
|
|
64
|
+
if (this.children !== null) {
|
|
65
|
+
return this.insertIntoChildren(item);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Add to this node
|
|
69
|
+
this.items.push(item);
|
|
70
|
+
|
|
71
|
+
// Check if we need to split
|
|
72
|
+
if (this.shouldSplit()) {
|
|
73
|
+
this.split();
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Insert an item with just bounds and data
|
|
80
|
+
*/
|
|
81
|
+
insertRect(bounds, data) {
|
|
82
|
+
return this.insert({
|
|
83
|
+
bounds,
|
|
84
|
+
data
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Query all items that intersect with the given bounds
|
|
90
|
+
*/
|
|
91
|
+
query(bounds) {
|
|
92
|
+
const results = [];
|
|
93
|
+
this.queryInternal(bounds, results);
|
|
94
|
+
return results;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Query all items that contain the given point
|
|
99
|
+
*/
|
|
100
|
+
queryPoint(point) {
|
|
101
|
+
const results = [];
|
|
102
|
+
this.queryPointInternal(point, results);
|
|
103
|
+
return results;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get all items in the tree
|
|
108
|
+
*/
|
|
109
|
+
getAllItems() {
|
|
110
|
+
const results = [...this.items];
|
|
111
|
+
if (this.children !== null) {
|
|
112
|
+
for (const child of this.children) {
|
|
113
|
+
results.push(...child.getAllItems());
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return results;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Clear all items from the tree
|
|
121
|
+
*/
|
|
122
|
+
clear() {
|
|
123
|
+
this.items = [];
|
|
124
|
+
this.children = null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get the total number of items in the tree
|
|
129
|
+
*/
|
|
130
|
+
get size() {
|
|
131
|
+
let count = this.items.length;
|
|
132
|
+
if (this.children !== null) {
|
|
133
|
+
for (const child of this.children) {
|
|
134
|
+
count += child.size;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return count;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get the depth of the tree
|
|
142
|
+
*/
|
|
143
|
+
getMaxDepth() {
|
|
144
|
+
if (this.children === null) {
|
|
145
|
+
return this.depth;
|
|
146
|
+
}
|
|
147
|
+
let maxChildDepth = this.depth;
|
|
148
|
+
for (const child of this.children) {
|
|
149
|
+
maxChildDepth = Math.max(maxChildDepth, child.getMaxDepth());
|
|
150
|
+
}
|
|
151
|
+
return maxChildDepth;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Internal query implementation
|
|
156
|
+
*/
|
|
157
|
+
queryInternal(bounds, results) {
|
|
158
|
+
// Check if query bounds intersects this node
|
|
159
|
+
if (!this.intersects(bounds)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Check items in this node
|
|
164
|
+
for (const item of this.items) {
|
|
165
|
+
if (this.rectanglesIntersect(item.bounds, bounds)) {
|
|
166
|
+
results.push(item);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Query children
|
|
171
|
+
if (this.children !== null) {
|
|
172
|
+
for (const child of this.children) {
|
|
173
|
+
child.queryInternal(bounds, results);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Internal point query implementation
|
|
180
|
+
*/
|
|
181
|
+
queryPointInternal(point, results) {
|
|
182
|
+
// Check if point is within this node's bounds
|
|
183
|
+
if (!this.containsPoint(point)) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Check items in this node
|
|
188
|
+
for (const item of this.items) {
|
|
189
|
+
if (item.bounds.containsPoint(point)) {
|
|
190
|
+
results.push(item);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Query children
|
|
195
|
+
if (this.children !== null) {
|
|
196
|
+
for (const child of this.children) {
|
|
197
|
+
child.queryPointInternal(point, results);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Check if this node should split
|
|
204
|
+
*/
|
|
205
|
+
shouldSplit() {
|
|
206
|
+
return this.items.length > this.config.maxItems && this.depth < this.config.maxDepth && this.bounds.width > this.config.minSize * 2 && this.bounds.height > this.config.minSize * 2;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Split this node into four children
|
|
211
|
+
*/
|
|
212
|
+
split() {
|
|
213
|
+
const halfWidth = this.bounds.width / 2;
|
|
214
|
+
const halfHeight = this.bounds.height / 2;
|
|
215
|
+
const x = this.bounds.x;
|
|
216
|
+
const y = this.bounds.y;
|
|
217
|
+
const nextDepth = this.depth + 1;
|
|
218
|
+
this.children = [
|
|
219
|
+
// Top-left
|
|
220
|
+
new QuadTree(new _geometry.Rectangle(x, y, halfWidth, halfHeight), this.config, nextDepth),
|
|
221
|
+
// Top-right
|
|
222
|
+
new QuadTree(new _geometry.Rectangle(x + halfWidth, y, halfWidth, halfHeight), this.config, nextDepth),
|
|
223
|
+
// Bottom-left
|
|
224
|
+
new QuadTree(new _geometry.Rectangle(x, y + halfHeight, halfWidth, halfHeight), this.config, nextDepth),
|
|
225
|
+
// Bottom-right
|
|
226
|
+
new QuadTree(new _geometry.Rectangle(x + halfWidth, y + halfHeight, halfWidth, halfHeight), this.config, nextDepth)];
|
|
227
|
+
|
|
228
|
+
// Redistribute items to children
|
|
229
|
+
const itemsToRedistribute = this.items;
|
|
230
|
+
this.items = [];
|
|
231
|
+
for (const item of itemsToRedistribute) {
|
|
232
|
+
this.insertIntoChildren(item);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Insert item into appropriate children
|
|
238
|
+
*/
|
|
239
|
+
insertIntoChildren(item) {
|
|
240
|
+
if (this.children === null) {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
let inserted = false;
|
|
244
|
+
for (const child of this.children) {
|
|
245
|
+
if (child.insert(item)) {
|
|
246
|
+
inserted = true;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// If item doesn't fit in any child (spans multiple), keep in this node
|
|
251
|
+
if (!inserted) {
|
|
252
|
+
this.items.push(item);
|
|
253
|
+
inserted = true;
|
|
254
|
+
}
|
|
255
|
+
return inserted;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Check if a rectangle intersects this node's bounds
|
|
260
|
+
*/
|
|
261
|
+
intersects(rect) {
|
|
262
|
+
return this.rectanglesIntersect(this.bounds, rect);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Check if two rectangles intersect
|
|
267
|
+
*/
|
|
268
|
+
rectanglesIntersect(a, b) {
|
|
269
|
+
return !(a.x + a.width <= b.x || b.x + b.width <= a.x || a.y + a.height <= b.y || b.y + b.height <= a.y);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Check if this node's bounds contain a point
|
|
274
|
+
*/
|
|
275
|
+
containsPoint(point) {
|
|
276
|
+
return point.x >= this.bounds.x && point.x <= this.bounds.x + this.bounds.width && point.y >= this.bounds.y && point.y <= this.bounds.y + this.bounds.height;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Get statistics about the tree
|
|
281
|
+
*/
|
|
282
|
+
getStats() {
|
|
283
|
+
const stats = {
|
|
284
|
+
totalItems: 0,
|
|
285
|
+
maxDepth: 0,
|
|
286
|
+
nodeCount: 0,
|
|
287
|
+
itemsPerNode: 0
|
|
288
|
+
};
|
|
289
|
+
this.collectStats(stats);
|
|
290
|
+
stats.itemsPerNode = stats.nodeCount > 0 ? stats.totalItems / stats.nodeCount : 0;
|
|
291
|
+
return stats;
|
|
292
|
+
}
|
|
293
|
+
collectStats(stats) {
|
|
294
|
+
stats.totalItems += this.items.length;
|
|
295
|
+
stats.maxDepth = Math.max(stats.maxDepth, this.depth);
|
|
296
|
+
stats.nodeCount++;
|
|
297
|
+
if (this.children !== null) {
|
|
298
|
+
for (const child of this.children) {
|
|
299
|
+
child.collectStats(stats);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Create a QuadTree with bounds that cover all given rectangles
|
|
307
|
+
*/
|
|
308
|
+
exports.QuadTree = QuadTree;
|
|
309
|
+
function createQuadTreeFromRects(items, config) {
|
|
310
|
+
if (items.length === 0) {
|
|
311
|
+
return new QuadTree(new _geometry.Rectangle(0, 0, 1000, 1000), config);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Calculate bounding box of all items
|
|
315
|
+
let minX = Infinity;
|
|
316
|
+
let minY = Infinity;
|
|
317
|
+
let maxX = -Infinity;
|
|
318
|
+
let maxY = -Infinity;
|
|
319
|
+
for (const item of items) {
|
|
320
|
+
minX = Math.min(minX, item.bounds.x);
|
|
321
|
+
minY = Math.min(minY, item.bounds.y);
|
|
322
|
+
maxX = Math.max(maxX, item.bounds.x + item.bounds.width);
|
|
323
|
+
maxY = Math.max(maxY, item.bounds.y + item.bounds.height);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Add some padding
|
|
327
|
+
const padding = 100;
|
|
328
|
+
const bounds = new _geometry.Rectangle(minX - padding, minY - padding, maxX - minX + padding * 2, maxY - minY + padding * 2);
|
|
329
|
+
const tree = new QuadTree(bounds, config);
|
|
330
|
+
for (const item of items) {
|
|
331
|
+
tree.insert(item);
|
|
332
|
+
}
|
|
333
|
+
return tree;
|
|
334
|
+
}
|
|
@@ -3,7 +3,7 @@ import type { ManhattanRouterOptions } from './types';
|
|
|
3
3
|
/**
|
|
4
4
|
* Default configuration for Manhattan router
|
|
5
5
|
*/
|
|
6
|
-
export declare const defaults: Required<Omit<ManhattanRouterOptions, 'fallbackRoute' | 'sourcePosition' | 'targetPosition'>>;
|
|
6
|
+
export declare const defaults: Required<Omit<ManhattanRouterOptions, 'fallbackRoute' | 'sourcePosition' | 'targetPosition' | 'performance' | 'adaptiveStep' | 'debug'>>;
|
|
7
7
|
/**
|
|
8
8
|
* Direction map - maps direction names to unit vectors
|
|
9
9
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/options/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,sBAAsB,EAAa,MAAM,SAAS,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,gBAAgB,GAAG,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/options/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,sBAAsB,EAAa,MAAM,SAAS,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,aAAa,GAAG,cAAc,GAAG,OAAO,CAAC,CAkB7J,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;CAKxB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/options/resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/options/resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAkC,MAAM,SAAS,CAAA;AAmCtG;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpD;AAgGD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CA4EpF"}
|
package/cjs/options/resolver.js
CHANGED
|
@@ -7,6 +7,26 @@ exports.normalizeAngle = normalizeAngle;
|
|
|
7
7
|
exports.resolveOptions = resolveOptions;
|
|
8
8
|
var _geometry = require("../geometry");
|
|
9
9
|
var _defaults = require("./defaults");
|
|
10
|
+
var _AdaptiveStepCalculator = require("../utils/AdaptiveStepCalculator");
|
|
11
|
+
/**
|
|
12
|
+
* Default performance configuration
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_PERFORMANCE_CONFIG = {
|
|
15
|
+
enableCache: true,
|
|
16
|
+
cacheSize: 100,
|
|
17
|
+
enableQuadTree: true,
|
|
18
|
+
earlyTermination: false
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Default debug configuration
|
|
23
|
+
*/
|
|
24
|
+
const DEFAULT_DEBUG_CONFIG = {
|
|
25
|
+
enableLogging: false,
|
|
26
|
+
enableMetrics: false,
|
|
27
|
+
logLevel: 'info'
|
|
28
|
+
};
|
|
29
|
+
|
|
10
30
|
/**
|
|
11
31
|
* Normalize padding value to box format
|
|
12
32
|
*/
|
|
@@ -35,26 +55,126 @@ function normalizeAngle(angle) {
|
|
|
35
55
|
return angle;
|
|
36
56
|
}
|
|
37
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Validate and fix configuration options
|
|
60
|
+
*/
|
|
61
|
+
function validateAndFixOptions(options) {
|
|
62
|
+
const fixed = {
|
|
63
|
+
...options
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Validate step
|
|
67
|
+
if (fixed.step !== undefined && fixed.step <= 0) {
|
|
68
|
+
console.warn('[ManhattanRouter] Invalid step value, using default');
|
|
69
|
+
fixed.step = _defaults.defaults.step;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Validate maxLoopCount
|
|
73
|
+
if (fixed.maxLoopCount !== undefined && fixed.maxLoopCount <= 0) {
|
|
74
|
+
console.warn('[ManhattanRouter] Invalid maxLoopCount, using default');
|
|
75
|
+
fixed.maxLoopCount = _defaults.defaults.maxLoopCount;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Validate borderRadius
|
|
79
|
+
if (fixed.borderRadius !== undefined && fixed.borderRadius < 0) {
|
|
80
|
+
console.warn('[ManhattanRouter] Invalid borderRadius, using default');
|
|
81
|
+
fixed.borderRadius = _defaults.defaults.borderRadius;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Validate extensionDistance
|
|
85
|
+
if (fixed.extensionDistance !== undefined && fixed.extensionDistance < 0) {
|
|
86
|
+
console.warn('[ManhattanRouter] Invalid extensionDistance, using default');
|
|
87
|
+
fixed.extensionDistance = _defaults.defaults.extensionDistance;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Validate precision
|
|
91
|
+
if (fixed.precision !== undefined && (fixed.precision < 0 || fixed.precision > 10)) {
|
|
92
|
+
console.warn('[ManhattanRouter] Invalid precision, using default');
|
|
93
|
+
fixed.precision = _defaults.defaults.precision;
|
|
94
|
+
}
|
|
95
|
+
return fixed;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Resolve adaptive step configuration
|
|
100
|
+
*/
|
|
101
|
+
function resolveAdaptiveStepConfig(config) {
|
|
102
|
+
if (!config) {
|
|
103
|
+
return {
|
|
104
|
+
..._AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
enabled: config.enabled ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.enabled,
|
|
109
|
+
minStep: config.minStep ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.minStep,
|
|
110
|
+
maxStep: config.maxStep ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.maxStep,
|
|
111
|
+
densityBased: {
|
|
112
|
+
enabled: config.densityBased?.enabled ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.densityBased.enabled,
|
|
113
|
+
threshold: config.densityBased?.threshold ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.densityBased.threshold
|
|
114
|
+
},
|
|
115
|
+
distanceBased: {
|
|
116
|
+
enabled: config.distanceBased?.enabled ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.distanceBased.enabled,
|
|
117
|
+
shortPathThreshold: config.distanceBased?.shortPathThreshold ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.distanceBased.shortPathThreshold,
|
|
118
|
+
longPathThreshold: config.distanceBased?.longPathThreshold ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.distanceBased.longPathThreshold
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Resolve performance configuration
|
|
125
|
+
*/
|
|
126
|
+
function resolvePerformanceConfig(config) {
|
|
127
|
+
if (!config) {
|
|
128
|
+
return {
|
|
129
|
+
...DEFAULT_PERFORMANCE_CONFIG
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
enableCache: config.enableCache ?? DEFAULT_PERFORMANCE_CONFIG.enableCache,
|
|
134
|
+
cacheSize: config.cacheSize ?? DEFAULT_PERFORMANCE_CONFIG.cacheSize,
|
|
135
|
+
enableQuadTree: config.enableQuadTree ?? DEFAULT_PERFORMANCE_CONFIG.enableQuadTree,
|
|
136
|
+
earlyTermination: config.earlyTermination ?? DEFAULT_PERFORMANCE_CONFIG.earlyTermination
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Resolve debug configuration
|
|
142
|
+
*/
|
|
143
|
+
function resolveDebugConfig(config) {
|
|
144
|
+
if (!config) {
|
|
145
|
+
return {
|
|
146
|
+
...DEFAULT_DEBUG_CONFIG
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
enableLogging: config.enableLogging ?? DEFAULT_DEBUG_CONFIG.enableLogging,
|
|
151
|
+
enableMetrics: config.enableMetrics ?? DEFAULT_DEBUG_CONFIG.enableMetrics,
|
|
152
|
+
logLevel: config.logLevel ?? DEFAULT_DEBUG_CONFIG.logLevel
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
38
156
|
/**
|
|
39
157
|
* Resolve options by merging user options with defaults
|
|
40
158
|
*/
|
|
41
159
|
function resolveOptions(options = {}) {
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const
|
|
160
|
+
// Validate and fix options first
|
|
161
|
+
const validatedOptions = validateAndFixOptions(options);
|
|
162
|
+
const step = validatedOptions.step ?? _defaults.defaults.step;
|
|
163
|
+
const maxLoopCount = validatedOptions.maxLoopCount ?? _defaults.defaults.maxLoopCount;
|
|
164
|
+
const precision = validatedOptions.precision ?? _defaults.defaults.precision;
|
|
165
|
+
const maxDirectionChange = validatedOptions.maxDirectionChange ?? _defaults.defaults.maxDirectionChange;
|
|
166
|
+
const startDirections = validatedOptions.startDirections ?? _defaults.defaults.startDirections;
|
|
167
|
+
const endDirections = validatedOptions.endDirections ?? _defaults.defaults.endDirections;
|
|
168
|
+
const excludeNodes = validatedOptions.excludeNodes ?? _defaults.defaults.excludeNodes;
|
|
169
|
+
const excludeShapes = validatedOptions.excludeShapes ?? _defaults.defaults.excludeShapes;
|
|
170
|
+
const excludeTerminals = validatedOptions.excludeTerminals ?? _defaults.defaults.excludeTerminals;
|
|
171
|
+
const borderRadius = validatedOptions.borderRadius ?? _defaults.defaults.borderRadius;
|
|
172
|
+
const extensionDistance = validatedOptions.extensionDistance ?? _defaults.defaults.extensionDistance;
|
|
173
|
+
const penalties = validatedOptions.penalties ?? _defaults.defaults.penalties;
|
|
174
|
+
const fallbackRoute = validatedOptions.fallbackRoute;
|
|
55
175
|
|
|
56
176
|
// Convert padding to paddingBox
|
|
57
|
-
const padding =
|
|
177
|
+
const padding = validatedOptions.padding ?? _defaults.defaults.padding;
|
|
58
178
|
const sides = normalizePadding(padding);
|
|
59
179
|
const paddingBox = {
|
|
60
180
|
x: -sides.left,
|
|
@@ -95,6 +215,11 @@ function resolveOptions(options = {}) {
|
|
|
95
215
|
const point2 = new _geometry.Point(direction.offsetX, direction.offsetY);
|
|
96
216
|
direction.angle = normalizeAngle(point1.theta(point2));
|
|
97
217
|
});
|
|
218
|
+
|
|
219
|
+
// Resolve new configuration sections
|
|
220
|
+
const adaptiveStep = resolveAdaptiveStepConfig(validatedOptions.adaptiveStep);
|
|
221
|
+
const performance = resolvePerformanceConfig(validatedOptions.performance);
|
|
222
|
+
const debug = resolveDebugConfig(validatedOptions.debug);
|
|
98
223
|
return {
|
|
99
224
|
step,
|
|
100
225
|
maxLoopCount,
|
|
@@ -108,13 +233,16 @@ function resolveOptions(options = {}) {
|
|
|
108
233
|
paddingBox,
|
|
109
234
|
borderRadius,
|
|
110
235
|
extensionDistance,
|
|
111
|
-
sourcePosition:
|
|
112
|
-
targetPosition:
|
|
236
|
+
sourcePosition: validatedOptions.sourcePosition,
|
|
237
|
+
targetPosition: validatedOptions.targetPosition,
|
|
113
238
|
directionMap: _defaults.directionMap,
|
|
114
239
|
directions,
|
|
115
240
|
penalties,
|
|
116
241
|
cost,
|
|
117
242
|
fallbackRoute,
|
|
118
|
-
previousDirectionAngle: undefined
|
|
243
|
+
previousDirectionAngle: undefined,
|
|
244
|
+
adaptiveStep,
|
|
245
|
+
performance,
|
|
246
|
+
debug
|
|
119
247
|
};
|
|
120
248
|
}
|
package/cjs/options/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Point } from '../geometry';
|
|
2
|
+
import type { AdaptiveStepConfig } from '../utils/AdaptiveStepCalculator';
|
|
2
3
|
/**
|
|
3
4
|
* Direction type for routing
|
|
4
5
|
*/
|
|
@@ -34,6 +35,30 @@ export interface InternalNode {
|
|
|
34
35
|
* Node lookup map type (ReactFlow's internal structure)
|
|
35
36
|
*/
|
|
36
37
|
export type NodeLookup = Map<string, InternalNode>;
|
|
38
|
+
/**
|
|
39
|
+
* Performance optimization configuration
|
|
40
|
+
*/
|
|
41
|
+
export interface PerformanceConfig {
|
|
42
|
+
/** Enable path caching */
|
|
43
|
+
enableCache?: boolean;
|
|
44
|
+
/** Maximum cache size */
|
|
45
|
+
cacheSize?: number;
|
|
46
|
+
/** Enable QuadTree for obstacle queries */
|
|
47
|
+
enableQuadTree?: boolean;
|
|
48
|
+
/** Enable early termination when good path found */
|
|
49
|
+
earlyTermination?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Debug configuration
|
|
53
|
+
*/
|
|
54
|
+
export interface DebugConfig {
|
|
55
|
+
/** Enable logging */
|
|
56
|
+
enableLogging?: boolean;
|
|
57
|
+
/** Enable performance metrics collection */
|
|
58
|
+
enableMetrics?: boolean;
|
|
59
|
+
/** Log level */
|
|
60
|
+
logLevel?: 'error' | 'warn' | 'info' | 'debug';
|
|
61
|
+
}
|
|
37
62
|
/**
|
|
38
63
|
* Manhattan router configuration options
|
|
39
64
|
*/
|
|
@@ -121,6 +146,19 @@ export interface ManhattanRouterOptions {
|
|
|
121
146
|
* Fallback route function when pathfinding fails
|
|
122
147
|
*/
|
|
123
148
|
fallbackRoute?: (from: Point, to: Point) => Point[];
|
|
149
|
+
/**
|
|
150
|
+
* Adaptive step configuration
|
|
151
|
+
* Automatically adjusts step size based on node density and path distance
|
|
152
|
+
*/
|
|
153
|
+
adaptiveStep?: Partial<AdaptiveStepConfig>;
|
|
154
|
+
/**
|
|
155
|
+
* Performance optimization configuration
|
|
156
|
+
*/
|
|
157
|
+
performance?: PerformanceConfig;
|
|
158
|
+
/**
|
|
159
|
+
* Debug configuration
|
|
160
|
+
*/
|
|
161
|
+
debug?: DebugConfig;
|
|
124
162
|
}
|
|
125
163
|
/**
|
|
126
164
|
* Resolved options with all defaults applied
|
|
@@ -165,5 +203,8 @@ export interface ResolvedOptions {
|
|
|
165
203
|
cost: number;
|
|
166
204
|
fallbackRoute?: (from: Point, to: Point) => Point[];
|
|
167
205
|
previousDirectionAngle?: number | null;
|
|
206
|
+
adaptiveStep: AdaptiveStepConfig;
|
|
207
|
+
performance: Required<PerformanceConfig>;
|
|
208
|
+
debug: Required<DebugConfig>;
|
|
168
209
|
}
|
|
169
210
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/options/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/options/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAGzE;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE3D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAClC,SAAS,EAAE;QACT,gBAAgB,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAC3C,CAAA;IACD,QAAQ,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;AAElD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAE3B;;;OAGG;IACH,eAAe,CAAC,EAAE,SAAS,EAAE,CAAA;IAE7B;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,EAAE,CAAA;IAE3B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IAExB;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAA;IAE1C;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAE/E;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAEvC;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,KAAK,KAAK,EAAE,CAAA;IAEnD;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAE1C;;OAEG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAE/B;;OAEG;IACH,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,eAAe,EAAE,SAAS,EAAE,CAAA;IAC5B,aAAa,EAAE,SAAS,EAAE,CAAA;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,gBAAgB,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAA;IACzC,UAAU,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACnE,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE;QACZ,GAAG,EAAE,KAAK,CAAA;QACV,KAAK,EAAE,KAAK,CAAA;QACZ,MAAM,EAAE,KAAK,CAAA;QACb,IAAI,EAAE,KAAK,CAAA;KACZ,CAAA;IACD,UAAU,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAC,CAAA;IACF,SAAS,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,KAAK,KAAK,EAAE,CAAA;IACnD,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,YAAY,EAAE,kBAAkB,CAAA;IAChC,WAAW,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAA;IACxC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;CAC7B"}
|