bpmn-auto-layout 0.2.0 → 0.3.0
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 +8 -4
- package/dist/index.esm.js +578 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +580 -0
- package/dist/index.js.map +1 -0
- package/package.json +20 -8
- package/index.js +0 -1
- package/lib/AutoLayout.js +0 -514
- package/lib/DiFactory.js +0 -152
- package/lib/DiUtil.js +0 -263
- package/lib/Tree.js +0 -335
package/README.md
CHANGED
|
@@ -15,16 +15,20 @@ This library works in [Node.js](https://nodejs.org/) and in the browser.
|
|
|
15
15
|
To layout diagrams these must have __exactly one single start event__.
|
|
16
16
|
|
|
17
17
|
```javascript
|
|
18
|
-
import
|
|
18
|
+
import { layoutProcess } from 'bpmn-auto-layout';
|
|
19
19
|
|
|
20
20
|
const diagramXML = '<bpmn:defintions ...></bpmn:defintions>';
|
|
21
21
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const layoutedDiagramXML = await autoLayout.layoutProcess(diagramXML);
|
|
22
|
+
const layoutedDiagramXML = await layoutProcess(diagramXML);
|
|
25
23
|
|
|
26
24
|
console.log(layoutedDiagramXML);
|
|
27
25
|
```
|
|
26
|
+
## Unsupported Concepts and elements
|
|
27
|
+
|
|
28
|
+
The Tool can currently not properly layout diagrams containing any of the following:
|
|
29
|
+
- Pools
|
|
30
|
+
- Data/Message Flows and Objects, Data Stores
|
|
31
|
+
- event sub-processes
|
|
28
32
|
|
|
29
33
|
|
|
30
34
|
## Resources
|
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
import BPMNModdle from 'bpmn-moddle';
|
|
2
|
+
import { assign, map, pick } from 'min-dash';
|
|
3
|
+
|
|
4
|
+
function isConnection(element) {
|
|
5
|
+
return !!element.sourceRef;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function isBoundaryEvent(element) {
|
|
9
|
+
return !!element.attachedToRef;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
class Grid {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.grid = [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
add(element) {
|
|
18
|
+
this._addStart(element);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
_addStart(element) {
|
|
22
|
+
this.grid.push([ element ]);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
addAfter(element, newElement) {
|
|
26
|
+
if (!element) {
|
|
27
|
+
this._addStart(newElement);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const [ row, col ] = this.find(element);
|
|
31
|
+
this.grid[row].splice(col + 1, 0, newElement);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
addBelow(element, newElement) {
|
|
35
|
+
if (!element) {
|
|
36
|
+
this._addStart(newElement);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const [ row, col ] = this.find(element);
|
|
40
|
+
|
|
41
|
+
// We are at the bottom of the current grid - add empty row below
|
|
42
|
+
if (!this.grid[row + 1]) {
|
|
43
|
+
this.grid[row + 1] = [];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// The element below is already occupied - insert new row
|
|
47
|
+
if (this.grid[row + 1][col]) {
|
|
48
|
+
this.grid.splice(row + 1, 0, []);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (this.grid[row + 1][col]) {
|
|
52
|
+
throw new Error('Grid is occupied and we could not find a place - this should not happen');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.grid[row + 1][col] = newElement;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
find(element) {
|
|
59
|
+
let row, col;
|
|
60
|
+
row = this.grid.findIndex((row) => {
|
|
61
|
+
col = row.findIndex((el) => {
|
|
62
|
+
return el === element;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return col !== -1;
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return [ row, col ];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get(row, col) {
|
|
72
|
+
return (this.grid[row] || [])[col];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getElementsInRange({ row: startRow, col: startCol }, { row: endRow, col: endCol }) {
|
|
76
|
+
const elements = [];
|
|
77
|
+
|
|
78
|
+
if (startRow > endRow) {
|
|
79
|
+
[ startRow, endRow ] = [ endRow, startRow ];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (startCol > endCol) {
|
|
83
|
+
[ startCol, endCol ] = [ endCol, startCol ];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
for (let row = startRow; row <= endRow; row++) {
|
|
87
|
+
for (let col = startCol; col <= endCol; col++) {
|
|
88
|
+
const element = this.get(row, col);
|
|
89
|
+
|
|
90
|
+
if (element) {
|
|
91
|
+
elements.push(element);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return elements;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
elementsByPosition() {
|
|
100
|
+
const elements = [];
|
|
101
|
+
|
|
102
|
+
this.grid.forEach((row, rowIndex) => {
|
|
103
|
+
row.forEach((element, colIndex) => {
|
|
104
|
+
if (!element) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
elements.push({
|
|
108
|
+
element,
|
|
109
|
+
row: rowIndex,
|
|
110
|
+
col: colIndex
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return elements;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
class DiFactory {
|
|
120
|
+
constructor(moddle) {
|
|
121
|
+
this.moddle = moddle;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
create(type, attrs) {
|
|
125
|
+
return this.moddle.create(type, attrs || {});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
createDiBounds(bounds) {
|
|
129
|
+
return this.create('dc:Bounds', bounds);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
createDiLabel() {
|
|
133
|
+
return this.create('bpmndi:BPMNLabel', {
|
|
134
|
+
bounds: this.createDiBounds()
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
createDiShape(semantic, bounds, attrs) {
|
|
139
|
+
return this.create('bpmndi:BPMNShape', assign({
|
|
140
|
+
bpmnElement: semantic,
|
|
141
|
+
bounds: this.createDiBounds(bounds)
|
|
142
|
+
}, attrs));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
createDiWaypoints(waypoints) {
|
|
146
|
+
var self = this;
|
|
147
|
+
|
|
148
|
+
return map(waypoints, function(pos) {
|
|
149
|
+
return self.createDiWaypoint(pos);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
createDiWaypoint(point) {
|
|
154
|
+
return this.create('dc:Point', pick(point, [ 'x', 'y' ]));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
createDiEdge(semantic, waypoints, attrs) {
|
|
158
|
+
return this.create('bpmndi:BPMNEdge', assign({
|
|
159
|
+
bpmnElement: semantic,
|
|
160
|
+
waypoint: this.createDiWaypoints(waypoints)
|
|
161
|
+
}, attrs));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
createDiPlane(attrs) {
|
|
165
|
+
return this.create('bpmndi:BPMNPlane', attrs);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
createDiDiagram(attrs) {
|
|
169
|
+
return this.create('bpmndi:BPMNDiagram', attrs);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function getDefaultSize(element) {
|
|
174
|
+
if (is(element, 'bpmn:SubProcess')) {
|
|
175
|
+
return { width: 100, height: 80 };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (is(element, 'bpmn:Task')) {
|
|
179
|
+
return { width: 100, height: 80 };
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (is(element, 'bpmn:Gateway')) {
|
|
183
|
+
return { width: 50, height: 50 };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (is(element, 'bpmn:Event')) {
|
|
187
|
+
return { width: 36, height: 36 };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (is(element, 'bpmn:Participant')) {
|
|
191
|
+
return { width: 400, height: 100 };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (is(element, 'bpmn:Lane')) {
|
|
195
|
+
return { width: 400, height: 100 };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (is(element, 'bpmn:DataObjectReference')) {
|
|
199
|
+
return { width: 36, height: 50 };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (is(element, 'bpmn:DataStoreReference')) {
|
|
203
|
+
return { width: 50, height: 50 };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (is(element, 'bpmn:TextAnnotation')) {
|
|
207
|
+
return { width: 100, height: 30 };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return { width: 100, height: 80 };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function is(element, type) {
|
|
214
|
+
return element.$instanceOf(type);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const DEFAULT_CELL_WIDTH = 150;
|
|
218
|
+
const DEFAULT_CELL_HEIGHT = 110;
|
|
219
|
+
|
|
220
|
+
function getMid(bounds) {
|
|
221
|
+
return {
|
|
222
|
+
x: bounds.x + bounds.width / 2,
|
|
223
|
+
y: bounds.y + bounds.height / 2
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function getDockingPoint(point, rectangle, dockingDirection = 'r', targetOrientation = 'top-left') {
|
|
228
|
+
|
|
229
|
+
// ensure we end up with a specific docking direction
|
|
230
|
+
// based on the targetOrientation, if <h|v> is being passed
|
|
231
|
+
|
|
232
|
+
if (dockingDirection === 'h') {
|
|
233
|
+
dockingDirection = /left/.test(targetOrientation) ? 'l' : 'r';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (dockingDirection === 'v') {
|
|
237
|
+
dockingDirection = /top/.test(targetOrientation) ? 't' : 'b';
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (dockingDirection === 't') {
|
|
241
|
+
return { original: point, x: point.x, y: rectangle.y };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (dockingDirection === 'r') {
|
|
245
|
+
return { original: point, x: rectangle.x + rectangle.width, y: point.y };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (dockingDirection === 'b') {
|
|
249
|
+
return { original: point, x: point.x, y: rectangle.y + rectangle.height };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (dockingDirection === 'l') {
|
|
253
|
+
return { original: point, x: rectangle.x, y: point.y };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
throw new Error('unexpected dockingDirection: <' + dockingDirection + '>');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Modified Manhattan layout: Uses space between grid coloumns to route connections
|
|
261
|
+
* if direct connection is not possible.
|
|
262
|
+
* @param {*} source
|
|
263
|
+
* @param {*} target
|
|
264
|
+
* @returns waypoints
|
|
265
|
+
*/
|
|
266
|
+
function connectElements(source, target, layoutGrid) {
|
|
267
|
+
const sourceDi = source.di;
|
|
268
|
+
const targetDi = target.di;
|
|
269
|
+
|
|
270
|
+
const sourceBounds = sourceDi.get('bounds');
|
|
271
|
+
const targetBounds = targetDi.get('bounds');
|
|
272
|
+
|
|
273
|
+
const sourceMid = getMid(sourceBounds);
|
|
274
|
+
const targetMid = getMid(targetBounds);
|
|
275
|
+
|
|
276
|
+
const dX = target.gridPosition.col - source.gridPosition.col;
|
|
277
|
+
const dY = target.gridPosition.row - source.gridPosition.row;
|
|
278
|
+
|
|
279
|
+
const dockingSource = `${(dY > 0 ? 'bottom' : 'top')}-${dX > 0 ? 'right' : 'left'}`;
|
|
280
|
+
const dockingTarget = `${(dY > 0 ? 'top' : 'bottom')}-${dX > 0 ? 'left' : 'right'}`;
|
|
281
|
+
|
|
282
|
+
// Source === Target ==> Build loop
|
|
283
|
+
if (dX === 0 && dY === 0) {
|
|
284
|
+
return [
|
|
285
|
+
getDockingPoint(sourceMid, sourceBounds, 'r', dockingSource),
|
|
286
|
+
{ x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: sourceMid.y },
|
|
287
|
+
{ x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: sourceMid.y - DEFAULT_CELL_HEIGHT / 2 },
|
|
288
|
+
{ x: targetMid.x, y: sourceMid.y - DEFAULT_CELL_HEIGHT / 2 },
|
|
289
|
+
getDockingPoint(targetMid, targetBounds, 't', dockingTarget)
|
|
290
|
+
];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// connect horizontally
|
|
294
|
+
if (dY === 0) {
|
|
295
|
+
if (layoutGrid.getElementsInRange(source.gridPosition, target.gridPosition).length > 2) {
|
|
296
|
+
|
|
297
|
+
// Route on top
|
|
298
|
+
return [
|
|
299
|
+
getDockingPoint(sourceMid, sourceBounds, 't'),
|
|
300
|
+
{ x: sourceMid.x, y: sourceMid.y - DEFAULT_CELL_HEIGHT / 2 },
|
|
301
|
+
{ x: targetMid.x, y: sourceMid.y - DEFAULT_CELL_HEIGHT / 2 },
|
|
302
|
+
getDockingPoint(targetMid, targetBounds, 't')
|
|
303
|
+
];
|
|
304
|
+
} else {
|
|
305
|
+
|
|
306
|
+
// if space is clear, connect directly
|
|
307
|
+
return [
|
|
308
|
+
getDockingPoint(sourceMid, sourceBounds, 'h', dockingSource),
|
|
309
|
+
getDockingPoint(targetMid, targetBounds, 'h', dockingTarget)
|
|
310
|
+
];
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// connect vertically
|
|
315
|
+
if (dX === 0) {
|
|
316
|
+
if (layoutGrid.getElementsInRange(source.gridPosition, target.gridPosition).length > 2) {
|
|
317
|
+
|
|
318
|
+
// Route parallel
|
|
319
|
+
const yOffset = -Math.sign(dY) * DEFAULT_CELL_HEIGHT / 2;
|
|
320
|
+
return [
|
|
321
|
+
getDockingPoint(sourceMid, sourceBounds, 'r'),
|
|
322
|
+
{ x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: sourceMid.y }, // out right
|
|
323
|
+
{ x: targetMid.x + DEFAULT_CELL_WIDTH / 2, y: targetMid.y + yOffset },
|
|
324
|
+
{ x: targetMid.x, y: targetMid.y + yOffset },
|
|
325
|
+
getDockingPoint(targetMid, targetBounds, Math.sign(yOffset) > 0 ? 'b' : 't')
|
|
326
|
+
];
|
|
327
|
+
} else {
|
|
328
|
+
|
|
329
|
+
// if space is clear, connect directly
|
|
330
|
+
return [ getDockingPoint(sourceMid, sourceBounds, 'v', dockingSource),
|
|
331
|
+
getDockingPoint(targetMid, targetBounds, 'v', dockingTarget)
|
|
332
|
+
];
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const yOffset = -Math.sign(dY) * DEFAULT_CELL_HEIGHT / 2;
|
|
337
|
+
|
|
338
|
+
return [
|
|
339
|
+
getDockingPoint(sourceMid, sourceBounds, 'r', dockingSource),
|
|
340
|
+
{ x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: sourceMid.y }, // out right
|
|
341
|
+
{ x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: targetMid.y + yOffset }, // to target row
|
|
342
|
+
{ x: targetMid.x - DEFAULT_CELL_WIDTH / 2, y: targetMid.y + yOffset }, // to target column
|
|
343
|
+
{ x: targetMid.x - DEFAULT_CELL_WIDTH / 2, y: targetMid.y }, // to mid
|
|
344
|
+
getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)
|
|
345
|
+
];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// helpers /////
|
|
349
|
+
function getBounds(element, row, col, attachedTo) {
|
|
350
|
+
const { width, height } = getDefaultSize(element);
|
|
351
|
+
|
|
352
|
+
// Center in cell
|
|
353
|
+
if (!attachedTo) {
|
|
354
|
+
return {
|
|
355
|
+
width, height,
|
|
356
|
+
x: (col * DEFAULT_CELL_WIDTH) + (DEFAULT_CELL_WIDTH - width) / 2,
|
|
357
|
+
y: row * DEFAULT_CELL_HEIGHT + (DEFAULT_CELL_HEIGHT - height) / 2
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const hostBounds = getBounds(attachedTo, row, col);
|
|
362
|
+
|
|
363
|
+
return {
|
|
364
|
+
width, height,
|
|
365
|
+
x: Math.round(hostBounds.x + hostBounds.width / 2 - width / 2),
|
|
366
|
+
y: Math.round(hostBounds.y + hostBounds.height - height / 2)
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
class Layouter {
|
|
371
|
+
constructor() {
|
|
372
|
+
this.moddle = new BPMNModdle();
|
|
373
|
+
this.diFactory = new DiFactory(this.moddle);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
async layoutProcess(xml) {
|
|
377
|
+
const { rootElement } = await this.moddle.fromXML(xml);
|
|
378
|
+
|
|
379
|
+
this.diagram = rootElement;
|
|
380
|
+
|
|
381
|
+
const root = this.getProcess();
|
|
382
|
+
|
|
383
|
+
this.cleanDi();
|
|
384
|
+
this.handlePlane(root);
|
|
385
|
+
|
|
386
|
+
return (await this.moddle.toXML(this.diagram, { format: true })).xml;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
handlePlane(planeElement) {
|
|
390
|
+
const layout = this.createGridLayout(planeElement);
|
|
391
|
+
this.generateDi(planeElement, layout);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
cleanDi() {
|
|
395
|
+
this.diagram.diagrams = [];
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
createGridLayout(root) {
|
|
399
|
+
const grid = new Grid();
|
|
400
|
+
|
|
401
|
+
// const process = this.getProcess();
|
|
402
|
+
const flowElements = root.flowElements;
|
|
403
|
+
|
|
404
|
+
const startingElements = flowElements.filter(el => {
|
|
405
|
+
return !isConnection(el) && !isBoundaryEvent(el) && (!el.incoming || el.length === 0);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
const boundaryEvents = flowElements.filter(el => isBoundaryEvent(el));
|
|
409
|
+
boundaryEvents.forEach(boundaryEvent => {
|
|
410
|
+
const attachedTask = boundaryEvent.attachedToRef;
|
|
411
|
+
const attachers = attachedTask.attachers || [];
|
|
412
|
+
attachers.push(boundaryEvent);
|
|
413
|
+
attachedTask.attachers = attachers;
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
// Depth-first-search
|
|
417
|
+
const stack = [ ...startingElements ];
|
|
418
|
+
const visited = new Set();
|
|
419
|
+
|
|
420
|
+
startingElements.forEach(el => {
|
|
421
|
+
grid.add(el);
|
|
422
|
+
visited.add(el);
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
while (stack.length > 0) {
|
|
426
|
+
const currentElement = stack.pop();
|
|
427
|
+
|
|
428
|
+
if (is(currentElement, 'bpmn:SubProcess')) {
|
|
429
|
+
this.handlePlane(currentElement);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Handle outgoing paths
|
|
433
|
+
const outgoing = (currentElement.outgoing || [])
|
|
434
|
+
.map(out => out.targetRef)
|
|
435
|
+
.filter(el => el);
|
|
436
|
+
|
|
437
|
+
let previousElement = null;
|
|
438
|
+
outgoing.forEach((nextElement, index, arr) => {
|
|
439
|
+
if (visited.has(nextElement)) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (!previousElement) {
|
|
444
|
+
grid.addAfter(currentElement, nextElement);
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
grid.addBelow(arr[index - 1], nextElement);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Is self-looping
|
|
451
|
+
if (nextElement !== currentElement) {
|
|
452
|
+
previousElement = nextElement;
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
const attachedOutgoing = (currentElement.attachers || [])
|
|
457
|
+
.map(att => att.outgoing)
|
|
458
|
+
.flat()
|
|
459
|
+
.map(out => out.targetRef);
|
|
460
|
+
|
|
461
|
+
// handle boundary events
|
|
462
|
+
attachedOutgoing.forEach((nextElement, index, arr) => {
|
|
463
|
+
if (visited.has(nextElement)) {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const below = arr[index - 1] || currentElement;
|
|
468
|
+
grid.addBelow(below, nextElement);
|
|
469
|
+
stack.push(nextElement);
|
|
470
|
+
visited.add(nextElement);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
// add to stack in reverse order: first element should be first of the stack
|
|
474
|
+
outgoing.reverse().forEach(el => {
|
|
475
|
+
if (visited.has(el)) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
visited.add(el);
|
|
479
|
+
stack.push(el);
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return grid;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
generateDi(root, layoutGrid) {
|
|
487
|
+
const diFactory = this.diFactory;
|
|
488
|
+
|
|
489
|
+
// Step 0: Create Root element
|
|
490
|
+
const diagram = this.diagram;
|
|
491
|
+
|
|
492
|
+
var planeDi = diFactory.createDiPlane({
|
|
493
|
+
id: 'BPMNPlane_' + root.id,
|
|
494
|
+
bpmnElement: root
|
|
495
|
+
});
|
|
496
|
+
var diagramDi = diFactory.createDiDiagram({
|
|
497
|
+
id: 'BPMNDiagram_' + root.id,
|
|
498
|
+
plane: planeDi
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
// deepest subprocess is added first - insert at the front
|
|
502
|
+
diagram.diagrams.unshift(diagramDi);
|
|
503
|
+
|
|
504
|
+
const planeElement = planeDi.get('planeElement');
|
|
505
|
+
|
|
506
|
+
// Step 1: Create DI for all elements
|
|
507
|
+
layoutGrid.elementsByPosition().forEach(({ element, row, col }) => {
|
|
508
|
+
const bounds = getBounds(element, row, col);
|
|
509
|
+
|
|
510
|
+
const shapeDi = diFactory.createDiShape(element, bounds, {
|
|
511
|
+
id: element.id + '_di'
|
|
512
|
+
});
|
|
513
|
+
element.di = shapeDi;
|
|
514
|
+
element.gridPosition = { row, col };
|
|
515
|
+
|
|
516
|
+
planeElement.push(shapeDi);
|
|
517
|
+
|
|
518
|
+
// handle attachers
|
|
519
|
+
(element.attachers || []).forEach(att => {
|
|
520
|
+
att.gridPosition = { row, col };
|
|
521
|
+
const attacherBounds = getBounds(att, row, col, element);
|
|
522
|
+
|
|
523
|
+
const attacherDi = diFactory.createDiShape(att, attacherBounds, {
|
|
524
|
+
id: att.id + '_di'
|
|
525
|
+
});
|
|
526
|
+
att.di = attacherDi;
|
|
527
|
+
att.gridPosition = { row, col };
|
|
528
|
+
|
|
529
|
+
planeElement.push(attacherDi);
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
// Step 2: Create DI for all connections
|
|
534
|
+
layoutGrid.elementsByPosition().forEach(({ element, row, col }) => {
|
|
535
|
+
const outgoing = element.outgoing || [];
|
|
536
|
+
|
|
537
|
+
outgoing.forEach(out => {
|
|
538
|
+
const target = out.targetRef;
|
|
539
|
+
const waypoints = connectElements(element, target, layoutGrid);
|
|
540
|
+
|
|
541
|
+
const connectionDi = diFactory.createDiEdge(out, waypoints, {
|
|
542
|
+
id: out.id + '_di'
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
planeElement.push(connectionDi);
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
// handle attachers
|
|
549
|
+
(element.attachers || []).forEach(att => {
|
|
550
|
+
const outgoing = att.outgoing || [];
|
|
551
|
+
|
|
552
|
+
outgoing.forEach(out => {
|
|
553
|
+
const target = out.targetRef;
|
|
554
|
+
const waypoints = connectElements(att, target, layoutGrid);
|
|
555
|
+
|
|
556
|
+
const connectionDi = diFactory.createDiEdge(out, waypoints, {
|
|
557
|
+
id: out.id + '_di'
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
planeElement.push(connectionDi);
|
|
561
|
+
});
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
getProcess() {
|
|
569
|
+
return this.diagram.get('rootElements').find(el => el.$type === 'bpmn:Process');
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function layoutProcess(xml) {
|
|
574
|
+
return new Layouter().layoutProcess(xml);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export { layoutProcess };
|
|
578
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../lib/utils/elementUtils.js","../lib/Grid.js","../lib/di/DiFactory.js","../lib/di/DiUtil.js","../lib/utils/layoutUtil.js","../lib/Layouter.js","../lib/index.js"],"sourcesContent":["export function isConnection(element) {\n return !!element.sourceRef;\n}\n\nexport function isBoundaryEvent(element) {\n return !!element.attachedToRef;\n}","export class Grid {\n constructor() {\n this.grid = [];\n }\n\n add(element) {\n this._addStart(element);\n }\n\n _addStart(element) {\n this.grid.push([ element ]);\n }\n\n addAfter(element, newElement) {\n if (!element) {\n this._addStart(newElement);\n }\n\n const [ row, col ] = this.find(element);\n this.grid[row].splice(col + 1, 0, newElement);\n }\n\n addBelow(element, newElement) {\n if (!element) {\n this._addStart(newElement);\n }\n\n const [ row, col ] = this.find(element);\n\n // We are at the bottom of the current grid - add empty row below\n if (!this.grid[row + 1]) {\n this.grid[row + 1] = [];\n }\n\n // The element below is already occupied - insert new row\n if (this.grid[row + 1][col]) {\n this.grid.splice(row + 1, 0, []);\n }\n\n if (this.grid[row + 1][col]) {\n throw new Error('Grid is occupied and we could not find a place - this should not happen');\n }\n\n this.grid[row + 1][col] = newElement;\n }\n\n find(element) {\n let row, col;\n row = this.grid.findIndex((row) => {\n col = row.findIndex((el) => {\n return el === element;\n });\n\n return col !== -1;\n });\n\n return [ row, col ];\n }\n\n get(row, col) {\n return (this.grid[row] || [])[col];\n }\n\n getElementsInRange({ row: startRow, col: startCol }, { row: endRow, col: endCol }) {\n const elements = [];\n\n if (startRow > endRow) {\n [ startRow, endRow ] = [ endRow, startRow ];\n }\n\n if (startCol > endCol) {\n [ startCol, endCol ] = [ endCol, startCol ];\n }\n\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n const element = this.get(row, col);\n\n if (element) {\n elements.push(element);\n }\n }\n }\n\n return elements;\n }\n\n elementsByPosition() {\n const elements = [];\n\n this.grid.forEach((row, rowIndex) => {\n row.forEach((element, colIndex) => {\n if (!element) {\n return;\n }\n elements.push({\n element,\n row: rowIndex,\n col: colIndex\n });\n });\n });\n\n return elements;\n }\n}\n\n","import { assign, map, pick } from 'min-dash';\n\n\nexport class DiFactory {\n constructor(moddle) {\n this.moddle = moddle;\n }\n\n create(type, attrs) {\n return this.moddle.create(type, attrs || {});\n }\n\n createDiBounds(bounds) {\n return this.create('dc:Bounds', bounds);\n }\n\n createDiLabel() {\n return this.create('bpmndi:BPMNLabel', {\n bounds: this.createDiBounds()\n });\n }\n\n createDiShape(semantic, bounds, attrs) {\n return this.create('bpmndi:BPMNShape', assign({\n bpmnElement: semantic,\n bounds: this.createDiBounds(bounds)\n }, attrs));\n }\n\n createDiWaypoints(waypoints) {\n var self = this;\n\n return map(waypoints, function(pos) {\n return self.createDiWaypoint(pos);\n });\n }\n\n createDiWaypoint(point) {\n return this.create('dc:Point', pick(point, [ 'x', 'y' ]));\n }\n\n createDiEdge(semantic, waypoints, attrs) {\n return this.create('bpmndi:BPMNEdge', assign({\n bpmnElement: semantic,\n waypoint: this.createDiWaypoints(waypoints)\n }, attrs));\n }\n\n createDiPlane(attrs) {\n return this.create('bpmndi:BPMNPlane', attrs);\n }\n\n createDiDiagram(attrs) {\n return this.create('bpmndi:BPMNDiagram', attrs);\n }\n}","export function getDefaultSize(element) {\n if (is(element, 'bpmn:SubProcess')) {\n return { width: 100, height: 80 };\n }\n\n if (is(element, 'bpmn:Task')) {\n return { width: 100, height: 80 };\n }\n\n if (is(element, 'bpmn:Gateway')) {\n return { width: 50, height: 50 };\n }\n\n if (is(element, 'bpmn:Event')) {\n return { width: 36, height: 36 };\n }\n\n if (is(element, 'bpmn:Participant')) {\n return { width: 400, height: 100 };\n }\n\n if (is(element, 'bpmn:Lane')) {\n return { width: 400, height: 100 };\n }\n\n if (is(element, 'bpmn:DataObjectReference')) {\n return { width: 36, height: 50 };\n }\n\n if (is(element, 'bpmn:DataStoreReference')) {\n return { width: 50, height: 50 };\n }\n\n if (is(element, 'bpmn:TextAnnotation')) {\n return { width: 100, height: 30 };\n }\n\n return { width: 100, height: 80 };\n}\n\nexport function is(element, type) {\n return element.$instanceOf(type);\n}\n","import { getDefaultSize } from '../di/DiUtil';\n\nexport const DEFAULT_CELL_WIDTH = 150;\nexport const DEFAULT_CELL_HEIGHT = 110;\n\nexport function getMid(bounds) {\n return {\n x: bounds.x + bounds.width / 2,\n y: bounds.y + bounds.height / 2\n };\n}\n\nexport function getDockingPoint(point, rectangle, dockingDirection = 'r', targetOrientation = 'top-left') {\n\n // ensure we end up with a specific docking direction\n // based on the targetOrientation, if <h|v> is being passed\n\n if (dockingDirection === 'h') {\n dockingDirection = /left/.test(targetOrientation) ? 'l' : 'r';\n }\n\n if (dockingDirection === 'v') {\n dockingDirection = /top/.test(targetOrientation) ? 't' : 'b';\n }\n\n if (dockingDirection === 't') {\n return { original: point, x: point.x, y: rectangle.y };\n }\n\n if (dockingDirection === 'r') {\n return { original: point, x: rectangle.x + rectangle.width, y: point.y };\n }\n\n if (dockingDirection === 'b') {\n return { original: point, x: point.x, y: rectangle.y + rectangle.height };\n }\n\n if (dockingDirection === 'l') {\n return { original: point, x: rectangle.x, y: point.y };\n }\n\n throw new Error('unexpected dockingDirection: <' + dockingDirection + '>');\n}\n\n/**\n * Modified Manhattan layout: Uses space between grid coloumns to route connections\n * if direct connection is not possible.\n * @param {*} source\n * @param {*} target\n * @returns waypoints\n */\nexport function connectElements(source, target, layoutGrid) {\n const sourceDi = source.di;\n const targetDi = target.di;\n\n const sourceBounds = sourceDi.get('bounds');\n const targetBounds = targetDi.get('bounds');\n\n const sourceMid = getMid(sourceBounds);\n const targetMid = getMid(targetBounds);\n\n const dX = target.gridPosition.col - source.gridPosition.col;\n const dY = target.gridPosition.row - source.gridPosition.row;\n\n const dockingSource = `${(dY > 0 ? 'bottom' : 'top')}-${dX > 0 ? 'right' : 'left'}`;\n const dockingTarget = `${(dY > 0 ? 'top' : 'bottom')}-${dX > 0 ? 'left' : 'right'}`;\n\n // Source === Target ==> Build loop\n if (dX === 0 && dY === 0) {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'r', dockingSource),\n { x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: sourceMid.y },\n { x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: sourceMid.y - DEFAULT_CELL_HEIGHT / 2 },\n { x: targetMid.x, y: sourceMid.y - DEFAULT_CELL_HEIGHT / 2 },\n getDockingPoint(targetMid, targetBounds, 't', dockingTarget)\n ];\n }\n\n // connect horizontally\n if (dY === 0) {\n if (layoutGrid.getElementsInRange(source.gridPosition, target.gridPosition).length > 2) {\n\n // Route on top\n return [\n getDockingPoint(sourceMid, sourceBounds, 't'),\n { x: sourceMid.x, y: sourceMid.y - DEFAULT_CELL_HEIGHT / 2 },\n { x: targetMid.x, y: sourceMid.y - DEFAULT_CELL_HEIGHT / 2 },\n getDockingPoint(targetMid, targetBounds, 't')\n ];\n } else {\n\n // if space is clear, connect directly\n return [\n getDockingPoint(sourceMid, sourceBounds, 'h', dockingSource),\n getDockingPoint(targetMid, targetBounds, 'h', dockingTarget)\n ];\n }\n }\n\n // connect vertically\n if (dX === 0) {\n if (layoutGrid.getElementsInRange(source.gridPosition, target.gridPosition).length > 2) {\n\n // Route parallel\n const yOffset = -Math.sign(dY) * DEFAULT_CELL_HEIGHT / 2;\n return [\n getDockingPoint(sourceMid, sourceBounds, 'r'),\n { x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: sourceMid.y }, // out right\n { x: targetMid.x + DEFAULT_CELL_WIDTH / 2, y: targetMid.y + yOffset },\n { x: targetMid.x, y: targetMid.y + yOffset },\n getDockingPoint(targetMid, targetBounds, Math.sign(yOffset) > 0 ? 'b' : 't')\n ];\n } else {\n\n // if space is clear, connect directly\n return [ getDockingPoint(sourceMid, sourceBounds, 'v', dockingSource),\n getDockingPoint(targetMid, targetBounds, 'v', dockingTarget)\n ];\n }\n }\n\n const yOffset = -Math.sign(dY) * DEFAULT_CELL_HEIGHT / 2;\n\n return [\n getDockingPoint(sourceMid, sourceBounds, 'r', dockingSource),\n { x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: sourceMid.y }, // out right\n { x: sourceMid.x + DEFAULT_CELL_WIDTH / 2, y: targetMid.y + yOffset }, // to target row\n { x: targetMid.x - DEFAULT_CELL_WIDTH / 2, y: targetMid.y + yOffset }, // to target column\n { x: targetMid.x - DEFAULT_CELL_WIDTH / 2, y: targetMid.y }, // to mid\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n}\n\n// helpers /////\nexport function getBounds(element, row, col, attachedTo) {\n const { width, height } = getDefaultSize(element);\n\n // Center in cell\n if (!attachedTo) {\n return {\n width, height,\n x: (col * DEFAULT_CELL_WIDTH) + (DEFAULT_CELL_WIDTH - width) / 2,\n y: row * DEFAULT_CELL_HEIGHT + (DEFAULT_CELL_HEIGHT - height) / 2\n };\n }\n\n const hostBounds = getBounds(attachedTo, row, col);\n\n return {\n width, height,\n x: Math.round(hostBounds.x + hostBounds.width / 2 - width / 2),\n y: Math.round(hostBounds.y + hostBounds.height - height / 2)\n };\n}","import BPMNModdle from 'bpmn-moddle';\nimport { isBoundaryEvent, isConnection } from './utils/elementUtils';\nimport { Grid } from './Grid';\nimport { DiFactory } from './di/DiFactory';\nimport { connectElements, getBounds } from './utils/layoutUtil';\nimport { is } from './di/DiUtil';\n\nexport class Layouter {\n constructor() {\n this.moddle = new BPMNModdle();\n this.diFactory = new DiFactory(this.moddle);\n }\n\n async layoutProcess(xml) {\n const { rootElement } = await this.moddle.fromXML(xml);\n\n this.diagram = rootElement;\n\n const root = this.getProcess();\n\n this.cleanDi();\n this.handlePlane(root);\n\n return (await this.moddle.toXML(this.diagram, { format: true })).xml;\n }\n\n handlePlane(planeElement) {\n const layout = this.createGridLayout(planeElement);\n this.generateDi(planeElement, layout);\n }\n\n cleanDi() {\n this.diagram.diagrams = [];\n }\n\n createGridLayout(root) {\n const grid = new Grid();\n\n // const process = this.getProcess();\n const flowElements = root.flowElements;\n\n const startingElements = flowElements.filter(el => {\n return !isConnection(el) && !isBoundaryEvent(el) && (!el.incoming || el.length === 0);\n });\n\n const boundaryEvents = flowElements.filter(el => isBoundaryEvent(el));\n boundaryEvents.forEach(boundaryEvent => {\n const attachedTask = boundaryEvent.attachedToRef;\n const attachers = attachedTask.attachers || [];\n attachers.push(boundaryEvent);\n attachedTask.attachers = attachers;\n });\n\n // Depth-first-search\n const stack = [ ...startingElements ];\n const visited = new Set();\n\n startingElements.forEach(el => {\n grid.add(el);\n visited.add(el);\n });\n\n while (stack.length > 0) {\n const currentElement = stack.pop();\n\n if (is(currentElement, 'bpmn:SubProcess')) {\n this.handlePlane(currentElement);\n }\n\n // Handle outgoing paths\n const outgoing = (currentElement.outgoing || [])\n .map(out => out.targetRef)\n .filter(el => el);\n\n let previousElement = null;\n outgoing.forEach((nextElement, index, arr) => {\n if (visited.has(nextElement)) {\n return;\n }\n\n if (!previousElement) {\n grid.addAfter(currentElement, nextElement);\n }\n else {\n grid.addBelow(arr[index - 1], nextElement);\n }\n\n // Is self-looping\n if (nextElement !== currentElement) {\n previousElement = nextElement;\n }\n });\n\n const attachedOutgoing = (currentElement.attachers || [])\n .map(att => att.outgoing)\n .flat()\n .map(out => out.targetRef);\n\n // handle boundary events\n attachedOutgoing.forEach((nextElement, index, arr) => {\n if (visited.has(nextElement)) {\n return;\n }\n\n const below = arr[index - 1] || currentElement;\n grid.addBelow(below, nextElement);\n stack.push(nextElement);\n visited.add(nextElement);\n });\n\n // add to stack in reverse order: first element should be first of the stack\n outgoing.reverse().forEach(el => {\n if (visited.has(el)) {\n return;\n }\n visited.add(el);\n stack.push(el);\n });\n }\n\n return grid;\n }\n\n generateDi(root, layoutGrid) {\n const diFactory = this.diFactory;\n\n // Step 0: Create Root element\n const diagram = this.diagram;\n\n var planeDi = diFactory.createDiPlane({\n id: 'BPMNPlane_' + root.id,\n bpmnElement: root\n });\n var diagramDi = diFactory.createDiDiagram({\n id: 'BPMNDiagram_' + root.id,\n plane: planeDi\n });\n\n // deepest subprocess is added first - insert at the front\n diagram.diagrams.unshift(diagramDi);\n\n const planeElement = planeDi.get('planeElement');\n\n // Step 1: Create DI for all elements\n layoutGrid.elementsByPosition().forEach(({ element, row, col }) => {\n const bounds = getBounds(element, row, col);\n\n const shapeDi = diFactory.createDiShape(element, bounds, {\n id: element.id + '_di'\n });\n element.di = shapeDi;\n element.gridPosition = { row, col };\n\n planeElement.push(shapeDi);\n\n // handle attachers\n (element.attachers || []).forEach(att => {\n att.gridPosition = { row, col };\n const attacherBounds = getBounds(att, row, col, element);\n\n const attacherDi = diFactory.createDiShape(att, attacherBounds, {\n id: att.id + '_di'\n });\n att.di = attacherDi;\n att.gridPosition = { row, col };\n\n planeElement.push(attacherDi);\n });\n });\n\n // Step 2: Create DI for all connections\n layoutGrid.elementsByPosition().forEach(({ element, row, col }) => {\n const outgoing = element.outgoing || [];\n\n outgoing.forEach(out => {\n const target = out.targetRef;\n const waypoints = connectElements(element, target, layoutGrid);\n\n const connectionDi = diFactory.createDiEdge(out, waypoints, {\n id: out.id + '_di'\n });\n\n planeElement.push(connectionDi);\n });\n\n // handle attachers\n (element.attachers || []).forEach(att => {\n const outgoing = att.outgoing || [];\n\n outgoing.forEach(out => {\n const target = out.targetRef;\n const waypoints = connectElements(att, target, layoutGrid);\n\n const connectionDi = diFactory.createDiEdge(out, waypoints, {\n id: out.id + '_di'\n });\n\n planeElement.push(connectionDi);\n });\n });\n\n });\n }\n\n\n getProcess() {\n return this.diagram.get('rootElements').find(el => el.$type === 'bpmn:Process');\n }\n}\n","import { Layouter } from './Layouter';\n\nexport function layoutProcess(xml) {\n return new Layouter().layoutProcess(xml);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,YAAY,CAAC,OAAO,EAAE;AACtC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;AAC7B,CAAC;AACD;AACO,SAAS,eAAe,CAAC,OAAO,EAAE;AACzC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;AACjC;;ACNO,MAAM,IAAI,CAAC;AAClB,EAAE,WAAW,GAAG;AAChB,IAAI,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;AACnB,GAAG;AACH;AACA,EAAE,GAAG,CAAC,OAAO,EAAE;AACf,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAC5B,GAAG;AACH;AACA,EAAE,SAAS,CAAC,OAAO,EAAE;AACrB,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;AAChC,GAAG;AACH;AACA,EAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE;AAChC,IAAI,IAAI,CAAC,OAAO,EAAE;AAClB,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;AACjC,KAAK;AACL;AACA,IAAI,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5C,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;AAClD,GAAG;AACH;AACA,EAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE;AAChC,IAAI,IAAI,CAAC,OAAO,EAAE;AAClB,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;AACjC,KAAK;AACL;AACA,IAAI,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5C;AACA;AACA,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE;AAC7B,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;AAC9B,KAAK;AACL;AACA;AACA,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;AACjC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AACvC,KAAK;AACL;AACA,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;AACjC,MAAM,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;AACjG,KAAK;AACL;AACA,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;AACzC,GAAG;AACH;AACA,EAAE,IAAI,CAAC,OAAO,EAAE;AAChB,IAAI,IAAI,GAAG,EAAE,GAAG,CAAC;AACjB,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,KAAK;AACvC,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK;AAClC,QAAQ,OAAO,EAAE,KAAK,OAAO,CAAC;AAC9B,OAAO,CAAC,CAAC;AACT;AACA,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;AACxB,KAAK,CAAC,CAAC;AACP;AACA,IAAI,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACxB,GAAG;AACH;AACA,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE;AAChB,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;AACvC,GAAG;AACH;AACA,EAAE,kBAAkB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;AACrF,IAAI,MAAM,QAAQ,GAAG,EAAE,CAAC;AACxB;AACA,IAAI,IAAI,QAAQ,GAAG,MAAM,EAAE;AAC3B,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAClD,KAAK;AACL;AACA,IAAI,IAAI,QAAQ,GAAG,MAAM,EAAE;AAC3B,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAClD,KAAK;AACL;AACA,IAAI,KAAK,IAAI,GAAG,GAAG,QAAQ,EAAE,GAAG,IAAI,MAAM,EAAE,GAAG,EAAE,EAAE;AACnD,MAAM,KAAK,IAAI,GAAG,GAAG,QAAQ,EAAE,GAAG,IAAI,MAAM,EAAE,GAAG,EAAE,EAAE;AACrD,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC3C;AACA,QAAQ,IAAI,OAAO,EAAE;AACrB,UAAU,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACjC,SAAS;AACT,OAAO;AACP,KAAK;AACL;AACA,IAAI,OAAO,QAAQ,CAAC;AACpB,GAAG;AACH;AACA,EAAE,kBAAkB,GAAG;AACvB,IAAI,MAAM,QAAQ,GAAG,EAAE,CAAC;AACxB;AACA,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAK;AACzC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,QAAQ,KAAK;AACzC,QAAQ,IAAI,CAAC,OAAO,EAAE;AACtB,UAAU,OAAO;AACjB,SAAS;AACT,QAAQ,QAAQ,CAAC,IAAI,CAAC;AACtB,UAAU,OAAO;AACjB,UAAU,GAAG,EAAE,QAAQ;AACvB,UAAU,GAAG,EAAE,QAAQ;AACvB,SAAS,CAAC,CAAC;AACX,OAAO,CAAC,CAAC;AACT,KAAK,CAAC,CAAC;AACP;AACA,IAAI,OAAO,QAAQ,CAAC;AACpB,GAAG;AACH;;ACtGO,MAAM,SAAS,CAAC;AACvB,EAAE,WAAW,CAAC,MAAM,EAAE;AACtB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;AACzB,GAAG;AACH;AACA,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE;AACtB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;AACjD,GAAG;AACH;AACA,EAAE,cAAc,CAAC,MAAM,EAAE;AACzB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAC5C,GAAG;AACH;AACA,EAAE,aAAa,GAAG;AAClB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE;AAC3C,MAAM,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE;AACnC,KAAK,CAAC,CAAC;AACP,GAAG;AACH;AACA,EAAE,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;AACzC,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC;AAClD,MAAM,WAAW,EAAE,QAAQ;AAC3B,MAAM,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;AACzC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AACf,GAAG;AACH;AACA,EAAE,iBAAiB,CAAC,SAAS,EAAE;AAC/B,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;AACpB;AACA,IAAI,OAAO,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,EAAE;AACxC,MAAM,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;AACxC,KAAK,CAAC,CAAC;AACP,GAAG;AACH;AACA,EAAE,gBAAgB,CAAC,KAAK,EAAE;AAC1B,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAC9D,GAAG;AACH;AACA,EAAE,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE;AAC3C,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC;AACjD,MAAM,WAAW,EAAE,QAAQ;AAC3B,MAAM,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC;AACjD,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AACf,GAAG;AACH;AACA,EAAE,aAAa,CAAC,KAAK,EAAE;AACvB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;AAClD,GAAG;AACH;AACA,EAAE,eAAe,CAAC,KAAK,EAAE;AACzB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;AACpD,GAAG;AACH;;ACvDO,SAAS,cAAc,CAAC,OAAO,EAAE;AACxC,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,iBAAiB,CAAC,EAAE;AACtC,IAAI,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACtC,GAAG;AACH;AACA,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE;AAChC,IAAI,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACtC,GAAG;AACH;AACA,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE;AACnC,IAAI,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACrC,GAAG;AACH;AACA,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE;AACjC,IAAI,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACrC,GAAG;AACH;AACA,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,kBAAkB,CAAC,EAAE;AACvC,IAAI,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACvC,GAAG;AACH;AACA,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE;AAChC,IAAI,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACvC,GAAG;AACH;AACA,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,0BAA0B,CAAC,EAAE;AAC/C,IAAI,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACrC,GAAG;AACH;AACA,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,yBAAyB,CAAC,EAAE;AAC9C,IAAI,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACrC,GAAG;AACH;AACA,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,qBAAqB,CAAC,EAAE;AAC1C,IAAI,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACtC,GAAG;AACH;AACA,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACpC,CAAC;AACD;AACO,SAAS,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE;AAClC,EAAE,OAAO,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AACnC;;ACxCO,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC;AACO,SAAS,MAAM,CAAC,MAAM,EAAE;AAC/B,EAAE,OAAO;AACT,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC;AAClC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC;AACnC,GAAG,CAAC;AACJ,CAAC;AACD;AACO,SAAS,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,gBAAgB,GAAG,GAAG,EAAE,iBAAiB,GAAG,UAAU,EAAE;AAC1G;AACA;AACA;AACA;AACA,EAAE,IAAI,gBAAgB,KAAK,GAAG,EAAE;AAChC,IAAI,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;AAClE,GAAG;AACH;AACA,EAAE,IAAI,gBAAgB,KAAK,GAAG,EAAE;AAChC,IAAI,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;AACjE,GAAG;AACH;AACA,EAAE,IAAI,gBAAgB,KAAK,GAAG,EAAE;AAChC,IAAI,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;AAC3D,GAAG;AACH;AACA,EAAE,IAAI,gBAAgB,KAAK,GAAG,EAAE;AAChC,IAAI,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;AAC7E,GAAG;AACH;AACA,EAAE,IAAI,gBAAgB,KAAK,GAAG,EAAE;AAChC,IAAI,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;AAC9E,GAAG;AACH;AACA,EAAE,IAAI,gBAAgB,KAAK,GAAG,EAAE;AAChC,IAAI,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;AAC3D,GAAG;AACH;AACA,EAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,gBAAgB,GAAG,GAAG,CAAC,CAAC;AAC7E,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE;AAC5D,EAAE,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;AAC7B,EAAE,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;AAC7B;AACA,EAAE,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC9C,EAAE,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC9C;AACA,EAAE,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AACzC,EAAE,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AACzC;AACA,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC;AAC/D,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC;AAC/D;AACA,EAAE,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC;AACtF,EAAE,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;AACtF;AACA;AACA,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AAC5B,IAAI,OAAO;AACX,MAAM,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,CAAC;AAClE,MAAM,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,kBAAkB,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE;AACjE,MAAM,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,kBAAkB,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,EAAE;AAC3F,MAAM,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,EAAE;AAClE,MAAM,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,CAAC;AAClE,KAAK,CAAC;AACN,GAAG;AACH;AACA;AACA,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;AAChB,IAAI,IAAI,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;AAC5F;AACA;AACA,MAAM,OAAO;AACb,QAAQ,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,CAAC;AACrD,QAAQ,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,EAAE;AACpE,QAAQ,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,EAAE;AACpE,QAAQ,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,CAAC;AACrD,OAAO,CAAC;AACR,KAAK,MAAM;AACX;AACA;AACA,MAAM,OAAO;AACb,QAAQ,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,CAAC;AACpE,QAAQ,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,CAAC;AACpE,OAAO,CAAC;AACR,KAAK;AACL,GAAG;AACH;AACA;AACA,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;AAChB,IAAI,IAAI,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;AAC5F;AACA;AACA,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC;AAC/D,MAAM,OAAO;AACb,QAAQ,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,CAAC;AACrD,QAAQ,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,kBAAkB,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE;AACnE,QAAQ,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,kBAAkB,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE;AAC7E,QAAQ,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE;AACpD,QAAQ,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;AACpF,OAAO,CAAC;AACR,KAAK,MAAM;AACX;AACA;AACA,MAAM,OAAO,EAAE,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,CAAC;AAC3E,QAAQ,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,CAAC;AACpE,OAAO,CAAC;AACR,KAAK;AACL,GAAG;AACH;AACA,EAAE,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC;AAC3D;AACA,EAAE,OAAO;AACT,IAAI,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,CAAC;AAChE,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,kBAAkB,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE;AAC/D,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,kBAAkB,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE;AACzE,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,kBAAkB,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE;AACzE,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,kBAAkB,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE;AAC/D,IAAI,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,CAAC;AAChE,GAAG,CAAC;AACJ,CAAC;AACD;AACA;AACO,SAAS,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE;AACzD,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;AACpD;AACA;AACA,EAAE,IAAI,CAAC,UAAU,EAAE;AACnB,IAAI,OAAO;AACX,MAAM,KAAK,EAAE,MAAM;AACnB,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,kBAAkB,IAAI,CAAC,kBAAkB,GAAG,KAAK,IAAI,CAAC;AACtE,MAAM,CAAC,EAAE,GAAG,GAAG,mBAAmB,GAAG,CAAC,mBAAmB,GAAG,MAAM,IAAI,CAAC;AACvE,KAAK,CAAC;AACN,GAAG;AACH;AACA,EAAE,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AACrD;AACA,EAAE,OAAO;AACT,IAAI,KAAK,EAAE,MAAM;AACjB,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AAClE,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC;AAChE,GAAG,CAAC;AACJ;;AClJO,MAAM,QAAQ,CAAC;AACtB,EAAE,WAAW,GAAG;AAChB,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;AACnC,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAChD,GAAG;AACH;AACA,EAAE,MAAM,aAAa,CAAC,GAAG,EAAE;AAC3B,IAAI,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAC3D;AACA,IAAI,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC;AAC/B;AACA,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;AACnC;AACA,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;AACnB,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AAC3B;AACA,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC;AACzE,GAAG;AACH;AACA,EAAE,WAAW,CAAC,YAAY,EAAE;AAC5B,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACvD,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AAC1C,GAAG;AACH;AACA,EAAE,OAAO,GAAG;AACZ,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,EAAE,CAAC;AAC/B,GAAG;AACH;AACA,EAAE,gBAAgB,CAAC,IAAI,EAAE;AACzB,IAAI,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;AAC5B;AACA;AACA,IAAI,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;AAC3C;AACA,IAAI,MAAM,gBAAgB,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,IAAI;AACvD,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;AAC5F,KAAK,CAAC,CAAC;AACP;AACA,IAAI,MAAM,cAAc,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,IAAI,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1E,IAAI,cAAc,CAAC,OAAO,CAAC,aAAa,IAAI;AAC5C,MAAM,MAAM,YAAY,GAAG,aAAa,CAAC,aAAa,CAAC;AACvD,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,IAAI,EAAE,CAAC;AACrD,MAAM,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACpC,MAAM,YAAY,CAAC,SAAS,GAAG,SAAS,CAAC;AACzC,KAAK,CAAC,CAAC;AACP;AACA;AACA,IAAI,MAAM,KAAK,GAAG,EAAE,GAAG,gBAAgB,EAAE,CAAC;AAC1C,IAAI,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;AAC9B;AACA,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,IAAI;AACnC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACnB,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACtB,KAAK,CAAC,CAAC;AACP;AACA,IAAI,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;AAC7B,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;AACzC;AACA,MAAM,IAAI,EAAE,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE;AACjD,QAAQ,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;AACzC,OAAO;AACP;AACA;AACA,MAAM,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,QAAQ,IAAI,EAAE;AACrD,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC;AAClC,SAAS,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1B;AACA,MAAM,IAAI,eAAe,GAAG,IAAI,CAAC;AACjC,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK;AACpD,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;AACtC,UAAU,OAAO;AACjB,SAAS;AACT;AACA,QAAQ,IAAI,CAAC,eAAe,EAAE;AAC9B,UAAU,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AACrD,SAAS;AACT,aAAa;AACb,UAAU,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;AACrD,SAAS;AACT;AACA;AACA,QAAQ,IAAI,WAAW,KAAK,cAAc,EAAE;AAC5C,UAAU,eAAe,GAAG,WAAW,CAAC;AACxC,SAAS;AACT,OAAO,CAAC,CAAC;AACT;AACA,MAAM,MAAM,gBAAgB,GAAG,CAAC,cAAc,CAAC,SAAS,IAAI,EAAE;AAC9D,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC;AACjC,SAAS,IAAI,EAAE;AACf,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;AACnC;AACA;AACA,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK;AAC5D,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;AACtC,UAAU,OAAO;AACjB,SAAS;AACT;AACA,QAAQ,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,cAAc,CAAC;AACvD,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;AAC1C,QAAQ,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAChC,QAAQ,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACjC,OAAO,CAAC,CAAC;AACT;AACA;AACA,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI;AACvC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AAC7B,UAAU,OAAO;AACjB,SAAS;AACT,QAAQ,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACxB,QAAQ,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACvB,OAAO,CAAC,CAAC;AACT,KAAK;AACL;AACA,IAAI,OAAO,IAAI,CAAC;AAChB,GAAG;AACH;AACA,EAAE,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE;AAC/B,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;AACrC;AACA;AACA,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;AACjC;AACA,IAAI,IAAI,OAAO,GAAG,SAAS,CAAC,aAAa,CAAC;AAC1C,MAAM,EAAE,EAAE,YAAY,GAAG,IAAI,CAAC,EAAE;AAChC,MAAM,WAAW,EAAE,IAAI;AACvB,KAAK,CAAC,CAAC;AACP,IAAI,IAAI,SAAS,GAAG,SAAS,CAAC,eAAe,CAAC;AAC9C,MAAM,EAAE,EAAE,cAAc,GAAG,IAAI,CAAC,EAAE;AAClC,MAAM,KAAK,EAAE,OAAO;AACpB,KAAK,CAAC,CAAC;AACP;AACA;AACA,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACxC;AACA,IAAI,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AACrD;AACA;AACA,IAAI,UAAU,CAAC,kBAAkB,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK;AACvE,MAAM,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAClD;AACA,MAAM,MAAM,OAAO,GAAG,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE;AAC/D,QAAQ,EAAE,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK;AAC9B,OAAO,CAAC,CAAC;AACT,MAAM,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC;AAC3B,MAAM,OAAO,CAAC,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC1C;AACA,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACjC;AACA;AACA,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,OAAO,CAAC,GAAG,IAAI;AAC/C,QAAQ,GAAG,CAAC,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACxC,QAAQ,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AACjE;AACA,QAAQ,MAAM,UAAU,GAAG,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE;AACxE,UAAU,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK;AAC5B,SAAS,CAAC,CAAC;AACX,QAAQ,GAAG,CAAC,EAAE,GAAG,UAAU,CAAC;AAC5B,QAAQ,GAAG,CAAC,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACxC;AACA,QAAQ,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACtC,OAAO,CAAC,CAAC;AACT,KAAK,CAAC,CAAC;AACP;AACA;AACA,IAAI,UAAU,CAAC,kBAAkB,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK;AACvE,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;AAC9C;AACA,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI;AAC9B,QAAQ,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC;AACrC,QAAQ,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACvE;AACA,QAAQ,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE;AACpE,UAAU,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK;AAC5B,SAAS,CAAC,CAAC;AACX;AACA,QAAQ,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AACxC,OAAO,CAAC,CAAC;AACT;AACA;AACA,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,OAAO,CAAC,GAAG,IAAI;AAC/C,QAAQ,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;AAC5C;AACA,QAAQ,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI;AAChC,UAAU,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC;AACvC,UAAU,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACrE;AACA,UAAU,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE;AACtE,YAAY,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK;AAC9B,WAAW,CAAC,CAAC;AACb;AACA,UAAU,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAC1C,SAAS,CAAC,CAAC;AACX,OAAO,CAAC,CAAC;AACT;AACA,KAAK,CAAC,CAAC;AACP,GAAG;AACH;AACA;AACA,EAAE,UAAU,GAAG;AACf,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,KAAK,cAAc,CAAC,CAAC;AACpF,GAAG;AACH;;AC9MO,SAAS,aAAa,CAAC,GAAG,EAAE;AACnC,EAAE,OAAO,IAAI,QAAQ,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AAC3C;;;;"}
|