diff --git a/open-bpmn.glsp-client/open-bpmn-glsp/src/bpmn-helperlines.tsx b/open-bpmn.glsp-client/open-bpmn-glsp/src/bpmn-helperlines.tsx deleted file mode 100644 index 7a237288..00000000 --- a/open-bpmn.glsp-client/open-bpmn-glsp/src/bpmn-helperlines.tsx +++ /dev/null @@ -1,630 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022 Imixs Software Solutions GmbH and others. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * This Source Code may also be made available under the following Secondary - * Licenses when the conditions for such availability set forth in the Eclipse - * Public License v. 2.0 are satisfied: GNU General Public License, version 2 - * with the GNU Classpath Exception which is available at - * https://www.gnu.org/software/classpath/license.html. - * - * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 - ********************************************************************************/ -import { - Action, - FeedbackCommand, - GModelElement, - GModelRoot, - GParentElement, - IActionHandler, - ISnapper, - MouseListener, - SetBoundsAction, - SetBoundsFeedbackAction, - findParentByFeature, - hasArgs, - hasObjectProp, - isBoundsAware -} from '@eclipse-glsp/client'; -import { - EventNode, - TaskNode, - isBPMNNode, - isBoundaryEvent, - isLaneDivider, - isTaskNode -} from '@open-bpmn/open-bpmn-model'; -import { inject, injectable } from 'inversify'; -import { VNode } from 'snabbdom'; -import { - CommandExecutionContext, - CommandReturn, - IView, - RenderingContext, - SChildElementImpl, - TYPES, - svg -} from 'sprotty'; -import { Bounds, Point } from 'sprotty-protocol'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const JSX = { createElement: svg }; - -/**************************************************************************** - * This module extends the mouseListener to support helper lines. - * HelperLines are displayed when a element is selected and dragged on the diagram pane. - * - * If the moved element is aligned to the center of another element on the diagram - * the helper line is shown. There are can be up to two helper-lines be displayed - * - horizontal and vertical - * - * The method 'findHelperLines' can be extended to provide more helper lines - * to show a different behavior. - ****************************************************************************/ - -/* - * The HelperLinesElement defines the SModelElement - * to containing a list of helperLines. - */ -export class HelperLinesElement extends SChildElementImpl { - override type: string; - override id: string; - readonly helperLines: ReadonlyArray = []; - constructor(type: string, id: string, helperLines: HelperLine[]) { - super(); - this.type = type; - this.id = id; - this.helperLines = helperLines; - } -} -export interface HelperLine { - readonly x1: number; - readonly y1: number; - readonly x2: number; - readonly y2: number; -} - - -@injectable() -export class BPMNHelperLineManager implements IActionHandler { - - //@inject(TYPES.IFeedbackActionDispatcher) protected feedbackDispatcher: IFeedbackActionDispatcher; - - - handle(action: Action): void { - console.log('...-- im handler **************'); - if (SetBoundsAction.is(action) || SetBoundsFeedbackAction.is(action)) { - this.handleSetBoundsAction(action); - } - } - protected handleSetBoundsAction(action: SetBoundsAction | SetBoundsFeedbackAction): void { - const elementIds = action.bounds.map(bound => bound.elementId); - - console.log('...-- im handler setBoundsAction' + elementIds); - - - } - - -} - - - -/** - * Snapper implementation to align elements. - * The snapper finds surrounding elements and snaps the - * current position if the alignment is not grater than 10 pixels. - * This leads to a magnetic snap behavior. - */ -@injectable() -export class BPMNElementSnapper implements ISnapper { - - // minimum snap range to catch a helper line - get minSnapRange(): number { - return 10; - } - - /* - * Find a possible snapPoint. - * A SnapPoint is found if the x or y coordinates matching the position - * of another element Node. This behavior is applied for all BPMNNode elements. - * - * For all other element we return general Snapper with 5px. - */ - snap(position: Point, element: GModelElement): Point { - let snapPoint: Point; - if (isLaneDivider(element)) { - snapPoint = this.findLaneDividerSnapPoint(element, position); - return snapPoint; - } - // Is it a Element node? - if (isBPMNNode(element) && isBoundsAware(element)) { - if (isBoundaryEvent(element)) { - snapPoint = this.findBoundarySnapPoint(element, position); - } else { - console.log('==============================='); - console.log('---- wir suchen einen Snap Point for ' + element.id + ' position=' + position.x + ',' + position.y); - // find default snap position - snapPoint = this.findSnapPoint(element); - // if a snapPoint was found and this snapPoint is still in the snapRange, - // then we adjust the current mouse Postion. Otherwise we return the current position - - //let snapX = (Math.round(position.x / this.minSnapRange) * this.minSnapRange); - let snapX = (Math.round(position.x)); - if (snapPoint.x > -1) { - // we have a hit - snapX = Math.round(element.bounds.x - snapPoint.x); - console.log(' - hurrar snapx=' + snapX); - } - - //let snapY = (Math.round(position.y / this.minSnapRange) * this.minSnapRange); - let snapY = (Math.round(position.y)); - if (snapPoint.y > -1) { - // we have a hit - snapY = Math.round(element.bounds.y - snapPoint.y); - console.log(' - hurrar snapy=' + snapY); - } - - - snapPoint = { x: snapX, y: snapY }; - } - - // fix BPMNLabel offset (only needed or Elements with a separate label)? - // if (isBPMNLabelNode(element)) { - // const xOffset = snapPoint.x - position.x; - // const yOffset = snapPoint.y - position.y; - // const label: any = element.root.index.getById(element.id + '_bpmnlabel'); - // if (label instanceof LabelNode) { - // // fix offset of the lable position.... - // const ly = label.position.y + yOffset; - // const lx = label.position.x + xOffset; - // label.position = { x: lx, y: ly }; - // } - // } - - - console.log('---- FINAL SnapPoint = ' + snapPoint.x + ',' + snapPoint.y); - - return snapPoint; - } - - // not a standard BPMN element - // return a snap grid with 5x5 (supporting the Gatway Width) - return { - x: Math.round(position.x / 5) * 5, - y: Math.round(position.y / 5) * 5 - }; - - } - - /* - * This helper method computes the snap Position of a BoundaryEvent. - * The position is based on the Bounds of the containing TaskElement. - * The final position is always on the edge of the TaskElement. - */ - private findBoundarySnapPoint(element: EventNode, position: Point): Point { - const offset = 18; - let x = position.x; - let y = position.y; - - if (hasArgs(element)) { - - // now we compute the x/y on the edge of the task bounds - - const taskRef = element.args.attachedToRef + ''; - // find the task... - const task = element.root.index.getById(taskRef); - if (task && task instanceof TaskNode) { - const taskCenter = Bounds.center(task.bounds); - // x-axis move - if (x >= task.bounds.x - offset && x <= (task.bounds.x - offset + task.bounds.width)) { - if (y + offset > taskCenter.y) { - y = task.position.y + task.bounds.height - offset; - } else { - y = task.position.y - offset; - } - } else if (y >= task.bounds.y - offset && y <= (task.bounds.y - offset + task.bounds.height)) { - // y-axis move - if (x + offset > taskCenter.x) { - x = task.position.x + task.bounds.width - offset; - } else { - x = task.position.x - offset; - } - } else { - // default - out of range = do not move - x = element.bounds.x; - y = element.bounds.y; - } - } - } - // return the new position; - return { x: x, y: y }; - } - - /* - * This helper method computes the snap Position of a Lane-Divider. - * The position is based on the Bounds of the containing Pool. - * The final position is always on the x position of the Pool. - */ - private findLaneDividerSnapPoint(element: GModelElement, position: Point): Point { - const x = 30; - let y = position.y; - // test min / max position - if (hasArgs(element)) { - const yMin = Number(element.args.ymin); - const yMax = Number(element.args.ymax); - if (y < yMin) { - y = yMin; - } - if (y > yMax) { - y = yMax; - } - } - // return the new position; - return { x: x, y: y }; - } - - /* - * This helper method searches the model for model elements - * matching the horizontal and/or vertical alignment of the given modelElement. - * - * A ModelElement is a aligned to another element if its center point matches - * the same x or y axis. The method returns up to two elements - vertical and/or horizontal - * - * The method takes into account an approximation of 10. (See method 'isNear') - * - */ - private findSnapPoint(modelElement: GModelElement): Point { - let x = -1; - let y = -1; - let childs: any; - - if (isBoundsAware(modelElement)) { - // we need to find out if we are in a container.... - if (modelElement instanceof SChildElementImpl) { - childs = modelElement.parent.children; - } - - const modelElementCenter = Bounds.center(modelElement.bounds); - console.log(' ... snap model element ' + modelElement.id + ' pos=' + modelElement.bounds.x + ',' + modelElement.bounds.y); - // In the following we iterate over all model elements - // and compare the x and y axis of the center points - for (const element of childs) { - if (element.id !== modelElement.id && isBPMNNode(element) && isBoundsAware(element)) { - console.log('----- test snap for element ' + element.id); - const elementCenter = Bounds.center(element.bounds); - // console.log(' ... found element ' + element.id + ' pos=' + elementCenter.x + ','+elementCenter.y); - if (elementCenter && modelElementCenter) { - // test horizontal alligment... - if (y === -1 && this.isNear(elementCenter.y, modelElementCenter.y)) { - // fount horizontal snap point - y = elementCenter.y - modelElement.bounds.height * 0.5; - console.log('------ Y is near = ' + y); - } - // test vertical alligment... - if (x === -1 && this.isNear(elementCenter.x, modelElementCenter.x)) { - // found vertical snap point! - x = elementCenter.x - modelElement.bounds.width * 0.5; - console.log('------ X is near = ' + x); - } - } - } - if (x > -1 && y > -1) { - // we can break here as we found already the maximum of two possible matches. - break; - } - } - } - // return snapPoint (-1,-1 if not match was found) - - console.log('---- Ergebnis von findSnapPoint = ' + x + ',' + y); - - return { x: x, y: y }; - } - - /** - * Returns true if the values are in a range of 10 - */ - private isNear(p1: number, p2: number): boolean { - const p3 = Math.abs(p1 - p2); - if (p3 < this.minSnapRange) { - return true; - } - return false; - } -} - - -/* - * The HelperLineListener reacts on mouseDown and mouseMove and searches for - * matching elements according to the current position of the dragged element. - * - * The listener just draws the lines, but does not snap the elements. This is the task of - * the BPMNElementSnapper. - */ -@injectable() -export class HelperLineListener extends MouseListener, IActionHandler { - protected isActive = false; - - override mouseDown(target: GModelElement, event: MouseEvent): Action[] { - // check if target is relevant.... - if (isBPMNNode(target) || target.type === 'icon' || target.type === 'bpmn-text-node') { - // switch into active mode - this.isActive = true; - } else { - this.isActive = false; - } - return []; - } - - /** - * This method acts on a mouseMove event if a BPMN element is selected (isActive==true). - * The method computes a list of helperLines to alligned elements in the diagram. - * If helper lines where found, the method fires the corresponding - * command to draw the helper lines. - */ - override mouseMove(target: GModelElement, event: MouseEvent): Action[] { - if (this.isActive) { - // if we have a bpmn-text-node we need ot find the corresponding Task node... - if (target.type === 'bpmn-text-node') { - const task = findParentByFeature(target, isTaskNode); - if (task) { - target = task; - } - } - // first test if we have a mouseMove on a BPMNNode - // const bpmnNode = isBPMNNode(target); - if (isBPMNNode(target)) { - const helperLines: HelperLine[] | undefined = this.findHelperLines(target); - if (helperLines) { - - // console.log('------- we found helper lines!'); - return [DrawHelperLinesAction.create({ helperLines: helperLines })]; - } else { - // now match! remove helper lines... - return [RemoveHelperLinesAction.create()]; - } - } - } - return []; - } - - /* - * On the mouseUp event we end the active mode and - * remove the HelperLines from the model - */ - override mouseUp(target: GModelElement, event: MouseEvent): Action[] { - this.isActive = false; - return [RemoveHelperLinesAction.create()]; // EnableDefaultToolsAction.create() - } - - /* - * Helper Method to find an optional parent pool of a given element. - * If the element is not part of a Pool the method returns undefined. - */ - private findPool(element: GModelElement): GModelElement | undefined { - const boundsAware = findParentByFeature(element, isBoundsAware); - if (boundsAware !== undefined) { - let current: GModelElement = boundsAware; - while (current instanceof SChildElementImpl) { - const parent = current.parent; - if ('pool' === parent.type) { - return parent; - } - current = parent; - } - } - // no pool found - return undefined; - } - - /* - * This helper method searches the model for model elements - * matching the horizontal and/or vertical alignment of the given modelElement. - * - * A ModelElement is a aligned to another element if its center point matches - * the same x or y axis. The method returns up to two helper lines. The helper lines - * go through the full dimensions of the canvas. - * - * The method can be extended to find more helper lines with a different algorithm. - */ - private findHelperLines(modelElement: GModelElement): HelperLine[] | undefined { - const root: GModelRoot = modelElement.root; - const helperLines: HelperLine[] = []; - let xOffset = 0; - let yOffset = 0; - if (root && isBoundsAware(modelElement)) { - let childs = root.children; - let canvasBounds = root.canvasBounds; - // test if we are in a pool... - const pool = this.findPool(modelElement); - if (pool) { - if (pool instanceof GParentElement) { - childs = pool.children; - } - if (isBoundsAware(pool)) { - canvasBounds = pool.bounds; - } - } - const _modelElementCenter = Bounds.center(modelElement.bounds); - const modelElementCenter = { x: Math.round(_modelElementCenter.x), y: Math.round(_modelElementCenter.y) }; - - // In the following we iterate over all model elements - // and compare the x and y axis of the center points - let foundHorizontal = false; - let foundVertical = false; - for (const element of childs) { - if (element.id !== modelElement.id && isBPMNNode(element) && isBoundsAware(element)) { - const _elementCenter = Bounds.center(element.bounds); - const elementCenter = { x: Math.round(_elementCenter.x), y: Math.round(_elementCenter.y) }; - - if (elementCenter && modelElementCenter) { - // console.log('--------- Model element : ' + modelElement.id + ' pos=' + modelElementCenter.x + ',' + modelElementCenter.y); - // console.log('--------- Refer element : ' + element.id + ' pos=' + elementCenter.x + ',' + elementCenter.y); - - - // test vertical alignment... - if (!foundHorizontal && elementCenter.y === modelElementCenter.y) { - if (pool && isBoundsAware(pool)) { - yOffset = canvasBounds.y; - xOffset = 0; - } else { - xOffset = canvasBounds.x; - yOffset = 0; - } - const horizontalLine: HelperLine = { - x1: canvasBounds.x - xOffset, - y1: elementCenter.y + yOffset, - x2: canvasBounds.x + canvasBounds.width - xOffset, - y2: elementCenter.y + yOffset - }; - foundHorizontal = true; - helperLines.push(horizontalLine); - } - // test horizontal alignment... - if (!foundVertical && elementCenter.x === modelElementCenter.x) { - if (pool && isBoundsAware(pool)) { - xOffset = canvasBounds.x; - yOffset = 0; - } else { - yOffset = canvasBounds.y; - xOffset = 0; - } - const verticalLine: HelperLine = { - x1: elementCenter.x + xOffset, - y1: canvasBounds.y - yOffset, - x2: elementCenter.x + xOffset, - y2: canvasBounds.y + canvasBounds.height - yOffset - }; - foundVertical = true; - helperLines.push(verticalLine); - } - } - } - if (foundHorizontal === true && foundVertical === true) { - // we can break here as we found already two possible matches. - break; - } - } - } - if (helperLines.length > 0) { - return helperLines; - } - return undefined; - } -} - -export const HELPLINE = 'helpline'; - -export function helpLineId(root: GModelRoot): string { - return root.id + '_' + HELPLINE; -} - -/** - * DrawHelperLines Action - */ -export interface DrawHelperLinesAction extends Action { - kind: typeof DrawHelperLinesAction.KIND; - helperLines: HelperLine[]; -} -export namespace DrawHelperLinesAction { - export const KIND = 'drawHelperLines'; - export function is(object: any): object is DrawHelperLinesAction { - return Action.hasKind(object, KIND) && hasObjectProp(object, 'helperLines'); - } - export function create(options: { helperLines: HelperLine[] }): DrawHelperLinesAction { - return { - kind: KIND, - ...options - }; - } -} - -/* - * The HelperLinesCommand creates the HelperLinesElement model element - * and adds it to the model. - */ -@injectable() -export class DrawHelperLinesCommand extends FeedbackCommand { - static readonly KIND = DrawHelperLinesAction.KIND; - - constructor(@inject(TYPES.Action) protected action: DrawHelperLinesAction) { - super(); - } - execute(context: CommandExecutionContext): CommandReturn { - const root = context.root; - removeHelperLines(root); - // create new helperLineElement.... - const helperLineElement = new HelperLinesElement(HELPLINE, helpLineId(root), this.action.helperLines); - root.add(helperLineElement); - return context.root; - } -} - -export interface RemoveHelperLinesAction extends Action { - kind: typeof RemoveHelperLinesAction.KIND; -} - -export namespace RemoveHelperLinesAction { - export const KIND = 'removeHelperLines'; - export function is(object: any): object is RemoveHelperLinesAction { - return Action.hasKind(object, KIND); - } - export function create(): RemoveHelperLinesAction { - return { kind: KIND }; - } -} - -/* - * HelperLine Command to remove the helperlines form the model - * called when mouse move event ended - */ -@injectable() -export class RemoveHelperLinesCommand extends FeedbackCommand { - static readonly KIND = RemoveHelperLinesAction.KIND; - execute(context: CommandExecutionContext): CommandReturn { - removeHelperLines(context.root); - return context.root; - } -} - -/* - * Helper method to remove the HelperLine element - * from the model. - */ -export function removeHelperLines(root: GModelRoot): void { - const helperLines = root.index.getById(helpLineId(root)); - if (helperLines instanceof SChildElementImpl) { - root.remove(helperLines); - } -} - -/* - * The HelperLineView shows the helper lines. - * The method draws either one line (horizontal|vertical) or both if two matching points are available. - * - * This View can be extended to display more helper lines in a different layout if needed. - */ -@injectable() -export class HelperLineView implements IView { - render(model: Readonly, context: RenderingContext): VNode { - const helperLines: ReadonlyArray = (model as HelperLinesElement).helperLines; - let vnode: any; - // draw only one helper line? - if (helperLines.length === 1) { - vnode = ; - } - // draw two helper lines (horizontal|vertical) - if (helperLines.length === 2) { - vnode = ( - - - - - ); - } - return vnode; - } -} diff --git a/open-bpmn.glsp-client/open-bpmn-glsp/src/bpmn-select-listeners.tsx b/open-bpmn.glsp-client/open-bpmn-glsp/src/bpmn-select-listeners.tsx index aa53feee..fc73fea9 100644 --- a/open-bpmn.glsp-client/open-bpmn-glsp/src/bpmn-select-listeners.tsx +++ b/open-bpmn.glsp-client/open-bpmn-glsp/src/bpmn-select-listeners.tsx @@ -15,8 +15,11 @@ ********************************************************************************/ import { ActionDispatcher, + GModelElement, GModelRoot, ISelectionListener, + ISnapper, + Point, SelectAction, TYPES, filter, @@ -26,7 +29,11 @@ import { import { isBPMNLabelNode, isBoundaryEvent, - isLaneNode, isPoolNode, isTaskNode + isEventNode, + isGatewayNode, + isLaneNode, + isPoolNode, + isTaskNode } from '@open-bpmn/open-bpmn-model'; import { inject, injectable } from 'inversify'; @@ -35,6 +42,49 @@ import { inject, injectable } from 'inversify'; * ****************************************************************************/ + + +/** + * A {@link ISnapper} implementation that snaps BPMN elements onto a fixed gride size. + * This snapper calulates the grid size based on the selected element to allign tasks, gateways and events. + * + */ +@injectable() +export class BPMNElementSnapper implements ISnapper { + constructor(public grid: { x: number; y: number } = { x: 10, y: 10 }) { } + + snap(position: Point, _element: GModelElement): Point { + + if (isTaskNode(_element)) { + return { + x: Math.round(position.x / 10) * 10, + y: Math.round(position.y / 10) * 10 + }; + } + + if (isGatewayNode(_element)) { + return { + x: Math.round(position.x / 5) * 5, + y: Math.round(position.y / 5) * 5 + }; + } + + if (isEventNode(_element)) { + return { + x: Math.round(position.x / 1) * 1, + y: Math.round(position.y / 1) * 1 + }; + } + + // default... + return { + x: Math.round(position.x / this.grid.x) * this.grid.x, + y: Math.round(position.y / this.grid.y) * this.grid.y + }; + } +} + + /** * This selectionListener selects additional associated BoundaryEvents and BPMNLabels. * This allows to move both independent Nodes (TaskNode and BoundaryEvent, Event|Gateway and BPMNLabel) diff --git a/open-bpmn.glsp-client/open-bpmn-glsp/src/di.config.ts b/open-bpmn.glsp-client/open-bpmn-glsp/src/di.config.ts index 2b6d52ce..f69060c0 100644 --- a/open-bpmn.glsp-client/open-bpmn-glsp/src/di.config.ts +++ b/open-bpmn.glsp-client/open-bpmn-glsp/src/di.config.ts @@ -23,17 +23,15 @@ import { GCompartmentView, GLabel, GLabelView, + IHelperLineOptions, LogLevel, RectangularNodeView, RoundedCornerNodeView, - SetBoundsAction, TYPES, - configureActionHandler, - configureCommand, configureDefaultModelElements, configureModelElement, - configureView, editLabelFeature, + helperLineModule, initializeDiagramContainer, moveFeature, selectFeature @@ -49,7 +47,8 @@ import { MessageNode, MultiLineTextNode, PoolNode, TaskNode, - TextAnnotationNode + TextAnnotationNode, + isBPMNNode } from '@open-bpmn/open-bpmn-model'; import 'balloon-css/balloon.min.css'; import { Container, ContainerModule } from 'inversify'; @@ -68,12 +67,6 @@ import { } from './bpmn-element-views'; -import { - DrawHelperLinesCommand, - HelperLineListener, - HelperLineView, - RemoveHelperLinesCommand -} from './bpmn-helperlines'; import { BPMNEdgeView } from './bpmn-routing-views'; @@ -82,11 +75,12 @@ import { BPMNPropertiesMouseListener, BPMNPropertyModule } from '@open-bpmn/open-bpmn-properties'; +// import { +// BPMNElementSnapper, +// BPMNHelperLineManager, +// } from './bpmn-helperlines'; import { BPMNElementSnapper, - BPMNHelperLineManager, -} from './bpmn-helperlines'; -import { BPMNMultiNodeSelectionListener, BPMNSelectionHelper } from './bpmn-select-listeners'; @@ -99,23 +93,19 @@ const bpmnDiagramModule = new ContainerModule((bind, unbind, isBound, rebind) => - //bind(TYPES.ISnapper).to(GridSnapper); - //bind(TYPES.ISnapper).toConstantValue(new GridSnapper({ x: 5, y: 5 })); - bind(TYPES.IContextMenuItemProvider).to(DeleteElementContextMenuItemProvider); // bpmn helper lines bind(TYPES.ISnapper).toConstantValue(new BPMNElementSnapper()); - bind(TYPES.MouseListener).to(HelperLineListener); - configureCommand({ bind, isBound }, DrawHelperLinesCommand); - configureCommand({ bind, isBound }, RemoveHelperLinesCommand); - configureView({ bind, isBound }, 'helpline', HelperLineView); - + //bind(TYPES.ISnapper).toConstantValue(new GridSnapper({ x: 5, y: 5 })); + bind(TYPES.IHelperLineOptions).toConstantValue({ + alignmentElementFilter: element => + isBPMNNode(element), + minimumMoveDelta: { x: 10, y: 10 } + }); - //bind(TYPES.Action).toConstantValue(new BPMNHelperLineManager()); - configureActionHandler(context, SetBoundsAction.KIND, BPMNHelperLineManager); // bind new SelectionListener for BPMNLabels and BoundaryEvents @@ -205,7 +195,7 @@ export function initializeBPMNDiagramContainer(container: Container, // return initializeDiagramContainer(container, bpmnDiagramModule, ...containerConfiguration); - return initializeDiagramContainer(container, bpmnDiagramModule, BPMNPropertyModule, ...containerConfiguration); + return initializeDiagramContainer(container, bpmnDiagramModule, helperLineModule, BPMNPropertyModule, ...containerConfiguration); } diff --git a/open-bpmn.glsp-client/workspace/test.bpmn b/open-bpmn.glsp-client/workspace/test.bpmn new file mode 100644 index 00000000..cae2d987 --- /dev/null +++ b/open-bpmn.glsp-client/workspace/test.bpmn @@ -0,0 +1,95 @@ + + + + + + + sequenceFlow_lSyUUw + sequenceFlow_Z90WfQ + sequenceFlow_FM0m0Q + + + + sequenceFlow_fOGZ3Q + sequenceFlow_FM0m0Q + + + + sequenceFlow_lSyUUw + + + + sequenceFlow_1avBJw + sequenceFlow_fOGZ3Q + + + + sequenceFlow_Z90WfQ + sequenceFlow_1avBJw + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/open-bpmn.glsp-client/yarn.lock b/open-bpmn.glsp-client/yarn.lock index e3e88805..f8410957 100644 --- a/open-bpmn.glsp-client/yarn.lock +++ b/open-bpmn.glsp-client/yarn.lock @@ -10814,6 +10814,7 @@ workerpool@6.2.1: integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + name wrap-ansi-cjs version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==