yet-another-bpmn-auto-layout 0.0.9 → 0.0.10

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../lib/di/DiUtil.js","../lib/utils/elementUtils.js","../lib/utils/layoutUtils.js","../lib/di/DiFactory.js","../lib/Grid.js","../lib/GridWithEdges.js","../lib/newHandlers/outgoingHandler.js","../lib/newHandlers/createConnection.js","../lib/newHandlers/createElementDi.js","../lib/Edge.js","../lib/Layouter.js","../lib/index.js"],"sourcesContent":["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 { is } from '../di/DiUtil.js';\n\nexport function isConnection(element) {\n return !!element.sourceRef;\n}\n\nexport function isBoundaryEvent(element) {\n return !!element.attachedToRef;\n}\n\nexport function getOutgoingElements(element) {\n if (!element) throw new Error('Element is not defined in getOutgoingElements');\n const outgoingElements = (element.outgoing || []).map(out => out.targetRef);\n\n // возвращаем уникальные, так как BPMN может быть не валидным\n return [ ...new Set(outgoingElements) ];\n}\n\nexport function getIncomingElements(element) {\n if (!element) throw new Error('Element is not defined in getIncomingElements');\n let incomingElements = (element.incoming || []).map(out => out.sourceRef);\n\n // возвращаем уникальные, так как BPMN может быть не валидным\n return [ ...new Set(incomingElements) ];\n}\n\n/**\n * Только входящие из хоста\n * @param element\n * @returns {any[]}\n */\nexport function getHostIncoming(element) {\n return (element.incoming || [])\n .map(out => {\n if (!out.sourceRef) throw new Error(`${out.id} has no sourceRef`);\n return out.sourceRef;\n })\n .filter(el => !isBoundaryEvent(el));\n}\n\nexport function getBoundaryIncomingHosts(element) {\n let boundaryIncoming = (element.incoming || [])\n .map(out => out.sourceRef)\n .filter(el => isBoundaryEvent(el))\n .map(item => item.attachedToRef);\n boundaryIncoming = new Set(boundaryIncoming);\n\n return [ ...boundaryIncoming ];\n}\n\nexport function getAttachedOutgoingElements(element) {\n const outgoing = new Set();\n if (element) {\n const attachedOutgoing = (element.attachers || [])\n .sort((a,b) => {\n const bOutCount = b.outgoing ? b.outgoing.length : 0;\n const aOutCount = a.outgoing ? a.outgoing.length : 0;\n return bOutCount - aOutCount;\n })\n .map(attacher => (attacher.outgoing || []).reverse())\n .flat()\n .map(out => out.targetRef)\n .filter((item, index, self) => self.indexOf(item) === index);\n for (const out of attachedOutgoing) {\n outgoing.add(out);\n }\n }\n\n return [ ...outgoing ];\n}\n\nexport function isStartIntermediate(element) {\n return (is(element, 'bpmn:IntermediateThrowEvent') || is(element, 'bpmn:IntermediateCatchEvent'))\n && (element.incoming === undefined || element.incoming.length === 0);\n}\n\nexport function bindBoundaryEventsWithHosts(elements) {\n const boundaryEvents = elements.filter(element => isBoundaryEvent(element));\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\nexport function getAllProcesses(bpmnModel) {\n const allElements = bpmnModel.elementsById;\n if (!allElements) return [];\n return Object.values(allElements).filter(element => element.$type === 'bpmn:Process' || element.$type === 'bpmn:SubProcess');\n}\n\n// /**\n// * Set expanded property to element from its diagram\n// * @param bpmnModel\n// */\nexport function setAdditionalPropsToElements(bpmnModel, getLanes) {\n const allElements = bpmnModel.elementsById;\n if (allElements) {\n for (const element of Object.values(allElements)) {\n\n // mark expanded processes\n if (element.$type === 'bpmndi:BPMNShape' && element.isExpanded === true) element.bpmnElement.isExpanded = true;\n\n // mark lane indexes\n // todo: добавить очередность как она есть в DI, если есть\n if (element.$type === 'bpmn:Participant') {\n const lanes = [ ...getLanes(element.processRef) ].filter(([ , itemPos ]) => itemPos.right - itemPos.left === 1)\n .map(([ item ]) => item);\n if (lanes) {\n lanes.forEach((lane, index) => {\n const nodes = lane.flowNodeRef;\n if (nodes) {\n nodes.forEach(node => node.laneRef = lane);\n }\n });\n }\n }\n }\n }\n}\n","import { getDefaultSize, is } from '../di/DiUtil.js';\n\nimport {\n getAttachedOutgoingElements,\n getIncomingElements as utilsGetIncomingElements,\n getOutgoingElements as utilsGetOutgoingElements,\n} from './elementUtils.js';\n\nexport const DEFAULT_CELL_WIDTH = 150;\nexport const DEFAULT_CELL_HEIGHT = 140;\nexport const DEFAULT_POOL_MARGIN = DEFAULT_CELL_HEIGHT / 2;\n\nexport function getOutgoingElements(element, isFlipped) {\n return !isFlipped ? new Set (utilsGetOutgoingElements(element).concat(getAttachedOutgoingElements(element))) : new Set (utilsGetIncomingElements(element));\n}\n\n/**\n * Modified Manhattan layout: Uses space between grid columns to route connections\n * if direct connection is not possible.\n * @param edge\n * @param layoutGrid\n * @param shift\n * @returns waypoints\n */\nexport function connectElements(edge, layoutGrid, shift) {\n\n const { source, target } = edge;\n\n // TODO: Use GridController for Drawing\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 [ sourceRow, sourceCol, sourceHeight = 1 ] = layoutGrid.find(source);\n const [ targetRow, targetCol ] = layoutGrid.find(target);\n\n // todo: убрать dX ???\n const edgeDirection = layoutGrid.getEdgeDirection(edge);\n const dX = targetCol - sourceCol;\n const dY = targetRow - sourceRow;\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 const { x: sourceX, y: sourceY } = coordinatesToPosition(source, layoutGrid, shift);\n const { x: targetX, y: targetY } = coordinatesToPosition(target, layoutGrid, shift);\n\n const sourceIsBoundary = source.$type === 'bpmn:BoundaryEvent';\n\n // Source === Target ==> Build loop\n if (edgeDirection === 'NO_DIRECTION') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetX, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: sourceX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: sourceY + sourceHeight * DEFAULT_CELL_HEIGHT },\n { x: targetX, y: sourceY + sourceHeight * DEFAULT_CELL_HEIGHT },\n { x: sourceX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n }\n\n // 12 часов\n if (edgeDirection === 'S_N') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: sourceX, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n\n // пока так по колхозному\n const hasReversEdge = [ ...getOutgoingElements(target) ].includes(source);\n\n if (hasReversEdge) {\n\n // идем в обход\n return [\n getDockingPoint(sourceMid, sourceBounds, 'l', dockingSource),\n { x: sourceX, y: sourceMid.y },\n { x: targetX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n } else {\n return [\n getDockingPoint(sourceMid, sourceBounds, 't', dockingSource),\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n }\n }\n\n // 1 час\n if (edgeDirection === 'SW_NE') {\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n\n return [\n getDockingPoint(sourceMid, sourceBounds, 'r'),\n { x: targetMid.x, y: sourceMid.y },\n getDockingPoint(targetMid, targetBounds, 'b')\n ];\n }\n\n // 3\n if (edgeDirection === 'W_E') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'r', dockingSource);\n if (source.isExpanded) {\n firstPoint.y = sourceY + DEFAULT_CELL_HEIGHT / 2;\n }\n const lastPoint = getDockingPoint(targetMid, targetBounds, 'l', dockingTarget);\n if (target.isExpanded) {\n lastPoint.y = targetY + DEFAULT_CELL_HEIGHT / 2;\n }\n return [\n firstPoint,\n lastPoint\n ];\n }\n\n // 4 час\n if (edgeDirection === 'NW_SE') {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l')\n ];\n }\n\n // 6\n if (edgeDirection === 'N_S') {\n if (sourceIsBoundary) {\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource);\n const lastPoint = getDockingPoint(targetMid, targetBounds, 't', dockingTarget);\n\n if (source.attachedToRef.isExpanded) {\n return [\n firstPoint,\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n lastPoint\n ];\n }\n\n return [\n firstPoint,\n lastPoint\n ];\n }\n\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource);\n const lastPoint = getDockingPoint(targetMid, targetBounds, 't', dockingTarget);\n\n if (source.isExpanded || target.isExpanded) {\n return [\n firstPoint,\n { x: sourceMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n lastPoint\n ];\n }\n return [\n firstPoint,\n lastPoint\n ];\n }\n\n // 7 часов\n if (edgeDirection === 'NE_SW') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'r')\n ];\n\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'r')\n ];\n }\n\n // 9 часов\n if (edgeDirection === 'E_W') {\n const maxExpanded = getMaxExpandedBetween(source, target, layoutGrid);\n\n // пока так по колхозному\n const hasReversEdge = utilsGetOutgoingElements(target).includes(source);\n\n // TODO: Remove by new edge drawing logic\n let hasSW_NEOut = layoutGrid ? layoutGrid.getExistingOutgoingEdgesFor(target) : [];\n hasSW_NEOut = hasSW_NEOut.some(item => layoutGrid.getEdgeDirection(item) === 'SW_NE');\n\n if (sourceIsBoundary || hasReversEdge || hasSW_NEOut) {\n\n // идем в обход\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: sourceY + DEFAULT_CELL_HEIGHT + (maxExpanded ? maxExpanded - 1 : 0) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: sourceY + DEFAULT_CELL_HEIGHT + (maxExpanded ? maxExpanded - 1 : 0) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n } else {\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'l', dockingSource);\n if (source.isExpanded) {\n firstPoint.y = sourceY + DEFAULT_CELL_HEIGHT / 2;\n }\n const lastPoint = getDockingPoint(targetMid, targetBounds, 'r', dockingTarget);\n if (target.isExpanded) {\n lastPoint.y = targetY + DEFAULT_CELL_HEIGHT / 2;\n }\n return [\n firstPoint,\n lastPoint\n ];\n }\n }\n\n // negative dX indicates connection from future to past\n // 10 часов\n if (edgeDirection === 'SE_NW') {\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n\n // колхоз\n const elementsInHorizontal = [];\n for (let col = sourceCol - 1; col >= targetCol; col--) {\n const candidate = layoutGrid ? layoutGrid.get(sourceRow, col) : null;\n if (candidate) elementsInHorizontal.push(candidate);\n }\n if (elementsInHorizontal.length > 0) {\n\n // идем в обход\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n } else {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'l'),\n { x: targetMid.x, y: sourceMid.y },\n getDockingPoint(targetMid, targetBounds, 'b')\n ];\n }\n }\n\n // на будущее если не сработает что-то сверху\n const directManhattan = directManhattanConnect(source, target, layoutGrid);\n\n if (directManhattan) {\n const startPoint = getDockingPoint(sourceMid, sourceBounds, directManhattan[0], dockingSource);\n const endPoint = getDockingPoint(targetMid, targetBounds, directManhattan[1], dockingTarget);\n\n const midPoint = directManhattan[0] === 'h' ? { x: endPoint.x, y: startPoint.y } : { x: startPoint.x, y: endPoint.y };\n\n return [\n startPoint,\n midPoint,\n endPoint\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\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 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// helpers /////\nexport function coordinatesToPosition(element, grid, shift = { x: 0, y:0 }) {\n const [ row, col ] = grid.find(element);\n\n return {\n x: col * DEFAULT_CELL_WIDTH + shift.x,\n y: row * DEFAULT_CELL_HEIGHT + shift.y\n };\n}\n\nexport function getBounds(element, elementPosition, shift, laneLevelDif) {\n const [ row, col, positionWidth, positionHeight ] = elementPosition;\n const { width: defaultWidth, height: defaultHeight } = getDefaultSize(element);\n\n let width = ((!positionWidth ? 1 : positionWidth) - 1) * DEFAULT_CELL_WIDTH + defaultWidth;\n let height = ((!positionHeight ? 1 : positionHeight) - 1) * DEFAULT_CELL_HEIGHT + defaultHeight;\n let x = col * DEFAULT_CELL_WIDTH + (DEFAULT_CELL_WIDTH - defaultWidth) / 2 + shift.x;\n let y = row * DEFAULT_CELL_HEIGHT + (DEFAULT_CELL_HEIGHT - defaultHeight) / 2 + shift.y;\n\n // todo: сделать универсально\n if (element.$type === 'bpmn:Lane') {\n const participantLabelWidth = 30;\n\n width = (positionWidth || 1) * DEFAULT_CELL_WIDTH + DEFAULT_CELL_WIDTH + (laneLevelDif - 1) * participantLabelWidth;\n x = col * DEFAULT_CELL_WIDTH + shift.x - DEFAULT_CELL_WIDTH / 2 + participantLabelWidth;\n y = row * DEFAULT_CELL_HEIGHT + shift.y - DEFAULT_CELL_HEIGHT / 2;\n height = (positionHeight || 1) * DEFAULT_CELL_HEIGHT;\n }\n\n return {\n width,\n height,\n x,\n y\n };\n}\n\n// TODO: for future\n// eslint-disable-next-line no-unused-vars\nfunction isDirectPathBlocked(source, target, layoutGrid) {\n const [ sourceRow, sourceCol ] = layoutGrid.find(source);\n const [ targetRow, targetCol ] = layoutGrid.find(target);\n\n const dX = targetCol - sourceCol;\n const dY = targetRow - sourceRow;\n\n let totalElements = 0;\n\n if (dX) {\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: sourceCol }, { row: sourceRow, col: targetCol }).length;\n }\n\n if (dY) {\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: targetCol }, { row: targetRow, col: targetCol }).length;\n }\n\n return totalElements > 2;\n}\n\nfunction directManhattanConnect(source, target, layoutGrid) {\n const [ sourceRow, sourceCol ] = layoutGrid.find(source);\n const [ targetRow, targetCol ] = layoutGrid.find(target);\n\n const dX = targetCol - sourceCol;\n const dY = targetRow - sourceRow;\n\n // Only directly connect left-to-right flow\n if (!(dX > 0 && dY !== 0)) {\n return;\n }\n\n // If below, go down then horizontal\n if (dY > 0) {\n let totalElements = 0;\n const bendPoint = { row: targetRow, col: sourceCol };\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: sourceCol }, bendPoint).length;\n totalElements += layoutGrid.getElementsInRange(bendPoint, { row: targetRow, col: targetCol }).length;\n\n return totalElements > 2 ? false : [ 'v', 'h' ];\n } else {\n\n // If above, go horizontal than vertical\n let totalElements = 0;\n const bendPoint = { row: sourceRow, col: targetCol };\n\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: sourceCol }, bendPoint).length;\n totalElements += layoutGrid.getElementsInRange(bendPoint, { row: targetRow, col: targetCol }).length;\n\n return totalElements > 2 ? false : [ 'h', 'v' ];\n }\n}\n\nexport function sortElementsTopLeftBottomRight(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n return aPos[0] - bPos[0] || aPos[1] - bPos[1];\n };\n}\n\nexport function sortElementsTopRightBottomLeft(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n return aPos[0] - bPos[0] || bPos[1] - aPos[1];\n };\n}\n\nexport function sortColsLeftRightRowsBottomTop(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n return aPos[1] - bPos[1] || bPos[0] - aPos[0];\n };\n}\n\n/**\n *\n * @param {*[]} arr array of BPMN elements\n * @param {string|string[]} types array of types\n * @returns {*[]} sorted array of BPMN elements\n */\nexport function sortByType(arr, types) {\n const typesArray = [ types ].flat();\n\n let result = [];\n\n if (typesArray.length > 0) {\n typesArray.forEach((type,index) => {\n const matching = arr.filter(item => is(item, type));\n result = result.concat(matching);\n if (index === typesArray.length - 1 && result.length !== arr.length) {\n for (const item of arr) {\n if (!result.includes(item)) result.push(item);\n }\n }\n });\n } else {\n result = arr;\n }\n\n return result;\n}\n\nfunction getMaxExpandedBetween(source, target, layoutGrid) {\n const [ sourceRow, sourceCol ] = layoutGrid.find(source);\n const [ , targetCol ] = layoutGrid.find(target);\n\n const firstCol = sourceCol < targetCol ? sourceCol : targetCol;\n const lastCol = sourceCol < targetCol ? targetCol : sourceCol;\n\n const elementsInRange = [ ...layoutGrid.rows[sourceRow] ].filter(item => {\n const [ , col ] = layoutGrid.find(item);\n return col >= firstCol && col <= lastCol;\n });\n\n return elementsInRange.reduce((acc, cur) => {\n const [ , , , height ] = layoutGrid.find(cur);\n return height > acc ? height : acc;\n }, 0);\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}\n","export class Grid {\n constructor() {\n this.isFlipped = false;\n this._elements = new Map();\n this.rows = {};\n this.cols = {};\n }\n\n get rowCount() {\n return Object.keys(this.rows).length;\n }\n\n get colCount() {\n return Object.keys(this.cols).length;\n }\n\n get elementsCount() {\n return this._elements.size;\n }\n\n get elements() {\n return new Set (this._elements.keys());\n }\n\n /**\n *\n * @param element\n * @param {[number, number]} position - numbers are integer\n */\n add(element, position) {\n\n if (this._elements.has(element)) throw new Error(`Cannot add duplicated element ${JSON.stringify(element)}`);\n\n if (!position) {\n this._addStart(element);\n return;\n }\n\n const lastRow = this.rowCount - 1;\n const lastCol = this.colCount - 1;\n\n const rowDif = position[0] - lastRow;\n const colDif = position[1] - lastCol;\n this.addRowCol(false, lastRow >= 0 ? lastRow : undefined, rowDif);\n this.addRowCol(true, lastCol >= 0 ? lastCol : undefined, colDif);\n\n this._elements.set(element, position);\n this._addElementToRowsCols(element, position);\n }\n\n _addElementToRowsCols(element) {\n const position = this._elements.get(element);\n this.rows[position[0]] ? this.rows[position[0]].add(element) : this.rows[position[0]] = new Set([ element ]);\n this.cols[position[1]] ? this.cols[position[1]].add(element) : this.cols[position[1]] = new Set([ element ]);\n }\n _removeElementFromRowsCols(element) {\n const position = this._elements.get(element);\n if (this.rows[position[0]]) this.rows[position[0]].delete(element);\n if (this.cols[position[1]]) this.cols[position[1]].delete(element);\n }\n\n _addStart(element) {\n const [ row, ] = this.getGridDimensions();\n this._elements.set(element, [ row, 0 ]);\n this._addElementToRowsCols(element, [ row, 0 ]);\n }\n\n move(element, toPosition) {\n if (!this.elements.has(element)) throw new Error(`Cannot move not exist element ${JSON.stringify(element)}`);\n if (!this.isValidPosition(toPosition)) throw new Error(`Cannot move element ${JSON.stringify(element)} to invalid position ${toPosition}`);\n this._removeElementFromRowsCols(element);\n this._elements.set(element, toPosition);\n this._addElementToRowsCols(element, toPosition);\n }\n\n removeElement(element) {\n if (this._elements.has(element)) {\n this._removeElementFromRowsCols(element);\n this._elements.delete(element);\n }\n }\n\n addRowCol(addCol, afterIndex, count = 1) {\n\n // добавляем линии\n const gridCount = addCol ? this.colCount : this.rowCount;\n const addCount = afterIndex >= gridCount - 1 ? afterIndex - (gridCount - 1) + count : count;\n for (let i = 0; i < addCount; i++) {\n if (addCol) {\n this.cols[gridCount + i] = new Set();\n } else {\n this.rows[gridCount + i] = new Set();\n }\n }\n\n // перемещаем элементы\n for (const [ item, elementPosition ] of this._elements.entries()) {\n const position = addCol ? elementPosition[1] : elementPosition[0];\n\n if (position > afterIndex || afterIndex === undefined) {\n this._removeElementFromRowsCols(item);\n elementPosition[addCol ? 1 : 0] += count;\n this._addElementToRowsCols(item);\n }\n }\n }\n\n /**\n * Для добавления перед первым элементом afterIndex = undefined\n * @param {number} rowIndex - is positive integer\n * @param {number=} afterIndex - is integer\n * @param {number=} colCount - is positive integer\n */\n expandRow(rowIndex, afterIndex, colCount = 1) {\n\n if (!Number.isInteger(rowIndex) || rowIndex < 0 || rowIndex > this.rowCount - 1) throw new Error (`Can't expand row with index: ${rowIndex}. Grid row count is ${this.rowCount}`);\n\n // готовим строку\n const gridColCount = this.colCount;\n const addCount = afterIndex >= gridColCount - 1 ? afterIndex - (gridColCount - 1) + colCount : colCount;\n for (let i = 0; i < addCount; i++) {\n this.cols[gridColCount + i] = new Set();\n }\n\n // перемещаем элементы\n [ ...this.rows[rowIndex] ].forEach(item => {\n const position = this.find(item);\n if (position[1] > afterIndex || afterIndex === undefined) {\n this._removeElementFromRowsCols(item);\n position[1] += colCount;\n this._addElementToRowsCols(item);\n }\n });\n }\n\n /**\n * return position of element:\n * - [row: integer, col: integer] if element exist\n * - else undefined\n * @param element\n * @returns {number[] | undefined}\n */\n find(element) {\n return this._elements.get(element);\n }\n\n get(row, col) {\n\n // todo: make simple to read\n const elementsAtPosition = new Set ([ ...this._elements.entries() ].filter(([ item, position ]) => position[0] === row && position[1] === col)\n .map(item => item[0]));\n\n return elementsAtPosition.size ? elementsAtPosition : null;\n }\n\n getElementsInRange({ row: startRow, col: startCol }, { row: endRow, col: endCol }) {\n\n if (startRow > endRow) {\n [ startRow, endRow ] = [ endRow, startRow ];\n }\n\n if (startCol > endCol) {\n [ startCol, endCol ] = [ endCol, startCol ];\n }\n\n return [ ...this._elements.entries() ]\n .filter(([ , position ]) => position[0] >= startRow && position[0] <= endRow && position[1] >= startCol && position[1] <= endCol)\n .map(item => item[0]);\n }\n\n getGridDimensions() {\n const rows = this.rowCount;\n const cols = this.colCount;\n\n return [ rows, cols ];\n }\n\n // todo: переписать на строки\n shrink(byVertical) {\n\n // Отсортированный массив элементов по строкам или столбцам\n const sortedElements = [ ...this._elements.entries() ]\n .sort((a, b) => {\n const aPosition = !byVertical ? a[1][1] : a[1][0];\n const bPosition = !byVertical ? b[1][1] : b[1][0];\n return aPosition - bPosition;\n });\n\n // актуальный индекс = 0\n // смещение = 0\n let shift = 0;\n let previousIndex = null;\n\n for (const element of sortedElements) {\n\n // У элемента берём позицию\n const position = !byVertical ? element[1][1] : element[1][0];\n this._removeElementFromRowsCols(element[0]);\n\n if (previousIndex === null) {\n shift = position;\n } else if (previousIndex !== position) {\n shift = shift + position - previousIndex - 1;\n }\n\n previousIndex = position;\n\n const newElPos = [ ...element[1] ];\n if (!byVertical) {\n newElPos[1] -= shift;\n } else {\n newElPos[0] -= shift;\n }\n this._elements.set(element[0], newElPos);\n\n this._addElementToRowsCols(element[0]);\n }\n\n // todo: пока не смотрим на размер элементов, а просто удаляем пустые строки\n // Здесь уже все сдвинуты\n for (const [ key, value ] of Object.entries(!byVertical ? this.cols : this.rows)) {\n if (value.size === 0) {\n if (!byVertical) {\n delete this.cols[key];\n } else {\n delete this.rows[key];\n }\n }\n }\n\n }\n\n flip(byVertical) {\n\n // Получить измерения\n const [ rowCount, colCount ] = this.getGridDimensions();\n\n // Для каждой позиции\n // - измерение - 1 - позиция\n for (const [ element, position ] of this._elements.entries()) {\n this._removeElementFromRowsCols(element, position);\n this._elements.set(element, !byVertical ? [ position[0], colCount - 1 - position[1] ] : [ rowCount - 1 - position[0], position[1] ]);\n this._addElementToRowsCols(element, !byVertical ? [ position[0], colCount - 1 - position[1] ] : [ rowCount - 1 - position[0], position[1] ]);\n }\n\n // todo: add directional flip flag\n this.isFlipped = !this.isFlipped;\n }\n\n hasElement(element) {\n return this.elements.has(element);\n }\n\n isValidPosition(position) {\n if (!position || !Array.isArray(position)) return false;\n const [ row, col ] = position;\n return Number.isInteger(row) && Number.isInteger(col) && row >= 0 && col >= 0;\n }\n\n hasIntermediateElements(firstPosition, lastPosition, onVertical) {\n if (!this.isValidPosition(firstPosition) || !this.isValidPosition(lastPosition)) return false;\n if (!onVertical ? firstPosition[0] !== lastPosition[0] : firstPosition[1] !== lastPosition[1]) return false;\n\n const index = !onVertical ? firstPosition[1] : firstPosition[0];\n const [ start, end ] = !onVertical ? (firstPosition[1] <= lastPosition[1] ? [ firstPosition[1] , lastPosition[1] ] : [ lastPosition[1], firstPosition[1] ]) : (firstPosition[0] <= lastPosition[0] ? [ firstPosition[0] , lastPosition[0] ] : [ lastPosition[0], firstPosition[0] ]);\n return [ ...this._elements.values() ].some(item => !onVertical ? item[0] === index && item[1] > start && item[1] < end : item[1] === index && item[0] > start && item[0] < end);\n }\n\n hasElementAt(position) {\n if (!this.isValidPosition(position)) return false;\n const [ row, col ] = position;\n const element = this.get(row, col);\n return !!element;\n }\n}","import { Graph } from 'graph-by-ivan-tulaev';\n\nimport { Grid } from './Grid.js';\n\nimport {\n sortColsLeftRightRowsBottomTop, sortElementsTopRightBottomLeft,\n} from './utils/layoutUtils.js';\n\n\n/**\n * @typedef {[number, number]} Position\n * numbers must be integer\n */\n\n/**\n * @typedef {{position: Position, vCross: boolean, hCross: boolean}} PathSegment\n */\n\nexport class GridWithEdges extends Grid {\n constructor(initialGraph) {\n super();\n\n this.initialGraph = initialGraph;\n this.graph = new Graph();\n }\n\n getLanes() {\n return [ ...this.elements ].filter(element => element.$type === 'bpmn:Lane');\n }\n\n /**\n *\n * @param element\n * @param {[number, number]=} position - numbers are integer\n */\n add(element, position) {\n\n // добавляем lanes\n if (element.$type === 'bpmn:Lane') {\n super.add(element, position);\n return;\n }\n\n // обычное добавление элементов если lanes нет\n const lanes = this.getLanes();\n if (lanes.length === 0) {\n super.add(element, position);\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n return;\n }\n\n // добавляем элементы в lanes\n const lanePosition = this.find(element.laneRef);\n if (!position) {\n\n // получаем первую пустую строку в пределах lane и помещаем элемент туда\n const firstLaneRow = lanePosition[0];\n const lastLaneRow = lanePosition[0] + lanePosition[3] - 1;\n for (let rowIndex = firstLaneRow; rowIndex <= lastLaneRow; rowIndex++) {\n const elementsInRow = new Set (this.rows[rowIndex]);\n elementsInRow.delete(element.laneRef);\n if (elementsInRow.size === 0) {\n\n // здесь вставляем и тормозим\n super.add(element, [ rowIndex, 0 ]);\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n return;\n }\n }\n\n // если пробежались по всем строкам lane и не нашли пустую, то добавляем новую строку в lane\n this.addRowCol(false, lanePosition[0] + lanePosition[3] - 1);\n super.add(element, [ lanePosition[0] + lanePosition[3], 0 ]);\n lanePosition[3] += 1;\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n return;\n }\n\n const rowDif = position[0] + (position[3] || 1) - (lanePosition[0] + (lanePosition[3] || 1));\n if (rowDif > 0) {\n this.addRowCol(false, lanePosition[0] + (lanePosition[3] || 1) - 1, rowDif);\n lanePosition[3] += rowDif;\n }\n super.add(element, position);\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n }\n\n removeElement(element) {\n this.graph.deleteNode(element);\n\n super.removeElement(element);\n }\n\n /**\n * Проверка существования для НОВЫХ ребер\n * Со старыми только через мапу\n * @param edge\n * @returns {*}\n * @private\n */\n _edgeIsExist(edge) {\n return [ ...this.graph.edges ].includes(edge);\n }\n\n _addEdgeToGrid(edge) {\n if (!this._edgeIsExist(edge)) this.graph.addEdge(edge);\n }\n\n /**\n *\n * @param element element\n * @private\n */\n _createNewEdgesFor(element) {\n\n // todo: переписать под обертку\n const edges = [ ...this.initialGraph.getOutgoingEdgesFor(element), ...this.initialGraph.getIncomingEdgesFor(element) ]\n .filter(edge => this.hasElement(edge.source) && this.hasElement(edge.target));\n for (const edge of edges) {\n this._addEdgeToGrid(edge);\n }\n }\n\n /** @typedef {[number, number]} Position*/\n\n /**\n * @param {Position} position\n * @param {boolean=} byVertical\n * @returns {boolean}\n */\n isCrossed(position, byVertical = false) {\n\n return [ ...this._allEdges ].some(edge => this.isIntersect(edge, position, byVertical));\n }\n\n get _allEdges() {\n return this.graph.edges;\n }\n\n /**\n * Пока так наличие пересечений определим\n * @param {Edge[]=} edges\n * @returns {boolean}\n */\n hasAnyCross(edges) {\n const executedEdges = edges ? edges : this._allEdges;\n\n return [ ...executedEdges ].some(edge => this.getCrossedElementsFor(edge).length > 0 || this.getCrossedElementsFor(edge, true).length > 0);\n }\n\n /**\n * Уплотняет грид по горизонтали или по вертикали\n * @param {boolean} byVertical\n */\n shakeIt(byVertical) {\n\n const sortedElements = [ ...this.elements ].filter(item => item.$type !== 'bpmn:Lane').sort(byVertical ? sortElementsTopRightBottomLeft(this) : sortColsLeftRightRowsBottomTop (this)).reverse();\n\n while (sortedElements.length > 0) {\n\n // работаем по первому элементу\n const element = sortedElements.pop();\n\n // получаем цепочку противоположную направлению уплотнения\n // удаляем из стека sortedElements все элементы из цепочки\n const chain = this.getChain(element, !byVertical);\n\n for (const chainElement of chain) {\n const deleteIndex = sortedElements.indexOf(chainElement);\n if (deleteIndex >= 0) {\n sortedElements.splice(deleteIndex, 1);\n }\n }\n\n // проверяем можно ли двинуть цепочку вверх для уплотнения по вертикали и влево для уплотнения по горизонтали\n // не одна из позиций не должна быть занята или иметь пересечения\n // - цепочка не должна удлиниться\n // todo: пока под вопросом для ребра из boundary не должны закручиваться\n const [ baseRow, baseCol ] = this.find([ ...chain ][0]);\n\n // двигаться не вариант если цепочка у края грида\n if (byVertical ? baseRow <= 0 : baseCol <= 0) continue;\n\n for (let index = byVertical ? baseRow - 1 : baseCol - 1 ; index >= 0; index--) {\n\n // не двигаем если есть пересечения\n // todo: добавить оптимизации\n const allPositionsAreFine = [ ...chain ].every(element => {\n const curPos = this.find(element);\n\n return curPos && !this.isCrossed(curPos, true) && !this.isCrossed(curPos, false) ;\n });\n if (!allPositionsAreFine) break;\n\n // проверяем заняты ли новые позиции\n // todo: добавить оптимизации\n const newPositionsAreFine = [ ...chain ].every(element => {\n const curPos = this.find(element);\n const checkedRow = byVertical ? index : curPos[0];\n const checkedCol = byVertical ? curPos[1] : index;\n return !this.get(checkedRow, checkedCol);\n });\n if (!newPositionsAreFine) break;\n\n // пробно перемещаем все элементы из цепочки на новые места\n // пересечения позже всем скоупом проверим\n for (const chainElement of chain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, byVertical ? [ index, chainElementPosition[1] ] : [ chainElementPosition[0], index ]);\n }\n\n // проверяем не образовалось ли новых пересечений пока по старинке\n // и не удлинилась ли цепочка\n // todo: не пробегаться по всему гриду, а работать только по цепочке!!!\n const hasNewCrosses = this.hasAnyCross();\n const newChain = this.getChain(element, !byVertical);\n if (hasNewCrosses || newChain.size > chain.size) {\n\n // вертаем все элементы взад\n for (const chainElement of chain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, byVertical ? [ index + 1 , chainElementPosition[1] ] : [ chainElementPosition[0], index + 1 ]);\n }\n break;\n }\n }\n\n // после каждого прохода удаляем пустые линии чтобы не ходить по пустым местам\n this.shrink(byVertical);\n }\n }\n\n /**\n * Возвращает горизонтальную или вертикальную последовательность элементов\n * @param {any} element BPMN Element\n * @param {boolean} byVertical\n * @param {Set<any>=}oldChain\n * @returns {Set<any>}\n */\n getChain(element, byVertical, oldChain) {\n const chain = !oldChain ? new Set() : oldChain;\n if (!element) return chain;\n\n const elementPosition = this.find(element);\n if (!elementPosition) return chain;\n\n const edges = [];\n\n // получаем все элементы в позиции\n const elInPos = [ ...this.get(elementPosition[0], elementPosition[1]) ].filter(item => item.$type !== 'bpmn:Lane');\n for (const el of elInPos) {\n chain.add(el);\n\n // todo: возможно стоит добавить другие варианты ребер - в себя - убрать undefined\n [ ...this.getAllExistingEdgesFor(el) ]\n .filter(edge => {\n const edgeDirection = this.getEdgeDirection(edge);\n return !byVertical ? (edgeDirection === 'W_E' || edgeDirection === 'E_W') : (edgeDirection === 'N_S' || edgeDirection === 'S_N');\n })\n .forEach(edge => edges.push(edge));\n }\n\n for (const edge of edges) {\n const nextElement = edge.source === element ? edge.target : edge.source;\n if (!chain.has(nextElement)) {\n const nextChain = this.getChain(nextElement, byVertical, chain);\n for (const nextChainEl of nextChain) {\n chain.add(nextChainEl);\n }\n }\n }\n return chain;\n }\n\n getExistingOutgoingEdgesFor(element) {\n return !this.isFlipped ? [ ...this.graph.getOutgoingEdgesFor(element) ] : [ ...this.graph.getIncomingEdgesFor(element) ];\n }\n\n getExistingIncomingEdgesFor(element) {\n return !this.isFlipped ? [ ...this.graph.getIncomingEdgesFor(element) ] : [ ...this.graph.getOutgoingEdgesFor(element) ];\n }\n\n getAllExistingEdgesFor(element) {\n const outgoingEdges = this.getExistingOutgoingEdgesFor(element);\n const incomingEdges = this.getExistingIncomingEdgesFor(element);\n return new Set([ ...outgoingEdges, ...incomingEdges ]);\n }\n\n _separateGrid() {\n\n // создаем копию графа\n const executedGraph = Graph.mergeGraphs(new Set([ this.graph ]));\n\n const separatedGraphs = executedGraph.getSeparatedGraphs();\n\n // todo: костыль для устранения проблемы после разделения пустого графа\n if (separatedGraphs.length === 0) return [ new GridWithEdges(this.initialGraph) ];\n\n // todo: добавить проверку на не пересечение\n const grids = [];\n\n for (const graph of separatedGraphs) {\n const grid = new GridWithEdges(this.initialGraph);\n\n let minRow = null;\n let maxRow = null;\n\n for (const node of graph.nodes) {\n const position = [ ...this.find(node) ];\n if (minRow === null || minRow > position[0]) minRow = position[0];\n if (maxRow === null || maxRow < position[0]) maxRow = position[0];\n grid.add(node, position);\n }\n\n grids.push(grid);\n }\n\n return grids;\n }\n\n // todo: сделать нормальное копирование\n _mergeGrids(grids) {\n const newGrid = new GridWithEdges(grids[0].initialGraph);\n\n grids.forEach(grid => {\n let rowShift = newGrid.rowCount;\n\n Object.keys(grid.rows).forEach(rowIndex => {\n if (grid.rows[rowIndex].size === 0) {\n newGrid.addRowCol(false, rowShift + Number.parseInt(rowIndex) - 1);\n } else {\n grid.rows[rowIndex].forEach(node => {\n const newPosition = [ ...grid.find(node) ];\n newPosition[0] = newPosition[0] + rowShift;\n newGrid.add(node, newPosition);\n });\n }\n });\n });\n\n return newGrid;\n }\n\n getSourcePosition(edge) {\n const source = this.getEdgeSource(edge);\n return this.find(source);\n }\n\n getTargetPosition(edge) {\n const target = this.getEdgeTarget(edge);\n return this.find(target);\n }\n\n /**\n * @typedef {('S_N' | 'SW_NE' | 'W_E' | 'NW_SE' | 'N_S' | 'NE_SW' | 'E_W' | 'SE_NW' | 'NO_DIRECTION')} Direction\n * - **S_N** - south to north\n * - **SW_NE** - south-west to north-east\n * - **W_E** - west to east\n * - **NW_SE** - north-west to south-east\n * - **N_S** - north to south\n * - **NE_SW** - north-east to south-west\n * - **E_W** - east to west\n * - **SE_NW** - south-east to north-west\n * - **NO_DIRECTION** - if it's not a vector but a point\n */\n\n /**\n * @param edge\n * @returns {Direction}\n */\n getEdgeDirection(edge) {\n const sourcePosition = this.getSourcePosition(edge);\n const targetPosition = this.getTargetPosition(edge);\n\n if (!this.isValidPosition(sourcePosition) || !this.isValidPosition(targetPosition)) throw new Error(`Invalid position of source or target in ${edge.source.id}-${edge.target.id} flipped:${this.isFlipped}`);\n\n const [ sourceRow, sourceCol ] = sourcePosition;\n const [ targetRow, targetCol ] = targetPosition;\n\n const vDifference = sourceRow - targetRow;\n const hDifference = sourceCol - targetCol;\n\n // self\n if (vDifference === 0 && hDifference === 0) return 'NO_DIRECTION';\n\n // south to north\n if (vDifference > 0 && hDifference === 0) return 'S_N';\n\n // south-west to north-east\n if (vDifference > 0 && hDifference < 0) return 'SW_NE';\n\n // west to east\n if (vDifference === 0 && hDifference < 0) return 'W_E';\n\n // north-west to south-east\n if (vDifference < 0 && hDifference < 0) return 'NW_SE';\n\n // north to south\n if (vDifference < 0 && hDifference === 0) return 'N_S';\n\n // north-east to south-west\n if (sourceRow < targetRow && sourceCol > targetCol) return 'NE_SW';\n\n // east to west\n if (sourceRow === targetRow && sourceCol > targetCol) return 'E_W';\n\n // south-east to north-west\n if (sourceRow > targetRow && sourceCol > targetCol) return 'SE_NW';\n }\n\n /**\n * @param edge\n * @returns {Array<PathSegment>}\n */\n getPathFor(edge) {\n const direction = this.getEdgeDirection(edge);\n\n if (direction === 'NO_DIRECTION') return this._pathForNoDirection();\n if (direction === 'S_N') return this._pathForSouthToNorth(edge);\n if (direction === 'SW_NE') return this._pathForSouthWestToNorthEast(edge);\n if (direction === 'W_E') return this._pathForWestToEast(edge);\n if (direction === 'NW_SE') return this._pathForNorthWestToSouthEast(edge);\n if (direction === 'N_S') return this._pathForNorthToSouth(edge);\n if (direction === 'NE_SW') return this._pathForNorthEastToSouthWest(edge);\n if (direction === 'E_W') return this._pathForEastToWest(edge);\n if (direction === 'SE_NW') return this._pathForSouthEastToNorthWest(edge);\n return [];\n }\n\n _pathForNoDirection() {\n return [];\n }\n\n getEdgeSource(edge) {\n return !this.isFlipped ? edge.source : edge.target;\n }\n\n getEdgeTarget(edge) {\n return !this.isFlipped ? edge.target : edge.source;\n }\n\n _pathForSouthToNorth(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow ] = this.getTargetPosition(edge);\n\n // если sourceIsBoundary, то сразу идем в обход, так же для реверса\n if (this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent' && edge.id) return pathSegments;\n\n // TODO: при реверсе флипать сегменты перед отдачей? Need tests!\n // проверяем есть ли элементы между sourcePosition, targetPosition\n // если есть, то ребро пойдет в обход\n // так же оно пойдет в обход если элементы на соседних клетках и есть обратное ребро targetPosition-sourcePosition\n let hasIntermediateElements = this.hasIntermediateElements(this.getSourcePosition(edge), this.getTargetPosition(edge), true);\n\n // идем между ячейками грида\n if (hasIntermediateElements) return pathSegments;\n\n // проверяем петлю source -> target -> source\n const targetElementOutgoingEdges = this.getExistingOutgoingEdgesFor(this.getEdgeTarget(edge));\n const targetElementOutgoing = [ ...targetElementOutgoingEdges ].map(edge => this.getEdgeTarget(edge));\n\n // идем в обход если есть ребро в противоположном направлении\n if (targetElementOutgoing.includes(this.getEdgeSource(edge))) return pathSegments;\n\n // в остальных случаях идем прямо\n for (let rowIndex = sourceRow - 1; rowIndex > targetRow; rowIndex--) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForSouthWestToNorthEast(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // если sourceIsBoundary, то пропускаем горизонтальную часть\n if (!(this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent')) {\n\n // move right then up\n for (let colIndex = sourceCol + 1; colIndex < targetCol; colIndex++) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n }\n\n pathSegments.push({ position: [ sourceRow, targetCol ], hCross: true, vCross: true });\n\n for (let rowIndex = sourceRow - 1; rowIndex > targetRow; rowIndex--) {\n pathSegments.push({ position: [ rowIndex, targetCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForWestToEast(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ , targetCol ] = this.getTargetPosition(edge);\n\n // всегда идем вперед\n for (let colIndex = sourceCol + 1; colIndex < targetCol; colIndex++) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForNorthWestToSouthEast(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // идем сначала вниз, потом вправо так же и для sourceIsBoundary\n for (let rowIndex = sourceRow + 1; rowIndex < targetRow; rowIndex++) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n pathSegments.push({ position: [ targetRow, sourceCol ], vCross: true, hCross: true });\n\n for (let colIndex = sourceCol + 1; colIndex < targetCol; colIndex++) {\n pathSegments.push({ position: [ targetRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForNorthToSouth(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow ] = this.getTargetPosition(edge);\n\n // всегда идем вниз так же и для sourceIsBoundary\n for (let rowIndex = sourceRow + 1; rowIndex < targetRow; rowIndex++) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForNorthEastToSouthWest(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // идем вниз потом налево так же и для sourceIsBoundary\n for (let rowIndex = sourceRow + 1; rowIndex < targetRow; rowIndex++) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n\n pathSegments.push({ position: [ targetRow, sourceCol ], vCross: true, hCross: true });\n\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ targetRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForEastToWest(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ , targetCol ] = this.getTargetPosition(edge);\n\n // здесь аналогично движению вверх\n // проверяем есть ли элементы между sourcePosition, targetPosition\n // если есть, то ребро пойдет в обход\n // так же оно пойдет в обход если элементы на соседних клетках и есть обратное ребро targetPosition-sourcePosition\n // идем между ячейками грида\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForSouthEastToNorthWest(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // для sourceIsBoundary пропускаем горизонталь\n if (!(this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent' && edge.id)) {\n\n // пробуем новую схему для хост-хост без обхода\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n }\n\n // угловой сегмент\n if (!(this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent' && edge.id)) {\n pathSegments.push({ position: [ sourceRow, targetCol ], hCross: true, vCross: true });\n } else {\n pathSegments.push({ position: [ sourceRow, targetCol ], vCross: true });\n }\n\n // идем наверх\n for (let rowIndex = sourceRow - 1; rowIndex > targetRow; rowIndex--) {\n pathSegments.push({ position: [ rowIndex, targetCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n getCrossedElementsFor(edge, byVertical = false) {\n const crossedElements = [];\n for (const segment of this.getPathFor(edge)) {\n const [ row, col ] = segment.position;\n const element = this.get(row, col);\n if (element && ((byVertical && segment.vCross) || (!byVertical && segment.hCross))) crossedElements.push(element);\n }\n return crossedElements;\n }\n\n isIntersect(edge, position, byVertical) {\n\n // быстрый расчет по направлениям\n const [ row, col ] = position;\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n const direction = this.getEdgeDirection(edge);\n\n if (direction === 'S_N') {\n return byVertical && col === sourceCol && row < sourceRow && row > targetRow;\n }\n\n if (direction === 'SW_NE') {\n if (byVertical && col === targetCol && row <= sourceRow && row > targetRow) return true;\n return !byVertical && col > sourceCol && col <= targetCol && row === sourceRow;\n }\n\n if (direction === 'W_E') {\n return !byVertical && col > sourceCol && col < targetCol && row === sourceRow;\n }\n\n if (direction === 'NW_SE') {\n if (byVertical && col === sourceCol && row > sourceRow && row <= targetRow) return true;\n return !byVertical && col >= sourceCol && col < targetCol && row === targetRow;\n }\n\n if (direction === 'N_S') {\n return byVertical && col === sourceCol && row > sourceRow && row < targetRow;\n }\n\n if (direction === 'NE_SW') {\n if (byVertical && col === sourceCol && row > sourceRow && row <= targetRow) return true;\n return !byVertical && col > targetCol && col <= sourceCol && row === targetRow;\n\n }\n\n if (direction === 'E_W') {\n return !byVertical && col > targetCol && col < sourceCol && row === sourceRow;\n }\n\n if (direction === 'SE_NW') {\n\n // todo: все это надо собрать в одном месте\n // а так же если есть входящие в source с направлением NW_SE\n if (byVertical && col === targetCol && row > targetRow && row <= sourceRow) return true;\n return !byVertical && col >= targetCol &&\n col < sourceCol && row === sourceRow &&\n !this.getExistingIncomingEdgesFor(this.getEdgeSource(edge))\n .some(edge => this.getEdgeDirection(edge) === 'NW_SE' || this.getEdgeDirection(edge) === 'W_E');\n }\n }\n\n /**\n * Получает ребра идущие назад и вверх\n * @param node\n * @returns {*}\n */\n getBackwardUpOutgoingEdgesFor(node) {\n return this.getExistingOutgoingEdgesFor(node).filter(edge => {\n const direction = this.getEdgeDirection(edge);\n return direction === 'S_N' || direction === 'SE_NW';\n });\n }\n\n /**\n * Создает копию грида\n * @returns {GridWithEdges}\n */\n getGridCopy() {\n return this._mergeGrids([ this ]);\n }\n\n /**\n * Удаляет ребро из грида\n * @param edge\n */\n removeEdge(edge) {\n this.graph.deleteEdge(edge);\n }\n\n getGraphSegmentFrom(node) {\n\n const segment = new Graph();\n\n // проходим только вперед\n // GetStartElementFunction<N> = (visited: Set<N>, initialGraph: Graph<N>) => N | undefined\n const getStartElement = (visited, initialGraph) => {\n return !visited.has(node) ? node : undefined;\n };\n\n // GetNextNodesFunction<N> = (node: N, graph: Graph<N>, visited: Set<N>, executionSequence: Array<N>) => Array<N> | undefined\n const getNextNodes = (node, graph, visited, executionSequence) => {\n const nextEdges = this.getExistingOutgoingEdgesFor(node).filter(edge => {\n const target = this.getEdgeTarget(edge);\n const source = this.getEdgeSource(edge);\n return !visited.has(target) && target !== source;\n });\n\n segment.addNode(node);\n const nextNodes = nextEdges.map(edge => {\n return this.getEdgeTarget(edge);\n });\n\n for (const node of nextNodes) {\n segment.addNode(node);\n }\n\n for (const edge of nextEdges) {\n segment.addEdge(edge);\n }\n\n return nextNodes;\n };\n\n this.graph.genericTraversing(getNextNodes, getStartElement);\n\n return segment;\n }\n\n getSegmentLeftCoordinates(segment) {\n\n const leftCoordinates = new Map();\n\n for (const node of segment.nodes) {\n const [ nodeRow, nodeCol ] = this.find(node);\n\n if (!leftCoordinates.has(nodeRow)) leftCoordinates.set(nodeRow, nodeCol);\n\n if (nodeCol < leftCoordinates.get(nodeRow)) leftCoordinates.set(nodeRow, nodeCol);\n }\n return leftCoordinates;\n }\n}\n","import {\n sortElementsTopLeftBottomRight\n} from '../utils/layoutUtils.js';\n\nexport function elementExecution(node, grid, executionSequence, visited, graph) {\n if (!grid.hasElement(node)) {\n grid.add(node);\n }\n\n // получаем новые которых нет в гриде\n // todo: перенести код\n const newOutgoing = (!grid.isFlipped ? [ ...grid.initialGraph.getOutgoingEdgesFor(node) ] : [ ...grid.initialGraph.getIncomingEdgesFor(node) ]).filter(edge => !grid.hasElement(!grid.isFlipped ? edge.target : edge.source)).map(edge => !grid.isFlipped ? edge.target : edge.source);\n\n // получаем вершины из стека с удалением их из грида\n // грохнем для теста так как их уже вытянули вперед\n const outgoingFromStack = getOutgoingFromStack(node, grid, executionSequence, newOutgoing && newOutgoing.length > 0, graph, visited);\n\n // Handle outgoing paths without boundaryEvents\n // Maybe later it will merge (Добавить сортировку по типу исходящих?)\n let outgoing = [ ...newOutgoing, ...outgoingFromStack ];\n\n let nextElements = [];\n\n outgoing.forEach(nextElement => {\n\n // подготавливаем место\n const nextPosition = [ ...getInsertPosition (node, grid, nextElement) ];\n\n // вставляем элемент\n // todo: костыль вставляем attachedToRef\n if (grid.isFlipped && nextElement.$type === 'bpmn:BoundaryEvent' && nextElement.attachedToRef !== node) {\n const attachedToRef = nextElement.attachedToRef;\n if (!visited.has(attachedToRef)) {\n grid.add(attachedToRef, nextPosition);\n visited.add(attachedToRef);\n fixNewCrosses(attachedToRef, grid, executionSequence, nextElements, true);\n nextElements.unshift(nextElement);\n }\n }\n grid.add(nextElement, nextPosition);\n visited.add(nextElement);\n\n fixNewCrosses(nextElement, grid, executionSequence, nextElements, true);\n\n // выворачиваем\n // Верхние левые сдвигаем вперед и проверяем пересечения начиная с левого.\n moveTopLeftOutgoingForward(nextElement, grid);\n\n nextElements.unshift(nextElement);\n });\n\n // TODO: sort by priority\n const nextBoundaries = [];\n const nextOther = [];\n for (const item of nextElements) {\n if (item.$type === 'bpmn:BoundaryEvent') {\n nextBoundaries.push(item);\n } else {\n nextOther.push(item);\n }\n }\n\n nextBoundaries.sort((a, b) => {\n const aOutCount = a.outgoing ? a.outgoing.length : 0;\n const bOutCount = b.outgoing ? b.outgoing.length : 0;\n return aOutCount - bOutCount;\n });\n\n nextElements = [ ...nextBoundaries, ...nextOther ];\n return nextElements;\n}\n\nfunction moveTopLeftOutgoingForward(node, grid) {\n\n // todo: выбрать сегмент по всем идущим назад ребрами\n // двигать весь сегмент\n // нужны тестовые данные для этого кейса\n /*\n Алгоритм без выворачивания следующий.\n Вопрос по элементам ниже пока не двигаем - тоже их удаляем из копии.\n Делаем копию грида.\n Работаем по копии грида.\n Удаляем все элементы левее таргета.\n Удаляем все исходящие ребра из сорса. ---\n Строим сегмент графа из таргета.\n Если сорс в сегменте, то не двигаем.\n Находим крайние левые позиции сегмента.\n Двигаем в базовом гриде сегмент вправо таким образом, чтобы крайний левый элемент оказался правее сорса\n */\n // получаем ребра ведущие назад из элемента\n let existingEdges = grid.getBackwardUpOutgoingEdgesFor(node);\n\n // todo: пока без сортировки чтобы проверить концепцию сдвига\n while (existingEdges.length > 0) {\n\n const workingEdge = existingEdges.shift();\n\n // todo: оптимизировать\n const sourcePos = grid.getSourcePosition(workingEdge);\n const targetPos = grid.getTargetPosition(workingEdge);\n const source = grid.getEdgeSource(workingEdge);\n const target = grid.getEdgeTarget(workingEdge);\n\n if (targetPos[1] > grid.find(node)[1]) continue;\n\n const gridCopy = grid.getGridCopy();\n\n gridCopy.removeEdge(workingEdge);\n\n // оптимизированный проход без поиска в гриде\n gridCopy._elements.forEach((value, key) => {\n const [ , colIndex ] = value;\n if (colIndex < targetPos[1]) gridCopy.removeElement(key);\n });\n\n const graphSegment = gridCopy.getGraphSegmentFrom(target);\n\n if (graphSegment.nodes.includes(source)) continue;\n\n const segmentCords = Array.from(gridCopy.getSegmentLeftCoordinates(graphSegment));\n\n const minColPosition = segmentCords.reduce((acc, cur) => {\n return acc === undefined || cur[1] < acc[1] ? cur : acc;\n }, undefined);\n\n const minRowPosition = segmentCords.reduce((acc, cur) => {\n return acc === undefined || cur[0] < acc[0] ? cur : acc;\n }, undefined);\n\n const maxRowPosition = segmentCords.reduce((acc, cur) => {\n return acc === undefined || cur[0] > acc[0] ? cur : acc;\n }, undefined);\n\n const shift = sourcePos[1] - minColPosition[1] + 1;\n\n const newMap = new Map(segmentCords);\n\n let previousShiftPos = undefined; // [row, col]\n\n for (let rowIndex = 0; rowIndex < grid.rowCount; rowIndex++) {\n\n const getShiftPos = () => {\n\n // todo: погонять тесты\n // здесь надо смещать все что выше\n if (rowIndex < minRowPosition[0]) {\n previousShiftPos = minRowPosition[0];\n return minRowPosition[1] - 1; // выше сегмента\n }\n if (newMap.has(rowIndex)) {\n previousShiftPos = newMap.get(rowIndex);\n return newMap.get(rowIndex) - 1;\n }\n\n const nodePosition = grid.find(node) || [];\n\n // посреди сегмента выше ноды\n if (rowIndex > minRowPosition[0] && rowIndex < maxRowPosition[0] && rowIndex < nodePosition[0]) {\n return previousShiftPos;\n }\n\n\n if (rowIndex === nodePosition[0] || rowIndex > minRowPosition[0]) {\n previousShiftPos = nodePosition;\n\n return nodePosition[1];\n }\n\n return previousShiftPos;\n };\n\n const shiftPos = getShiftPos() ;\n\n grid.expandRow(rowIndex, shiftPos, shift);\n }\n }\n}\n\nfunction inStackWithoutOutgoing(node, executionSequence, grid) {\n const inStack = executionSequence.includes(node);\n const outgoing = grid.getExistingOutgoingEdgesFor(node);\n\n return inStack && (!outgoing?.length > 0);\n}\n\n/**\n * @param grid\n * @param {[number, number]} topLeftPosition\n * @param {[number, number]} bottomRightPosition\n */\n// eslint-disable-next-line no-unused-vars\nfunction fixCrossesInGridPart(grid, graph, visited, topLeftPosition, bottomRightPosition) {\n if (!grid.isValidPosition(topLeftPosition) || !grid.isValidPosition(bottomRightPosition)) throw new Error('fixCrossesInGridPart: invalid position');\n\n const [ topLeftRow, topLeftCol ] = topLeftPosition;\n const [ bottomRightRow, bottomRightCol ] = bottomRightPosition;\n\n for (let rowIndex = topLeftRow; rowIndex <= bottomRightRow; rowIndex++) {\n for (let colIndex = topLeftCol; colIndex <= bottomRightCol; colIndex++) {\n const element = grid.get(rowIndex, colIndex);\n if (!element) continue;\n fixNewCrosses(element, grid);\n }\n }\n}\n\n\n/**\n * - Выдергивает исходящие элементы из стека обработки\n * - Так же удаляет их из графа\n * - Для дальнейшей обработки воспринимаем их как абсолютно новые вершины\n // * @param element - элемент для которого ищем исходящие\n // * @param grid\n // * @param {Array<Element>}stack\n // * @returns {any[]} - массив элементов\n */\nfunction getOutgoingFromStack(node, grid, executionSequence, hasNewOutgoings, graph, visited) {\n\n // получаем все исходящие базового элемента\n // const outgoing = grid.getExistingOutgoingEdgesFor(node);\n const outgoing = grid.getExistingOutgoingEdgesFor(node) ;\n const incoming = grid.getExistingIncomingEdgesFor(node).map(edge => grid.getEdgeSource(edge));\n\n const [ , elementCol ] = grid.find(node);\n const processingElements = [ ...outgoing ].filter(edge => {\n\n // оставляем только те, что идут в стек и не имеют исходящих\n const target = grid.getEdgeTarget(edge);\n const targetCol = grid.find(target)[1];\n\n if (!inStackWithoutOutgoing(target, executionSequence, grid)) return false;\n\n\n // исключаем если общий родитель, так как уже расставили их правильно\n // пробуем нет входящих кроме element\n // если есть общий родитель и есть новые исходящие то выкидываем\n const targetIncoming = grid.getExistingIncomingEdgesFor(target)\n .map(targetEdge => targetEdge.source);\n\n const commonParent = targetIncoming.find(targetParent => incoming.includes(targetParent));\n if (commonParent && hasNewOutgoings) return false;\n\n // пробуем оставлять только те, что слева\n return targetCol <= elementCol;\n }).map(item => grid.getEdgeTarget(item)).sort(sortElementsTopLeftBottomRight (grid));\n\n // Обрабатываем элементы.\n // Удаляем их из стека и из грида\n for (const processingElement of processingElements) {\n executionSequence.splice(executionSequence.indexOf(processingElement), 1);\n visited.delete(processingElement);\n grid.removeElement(processingElement);\n }\n\n // после удаления из грида удаляем лишние колонки\n // grid.shrink(true);\n // grid.shrink(false);\n\n // обрабатываем их как новые исходящие\n return processingElements;\n}\n\nfunction getInsertPosition(element, grid, nextEl) {\n\n // todo: пока костыль\n if (grid.isFlipped && nextEl.$type === 'bpmn:BoundaryEvent' && grid.hasElement(nextEl.attachedToRef)) return grid.find(nextEl.attachedToRef);\n\n const nextOnElement = nextEl.attachedToRef === element;\n if (nextOnElement) return grid.find(element);\n\n const sourcePosition = grid.find(element);\n if (!sourcePosition) throw new Error('No source position');\n\n // по умолчанию располагаем справа от element\n const position = [ sourcePosition[0], sourcePosition[1] + 1 ];\n\n // если boundary в одном лэйне, то по диагонали\n const isBoundarySource = element.$type === 'bpmn:BoundaryEvent' && !grid.isFlipped;\n const elementLane = element.laneRef;\n const nextElLane = nextEl.laneRef;\n if (isBoundarySource && elementLane === nextElLane) {\n position[0] += 1;\n }\n\n if (elementLane !== nextElLane) { // todo: здесь!!!\n const [ elementLaneRow ] = grid.find(elementLane);\n const [ nextElLaneRow, , , nextElLaneHeight ] = grid.find(nextElLane);\n const laneRowPosDif = elementLaneRow - nextElLaneRow;\n if (laneRowPosDif > 0) {\n position[0] = nextElLaneRow + nextElLaneHeight - 1;\n } else {\n position[0] = nextElLaneRow;\n }\n }\n\n // ищем первую дырку между ребрами источника\n const elPos = grid.find(element);\n const allItemsInElementPosition = [ ...grid.get(elPos[0], elPos[1]) ];\n const elementPositionEdges = [];\n\n // todo: надо смотреть реверс\n for (const item of allItemsInElementPosition) {\n [ ...grid.getExistingOutgoingEdgesFor(item) ]\n\n // .filter(edge => edge.target !== edge.source && visited.has(edge.source) && visited.has(edge.target))\n .filter(edge => edge.target !== edge.source)\n .forEach(edge => elementPositionEdges.push(edge));\n }\n\n // проверяем вертикаль вниз от позиции\n for (let i = position[0]; i <= grid.rowCount; i++) {\n const point = [ i, position[1] ];\n const crossedOrOccupied = elementPositionEdges.some(edge => {\n return (grid.getTargetPosition(edge)[0] === i && grid.getTargetPosition(edge)[1] === position[1]) || grid.isIntersect(edge, point, false) || grid.isIntersect(edge, point, true);\n });\n\n if (crossedOrOccupied && i === grid.colCount - 1) {\n position[0] = i + 1;\n continue;\n }\n\n if (crossedOrOccupied) continue;\n position[0] = i;\n break;\n }\n\n // todo: убрать на после вставки?\n // обрабатываем занятость и вертикальные пересечения\n if (grid.get(position[0], position[1]) || grid.isCrossed(position, true)) {\n grid.addRowCol(true, position[1] - 1);\n }\n\n if (grid.isCrossed([ position[0], position[1] ])) {\n\n // todo: возможно стоит посмотреть по направлениям\n grid.addRowCol(false, position[0] - 1);\n }\n return position;\n}\n\n// только для тех что впереди\n// /**\n// * @param element\n// * @param grid\n// * @param {[Element]=} stack\n// * @param {[Element]=} nextElements\n// * @param {boolean} skipTopLeftOutgoing\n// * @param {boolean} forwardOnlyOutgoing\n// */\nfunction fixNewCrosses(element, grid, stack, nextElements, skipTopLeftOutgoing) {\n\n // реверс логики переноса вперед для исходящих\n // исправляем пересечения образованные исходящими и входящими ребрами новой вершины\n // получаем исходящие\n const outgoingEdges = [ ...grid.getExistingOutgoingEdgesFor(element) ]\n .sort((a, b) => {\n const [ aRow, aCol ] = grid.getTargetPosition(a);\n const [ bRow, bCol ] = grid.getTargetPosition(b);\n return aRow - bRow || aCol - bCol;\n });\n const incomingEdges = [ ...grid.getExistingIncomingEdgesFor(element) ]\n .sort((a, b) => {\n const [ aRow, aCol ] = grid.getSourcePosition(a);\n const [ bRow, bCol ] = grid.getSourcePosition(b);\n return aRow - bRow || aCol - bCol;\n });\n\n const edges = [ ...outgoingEdges, ...incomingEdges ]\n .filter(edge => {\n const { target, source } = edge;\n const direction = grid.getEdgeDirection(edge);\n\n // не обрабатываем следующие случаи\n // если self loop\n if (target === source) return false;\n\n // если в обработке текущей очереди исходящих\n if (nextElements && nextElements.includes(target)) return false;\n\n // если таргет в стеке и у него нет существующих исходящих если передали стек\n if (stack) {\n\n if (inStackWithoutOutgoing(target, stack, grid)) return false;\n }\n if (skipTopLeftOutgoing) {\n\n // TODO: Пока непонятно надо ли как то обрабатывать стек?\n if (source === element && (direction === 'SE_NW' || direction === 'S_N')) return false;\n }\n\n return true;\n });\n\n for (const edge of edges) {\n\n // исправляем вертикали\n fixNewVerticalCrosses(edge, grid);\n\n // не исправляем гризонтали если E_W из boundary\n if (grid.getEdgeDirection(edge) === 'E_W' && ((grid.getEdgeSource(edge)).$type === 'bpmn:BoundaryEvent' && edge.id)) continue;\n fixNewHorizontalCrosses(edge, grid);\n }\n}\n\n// TODO: Add tests for boundary edges\nfunction fixNewVerticalCrosses(edge, grid) {\n\n // заготовка по направлениям\n // S_N - нет, так как не предполагается схемой\n // SW_NE\n // W_E - нет вертикали\n // NW_SE\n // N_S\n // NE_SW\n // E_W - нет вертикали\n // SE_NW\n\n const direction = grid.getEdgeDirection(edge);\n\n if (direction === 'W_E' || direction === 'E_W') return;\n\n const vCrossed = grid.getCrossedElementsFor(edge, true).map(item => [ ...item ]).flat().filter(item => item.$type !== 'bpmn:Lane');\n\n if (vCrossed.length <= 0) return;\n\n if (direction === 'S_N') {\n moveElementsRighterCrossLine(vCrossed, grid);\n return;\n }\n\n if (direction === 'SW_NE') {\n\n // требуется дополнительное условие?\n // пока сдвигаем вертикаль\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n if (direction === 'NW_SE') {\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n if (direction === 'N_S') {\n moveElementsRighterCrossLine(vCrossed, grid);\n return;\n }\n\n if (direction === 'NE_SW') {\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n if (direction === 'SE_NW') {\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n}\n\n// TODO: Add tests for boundary edges\n// возможно добавить потом наличие ребер\nfunction fixNewHorizontalCrosses(edge, grid) {\n\n // заготовка по направлениям\n const direction = grid.getEdgeDirection(edge);\n\n // по этим направлениям не предполагается горизонтальных пересечений\n if (direction === 'S_N' || direction === 'N_S') return;\n\n const hCrossed = grid.getCrossedElementsFor(edge, false).map(item => [ ...item ]).flat().filter(item => item.$type !== 'bpmn:Lane');\n\n if (hCrossed.length === 0) return;\n\n if (direction === 'SW_NE') {\n\n // поднимаем элементы выше пересечения\n const maxDown = getMaxDown(edge, grid);\n const [ baseSourceRow ] = grid.getSourcePosition(edge);\n grid.addRowCol(false, baseSourceRow - 1, maxDown);\n\n const elements = grid.getElementsInRange({ row: grid.getSourcePosition(edge)[0], col: grid.getSourcePosition(edge)[1] + 1 }, { row: grid.rowCount - 1, col: grid.colCount - 1 }).filter(item => item.$type !== 'bpmn:Lane');\n\n for (const element of elements) {\n const [ row, col ] = grid.find(element);\n for (const innerElement of [ ...grid.get(row, col) ]) {\n grid.move(innerElement, [ row - maxDown, col ]);\n }\n }\n return;\n }\n\n if (direction === 'W_E') {\n\n // опускаем элементы\n moveElementsUnderCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'NW_SE') {\n moveElementsUpperCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'NE_SW') {\n moveElementsUpperCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'E_W') {\n\n // опускаем элементы\n moveElementsUnderCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'SE_NW') {\n moveElementsUpperCrossLine(hCrossed, grid);\n return;\n }\n}\n\nfunction moveElementsUpperCrossLine(elements, grid) {\n\n // пробуем поднимать элементы выше пересечения\n const [ row ] = grid.find(elements[0]);\n grid.addRowCol(false, row - 1);\n for (const element of elements) {\n const [ , col ] = grid.find(element);\n grid.move(element, [ row , col ]);\n }\n}\n\nfunction moveElementsUnderCrossLine(elements, grid) {\n\n // пробуем опускать элементы ниже пересечения\n const [ row ] = grid.find(elements[0]);\n grid.addRowCol(false, row);\n for (const element of elements) {\n const [ , col ] = grid.find(element);\n grid.move(element, [ row + 1 , col ]);\n }\n}\n\n// TODO: проверить\nfunction moveElementsRighterCrossLine(elements, grid) {\n\n // TODO: костыльчик чтобы запустилось\n const [ , col ] = grid.find(elements[0]);\n grid.addRowCol(true, col);\n\n for (const element of elements) {\n const [ elRow ] = grid.find(element);\n grid.move(element, [ elRow, col + 1 ]);\n }\n}\n\n/**\n * All crossed on one column\n * @param elements\n * @param grid\n */\nfunction pushVerticalEdgeBy(elements, grid) {\n const [ , col ] = grid.find(elements[0]);\n grid.addRowCol(true, col - 1);\n\n for (const element of elements) {\n const [ row ] = grid.find(element);\n grid.move(element, [ row, col ]);\n }\n}\n\n// Todo: сделать для всех направлений, а не только для SW_NE и сделать методы в гриде\nfunction getMaxDown(edge, grid) {\n const sourcePosition = grid.getSourcePosition(edge);\n const targetPosition = grid.getTargetPosition(edge);\n\n let maxDown = sourcePosition[0];\n\n for (let rowIndex = sourcePosition[0]; rowIndex < grid.rowCount; rowIndex++) {\n if (grid.getElementsInRange({ row: rowIndex, col: sourcePosition[1] + 1 }, { row: rowIndex, col: targetPosition[1] }).length > 0) {\n maxDown++;\n } else {\n break;\n }\n }\n\n return maxDown - sourcePosition[0];\n}\n","import {\n connectElements,\n} from '../utils/layoutUtils.js';\n\nexport default function createConnection(edge, layoutGrid, diFactory, shift) {\n const { id } = edge;\n\n // todo: пока костыль для отрисовки только тех, которые с id\n if (id) {\n const waypoints = connectElements(edge, layoutGrid, shift);\n return diFactory.createDiEdge(edge, waypoints, {\n id: id + '_di'\n });\n }\n}\n","import { getBounds } from '../utils/layoutUtils.js';\nimport { getOutgoingElements } from '../utils/elementUtils.js';\nimport { is } from '../di/DiUtil.js';\n\nexport default function createElementDi(element, elementPosition, diFactory, grid, shift, laneLevelDif) {\n if (element.di) return [];\n\n if (element.$type === 'bpmn:BoundaryEvent') {\n return createBEl(element, elementPosition, diFactory, grid, shift);\n }\n\n if (element.$type === 'bpmn:Lane') {\n elementPosition[2] = grid.colCount;\n }\n\n const bounds = getBounds(element, elementPosition, shift, laneLevelDif);\n\n const options = {\n id: element.id + '_di'\n };\n\n if (element.isExpanded) {\n options.isExpanded = true;\n }\n\n if (is(element, 'bpmn:ExclusiveGateway')) {\n options.isMarkerVisible = true;\n }\n\n const shapeDi = diFactory.createDiShape(element, bounds, options);\n element.di = shapeDi;\n return [ shapeDi ];\n}\n\nfunction createBEl(element, elementPosition, diFactory, grid, shift) {\n const host = element.attachedToRef;\n const hostPosition = grid.find(host);\n\n const hostBounds = getBounds(host, hostPosition, shift);\n if (!hostBounds) throw new Error(`Create DI for ${element.id}. Nо hostBounds`);\n const DIs = [];\n\n // получаем соседние boundary\n // первыми должны отрисовываться те, у которых потомки ниже и правей\n let neighboursBoundary = element.$parent.flowElements.filter(item => item.attachedToRef === element.attachedToRef && grid.hasElement(element));\n neighboursBoundary = getSortedElementsByOutgoingPosition(neighboursBoundary, grid);\n neighboursBoundary.forEach((att, i, arr) => {\n const bounds = getBounds(att, elementPosition, shift);\n\n // distribute along lower edge\n bounds.x = hostBounds.x + (i + 1) * (hostBounds.width / (arr.length + 1)) - bounds.width / 2;\n bounds.y = hostBounds.y + hostBounds.height - bounds.height / 2;\n\n const attacherDi = diFactory.createDiShape(att, bounds, {\n id: att.id + '_di'\n });\n att.di = attacherDi;\n\n DIs.push(attacherDi);\n });\n return DIs;\n}\n\n// Первыми идут те у которых исходящие ниже\nfunction getSortedElementsByOutgoingPosition(elements, grid) {\n return elements.sort((a, b) => {\n const aBottomRightChildPosition = getPositionRightBottomOutgoingElement(a, grid);\n const bBottomRightChildPosition = getPositionRightBottomOutgoingElement(b, grid);\n\n return aBottomRightChildPosition[0] - bBottomRightChildPosition[0] || aBottomRightChildPosition[1] - bBottomRightChildPosition[1];\n }).reverse();\n}\n\nfunction getPositionRightBottomOutgoingElement(element, grid) {\n return getOutgoingElements(element).reduce((prev, cur) => {\n if (!grid.hasElement(cur)) return prev;\n const curPosition = grid.find(cur);\n if (prev[0] < curPosition[0] || prev[1] < curPosition[1]) return curPosition;\n return prev;\n }, [ 0 ,0 ]);\n}","export class Edge {\n constructor(source, target) {\n this.source = source;\n this.target = target;\n }\n}","import BPMNModdle from 'bpmn-moddle';\nimport { Graph } from 'graph-by-ivan-tulaev';\n\n// todo: настроить сборщик resolve js\nimport {\n isStartIntermediate,\n setAdditionalPropsToElements, getAllProcesses,\n} from './utils/elementUtils.js';\n\nimport {\n DEFAULT_CELL_HEIGHT,\n DEFAULT_CELL_WIDTH,\n DEFAULT_POOL_MARGIN,\n sortByType,\n} from './utils/layoutUtils.js';\nimport { DiFactory } from './di/DiFactory.js';\nimport { is, getDefaultSize } from './di/DiUtil.js';\nimport { GridWithEdges } from './GridWithEdges.js';\nimport { elementExecution } from './newHandlers/outgoingHandler.js';\nimport createConnection from './newHandlers/createConnection.js';\nimport createElementDi from './newHandlers/createElementDi.js';\nimport { Edge } from './Edge.js';\n\n\n/**\n * @typedef {Object} BPMNElement\n * @property {boolean} isExpanded - is expanded or collapsed\n * @property {Array<BPMNElement>} attachers - prop for host element\n */\n\n\nexport class Layouter {\n constructor(debuggerCounter) {\n this.moddle = new BPMNModdle();\n this.diFactory = new DiFactory(this.moddle);\n this.maxDebugStep = debuggerCounter;\n this.currentDebugStep = 0;\n }\n\n async layoutProcess(xml) {\n const moddleObj = await this.moddle.fromXML(xml);\n\n const { rootElement } = moddleObj;\n\n // init important properties\n this.diagram = rootElement;\n\n // todo: убрать лишний параметр\n setAdditionalPropsToElements(moddleObj, this.getLanesNestedSet);\n\n // init process trees as nested sets\n // add nested set properties to process (left, right, level)\n this.processTrees = this.createNestedSets(moddleObj);\n\n // create and add grids for each process\n // root processes should be processed last for element expanding\n this.createGridsForProcesses();\n\n // expand grids\n this.expandProcessesGrids();\n\n // expand procsses with lanes\n this.expandParticipants();\n\n // get all process from root\n const rootProcesses = this.getRootProcesses();\n const collaboration = this.getCollaboration();\n\n if (rootProcesses.length > 0) {\n this.cleanDi();\n this.createRootDi(rootProcesses, collaboration);\n this.drawParticipants();\n this.drawProcesses();\n this.drawCollaborationMessageFlows(collaboration);\n }\n\n return (await this.moddle.toXML(this.diagram, { format: true })).xml;\n }\n\n expandParticipants() {\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n\n for (const process of processes) {\n const lanes = process.grid.getLanes();\n for (const lane of lanes || []) {\n const lanePos = process.grid.find(lane);\n process.grid.addRowCol(false, lanePos[0] + lanePos[3] - 1, 1);\n lanePos[3] += 1;\n }\n }\n }\n\n createGridsForProcesses() {\n\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n processes.sort((a, b) => a.level - b.level);\n\n // create and add grids for each process\n for (const process of processes) {\n\n const hasLanes = (process.laneSets || [])[0]?.lanes.length > 0;\n\n // add base grid with collapsed elements\n process.grid = this.createGridLayout(process);\n\n // separate base grid to independent grids\n // todo: временно костыляем\n const tempGridCollection = hasLanes ? [ process.grid ] : (process.grid._separateGrid() || [ process.grid ]);\n\n // for each independent grid:\n // - remove empty rows and cols\n // - shake elements by vertical and horizontal\n // todo: временно костыляем\n for (const grid of tempGridCollection) {\n grid.shrink(true);\n grid.shrink(false);\n\n grid.shakeIt(true);\n grid.shakeIt(false);\n\n // todo: временно костыляем\n }\n\n // merge separated grids and set new grid to the process\n // todo: временно костыляем\n if (!hasLanes) {\n process.grid = process.grid._mergeGrids(tempGridCollection);\n }\n }\n }\n\n expandProcessesGrids() {\n\n // root processes should be processed last for element expanding\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n processes.sort((a, b) => b.level - a.level);\n\n for (const process of processes) {\n\n // separate base grid to independent grids\n // todo: временно костыляем\n const hasLanes = (process.laneSets || [])[0]?.lanes.length > 0;\n const tempGridCollection = hasLanes ? [ process.grid ] : (process.grid._separateGrid() || [ process.grid ]);\n for (const grid of tempGridCollection) {\n grid.shrink(true);\n grid.shrink(false);\n\n expandGrid(grid, false);\n expandGrid(grid, true);\n }\n\n // merge separated grids and set new grid to the process\n // todo: временно костыляем\n if (!hasLanes) {\n process.grid = process.grid._mergeGrids(tempGridCollection);\n }\n }\n }\n\n /**\n * draw participants pools at root\n */\n drawParticipants() {\n const collaboration = this.getCollaboration();\n\n if (!collaboration || !collaboration[0]) return;\n const participants = collaboration[0].participants;\n\n const x = 0;\n let y = 0;\n\n for (const participant of participants) {\n y = this.createParticipantDi(participant, { x, y }) + DEFAULT_POOL_MARGIN;\n }\n }\n\n /**\n * Draw processes.\n * Root processes should be processed first for element expanding\n */\n drawProcesses() {\n\n const sortedProcesses = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n sortedProcesses.sort((a, b) => a.level - b.level);\n\n for (const process of sortedProcesses) {\n\n // draw root processes in participants\n const participant = this.getParticipantForProcess(process);\n\n if (participant) {\n const participantDi = this.getElementDi(participant);\n const diagram = this.getProcDi(participantDi);\n\n let { x, y } = participantDi.bounds;\n x += DEFAULT_CELL_WIDTH / 2;\n y += DEFAULT_CELL_HEIGHT / 2;\n this.generateDi(process, { x, y }, diagram);\n continue;\n }\n\n // draw processes in expanded elements\n // todo: сделать понятнее для this.maxDebugStep\n if (process.isExpanded && !this.existingNodes.includes(process)) continue;\n if (process.isExpanded) {\n const baseProcDi = this.getElementDi(process);\n const diagram = this.getProcDi(baseProcDi);\n let { x, y } = baseProcDi.bounds;\n const { width, height } = getDefaultSize(process);\n x += DEFAULT_CELL_WIDTH / 2 - width / 4;\n y += DEFAULT_CELL_HEIGHT - height - height / 4;\n this.generateDi(process, { x, y }, diagram);\n continue;\n }\n\n // draw other processes\n const diagram = this.diagram.diagrams.find(diagram => diagram.plane.bpmnElement === process);\n this.generateDi(process, { x: 0, y: 0 }, diagram);\n }\n }\n\n get existingNodes() {\n return this.processTrees.map(graph => [ ...graph.nodes ]).flat().map(item => [ ...item.grid.elements ]).flat();\n }\n\n drawCollaborationMessageFlows(collaboration) {\n const messageFlows = collaboration[0] ? collaboration[0].messageFlows : null;\n if (messageFlows) {\n for (const message of messageFlows) {\n const { sourceRef, targetRef } = message;\n\n // todo: debug mode сделать презентабельнее\n const existNodes = this.existingNodes;\n if (!existNodes.includes(sourceRef) || !existNodes.includes(targetRef)) continue;\n\n const sourceBounds = sourceRef.di.bounds;\n const targetBounds = targetRef.di.bounds;\n const dY = targetBounds.y - sourceBounds.y;\n const waypoints = [\n { x: sourceBounds.x + sourceBounds.width / 2 },\n { x: targetBounds.x + targetBounds.width / 2 }\n ];\n\n if (dY > 0) {\n waypoints[0].y = sourceBounds.y + sourceBounds.height;\n waypoints[1].y = targetBounds.y;\n } else {\n waypoints[0].y = sourceBounds.y;\n waypoints[1].y = targetBounds.y + targetBounds.height;\n }\n\n const edge = this.diFactory.createDiEdge(message, waypoints);\n this.diagram.diagrams[0].plane.get('planeElement').push(edge);\n }\n }\n }\n\n getParticipantForProcess(process) {\n const collaboration = this.getCollaboration();\n if (!collaboration || !collaboration[0]) return;\n const participants = this.getCollaboration()[0].participants;\n\n if (!participants) return;\n\n return participants.find(participant => participant.processRef === process);\n }\n\n getElementDi(element) {\n return this.diagram.diagrams\n .map(diagram => diagram.plane.planeElement).flat()\n .find(item => item.bpmnElement === element);\n }\n\n getProcDi(element) {\n return this.diagram.diagrams.find(diagram => diagram.plane.planeElement.includes(element));\n }\n\n createNestedSets(bpmnModel) {\n const processGraph = new Graph();\n const allProcesses = getAllProcesses(bpmnModel);\n\n // add nodes to graph\n for (const process of allProcesses) {\n processGraph.addNode(process);\n }\n\n // add edges\n for (const process of allProcesses) {\n const children = this.getSubProcesses(process);\n for (const child of children) {\n processGraph.addEdge({ source: process, target: child });\n }\n }\n\n const separatedGraphs = processGraph.getSeparatedGraphs();\n\n // set root process to tree\n for (const graph of separatedGraphs) {\n const rootProcesses = graph.nodes.filter(node => graph.getIncomingEdgesFor(node).size === 0);\n\n // must have 1 root process\n if (rootProcesses.length > 1) throw new Error('Process tree has more than 1 root elements');\n if (rootProcesses.length === 0) throw new Error('Process tree has more than 0 root elements');\n\n graph.rootProcess = rootProcesses[0];\n }\n\n // set nested sets attributes\n for (const graph of separatedGraphs) {\n\n // callback that get start node from process tree\n // it's root process\n const getStartElement = (visited, initialGraph) => {\n const root = initialGraph.rootProcess;\n\n root.left = 0;\n root.level = 0;\n\n return root;\n };\n\n // callback that get next executed nodes\n // it's first node without left prop if we go from root,\n // or without right prop if we go to root\n const getNextNodes = (node, graph) => {\n\n const { left, level } = node;\n\n // get first node without left prop\n const outgoingNode = [ ...graph.getOutgoingEdgesFor(node) ]\n .map(edge => edge.target)\n .find(node => node.left === undefined);\n\n if (outgoingNode) {\n outgoingNode.level = level + 1;\n outgoingNode.left = left + 1;\n return [ outgoingNode ];\n }\n\n // if no outgoingNode get max right\n const maxRight = [ ...graph.getOutgoingEdgesFor(node) ]\n .map(edge => edge.target)\n .reduce((prev, cur) => {\n return prev === undefined || cur.right > prev.right ? cur.right : prev;\n } , undefined);\n\n if (maxRight) {\n node.right = maxRight + 1;\n } else {\n node.right = node.left + 1;\n }\n\n // get incoming\n const incoming = [ ...graph.getIncomingEdgesFor(node) ]\n .map(edge => edge.source)\n .find(node => node.right === undefined);\n\n if (incoming) return [ incoming ];\n };\n graph.genericTraversing(getNextNodes, getStartElement);\n }\n\n return separatedGraphs;\n }\n\n getSubProcesses(processes) {\n return processes.flowElements ? processes.flowElements.filter(process => process.$type === 'bpmn:SubProcess') : [];\n }\n\n createRootDi(processes, collaboration) {\n\n const mainElement = collaboration && collaboration.length > 0 ? collaboration[0] : processes[0];\n this.createProcessDi(mainElement);\n }\n\n createProcessDi(element) {\n const diFactory = this.diFactory;\n\n const planeDi = diFactory.createDiPlane({\n id: 'BPMNPlane_' + element.id,\n bpmnElement: element\n });\n const diagramDi = diFactory.createDiDiagram({\n id: 'BPMNDiagram_' + element.id,\n plane: planeDi\n });\n\n const diagram = this.diagram;\n\n diagram.diagrams.push(diagramDi);\n\n return diagramDi;\n }\n\n /**\n * Create participant diagram\n * @param participant\n * @param {{x: number, y: number}} origin\n * @returns {number} bottom Y coordinate of created shape\n */\n createParticipantDi(participant, origin) {\n\n // get size of child process element\n const { colCount, rowCount } = participant.processRef.grid;\n\n const { width: defaultWidth, height: defaultHeight } = getDefaultSize(participant);\n\n\n // Result size is children grid size + paddings ( 1/2 of width or height)\n // let width = colCount > 0 ? colCount * DEFAULT_CELL_WIDTH + DEFAULT_CELL_WIDTH : defaultWidth;\n let width = colCount > 0 ? colCount * DEFAULT_CELL_WIDTH + DEFAULT_CELL_WIDTH : defaultWidth;\n\n let height = defaultHeight;\n if (participant.processRef.grid.getLanes().length > 0) {\n height = rowCount * DEFAULT_CELL_HEIGHT;\n\n const lanesNested = this.getLanesNestedSet(participant.processRef);\n const maxLevel = [ ...lanesNested ].reduce((prev, [ , nestPos ]) => {\n return prev < nestPos.level ? nestPos.level : prev;\n },0);\n\n const labelWidth = 30;\n width = width + maxLevel * labelWidth;\n } else {\n height = rowCount > 0 ? rowCount * DEFAULT_CELL_HEIGHT + DEFAULT_CELL_HEIGHT : defaultHeight;\n }\n\n const participantDi = this.diFactory.createDiShape(participant, { width, height, ...origin }, { id: participant.id + '_di' });\n\n const planeDi = this.diagram.diagrams[0].plane.get('planeElement');\n\n planeDi.push(...[ participantDi ]);\n\n return participantDi.bounds.y + participantDi.bounds.height;\n }\n\n cleanDi() {\n this.diagram.diagrams = [];\n }\n\n getLanesNestedSet(process) {\n const resultNestedSet = new Map(); // left, right, level\n const stack = [ ...process.laneSets ? process.laneSets[0].lanes : [] ].reverse();\n stack.forEach(lane => {\n resultNestedSet.set(lane, { level: 0 });\n });\n\n while (stack.length > 0) {\n const curLane = stack.pop();\n const curPosition = resultNestedSet.get(curLane);\n if (curPosition.left === undefined) {\n const maxRight = [ ...resultNestedSet.values() ].reduce((prev, cur) => {\n return cur.right > prev || prev === undefined ? cur.right : prev;\n }, undefined);\n curPosition.left = maxRight !== undefined ? maxRight + 1 : 0;\n }\n if (curPosition.right === undefined) {\n stack.push(curLane);\n const subLanes = (curLane.childLaneSet?.lanes || []).filter(item => resultNestedSet.get(item)?.level === undefined);\n if (subLanes.length === 0) {\n let maxRight = [ ...resultNestedSet.values() ].reduce((prev, cur) => {\n return cur.right > prev || prev === undefined ? cur.right : prev;\n }, undefined);\n if (maxRight === undefined) maxRight = [ ...resultNestedSet.values() ].reduce((prev, cur) => {\n return cur.left > prev || prev === undefined ? cur.left : prev;\n }, undefined);\n if (curPosition.left > maxRight) maxRight = curPosition.left;\n curPosition.right = maxRight + 1;\n }\n [ ...subLanes ].reverse().forEach((subLane, index, arr) => {\n stack.push(subLane);\n const subPosition = index === arr.length - 1 ? { level: curPosition.level + 1, left: curPosition.left + 1 } : { level: curPosition.level + 1 };\n resultNestedSet.set(subLane, subPosition);\n });\n }\n }\n\n return resultNestedSet;\n }\n\n createGridLayout(process) {\n\n // create graph from elements\n const processGraph = new Graph();\n const grid = new GridWithEdges(processGraph);\n\n // add lanes\n const lanes = [ ...this.getLanesNestedSet(process) ]\n .filter(([ , position ]) => position.right - position.left === 1)\n .sort(([ ,aPosition ], [ ,bPosition ]) => aPosition.left - bPosition.left).map(([ lane ]) => lane);\n for (const lane of lanes) {\n grid.add(lane);\n grid.find(lane)[3] = 1;\n }\n\n // add nodes\n for (const flowElement of process.flowElements || []) {\n\n if (!is(flowElement,'bpmn:SequenceFlow') && !is(flowElement,'bpmn:DataObject')) {\n processGraph.addNode(flowElement);\n }\n }\n\n // add edges\n // todo: переписать компактней\n for (const node of processGraph.nodes) {\n\n // boundary\n // добавляем два ребра, так как у нас направленный граф\n if (node.$type === 'bpmn:BoundaryEvent') {\n processGraph.addEdge(new Edge(node, node.attachedToRef));\n processGraph.addEdge(new Edge(node.attachedToRef, node));\n }\n\n // sequenceFlow\n for (const outgoingItem of node.outgoing || []) {\n const newEdge = new Edge(outgoingItem.sourceRef, outgoingItem.targetRef);\n newEdge.id = outgoingItem.id;\n processGraph.addEdge(newEdge);\n }\n\n // data associations - двигаемся от связанной ноды\n const dataInputAssociations = node.dataInputAssociations;\n for (const association of dataInputAssociations || []) {\n for (const dataSource of association.sourceRef || []) {\n const newEdge = new Edge(dataSource, association.$parent);\n newEdge.id = association.id;\n newEdge.propRef = association.targetRef;\n processGraph.addEdge(newEdge);\n }\n }\n\n const dataOutputAssociations = node.dataOutputAssociations;\n for (const association of dataOutputAssociations || []) {\n const source = association.$parent;\n const target = association.targetRef;\n const newEdge = new Edge(source, target);\n newEdge.id = association.id;\n processGraph.addEdge(newEdge);\n }\n }\n\n // export type GetStartElementFunction<N> = (visited: Set<N>, initialGraph: Graph<N>)\n const dfsGetStartElement = (visited, initialGraph) => {\n if (this.maxDebugStep !== undefined && this.maxDebugStep <= this.currentDebugStep) return;\n\n // get elements in the grid that have incoming that are not in grid\n const targetElementInGridSourceNotExist = [ ...visited ].find(node => {\n const incomingEdges = !grid.isFlipped ? [ ...initialGraph.getIncomingEdgesFor(node) ] : [ ...initialGraph.getOutgoingEdgesFor(node) ];\n return incomingEdges.filter(edge => !visited.has(!grid.isFlipped ? edge.source : edge.target)).length > 0;\n });\n if (targetElementInGridSourceNotExist) {\n grid.flip(false);\n\n return targetElementInGridSourceNotExist;\n }\n\n // maybe need boundaryEvents processing here\n const primaryStartElements = initialGraph.nodes.filter(node => {\n const incomingEdges = !grid.isFlipped ? initialGraph.getIncomingEdgesFor(node) : initialGraph.getOutgoingEdgesFor(node);\n return !visited.has(node) && incomingEdges.size === 0 && !isStartIntermediate(node);\n });\n if (primaryStartElements.length > 0) return sortByType(primaryStartElements, 'bpmn:StartEvent')[0];\n\n const sourceElementInGridTargetNotExist = [ ...visited ].find(node => {\n\n // todo: добавить сортировку sortElementsTopLeftBottomRight?\n const outgoing = !grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ];\n return outgoing.filter(edge => !visited.has(!grid.isFlipped ? edge.target : edge.source)).length > 0;\n });\n if (sourceElementInGridTargetNotExist) return sourceElementInGridTargetNotExist;\n\n // All elements without incoming from other elements\n // this case as the very last one\n const otherStartingElement = initialGraph.nodes.find(node => {\n if (visited.has(node)) return false;\n\n // incoming without Loops\n const incoming = !grid.isFlipped ? [ ...initialGraph.getIncomingEdgesFor(node) ] : [ ...initialGraph.getOutgoingEdgesFor(node) ];\n return incoming.filter(edge => node !== (!grid.isFlipped ? edge.source : edge.target)).length === 0;\n });\n if (otherStartingElement) return otherStartingElement;\n\n const flippedStartElement = initialGraph.nodes.find(node => {\n\n if (visited.has(node)) return false;\n\n let outgoingEdges = (!grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ]).filter(edge => edge.target !== edge.source);\n\n return outgoingEdges.length === 0;\n });\n\n if (flippedStartElement) {\n grid.flip(false);\n return flippedStartElement;\n }\n this.currentDebugStep += 1;\n\n // not traversed elements (restElements)\n return initialGraph.nodes.find(node => !visited.has(node));\n };\n\n // GetNextNodesFunction<N> = (node: N, graph: Graph<N>, visited: Set<N>) => Array<N> | undefined\n const dfsGetNextNodes = (node, graph, visited, executionSequence) => {\n if (this.maxDebugStep !== undefined && this.maxDebugStep <= this.currentDebugStep) return;\n\n // основная обработка\n const nextElements = elementExecution(node, grid, executionSequence, visited, graph);\n\n this.currentDebugStep += 1;\n return nextElements;\n };\n\n processGraph.genericTraversing(\n dfsGetNextNodes,\n dfsGetStartElement,\n );\n\n // flip grid on end\n if (grid.isFlipped) {\n grid.flip(false);\n }\n\n return grid;\n }\n\n generateDi(process , shift, procDi) {\n const { grid: layoutGrid } = process;\n\n const diFactory = this.diFactory;\n\n const prePlaneElement = procDi ? procDi : this.diagram.diagrams[0];\n\n const planeElement = prePlaneElement.plane.get('planeElement');\n\n // todo: убрать после нормальной реализации отрисовки\n const flowElsDIs = [];\n\n // Step 0: Create DI for lanes\n const lanes = [ ...this.getLanesNestedSet(process) ].sort(([ , aPos ], [ , bPos ]) => bPos.level - aPos.level);\n const lanesMaxLevel = lanes.reduce((prev, [ , itemPos ]) => {\n return itemPos.level > prev ? itemPos.level : prev;\n }, 0);\n\n lanes.forEach(([ lane, pos ]) => {\n const curShift = { ...shift };\n const poolLabelWidth = 30;\n const xAdd = (pos.level) * poolLabelWidth;\n curShift.x += xAdd;\n const leaves = lanes.filter(([ item, itemPos ]) => {\n return itemPos.left > pos.left && itemPos.right < pos.right && itemPos.right - itemPos.left === 1;\n });\n if (leaves.length === 0) leaves.push([ lane, pos ]);\n\n const [ y, x ] = leaves.reduce((prev, [ curLeave ]) => {\n const curGridPos = layoutGrid.find(curLeave);\n return prev === undefined || curGridPos[0] < prev[0] ? curGridPos : prev;\n }, undefined);\n\n let width = layoutGrid.colCount > 0 ? layoutGrid.colCount + 1 : 2;\n\n // const leaveMaxLevel = leaves.reduce((prev, [ , leavePos]) => {\n // return leavePos.level > prev ? leavePos.level : prev;\n // }, 0)\n const levelDif = lanesMaxLevel - pos.level;\n\n // width += (lanesMaxLevel - selfLevel) * poolLabelWidth;\n\n let height = leaves.reduce((prev, [ curLeave ]) => {\n const curGridPos = layoutGrid.find(curLeave);\n return prev + (curGridPos[3] || 2);\n }, 0);\n\n\n // todo: убрать лишний параметр пока для теста так\n const dis = createElementDi(lane, [ y, x, width, height ], diFactory, layoutGrid, curShift, levelDif);\n flowElsDIs.push(...dis);\n\n });\n\n const lanesPos = this.getLanesNestedSet(process).values();\n const maxLevel = [ ...lanesPos ].reduce((prev, cur) => {\n return cur.level > prev ? cur.level : prev;\n }, 0);\n\n const labelWidth = 30;\n const elXShift = maxLevel * labelWidth;\n\n // Step 1: Create DI for all elements\n [ ...layoutGrid._elements ].filter(([ item ]) => item.$type !== 'bpmn:Lane').forEach(([ element, elementPosition ]) => {\n\n const curShift = { ...shift };\n curShift.x += elXShift;\n const dis = createElementDi(element, elementPosition, diFactory, layoutGrid, curShift);\n flowElsDIs.push(...dis);\n });\n\n // Step 2: Create DI for all connections\n layoutGrid._allEdges.forEach(edge => {\n const curShift = { ...shift };\n curShift.x += elXShift;\n const connection = createConnection(edge, layoutGrid, diFactory, curShift);\n if (connection) flowElsDIs.push(connection);\n });\n\n // todo: убрать после нормальной реализации отрисовки\n // Пока сортируем для стабильности результата\n this.sortDIsByDefinitionPosition(flowElsDIs, process).forEach(item => planeElement.push(item));\n }\n\n sortDIsByDefinitionPosition(DIs, process) {\n return DIs.sort((a, b) => {\n const aIndex = process.flowElements?.findIndex(item => item.id === a.bpmnElement.id);\n const bIndex = process.flowElements?.findIndex(item => item.id === b.bpmnElement.id);\n return aIndex - bIndex;\n });\n }\n\n getRootProcesses() {\n return this.diagram.get('rootElements').filter(el => el.$type === 'bpmn:Process');\n }\n\n getCollaboration() {\n return this.diagram.get('rootElements').filter(el => el.$type === 'bpmn:Collaboration');\n }\n}\n\n/**\n * Check grid by columns or rows.\n * If it has elements with isExpanded === true,\n * find the maximum size of elements grids and expand the parent grid horizontally or vertically.\n * @param grid\n * @param {boolean=} byVertical\n */\nfunction expandGrid(grid, byVertical) {\n\n // todo: здесь можно оптимизировать добавив строки и колонки в грид\n const indexesToExpand = new Map();\n const elementsToExpand = new Set();\n\n Object.entries(!byVertical ? grid.cols : grid.rows).forEach(([ index, elements ]) => {\n elements.forEach(element => {\n if (element.isExpanded) {\n elementsToExpand.add(element);\n const maxCount = indexesToExpand.get(Number.parseInt(index));\n const [ rowCount, colCount ] = element.grid.getGridDimensions();\n let curCount = !byVertical ? colCount : rowCount;\n if (!curCount) {\n curCount = 1;\n }\n if (maxCount === undefined || curCount > maxCount) {\n indexesToExpand.set(Number.parseInt(index), curCount);\n }\n }\n });\n });\n\n [ ...indexesToExpand.entries() ].sort(([ aKey ],[ bKey ]) => bKey - aKey).forEach(([ key, value ]) => {\n\n // расширяем лэйны\n if (byVertical) {\n const lanes = grid.getLanes();\n for (const lane of lanes) {\n const lanePos = grid.find(lane);\n if (Number.parseInt(key) <= lanePos[0] + lanePos[3] - 1 && Number.parseInt(key) >= lanePos[0]) {\n lanePos[3] += Number.parseInt(value);\n }\n }\n }\n\n grid.addRowCol(!byVertical, key, value);\n });\n\n elementsToExpand.forEach((value) => {\n const position = grid.find(value);\n const [ row, col ] = value.grid.getGridDimensions();\n if (!byVertical) {\n (position[2] = col < 1 ? 2 : col + 1);\n } else {\n (position[3] = row < 1 ? 2 : row + 1);\n }\n });\n}\n","import { Layouter } from './Layouter.js';\n\nexport function layoutProcess(xml, debuggerCounter) {\n return new Layouter(debuggerCounter).layoutProcess(xml);\n}\n"],"names":["getDefaultSize","element","is","width","height","type","$instanceOf","getOutgoingElements","Error","outgoingElements","outgoing","map","out","targetRef","Set","DEFAULT_CELL_WIDTH","DEFAULT_CELL_HEIGHT","isFlipped","utilsGetOutgoingElements","concat","attachedOutgoing","attachers","sort","a","b","length","attacher","reverse","flat","filter","item","index","self","indexOf","add","getAttachedOutgoingElements","getMid","bounds","x","y","getDockingPoint","point","rectangle","dockingDirection","targetOrientation","test","original","coordinatesToPosition","grid","shift","row","col","find","getBounds","elementPosition","laneLevelDif","positionWidth","positionHeight","defaultWidth","defaultHeight","$type","participantLabelWidth","DiFactory","constructor","moddle","this","create","attrs","createDiBounds","createDiLabel","createDiShape","semantic","assign","bpmnElement","createDiWaypoints","waypoints","pos","createDiWaypoint","pick","createDiEdge","waypoint","createDiPlane","createDiDiagram","Grid","_elements","Map","rows","cols","rowCount","Object","keys","colCount","elementsCount","size","elements","position","has","JSON","stringify","_addStart","lastRow","lastCol","rowDif","colDif","addRowCol","undefined","set","_addElementToRowsCols","get","_removeElementFromRowsCols","delete","getGridDimensions","move","toPosition","isValidPosition","removeElement","addCol","afterIndex","count","gridCount","addCount","i","entries","expandRow","rowIndex","Number","isInteger","gridColCount","forEach","elementsAtPosition","getElementsInRange","startRow","startCol","endRow","endCol","shrink","byVertical","sortedElements","previousIndex","newElPos","key","value","flip","hasElement","Array","isArray","hasIntermediateElements","firstPosition","lastPosition","onVertical","start","end","values","some","hasElementAt","GridWithEdges","initialGraph","super","graph","Graph","getLanes","addNode","_createNewEdgesFor","lanePosition","laneRef","firstLaneRow","lastLaneRow","elementsInRow","deleteNode","_edgeIsExist","edge","edges","includes","_addEdgeToGrid","addEdge","getOutgoingEdgesFor","getIncomingEdgesFor","source","target","isCrossed","_allEdges","isIntersect","hasAnyCross","getCrossedElementsFor","shakeIt","aPos","bPos","sortColsLeftRightRowsBottomTop","pop","chain","getChain","chainElement","deleteIndex","splice","baseRow","baseCol","allPositionsAreFine","every","curPos","newPositionsAreFine","checkedRow","checkedCol","chainElementPosition","hasNewCrosses","newChain","oldChain","elInPos","el","getAllExistingEdgesFor","edgeDirection","getEdgeDirection","push","nextElement","nextChain","nextChainEl","getExistingOutgoingEdgesFor","getExistingIncomingEdgesFor","outgoingEdges","incomingEdges","_separateGrid","separatedGraphs","mergeGraphs","getSeparatedGraphs","grids","minRow","maxRow","node","nodes","_mergeGrids","newGrid","rowShift","parseInt","newPosition","getSourcePosition","getEdgeSource","getTargetPosition","getEdgeTarget","sourcePosition","targetPosition","id","sourceRow","sourceCol","targetRow","targetCol","vDifference","hDifference","getPathFor","direction","_pathForNoDirection","_pathForSouthToNorth","_pathForSouthWestToNorthEast","_pathForWestToEast","_pathForNorthWestToSouthEast","_pathForNorthToSouth","_pathForNorthEastToSouthWest","_pathForEastToWest","_pathForSouthEastToNorthWest","pathSegments","vCross","colIndex","hCross","crossedElements","segment","getBackwardUpOutgoingEdgesFor","getGridCopy","removeEdge","deleteEdge","getGraphSegmentFrom","genericTraversing","visited","executionSequence","nextEdges","nextNodes","getSegmentLeftCoordinates","leftCoordinates","nodeRow","nodeCol","elementExecution","newOutgoing","outgoingFromStack","hasNewOutgoings","incoming","elementCol","processingElements","inStackWithoutOutgoing","targetEdge","targetParent","sortElementsTopLeftBottomRight","processingElement","getOutgoingFromStack","nextElements","nextPosition","getInsertPosition","attachedToRef","fixNewCrosses","unshift","existingEdges","workingEdge","sourcePos","targetPos","gridCopy","graphSegment","segmentCords","from","minColPosition","reduce","acc","cur","minRowPosition","maxRowPosition","newMap","previousShiftPos","shiftPos","nodePosition","getShiftPos","moveTopLeftOutgoingForward","nextBoundaries","nextOther","inStack","nextEl","isBoundarySource","elementLane","nextElLane","elementLaneRow","nextElLaneRow","nextElLaneHeight","laneRowPosDif","elPos","allItemsInElementPosition","elementPositionEdges","crossedOrOccupied","stack","skipTopLeftOutgoing","aRow","aCol","bRow","bCol","fixNewVerticalCrosses","fixNewHorizontalCrosses","vCrossed","pushVerticalEdgeBy","moveElementsRighterCrossLine","hCrossed","maxDown","getMaxDown","baseSourceRow","innerElement","moveElementsUpperCrossLine","moveElementsUnderCrossLine","elRow","createConnection","layoutGrid","diFactory","sourceDi","di","targetDi","sourceBounds","targetBounds","sourceMid","targetMid","sourceHeight","dX","dY","dockingSource","dockingTarget","sourceX","sourceY","targetX","targetY","sourceIsBoundary","isExpanded","firstPoint","lastPoint","maxExpanded","firstCol","getMaxExpandedBetween","hasReversEdge","hasSW_NEOut","elementsInHorizontal","candidate","directManhattan","totalElements","bendPoint","directManhattanConnect","startPoint","endPoint","yOffset","Math","sign","connectElements","createElementDi","host","hostPosition","hostBounds","DIs","neighboursBoundary","$parent","flowElements","aBottomRightChildPosition","getPositionRightBottomOutgoingElement","bBottomRightChildPosition","getSortedElementsByOutgoingPosition","att","arr","attacherDi","createBEl","options","isMarkerVisible","shapeDi","prev","curPosition","Edge","Layouter","debuggerCounter","BPMNModdle","maxDebugStep","currentDebugStep","layoutProcess","xml","moddleObj","fromXML","rootElement","diagram","bpmnModel","allElements","elementsById","lanes","processRef","itemPos","right","left","lane","flowNodeRef","setAdditionalPropsToElements","getLanesNestedSet","processTrees","createNestedSets","createGridsForProcesses","expandProcessesGrids","expandParticipants","rootProcesses","getRootProcesses","collaboration","getCollaboration","cleanDi","createRootDi","drawParticipants","drawProcesses","drawCollaborationMessageFlows","toXML","format","processes","process","lanePos","level","hasLanes","laneSets","createGridLayout","tempGridCollection","expandGrid","participants","participant","createParticipantDi","sortedProcesses","getParticipantForProcess","participantDi","getElementDi","getProcDi","generateDi","existingNodes","baseProcDi","diagrams","plane","messageFlows","message","sourceRef","existNodes","planeElement","processGraph","allProcesses","getAllProcesses","children","getSubProcesses","child","rootProcess","getStartElement","root","getNextNodes","outgoingNode","maxRight","mainElement","createProcessDi","planeDi","diagramDi","origin","nestPos","resultNestedSet","curLane","subLanes","childLaneSet","subLane","subPosition","aPosition","bPosition","flowElement","outgoingItem","newEdge","dataInputAssociations","association","dataSource","propRef","dataOutputAssociations","targetElementInGridSourceNotExist","primaryStartElements","types","typesArray","result","matching","sortByType","sourceElementInGridTargetNotExist","otherStartingElement","flippedStartElement","procDi","flowElsDIs","lanesMaxLevel","curShift","xAdd","leaves","curLeave","curGridPos","levelDif","dis","elXShift","connection","sortDIsByDefinitionPosition","aIndex","findIndex","bIndex","indexesToExpand","elementsToExpand","maxCount","curCount","aKey","bKey","exports"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../lib/di/DiUtil.js","../lib/utils/elementUtils.js","../lib/utils/layoutUtils.js","../lib/di/DiFactory.js","../lib/Grid.js","../lib/GridWithEdges.js","../lib/newHandlers/outgoingHandler.js","../lib/newHandlers/createConnection.js","../lib/newHandlers/createElementDi.js","../lib/Edge.js","../lib/NestedSet.js","../lib/Layouter.js","../lib/index.js"],"sourcesContent":["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 { is } from '../di/DiUtil.js';\n\nexport function isConnection(element) {\n return !!element.sourceRef;\n}\n\nexport function isBoundaryEvent(element) {\n return !!element.attachedToRef;\n}\n\nexport function getOutgoingElements(element) {\n if (!element) throw new Error('Element is not defined in getOutgoingElements');\n const outgoingElements = (element.outgoing || []).map(out => out.targetRef);\n\n // возвращаем уникальные, так как BPMN может быть не валидным\n return [ ...new Set(outgoingElements) ];\n}\n\nexport function getIncomingElements(element) {\n if (!element) throw new Error('Element is not defined in getIncomingElements');\n let incomingElements = (element.incoming || []).map(out => out.sourceRef);\n\n // возвращаем уникальные, так как BPMN может быть не валидным\n return [ ...new Set(incomingElements) ];\n}\n\nexport function getAttachedOutgoingElements(element) {\n const outgoing = new Set();\n if (element) {\n const attachedOutgoing = (element.attachers || [])\n .sort((a,b) => {\n const bOutCount = b.outgoing ? b.outgoing.length : 0;\n const aOutCount = a.outgoing ? a.outgoing.length : 0;\n return bOutCount - aOutCount;\n })\n .map(attacher => (attacher.outgoing || []).reverse())\n .flat()\n .map(out => out.targetRef)\n .filter((item, index, self) => self.indexOf(item) === index);\n for (const out of attachedOutgoing) {\n outgoing.add(out);\n }\n }\n\n return [ ...outgoing ];\n}\n\nexport function isStartIntermediate(element) {\n return (is(element, 'bpmn:IntermediateThrowEvent') || is(element, 'bpmn:IntermediateCatchEvent'))\n && (element.incoming === undefined || element.incoming.length === 0);\n}\n\nexport function bindBoundaryEventsWithHosts(elements) {\n const boundaryEvents = elements.filter(element => isBoundaryEvent(element));\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\nexport function getAllProcesses(bpmnModel) {\n const allElements = bpmnModel.elementsById;\n if (!allElements) return [];\n return Object.values(allElements).filter(element => element.$type === 'bpmn:Process' || element.$type === 'bpmn:SubProcess');\n}\n\n// /**\n// * Set expanded property to element from its diagram\n// * @param bpmnModel\n// */\nexport function setAdditionalPropsToElements(bpmnModel, getLanes) {\n const allElements = bpmnModel.elementsById;\n if (allElements) {\n for (const element of Object.values(allElements)) {\n\n // mark expanded processes\n if (element.$type === 'bpmndi:BPMNShape' && element.isExpanded === true) element.bpmnElement.isExpanded = true;\n\n // mark lane indexes\n // todo: добавить очередность как она есть в DI, если есть\n if (element.$type === 'bpmn:Participant') {\n const lanes = getLanes(element.processRef).getLeaves().map(([ item ]) => item);\n if (lanes) {\n lanes.forEach((lane) => {\n const nodes = lane.flowNodeRef;\n if (nodes) {\n nodes.forEach(node => node.laneRef = lane);\n }\n });\n }\n }\n }\n }\n}\n","import { getDefaultSize, is } from '../di/DiUtil.js';\n\nimport {\n getAttachedOutgoingElements,\n getIncomingElements as utilsGetIncomingElements,\n getOutgoingElements as utilsGetOutgoingElements,\n} from './elementUtils.js';\n\nexport const DEFAULT_CELL_WIDTH = 150;\nexport const DEFAULT_CELL_HEIGHT = 140;\nexport const DEFAULT_POOL_MARGIN = DEFAULT_CELL_HEIGHT / 2;\nexport const PARTICIPANT_LABEL_WIDTH = 30;\n\nexport function getOutgoingElements(element, isFlipped) {\n return !isFlipped ? new Set (utilsGetOutgoingElements(element).concat(getAttachedOutgoingElements(element))) : new Set (utilsGetIncomingElements(element));\n}\n\n/**\n * Modified Manhattan layout: Uses space between grid columns to route connections\n * if direct connection is not possible.\n * @param edge\n * @param layoutGrid\n * @param shift\n * @returns waypoints\n */\nexport function connectElements(edge, layoutGrid, shift) {\n\n const { source, target } = edge;\n\n // TODO: Use GridController for Drawing\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 [ sourceRow, sourceCol, sourceHeight = 1 ] = layoutGrid.find(source);\n const [ targetRow, targetCol ] = layoutGrid.find(target);\n\n // todo: убрать dX ???\n const edgeDirection = layoutGrid.getEdgeDirection(edge);\n const dX = targetCol - sourceCol;\n const dY = targetRow - sourceRow;\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 const { x: sourceX, y: sourceY } = coordinatesToPosition(source, layoutGrid, shift);\n const { x: targetX, y: targetY } = coordinatesToPosition(target, layoutGrid, shift);\n\n const sourceIsBoundary = source.$type === 'bpmn:BoundaryEvent';\n\n // Source === Target ==> Build loop\n if (edgeDirection === 'NO_DIRECTION') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetX, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: sourceX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: sourceY + sourceHeight * DEFAULT_CELL_HEIGHT },\n { x: targetX, y: sourceY + sourceHeight * DEFAULT_CELL_HEIGHT },\n { x: sourceX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n }\n\n // 12 часов\n if (edgeDirection === 'S_N') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: sourceX, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n\n // пока так по колхозному\n const hasReversEdge = [ ...getOutgoingElements(target) ].includes(source);\n\n if (hasReversEdge) {\n\n // идем в обход\n return [\n getDockingPoint(sourceMid, sourceBounds, 'l', dockingSource),\n { x: sourceX, y: sourceMid.y },\n { x: targetX, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l', dockingTarget)\n ];\n } else {\n return [\n getDockingPoint(sourceMid, sourceBounds, 't', dockingSource),\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n }\n }\n\n // 1 час\n if (edgeDirection === 'SW_NE') {\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n\n return [\n getDockingPoint(sourceMid, sourceBounds, 'r'),\n { x: targetMid.x, y: sourceMid.y },\n getDockingPoint(targetMid, targetBounds, 'b')\n ];\n }\n\n // 3\n if (edgeDirection === 'W_E') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'r', dockingSource);\n if (source.isExpanded) {\n firstPoint.y = sourceY + DEFAULT_CELL_HEIGHT / 2;\n }\n const lastPoint = getDockingPoint(targetMid, targetBounds, 'l', dockingTarget);\n if (target.isExpanded) {\n lastPoint.y = targetY + DEFAULT_CELL_HEIGHT / 2;\n }\n return [\n firstPoint,\n lastPoint\n ];\n }\n\n // 4 час\n if (edgeDirection === 'NW_SE') {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'l')\n ];\n }\n\n // 6\n if (edgeDirection === 'N_S') {\n if (sourceIsBoundary) {\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource);\n const lastPoint = getDockingPoint(targetMid, targetBounds, 't', dockingTarget);\n\n if (source.attachedToRef.isExpanded) {\n return [\n firstPoint,\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n lastPoint\n ];\n }\n\n return [\n firstPoint,\n lastPoint\n ];\n }\n\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource);\n const lastPoint = getDockingPoint(targetMid, targetBounds, 't', dockingTarget);\n\n if (source.isExpanded || target.isExpanded) {\n return [\n firstPoint,\n { x: sourceMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n lastPoint\n ];\n }\n return [\n firstPoint,\n lastPoint\n ];\n }\n\n // 7 часов\n if (edgeDirection === 'NE_SW') {\n\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'r')\n ];\n\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b'),\n { x: sourceMid.x, y: targetMid.y },\n getDockingPoint(targetMid, targetBounds, 'r')\n ];\n }\n\n // 9 часов\n if (edgeDirection === 'E_W') {\n const maxExpanded = getMaxExpandedBetween(source, target, layoutGrid);\n\n // пока так по колхозному\n const hasReversEdge = utilsGetOutgoingElements(target).includes(source);\n\n // TODO: Remove by new edge drawing logic\n let hasSW_NEOut = layoutGrid.getExistingOutgoingEdgesFor(target)\n .some(item => layoutGrid.getEdgeDirection(item) === 'SW_NE');\n\n if (sourceIsBoundary || hasReversEdge || hasSW_NEOut) {\n\n // идем в обход\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: sourceY + DEFAULT_CELL_HEIGHT + (maxExpanded ? maxExpanded - 1 : 0) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: sourceY + DEFAULT_CELL_HEIGHT + (maxExpanded ? maxExpanded - 1 : 0) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n } else {\n const firstPoint = getDockingPoint(sourceMid, sourceBounds, 'l', dockingSource);\n if (source.isExpanded) {\n firstPoint.y = sourceY + DEFAULT_CELL_HEIGHT / 2;\n }\n const lastPoint = getDockingPoint(targetMid, targetBounds, 'r', dockingTarget);\n if (target.isExpanded) {\n lastPoint.y = targetY + DEFAULT_CELL_HEIGHT / 2;\n }\n return [\n firstPoint,\n lastPoint\n ];\n }\n }\n\n // negative dX indicates connection from future to past\n // 10 часов\n if (edgeDirection === 'SE_NW') {\n if (sourceIsBoundary) return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.attachedToRef.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.attachedToRef.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n\n // колхоз\n const elementsInHorizontal = [];\n for (let col = sourceCol - 1; col >= targetCol; col--) {\n const candidate = layoutGrid ? layoutGrid.get(sourceRow, col) : null;\n if (candidate) elementsInHorizontal.push(candidate);\n }\n if (elementsInHorizontal.length > 0) {\n\n // идем в обход\n return [\n getDockingPoint(sourceMid, sourceBounds, 'b', dockingSource),\n { x: sourceMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n { x: targetMid.x, y: !source.isExpanded ? sourceY + DEFAULT_CELL_HEIGHT : sourceY + (source.grid.rowCount + 1) * DEFAULT_CELL_HEIGHT },\n getDockingPoint(targetMid, targetBounds, 'b', dockingTarget)\n ];\n } else {\n return [\n getDockingPoint(sourceMid, sourceBounds, 'l'),\n { x: targetMid.x, y: sourceMid.y },\n getDockingPoint(targetMid, targetBounds, 'b')\n ];\n }\n }\n\n // на будущее если не сработает что-то сверху\n const directManhattan = directManhattanConnect(source, target, layoutGrid);\n\n if (directManhattan) {\n const startPoint = getDockingPoint(sourceMid, sourceBounds, directManhattan[0], dockingSource);\n const endPoint = getDockingPoint(targetMid, targetBounds, directManhattan[1], dockingTarget);\n\n const midPoint = directManhattan[0] === 'h' ? { x: endPoint.x, y: startPoint.y } : { x: startPoint.x, y: endPoint.y };\n\n return [\n startPoint,\n midPoint,\n endPoint\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\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 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// helpers /////\nexport function coordinatesToPosition(element, grid, shift = { x: 0, y:0 }) {\n const [ row, col ] = grid.find(element);\n\n return {\n x: col * DEFAULT_CELL_WIDTH + shift.x,\n y: row * DEFAULT_CELL_HEIGHT + shift.y\n };\n}\n\nexport function getBounds(element, elementPosition, shift, laneLevelDif) {\n const [ row, col, positionWidth, positionHeight ] = elementPosition;\n const { width: defaultWidth, height: defaultHeight } = getDefaultSize(element);\n\n let width = ((!positionWidth ? 1 : positionWidth) - 1) * DEFAULT_CELL_WIDTH + defaultWidth;\n let height = ((!positionHeight ? 1 : positionHeight) - 1) * DEFAULT_CELL_HEIGHT + defaultHeight;\n let x = col * DEFAULT_CELL_WIDTH + (DEFAULT_CELL_WIDTH - defaultWidth) / 2 + shift.x;\n let y = row * DEFAULT_CELL_HEIGHT + (DEFAULT_CELL_HEIGHT - defaultHeight) / 2 + shift.y;\n\n // todo: сделать универсально\n if (element.$type === 'bpmn:Lane') {\n width = (positionWidth || 1) * DEFAULT_CELL_WIDTH + DEFAULT_CELL_WIDTH + (laneLevelDif - 1) * PARTICIPANT_LABEL_WIDTH;\n x = col * DEFAULT_CELL_WIDTH + shift.x - DEFAULT_CELL_WIDTH / 2 + PARTICIPANT_LABEL_WIDTH;\n y = row * DEFAULT_CELL_HEIGHT + shift.y - DEFAULT_CELL_HEIGHT / 2;\n height = (positionHeight || 1) * DEFAULT_CELL_HEIGHT;\n }\n\n return {\n width,\n height,\n x,\n y\n };\n}\n\n// TODO: for future\n// eslint-disable-next-line no-unused-vars\nfunction isDirectPathBlocked(source, target, layoutGrid) {\n const [ sourceRow, sourceCol ] = layoutGrid.find(source);\n const [ targetRow, targetCol ] = layoutGrid.find(target);\n\n const dX = targetCol - sourceCol;\n const dY = targetRow - sourceRow;\n\n let totalElements = 0;\n\n if (dX) {\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: sourceCol }, { row: sourceRow, col: targetCol }).length;\n }\n\n if (dY) {\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: targetCol }, { row: targetRow, col: targetCol }).length;\n }\n\n return totalElements > 2;\n}\n\nfunction directManhattanConnect(source, target, layoutGrid) {\n const [ sourceRow, sourceCol ] = layoutGrid.find(source);\n const [ targetRow, targetCol ] = layoutGrid.find(target);\n\n const dX = targetCol - sourceCol;\n const dY = targetRow - sourceRow;\n\n // Only directly connect left-to-right flow\n if (!(dX > 0 && dY !== 0)) {\n return;\n }\n\n // If below, go down then horizontal\n if (dY > 0) {\n let totalElements = 0;\n const bendPoint = { row: targetRow, col: sourceCol };\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: sourceCol }, bendPoint).length;\n totalElements += layoutGrid.getElementsInRange(bendPoint, { row: targetRow, col: targetCol }).length;\n\n return totalElements > 2 ? false : [ 'v', 'h' ];\n } else {\n\n // If above, go horizontal than vertical\n let totalElements = 0;\n const bendPoint = { row: sourceRow, col: targetCol };\n\n totalElements += layoutGrid.getElementsInRange({ row: sourceRow, col: sourceCol }, bendPoint).length;\n totalElements += layoutGrid.getElementsInRange(bendPoint, { row: targetRow, col: targetCol }).length;\n\n return totalElements > 2 ? false : [ 'h', 'v' ];\n }\n}\n\nexport function sortElementsTopLeftBottomRight(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n return aPos[0] - bPos[0] || aPos[1] - bPos[1];\n };\n}\n\nexport function sortElementsTopRightBottomLeft(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n return aPos[0] - bPos[0] || bPos[1] - aPos[1];\n };\n}\n\nexport function sortColsLeftRightRowsBottomTop(grid) {\n return function(a, b) {\n const aPos = grid.find(a);\n const bPos = grid.find(b);\n\n return aPos[1] - bPos[1] || bPos[0] - aPos[0];\n };\n}\n\n/**\n *\n * @param {*[]} arr array of BPMN elements\n * @param {string|string[]} types array of types\n * @returns {*[]} sorted array of BPMN elements\n */\nexport function sortByType(arr, types) {\n const typesArray = [ types ].flat();\n\n let result = [];\n\n if (typesArray.length > 0) {\n typesArray.forEach((type,index) => {\n const matching = arr.filter(item => is(item, type));\n result = result.concat(matching);\n if (index === typesArray.length - 1 && result.length !== arr.length) {\n for (const item of arr) {\n if (!result.includes(item)) result.push(item);\n }\n }\n });\n } else {\n result = arr;\n }\n\n return result;\n}\n\nfunction getMaxExpandedBetween(source, target, layoutGrid) {\n const [ sourceRow, sourceCol ] = layoutGrid.find(source);\n const [ , targetCol ] = layoutGrid.find(target);\n\n const firstCol = sourceCol < targetCol ? sourceCol : targetCol;\n const lastCol = sourceCol < targetCol ? targetCol : sourceCol;\n\n return [ ...layoutGrid.rows[sourceRow] ].reduce((prev, item) => {\n const [ , col, , height ] = layoutGrid.find(item);\n return col >= firstCol && col <= lastCol && height > prev ? height : prev;\n }, 0);\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}\n","export class Grid {\n constructor() {\n this.isFlipped = false;\n this._elements = new Map();\n this.rows = {};\n this.cols = {};\n }\n\n get rowCount() {\n return Object.keys(this.rows).length;\n }\n\n get colCount() {\n return Object.keys(this.cols).length;\n }\n\n get elementsCount() {\n return this._elements.size;\n }\n\n get elements() {\n return new Set (this._elements.keys());\n }\n\n /**\n *\n * @param element\n * @param {[number, number]} position - numbers are integer\n */\n add(element, position) {\n\n if (this._elements.has(element)) throw new Error(`Cannot add duplicated element ${JSON.stringify(element)}`);\n\n if (!position) {\n this._addStart(element);\n return;\n }\n\n const lastRow = this.rowCount - 1;\n const lastCol = this.colCount - 1;\n\n const rowDif = position[0] - lastRow;\n const colDif = position[1] - lastCol;\n this.addRowCol(false, lastRow >= 0 ? lastRow : undefined, rowDif);\n this.addRowCol(true, lastCol >= 0 ? lastCol : undefined, colDif);\n\n this._elements.set(element, position);\n this._addElementToRowsCols(element, position);\n }\n\n _addElementToRowsCols(element) {\n const position = this._elements.get(element);\n this.rows[position[0]] ? this.rows[position[0]].add(element) : this.rows[position[0]] = new Set([ element ]);\n this.cols[position[1]] ? this.cols[position[1]].add(element) : this.cols[position[1]] = new Set([ element ]);\n }\n _removeElementFromRowsCols(element) {\n const position = this._elements.get(element);\n if (this.rows[position[0]]) this.rows[position[0]].delete(element);\n if (this.cols[position[1]]) this.cols[position[1]].delete(element);\n }\n\n _addStart(element) {\n const [ row, ] = this.getGridDimensions();\n this._elements.set(element, [ row, 0 ]);\n this._addElementToRowsCols(element, [ row, 0 ]);\n }\n\n move(element, toPosition) {\n if (!this.elements.has(element)) throw new Error(`Cannot move not exist element ${JSON.stringify(element)}`);\n if (!this.isValidPosition(toPosition)) throw new Error(`Cannot move element ${JSON.stringify(element)} to invalid position ${toPosition}`);\n const newPos = [ ...toPosition ];\n this._removeElementFromRowsCols(element);\n this._elements.set(element, newPos);\n this._addElementToRowsCols(element);\n }\n\n removeElement(element) {\n if (this._elements.has(element)) {\n this._removeElementFromRowsCols(element);\n this._elements.delete(element);\n }\n }\n\n addRowCol(addCol, afterIndex, count = 1) {\n\n // добавляем линии\n const gridCount = addCol ? this.colCount : this.rowCount;\n const addCount = afterIndex >= gridCount - 1 ? afterIndex - (gridCount - 1) + count : count;\n for (let i = 0; i < addCount; i++) {\n if (addCol) {\n this.cols[gridCount + i] = new Set();\n } else {\n this.rows[gridCount + i] = new Set();\n }\n }\n\n // перемещаем элементы\n for (const [ item, elementPosition ] of this._elements.entries()) {\n const position = addCol ? elementPosition[1] : elementPosition[0];\n\n if (position > afterIndex || afterIndex === undefined) {\n this._removeElementFromRowsCols(item);\n elementPosition[addCol ? 1 : 0] += count;\n this._addElementToRowsCols(item);\n }\n }\n }\n\n /**\n * Для добавления перед первым элементом afterIndex = undefined\n * @param {number} rowIndex - is positive integer\n * @param {number=} afterIndex - is integer\n * @param {number=} colCount - is positive integer\n */\n expandRow(rowIndex, afterIndex, colCount = 1) {\n\n if (!Number.isInteger(rowIndex) || rowIndex < 0 || rowIndex > this.rowCount - 1) throw new Error (`Can't expand row with index: ${rowIndex}. Grid row count is ${this.rowCount}`);\n\n // готовим строку\n const gridColCount = this.colCount;\n const addCount = afterIndex >= gridColCount - 1 ? afterIndex - (gridColCount - 1) + colCount : colCount;\n for (let i = 0; i < addCount; i++) {\n this.cols[gridColCount + i] = new Set();\n }\n\n // перемещаем элементы\n [ ...this.rows[rowIndex] ].forEach(item => {\n const position = this.find(item);\n if (position[1] > afterIndex || afterIndex === undefined) {\n this._removeElementFromRowsCols(item);\n position[1] += colCount;\n this._addElementToRowsCols(item);\n }\n });\n }\n\n /**\n * return position of element:\n * - [row: integer, col: integer] if element exist\n * - else undefined\n * @param element\n * @returns {number[] | undefined}\n */\n find(element) {\n return this._elements.get(element);\n }\n\n get(row, col) {\n\n // todo: make simple to read\n const elementsAtPosition = new Set ([ ...this._elements.entries() ].filter(([ item, position ]) => position[0] === row && position[1] === col)\n .map(item => item[0]));\n\n return elementsAtPosition.size ? elementsAtPosition : null;\n }\n\n getElementsInRange({ row: startRow, col: startCol }, { row: endRow, col: endCol }) {\n\n if (startRow > endRow) {\n [ startRow, endRow ] = [ endRow, startRow ];\n }\n\n if (startCol > endCol) {\n [ startCol, endCol ] = [ endCol, startCol ];\n }\n\n return [ ...this._elements.entries() ]\n .filter(([ , position ]) => position[0] >= startRow && position[0] <= endRow && position[1] >= startCol && position[1] <= endCol)\n .map(item => item[0]);\n }\n\n getGridDimensions() {\n const rows = this.rowCount;\n const cols = this.colCount;\n\n return [ rows, cols ];\n }\n\n // todo: переписать на строки\n shrink(byVertical) {\n\n // Отсортированный массив элементов по строкам или столбцам\n const sortedElements = [ ...this._elements.entries() ]\n .sort((a, b) => {\n const aPosition = !byVertical ? a[1][1] : a[1][0];\n const bPosition = !byVertical ? b[1][1] : b[1][0];\n return aPosition - bPosition;\n });\n\n // актуальный индекс = 0\n // смещение = 0\n let shift = 0;\n let previousIndex = null;\n\n for (const element of sortedElements) {\n\n // У элемента берём позицию\n const position = !byVertical ? element[1][1] : element[1][0];\n this._removeElementFromRowsCols(element[0]);\n\n if (previousIndex === null) {\n shift = position;\n } else if (previousIndex !== position) {\n shift = shift + position - previousIndex - 1;\n }\n\n previousIndex = position;\n\n const newElPos = [ ...element[1] ];\n if (!byVertical) {\n newElPos[1] -= shift;\n } else {\n newElPos[0] -= shift;\n }\n this._elements.set(element[0], newElPos);\n\n this._addElementToRowsCols(element[0]);\n }\n\n // todo: пока не смотрим на размер элементов, а просто удаляем пустые строки\n // Здесь уже все сдвинуты\n for (const [ key, value ] of Object.entries(!byVertical ? this.cols : this.rows)) {\n if (value.size === 0) {\n if (!byVertical) {\n delete this.cols[key];\n } else {\n delete this.rows[key];\n }\n }\n }\n\n }\n\n flip(byVertical) {\n\n // Получить измерения\n const [ rowCount, colCount ] = this.getGridDimensions();\n\n // Для каждой позиции\n // - измерение - 1 - позиция\n for (const [ element, position ] of this._elements.entries()) {\n const newPosition = [ ...position ];\n this._removeElementFromRowsCols(element);\n if (!byVertical) {\n newPosition[1] = colCount - 1 - newPosition[1];\n } else {\n newPosition[0] = rowCount - 1 - newPosition[0];\n }\n this._elements.set(element, newPosition);\n this._addElementToRowsCols(element);\n }\n\n // todo: add directional flip flag\n this.isFlipped = !this.isFlipped;\n }\n\n hasElement(element) {\n return this.elements.has(element);\n }\n\n isValidPosition(position) {\n if (!position || !Array.isArray(position)) return false;\n const [ row, col ] = position;\n return Number.isInteger(row) && Number.isInteger(col) && row >= 0 && col >= 0;\n }\n\n hasIntermediateElements(firstPosition, lastPosition, onVertical) {\n if (!this.isValidPosition(firstPosition) || !this.isValidPosition(lastPosition)) return false;\n if (!onVertical ? firstPosition[0] !== lastPosition[0] : firstPosition[1] !== lastPosition[1]) return false;\n\n const index = !onVertical ? firstPosition[1] : firstPosition[0];\n const [ start, end ] = !onVertical ? (firstPosition[1] <= lastPosition[1] ? [ firstPosition[1] , lastPosition[1] ] : [ lastPosition[1], firstPosition[1] ]) : (firstPosition[0] <= lastPosition[0] ? [ firstPosition[0] , lastPosition[0] ] : [ lastPosition[0], firstPosition[0] ]);\n return [ ...this._elements.values() ].some(item => !onVertical ? item[0] === index && item[1] > start && item[1] < end : item[1] === index && item[0] > start && item[0] < end);\n }\n\n hasElementAt(position) {\n if (!this.isValidPosition(position)) return false;\n const [ row, col ] = position;\n const element = this.get(row, col);\n return !!element;\n }\n}","import { Graph } from 'graph-by-ivan-tulaev';\n\nimport { Grid } from './Grid.js';\n\nimport {\n sortColsLeftRightRowsBottomTop, sortElementsTopRightBottomLeft,\n} from './utils/layoutUtils.js';\n\n\n/**\n * @typedef {[number, number]} Position\n * numbers must be integer\n */\n\n/**\n * @typedef {{position: Position, vCross: boolean, hCross: boolean}} PathSegment\n */\n\nexport class GridWithEdges extends Grid {\n constructor(initialGraph) {\n super();\n\n this.initialGraph = initialGraph;\n this.graph = new Graph();\n }\n\n getLanes() {\n return [ ...this.elements ].filter(element => element.$type === 'bpmn:Lane');\n }\n\n /**\n *\n * @param element\n * @param {[number, number]=} position - numbers are integer\n */\n add(element, position) {\n\n // добавляем lanes\n if (element.$type === 'bpmn:Lane') {\n super.add(element, position);\n return;\n }\n\n // обычное добавление элементов если lanes нет\n const lanes = this.getLanes();\n if (lanes.length === 0) {\n super.add(element, position);\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n return;\n }\n\n // добавляем элементы в lanes\n const lanePosition = this.find(element.laneRef);\n if (!position) {\n\n // получаем первую пустую строку в пределах lane и помещаем элемент туда\n const firstLaneRow = lanePosition[0];\n const lastLaneRow = lanePosition[0] + (lanePosition[3] || 1) - 1;\n for (let rowIndex = firstLaneRow; rowIndex <= lastLaneRow; rowIndex++) {\n const elementsInRow = new Set (this.rows[rowIndex]);\n elementsInRow.delete(element.laneRef);\n if (elementsInRow.size === 0) {\n\n // здесь вставляем и тормозим\n super.add(element, [ rowIndex, 0 ]);\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n return;\n }\n }\n\n // если пробежались по всем строкам lane и не нашли пустую, то добавляем новую строку в lane\n this.addRowCol(false, lanePosition[0] + lanePosition[3] - 1);\n super.add(element, [ lanePosition[0] + lanePosition[3], 0 ]);\n lanePosition[3] += 1;\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n return;\n }\n\n const rowDif = position[0] + (position[3] || 1) - (lanePosition[0] + (lanePosition[3] || 1));\n if (rowDif > 0) {\n this.addRowCol(false, lanePosition[0] + (lanePosition[3] || 1) - 1, rowDif);\n lanePosition[3] = (lanePosition[3] || 1) + rowDif;\n }\n super.add(element, position);\n this.graph.addNode(element);\n this._createNewEdgesFor(element);\n }\n\n removeElement(element) {\n this.graph.deleteNode(element);\n\n super.removeElement(element);\n }\n\n /**\n * Проверка существования для НОВЫХ ребер\n * Со старыми только через мапу\n * @param edge\n * @returns {*}\n * @private\n */\n _edgeIsExist(edge) {\n return [ ...this.graph.edges ].includes(edge);\n }\n\n _addEdgeToGrid(edge) {\n if (!this._edgeIsExist(edge)) this.graph.addEdge(edge);\n }\n\n /**\n *\n * @param element element\n * @private\n */\n _createNewEdgesFor(element) {\n\n // todo: переписать под обертку\n const edges = [ ...this.initialGraph.getOutgoingEdgesFor(element), ...this.initialGraph.getIncomingEdgesFor(element) ]\n .filter(edge => this.hasElement(edge.source) && this.hasElement(edge.target));\n for (const edge of edges) {\n this._addEdgeToGrid(edge);\n }\n }\n\n /** @typedef {[number, number]} Position*/\n\n /**\n * @param {Position} position\n * @param {boolean=} byVertical\n * @returns {boolean}\n */\n isCrossed(position, byVertical = false) {\n\n return [ ...this._allEdges ].some(edge => this.isIntersect(edge, position, byVertical));\n }\n\n get _allEdges() {\n return this.graph.edges;\n }\n\n /**\n * Пока так наличие пересечений определим\n * @param {Edge[]=} edges\n * @returns {boolean}\n */\n hasAnyCross(edges) {\n const executedEdges = edges ? edges : this._allEdges;\n return [ ...executedEdges ].some(edge => {\n const hasHorizontalCross = this.getCrossedElementsFor(edge).filter(item => item.$type !== 'bpmn:Lane').length > 0;\n if (hasHorizontalCross) return true;\n\n const verticalCross = this.getCrossedElementsFor(edge, true).filter(item => item.$type !== 'bpmn:Lane').length > 0;\n if (verticalCross) return true;\n });\n }\n\n /**\n * Уплотняет грид по горизонтали или по вертикали\n * @param {boolean} byVertical\n */\n shakeIt(byVertical) {\n\n const sortedElements = [ ...this.elements ].filter(item => item.$type !== 'bpmn:Lane').sort(byVertical ? sortElementsTopRightBottomLeft(this) : sortColsLeftRightRowsBottomTop (this)).reverse();\n\n while (sortedElements.length > 0) {\n\n // работаем по первому элементу\n const element = sortedElements.pop();\n\n // получаем цепочку противоположную направлению уплотнения\n // удаляем из стека sortedElements все элементы из цепочки\n const chain = this.getChain(element, !byVertical);\n\n for (const chainElement of chain) {\n const deleteIndex = sortedElements.indexOf(chainElement);\n if (deleteIndex >= 0) {\n sortedElements.splice(deleteIndex, 1);\n }\n }\n\n // проверяем можно ли двинуть цепочку вверх для уплотнения по вертикали и влево для уплотнения по горизонтали\n // не одна из позиций не должна быть занята или иметь пересечения\n // - цепочка не должна удлиниться\n // todo: пока под вопросом для ребра из boundary не должны закручиваться\n const [ baseRow, baseCol ] = this.find([ ...chain ][0]);\n\n // двигаться не вариант если цепочка у края грида\n if (byVertical ? baseRow <= 0 : baseCol <= 0) continue;\n\n for (let index = byVertical ? baseRow - 1 : baseCol - 1 ; index >= 0; index--) {\n\n if (this.getLanes().length > 0 && byVertical) {\n const chainLane = [ ...chain ][0].laneRef;\n const [ laneRow, , , laneHeight = 1 ] = this.find(chainLane);\n if (index < laneRow || index > laneRow + laneHeight - 1) break;\n }\n\n\n\n // не двигаем если есть пересечения\n // todo: добавить оптимизации\n const allPositionsAreFine = [ ...chain ].every(element => {\n const curPos = this.find(element);\n\n return curPos && !this.isCrossed(curPos, true) && !this.isCrossed(curPos, false) ;\n });\n if (!allPositionsAreFine) break;\n\n // проверяем заняты ли новые позиции\n // todo: добавить оптимизации\n const newPositionsAreFine = [ ...chain ].every(element => {\n const curPos = this.find(element);\n const checkedRow = byVertical ? index : curPos[0];\n const checkedCol = byVertical ? curPos[1] : index;\n return !this.get(checkedRow, checkedCol);\n });\n if (!newPositionsAreFine) break;\n\n // пробно перемещаем все элементы из цепочки на новые места\n // пересечения позже всем скоупом проверим\n for (const chainElement of chain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, byVertical ? [ index, chainElementPosition[1] ] : [ chainElementPosition[0], index ]);\n }\n\n // проверяем не образовалось ли новых пересечений пока по старинке\n // и не удлинилась ли цепочка\n // todo: не пробегаться по всему гриду, а работать только по цепочке!!!\n const hasNewCrosses = this.hasAnyCross();\n const newChain = this.getChain(element, !byVertical);\n if (hasNewCrosses || newChain.size > chain.size) {\n\n // вертаем все элементы взад\n for (const chainElement of chain) {\n const chainElementPosition = this.find(chainElement);\n this.move(chainElement, byVertical ? [ index + 1 , chainElementPosition[1] ] : [ chainElementPosition[0], index + 1 ]);\n }\n break;\n }\n }\n\n // после каждого прохода удаляем пустые линии чтобы не ходить по пустым местам\n this.shrink(byVertical);\n }\n }\n\n /**\n * Возвращает горизонтальную или вертикальную последовательность элементов\n * @param {any} element BPMN Element\n * @param {boolean} byVertical\n * @param {Set<any>=}oldChain\n * @returns {Set<any>}\n */\n getChain(element, byVertical, oldChain) {\n const chain = !oldChain ? new Set() : oldChain;\n if (!element) return chain;\n\n const elementPosition = this.find(element);\n if (!elementPosition) return chain;\n\n const edges = [];\n\n // получаем все элементы в позиции\n const elInPos = [ ...this.get(elementPosition[0], elementPosition[1]) ].filter(item => item.$type !== 'bpmn:Lane');\n for (const el of elInPos) {\n chain.add(el);\n\n // todo: возможно стоит добавить другие варианты ребер - в себя - убрать undefined\n [ ...this.getAllExistingEdgesFor(el) ]\n .filter(edge => {\n const edgeDirection = this.getEdgeDirection(edge);\n return !byVertical ? (edgeDirection === 'W_E' || edgeDirection === 'E_W') : (edgeDirection === 'N_S' || edgeDirection === 'S_N');\n })\n .forEach(edge => edges.push(edge));\n }\n\n for (const edge of edges) {\n const nextElement = edge.source === element ? edge.target : edge.source;\n if (!chain.has(nextElement)) {\n const nextChain = this.getChain(nextElement, byVertical, chain);\n for (const nextChainEl of nextChain) {\n chain.add(nextChainEl);\n }\n }\n }\n return chain;\n }\n\n getExistingOutgoingEdgesFor(element) {\n return !this.isFlipped ? [ ...this.graph.getOutgoingEdgesFor(element) ] : [ ...this.graph.getIncomingEdgesFor(element) ];\n }\n\n getExistingIncomingEdgesFor(element) {\n return !this.isFlipped ? [ ...this.graph.getIncomingEdgesFor(element) ] : [ ...this.graph.getOutgoingEdgesFor(element) ];\n }\n\n getAllExistingEdgesFor(element) {\n const outgoingEdges = this.getExistingOutgoingEdgesFor(element);\n const incomingEdges = this.getExistingIncomingEdgesFor(element);\n return new Set([ ...outgoingEdges, ...incomingEdges ]);\n }\n\n _separateGrid() {\n\n // создаем копию графа\n const executedGraph = Graph.mergeGraphs(new Set([ this.graph ]));\n\n const separatedGraphs = executedGraph.getSeparatedGraphs();\n\n // todo: костыль для устранения проблемы после разделения пустого графа\n if (separatedGraphs.length === 0) return [ new GridWithEdges(this.initialGraph) ];\n\n // todo: добавить проверку на не пересечение\n const grids = [];\n\n for (const graph of separatedGraphs) {\n const grid = new GridWithEdges(this.initialGraph);\n\n let minRow = null;\n let maxRow = null;\n\n for (const node of graph.nodes) {\n const position = [ ...this.find(node) ];\n if (minRow === null || minRow > position[0]) minRow = position[0];\n if (maxRow === null || maxRow < position[0]) maxRow = position[0];\n grid.add(node, position);\n }\n\n grids.push(grid);\n }\n return grids;\n }\n\n _mergeGrids(grids) {\n const newGrid = new GridWithEdges(grids[0].initialGraph);\n\n grids.forEach(grid => {\n const [ resGridRowCount, resGridColCount ] = newGrid.getGridDimensions();\n const [ rowCount, colCount ] = grid.getGridDimensions();\n\n const colDif = colCount - resGridColCount;\n if (colDif > 0) newGrid.addRowCol(true, resGridColCount - 1, colDif);\n\n if (rowCount > 0) newGrid.addRowCol(false, resGridRowCount - 1, rowCount);\n\n for (const element of grid.elements) {\n const newPosition = [ ...grid.find(element) ];\n newPosition[0] = newPosition[0] + resGridRowCount;\n newGrid.add(element, newPosition);\n }\n });\n\n return newGrid;\n }\n\n getSourcePosition(edge) {\n const source = this.getEdgeSource(edge);\n return this.find(source);\n }\n\n getTargetPosition(edge) {\n const target = this.getEdgeTarget(edge);\n return this.find(target);\n }\n\n /**\n * @typedef {('S_N' | 'SW_NE' | 'W_E' | 'NW_SE' | 'N_S' | 'NE_SW' | 'E_W' | 'SE_NW' | 'NO_DIRECTION')} Direction\n * - **S_N** - south to north\n * - **SW_NE** - south-west to north-east\n * - **W_E** - west to east\n * - **NW_SE** - north-west to south-east\n * - **N_S** - north to south\n * - **NE_SW** - north-east to south-west\n * - **E_W** - east to west\n * - **SE_NW** - south-east to north-west\n * - **NO_DIRECTION** - if it's not a vector but a point\n */\n\n /**\n * @param edge\n * @returns {Direction}\n */\n getEdgeDirection(edge) {\n const sourcePosition = this.getSourcePosition(edge);\n const targetPosition = this.getTargetPosition(edge);\n\n if (!this.isValidPosition(sourcePosition) || !this.isValidPosition(targetPosition)) throw new Error(`Invalid position of source or target in ${edge.source.id}-${edge.target.id} flipped:${this.isFlipped}`);\n\n const [ sourceRow, sourceCol ] = sourcePosition;\n const [ targetRow, targetCol ] = targetPosition;\n\n const vDifference = sourceRow - targetRow;\n const hDifference = sourceCol - targetCol;\n\n // self\n if (vDifference === 0 && hDifference === 0) return 'NO_DIRECTION';\n\n // south to north\n if (vDifference > 0 && hDifference === 0) return 'S_N';\n\n // south-west to north-east\n if (vDifference > 0 && hDifference < 0) return 'SW_NE';\n\n // west to east\n if (vDifference === 0 && hDifference < 0) return 'W_E';\n\n // north-west to south-east\n if (vDifference < 0 && hDifference < 0) return 'NW_SE';\n\n // north to south\n if (vDifference < 0 && hDifference === 0) return 'N_S';\n\n // north-east to south-west\n if (sourceRow < targetRow && sourceCol > targetCol) return 'NE_SW';\n\n // east to west\n if (sourceRow === targetRow && sourceCol > targetCol) return 'E_W';\n\n // south-east to north-west\n if (sourceRow > targetRow && sourceCol > targetCol) return 'SE_NW';\n }\n\n /**\n * @param edge\n * @returns {Array<PathSegment>}\n */\n getPathFor(edge) {\n const direction = this.getEdgeDirection(edge);\n\n if (direction === 'NO_DIRECTION') return this._pathForNoDirection();\n if (direction === 'S_N') return this._pathForSouthToNorth(edge);\n if (direction === 'SW_NE') return this._pathForSouthWestToNorthEast(edge);\n if (direction === 'W_E') return this._pathForWestToEast(edge);\n if (direction === 'NW_SE') return this._pathForNorthWestToSouthEast(edge);\n if (direction === 'N_S') return this._pathForNorthToSouth(edge);\n if (direction === 'NE_SW') return this._pathForNorthEastToSouthWest(edge);\n if (direction === 'E_W') return this._pathForEastToWest(edge);\n if (direction === 'SE_NW') return this._pathForSouthEastToNorthWest(edge);\n return [];\n }\n\n _pathForNoDirection() {\n return [];\n }\n\n getEdgeSource(edge) {\n return !this.isFlipped ? edge.source : edge.target;\n }\n\n getEdgeTarget(edge) {\n return !this.isFlipped ? edge.target : edge.source;\n }\n\n _pathForSouthToNorth(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow ] = this.getTargetPosition(edge);\n\n // если sourceIsBoundary, то сразу идем в обход, так же для реверса\n if (this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent' && edge.id) return pathSegments;\n\n // TODO: при реверсе флипать сегменты перед отдачей? Need tests!\n // проверяем есть ли элементы между sourcePosition, targetPosition\n // если есть, то ребро пойдет в обход\n // так же оно пойдет в обход если элементы на соседних клетках и есть обратное ребро targetPosition-sourcePosition\n let hasIntermediateElements = this.hasIntermediateElements(this.getSourcePosition(edge), this.getTargetPosition(edge), true);\n\n // идем между ячейками грида\n if (hasIntermediateElements) return pathSegments;\n\n // проверяем петлю source -> target -> source\n const targetElementOutgoingEdges = this.getExistingOutgoingEdgesFor(this.getEdgeTarget(edge));\n const targetElementOutgoing = [ ...targetElementOutgoingEdges ].map(edge => this.getEdgeTarget(edge));\n\n // идем в обход если есть ребро в противоположном направлении\n if (targetElementOutgoing.includes(this.getEdgeSource(edge))) return pathSegments;\n\n // в остальных случаях идем прямо\n for (let rowIndex = sourceRow - 1; rowIndex > targetRow; rowIndex--) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForSouthWestToNorthEast(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // если sourceIsBoundary, то пропускаем горизонтальную часть\n if (!(this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent')) {\n\n // move right then up\n for (let colIndex = sourceCol + 1; colIndex < targetCol; colIndex++) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n }\n\n pathSegments.push({ position: [ sourceRow, targetCol ], hCross: true, vCross: true });\n\n for (let rowIndex = sourceRow - 1; rowIndex > targetRow; rowIndex--) {\n pathSegments.push({ position: [ rowIndex, targetCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForWestToEast(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ , targetCol ] = this.getTargetPosition(edge);\n\n // всегда идем вперед\n for (let colIndex = sourceCol + 1; colIndex < targetCol; colIndex++) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForNorthWestToSouthEast(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // идем сначала вниз, потом вправо так же и для sourceIsBoundary\n for (let rowIndex = sourceRow + 1; rowIndex < targetRow; rowIndex++) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n pathSegments.push({ position: [ targetRow, sourceCol ], vCross: true, hCross: true });\n\n for (let colIndex = sourceCol + 1; colIndex < targetCol; colIndex++) {\n pathSegments.push({ position: [ targetRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForNorthToSouth(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow ] = this.getTargetPosition(edge);\n\n // всегда идем вниз так же и для sourceIsBoundary\n for (let rowIndex = sourceRow + 1; rowIndex < targetRow; rowIndex++) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForNorthEastToSouthWest(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // идем вниз потом налево так же и для sourceIsBoundary\n for (let rowIndex = sourceRow + 1; rowIndex < targetRow; rowIndex++) {\n pathSegments.push({ position: [ rowIndex, sourceCol ], vCross: true });\n }\n\n pathSegments.push({ position: [ targetRow, sourceCol ], vCross: true, hCross: true });\n\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ targetRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForEastToWest(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ , targetCol ] = this.getTargetPosition(edge);\n\n // здесь аналогично движению вверх\n // проверяем есть ли элементы между sourcePosition, targetPosition\n // если есть, то ребро пойдет в обход\n // так же оно пойдет в обход если элементы на соседних клетках и есть обратное ребро targetPosition-sourcePosition\n // идем между ячейками грида\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n\n return pathSegments;\n }\n\n _pathForSouthEastToNorthWest(edge) {\n const pathSegments = [];\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n\n // для sourceIsBoundary пропускаем горизонталь\n if (!(this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent' && edge.id)) {\n\n // пробуем новую схему для хост-хост без обхода\n for (let colIndex = sourceCol - 1; colIndex > targetCol; colIndex--) {\n pathSegments.push({ position: [ sourceRow, colIndex ], hCross: true });\n }\n }\n\n // угловой сегмент\n if (!(this.getEdgeSource(edge).$type === 'bpmn:BoundaryEvent' && edge.id)) {\n pathSegments.push({ position: [ sourceRow, targetCol ], hCross: true, vCross: true });\n } else {\n pathSegments.push({ position: [ sourceRow, targetCol ], vCross: true });\n }\n\n // идем наверх\n for (let rowIndex = sourceRow - 1; rowIndex > targetRow; rowIndex--) {\n pathSegments.push({ position: [ rowIndex, targetCol ], vCross: true });\n }\n\n return pathSegments;\n }\n\n getCrossedElementsFor(edge, byVertical = false) {\n const crossedElements = [];\n for (const segment of this.getPathFor(edge)) {\n const [ row, col ] = segment.position;\n const elements = this.get(row, col);\n if (elements && ((byVertical && segment.vCross) || (!byVertical && segment.hCross))) {\n for (const element of elements) {\n crossedElements.push(element);\n }\n }\n }\n return crossedElements;\n }\n\n isIntersect(edge, position, byVertical) {\n\n // быстрый расчет по направлениям\n const [ row, col ] = position;\n const [ sourceRow, sourceCol ] = this.getSourcePosition(edge);\n const [ targetRow, targetCol ] = this.getTargetPosition(edge);\n const direction = this.getEdgeDirection(edge);\n\n if (direction === 'S_N') {\n return byVertical && col === sourceCol && row < sourceRow && row > targetRow;\n }\n\n if (direction === 'SW_NE') {\n if (byVertical && col === targetCol && row <= sourceRow && row > targetRow) return true;\n return !byVertical && col > sourceCol && col <= targetCol && row === sourceRow;\n }\n\n if (direction === 'W_E') {\n return !byVertical && col > sourceCol && col < targetCol && row === sourceRow;\n }\n\n if (direction === 'NW_SE') {\n if (byVertical && col === sourceCol && row > sourceRow && row <= targetRow) return true;\n return !byVertical && col >= sourceCol && col < targetCol && row === targetRow;\n }\n\n if (direction === 'N_S') {\n return byVertical && col === sourceCol && row > sourceRow && row < targetRow;\n }\n\n if (direction === 'NE_SW') {\n if (byVertical && col === sourceCol && row > sourceRow && row <= targetRow) return true;\n return !byVertical && col > targetCol && col <= sourceCol && row === targetRow;\n\n }\n\n if (direction === 'E_W') {\n return !byVertical && col > targetCol && col < sourceCol && row === sourceRow;\n }\n\n if (direction === 'SE_NW') {\n\n // todo: все это надо собрать в одном месте\n // а так же если есть входящие в source с направлением NW_SE\n if (byVertical && col === targetCol && row > targetRow && row <= sourceRow) return true;\n return !byVertical && col >= targetCol &&\n col < sourceCol && row === sourceRow &&\n !this.getExistingIncomingEdgesFor(this.getEdgeSource(edge))\n .some(edge => this.getEdgeDirection(edge) === 'NW_SE' || this.getEdgeDirection(edge) === 'W_E');\n }\n }\n\n /**\n * Получает ребра идущие назад и вверх\n * @param node\n * @returns {*}\n */\n getBackwardUpOutgoingEdgesFor(node) {\n return this.getExistingOutgoingEdgesFor(node).filter(edge => {\n const direction = this.getEdgeDirection(edge);\n return direction === 'S_N' || direction === 'SE_NW';\n });\n }\n\n /**\n * Создает копию грида\n * @returns {GridWithEdges}\n */\n getGridCopy() {\n return this._mergeGrids([ this ]);\n }\n\n /**\n * Удаляет ребро из грида\n * @param edge\n */\n removeEdge(edge) {\n this.graph.deleteEdge(edge);\n }\n\n getGraphSegmentFrom(node) {\n\n const segment = new Graph();\n\n // проходим только вперед\n // GetStartElementFunction<N> = (visited: Set<N>, initialGraph: Graph<N>) => N | undefined\n const getStartElement = (visited, initialGraph) => {\n return !visited.has(node) ? node : undefined;\n };\n\n // GetNextNodesFunction<N> = (node: N, graph: Graph<N>, visited: Set<N>, executionSequence: Array<N>) => Array<N> | undefined\n const getNextNodes = (node, graph, visited, executionSequence) => {\n const nextEdges = this.getExistingOutgoingEdgesFor(node).filter(edge => {\n const target = this.getEdgeTarget(edge);\n const source = this.getEdgeSource(edge);\n return !visited.has(target) && target !== source;\n });\n\n segment.addNode(node);\n const nextNodes = nextEdges.map(edge => {\n return this.getEdgeTarget(edge);\n });\n\n for (const node of nextNodes) {\n segment.addNode(node);\n }\n\n for (const edge of nextEdges) {\n segment.addEdge(edge);\n }\n\n return nextNodes;\n };\n\n this.graph.genericTraversing(getNextNodes, getStartElement);\n\n return segment;\n }\n\n getSegmentLeftCoordinates(segment) {\n\n const leftCoordinates = new Map();\n\n for (const node of segment.nodes) {\n const [ nodeRow, nodeCol ] = this.find(node);\n\n if (!leftCoordinates.has(nodeRow)) leftCoordinates.set(nodeRow, nodeCol);\n\n if (nodeCol < leftCoordinates.get(nodeRow)) leftCoordinates.set(nodeRow, nodeCol);\n }\n return leftCoordinates;\n }\n\n flip(byVertical) {\n super.flip(byVertical);\n\n // дополнительно перемещаем лэйны в начало\n const lanes = this.getLanes();\n for (const lane of lanes) {\n const nextPos = [ ...this.find(lane) ];\n nextPos[1] = 0;\n this.move(lane, nextPos);\n }\n }\n\n shrink(byVertical) {\n super.shrink(byVertical);\n if (byVertical && this.getLanes().length > 0) {\n let lastRows = new Map();\n\n // актуализируем размеры лейнов\n for (const element of [ ...this.elements ].filter(item => item.$type !== 'bpmn:Lane')) {\n const elLane = element.laneRef;\n const [ elRow, , , elHeight ] = this.find(element);\n const elMaxRow = elRow + (elHeight || 1) - 1;\n if (lastRows.get(elLane) === undefined || elMaxRow > lastRows.get(elLane)) lastRows.set(elLane, elMaxRow);\n }\n\n lastRows.forEach((lastRow, lane) => {\n const lanePos = this.find(lane);\n lanePos[3] = lastRow - lanePos[0] + 1;\n });\n }\n }\n}\n","import {\n sortElementsTopLeftBottomRight\n} from '../utils/layoutUtils.js';\n\nexport function elementExecution(node, grid, executionSequence, visited, graph) {\n if (!grid.hasElement(node)) {\n grid.add(node);\n\n // todo: пока здесь фиксим пересечение нового элемента старыми ребрами\n // актуально для вставки в лейнах, возможно и в обычной вставке востребовано\n if (grid.isCrossed(grid.find(node), true)) {\n pushVerticalEdgeBy([ node ], grid);\n }\n }\n\n // получаем новые которых нет в гриде\n // todo: перенести код\n const newOutgoing = (!grid.isFlipped ? [ ...grid.initialGraph.getOutgoingEdgesFor(node) ] : [ ...grid.initialGraph.getIncomingEdgesFor(node) ])\n .reduce((prev, edge) => {\n if (!grid.hasElement(!grid.isFlipped ? edge.target : edge.source)) {\n prev.push(!grid.isFlipped ? edge.target : edge.source);\n }\n return prev;\n },[]);\n\n // получаем вершины из стека с удалением их из грида\n // грохнем для теста так как их уже вытянули вперед\n const outgoingFromStack = getOutgoingFromStack(node, grid, executionSequence, newOutgoing && newOutgoing.length > 0, graph, visited);\n\n // Handle outgoing paths without boundaryEvents\n // Maybe later it will merge (Добавить сортировку по типу исходящих?)\n let outgoing = [ ...newOutgoing, ...outgoingFromStack ];\n\n let nextElements = [];\n\n outgoing.forEach(nextElement => {\n\n // подготавливаем место\n const nextPosition = [ ...getInsertPosition (node, grid, nextElement) ];\n\n // вставляем элемент\n // todo: костыль вставляем attachedToRef\n if (grid.isFlipped && nextElement.$type === 'bpmn:BoundaryEvent' && nextElement.attachedToRef !== node) {\n const attachedToRef = nextElement.attachedToRef;\n if (!visited.has(attachedToRef)) {\n grid.add(attachedToRef, nextPosition);\n visited.add(attachedToRef);\n fixNewCrosses(attachedToRef, grid, executionSequence, nextElements, true);\n nextElements.unshift(nextElement);\n }\n }\n grid.add(nextElement, nextPosition);\n visited.add(nextElement);\n\n fixNewCrosses(nextElement, grid, executionSequence, nextElements, true);\n\n // выворачиваем\n // Верхние левые сдвигаем вперед и проверяем пересечения начиная с левого.\n moveTopLeftOutgoingForward(nextElement, grid);\n\n nextElements.unshift(nextElement);\n });\n\n // TODO: sort by priority\n const nextBoundaries = [];\n const nextOther = [];\n for (const item of nextElements) {\n if (item.$type === 'bpmn:BoundaryEvent') {\n nextBoundaries.push(item);\n } else {\n nextOther.push(item);\n }\n }\n\n nextBoundaries.sort((a, b) => {\n const aOutCount = a.outgoing ? a.outgoing.length : 0;\n const bOutCount = b.outgoing ? b.outgoing.length : 0;\n return aOutCount - bOutCount;\n });\n\n nextElements = [ ...nextBoundaries, ...nextOther ];\n return nextElements;\n}\n\nfunction moveTopLeftOutgoingForward(node, grid) {\n\n // todo: выбрать сегмент по всем идущим назад ребрами\n // двигать весь сегмент\n // нужны тестовые данные для этого кейса\n /*\n Алгоритм без выворачивания следующий.\n Вопрос по элементам ниже пока не двигаем - тоже их удаляем из копии.\n Делаем копию грида.\n Работаем по копии грида.\n Удаляем все элементы левее таргета.\n Удаляем все исходящие ребра из сорса. ---\n Строим сегмент графа из таргета.\n Если сорс в сегменте, то не двигаем.\n Находим крайние левые позиции сегмента.\n Двигаем в базовом гриде сегмент вправо таким образом, чтобы крайний левый элемент оказался правее сорса\n */\n // получаем ребра ведущие назад из элемента\n let existingEdges = grid.getBackwardUpOutgoingEdgesFor(node);\n\n // todo: пока без сортировки чтобы проверить концепцию сдвига\n while (existingEdges.length > 0) {\n\n const workingEdge = existingEdges.shift();\n\n // todo: оптимизировать\n const sourcePos = grid.getSourcePosition(workingEdge);\n const targetPos = grid.getTargetPosition(workingEdge);\n const source = grid.getEdgeSource(workingEdge);\n const target = grid.getEdgeTarget(workingEdge);\n\n if (targetPos[1] > grid.find(node)[1]) continue;\n\n const gridCopy = grid.getGridCopy();\n\n gridCopy.removeEdge(workingEdge);\n\n // оптимизированный проход без поиска в гриде\n gridCopy._elements.forEach((value, key) => {\n const [ , colIndex ] = value;\n if (colIndex < targetPos[1]) gridCopy.removeElement(key);\n });\n\n const graphSegment = gridCopy.getGraphSegmentFrom(target);\n\n if (graphSegment.nodes.includes(source)) continue;\n\n const segmentCords = Array.from(gridCopy.getSegmentLeftCoordinates(graphSegment));\n\n const minColPosition = segmentCords.reduce((acc, cur) => {\n return acc === undefined || cur[1] < acc[1] ? cur : acc;\n }, undefined);\n\n const minRowPosition = segmentCords.reduce((acc, cur) => {\n return acc === undefined || cur[0] < acc[0] ? cur : acc;\n }, undefined);\n\n const maxRowPosition = segmentCords.reduce((acc, cur) => {\n return acc === undefined || cur[0] > acc[0] ? cur : acc;\n }, undefined);\n\n const shift = sourcePos[1] - minColPosition[1] + 1;\n\n const newMap = new Map(segmentCords);\n\n let previousShiftPos = undefined; // [row, col]\n\n for (let rowIndex = 0; rowIndex < grid.rowCount; rowIndex++) {\n\n const getShiftPos = () => {\n\n // todo: погонять тесты\n // здесь надо смещать все что выше\n if (rowIndex < minRowPosition[0]) {\n previousShiftPos = minRowPosition[0];\n return minRowPosition[1] - 1; // выше сегмента\n }\n if (newMap.has(rowIndex)) {\n previousShiftPos = newMap.get(rowIndex);\n return newMap.get(rowIndex) - 1;\n }\n\n const nodePosition = grid.find(node) || [];\n\n // посреди сегмента выше ноды\n if (rowIndex > minRowPosition[0] && rowIndex < maxRowPosition[0] && rowIndex < nodePosition[0]) {\n return previousShiftPos;\n }\n\n\n if (rowIndex === nodePosition[0] || rowIndex > minRowPosition[0]) {\n previousShiftPos = nodePosition;\n\n return nodePosition[1];\n }\n\n return previousShiftPos;\n };\n\n const shiftPos = getShiftPos() ;\n\n grid.expandRow(rowIndex, shiftPos, shift);\n }\n }\n}\n\nfunction inStackWithoutOutgoing(node, executionSequence, grid) {\n const inStack = executionSequence.includes(node);\n const outgoing = grid.getExistingOutgoingEdgesFor(node);\n\n return inStack && (!outgoing?.length > 0);\n}\n\n/**\n * @param grid\n * @param {[number, number]} topLeftPosition\n * @param {[number, number]} bottomRightPosition\n */\n// eslint-disable-next-line no-unused-vars\nfunction fixCrossesInGridPart(grid, graph, visited, topLeftPosition, bottomRightPosition) {\n if (!grid.isValidPosition(topLeftPosition) || !grid.isValidPosition(bottomRightPosition)) throw new Error('fixCrossesInGridPart: invalid position');\n\n const [ topLeftRow, topLeftCol ] = topLeftPosition;\n const [ bottomRightRow, bottomRightCol ] = bottomRightPosition;\n\n for (let rowIndex = topLeftRow; rowIndex <= bottomRightRow; rowIndex++) {\n for (let colIndex = topLeftCol; colIndex <= bottomRightCol; colIndex++) {\n const element = grid.get(rowIndex, colIndex);\n if (!element) continue;\n fixNewCrosses(element, grid);\n }\n }\n}\n\n\n/**\n * - Выдергивает исходящие элементы из стека обработки\n * - Так же удаляет их из графа\n * - Для дальнейшей обработки воспринимаем их как абсолютно новые вершины\n // * @param element - элемент для которого ищем исходящие\n // * @param grid\n // * @param {Array<Element>}stack\n // * @returns {any[]} - массив элементов\n */\nfunction getOutgoingFromStack(node, grid, executionSequence, hasNewOutgoings, graph, visited) {\n\n // получаем все исходящие базового элемента\n const outgoing = grid.getExistingOutgoingEdgesFor(node) ;\n const incoming = grid.getExistingIncomingEdgesFor(node).map(edge => grid.getEdgeSource(edge));\n\n const [ , elementCol ] = grid.find(node);\n const processingElements = outgoing.filter(edge => {\n\n // оставляем только те, что идут в стек и не имеют исходящих\n const target = grid.getEdgeTarget(edge);\n const targetCol = grid.find(target)[1];\n\n if (!inStackWithoutOutgoing(target, executionSequence, grid)) return false;\n\n\n // исключаем если общий родитель, так как уже расставили их правильно\n // пробуем нет входящих кроме element\n // если есть общий родитель и есть новые исходящие то выкидываем\n const targetIncoming = grid.getExistingIncomingEdgesFor(target)\n .map(targetEdge => targetEdge.source);\n\n const commonParent = targetIncoming.find(targetParent => incoming.includes(targetParent));\n if (commonParent && hasNewOutgoings) return false;\n\n // пробуем оставлять только те, что слева\n return targetCol <= elementCol;\n }).map(item => grid.getEdgeTarget(item)).sort(sortElementsTopLeftBottomRight (grid));\n\n // Обрабатываем элементы.\n // Удаляем их из стека и из грида\n for (const processingElement of processingElements) {\n executionSequence.splice(executionSequence.indexOf(processingElement), 1);\n visited.delete(processingElement);\n grid.removeElement(processingElement);\n }\n\n // после удаления из грида удаляем лишние колонки\n // grid.shrink(true);\n // grid.shrink(false);\n\n // обрабатываем их как новые исходящие\n return processingElements;\n}\n\nfunction getInsertPosition(element, grid, nextEl) {\n\n // todo: пока костыль\n if (grid.isFlipped && nextEl.$type === 'bpmn:BoundaryEvent' && grid.hasElement(nextEl.attachedToRef)) return grid.find(nextEl.attachedToRef);\n\n const nextOnElement = nextEl.attachedToRef === element;\n if (nextOnElement) return grid.find(element);\n\n const sourcePosition = grid.find(element);\n if (!sourcePosition) throw new Error('No source position');\n\n // по умолчанию располагаем справа от element\n const position = [ sourcePosition[0], sourcePosition[1] + 1 ];\n\n // если boundary в одном лэйне, то по диагонали\n const isBoundarySource = element.$type === 'bpmn:BoundaryEvent' && !grid.isFlipped;\n const elementLane = element.laneRef;\n const nextElLane = nextEl.laneRef;\n if (isBoundarySource && elementLane === nextElLane) {\n position[0] += 1;\n }\n\n if (elementLane !== nextElLane) { // todo: здесь!!!\n const [ elementLaneRow ] = grid.find(elementLane);\n const [ nextElLaneRow, , , nextElLaneHeight ] = grid.find(nextElLane);\n const laneRowPosDif = elementLaneRow - nextElLaneRow;\n if (laneRowPosDif > 0) {\n position[0] = nextElLaneRow + (nextElLaneHeight || 1) - 1;\n } else {\n position[0] = nextElLaneRow;\n }\n }\n\n // ищем первую дырку между ребрами источника\n const elPos = grid.find(element);\n const allItemsInElementPosition = [ ...grid.get(elPos[0], elPos[1]) ].filter(item => item.$type !== 'bpmn:Lane');\n const elementPositionEdges = [];\n\n // todo: надо смотреть реверс\n for (const item of allItemsInElementPosition) {\n grid.getExistingOutgoingEdgesFor(item).forEach(edge => {\n if (edge.target !== edge.source) elementPositionEdges.push(edge);\n });\n }\n\n // проверяем вертикаль вниз от позиции\n for (let i = position[0]; i <= grid.rowCount; i++) {\n const point = [ i, position[1] ];\n const crossedOrOccupied = elementPositionEdges.some(edge => {\n return (grid.getTargetPosition(edge)[0] === i && grid.getTargetPosition(edge)[1] === position[1]) || grid.isIntersect(edge, point, false) || grid.isIntersect(edge, point, true);\n });\n\n if (crossedOrOccupied && i === grid.colCount - 1) {\n position[0] = i + 1;\n continue;\n }\n\n if (crossedOrOccupied) continue;\n position[0] = i;\n break;\n }\n\n // todo: убрать на после вставки?\n // обрабатываем занятость и вертикальные пересечения\n if (grid.get(position[0], position[1]) || grid.isCrossed(position, true)) {\n grid.addRowCol(true, position[1] - 1);\n }\n\n if (grid.isCrossed([ position[0], position[1] ])) {\n\n // todo: возможно стоит посмотреть по направлениям\n grid.addRowCol(false, position[0] - 1);\n }\n return position;\n}\n\n// только для тех что впереди\n// /**\n// * @param element\n// * @param grid\n// * @param {[Element]=} stack\n// * @param {[Element]=} nextElements\n// * @param {boolean} skipTopLeftOutgoing\n// * @param {boolean} forwardOnlyOutgoing\n// */\nfunction fixNewCrosses(element, grid, stack, nextElements, skipTopLeftOutgoing) {\n\n // todo: пока здесь фиксим пересечение нового элемента старыми ребрами\n // актуально для вставки в лейнах, возможно и в обычной вставке востребовано\n if (grid.isCrossed(grid.find(element), true)) {\n pushVerticalEdgeBy([ element ], grid);\n }\n\n // реверс логики переноса вперед для исходящих\n // исправляем пересечения образованные исходящими и входящими ребрами новой вершины\n // получаем исходящие\n const outgoingEdges = grid.getExistingOutgoingEdgesFor(element)\n .sort((a, b) => {\n const [ aRow, aCol ] = grid.getTargetPosition(a);\n const [ bRow, bCol ] = grid.getTargetPosition(b);\n return aRow - bRow || aCol - bCol;\n });\n const incomingEdges = grid.getExistingIncomingEdgesFor(element)\n .sort((a, b) => {\n const [ aRow, aCol ] = grid.getSourcePosition(a);\n const [ bRow, bCol ] = grid.getSourcePosition(b);\n return aRow - bRow || aCol - bCol;\n });\n\n const edges = [ ...outgoingEdges, ...incomingEdges ]\n .filter(edge => {\n const { target, source } = edge;\n const direction = grid.getEdgeDirection(edge);\n\n // не обрабатываем следующие случаи\n // если self loop\n if (target === source) return false;\n\n // если в обработке текущей очереди исходящих\n if (nextElements && nextElements.includes(target)) return false;\n\n // если таргет в стеке и у него нет существующих исходящих если передали стек\n if (stack) {\n\n if (inStackWithoutOutgoing(target, stack, grid)) return false;\n }\n if (skipTopLeftOutgoing) {\n\n // TODO: Пока непонятно надо ли как то обрабатывать стек?\n if (source === element && (direction === 'SE_NW' || direction === 'S_N')) return false;\n }\n\n return true;\n });\n\n for (const edge of edges) {\n\n // исправляем вертикали\n fixNewVerticalCrosses(edge, grid);\n\n // не исправляем гризонтали если E_W из boundary\n if (grid.getEdgeDirection(edge) === 'E_W' && ((grid.getEdgeSource(edge)).$type === 'bpmn:BoundaryEvent' && edge.id)) continue;\n fixNewHorizontalCrosses(edge, grid);\n }\n}\n\n// TODO: Add tests for boundary edges\nfunction fixNewVerticalCrosses(edge, grid) {\n\n // заготовка по направлениям\n // S_N - нет, так как не предполагается схемой\n // SW_NE\n // W_E - нет вертикали\n // NW_SE\n // N_S\n // NE_SW\n // E_W - нет вертикали\n // SE_NW\n\n const direction = grid.getEdgeDirection(edge);\n\n if (direction === 'W_E' || direction === 'E_W') return;\n\n const vCrossed = grid.getCrossedElementsFor(edge, true).filter(item => item.$type !== 'bpmn:Lane');\n\n if (vCrossed.length <= 0) return;\n\n if (direction === 'S_N') {\n moveElementsRighterCrossLine(vCrossed, grid);\n return;\n }\n\n if (direction === 'SW_NE') {\n\n // требуется дополнительное условие?\n // пока сдвигаем вертикаль\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n if (direction === 'NW_SE') {\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n if (direction === 'N_S') {\n moveElementsRighterCrossLine(vCrossed, grid);\n return;\n }\n\n if (direction === 'NE_SW') {\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n\n if (direction === 'SE_NW') {\n pushVerticalEdgeBy(vCrossed, grid);\n return;\n }\n}\n\n// TODO: Add tests for boundary edges\n// возможно добавить потом наличие ребер\nfunction fixNewHorizontalCrosses(edge, grid) {\n\n // заготовка по направлениям\n const direction = grid.getEdgeDirection(edge);\n\n // по этим направлениям не предполагается горизонтальных пересечений\n if (direction === 'S_N' || direction === 'N_S') return;\n\n const hCrossed = grid.getCrossedElementsFor(edge, false).filter(item => item.$type !== 'bpmn:Lane');\n\n if (hCrossed.length === 0) return;\n\n if (direction === 'SW_NE') {\n\n // поднимаем элементы выше пересечения\n const maxDown = getMaxDown(edge, grid);\n const [ baseSourceRow ] = grid.getSourcePosition(edge);\n grid.addRowCol(false, baseSourceRow - 1, maxDown);\n\n const [ sourceRow, sourceCol ] = grid.getSourcePosition(edge);\n const elements = grid.getElementsInRange({ row: sourceRow, col: sourceCol + 1 }, { row: grid.rowCount - 1, col: grid.colCount - 1 })\n .filter(item => item.$type !== 'bpmn:Lane');\n\n for (const element of elements) {\n const [ row, col ] = grid.find(element);\n for (const innerElement of [ ...grid.get(row, col) ]) {\n grid.move(innerElement, [ row - maxDown, col ]);\n }\n }\n return;\n }\n\n if (direction === 'W_E') {\n\n // опускаем элементы\n moveElementsUnderCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'NW_SE') {\n moveElementsUpperCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'NE_SW') {\n moveElementsUpperCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'E_W') {\n\n // опускаем элементы\n moveElementsUnderCrossLine(hCrossed, grid);\n return;\n }\n\n if (direction === 'SE_NW') {\n moveElementsUpperCrossLine(hCrossed, grid);\n return;\n }\n}\n\nfunction moveElementsUpperCrossLine(elements, grid) {\n\n // пробуем поднимать элементы выше пересечения\n const [ row ] = grid.find(elements[0]);\n grid.addRowCol(false, row - 1);\n for (const element of elements) {\n const [ , col ] = grid.find(element);\n grid.move(element, [ row , col ]);\n }\n}\n\nfunction moveElementsUnderCrossLine(elements, grid) {\n\n // пробуем опускать элементы ниже пересечения\n const [ row ] = grid.find(elements[0]);\n grid.addRowCol(false, row);\n for (const element of elements) {\n const [ , col ] = grid.find(element);\n grid.move(element, [ row + 1 , col ]);\n }\n}\n\n// TODO: проверить\nfunction moveElementsRighterCrossLine(elements, grid) {\n\n // TODO: костыльчик чтобы запустилось\n const [ , col ] = grid.find(elements[0]);\n grid.addRowCol(true, col);\n\n for (const element of elements) {\n const [ elRow ] = grid.find(element);\n grid.move(element, [ elRow, col + 1 ]);\n }\n}\n\n/**\n * All crossed on one column\n * @param elements\n * @param grid\n */\nfunction pushVerticalEdgeBy(elements, grid) {\n const [ , col ] = grid.find(elements[0]);\n grid.addRowCol(true, col - 1);\n\n for (const element of elements) {\n const [ row ] = grid.find(element);\n grid.move(element, [ row, col ]);\n }\n}\n\n// Todo: сделать для всех направлений, а не только для SW_NE и сделать методы в гриде\nfunction getMaxDown(edge, grid) {\n const sourcePosition = grid.getSourcePosition(edge);\n const targetPosition = grid.getTargetPosition(edge);\n\n let maxDown = sourcePosition[0];\n\n for (let rowIndex = sourcePosition[0]; rowIndex < grid.rowCount; rowIndex++) {\n if (grid.getElementsInRange({ row: rowIndex, col: sourcePosition[1] + 1 }, { row: rowIndex, col: targetPosition[1] }).length > 0) {\n maxDown++;\n } else {\n break;\n }\n }\n\n return maxDown - sourcePosition[0];\n}\n","import {\n connectElements,\n} from '../utils/layoutUtils.js';\n\nexport default function createConnection(edge, layoutGrid, diFactory, shift) {\n const { id } = edge;\n\n // todo: пока костыль для отрисовки только тех, которые с id\n if (id) {\n const waypoints = connectElements(edge, layoutGrid, shift);\n return diFactory.createDiEdge(edge, waypoints, {\n id: id + '_di'\n });\n }\n}\n","import { getBounds } from '../utils/layoutUtils.js';\nimport { getOutgoingElements } from '../utils/elementUtils.js';\nimport { is } from '../di/DiUtil.js';\n\nexport default function createElementDi(element, elementPosition, diFactory, grid, shift, laneLevelDif) {\n if (element.di) return [];\n\n if (element.$type === 'bpmn:BoundaryEvent') {\n return createBEl(element, elementPosition, diFactory, grid, shift);\n }\n\n if (element.$type === 'bpmn:Lane') {\n elementPosition[2] = grid.colCount;\n }\n\n const bounds = getBounds(element, elementPosition, shift, laneLevelDif);\n\n const options = {\n id: element.id + '_di'\n };\n\n if (element.isExpanded) {\n options.isExpanded = true;\n }\n\n if (is(element, 'bpmn:ExclusiveGateway')) {\n options.isMarkerVisible = true;\n }\n\n const shapeDi = diFactory.createDiShape(element, bounds, options);\n element.di = shapeDi;\n return [ shapeDi ];\n}\n\nfunction createBEl(element, elementPosition, diFactory, grid, shift) {\n const host = element.attachedToRef;\n const hostPosition = grid.find(host);\n\n const hostBounds = getBounds(host, hostPosition, shift);\n if (!hostBounds) throw new Error(`Create DI for ${element.id}. Nо hostBounds`);\n const DIs = [];\n\n // получаем соседние boundary\n // первыми должны отрисовываться те, у которых потомки ниже и правей\n let neighboursBoundary = element.$parent.flowElements.filter(item => item.attachedToRef === element.attachedToRef && grid.hasElement(element));\n neighboursBoundary = getSortedElementsByOutgoingPosition(neighboursBoundary, grid);\n neighboursBoundary.forEach((att, i, arr) => {\n const bounds = getBounds(att, elementPosition, shift);\n\n // distribute along lower edge\n bounds.x = hostBounds.x + (i + 1) * (hostBounds.width / (arr.length + 1)) - bounds.width / 2;\n bounds.y = hostBounds.y + hostBounds.height - bounds.height / 2;\n\n const attacherDi = diFactory.createDiShape(att, bounds, {\n id: att.id + '_di'\n });\n att.di = attacherDi;\n\n DIs.push(attacherDi);\n });\n return DIs;\n}\n\n// Первыми идут те у которых исходящие ниже\nfunction getSortedElementsByOutgoingPosition(elements, grid) {\n return elements.sort((a, b) => {\n const aBottomRightChildPosition = getPositionRightBottomOutgoingElement(a, grid);\n const bBottomRightChildPosition = getPositionRightBottomOutgoingElement(b, grid);\n\n return aBottomRightChildPosition[0] - bBottomRightChildPosition[0] || aBottomRightChildPosition[1] - bBottomRightChildPosition[1];\n }).reverse();\n}\n\nfunction getPositionRightBottomOutgoingElement(element, grid) {\n return getOutgoingElements(element).reduce((prev, cur) => {\n if (!grid.hasElement(cur)) return prev;\n const curPosition = grid.find(cur);\n if (prev[0] < curPosition[0] || prev[1] < curPosition[1]) return curPosition;\n return prev;\n }, [ 0 ,0 ]);\n}","export class Edge {\n constructor(source, target) {\n this.source = source;\n this.target = target;\n }\n}","export class NestedSet {\n constructor(object, getFirst, getNext) {\n\n this.nestedSet = this._init(object, getFirst, getNext);\n }\n\n _init(object, getFirst, getNext) {\n const resultNestedSet = new Map(); // left, right, level\n const stack = getFirst(object);\n stack.forEach(item => {\n resultNestedSet.set(item, { level: 0 });\n });\n\n while (stack.length > 0) {\n const curItem = stack.pop();\n const curPosition = resultNestedSet.get(curItem);\n if (curPosition.left === undefined) {\n const maxRight = [ ...resultNestedSet.values() ].reduce((prev, cur) => {\n return cur.right > prev || prev === undefined ? cur.right : prev;\n }, undefined);\n curPosition.left = maxRight !== undefined ? maxRight + 1 : 0;\n }\n if (curPosition.right === undefined) {\n stack.push(curItem);\n const subItems = getNext(curItem).filter(item => resultNestedSet.get(item)?.level === undefined);\n if (subItems.length === 0) {\n let maxRight = [ ...resultNestedSet.values() ].reduce((prev, cur) => {\n return cur.right > prev || prev === undefined ? cur.right : prev;\n }, undefined);\n if (maxRight === undefined) maxRight = [ ...resultNestedSet.values() ].reduce((prev, cur) => {\n return cur.left > prev || prev === undefined ? cur.left : prev;\n }, undefined);\n if (curPosition.left > maxRight) maxRight = curPosition.left;\n curPosition.right = maxRight + 1;\n }\n [ ...subItems ].reverse().forEach((subLane, index, arr) => {\n stack.push(subLane);\n const subPosition = index === arr.length - 1 ? { level: curPosition.level + 1, left: curPosition.left + 1 } : { level: curPosition.level + 1 };\n resultNestedSet.set(subLane, subPosition);\n });\n }\n }\n\n return resultNestedSet;\n }\n\n getLeaves(item) {\n const position = this.nestedSet.get(item);\n return [ ...this.nestedSet.entries() ].filter(([ element, elPos ]) => {\n if (!position) return elPos.right - elPos.left === 1;\n return elPos.left > position.left && elPos.right < position.right && elPos.right - elPos.left === 1;\n });\n }\n\n getNested(item) {\n if (!item) return this.nestedSet.entries();\n const position = this.nestedSet.get(item);\n return [ ...this.nestedSet.entries() ].filter(([ , elPos ]) => {\n return elPos.left > position.left && elPos.right < position.right;\n });\n }\n\n isLeaf(item) {\n const position = this.nestedSet.get(item);\n return position.right - position.left === 1;\n }\n\n getMaxLevel() {\n return [ ...this.nestedSet.values() ].reduce((prev, nestPos) => {\n return prev < nestPos.level ? nestPos.level : prev;\n },0) ;\n }\n\n}","import BPMNModdle from 'bpmn-moddle';\nimport { Graph } from 'graph-by-ivan-tulaev';\n\n// todo: настроить сборщик resolve js\nimport {\n isStartIntermediate,\n setAdditionalPropsToElements, getAllProcesses,\n} from './utils/elementUtils.js';\n\nimport {\n DEFAULT_CELL_HEIGHT,\n DEFAULT_CELL_WIDTH,\n DEFAULT_POOL_MARGIN,\n PARTICIPANT_LABEL_WIDTH,\n sortByType,\n} from './utils/layoutUtils.js';\nimport { DiFactory } from './di/DiFactory.js';\nimport { is, getDefaultSize } from './di/DiUtil.js';\nimport { GridWithEdges } from './GridWithEdges.js';\nimport { elementExecution } from './newHandlers/outgoingHandler.js';\nimport createConnection from './newHandlers/createConnection.js';\nimport createElementDi from './newHandlers/createElementDi.js';\nimport { Edge } from './Edge.js';\nimport { NestedSet } from './NestedSet.js';\n\n\n/**\n * @typedef {Object} BPMNElement\n * @property {boolean} isExpanded - is expanded or collapsed\n * @property {Array<BPMNElement>} attachers - prop for host element\n */\n\n\nexport class Layouter {\n constructor(debuggerCounter) {\n this.moddle = new BPMNModdle();\n this.diFactory = new DiFactory(this.moddle);\n this.maxDebugStep = debuggerCounter;\n this.currentDebugStep = 0;\n }\n\n async layoutProcess(xml) {\n const moddleObj = await this.moddle.fromXML(xml);\n\n const { rootElement } = moddleObj;\n\n // init important properties\n this.diagram = rootElement;\n\n // todo: убрать лишний параметр\n setAdditionalPropsToElements(moddleObj, this.getLanesNestedSet);\n\n // init process trees as nested sets\n // add nested set properties to process (left, right, level)\n this.processTrees = this.createNestedSets(moddleObj);\n\n // create and add grids for each process\n // root processes should be processed last for element expanding\n this.createGridsForProcesses();\n\n // expand grids\n this.expandProcessesGrids();\n\n // expand procsses with lanes\n this.expandParticipants();\n\n // get all process from root\n const rootProcesses = this.getRootProcesses();\n const collaboration = this.getCollaboration();\n\n if (rootProcesses.length > 0) {\n this.cleanDi();\n this.createRootDi(rootProcesses, collaboration);\n this.drawParticipants();\n this.drawProcesses();\n this.drawCollaborationMessageFlows(collaboration);\n }\n\n return (await this.moddle.toXML(this.diagram, { format: true })).xml;\n }\n\n expandParticipants() {\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n\n for (const process of processes) {\n const lanes = process.grid.getLanes();\n for (const lane of lanes || []) {\n const lanePos = process.grid.find(lane);\n const laneHeight = lanePos[3] || 1;\n process.grid.addRowCol(false, lanePos[0] + laneHeight - 1, 1);\n lanePos[3] = laneHeight + 1;\n }\n }\n }\n\n createGridsForProcesses() {\n\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n processes.sort((a, b) => a.level - b.level);\n\n // create and add grids for each process\n for (const process of processes) {\n\n const hasLanes = (process.laneSets || [])[0]?.lanes.length > 0;\n\n // add base grid with collapsed elements\n process.grid = this.createGridLayout(process);\n\n // separate base grid to independent grids\n // todo: временно костыляем\n const tempGridCollection = hasLanes ? [ process.grid ] : (process.grid._separateGrid() || [ process.grid ]);\n\n // for each independent grid:\n // - remove empty rows and cols\n // - shake elements by vertical and horizontal\n // todo: временно костыляем\n for (const grid of tempGridCollection) {\n grid.shrink(true);\n grid.shrink(false);\n\n grid.shakeIt(true);\n grid.shakeIt(false);\n\n // todo: временно костыляем\n }\n\n // merge separated grids and set new grid to the process\n // todo: временно костыляем\n if (!hasLanes) {\n process.grid = process.grid._mergeGrids(tempGridCollection);\n }\n }\n }\n\n expandProcessesGrids() {\n\n // root processes should be processed last for element expanding\n const processes = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n processes.sort((a, b) => b.level - a.level);\n\n for (const process of processes) {\n\n // separate base grid to independent grids\n // todo: временно костыляем\n const hasLanes = (process.laneSets || [])[0]?.lanes.length > 0;\n const tempGridCollection = hasLanes ? [ process.grid ] : (process.grid._separateGrid() || [ process.grid ]);\n for (const grid of tempGridCollection) {\n grid.shrink(true);\n grid.shrink(false);\n\n expandGrid(grid, false);\n expandGrid(grid, true);\n }\n\n // merge separated grids and set new grid to the process\n // todo: временно костыляем\n if (!hasLanes) {\n process.grid = process.grid._mergeGrids(tempGridCollection);\n }\n }\n }\n\n /**\n * draw participants pools at root\n */\n drawParticipants() {\n const collaboration = this.getCollaboration();\n\n if (!collaboration || !collaboration[0]) return;\n const participants = collaboration[0].participants;\n\n const x = 0;\n let y = 0;\n\n for (const participant of participants) {\n y = this.createParticipantDi(participant, { x, y }) + DEFAULT_POOL_MARGIN;\n }\n }\n\n /**\n * Draw processes.\n * Root processes should be processed first for element expanding\n */\n drawProcesses() {\n\n const sortedProcesses = this.processTrees.map(graph => [ ...graph.nodes ]).flat();\n sortedProcesses.sort((a, b) => a.level - b.level);\n\n for (const process of sortedProcesses) {\n\n // draw root processes in participants\n const participant = this.getParticipantForProcess(process);\n\n if (participant) {\n const participantDi = this.getElementDi(participant);\n const diagram = this.getProcDi(participantDi);\n\n let { x, y } = participantDi.bounds;\n x += DEFAULT_CELL_WIDTH / 2;\n y += DEFAULT_CELL_HEIGHT / 2;\n this.generateDi(process, { x, y }, diagram);\n continue;\n }\n\n // draw processes in expanded elements\n // todo: сделать понятнее для this.maxDebugStep\n if (process.isExpanded && !this.existingNodes.includes(process)) continue;\n if (process.isExpanded) {\n const baseProcDi = this.getElementDi(process);\n const diagram = this.getProcDi(baseProcDi);\n let { x, y } = baseProcDi.bounds;\n const { width, height } = getDefaultSize(process);\n x += DEFAULT_CELL_WIDTH / 2 - width / 4;\n y += DEFAULT_CELL_HEIGHT - height - height / 4;\n this.generateDi(process, { x, y }, diagram);\n continue;\n }\n\n // draw other processes\n const diagram = this.diagram.diagrams.find(diagram => diagram.plane.bpmnElement === process);\n this.generateDi(process, { x: 0, y: 0 }, diagram);\n }\n }\n\n get existingNodes() {\n return this.processTrees.map(graph => [ ...graph.nodes ]).flat().map(item => [ ...item.grid.elements ]).flat();\n }\n\n drawCollaborationMessageFlows(collaboration) {\n const messageFlows = collaboration[0] ? collaboration[0].messageFlows : null;\n if (messageFlows) {\n for (const message of messageFlows) {\n const { sourceRef, targetRef } = message;\n\n // todo: debug mode сделать презентабельнее\n const existNodes = this.existingNodes;\n if (!existNodes.includes(sourceRef) || !existNodes.includes(targetRef)) continue;\n\n const sourceBounds = sourceRef.di.bounds;\n const targetBounds = targetRef.di.bounds;\n const dY = targetBounds.y - sourceBounds.y;\n const waypoints = [\n { x: sourceBounds.x + sourceBounds.width / 2 },\n { x: targetBounds.x + targetBounds.width / 2 }\n ];\n\n if (dY > 0) {\n waypoints[0].y = sourceBounds.y + sourceBounds.height;\n waypoints[1].y = targetBounds.y;\n } else {\n waypoints[0].y = sourceBounds.y;\n waypoints[1].y = targetBounds.y + targetBounds.height;\n }\n\n const edge = this.diFactory.createDiEdge(message, waypoints);\n this.diagram.diagrams[0].plane.get('planeElement').push(edge);\n }\n }\n }\n\n getParticipantForProcess(process) {\n const collaboration = this.getCollaboration();\n if (!collaboration || !collaboration[0]) return;\n const participants = this.getCollaboration()[0].participants;\n\n if (!participants) return;\n\n return participants.find(participant => participant.processRef === process);\n }\n\n getElementDi(element) {\n return this.diagram.diagrams\n .map(diagram => diagram.plane.planeElement).flat()\n .find(item => item.bpmnElement === element);\n }\n\n getProcDi(element) {\n return this.diagram.diagrams.find(diagram => diagram.plane.planeElement.includes(element));\n }\n\n // todo: переписать под nested sets\n createNestedSets(bpmnModel) {\n const processGraph = new Graph();\n const allProcesses = getAllProcesses(bpmnModel);\n\n // add nodes to graph\n for (const process of allProcesses) {\n processGraph.addNode(process);\n }\n\n // add edges\n for (const process of allProcesses) {\n const children = this.getSubProcesses(process);\n for (const child of children) {\n processGraph.addEdge({ source: process, target: child });\n }\n }\n\n const separatedGraphs = processGraph.getSeparatedGraphs();\n\n // set root process to tree\n for (const graph of separatedGraphs) {\n const rootProcesses = graph.nodes.filter(node => graph.getIncomingEdgesFor(node).size === 0);\n\n // must have 1 root process\n if (rootProcesses.length > 1) throw new Error('Process tree has more than 1 root elements');\n if (rootProcesses.length === 0) throw new Error('Process tree has 0 root elements');\n\n graph.rootProcess = rootProcesses[0];\n }\n\n // set nested sets attributes\n for (const graph of separatedGraphs) {\n\n // callback that get start node from process tree\n // it's root process\n const getStartElement = (visited, initialGraph) => {\n const root = initialGraph.rootProcess;\n\n root.left = 0;\n root.level = 0;\n\n return root;\n };\n\n // callback that get next executed nodes\n // it's first node without left prop if we go from root,\n // or without right prop if we go to root\n const getNextNodes = (node, graph) => {\n\n const { left, level } = node;\n\n // get first node without left prop\n const outgoingNode = [ ...graph.getOutgoingEdgesFor(node) ]\n .map(edge => edge.target)\n .find(node => node.left === undefined);\n\n if (outgoingNode) {\n outgoingNode.level = level + 1;\n outgoingNode.left = left + 1;\n return [ outgoingNode ];\n }\n\n // if no outgoingNode get max right\n const maxRight = [ ...graph.getOutgoingEdgesFor(node) ]\n .map(edge => edge.target)\n .reduce((prev, cur) => {\n return prev === undefined || cur.right > prev.right ? cur.right : prev;\n } , undefined);\n\n if (maxRight) {\n node.right = maxRight + 1;\n } else {\n node.right = node.left + 1;\n }\n\n // get incoming\n const incoming = [ ...graph.getIncomingEdgesFor(node) ]\n .map(edge => edge.source)\n .find(node => node.right === undefined);\n\n if (incoming) return [ incoming ];\n };\n graph.genericTraversing(getNextNodes, getStartElement);\n }\n\n return separatedGraphs;\n }\n\n getSubProcesses(processes) {\n return processes.flowElements ? processes.flowElements.filter(process => process.$type === 'bpmn:SubProcess') : [];\n }\n\n createRootDi(processes, collaboration) {\n\n const mainElement = collaboration && collaboration.length > 0 ? collaboration[0] : processes[0];\n this.createProcessDi(mainElement);\n }\n\n createProcessDi(element) {\n const diFactory = this.diFactory;\n\n const planeDi = diFactory.createDiPlane({\n id: 'BPMNPlane_' + element.id,\n bpmnElement: element\n });\n const diagramDi = diFactory.createDiDiagram({\n id: 'BPMNDiagram_' + element.id,\n plane: planeDi\n });\n\n const diagram = this.diagram;\n\n diagram.diagrams.push(diagramDi);\n\n return diagramDi;\n }\n\n /**\n * Create participant diagram\n * @param participant\n * @param {{x: number, y: number}} origin\n * @returns {number} bottom Y coordinate of created shape\n */\n createParticipantDi(participant, origin) {\n\n // get size of child process element\n const grid = participant.processRef.grid;\n const { colCount, rowCount } = grid;\n\n const { width: defaultWidth, height: defaultHeight } = getDefaultSize(participant);\n\n\n // Result size is children grid size + paddings ( 1/2 of width or height)\n // let width = colCount > 0 ? colCount * DEFAULT_CELL_WIDTH + DEFAULT_CELL_WIDTH : defaultWidth;\n let width = colCount > 0 ? (colCount + 1) * DEFAULT_CELL_WIDTH : defaultWidth;\n let height = defaultHeight;\n\n const nestedLanes = participant.processRef.lanesNestedSet;\n const maxLevel = nestedLanes.getMaxLevel();\n\n if (nestedLanes.nestedSet.size > 0) {\n height = rowCount * DEFAULT_CELL_HEIGHT;\n\n // 1 - лейбл пула\n // maxLevel + 1 level count\n width = width + (maxLevel + 2) * PARTICIPANT_LABEL_WIDTH;\n } else {\n height = rowCount > 0 ? rowCount * DEFAULT_CELL_HEIGHT + DEFAULT_CELL_HEIGHT : defaultHeight;\n }\n const participantDi = this.diFactory.createDiShape(participant, { width, height, ...origin }, { id: participant.id + '_di' });\n const planeDi = this.diagram.diagrams[0].plane.get('planeElement');\n planeDi.push(...[ participantDi ]);\n\n const poolOrigin = { ...origin };\n nestedLanes.nestedSet.forEach((pos, lane) => {\n\n const laneX = poolOrigin.x + (pos.level + 1) * PARTICIPANT_LABEL_WIDTH;\n const leaves = nestedLanes.getLeaves(lane);\n if (leaves.length === 0) leaves.push([ lane, pos ]);\n\n const laneRowPos = leaves.reduce((prev, [ curLeave ]) => {\n const curGridPos = grid.find(curLeave);\n return prev === undefined || curGridPos[0] < prev ? curGridPos[0] : prev;\n }, undefined);\n\n const laneY = poolOrigin.y + laneRowPos * DEFAULT_CELL_HEIGHT;\n\n const levelDif = maxLevel - pos.level;\n let laneWidth = (colCount > 0 ? colCount + 1 : 2) * DEFAULT_CELL_WIDTH + (levelDif + 1) * PARTICIPANT_LABEL_WIDTH;\n\n let laneHeight = leaves.reduce((prev, [ curLeave ]) => {\n const curGridPos = grid.find(curLeave);\n return prev + (curGridPos[3] || 2);\n }, 0) * DEFAULT_CELL_HEIGHT;\n\n const laneDi = this.diFactory.createDiShape(lane, { width: laneWidth, height:laneHeight, x: laneX, y: laneY }, { id: lane.id + '_di' });\n const planeDi = this.diagram.diagrams[0].plane.get('planeElement');\n planeDi.push(...[ laneDi ]);\n\n });\n\n return participantDi.bounds.y + participantDi.bounds.height;\n }\n\n cleanDi() {\n this.diagram.diagrams = [];\n }\n\n getLanesNestedSet(process) {\n\n const getFirstLevel = (process) => {\n return [ ...process.laneSets ? process.laneSets[0].lanes : [] ].reverse();\n };\n\n const getNext = (item) => {\n return item.childLaneSet?.lanes || [];\n };\n\n return new NestedSet(process, getFirstLevel, getNext);\n\n }\n\n createGridLayout(process) {\n\n // create graph from elements\n const processGraph = new Graph();\n const grid = new GridWithEdges(processGraph);\n\n // add lanesNestedSet to process\n process.lanesNestedSet = this.getLanesNestedSet(process);\n const lanes = process.lanesNestedSet.getLeaves().sort((a, b) => a[1].left - b[1].left).map(([ lane ]) => lane);\n for (const lane of lanes) {\n grid.add(lane);\n grid.find(lane)[3] = 1;\n }\n\n // add nodes\n for (const flowElement of process.flowElements || []) {\n\n if (!is(flowElement,'bpmn:SequenceFlow') && !is(flowElement,'bpmn:DataObject')) {\n processGraph.addNode(flowElement);\n }\n }\n\n // add edges\n // todo: переписать компактней\n for (const node of processGraph.nodes) {\n\n // boundary\n // добавляем два ребра, так как у нас направленный граф\n if (node.$type === 'bpmn:BoundaryEvent') {\n processGraph.addEdge(new Edge(node, node.attachedToRef));\n processGraph.addEdge(new Edge(node.attachedToRef, node));\n }\n\n // sequenceFlow\n for (const outgoingItem of node.outgoing || []) {\n const newEdge = new Edge(outgoingItem.sourceRef, outgoingItem.targetRef);\n newEdge.id = outgoingItem.id;\n processGraph.addEdge(newEdge);\n }\n\n // data associations - двигаемся от связанной ноды\n const dataInputAssociations = node.dataInputAssociations;\n for (const association of dataInputAssociations || []) {\n for (const dataSource of association.sourceRef || []) {\n const newEdge = new Edge(dataSource, association.$parent);\n newEdge.id = association.id;\n newEdge.propRef = association.targetRef;\n processGraph.addEdge(newEdge);\n }\n }\n\n const dataOutputAssociations = node.dataOutputAssociations;\n for (const association of dataOutputAssociations || []) {\n const source = association.$parent;\n const target = association.targetRef;\n const newEdge = new Edge(source, target);\n newEdge.id = association.id;\n processGraph.addEdge(newEdge);\n }\n }\n\n // export type GetStartElementFunction<N> = (visited: Set<N>, initialGraph: Graph<N>)\n const dfsGetStartElement = (visited, initialGraph) => {\n if (this.maxDebugStep !== undefined && this.maxDebugStep <= this.currentDebugStep) return;\n\n // get elements in the grid that have incoming that are not in grid\n const targetElementInGridSourceNotExist = [ ...visited ].find(node => {\n const incomingEdges = !grid.isFlipped ? [ ...initialGraph.getIncomingEdgesFor(node) ] : [ ...initialGraph.getOutgoingEdgesFor(node) ];\n return incomingEdges.filter(edge => !visited.has(!grid.isFlipped ? edge.source : edge.target)).length > 0;\n });\n if (targetElementInGridSourceNotExist) {\n grid.flip(false);\n\n return targetElementInGridSourceNotExist;\n }\n\n // maybe need boundaryEvents processing here\n const primaryStartElements = initialGraph.nodes.filter(node => {\n const incomingEdges = !grid.isFlipped ? initialGraph.getIncomingEdgesFor(node) : initialGraph.getOutgoingEdgesFor(node);\n return !visited.has(node) && incomingEdges.size === 0 && !isStartIntermediate(node);\n });\n if (primaryStartElements.length > 0) return sortByType(primaryStartElements, 'bpmn:StartEvent')[0];\n\n const sourceElementInGridTargetNotExist = [ ...visited ].find(node => {\n\n // todo: добавить сортировку sortElementsTopLeftBottomRight?\n const outgoing = !grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ];\n return outgoing.filter(edge => !visited.has(!grid.isFlipped ? edge.target : edge.source)).length > 0;\n });\n if (sourceElementInGridTargetNotExist) return sourceElementInGridTargetNotExist;\n\n // All elements without incoming from other elements\n // this case as the very last one\n const otherStartingElement = initialGraph.nodes.find(node => {\n if (visited.has(node)) return false;\n\n // incoming without Loops\n const incoming = !grid.isFlipped ? [ ...initialGraph.getIncomingEdgesFor(node) ] : [ ...initialGraph.getOutgoingEdgesFor(node) ];\n return incoming.filter(edge => node !== (!grid.isFlipped ? edge.source : edge.target)).length === 0;\n });\n if (otherStartingElement) return otherStartingElement;\n\n const flippedStartElement = initialGraph.nodes.find(node => {\n\n if (visited.has(node)) return false;\n\n let outgoingEdges = (!grid.isFlipped ? [ ...initialGraph.getOutgoingEdgesFor(node) ] : [ ...initialGraph.getIncomingEdgesFor(node) ]).filter(edge => edge.target !== edge.source);\n\n return outgoingEdges.length === 0;\n });\n\n if (flippedStartElement) {\n grid.flip(false);\n return flippedStartElement;\n }\n this.currentDebugStep += 1;\n\n // not traversed elements (restElements)\n return initialGraph.nodes.find(node => !visited.has(node));\n };\n\n // GetNextNodesFunction<N> = (node: N, graph: Graph<N>, visited: Set<N>) => Array<N> | undefined\n const dfsGetNextNodes = (node, graph, visited, executionSequence) => {\n if (this.maxDebugStep !== undefined && this.maxDebugStep <= this.currentDebugStep) return;\n\n // основная обработка\n const nextElements = elementExecution(node, grid, executionSequence, visited, graph);\n\n this.currentDebugStep += 1;\n return nextElements;\n };\n\n processGraph.genericTraversing(\n dfsGetNextNodes,\n dfsGetStartElement,\n );\n\n // flip grid on end\n if (grid.isFlipped) {\n grid.flip(false);\n }\n\n return grid;\n }\n\n generateDi(process , shift, procDi) {\n const { grid: layoutGrid } = process;\n\n const diFactory = this.diFactory;\n\n const prePlaneElement = procDi ? procDi : this.diagram.diagrams[0];\n\n const planeElement = prePlaneElement.plane.get('planeElement');\n\n // todo: убрать после нормальной реализации отрисовки\n const flowElsDIs = [];\n\n const maxLevel = process.lanesNestedSet.getMaxLevel();\n\n // 1 - лейбл пула\n // maxLevel + 1 level count\n const elXShift = (maxLevel + 2) * PARTICIPANT_LABEL_WIDTH;\n\n // Step 1: Create DI for all elements\n layoutGrid._elements.forEach((elementPosition, element) => {\n if (element.$type !== 'bpmn:Lane') {\n const curShift = { ...shift };\n if (layoutGrid.getLanes().length > 0) {\n curShift.x += elXShift;\n }\n const dis = createElementDi(element, elementPosition, diFactory, layoutGrid, curShift);\n flowElsDIs.push(...dis);\n }\n });\n\n // Step 2: Create DI for all connections\n layoutGrid._allEdges.forEach(edge => {\n const curShift = { ...shift };\n if (layoutGrid.getLanes().length > 0) {\n curShift.x += elXShift;\n }\n const connection = createConnection(edge, layoutGrid, diFactory, curShift);\n if (connection) flowElsDIs.push(connection);\n });\n\n // todo: убрать после нормальной реализации отрисовки\n // Пока сортируем для стабильности результата\n this.sortDIsByDefinitionPosition(flowElsDIs, process).forEach(item => planeElement.push(item));\n }\n\n sortDIsByDefinitionPosition(DIs, process) {\n return DIs.sort((a, b) => {\n const aIndex = process.flowElements?.findIndex(item => item.id === a.bpmnElement.id);\n const bIndex = process.flowElements?.findIndex(item => item.id === b.bpmnElement.id);\n return aIndex - bIndex;\n });\n }\n\n getRootProcesses() {\n return this.diagram.get('rootElements').filter(el => el.$type === 'bpmn:Process');\n }\n\n getCollaboration() {\n return this.diagram.get('rootElements').filter(el => el.$type === 'bpmn:Collaboration');\n }\n}\n\n/**\n * Check grid by columns or rows.\n * If it has elements with isExpanded === true,\n * find the maximum size of elements grids and expand the parent grid horizontally or vertically.\n * @param grid\n * @param {boolean=} byVertical\n */\nfunction expandGrid(grid, byVertical) {\n\n // todo: здесь можно оптимизировать добавив строки и колонки в грид\n const indexesToExpand = new Map();\n grid._elements.forEach((position, element) => {\n if (element.isExpanded) {\n const maxCount = indexesToExpand.get(byVertical ? position[0] : position[1]);\n let curCount = (!byVertical ? element.grid.colCount : element.grid.rowCount) || 1;\n const newCount = curCount + 1;\n byVertical ? position[3] = newCount : position[2] = newCount;\n if (maxCount === undefined || curCount > maxCount) {\n indexesToExpand.set(byVertical ? position[0] : position[1], curCount);\n }\n }\n });\n\n [ ...indexesToExpand.entries() ].sort(([ aKey ],[ bKey ]) => Number.parseInt(bKey) - Number.parseInt(aKey)).forEach(([ key, value ]) => {\n\n // расширяем лэйны начиная с последнего\n if (byVertical) {\n const lanes = grid.getLanes();\n for (const lane of lanes) {\n const lanePos = grid.find(lane);\n if (Number.parseInt(key) <= lanePos[0] + lanePos[3] - 1 && Number.parseInt(key) >= lanePos[0]) {\n lanePos[3] += Number.parseInt(value);\n }\n }\n }\n grid.addRowCol(!byVertical, key, value);\n });\n}\n","import { Layouter } from './Layouter.js';\n\nexport function layoutProcess(xml, debuggerCounter) {\n return new Layouter(debuggerCounter).layoutProcess(xml);\n}\n"],"names":["getDefaultSize","element","is","width","height","type","$instanceOf","getOutgoingElements","Error","outgoingElements","outgoing","map","out","targetRef","Set","DEFAULT_CELL_WIDTH","DEFAULT_CELL_HEIGHT","PARTICIPANT_LABEL_WIDTH","isFlipped","utilsGetOutgoingElements","concat","attachedOutgoing","attachers","sort","a","b","length","attacher","reverse","flat","filter","item","index","self","indexOf","add","getAttachedOutgoingElements","getMid","bounds","x","y","getDockingPoint","point","rectangle","dockingDirection","targetOrientation","test","original","coordinatesToPosition","grid","shift","row","col","find","getBounds","elementPosition","laneLevelDif","positionWidth","positionHeight","defaultWidth","defaultHeight","$type","DiFactory","constructor","moddle","this","create","attrs","createDiBounds","createDiLabel","createDiShape","semantic","assign","bpmnElement","createDiWaypoints","waypoints","pos","createDiWaypoint","pick","createDiEdge","waypoint","createDiPlane","createDiDiagram","Grid","_elements","Map","rows","cols","rowCount","Object","keys","colCount","elementsCount","size","elements","position","has","JSON","stringify","_addStart","lastRow","lastCol","rowDif","colDif","addRowCol","undefined","set","_addElementToRowsCols","get","_removeElementFromRowsCols","delete","getGridDimensions","move","toPosition","isValidPosition","newPos","removeElement","addCol","afterIndex","count","gridCount","addCount","i","entries","expandRow","rowIndex","Number","isInteger","gridColCount","forEach","elementsAtPosition","getElementsInRange","startRow","startCol","endRow","endCol","shrink","byVertical","sortedElements","previousIndex","newElPos","key","value","flip","newPosition","hasElement","Array","isArray","hasIntermediateElements","firstPosition","lastPosition","onVertical","start","end","values","some","hasElementAt","GridWithEdges","initialGraph","super","graph","Graph","getLanes","addNode","_createNewEdgesFor","lanePosition","laneRef","firstLaneRow","lastLaneRow","elementsInRow","deleteNode","_edgeIsExist","edge","edges","includes","_addEdgeToGrid","addEdge","getOutgoingEdgesFor","getIncomingEdgesFor","source","target","isCrossed","_allEdges","isIntersect","hasAnyCross","getCrossedElementsFor","shakeIt","aPos","bPos","sortColsLeftRightRowsBottomTop","pop","chain","getChain","chainElement","deleteIndex","splice","baseRow","baseCol","chainLane","laneRow","laneHeight","allPositionsAreFine","every","curPos","newPositionsAreFine","checkedRow","checkedCol","chainElementPosition","hasNewCrosses","newChain","oldChain","elInPos","el","getAllExistingEdgesFor","edgeDirection","getEdgeDirection","push","nextElement","nextChain","nextChainEl","getExistingOutgoingEdgesFor","getExistingIncomingEdgesFor","outgoingEdges","incomingEdges","_separateGrid","separatedGraphs","mergeGraphs","getSeparatedGraphs","grids","minRow","maxRow","node","nodes","_mergeGrids","newGrid","resGridRowCount","resGridColCount","getSourcePosition","getEdgeSource","getTargetPosition","getEdgeTarget","sourcePosition","targetPosition","id","sourceRow","sourceCol","targetRow","targetCol","vDifference","hDifference","getPathFor","direction","_pathForNoDirection","_pathForSouthToNorth","_pathForSouthWestToNorthEast","_pathForWestToEast","_pathForNorthWestToSouthEast","_pathForNorthToSouth","_pathForNorthEastToSouthWest","_pathForEastToWest","_pathForSouthEastToNorthWest","pathSegments","vCross","colIndex","hCross","crossedElements","segment","getBackwardUpOutgoingEdgesFor","getGridCopy","removeEdge","deleteEdge","getGraphSegmentFrom","genericTraversing","visited","executionSequence","nextEdges","nextNodes","getSegmentLeftCoordinates","leftCoordinates","nodeRow","nodeCol","lanes","lane","nextPos","lastRows","elLane","elRow","elHeight","elMaxRow","lanePos","elementExecution","pushVerticalEdgeBy","newOutgoing","reduce","prev","outgoingFromStack","hasNewOutgoings","incoming","elementCol","processingElements","inStackWithoutOutgoing","targetEdge","targetParent","sortElementsTopLeftBottomRight","processingElement","getOutgoingFromStack","nextElements","nextPosition","getInsertPosition","attachedToRef","fixNewCrosses","unshift","existingEdges","workingEdge","sourcePos","targetPos","gridCopy","graphSegment","segmentCords","from","minColPosition","acc","cur","minRowPosition","maxRowPosition","newMap","previousShiftPos","shiftPos","nodePosition","getShiftPos","moveTopLeftOutgoingForward","nextBoundaries","nextOther","inStack","nextEl","isBoundarySource","elementLane","nextElLane","elementLaneRow","nextElLaneRow","nextElLaneHeight","laneRowPosDif","elPos","allItemsInElementPosition","elementPositionEdges","crossedOrOccupied","stack","skipTopLeftOutgoing","aRow","aCol","bRow","bCol","fixNewVerticalCrosses","fixNewHorizontalCrosses","vCrossed","moveElementsRighterCrossLine","hCrossed","maxDown","getMaxDown","baseSourceRow","innerElement","moveElementsUpperCrossLine","moveElementsUnderCrossLine","createConnection","layoutGrid","diFactory","sourceDi","di","targetDi","sourceBounds","targetBounds","sourceMid","targetMid","sourceHeight","dX","dY","dockingSource","dockingTarget","sourceX","sourceY","targetX","targetY","sourceIsBoundary","isExpanded","firstPoint","lastPoint","maxExpanded","firstCol","getMaxExpandedBetween","hasReversEdge","hasSW_NEOut","elementsInHorizontal","candidate","directManhattan","totalElements","bendPoint","directManhattanConnect","startPoint","endPoint","yOffset","Math","sign","connectElements","createElementDi","host","hostPosition","hostBounds","DIs","neighboursBoundary","$parent","flowElements","aBottomRightChildPosition","getPositionRightBottomOutgoingElement","bBottomRightChildPosition","getSortedElementsByOutgoingPosition","att","arr","attacherDi","createBEl","options","isMarkerVisible","shapeDi","curPosition","Edge","NestedSet","object","getFirst","getNext","nestedSet","_init","resultNestedSet","level","curItem","left","maxRight","right","subItems","subLane","subPosition","getLeaves","getNested","isLeaf","getMaxLevel","nestPos","Layouter","debuggerCounter","BPMNModdle","maxDebugStep","currentDebugStep","layoutProcess","xml","moddleObj","fromXML","rootElement","diagram","bpmnModel","allElements","elementsById","processRef","flowNodeRef","setAdditionalPropsToElements","getLanesNestedSet","processTrees","createNestedSets","createGridsForProcesses","expandProcessesGrids","expandParticipants","rootProcesses","getRootProcesses","collaboration","getCollaboration","cleanDi","createRootDi","drawParticipants","drawProcesses","drawCollaborationMessageFlows","toXML","format","processes","process","hasLanes","laneSets","createGridLayout","tempGridCollection","expandGrid","participants","participant","createParticipantDi","sortedProcesses","getParticipantForProcess","participantDi","getElementDi","getProcDi","generateDi","existingNodes","baseProcDi","diagrams","plane","messageFlows","message","sourceRef","existNodes","planeElement","processGraph","allProcesses","getAllProcesses","children","getSubProcesses","child","rootProcess","getStartElement","root","getNextNodes","outgoingNode","mainElement","createProcessDi","planeDi","diagramDi","origin","nestedLanes","lanesNestedSet","maxLevel","poolOrigin","laneX","leaves","laneRowPos","curLeave","curGridPos","laneY","levelDif","laneWidth","laneDi","childLaneSet","flowElement","outgoingItem","newEdge","dataInputAssociations","association","dataSource","propRef","dataOutputAssociations","targetElementInGridSourceNotExist","primaryStartElements","types","typesArray","result","matching","sortByType","sourceElementInGridTargetNotExist","otherStartingElement","flippedStartElement","procDi","flowElsDIs","elXShift","curShift","dis","connection","sortDIsByDefinitionPosition","aIndex","findIndex","bIndex","indexesToExpand","maxCount","curCount","newCount","aKey","bKey","parseInt","exports"],"mappings":"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"}