From 4343fae2e31332aa000671e53c37291b86410461 Mon Sep 17 00:00:00 2001
From: winloong <21272660+vinloong@users.noreply.github.com>
Date: Mon, 16 May 2022 10:45:29 +0800
Subject: [PATCH] add code
---
.mvn/wrapper/MavenWrapperDownloader.java | 117 +
.mvn/wrapper/maven-wrapper.properties | 2 +
Dockerfile | 10 +
camunda-workflow-deployment.yml | 53 +
camundaDemo.iml | 179 +
mvnw | 310 +
mvnw.cmd | 182 +
pom.xml | 213 +
.../bpm/example/ExampleApplication.java | 52 +
.../bpm/example/conf/BasicPathAuthConfig.java | 108 +
.../bpm/example/conf/DemoWebMvcConfig.java | 87 +
.../controller/DeploymentController.java | 80 +
.../example/controller/HistoryController.java | 32 +
.../controller/ProcessInstanceController.java | 106 +
.../example/controller/TaskController.java | 305 +
.../example/controller/UserController.java | 147 +
.../bpm/example/entity/CSResponse.java | 53 +
.../bpm/example/entity/CommonEnum.java | 31 +
.../bpm/example/entity/Countersign.java | 17 +
.../example/entity/ObjectMemberEntity.java | 24 +
.../example/entity/ProcessDefineEntity.java | 23 +
.../example/entity/ProcessInstanceEntity.java | 15 +
.../bpm/example/entity/TaskEntity.java | 16 +
.../bpm/example/entity/TaskRequestEntity.java | 19 +
.../bpm/example/entity/TurnDownEntity.java | 24 +
.../camunda/bpm/example/entity/UserInfo.java | 10 +
.../bpm/example/entity/UserInfoEntity.java | 39 +
.../bpm/example/entity/UserRequestEntity.java | 15 +
.../example/entity/UserResponseEntity.java | 16 +
.../bpm/example/mapper/UserMapper.java | 22 +
.../bpm/example/service/UserService.java | 19 +
.../example/service/impl/UserServiceImpl.java | 67 +
.../camunda/bpm/example/utils/UserUtil.java | 59 +
src/main/resources/META-INF/processes.xml | 13 +
src/main/resources/application.yml | 65 +
src/main/resources/logback-spring.xml | 61 +
.../resources/mybatis/mapper/UserMapper.xml | 35 +
.../resources/static/camunda-swagger-ui.html | 6 +
src/main/resources/static/css/app.css | 749 +
src/main/resources/static/css/diagram-js.css | 683 +
src/main/resources/static/index.js | 82378 ++++++++++++++++
src/main/resources/static/modeler.html | 51 +
.../vendor/bpmn-font/css/bpmn-codes.css | 107 +
.../vendor/bpmn-font/css/bpmn-embedded.css | 160 +
.../static/vendor/bpmn-font/css/bpmn.css | 162 +
.../static/vendor/bpmn-font/font/bpmn.eot | Bin 0 -> 41724 bytes
.../static/vendor/bpmn-font/font/bpmn.svg | 117 +
.../static/vendor/bpmn-font/font/bpmn.ttf | Bin 0 -> 41572 bytes
.../static/vendor/bpmn-font/font/bpmn.woff | Bin 0 -> 14248 bytes
.../resources/static/vendor/diagram-js.css | 683 +
.../bpm/example/ExampleApplicationTests.java | 13 +
51 files changed, 87735 insertions(+)
create mode 100644 .mvn/wrapper/MavenWrapperDownloader.java
create mode 100644 .mvn/wrapper/maven-wrapper.properties
create mode 100644 Dockerfile
create mode 100644 camunda-workflow-deployment.yml
create mode 100644 camundaDemo.iml
create mode 100644 mvnw
create mode 100644 mvnw.cmd
create mode 100644 pom.xml
create mode 100644 src/main/java/com/fs/camunda/bpm/example/ExampleApplication.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/conf/BasicPathAuthConfig.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/conf/DemoWebMvcConfig.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/controller/DeploymentController.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/controller/HistoryController.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/controller/ProcessInstanceController.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/controller/TaskController.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/controller/UserController.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/CSResponse.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/CommonEnum.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/Countersign.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/ObjectMemberEntity.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/ProcessDefineEntity.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/ProcessInstanceEntity.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/TaskEntity.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/TaskRequestEntity.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/TurnDownEntity.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/UserInfo.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/UserInfoEntity.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/UserRequestEntity.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/entity/UserResponseEntity.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/mapper/UserMapper.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/service/UserService.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/service/impl/UserServiceImpl.java
create mode 100644 src/main/java/com/fs/camunda/bpm/example/utils/UserUtil.java
create mode 100644 src/main/resources/META-INF/processes.xml
create mode 100644 src/main/resources/application.yml
create mode 100644 src/main/resources/logback-spring.xml
create mode 100644 src/main/resources/mybatis/mapper/UserMapper.xml
create mode 100644 src/main/resources/static/camunda-swagger-ui.html
create mode 100644 src/main/resources/static/css/app.css
create mode 100644 src/main/resources/static/css/diagram-js.css
create mode 100644 src/main/resources/static/index.js
create mode 100644 src/main/resources/static/modeler.html
create mode 100644 src/main/resources/static/vendor/bpmn-font/css/bpmn-codes.css
create mode 100644 src/main/resources/static/vendor/bpmn-font/css/bpmn-embedded.css
create mode 100644 src/main/resources/static/vendor/bpmn-font/css/bpmn.css
create mode 100644 src/main/resources/static/vendor/bpmn-font/font/bpmn.eot
create mode 100644 src/main/resources/static/vendor/bpmn-font/font/bpmn.svg
create mode 100644 src/main/resources/static/vendor/bpmn-font/font/bpmn.ttf
create mode 100644 src/main/resources/static/vendor/bpmn-font/font/bpmn.woff
create mode 100644 src/main/resources/static/vendor/diagram-js.css
create mode 100644 src/test/java/com/fs/camunda/bpm/example/ExampleApplicationTests.java
diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
new file mode 100644
index 0000000..e76d1f3
--- /dev/null
+++ b/.mvn/wrapper/MavenWrapperDownloader.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+ private static final String WRAPPER_VERSION = "0.5.6";
+ /**
+ * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+ */
+ private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+ /**
+ * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+ * use instead of the default one.
+ */
+ private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+ ".mvn/wrapper/maven-wrapper.properties";
+
+ /**
+ * Path where the maven-wrapper.jar will be saved to.
+ */
+ private static final String MAVEN_WRAPPER_JAR_PATH =
+ ".mvn/wrapper/maven-wrapper.jar";
+
+ /**
+ * Name of the property which should be used to override the default download url for the wrapper.
+ */
+ private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+ public static void main(String args[]) {
+ System.out.println("- Downloader started");
+ File baseDirectory = new File(args[0]);
+ System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+ // If the maven-wrapper.properties exists, read it and check if it contains a custom
+ // wrapperUrl parameter.
+ File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+ String url = DEFAULT_DOWNLOAD_URL;
+ if(mavenWrapperPropertyFile.exists()) {
+ FileInputStream mavenWrapperPropertyFileInputStream = null;
+ try {
+ mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+ Properties mavenWrapperProperties = new Properties();
+ mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+ url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+ } catch (IOException e) {
+ System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+ } finally {
+ try {
+ if(mavenWrapperPropertyFileInputStream != null) {
+ mavenWrapperPropertyFileInputStream.close();
+ }
+ } catch (IOException e) {
+ // Ignore ...
+ }
+ }
+ }
+ System.out.println("- Downloading from: " + url);
+
+ File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+ if(!outputFile.getParentFile().exists()) {
+ if(!outputFile.getParentFile().mkdirs()) {
+ System.out.println(
+ "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+ }
+ }
+ System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+ try {
+ downloadFileFromURL(url, outputFile);
+ System.out.println("Done");
+ System.exit(0);
+ } catch (Throwable e) {
+ System.out.println("- Error downloading");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+ if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+ String username = System.getenv("MVNW_USERNAME");
+ char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+ }
+ });
+ }
+ URL website = new URL(urlString);
+ ReadableByteChannel rbc;
+ rbc = Channels.newChannel(website.openStream());
+ FileOutputStream fos = new FileOutputStream(destination);
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ fos.close();
+ rbc.close();
+ }
+
+}
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..642d572
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..efc9d23
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,10 @@
+FROM openjdk:8-jdk
+
+MAINTAINER cheeyy
+
+WORKDIR /app
+
+COPY ./target/camunda-service.jar /app/camunda-service.jar
+
+ENTRYPOINT [ "java", "-jar", "camunda-service.jar" ]
+
diff --git a/camunda-workflow-deployment.yml b/camunda-workflow-deployment.yml
new file mode 100644
index 0000000..1a199c4
--- /dev/null
+++ b/camunda-workflow-deployment.yml
@@ -0,0 +1,53 @@
+apiVersion: apps/v1beta2 # for versions before 1.8.0 use apps/v1beta1
+kind: Deployment
+metadata:
+ name: anxinyun-camunda-workflow
+ namespace: anxinyun
+ labels:
+ app: cwprocess
+spec:
+ selector:
+ matchLabels:
+ app: cwprocess
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: cwprocess
+ spec:
+ containers:
+ - name: anxinyun-camunda-workflow
+ image: repository.anxinyun.cn/anxinyun/camunda-workflow:dragon.1
+ command: [ "java", "-jar", "camunda-service.jar" ]
+ args: [ "--spring.datasource.driver-class-name=org.postgresql.Driver","--spring.datasource.url=jdbc:postgresql://10.8.30.39:5432/camunda","--spring.datasource.username=FashionAdmin","--spring.datasource.password=123" ]
+ volumeMounts:
+ - name: hostfile
+ mountPath: /etc/hosts
+ - name: localtime
+ mountPath: /etc/localtime
+ volumes:
+ - name: hostfile
+ hostPath:
+ path: /etc/hosts
+ - name: localtime
+ hostPath:
+ path: /etc/localtime
+ imagePullSecrets:
+ - name: anxinsecret
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: anxinyun-camunda-workflow
+ labels:
+ app: cwprocess
+ namespace: anxinyun
+spec:
+ type: ClusterIP
+ ports:
+ - port: 19094
+ targetPort: 8080
+ selector:
+ app: cwprocess
+ externalIPs:
+ - 10.8.30.157
diff --git a/camundaDemo.iml b/camundaDemo.iml
new file mode 100644
index 0000000..4c5e596
--- /dev/null
+++ b/camundaDemo.iml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mvnw b/mvnw
new file mode 100644
index 0000000..a16b543
--- /dev/null
+++ b/mvnw
@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
new file mode 100644
index 0000000..c8d4337
--- /dev/null
+++ b/mvnw.cmd
@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ac5b5ac
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,213 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.3
+
+
+ com.fs.camunda.bpm
+ example
+ 0.0.1-SNAPSHOT
+ example
+ Demo project for Spring Boot
+
+
+ 1.8
+ 7.15.0
+ 2.4.3
+ 1.8
+ 1.8
+ UTF-8
+ UTF-8
+ 2.5.0
+ 5.1.47
+ 7.8.0
+ 1.8.0
+ 3.20.9
+ 2.9.2
+ 1.2.31
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring-boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.1.1
+
+
+
+ org.mybatis.generator
+ mybatis-generator-core
+ 1.3.5
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.2
+ provided
+
+
+
+ org.camunda.bpm.springboot
+ camunda-bpm-spring-boot-starter-rest
+ ${camunda.spring-boot.version}
+
+
+ org.camunda.bpm.springboot
+ camunda-bpm-spring-boot-starter-webapp
+ ${camunda.spring-boot.version}
+
+
+ org.camunda.spin
+ camunda-spin-dataformat-all
+ ${camunda-spin.version}
+
+
+ mysql
+ mysql-connector-java
+ ${mysql-connector.version}
+
+
+
+
+ org.postgresql
+ postgresql
+ 42.1.1
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+ org.glassfish.hk2
+ hk2
+ ${hk2.version}
+
+
+ org.glassfish.hk2
+ spring-bridge
+ ${hk2.version}
+
+
+ org.camunda.bpm.extension.swagger
+ camunda-bpm-swagger-json
+ ${camunda-swagger.version}
+
+
+ org.webjars
+ swagger-ui
+ ${swagger-ui.version}
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${springfox.version}
+
+
+ io.springfox
+ springfox-swagger-ui
+ ${springfox.version}
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ com.alibaba
+ fastjson
+ ${fastjson.version}
+
+
+ de.odysseus.juel
+ juel-impl
+ 2.2.7
+
+
+
+ camunda-service
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ com.fs.camunda.bpm.example.ExampleApplication
+
+
+
+
+ repackage
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+ utf-8
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+
+
+
+
+
+ fs-releases
+ fs-releases
+ http://10.8.30.22:8081/repository/fs-releases/
+
+
+
+
diff --git a/src/main/java/com/fs/camunda/bpm/example/ExampleApplication.java b/src/main/java/com/fs/camunda/bpm/example/ExampleApplication.java
new file mode 100644
index 0000000..757f583
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/ExampleApplication.java
@@ -0,0 +1,52 @@
+package com.fs.camunda.bpm.example;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fs.camunda.bpm.example.conf.BasicPathAuthConfig;
+import org.camunda.bpm.spring.boot.starter.annotation.EnableProcessApplication;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Scope;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.Map;
+import java.util.Properties;
+
+@SpringBootApplication
+@EnableProcessApplication
+@ComponentScan("com")
+@EnableSwagger2
+public class ExampleApplication {
+
+ private static Logger logger = LoggerFactory.getLogger(ExampleApplication.class);
+ public static void main(String[] args) {
+
+ Map getenv = System.getenv();
+
+ logger.info("环境变量:"+JSON.toJSON(getenv));
+ Resource resource = new ClassPathResource("application.yml");
+ Properties properties = null;
+ YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
+ yamlFactory.setResources(resource);
+ properties = yamlFactory.getObject();
+ logger.info("配置文件参数内容:"+ JSON.toJSON(properties));
+ SpringApplication.run(ExampleApplication.class, args);
+ }
+
+ //关闭spring boot jackson的FAIL_ON_EMPTY_BEANS
+ @Bean
+ public ObjectMapper objectMapper() {
+ return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
+ }
+
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/conf/BasicPathAuthConfig.java b/src/main/java/com/fs/camunda/bpm/example/conf/BasicPathAuthConfig.java
new file mode 100644
index 0000000..abda7fe
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/conf/BasicPathAuthConfig.java
@@ -0,0 +1,108 @@
+package com.fs.camunda.bpm.example.conf;
+
+import com.fs.camunda.bpm.example.entity.CSResponse;
+import com.fs.camunda.bpm.example.entity.CommonEnum;
+import com.fs.camunda.bpm.example.utils.UserUtil;
+import org.camunda.bpm.engine.IdentityService;
+import org.camunda.bpm.engine.ProcessEngine;
+import org.camunda.bpm.engine.impl.IdentityServiceImpl;
+import org.camunda.bpm.engine.impl.digest._apacheCommonsCodec.Base64;
+import org.camunda.bpm.engine.rest.exception.InvalidRequestException;
+import org.camunda.bpm.engine.rest.util.EngineUtil;
+import org.camunda.bpm.webapp.impl.security.auth.AuthenticationDto;
+import org.camunda.bpm.webapp.impl.security.auth.AuthenticationService;
+import org.camunda.bpm.webapp.impl.security.auth.Authentications;
+import org.camunda.bpm.webapp.impl.security.auth.UserAuthentication;
+import org.camunda.bpm.webapp.impl.util.ProcessEngineUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+
+/**
+ * Created by cheeyy on 2020/5/25.
+ */
+public class BasicPathAuthConfig implements Filter {
+
+ private Logger logger = LoggerFactory.getLogger(BasicPathAuthConfig.class);
+
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+
+ logger.info("init方法");
+ }
+
+
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+ logger.info("请求进入过滤验证功能");
+ HttpServletRequest request = (HttpServletRequest) servletRequest;
+// logger.info("请求url为:"+request.getRequestURL().toString());
+ logger.info("请求路径为:"+request.getRequestURI());
+ if(request.getRequestURI().contains("login") || request.getRequestURI().contains("default")|| request.getRequestURI().contains("api")
+ || request.getRequestURI().contains("app")|| request.getRequestURI().contains("lib")){
+ filterChain.doFilter(servletRequest, servletResponse);
+ }else{
+ String header = request.getHeader("Authorization");
+ if (header == null || !header.startsWith("Basic ")) {
+ throw new ServletException("No Auth info");
+ }
+ boolean checkPassword = false;
+ String userName = "";
+ ProcessEngine engine = getAddressedEngine("default");
+ String encodedCredentials = header.substring(6);
+ String decodedCredentials = new String(Base64.decodeBase64(encodedCredentials),"UTF-8");
+ int firstColonIndex = decodedCredentials.indexOf(":");
+ if (firstColonIndex == -1) {
+ throw new ServletException("Auth params is lost");
+ } else {
+ userName = decodedCredentials.substring(0, firstColonIndex);
+ String password = decodedCredentials.substring(firstColonIndex + 1);
+ checkPassword = engine.getIdentityService().checkPassword(userName, password);
+ }
+ if(!checkPassword){
+ throw new ServletException("username or password is fault");
+ }
+ logger.info("登陆用户为:"+userName);
+ auth(userName,request);
+ engine.getIdentityService().setAuthenticatedUserId(userName);
+ logger.info("流程继续执行");
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+
+ }
+
+ protected ProcessEngine getAddressedEngine(String engineName) {
+ return EngineUtil.lookupProcessEngine(engineName);
+ }
+
+ @Override
+ public void destroy() {
+
+ }
+
+
+ public Response auth(String username,HttpServletRequest request){
+ String engineName = "default";
+ final ProcessEngine processEngine = ProcessEngineUtil.lookupProcessEngine(engineName);
+ if(processEngine == null) {
+ throw new InvalidRequestException(Response.Status.BAD_REQUEST, "Process engine with name "+engineName+" does not exist");
+ }
+ // make sure authentication is executed without authentication :)
+ processEngine.getIdentityService().clearAuthentication();
+
+ AuthenticationService authenticationService = new AuthenticationService();
+ UserAuthentication authentication = (UserAuthentication) authenticationService.createAuthenticate(processEngine, username, null, null);
+ if (request != null) {
+ Authentications.revalidateSession(request, authentication);
+ }
+ return Response.ok(AuthenticationDto.fromAuthentication(authentication)).build();
+
+ }
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/conf/DemoWebMvcConfig.java b/src/main/java/com/fs/camunda/bpm/example/conf/DemoWebMvcConfig.java
new file mode 100644
index 0000000..a4cd0af
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/conf/DemoWebMvcConfig.java
@@ -0,0 +1,87 @@
+package com.fs.camunda.bpm.example.conf;
+
+
+import org.camunda.bpm.engine.rest.security.auth.impl.HttpBasicAuthenticationProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.lang.Nullable;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.util.Arrays;
+import java.util.List;
+
+
+@Configuration
+public class DemoWebMvcConfig implements WebMvcConfigurer {
+ private static final Logger logger = LoggerFactory.getLogger(DemoWebMvcConfig.class);
+
+
+ //请求过滤器 暂时还没用 后续应该与session搭配使用
+
+
+ private static List AUTH_WHITELIST=Arrays.asList(
+ // -- swagger ui
+ "/v2/api-docs"
+ );
+
+ @Bean
+ public FilterRegistrationBean SenseSsoOauthWebFilterFilterRegistration() {
+
+ FilterRegistrationBean registration = new FilterRegistrationBean();
+ registration.setFilter(new BasicPathAuthConfig());//创建上面的自定义的WebFilter对象
+ registration.addUrlPatterns("/*");
+ registration.setName("BasicAuthConfig");//该Filter的名字,自己随便定义
+ registration.setOrder(1);//启动时候的优先级
+ return registration;
+
+ }
+
+
+ @Override
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+ configurer.enable();
+ }
+
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+// registry.addResourceHandler("/app/**").addResourceLocations(classpath + "/app/");
+
+ }
+
+
+
+ /*@Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(new HandlerInterceptor() {
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+ throws Exception {
+ String requestURI = request.getRequestURI();
+ logger.info(">>>>>>>>>>>>>请求路径>>>>>>>>>>>>>>>>" + requestURI);
+ for (String singleAuth : AUTH_WHITELIST) {
+ if (requestURI.contains(singleAuth)) {
+ return true;
+ }
+ }
+ return true;
+ }
+ @Override
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
+ @Nullable Exception ex) throws Exception {
+
+ }
+ });
+ }*/
+
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/controller/DeploymentController.java b/src/main/java/com/fs/camunda/bpm/example/controller/DeploymentController.java
new file mode 100644
index 0000000..97963e5
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/controller/DeploymentController.java
@@ -0,0 +1,80 @@
+package com.fs.camunda.bpm.example.controller;
+
+import com.fs.camunda.bpm.example.entity.CSResponse;
+import com.fs.camunda.bpm.example.entity.CommonEnum;
+import com.fs.camunda.bpm.example.utils.UserUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.camunda.bpm.engine.*;
+import org.camunda.bpm.engine.identity.User;
+import org.camunda.bpm.engine.repository.Deployment;
+import org.camunda.bpm.engine.repository.DeploymentBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.zip.ZipInputStream;
+
+@RestController
+@RequestMapping("/repository")
+public class DeploymentController {
+
+
+ private Logger logger = LoggerFactory.getLogger(DeploymentController.class);
+
+ @Autowired
+ private RepositoryService repositoryService;
+
+ @Autowired
+ private RuntimeService runtimeService;
+
+ @Autowired
+ private TaskService taskService;
+
+ @Autowired
+ private IdentityService identityService;
+
+ private ProcessEngine engine ;
+
+
+ @RequestMapping(value = "/deployments")
+ public CSResponse deployments(@RequestParam(value = "file")MultipartFile file,@RequestParam(value = "image",required = false)MultipartFile image, HttpServletRequest request){
+ try{
+ String username = UserUtil.getLoginUserName(request);
+ if(username == "" ){
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc(),"用户未登录");
+ }
+ identityService.setAuthenticatedUserId(username);
+ DeploymentBuilder deployment = repositoryService.createDeployment();
+
+ String filename = file.getOriginalFilename();
+ if(StringUtils.isEmpty(filename)){
+ filename = file.getName();
+ }
+
+ if(filename.endsWith(".bpm20.xml")||filename.endsWith("bpmn")){
+ if(image!=null){
+ deployment.addInputStream(image.getOriginalFilename(),image.getInputStream());
+ }
+ deployment.addInputStream(filename,file.getInputStream());
+ }else if(filename.endsWith(".zip")||filename.endsWith(".bar")){
+ deployment.addZipInputStream(new ZipInputStream(file.getInputStream()));
+ }else{
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc()
+ ,"请上传 .bpmn20.xml, .bpmn, .bar or .zip 类型文件");
+ }
+ deployment.name(filename);
+ Deployment deploy = deployment.deploy();
+ identityService.setAuthenticatedUserId(null);
+ return new CSResponse("流程部署成功,id:"+deploy.getId()+",name:"+deploy.getName());
+ }catch (Exception e){
+ logger.error("deployments 出现异常 , 原因:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+ }
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/controller/HistoryController.java b/src/main/java/com/fs/camunda/bpm/example/controller/HistoryController.java
new file mode 100644
index 0000000..374699c
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/controller/HistoryController.java
@@ -0,0 +1,32 @@
+package com.fs.camunda.bpm.example.controller;
+
+import org.camunda.bpm.engine.HistoryService;
+import org.camunda.bpm.engine.history.HistoricProcessInstanceQuery;
+import org.camunda.bpm.engine.history.HistoricVariableInstance;
+import org.camunda.bpm.engine.history.HistoricVariableInstanceQuery;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Created by cheeyy on 2020/6/30.
+ */
+@RestController
+public class HistoryController {
+
+ @Autowired
+ private HistoryService historyService;
+
+
+ @RequestMapping("/varaibles")
+ public List getVaraibles(@RequestParam String processInstId){
+ HistoricVariableInstanceQuery historicVariableInstanceQuery = historyService.createHistoricVariableInstanceQuery();
+ List file = historicVariableInstanceQuery.processInstanceId(processInstId).variableTypeIn("file").list();
+ return file;
+ }
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/controller/ProcessInstanceController.java b/src/main/java/com/fs/camunda/bpm/example/controller/ProcessInstanceController.java
new file mode 100644
index 0000000..81523db
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/controller/ProcessInstanceController.java
@@ -0,0 +1,106 @@
+package com.fs.camunda.bpm.example.controller;
+
+import com.fs.camunda.bpm.example.entity.CSResponse;
+import com.fs.camunda.bpm.example.entity.CommonEnum;
+import com.fs.camunda.bpm.example.entity.ProcessDefineEntity;
+import com.fs.camunda.bpm.example.entity.ProcessInstanceEntity;
+import com.fs.camunda.bpm.example.utils.UserUtil;
+import org.camunda.bpm.engine.*;
+import org.camunda.bpm.engine.identity.User;
+import org.camunda.bpm.engine.repository.ProcessDefinition;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.camunda.bpm.engine.task.TaskQuery;
+import org.camunda.bpm.model.bpmn.BpmnModelInstance;
+import org.camunda.bpm.webapp.impl.security.auth.Authentication;
+import org.camunda.bpm.webapp.impl.security.auth.AuthenticationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Scanner;
+
+@RestController
+public class ProcessInstanceController {
+
+ private Logger logger = LoggerFactory.getLogger(ProcessInstanceController.class);
+
+
+ @Autowired
+ private RepositoryService repositoryService;
+
+ @Autowired
+ private RuntimeService runtimeService;
+
+ @Autowired
+ private TaskService taskService;
+
+ @Autowired
+ private IdentityService identityService;
+
+ @Autowired
+ private ProcessEngine processEngine;
+
+
+ @RequestMapping("/process-definition/start")
+ public CSResponse startProcessInstance(@RequestBody ProcessDefineEntity processDefineEntity, HttpServletRequest request){
+
+ try{
+
+ String username = UserUtil.getLoginUserName(request);
+ if(username == "" ){
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc(),"用户未登录");
+ }
+ identityService.setAuthenticatedUserId(username);
+ String processDefineId = processDefineEntity.getProcessDefineId();
+ HashMap variables = (HashMap) processDefineEntity.getVariables();
+ //根据流程定义id来启动实例
+ runtimeService.startProcessInstanceById(processDefineId,variables);
+ identityService.setAuthenticatedUserId(null);
+ return new CSResponse("流程实例启动");
+ }catch (Exception e){
+ logger.error("启动流程实例失败,原因:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+
+ }
+
+
+ @RequestMapping("/process-definition/delete")
+ public CSResponse deleteProcessInstance(@RequestBody ProcessInstanceEntity processInstanceEntity, HttpServletRequest request){
+ try{
+ if(processInstanceEntity.getProcessInstanceId() == null){
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),"流程实例id不可为空");
+ }
+ if(processInstanceEntity.getReason() == null){
+ processInstanceEntity.setReason("");
+ }
+ runtimeService.deleteProcessInstance(processInstanceEntity.getProcessInstanceId(),processInstanceEntity.getReason());
+ return new CSResponse("流程驳回成功");
+ }catch (Exception e){
+ logger.error("流程驳回失败,原因:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),"流程驳回失败");
+ }
+ }
+
+
+
+
+
+
+
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/controller/TaskController.java b/src/main/java/com/fs/camunda/bpm/example/controller/TaskController.java
new file mode 100644
index 0000000..fe94ccf
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/controller/TaskController.java
@@ -0,0 +1,305 @@
+package com.fs.camunda.bpm.example.controller;
+
+import com.fs.camunda.bpm.example.entity.*;
+import com.fs.camunda.bpm.example.utils.UserUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.camunda.bpm.engine.*;
+import org.camunda.bpm.engine.history.HistoricActivityInstance;
+import org.camunda.bpm.engine.history.HistoricTaskInstance;
+import org.camunda.bpm.engine.history.HistoricTaskInstanceQuery;
+import org.camunda.bpm.engine.identity.User;
+import org.camunda.bpm.engine.rest.dto.VariableValueDto;
+import org.camunda.bpm.engine.rest.dto.runtime.TriggerVariableValueDto;
+import org.camunda.bpm.engine.rest.dto.task.TaskDto;
+import org.camunda.bpm.engine.runtime.ActivityInstance;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.camunda.bpm.engine.task.Task;
+import org.camunda.bpm.engine.task.TaskQuery;
+import org.camunda.bpm.model.bpmn.Bpmn;
+import org.camunda.bpm.model.bpmn.BpmnModelInstance;
+import org.camunda.bpm.model.bpmn.builder.ProcessBuilder;
+import org.camunda.bpm.model.bpmn.builder.UserTaskBuilder;
+import org.camunda.bpm.model.bpmn.instance.*;
+import org.camunda.bpm.model.bpmn.instance.Process;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Created by cheeyy on 2020/5/29.
+ */
+@RestController
+public class TaskController {
+
+ private Logger logger = LoggerFactory.getLogger(ProcessInstanceController.class);
+
+ @Autowired
+ private RepositoryService repositoryService;
+
+ @Autowired
+ private RuntimeService runtimeService;
+
+ @Autowired
+ private TaskService taskService;
+
+ @Autowired
+ private IdentityService identityService;
+
+ @Autowired
+ private HistoryService historyService;
+
+ @Autowired
+ private ProcessEngine processEngine;
+
+ @RequestMapping("/task/complete")
+ public CSResponse complete(@RequestBody TaskRequestEntity taskRequestEntity, HttpServletRequest request){
+ try{
+ String username = taskRequestEntity.getUserId();
+ HashMap variables = taskRequestEntity.getVariables();
+ identityService.setAuthenticatedUserId(username);
+ String taskid = taskRequestEntity.getTaskId();
+ taskService.complete(taskid,variables);
+ identityService.setAuthenticatedUserId(null);
+ return new CSResponse("任务complete完成");
+ }catch (Exception e){
+ logger.error("完成任务失败,原因:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+ }
+
+ @RequestMapping("/task/turnDown")
+ public CSResponse trunDownTask(@RequestBody TurnDownEntity turnDownEntity,HttpServletRequest request){
+ try{
+ String rejectType = turnDownEntity.getRejectType();
+ if(StringUtils.isBlank(rejectType)){
+ throw new Exception("驳回类型不能为空!");
+ }
+ List taskList = new ArrayList();
+ ActivityInstance tree = runtimeService.getActivityInstance(turnDownEntity.getProcessInstId());
+ if(rejectType.equals(turnDownEntity.REJECT_TO_START)){
+ List resultList = historyService
+ .createHistoricActivityInstanceQuery()
+ .processInstanceId(turnDownEntity.getProcessInstId())
+ .activityType("userTask")
+ .finished()
+ .orderByHistoricActivityInstanceEndTime()
+ .asc()
+ .list();
+ if (resultList == null || resultList.size() <= 0) {
+ throw new Exception("未找到发起节点");
+ }
+ turnDownEntity.setToActId(resultList.get(0).getActivityId());
+ }else if(rejectType.equals(turnDownEntity.REJECT_TO_LAST)){
+ List resultList = historyService
+ .createHistoricActivityInstanceQuery()
+ .processInstanceId(turnDownEntity.getProcessInstId())
+ .activityType("userTask")
+ .finished()
+ .orderByHistoricActivityInstanceEndTime()
+ .desc()
+ .list();
+ if (resultList == null || resultList.size() <= 0) {
+ throw new Exception("未找到上一节点");
+ }
+ turnDownEntity.setToActId(resultList.get(0).getActivityId());
+ }else if(rejectType.equals(turnDownEntity.REJECT_TO_TARGET)){
+ if(StringUtils.isBlank(turnDownEntity.getToActId())){
+ throw new Exception("指定目标节点不能为空!");
+ }
+ }else{
+ throw new Exception("驳回类型值不对,三种类型 1:起草节点,2:上一节点,3:目标节点!");
+ }
+
+ taskService.createComment(turnDownEntity.getTaskId(), turnDownEntity.getProcessInstId(), "驳回流程");
+
+ runtimeService
+ .createProcessInstanceModification(turnDownEntity.getProcessInstId())
+ .cancelActivityInstance(getInstanceIdForActivity(tree, turnDownEntity.getTaskDefKey()))
+ .startBeforeActivity(turnDownEntity.getToActId())
+ .execute();
+
+
+ taskList = simpleGetTasks(turnDownEntity.getProcessInstId());
+// if (taskList != null && taskList.size() == 1) {
+// taskService.setAssignee(taskList.get(0).getId(), pscCommonTaskRequest.getNextUserId());
+// }
+// taskList = simpleGetTasks(pscCommonTaskRequest.getProcessInstId());
+
+
+ return new CSResponse("驳回任务完成");
+ }catch (Exception e){
+ logger.error("驳回任务失败,原因:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+ }
+
+ public String getInstanceIdForActivity(ActivityInstance activityInstance, String activityId) {
+ ActivityInstance instance = getChildInstanceForActivity(activityInstance, activityId);
+ if (instance != null) {
+ return instance.getId();
+ }
+ return null;
+ }
+
+ public ActivityInstance getChildInstanceForActivity(ActivityInstance activityInstance, String activityId) {
+ if (activityId.equals(activityInstance.getActivityId())) {
+ return activityInstance;
+ }
+
+ for (ActivityInstance childInstance : activityInstance.getChildActivityInstances()) {
+ ActivityInstance instance = getChildInstanceForActivity(childInstance, activityId);
+ if (instance != null) {
+ return instance;
+ }
+ }
+
+ return null;
+ }
+
+ public List simpleGetTasks(String processInstId) throws Exception {
+ List resultList = new ArrayList();
+ List taskList = taskService.createTaskQuery().processInstanceId(processInstId).list();
+ for (Task task : taskList) {
+ TaskDto dto = new TaskDto();
+ dto = TaskDto.fromEntity(task);
+ resultList.add(dto);
+ }
+ return resultList;
+ }
+
+
+ @RequestMapping("/task/resolved")
+ public CSResponse resolved(@RequestBody TaskRequestEntity taskRequestEntity, HttpServletRequest request){
+ try{
+ String username = taskRequestEntity.getUserId();
+ HashMap variables = taskRequestEntity.getVariables();
+ identityService.setAuthenticatedUserId(username);
+ String taskId = taskRequestEntity.getTaskId();
+ taskService.resolveTask(taskId,variables);
+ identityService.setAuthenticatedUserId(null);
+ return new CSResponse("任务resolve完成");
+ }catch (Exception e){
+ logger.error("完成任务失败,原因:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+ }
+
+ @RequestMapping("/task/addCountersign")
+ public CSResponse addCountersign(@RequestBody Countersign countersign){
+ try{
+ String taskId = countersign.taskId;
+ ArrayList assigneeList = countersign.assigneeList;
+ Map variables = new HashMap<>();
+ variables.put("assigneeList",assigneeList);
+ taskService.complete(taskId,variables);
+ return new CSResponse("添加会签人员功能完成");
+ }catch (Exception e){
+ logger.error("完成任务失败,原因:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+ }
+
+
+ /*试验代码*/
+
+ protected T createElement(BpmnModelElementInstance parentElement, String id, Class elementClass) {
+ T element = parentElement.getModelInstance().newInstance(elementClass);
+ element.setAttributeValue("id", id, true);
+ parentElement.addChildElement(element);
+ return element;
+ }
+
+ public SequenceFlow createSequenceFlow(Process process, FlowNode from, FlowNode to) {
+ String identifier = from.getId() + "-" + to.getId();
+ SequenceFlow sequenceFlow = createElement( process, identifier, SequenceFlow.class);
+ process.addChildElement(sequenceFlow);
+ sequenceFlow.setSource(from);
+ from.getOutgoing().add(sequenceFlow);
+ sequenceFlow.setTarget(to);
+ to.getIncoming().add(sequenceFlow);
+ return sequenceFlow;
+ }
+
+
+
+
+// @RequestMapping("/task/addTask")
+ public void addDynamicTask(@RequestBody TaskRequestEntity taskRequestEntity,HttpServletResponse response){
+ String taskId = taskRequestEntity.getTaskId();
+ Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
+
+ ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).tenantIdIn("test02").orderByTenantId().desc().list().get(0);
+
+ BpmnModelInstance bpmnModelInstance = repositoryService.getBpmnModelInstance(processInstance.getProcessDefinitionId());
+
+ UserTask userTask = (UserTask) bpmnModelInstance.getModelElementById("deptLeaderAudit");
+ SequenceFlow outgoingSequenceFlow = userTask.getOutgoing().iterator().next();
+ FlowNode serviceTask = outgoingSequenceFlow.getTarget();
+ userTask.getOutgoing().remove(outgoingSequenceFlow);
+ UserTaskBuilder userTaskBuilder = userTask.builder()
+ .userTask("jiaqian");
+ userTaskBuilder.camundaAssignee("cheey");
+ userTaskBuilder.camundaCandidateGroups("sales");
+ BpmnModelInstance instance = userTaskBuilder.connectTo(serviceTask.getId()).done();
+
+
+ /* Definitions definitions = bpmnModelInstance.getDefinitions();
+ Process process = createElement( definitions, "process-before", Process.class);
+ UserTask task1 = createElement(process, "task1", UserTask.class);
+ task1.setName("User Task");
+ task1.setCamundaAssignee("cheey");
+ task1.builder().userTask().connectTo(serviceTask.getId());
+
+
+ UserTask deptLeaderAudit = (UserTask) bpmnModelInstance.getModelElementById("deptLeaderAudit");
+
+ ExclusiveGateway exclusivegateway = (ExclusiveGateway) bpmnModelInstance.getModelElementById("exclusivegateway");*/
+
+
+ /*createSequenceFlow(process,deptLeaderAudit,task1);
+ createSequenceFlow(process,task1,exclusivegateway);
+ Bpmn.validateModel(bpmnModelInstance);
+ ProcessBuilder builder = process.builder();
+ try {
+ Bpmn.writeModelToStream(response.getOutputStream(),bpmnModelInstance);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }*/
+ }
+
+
+ public CSResponse getUnfinishedTask(){
+ try{
+ HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
+ HistoricTaskInstanceQuery unfinished = historicTaskInstanceQuery.unfinished();
+ List userLists = unfinished.taskAssignee("cheey").list();
+ List groupLists = unfinished.taskInvolvedGroup("sales").list();
+ HashMap res = new HashMap<>();
+ for(HistoricTaskInstance user : userLists){
+ res.put(user.getId(),user);
+ }
+ for (HistoricTaskInstance group : groupLists){
+ res.put(group.getId(),group);
+ }
+// List groupLists2 = groupLists.stream().filter(x->x.getId().equals("")).collect(Collectors.toList());
+ Object[] objects = res.values().toArray();
+
+ return new CSResponse("任务resolve完成");
+ }catch (Exception e){
+ logger.error("完成任务失败,原因:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+
+ }
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/controller/UserController.java b/src/main/java/com/fs/camunda/bpm/example/controller/UserController.java
new file mode 100644
index 0000000..503dfbe
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/controller/UserController.java
@@ -0,0 +1,147 @@
+package com.fs.camunda.bpm.example.controller;
+
+import com.fs.camunda.bpm.example.entity.*;
+import com.fs.camunda.bpm.example.service.UserService;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.util.Strings;
+import org.camunda.bpm.engine.IdentityService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+/**
+ * Created by cheeyy on 2020/6/22.
+ */
+@Controller
+public class UserController {
+ private static Logger logger = LoggerFactory.getLogger(UserController.class);
+
+ @Autowired
+ private IdentityService identityService;
+
+ @Autowired
+ private UserService userService;
+
+
+
+
+ @RequestMapping(value = "/user/check")
+ @ResponseBody
+ public CSResponse checkUser(@RequestBody UserRequestEntity user){
+
+ try{
+
+ if(!(StringUtils.isNotBlank(user.getType())&&StringUtils.isNotBlank(user.getId()))){
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),"类型与id都不能为空");
+ }
+
+ String result = "类型有问题,请选择0-2之间类型";
+
+ Boolean isExist = true;
+ if(user.getType() .equals("0") ){
+ //0代表用户 1代表组 2代表租户
+ isExist = userService.checkUser(user.getId());
+ result = isExist==true?"用户已经存在":"该用户未存在";
+ }else if(user.getType() .equals("1") ){
+ //0代表用户 1代表组 2代表租户
+ isExist = userService.checkGroup(user.getId());
+ result = isExist==true?"组已经存在":"该组未存在";
+ }else if(user.getType() .equals("2") ){
+ //0代表用户 1代表组 2代表租户
+ isExist = userService.checkTenant(user.getId());
+ result = isExist==true?"租户已经存在":"该租户未存在";
+ }
+ UserResponseEntity userResponseEntity = new UserResponseEntity();
+ userResponseEntity.setDesc(result);
+ userResponseEntity.setIsExist(isExist);
+ return new CSResponse(userResponseEntity);
+
+ }catch (Exception e){
+ logger.error("用户检查异常:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+
+ }
+
+ @RequestMapping(value = "/membership/update")
+ @ResponseBody
+ public CSResponse updateMembership(@RequestBody ObjectMemberEntity membership){
+ try{
+ String result = "";
+ Boolean state = userService.updateGroupAndUser(membership);
+ if(state){
+ result="修改成功";
+ }else{
+ result = "修改失败";
+ }
+ return new CSResponse(result);
+ }catch (Exception e){
+ logger.error("用户检查异常:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+ }
+}
+
+
+/* *//**
+ * 用户登录(REST)
+ * 继承camunda的login方法,将camunda的缓存也设置到session中,后续如果有用到restapi时候,
+ * camunda的缓存就会有作用了
+ *
+ * @return
+ *//*
+ @RequestMapping(value = "/user/login", method = RequestMethod.POST)
+ @ResponseBody
+ public CSResponse login(@RequestBody UserInfo userInfo, HttpServletRequest request) {
+ try{
+
+
+ //获取用户数据
+ String username = userInfo.getUsername();
+ String password = userInfo.getPassword();
+ this.request = request;
+ //系统自带的登录,让系统的缓存也生效
+ this.doLogin("default","tasklist",username,password);
+ logger.debug("login request: {username={}, password={}}", username, password);
+ boolean checkPassword = identityService.checkPassword(username, password);
+ HashMap result = new HashMap();
+ if (checkPassword) {
+ //需要重新获取session,之前的认证过失效
+ HttpSession session = request.getSession();
+ User user = identityService.createUserQuery().userId(username).singleResult();
+ session.setAttribute("user",user);
+ List groupList = identityService.createGroupQuery().groupMember(username).list();
+ session.setAttribute("groups", groupList);
+ String[] groupNames = new String[groupList.size()];
+ for (int i = 0; i < groupNames.length; i++) {
+ System.out.println(groupList.get(i).getName());
+ groupNames[i] = groupList.get(i).getName();
+ }
+ session.setAttribute("groupNames", ArrayUtils.toString(groupNames));
+ result.put("authorized", true);
+ } else {
+ result.put("authorized", false);
+ }
+ return new CSResponse(result);
+ }catch (Exception e){
+ logger.error("用户登录异常:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+ }
+
+ @RequestMapping(value = "/user/logout")
+ public CSResponse logout(HttpSession session) {
+ try{
+ session.removeAttribute("user");
+ this.doLogout("default");
+ return new CSResponse();
+ }
+ catch (Exception e){
+ logger.error("用户登出异常:"+e);
+ return new CSResponse(CommonEnum.SYSTEM_ERROR.getCode(),CommonEnum.SYSTEM_ERROR.getDesc());
+ }
+ }*/
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/CSResponse.java b/src/main/java/com/fs/camunda/bpm/example/entity/CSResponse.java
new file mode 100644
index 0000000..a75ba5d
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/CSResponse.java
@@ -0,0 +1,53 @@
+/**
+ *
+ */
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author cheey
+ *
+ */
+@Data
+public class CSResponse implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8820950155758688519L;
+
+
+ private String code;
+
+ private String desc;
+
+ private Serializable data;
+
+ public CSResponse(String code, String desc, Serializable data) {
+ super();
+ this.code = code;
+ this.desc = desc;
+ this.data = data;
+ }
+
+ public CSResponse(String code, String desc) {
+ super();
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public CSResponse(Serializable data) {
+ this.code = CommonEnum.SUCCESS.getCode();
+ this.desc = CommonEnum.SUCCESS.getDesc();
+ this.data = data;
+ }
+
+ public CSResponse() {
+ this.code = CommonEnum.SUCCESS.getCode();
+ this.desc = CommonEnum.SUCCESS.getDesc();
+ }
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/CommonEnum.java b/src/main/java/com/fs/camunda/bpm/example/entity/CommonEnum.java
new file mode 100644
index 0000000..f449159
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/CommonEnum.java
@@ -0,0 +1,31 @@
+/**
+ *
+ */
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Getter;
+
+/**
+ * @author sunnan
+ *
+ */
+@Getter
+public enum CommonEnum {
+
+ SUCCESS("0000","接口请求成功"),
+
+ SYSTEM_ERROR("5000","失败");
+
+
+
+ private String code;
+
+ private String desc;
+
+ CommonEnum(String code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/Countersign.java b/src/main/java/com/fs/camunda/bpm/example/entity/Countersign.java
new file mode 100644
index 0000000..ba11737
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/Countersign.java
@@ -0,0 +1,17 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+
+/**
+ * Created by cheeyy on 2021/5/26.
+ */
+@Data
+public class Countersign {
+
+ public ArrayList assigneeList;
+
+ public String taskId;
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/ObjectMemberEntity.java b/src/main/java/com/fs/camunda/bpm/example/entity/ObjectMemberEntity.java
new file mode 100644
index 0000000..cb1095a
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/ObjectMemberEntity.java
@@ -0,0 +1,24 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Created by cheeyy on 2020/7/8.
+ */
+@Data
+public class ObjectMemberEntity implements Serializable {
+
+ private String userId;
+
+ private String originGroupId;
+
+ private String titleGroupId;
+
+ private String originTenantId;
+
+ private String titleTenantId;
+
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/ProcessDefineEntity.java b/src/main/java/com/fs/camunda/bpm/example/entity/ProcessDefineEntity.java
new file mode 100644
index 0000000..fa47979
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/ProcessDefineEntity.java
@@ -0,0 +1,23 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * Created by cheeyy on 2020/5/21.
+ */
+
+@Data
+public class ProcessDefineEntity implements Serializable{
+
+ private String processDefineId;
+
+ private String processDefineKey;
+
+ private String bussinessKey;
+
+ private Map variables;
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/ProcessInstanceEntity.java b/src/main/java/com/fs/camunda/bpm/example/entity/ProcessInstanceEntity.java
new file mode 100644
index 0000000..fde3dfa
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/ProcessInstanceEntity.java
@@ -0,0 +1,15 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+/**
+ * Created by cheeyy on 2021/6/8.
+ */
+@Data
+public class ProcessInstanceEntity {
+
+ private String processInstanceId;
+
+ private String reason;
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/TaskEntity.java b/src/main/java/com/fs/camunda/bpm/example/entity/TaskEntity.java
new file mode 100644
index 0000000..c592be8
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/TaskEntity.java
@@ -0,0 +1,16 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+import org.camunda.bpm.engine.rest.dto.task.TaskDto;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by cheeyy on 2020/5/29.
+ */
+@Data
+public class TaskEntity implements Serializable {
+
+ private List taskDtos;
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/TaskRequestEntity.java b/src/main/java/com/fs/camunda/bpm/example/entity/TaskRequestEntity.java
new file mode 100644
index 0000000..428ed0a
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/TaskRequestEntity.java
@@ -0,0 +1,19 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+import java.util.HashMap;
+
+/**
+ * Created by cheeyy on 2020/6/2.
+ */
+@Data
+public class TaskRequestEntity {
+
+
+ private String taskId;
+
+ private HashMap variables;
+
+ private String userId;
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/TurnDownEntity.java b/src/main/java/com/fs/camunda/bpm/example/entity/TurnDownEntity.java
new file mode 100644
index 0000000..4f65e78
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/TurnDownEntity.java
@@ -0,0 +1,24 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+/**
+ * Created by cheeyy on 2021/5/27.
+ */
+@Data
+public class TurnDownEntity {
+
+ private String rejectType; //驳回类型,1:起草节点,2:上一节点,3:目标节点
+
+ private String processInstId;//流程实例ID
+
+ private String toActId;//目标节点Id
+
+ private String taskId;//任务id
+
+ private String taskDefKey;//当前的任务key
+
+ public static String REJECT_TO_START ="1";
+ public static String REJECT_TO_LAST ="2";
+ public static String REJECT_TO_TARGET ="3";
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/UserInfo.java b/src/main/java/com/fs/camunda/bpm/example/entity/UserInfo.java
new file mode 100644
index 0000000..c8b7d44
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/UserInfo.java
@@ -0,0 +1,10 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+@Data
+public class UserInfo {
+ private String username;
+ private String password;
+
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/UserInfoEntity.java b/src/main/java/com/fs/camunda/bpm/example/entity/UserInfoEntity.java
new file mode 100644
index 0000000..64bde4c
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/UserInfoEntity.java
@@ -0,0 +1,39 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+import org.camunda.bpm.engine.identity.User;
+import org.camunda.bpm.engine.impl.db.DbEntity;
+import org.camunda.bpm.engine.impl.db.HasDbRevision;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Created by cheeyy on 2020/6/22.
+ */
+@Data
+public class UserInfoEntity implements User, Serializable, DbEntity, HasDbRevision {
+
+
+ private static final long serialVersionUID = 1L;
+ protected String id;
+ protected int revision;
+ protected String firstName;
+ protected String lastName;
+ protected String email;
+ protected String password;
+ protected String newPassword;
+ protected String salt;
+ protected Date lockExpirationTime;
+ protected int attempts;
+
+ @Override
+ public Object getPersistentState() {
+ return null;
+ }
+
+ @Override
+ public int getRevisionNext() {
+ return 0;
+ }
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/UserRequestEntity.java b/src/main/java/com/fs/camunda/bpm/example/entity/UserRequestEntity.java
new file mode 100644
index 0000000..e243cbc
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/UserRequestEntity.java
@@ -0,0 +1,15 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+/**
+ * Created by cheeyy on 2020/6/22.
+ */
+@Data
+public class UserRequestEntity {
+
+ private String id ;
+
+ //0代表用户 1代表组 2代表租户
+ private String type ;
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/entity/UserResponseEntity.java b/src/main/java/com/fs/camunda/bpm/example/entity/UserResponseEntity.java
new file mode 100644
index 0000000..9006605
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/entity/UserResponseEntity.java
@@ -0,0 +1,16 @@
+package com.fs.camunda.bpm.example.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Created by cheeyy on 2020/6/28.
+ */
+@Data
+public class UserResponseEntity implements Serializable {
+
+ private Boolean isExist;
+
+ private String desc;
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/mapper/UserMapper.java b/src/main/java/com/fs/camunda/bpm/example/mapper/UserMapper.java
new file mode 100644
index 0000000..141ecbb
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/mapper/UserMapper.java
@@ -0,0 +1,22 @@
+package com.fs.camunda.bpm.example.mapper;
+
+import com.fs.camunda.bpm.example.entity.UserInfoEntity;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Map;
+
+@Mapper
+public interface UserMapper {
+
+
+
+// int findUserById(String userId);
+ int findUserById(String userId);
+
+ int findGroupById(String groupId);
+
+ int findTenantById(String tenantId);
+
+ int updateGroupAndUser(@Param("groupId")String groupId,@Param("titleGroupId")String titleGroupId, @Param("userId")String userId);
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/service/UserService.java b/src/main/java/com/fs/camunda/bpm/example/service/UserService.java
new file mode 100644
index 0000000..f98b51f
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/service/UserService.java
@@ -0,0 +1,19 @@
+package com.fs.camunda.bpm.example.service;
+
+import com.fs.camunda.bpm.example.entity.ObjectMemberEntity;
+import org.springframework.stereotype.Service;
+
+/**
+ * Created by cheeyy on 2020/6/22.
+ */
+
+public interface UserService {
+
+ Boolean checkUser(String userId);
+
+ Boolean checkGroup(String groupId);
+
+ Boolean checkTenant(String tenantId);
+
+ Boolean updateGroupAndUser(ObjectMemberEntity membership);
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/service/impl/UserServiceImpl.java b/src/main/java/com/fs/camunda/bpm/example/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..b4dbee2
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/service/impl/UserServiceImpl.java
@@ -0,0 +1,67 @@
+package com.fs.camunda.bpm.example.service.impl;
+
+import com.fs.camunda.bpm.example.conf.BasicPathAuthConfig;
+import com.fs.camunda.bpm.example.entity.ObjectMemberEntity;
+import com.fs.camunda.bpm.example.entity.UserInfoEntity;
+import com.fs.camunda.bpm.example.mapper.UserMapper;
+import com.fs.camunda.bpm.example.service.UserService;
+import com.google.common.base.Strings;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * Created by cheeyy on 2020/6/22.
+ */
+@Service
+public class UserServiceImpl implements UserService {
+
+ @Autowired
+ UserMapper userMapper;
+
+ private Logger logger = LoggerFactory.getLogger(getClass());
+
+
+ public Boolean checkUser(String userId){
+
+ int count = userMapper.findUserById(userId);
+ if(count > 0 ){
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Boolean checkGroup(String groupId) {
+ int count = userMapper.findGroupById(groupId);
+ if(count > 0 ){
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Boolean checkTenant(String tenantId) {
+ int count = userMapper.findTenantById(tenantId);
+ if(count > 0 ){
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Boolean updateGroupAndUser(ObjectMemberEntity membership) {
+ if(Strings.isNullOrEmpty(membership.getUserId())||Strings.isNullOrEmpty(membership.getOriginGroupId())
+ ||Strings.isNullOrEmpty(membership.getTitleGroupId())){
+ logger.info("传入的用户id、原始组id、目标组id 必须都有值!目前参数为:"+membership.toString());
+ return false;
+ }
+ int count = userMapper.updateGroupAndUser(membership.getOriginGroupId(),membership.getTitleGroupId(),membership.getUserId());
+ if(count>0){
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/fs/camunda/bpm/example/utils/UserUtil.java b/src/main/java/com/fs/camunda/bpm/example/utils/UserUtil.java
new file mode 100644
index 0000000..5593f41
--- /dev/null
+++ b/src/main/java/com/fs/camunda/bpm/example/utils/UserUtil.java
@@ -0,0 +1,59 @@
+package com.fs.camunda.bpm.example.utils;
+
+import com.fs.camunda.bpm.example.conf.DemoWebMvcConfig;
+import org.camunda.bpm.engine.identity.User;
+import org.camunda.bpm.engine.impl.digest._apacheCommonsCodec.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * 用户工具类
+ *
+ * @author cheey
+ */
+public class UserUtil {
+
+ private static final Logger logger = LoggerFactory.getLogger(UserUtil.class);
+
+
+ public static final String USER = "user";
+
+ /**
+ * 设置用户到session
+ *
+ * @param session
+ * @param user
+ */
+ public static void saveUserToSession(HttpSession session, User user) {
+ session.setAttribute(USER, user);
+ }
+
+ /**
+ * 从Session获取当前用户信息
+ *
+ * @param session
+ * @return
+ */
+ public static User getUserFromSession(HttpSession session) {
+ Object attribute = session.getAttribute(USER);
+ return attribute == null ? null : (User) attribute;
+ }
+
+ public static String getLoginUserName(HttpServletRequest request){
+ try{
+ String header = request.getHeader("Authorization");
+ String encodedCredentials = header.substring(6);
+ String decodedCredentials = new String(Base64.decodeBase64(encodedCredentials),"UTF-8");
+ int firstColonIndex = decodedCredentials.indexOf(":");
+ String userName = decodedCredentials.substring(0, firstColonIndex);
+ return userName;
+ }catch (Exception e){
+ logger.error("获取登录名异常,原因:"+e);
+ return "";
+ }
+ }
+
+}
diff --git a/src/main/resources/META-INF/processes.xml b/src/main/resources/META-INF/processes.xml
new file mode 100644
index 0000000..f9a44e8
--- /dev/null
+++ b/src/main/resources/META-INF/processes.xml
@@ -0,0 +1,13 @@
+
+
+
+ default
+
+ false
+ false
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..7cf0f7e
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,65 @@
+server:
+ port: 8080
+ tomcat:
+ uri-encoding: UTF-8
+ servlet:
+ context-path: /fs-workflow
+ register-default-servlet: true
+
+spring:
+ application:
+ name: camunda-demo-service
+ jersey:
+ application-path: /engine-rest
+ datasource:
+# driver-class-name: com.mysql.jdbc.Driver
+# url: jdbc:mysql://127.0.0.1:3306/camunda_demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&useOldAliasMetadataBehavior=true
+# username: root
+# password: root
+ driver-class-name: org.postgresql.Driver
+ url: jdbc:postgres://10.8.30.156:5432/camunda04
+ username: FashionAdmin
+ password: 123456
+ tomcat:
+ max-idle: 10
+ max-wait: 10000
+ min-idle: 5
+ initial-size: 5
+ validation-query: SELECT 1
+ test-on-borrow: false
+ test-while-idle: true
+ time-between-eviction-runs-millis: 18800
+
+camunda.bpm:
+ filter:
+ create: All tasks#
+# database:
+# type: PostgreSQL
+ admin-user:
+ id: admin
+ password: fs-workflow
+ firstName: admin
+ auto-deployment-enabled: false
+ webapp:
+ index-redirect-enabled: true
+ application-path: /camunda-workflow
+
+mybatis:
+ type-aliases-package: com.fs.camunda.bpm.example.entity
+ mapper-locations: classpath:mybatis/mapper/*.xml
+
+#logging:
+# path: /logs/
+# file: springbootdemo.log
+# pattern:
+# console: %d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n
+# file: %d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
+#
+logging:
+ level:
+ com:
+ fs:
+ camunda:
+ bpm:
+ example:
+ mapper: debug
\ No newline at end of file
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..2eb0471
--- /dev/null
+++ b/src/main/resources/logback-spring.xml
@@ -0,0 +1,61 @@
+
+
+
+ logback
+
+
+
+
+
+
+
+ info
+
+
+
+
+ %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger) - %cyan(%msg%n)
+ UTF-8
+
+
+
+
+
+
+ ${LOG_HOME}logback.%d{yyyy-MM-dd}[%i].log
+ 10mb
+ 30
+ 1GB
+
+
+
+ 文件记录-%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n
+ UTF-8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mybatis/mapper/UserMapper.xml b/src/main/resources/mybatis/mapper/UserMapper.xml
new file mode 100644
index 0000000..b4e32ff
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/UserMapper.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+ select count(*) from act_id_user where 1=1
+
+ and id_ = #{userId}
+
+
+
+
+
+ select count(*) from act_id_group where 1=1
+
+ and id_ = #{groupId}
+
+
+
+
+ select count(*) from act_id_tenant where 1=1
+
+ and id_ = #{tenantId}
+
+
+
+
+
+ update act_id_membership set group_id_ = #{titleGroupId} where group_id_ = #{groupId} and user_id_ = #{userId}
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/static/camunda-swagger-ui.html b/src/main/resources/static/camunda-swagger-ui.html
new file mode 100644
index 0000000..8898756
--- /dev/null
+++ b/src/main/resources/static/camunda-swagger-ui.html
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/main/resources/static/css/app.css b/src/main/resources/static/css/app.css
new file mode 100644
index 0000000..dcdbd91
--- /dev/null
+++ b/src/main/resources/static/css/app.css
@@ -0,0 +1,749 @@
+@font-face {
+ font-family: 'bpmn-js-pp';
+ src: url("data:;base64,GBYAAGgVAAABAAIAAAAAAAIABQMAAAAAAAABAJABAAAAAExQAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAcCEPZQAAAAAAAAAAAAAAAAAAAAAAABQAYgBwAG0AbgAtAGkAbwAtAHAAcAAAAA4AUgBlAGcAdQBsAGEAcgAAABYAVgBlAHIAcwBpAG8AbgAgADEALgAwAAAAFABiAHAAbQBuAC0AaQBvAC0AcABwAAAAAAAAAQAAAA8AgAADAHBHU1VCsP6z7QAAAPwAAABCT1MvMj4iSaEAAAFAAAAAVmNtYXCd2b4sAAABmAAAAcZjdnQgAAAAAAAACXAAAAAKZnBnbYiQkFkAAAl8AAALcGdhc3AAAAAQAAAJaAAAAAhnbHlmhlzkXAAAA2AAAAIOaGVhZAjiposAAAVwAAAANmhoZWEHkQNNAAAFqAAAACRobXR4FWn/+gAABcwAAAAcbG9jYQGaAg0AAAXoAAAAEG1heHAAmgugAAAF+AAAACBuYW1lD9cCaQAABhgAAALlcG9zdPp/FpwAAAkAAAAAaHByZXDdawOFAAAU7AAAAHsAAQAAAAoAHgAsAAFERkxUAAgABAAAAAAAAAABAAAAAWxpZ2EACAAAAAEAAAABAAQABAAAAAEACAABAAYAAAABAAAAAAABAw8BkAAFAAACegK8AAAAjAJ6ArwAAAHgADEBAgAAAgAFAwAAAAAAAAAAAAAAAAAAAAAAAAAAAABQZkVkAEDoAukDA1L/agBaA1IAlgAAAAEAAAAAAAAAAAAFAAAAAwAAACwAAAAEAAABbgABAAAAAABoAAMAAQAAACwAAwAKAAABbgAEADwAAAAIAAgAAgAA6APoBukD//8AAOgC6AXpAv//AAAAAAAAAAEACAAKAAwAAAABAAIAAwAEAAUABgAAAQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAWAAAAAAAAAAGAADoAgAA6AIAAAABAADoAwAA6AMAAAACAADoBQAA6AUAAAADAADoBgAA6AYAAAAEAADpAgAA6QIAAAAFAADpAwAA6QMAAAAGAAAAAQAAAAAB1gJiAB0ABrMTAwEtKyUWFAYiLwEHBiInJjQ/AScmNDc2Mh8BNzYyFhQPAQHEEiQyEoSEEjISEBCKihAQEjIShIQSMiQSisISMiIQmJgQEBIyEpyeEjISEBCYmBAiMhKeAAABAAAAAAJEAoAAEwAGsxAGAS0rATIUKwEVFCI9ASMiNDsBNTQyHQECJh4e0mTSHh7SZAGQZNIeHtJk0h4e0gAAAgAA/8IDIgLqABEAGgAItRgUDAQCLSslFg8BBi8BBiMiJhA2IBYVFAclFBYyNjQmIgYDBB4YLiQgvkpSgL60AQDALv4YiLB+iLB+TiIcLiAgviq+AQC2voBYSqpYiH6yhn4AAAP/+v+2A8cDCAAMABAAFAAKtxIRDg0KAgMtKwUWBiMhIicmNwE2MhcTNSMVNxEjEQO9ChQU/IQSCg0LAb4ILAgabm5uGBAiEBIQAw4SEv0kZGSuASz+1AACAAD/ugNIAwIACAAUAAi1EQsEAAItKwEyFhAGICYQNgE3JwcnBxcHFzcXNwGkrvb2/qT29gEEmlaamFiamliYmlYDAvb+pPb2AVz2/lyaVpiYVpqYVpiYVgAAAAIAAP+6A0gDAgAIABQACLUTDQQAAi0rATIWEAYgJhA2EzM1IzUjFSMVMxUzAaSu9vb+pPb24sjIZsrKZgMC9v6k9vYBXPb+KmbKymbKAAAAAQAAAAEAAGUPIXBfDzz1AAsD6AAAAADS8LF0AAAAANLwsXT/+v+2A+gDCAAAAAgAAgAAAAAAAAABAAADUv9qAFoD6P/6//MD6AABAAAAAAAAAAAAAAAAAAAABwPoAAAB1gAAAkQAAAMVAAADwv/6A0gAAANIAAAAAAAAADQAVACGALIA4AEHAAEAAAAHAB4AAwAAAAAAAgAAABAAcwAAABwLcAAAAAAAAAASAN4AAQAAAAAAAAA1AAAAAQAAAAAAAQAKADUAAQAAAAAAAgAHAD8AAQAAAAAAAwAKAEYAAQAAAAAABAAKAFAAAQAAAAAABQALAFoAAQAAAAAABgAKAGUAAQAAAAAACgArAG8AAQAAAAAACwATAJoAAwABBAkAAABqAK0AAwABBAkAAQAUARcAAwABBAkAAgAOASsAAwABBAkAAwAUATkAAwABBAkABAAUAU0AAwABBAkABQAWAWEAAwABBAkABgAUAXcAAwABBAkACgBWAYsAAwABBAkACwAmAeFDb3B5cmlnaHQgKEMpIDIwMTYgYnkgb3JpZ2luYWwgYXV0aG9ycyBAIGZvbnRlbGxvLmNvbWJwbW4taW8tcHBSZWd1bGFyYnBtbi1pby1wcGJwbW4taW8tcHBWZXJzaW9uIDEuMGJwbW4taW8tcHBHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuaHR0cDovL2ZvbnRlbGxvLmNvbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAAMgAwADEANgAgAGIAeQAgAG8AcgBpAGcAaQBuAGEAbAAgAGEAdQB0AGgAbwByAHMAIABAACAAZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AYgBwAG0AbgAtAGkAbwAtAHAAcABSAGUAZwB1AGwAYQByAGIAcABtAG4ALQBpAG8ALQBwAHAAYgBwAG0AbgAtAGkAbwAtAHAAcABWAGUAcgBzAGkAbwBuACAAMQAuADAAYgBwAG0AbgAtAGkAbwAtAHAAcABHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAAAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAQIBAwEEAQUBBgEHAQgABWNsZWFyA2FkZAZzZWFyY2gJYXR0ZW50aW9uDWNsZWFyLWNpcmNsZWQLYWRkLWNpcmNsZWQAAAABAAH//wAPAAAAAAAAAAAAAAAAsAAsILAAVVhFWSAgS7gADlFLsAZTWliwNBuwKFlgZiCKVViwAiVhuQgACABjYyNiGyEhsABZsABDI0SyAAEAQ2BCLbABLLAgYGYtsAIsIGQgsMBQsAQmWrIoAQpDRWNFUltYISMhG4pYILBQUFghsEBZGyCwOFBYIbA4WVkgsQEKQ0VjRWFksChQWCGxAQpDRWNFILAwUFghsDBZGyCwwFBYIGYgiophILAKUFhgGyCwIFBYIbAKYBsgsDZQWCGwNmAbYFlZWRuwAStZWSOwAFBYZVlZLbADLCBFILAEJWFkILAFQ1BYsAUjQrAGI0IbISFZsAFgLbAELCMhIyEgZLEFYkIgsAYjQrEBCkNFY7EBCkOwAGBFY7ADKiEgsAZDIIogirABK7EwBSWwBCZRWGBQG2FSWVgjWSEgsEBTWLABKxshsEBZI7AAUFhlWS2wBSywB0MrsgACAENgQi2wBiywByNCIyCwACNCYbACYmawAWOwAWCwBSotsAcsICBFILALQ2O4BABiILAAUFiwQGBZZrABY2BEsAFgLbAILLIHCwBDRUIqIbIAAQBDYEItsAkssABDI0SyAAEAQ2BCLbAKLCAgRSCwASsjsABDsAQlYCBFiiNhIGQgsCBQWCGwABuwMFBYsCAbsEBZWSOwAFBYZVmwAyUjYUREsAFgLbALLCAgRSCwASsjsABDsAQlYCBFiiNhIGSwJFBYsAAbsEBZI7AAUFhlWbADJSNhRESwAWAtsAwsILAAI0KyCwoDRVghGyMhWSohLbANLLECAkWwZGFELbAOLLABYCAgsAxDSrAAUFggsAwjQlmwDUNKsABSWCCwDSNCWS2wDywgsBBiZrABYyC4BABjiiNhsA5DYCCKYCCwDiNCIy2wECxLVFixBGREWSSwDWUjeC2wESxLUVhLU1ixBGREWRshWSSwE2UjeC2wEiyxAA9DVVixDw9DsAFhQrAPK1mwAEOwAiVCsQwCJUKxDQIlQrABFiMgsAMlUFixAQBDYLAEJUKKiiCKI2GwDiohI7ABYSCKI2GwDiohG7EBAENgsAIlQrACJWGwDiohWbAMQ0ewDUNHYLACYiCwAFBYsEBgWWawAWMgsAtDY7gEAGIgsABQWLBAYFlmsAFjYLEAABMjRLABQ7AAPrIBAQFDYEItsBMsALEAAkVUWLAPI0IgRbALI0KwCiOwAGBCIGCwAWG1EBABAA4AQkKKYLESBiuwcisbIlktsBQssQATKy2wFSyxARMrLbAWLLECEystsBcssQMTKy2wGCyxBBMrLbAZLLEFEystsBossQYTKy2wGyyxBxMrLbAcLLEIEystsB0ssQkTKy2wHiwAsA0rsQACRVRYsA8jQiBFsAsjQrAKI7AAYEIgYLABYbUQEAEADgBCQopgsRIGK7ByKxsiWS2wHyyxAB4rLbAgLLEBHistsCEssQIeKy2wIiyxAx4rLbAjLLEEHistsCQssQUeKy2wJSyxBh4rLbAmLLEHHistsCcssQgeKy2wKCyxCR4rLbApLCA8sAFgLbAqLCBgsBBgIEMjsAFgQ7ACJWGwAWCwKSohLbArLLAqK7AqKi2wLCwgIEcgILALQ2O4BABiILAAUFiwQGBZZrABY2AjYTgjIIpVWCBHICCwC0NjuAQAYiCwAFBYsEBgWWawAWNgI2E4GyFZLbAtLACxAAJFVFiwARawLCqwARUwGyJZLbAuLACwDSuxAAJFVFiwARawLCqwARUwGyJZLbAvLCA1sAFgLbAwLACwAUVjuAQAYiCwAFBYsEBgWWawAWOwASuwC0NjuAQAYiCwAFBYsEBgWWawAWOwASuwABa0AAAAAABEPiM4sS8BFSotsDEsIDwgRyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsABDYTgtsDIsLhc8LbAzLCA8IEcgsAtDY7gEAGIgsABQWLBAYFlmsAFjYLAAQ2GwAUNjOC2wNCyxAgAWJSAuIEewACNCsAIlSYqKRyNHI2EgWGIbIVmwASNCsjMBARUUKi2wNSywABawBCWwBCVHI0cjYbAJQytlii4jICA8ijgtsDYssAAWsAQlsAQlIC5HI0cjYSCwBCNCsAlDKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgsAhDIIojRyNHI2EjRmCwBEOwAmIgsABQWLBAYFlmsAFjYCCwASsgiophILACQ2BkI7ADQ2FkUFiwAkNhG7ADQ2BZsAMlsAJiILAAUFiwQGBZZrABY2EjICCwBCYjRmE4GyOwCENGsAIlsAhDRyNHI2FgILAEQ7ACYiCwAFBYsEBgWWawAWNgIyCwASsjsARDYLABK7AFJWGwBSWwAmIgsABQWLBAYFlmsAFjsAQmYSCwBCVgZCOwAyVgZFBYIRsjIVkjICCwBCYjRmE4WS2wNyywABYgICCwBSYgLkcjRyNhIzw4LbA4LLAAFiCwCCNCICAgRiNHsAErI2E4LbA5LLAAFrADJbACJUcjRyNhsABUWC4gPCMhG7ACJbACJUcjRyNhILAFJbAEJUcjRyNhsAYlsAUlSbACJWG5CAAIAGNjIyBYYhshWWO4BABiILAAUFiwQGBZZrABY2AjLiMgIDyKOCMhWS2wOiywABYgsAhDIC5HI0cjYSBgsCBgZrACYiCwAFBYsEBgWWawAWMjICA8ijgtsDssIyAuRrACJUZSWCA8WS6xKwEUKy2wPCwjIC5GsAIlRlBYIDxZLrErARQrLbA9LCMgLkawAiVGUlggPFkjIC5GsAIlRlBYIDxZLrErARQrLbA+LLA1KyMgLkawAiVGUlggPFkusSsBFCstsD8ssDYriiAgPLAEI0KKOCMgLkawAiVGUlggPFkusSsBFCuwBEMusCsrLbBALLAAFrAEJbAEJiAuRyNHI2GwCUMrIyA8IC4jOLErARQrLbBBLLEIBCVCsAAWsAQlsAQlIC5HI0cjYSCwBCNCsAlDKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgR7AEQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwAmIgsABQWLBAYFlmsAFjYbACJUZhOCMgPCM4GyEgIEYjR7ABKyNhOCFZsSsBFCstsEIssDUrLrErARQrLbBDLLA2KyEjICA8sAQjQiM4sSsBFCuwBEMusCsrLbBELLAAFSBHsAAjQrIAAQEVFBMusDEqLbBFLLAAFSBHsAAjQrIAAQEVFBMusDEqLbBGLLEAARQTsDIqLbBHLLA0Ki2wSCywABZFIyAuIEaKI2E4sSsBFCstsEkssAgjQrBIKy2wSiyyAABBKy2wSyyyAAFBKy2wTCyyAQBBKy2wTSyyAQFBKy2wTiyyAABCKy2wTyyyAAFCKy2wUCyyAQBCKy2wUSyyAQFCKy2wUiyyAAA+Ky2wUyyyAAE+Ky2wVCyyAQA+Ky2wVSyyAQE+Ky2wViyyAABAKy2wVyyyAAFAKy2wWCyyAQBAKy2wWSyyAQFAKy2wWiyyAABDKy2wWyyyAAFDKy2wXCyyAQBDKy2wXSyyAQFDKy2wXiyyAAA/Ky2wXyyyAAE/Ky2wYCyyAQA/Ky2wYSyyAQE/Ky2wYiywNysusSsBFCstsGMssDcrsDsrLbBkLLA3K7A8Ky2wZSywABawNyuwPSstsGYssDgrLrErARQrLbBnLLA4K7A7Ky2waCywOCuwPCstsGkssDgrsD0rLbBqLLA5Ky6xKwEUKy2wayywOSuwOystsGwssDkrsDwrLbBtLLA5K7A9Ky2wbiywOisusSsBFCstsG8ssDorsDsrLbBwLLA6K7A8Ky2wcSywOiuwPSstsHIsswkEAgNFWCEbIyFZQiuwCGWwAyRQeLABFTAtAEu4AMhSWLEBAY5ZsAG5CAAIAGNwsQAFQrEAACqxAAVCsQAIKrEABUKxAAgqsQAFQrkAAAAJKrEABUK5AAAACSqxAwBEsSQBiFFYsECIWLEDZESxJgGIUVi6CIAAAQRAiGNUWLEDAERZWVlZsQAMKrgB/4WwBI2xAgBEAA==");
+ src: url("data:;base64,GBYAAGgVAAABAAIAAAAAAAIABQMAAAAAAAABAJABAAAAAExQAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAcCEPZQAAAAAAAAAAAAAAAAAAAAAAABQAYgBwAG0AbgAtAGkAbwAtAHAAcAAAAA4AUgBlAGcAdQBsAGEAcgAAABYAVgBlAHIAcwBpAG8AbgAgADEALgAwAAAAFABiAHAAbQBuAC0AaQBvAC0AcABwAAAAAAAAAQAAAA8AgAADAHBHU1VCsP6z7QAAAPwAAABCT1MvMj4iSaEAAAFAAAAAVmNtYXCd2b4sAAABmAAAAcZjdnQgAAAAAAAACXAAAAAKZnBnbYiQkFkAAAl8AAALcGdhc3AAAAAQAAAJaAAAAAhnbHlmhlzkXAAAA2AAAAIOaGVhZAjiposAAAVwAAAANmhoZWEHkQNNAAAFqAAAACRobXR4FWn/+gAABcwAAAAcbG9jYQGaAg0AAAXoAAAAEG1heHAAmgugAAAF+AAAACBuYW1lD9cCaQAABhgAAALlcG9zdPp/FpwAAAkAAAAAaHByZXDdawOFAAAU7AAAAHsAAQAAAAoAHgAsAAFERkxUAAgABAAAAAAAAAABAAAAAWxpZ2EACAAAAAEAAAABAAQABAAAAAEACAABAAYAAAABAAAAAAABAw8BkAAFAAACegK8AAAAjAJ6ArwAAAHgADEBAgAAAgAFAwAAAAAAAAAAAAAAAAAAAAAAAAAAAABQZkVkAEDoAukDA1L/agBaA1IAlgAAAAEAAAAAAAAAAAAFAAAAAwAAACwAAAAEAAABbgABAAAAAABoAAMAAQAAACwAAwAKAAABbgAEADwAAAAIAAgAAgAA6APoBukD//8AAOgC6AXpAv//AAAAAAAAAAEACAAKAAwAAAABAAIAAwAEAAUABgAAAQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAWAAAAAAAAAAGAADoAgAA6AIAAAABAADoAwAA6AMAAAACAADoBQAA6AUAAAADAADoBgAA6AYAAAAEAADpAgAA6QIAAAAFAADpAwAA6QMAAAAGAAAAAQAAAAAB1gJiAB0ABrMTAwEtKyUWFAYiLwEHBiInJjQ/AScmNDc2Mh8BNzYyFhQPAQHEEiQyEoSEEjISEBCKihAQEjIShIQSMiQSisISMiIQmJgQEBIyEpyeEjISEBCYmBAiMhKeAAABAAAAAAJEAoAAEwAGsxAGAS0rATIUKwEVFCI9ASMiNDsBNTQyHQECJh4e0mTSHh7SZAGQZNIeHtJk0h4e0gAAAgAA/8IDIgLqABEAGgAItRgUDAQCLSslFg8BBi8BBiMiJhA2IBYVFAclFBYyNjQmIgYDBB4YLiQgvkpSgL60AQDALv4YiLB+iLB+TiIcLiAgviq+AQC2voBYSqpYiH6yhn4AAAP/+v+2A8cDCAAMABAAFAAKtxIRDg0KAgMtKwUWBiMhIicmNwE2MhcTNSMVNxEjEQO9ChQU/IQSCg0LAb4ILAgabm5uGBAiEBIQAw4SEv0kZGSuASz+1AACAAD/ugNIAwIACAAUAAi1EQsEAAItKwEyFhAGICYQNgE3JwcnBxcHFzcXNwGkrvb2/qT29gEEmlaamFiamliYmlYDAvb+pPb2AVz2/lyaVpiYVpqYVpiYVgAAAAIAAP+6A0gDAgAIABQACLUTDQQAAi0rATIWEAYgJhA2EzM1IzUjFSMVMxUzAaSu9vb+pPb24sjIZsrKZgMC9v6k9vYBXPb+KmbKymbKAAAAAQAAAAEAAGUPIXBfDzz1AAsD6AAAAADS8LF0AAAAANLwsXT/+v+2A+gDCAAAAAgAAgAAAAAAAAABAAADUv9qAFoD6P/6//MD6AABAAAAAAAAAAAAAAAAAAAABwPoAAAB1gAAAkQAAAMVAAADwv/6A0gAAANIAAAAAAAAADQAVACGALIA4AEHAAEAAAAHAB4AAwAAAAAAAgAAABAAcwAAABwLcAAAAAAAAAASAN4AAQAAAAAAAAA1AAAAAQAAAAAAAQAKADUAAQAAAAAAAgAHAD8AAQAAAAAAAwAKAEYAAQAAAAAABAAKAFAAAQAAAAAABQALAFoAAQAAAAAABgAKAGUAAQAAAAAACgArAG8AAQAAAAAACwATAJoAAwABBAkAAABqAK0AAwABBAkAAQAUARcAAwABBAkAAgAOASsAAwABBAkAAwAUATkAAwABBAkABAAUAU0AAwABBAkABQAWAWEAAwABBAkABgAUAXcAAwABBAkACgBWAYsAAwABBAkACwAmAeFDb3B5cmlnaHQgKEMpIDIwMTYgYnkgb3JpZ2luYWwgYXV0aG9ycyBAIGZvbnRlbGxvLmNvbWJwbW4taW8tcHBSZWd1bGFyYnBtbi1pby1wcGJwbW4taW8tcHBWZXJzaW9uIDEuMGJwbW4taW8tcHBHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuaHR0cDovL2ZvbnRlbGxvLmNvbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAAMgAwADEANgAgAGIAeQAgAG8AcgBpAGcAaQBuAGEAbAAgAGEAdQB0AGgAbwByAHMAIABAACAAZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AYgBwAG0AbgAtAGkAbwAtAHAAcABSAGUAZwB1AGwAYQByAGIAcABtAG4ALQBpAG8ALQBwAHAAYgBwAG0AbgAtAGkAbwAtAHAAcABWAGUAcgBzAGkAbwBuACAAMQAuADAAYgBwAG0AbgAtAGkAbwAtAHAAcABHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAAAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAQIBAwEEAQUBBgEHAQgABWNsZWFyA2FkZAZzZWFyY2gJYXR0ZW50aW9uDWNsZWFyLWNpcmNsZWQLYWRkLWNpcmNsZWQAAAABAAH//wAPAAAAAAAAAAAAAAAAsAAsILAAVVhFWSAgS7gADlFLsAZTWliwNBuwKFlgZiCKVViwAiVhuQgACABjYyNiGyEhsABZsABDI0SyAAEAQ2BCLbABLLAgYGYtsAIsIGQgsMBQsAQmWrIoAQpDRWNFUltYISMhG4pYILBQUFghsEBZGyCwOFBYIbA4WVkgsQEKQ0VjRWFksChQWCGxAQpDRWNFILAwUFghsDBZGyCwwFBYIGYgiophILAKUFhgGyCwIFBYIbAKYBsgsDZQWCGwNmAbYFlZWRuwAStZWSOwAFBYZVlZLbADLCBFILAEJWFkILAFQ1BYsAUjQrAGI0IbISFZsAFgLbAELCMhIyEgZLEFYkIgsAYjQrEBCkNFY7EBCkOwAGBFY7ADKiEgsAZDIIogirABK7EwBSWwBCZRWGBQG2FSWVgjWSEgsEBTWLABKxshsEBZI7AAUFhlWS2wBSywB0MrsgACAENgQi2wBiywByNCIyCwACNCYbACYmawAWOwAWCwBSotsAcsICBFILALQ2O4BABiILAAUFiwQGBZZrABY2BEsAFgLbAILLIHCwBDRUIqIbIAAQBDYEItsAkssABDI0SyAAEAQ2BCLbAKLCAgRSCwASsjsABDsAQlYCBFiiNhIGQgsCBQWCGwABuwMFBYsCAbsEBZWSOwAFBYZVmwAyUjYUREsAFgLbALLCAgRSCwASsjsABDsAQlYCBFiiNhIGSwJFBYsAAbsEBZI7AAUFhlWbADJSNhRESwAWAtsAwsILAAI0KyCwoDRVghGyMhWSohLbANLLECAkWwZGFELbAOLLABYCAgsAxDSrAAUFggsAwjQlmwDUNKsABSWCCwDSNCWS2wDywgsBBiZrABYyC4BABjiiNhsA5DYCCKYCCwDiNCIy2wECxLVFixBGREWSSwDWUjeC2wESxLUVhLU1ixBGREWRshWSSwE2UjeC2wEiyxAA9DVVixDw9DsAFhQrAPK1mwAEOwAiVCsQwCJUKxDQIlQrABFiMgsAMlUFixAQBDYLAEJUKKiiCKI2GwDiohI7ABYSCKI2GwDiohG7EBAENgsAIlQrACJWGwDiohWbAMQ0ewDUNHYLACYiCwAFBYsEBgWWawAWMgsAtDY7gEAGIgsABQWLBAYFlmsAFjYLEAABMjRLABQ7AAPrIBAQFDYEItsBMsALEAAkVUWLAPI0IgRbALI0KwCiOwAGBCIGCwAWG1EBABAA4AQkKKYLESBiuwcisbIlktsBQssQATKy2wFSyxARMrLbAWLLECEystsBcssQMTKy2wGCyxBBMrLbAZLLEFEystsBossQYTKy2wGyyxBxMrLbAcLLEIEystsB0ssQkTKy2wHiwAsA0rsQACRVRYsA8jQiBFsAsjQrAKI7AAYEIgYLABYbUQEAEADgBCQopgsRIGK7ByKxsiWS2wHyyxAB4rLbAgLLEBHistsCEssQIeKy2wIiyxAx4rLbAjLLEEHistsCQssQUeKy2wJSyxBh4rLbAmLLEHHistsCcssQgeKy2wKCyxCR4rLbApLCA8sAFgLbAqLCBgsBBgIEMjsAFgQ7ACJWGwAWCwKSohLbArLLAqK7AqKi2wLCwgIEcgILALQ2O4BABiILAAUFiwQGBZZrABY2AjYTgjIIpVWCBHICCwC0NjuAQAYiCwAFBYsEBgWWawAWNgI2E4GyFZLbAtLACxAAJFVFiwARawLCqwARUwGyJZLbAuLACwDSuxAAJFVFiwARawLCqwARUwGyJZLbAvLCA1sAFgLbAwLACwAUVjuAQAYiCwAFBYsEBgWWawAWOwASuwC0NjuAQAYiCwAFBYsEBgWWawAWOwASuwABa0AAAAAABEPiM4sS8BFSotsDEsIDwgRyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsABDYTgtsDIsLhc8LbAzLCA8IEcgsAtDY7gEAGIgsABQWLBAYFlmsAFjYLAAQ2GwAUNjOC2wNCyxAgAWJSAuIEewACNCsAIlSYqKRyNHI2EgWGIbIVmwASNCsjMBARUUKi2wNSywABawBCWwBCVHI0cjYbAJQytlii4jICA8ijgtsDYssAAWsAQlsAQlIC5HI0cjYSCwBCNCsAlDKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgsAhDIIojRyNHI2EjRmCwBEOwAmIgsABQWLBAYFlmsAFjYCCwASsgiophILACQ2BkI7ADQ2FkUFiwAkNhG7ADQ2BZsAMlsAJiILAAUFiwQGBZZrABY2EjICCwBCYjRmE4GyOwCENGsAIlsAhDRyNHI2FgILAEQ7ACYiCwAFBYsEBgWWawAWNgIyCwASsjsARDYLABK7AFJWGwBSWwAmIgsABQWLBAYFlmsAFjsAQmYSCwBCVgZCOwAyVgZFBYIRsjIVkjICCwBCYjRmE4WS2wNyywABYgICCwBSYgLkcjRyNhIzw4LbA4LLAAFiCwCCNCICAgRiNHsAErI2E4LbA5LLAAFrADJbACJUcjRyNhsABUWC4gPCMhG7ACJbACJUcjRyNhILAFJbAEJUcjRyNhsAYlsAUlSbACJWG5CAAIAGNjIyBYYhshWWO4BABiILAAUFiwQGBZZrABY2AjLiMgIDyKOCMhWS2wOiywABYgsAhDIC5HI0cjYSBgsCBgZrACYiCwAFBYsEBgWWawAWMjICA8ijgtsDssIyAuRrACJUZSWCA8WS6xKwEUKy2wPCwjIC5GsAIlRlBYIDxZLrErARQrLbA9LCMgLkawAiVGUlggPFkjIC5GsAIlRlBYIDxZLrErARQrLbA+LLA1KyMgLkawAiVGUlggPFkusSsBFCstsD8ssDYriiAgPLAEI0KKOCMgLkawAiVGUlggPFkusSsBFCuwBEMusCsrLbBALLAAFrAEJbAEJiAuRyNHI2GwCUMrIyA8IC4jOLErARQrLbBBLLEIBCVCsAAWsAQlsAQlIC5HI0cjYSCwBCNCsAlDKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgR7AEQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwAmIgsABQWLBAYFlmsAFjYbACJUZhOCMgPCM4GyEgIEYjR7ABKyNhOCFZsSsBFCstsEIssDUrLrErARQrLbBDLLA2KyEjICA8sAQjQiM4sSsBFCuwBEMusCsrLbBELLAAFSBHsAAjQrIAAQEVFBMusDEqLbBFLLAAFSBHsAAjQrIAAQEVFBMusDEqLbBGLLEAARQTsDIqLbBHLLA0Ki2wSCywABZFIyAuIEaKI2E4sSsBFCstsEkssAgjQrBIKy2wSiyyAABBKy2wSyyyAAFBKy2wTCyyAQBBKy2wTSyyAQFBKy2wTiyyAABCKy2wTyyyAAFCKy2wUCyyAQBCKy2wUSyyAQFCKy2wUiyyAAA+Ky2wUyyyAAE+Ky2wVCyyAQA+Ky2wVSyyAQE+Ky2wViyyAABAKy2wVyyyAAFAKy2wWCyyAQBAKy2wWSyyAQFAKy2wWiyyAABDKy2wWyyyAAFDKy2wXCyyAQBDKy2wXSyyAQFDKy2wXiyyAAA/Ky2wXyyyAAE/Ky2wYCyyAQA/Ky2wYSyyAQE/Ky2wYiywNysusSsBFCstsGMssDcrsDsrLbBkLLA3K7A8Ky2wZSywABawNyuwPSstsGYssDgrLrErARQrLbBnLLA4K7A7Ky2waCywOCuwPCstsGkssDgrsD0rLbBqLLA5Ky6xKwEUKy2wayywOSuwOystsGwssDkrsDwrLbBtLLA5K7A9Ky2wbiywOisusSsBFCstsG8ssDorsDsrLbBwLLA6K7A8Ky2wcSywOiuwPSstsHIsswkEAgNFWCEbIyFZQiuwCGWwAyRQeLABFTAtAEu4AMhSWLEBAY5ZsAG5CAAIAGNwsQAFQrEAACqxAAVCsQAIKrEABUKxAAgqsQAFQrkAAAAJKrEABUK5AAAACSqxAwBEsSQBiFFYsECIWLEDZESxJgGIUVi6CIAAAQRAiGNUWLEDAERZWVlZsQAMKrgB/4WwBI2xAgBEAA==") format('embedded-opentype'), url("data:application/font-woff;base64,d09GRgABAAAAAAyIAA8AAAAAFWgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABWAAAADMAAABCsP6z7U9TLzIAAAGMAAAAQwAAAFY+IkmhY21hcAAAAdAAAABxAAABxp3ZvixjdnQgAAACRAAAAAoAAAAKAAAAAGZwZ20AAAJQAAAFlAAAC3CIkJBZZ2FzcAAAB+QAAAAIAAAACAAAABBnbHlmAAAH7AAAAbkAAAIOhlzkXGhlYWQAAAmoAAAAMwAAADYI4qaLaGhlYQAACdwAAAAgAAAAJAeRA01obXR4AAAJ/AAAABwAAAAcFWn/+mxvY2EAAAoYAAAAEAAAABABmgINbWF4cAAACigAAAAgAAAAIACaC6BuYW1lAAAKSAAAAYsAAALlD9cCaXBvc3QAAAvUAAAASgAAAGj6fxaccHJlcAAADCAAAABlAAAAe91rA4V4nGNgZGBg4GKQY9BhYHRx8wlh4GBgYYAAkAxjTmZ6IlAMygPKsYBpDiBmg4gCAIojA08AeJxjYGTmZ5zAwMrAwFTFtIeBgaEHQjM+YDBkZAKKMrAyM2AFAWmuKQwOL5heMjMH/c9iiGIOYpgGFGYEyQEAxHoLQgB4nO2R0Q2AMAhEr9ASYxzFERzEEfxybjqFHuAY0rzmONI0OQAMAEp20oF2oyHqotvSV6zpdxzsFx4BXN2mPg+V+JgSKqtxvmJLJXzb+YOxMfy15X1+nUV2RSTtWmS6o4jNuBWxnSlFbG1qAXsB44UXWgAAAAAAAAAAAAAAAAAAAHicrVZpcxNHEJ3VYcs2PoIPEjaBWcZyjHZWmMsIEMbsShbgHPKV7EKOXUt27otP/Ab9ml6RVJFv/LS8Hh3YYCdVVChK/ab37Uz3655ek9CSxF5Yj6TcfCmmtjZpZOdJSDdsWo7iQ9nZCylTTP4uiIJotdS+7TgkIhKBqnWFJYLY98jSJONDjzJatiW9alJu6Ul32RoP6q369tPQUY7dCSU1m6FD65EtqcKoEkUy7ZGSNi3D1V9JWuHnK8x81QwlgugkksabYQyP5GfjjFYZrcZ2HEWRTZYbRYpEMzyIIo+yWmKfXDFBQPmgGVJe+TSifIQfkRV7lNMKccl2mt/3JT/pHc6/JOJ6i7IlB/5AdmQHe6cr+SLS2grjpp1sR6GK8HR9J8Qjm5Pqn+xRXtNo4HZFpifNCJbKV5BY+Qll9g/JauF8ypc8GtWSg5wIWi9zYl/yDrQeR0yJaybIgu6OToig7pecodhj+rj4471dLBchBMg4lvWOSrgQRilhs5okbQQ5iJKyRZXUekdMnPI6LeItYb9O7ehLZ7RJqDsxnq2Hjq2cqOR4NKnTTKZO7aTm0ZQGUUo6Ezzm1wGUH9Ekr7axmsTKo2lsM2MkkVCghXNpKohlJ5Y0BdE8mtGbu2Gaa9eiRZo8UM89ek9vboWbOz2n7cA/a/xndSqmg70wnZ4OyEp8mna5SdG6fnqGfybxQ9YCKpEtNsOUxUO2fgfl5WNLjsJrA2z3nvMr6H32RMikgfgb8B4v1SkFTIWYVVAL3bTWtSzL1GpWi1Rk6rshTStf1mkCTTkOfWNfxjj+r5kZS0wJ3+/E6dkRl5659iXINIfcZl2P5nVqsV2AzmzP6TTL9n2d5th+oNM82/M6HWFr63SU7Yc6LbD9SKdjbC9oQZPuOwRyEYFcwAYSgbB1EAjbSwiErUIgbBcRCNsiAmG7hEDYfoxA2C4jELaXtayafippHDsTywBFiAOjOe7IZW4qV1PJpRKui0anNuQpcqukonhW/SsD/eKRN6yBtUC6RNb8ikmufFSV44+uaHnTxLkCjlV/e3NcnxMPZb9Y+FPwv9qaqqRXrHlkchV5I9CT40TXJhWPrunyuapH1/+Lig5rgX4DpRALRVmWDb6ZkPBRp9NQDVzlEDMbMw/X9bplzc/h/JsYIQvofvw3FBoL3INOWUlZ7WCv1dePZbm3B+WwJ1iSYr7M61vhi4zMSvtFZil7PvJ5wBUwKpVhqw1creDNexLzkOlN8kwQtxVlg6SNx5kgsYFjHjBvvpMgJExdtYHaKZywgbxgzCnY74RDVG+U5XB7oX0ejZR/a1fsyBkVTRD4bfZG2OuzUPJbrIGEJ7/U10BVIU3FuKmASyPlhmrwYVyt20YyTqCvqNgNy7KKDx9H3HdKjmUg+UgRq0dHP629Qp3Uuf3KKG7fO/0IgkFpYv72vpnioJR3tZJlVm0DU7calVPXmsPFqw7dzaPue8fZJ3LWNN10T9z0vqZVt4ODuVkQ7dsclKVMLqjrww4bqMvNpdDqZVyS3nYPMCwwoN+hFRv/V/dx+DxXqgqj40i9nagfo89iDPIPOH9H9QXo5zFMuYaU53uXE59u3MPZMl3FXayf4t/ArLXmZukacEPTDZiHrFodusoNfKcGOj3S3I70EPCx7grxAGATwGLwie5axvMpgPF8xhwf4HPmMGgyh8EWcxhsM2cNYIc5DHaZw2CPOQy+YM46wJfMYRAyh0HEHAZPmBMAPGUOg6+Yw+Br5jD4hjn3Ab5lDoOYOQwS5jDY13RrKHOLF3QXqG1QFejA9BMW97A41FQZsr/jhWF/bxCzfzCIqT9quj2k/sQLQ/3ZIKb+YhBTf9V0Z0j9jReG+rtBTP3DIKY+0y/GcpnBX0a+S4UDyi42n/P3xPsHwhpAtgABAAH//wAPeJxlUM9rE0EY/b6ZuLukTTs7O7sJxcZ1Nk2gaVOY/NiDiBcP0oMHDyGHniT0mD8h5BCk5ORxWaSnnjwUUdtCwUVKoSXHIv4BHv0D9iCaOJuAKA7DG943M++97wMEvfAreQmbYHxwKO7WtzxhyD00DVmrtp6ghrCjHqAGT6wjXvOK4uMxV5yxyYQxvmQVPrniSrIoWpTeHC8eaCYVP9YWmQ95SkbgaB9maB9Uoo6ukI8xkK1H2G6pTSTVcvmuf5cBvl6eGeivAPMrKsl3sGEDrLOSWM2RLOs6GntoBLLKOr7nCnNLeKrTqkqD5sqlRsVP9l+Mko8Inxuz0tG7od7P5f2G7yfbCcJ5Murtv+0dDd+/GgLQ+Y/5Ob2hFqwCAwH5C26vFfKE7tbveUbwUM8jxI4qOu3ADe3App/yQvwc83xhBRNrx9oYDAYlJhlndI3zX5V+/xR3Zl8W2S/pM0rA0qrWmb2SA5L17zHD17kxrJk1s2gWw2KIJ6dpOjtJU8zF3TjqxXEviruULGsH6ewg7kaRvskQ4D9tp/CvttNsBzpu4Dbd5h/tb7e3h9Pp4V+q2xmf/gaaAYe+AAAAeJxjYGRgYADiVL7Tf+L5bb4ycDO/AIowXPqwsQRG///1fxvzC2YOIJeDgQkkCgCeTA9OAHicY2BkYGAO+p/FEMX84v+v/5+ZXzAARVAAOwC+sAfjA+gAAAHWAAACRAAAAxUAAAPC//oDSAAAA0gAAAAAAAAANABUAIYAsgDgAQcAAQAAAAcAHgADAAAAAAACAAAAEABzAAAAHAtwAAAAAHicdZLNSgMxFIVPbKvYggsV3WYlSun0BxTsRqGgK0FcdOFu2qYzU6ZJyKRKn8E38B18JcE38XQarEKdMJnvnpzcexMGwCE+IbB+LvmuWaDOaM072MNN4Ar1u8BV8mPgGhp4DrxLXQWuowkTuIEjvDODqO4zmuEjsMCxOA28gwPRDFyhfh24Sn4IXMOJiAPvUn8NXMdQvAVu4Ex8DYxduixJvTwfXMhep3slR0tpKGU6zmW88KlxhbyVU6O9ynMTjc18ZOe6lZmWtU8qWeSx2wgbGipXZEbLbtTZiPdKKxd7NVlVKV6SnvdTOXVmLu9Cfmmdmamxj1Lvbb/d/l0XA16UxRIOGRKk8JA4p3rBbw8ddHFFGtEh6Vy7MmjEyKnEWHBHWq4UjG/5ThlpqoqOnBxhzHnOHJazRov7DWfL8URXwhw5M7mtjm3akLtW9bKykmSPETvd5rynU5fuuOxo8nOWAi+s3KPq2fGqa1d2Kfmj/e1fMs9qbUZlTD0qb8lT7aPN8c95vwGTUof7AHicY2BigAAuBuyAnZGJkZmRhZGVkY2RnZGDgTU5JzWxiDkxJYWtGMhIzuBMLClJzSvJzM/jBUvpJmcWARkp3EAlMDYDAwAmBxMfAAB4nGPw3sFwIihiIyNjX+QGxp0cDBwMyQUbGVidNjIwaEFoDhR6JwMDAycyi5nBZaMKY0dgxAaHjoiNzCkuG9VAvF0cDQyMLA4dySERICWRQLCRgUdrB+P/1g0svRuZGFwAB9MiuAAAAA==") format('woff'), url("data:application/x-font-ttf;base64,AAEAAAAPAIAAAwBwR1NVQrD+s+0AAAD8AAAAQk9TLzI+IkmhAAABQAAAAFZjbWFwndm+LAAAAZgAAAHGY3Z0IAAAAAAAAAlwAAAACmZwZ22IkJBZAAAJfAAAC3BnYXNwAAAAEAAACWgAAAAIZ2x5ZoZc5FwAAANgAAACDmhlYWQI4qaLAAAFcAAAADZoaGVhB5EDTQAABagAAAAkaG10eBVp//oAAAXMAAAAHGxvY2EBmgINAAAF6AAAABBtYXhwAJoLoAAABfgAAAAgbmFtZQ/XAmkAAAYYAAAC5XBvc3T6fxacAAAJAAAAAGhwcmVw3WsDhQAAFOwAAAB7AAEAAAAKAB4ALAABREZMVAAIAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAAAAQMPAZAABQAAAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA6ALpAwNS/2oAWgNSAJYAAAABAAAAAAAAAAAABQAAAAMAAAAsAAAABAAAAW4AAQAAAAAAaAADAAEAAAAsAAMACgAAAW4ABAA8AAAACAAIAAIAAOgD6AbpA///AADoAugF6QL//wAAAAAAAAABAAgACgAMAAAAAQACAAMABAAFAAYAAAEGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAFgAAAAAAAAABgAA6AIAAOgCAAAAAQAA6AMAAOgDAAAAAgAA6AUAAOgFAAAAAwAA6AYAAOgGAAAABAAA6QIAAOkCAAAABQAA6QMAAOkDAAAABgAAAAEAAAAAAdYCYgAdAAazEwMBLSslFhQGIi8BBwYiJyY0PwEnJjQ3NjIfATc2MhYUDwEBxBIkMhKEhBIyEhAQiooQEBIyEoSEEjIkEorCEjIiEJiYEBASMhKcnhIyEhAQmJgQIjISngAAAQAAAAACRAKAABMABrMQBgEtKwEyFCsBFRQiPQEjIjQ7ATU0Mh0BAiYeHtJk0h4e0mQBkGTSHh7SZNIeHtIAAAIAAP/CAyIC6gARABoACLUYFAwEAi0rJRYPAQYvAQYjIiYQNiAWFRQHJRQWMjY0JiIGAwQeGC4kIL5KUoC+tAEAwC7+GIiwfoiwfk4iHC4gIL4qvgEAtr6AWEqqWIh+soZ+AAAD//r/tgPHAwgADAAQABQACrcSEQ4NCgIDLSsFFgYjISInJjcBNjIXEzUjFTcRIxEDvQoUFPyEEgoNCwG+CCwIGm5ubhgQIhASEAMOEhL9JGRkrgEs/tQAAgAA/7oDSAMCAAgAFAAItRELBAACLSsBMhYQBiAmEDYBNycHJwcXBxc3FzcBpK729v6k9vYBBJpWmphYmppYmJpWAwL2/qT29gFc9v5cmlaYmFaamFaYmFYAAAACAAD/ugNIAwIACAAUAAi1Ew0EAAItKwEyFhAGICYQNhMzNSM1IxUjFTMVMwGkrvb2/qT29uLIyGbKymYDAvb+pPb2AVz2/ipmyspmygAAAAEAAAABAABlDyFwXw889QALA+gAAAAA0vCxdAAAAADS8LF0//r/tgPoAwgAAAAIAAIAAAAAAAAAAQAAA1L/agBaA+j/+v/zA+gAAQAAAAAAAAAAAAAAAAAAAAcD6AAAAdYAAAJEAAADFQAAA8L/+gNIAAADSAAAAAAAAAA0AFQAhgCyAOABBwABAAAABwAeAAMAAAAAAAIAAAAQAHMAAAAcC3AAAAAAAAAAEgDeAAEAAAAAAAAANQAAAAEAAAAAAAEACgA1AAEAAAAAAAIABwA/AAEAAAAAAAMACgBGAAEAAAAAAAQACgBQAAEAAAAAAAUACwBaAAEAAAAAAAYACgBlAAEAAAAAAAoAKwBvAAEAAAAAAAsAEwCaAAMAAQQJAAAAagCtAAMAAQQJAAEAFAEXAAMAAQQJAAIADgErAAMAAQQJAAMAFAE5AAMAAQQJAAQAFAFNAAMAAQQJAAUAFgFhAAMAAQQJAAYAFAF3AAMAAQQJAAoAVgGLAAMAAQQJAAsAJgHhQ29weXJpZ2h0IChDKSAyMDE2IGJ5IG9yaWdpbmFsIGF1dGhvcnMgQCBmb250ZWxsby5jb21icG1uLWlvLXBwUmVndWxhcmJwbW4taW8tcHBicG1uLWlvLXBwVmVyc2lvbiAxLjBicG1uLWlvLXBwR2VuZXJhdGVkIGJ5IHN2ZzJ0dGYgZnJvbSBGb250ZWxsbyBwcm9qZWN0Lmh0dHA6Ly9mb250ZWxsby5jb20AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAxADYAIABiAHkAIABvAHIAaQBnAGkAbgBhAGwAIABhAHUAdABoAG8AcgBzACAAQAAgAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAGIAcABtAG4ALQBpAG8ALQBwAHAAUgBlAGcAdQBsAGEAcgBiAHAAbQBuAC0AaQBvAC0AcABwAGIAcABtAG4ALQBpAG8ALQBwAHAAVgBlAHIAcwBpAG8AbgAgADEALgAwAGIAcABtAG4ALQBpAG8ALQBwAHAARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAAIAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwECAQMBBAEFAQYBBwEIAAVjbGVhcgNhZGQGc2VhcmNoCWF0dGVudGlvbg1jbGVhci1jaXJjbGVkC2FkZC1jaXJjbGVkAAAAAQAB//8ADwAAAAAAAAAAAAAAALAALCCwAFVYRVkgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbkIAAgAY2MjYhshIbAAWbAAQyNEsgABAENgQi2wASywIGBmLbACLCBkILDAULAEJlqyKAEKQ0VjRVJbWCEjIRuKWCCwUFBYIbBAWRsgsDhQWCGwOFlZILEBCkNFY0VhZLAoUFghsQEKQ0VjRSCwMFBYIbAwWRsgsMBQWCBmIIqKYSCwClBYYBsgsCBQWCGwCmAbILA2UFghsDZgG2BZWVkbsAErWVkjsABQWGVZWS2wAywgRSCwBCVhZCCwBUNQWLAFI0KwBiNCGyEhWbABYC2wBCwjISMhIGSxBWJCILAGI0KxAQpDRWOxAQpDsABgRWOwAyohILAGQyCKIIqwASuxMAUlsAQmUVhgUBthUllYI1khILBAU1iwASsbIbBAWSOwAFBYZVktsAUssAdDK7IAAgBDYEItsAYssAcjQiMgsAAjQmGwAmJmsAFjsAFgsAUqLbAHLCAgRSCwC0NjuAQAYiCwAFBYsEBgWWawAWNgRLABYC2wCCyyBwsAQ0VCKiGyAAEAQ2BCLbAJLLAAQyNEsgABAENgQi2wCiwgIEUgsAErI7AAQ7AEJWAgRYojYSBkILAgUFghsAAbsDBQWLAgG7BAWVkjsABQWGVZsAMlI2FERLABYC2wCywgIEUgsAErI7AAQ7AEJWAgRYojYSBksCRQWLAAG7BAWSOwAFBYZVmwAyUjYUREsAFgLbAMLCCwACNCsgsKA0VYIRsjIVkqIS2wDSyxAgJFsGRhRC2wDiywAWAgILAMQ0qwAFBYILAMI0JZsA1DSrAAUlggsA0jQlktsA8sILAQYmawAWMguAQAY4ojYbAOQ2AgimAgsA4jQiMtsBAsS1RYsQRkRFkksA1lI3gtsBEsS1FYS1NYsQRkRFkbIVkksBNlI3gtsBIssQAPQ1VYsQ8PQ7ABYUKwDytZsABDsAIlQrEMAiVCsQ0CJUKwARYjILADJVBYsQEAQ2CwBCVCioogiiNhsA4qISOwAWEgiiNhsA4qIRuxAQBDYLACJUKwAiVhsA4qIVmwDENHsA1DR2CwAmIgsABQWLBAYFlmsAFjILALQ2O4BABiILAAUFiwQGBZZrABY2CxAAATI0SwAUOwAD6yAQEBQ2BCLbATLACxAAJFVFiwDyNCIEWwCyNCsAojsABgQiBgsAFhtRAQAQAOAEJCimCxEgYrsHIrGyJZLbAULLEAEystsBUssQETKy2wFiyxAhMrLbAXLLEDEystsBgssQQTKy2wGSyxBRMrLbAaLLEGEystsBsssQcTKy2wHCyxCBMrLbAdLLEJEystsB4sALANK7EAAkVUWLAPI0IgRbALI0KwCiOwAGBCIGCwAWG1EBABAA4AQkKKYLESBiuwcisbIlktsB8ssQAeKy2wICyxAR4rLbAhLLECHistsCIssQMeKy2wIyyxBB4rLbAkLLEFHistsCUssQYeKy2wJiyxBx4rLbAnLLEIHistsCgssQkeKy2wKSwgPLABYC2wKiwgYLAQYCBDI7ABYEOwAiVhsAFgsCkqIS2wKyywKiuwKiotsCwsICBHICCwC0NjuAQAYiCwAFBYsEBgWWawAWNgI2E4IyCKVVggRyAgsAtDY7gEAGIgsABQWLBAYFlmsAFjYCNhOBshWS2wLSwAsQACRVRYsAEWsCwqsAEVMBsiWS2wLiwAsA0rsQACRVRYsAEWsCwqsAEVMBsiWS2wLywgNbABYC2wMCwAsAFFY7gEAGIgsABQWLBAYFlmsAFjsAErsAtDY7gEAGIgsABQWLBAYFlmsAFjsAErsAAWtAAAAAAARD4jOLEvARUqLbAxLCA8IEcgsAtDY7gEAGIgsABQWLBAYFlmsAFjYLAAQ2E4LbAyLC4XPC2wMywgPCBHILALQ2O4BABiILAAUFiwQGBZZrABY2CwAENhsAFDYzgtsDQssQIAFiUgLiBHsAAjQrACJUmKikcjRyNhIFhiGyFZsAEjQrIzAQEVFCotsDUssAAWsAQlsAQlRyNHI2GwCUMrZYouIyAgPIo4LbA2LLAAFrAEJbAEJSAuRyNHI2EgsAQjQrAJQysgsGBQWCCwQFFYswIgAyAbswImAxpZQkIjILAIQyCKI0cjRyNhI0ZgsARDsAJiILAAUFiwQGBZZrABY2AgsAErIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbACYiCwAFBYsEBgWWawAWNhIyAgsAQmI0ZhOBsjsAhDRrACJbAIQ0cjRyNhYCCwBEOwAmIgsABQWLBAYFlmsAFjYCMgsAErI7AEQ2CwASuwBSVhsAUlsAJiILAAUFiwQGBZZrABY7AEJmEgsAQlYGQjsAMlYGRQWCEbIyFZIyAgsAQmI0ZhOFktsDcssAAWICAgsAUmIC5HI0cjYSM8OC2wOCywABYgsAgjQiAgIEYjR7ABKyNhOC2wOSywABawAyWwAiVHI0cjYbAAVFguIDwjIRuwAiWwAiVHI0cjYSCwBSWwBCVHI0cjYbAGJbAFJUmwAiVhuQgACABjYyMgWGIbIVljuAQAYiCwAFBYsEBgWWawAWNgIy4jICA8ijgjIVktsDossAAWILAIQyAuRyNHI2EgYLAgYGawAmIgsABQWLBAYFlmsAFjIyAgPIo4LbA7LCMgLkawAiVGUlggPFkusSsBFCstsDwsIyAuRrACJUZQWCA8WS6xKwEUKy2wPSwjIC5GsAIlRlJYIDxZIyAuRrACJUZQWCA8WS6xKwEUKy2wPiywNSsjIC5GsAIlRlJYIDxZLrErARQrLbA/LLA2K4ogIDywBCNCijgjIC5GsAIlRlJYIDxZLrErARQrsARDLrArKy2wQCywABawBCWwBCYgLkcjRyNhsAlDKyMgPCAuIzixKwEUKy2wQSyxCAQlQrAAFrAEJbAEJSAuRyNHI2EgsAQjQrAJQysgsGBQWCCwQFFYswIgAyAbswImAxpZQkIjIEewBEOwAmIgsABQWLBAYFlmsAFjYCCwASsgiophILACQ2BkI7ADQ2FkUFiwAkNhG7ADQ2BZsAMlsAJiILAAUFiwQGBZZrABY2GwAiVGYTgjIDwjOBshICBGI0ewASsjYTghWbErARQrLbBCLLA1Ky6xKwEUKy2wQyywNishIyAgPLAEI0IjOLErARQrsARDLrArKy2wRCywABUgR7AAI0KyAAEBFRQTLrAxKi2wRSywABUgR7AAI0KyAAEBFRQTLrAxKi2wRiyxAAEUE7AyKi2wRyywNCotsEgssAAWRSMgLiBGiiNhOLErARQrLbBJLLAII0KwSCstsEossgAAQSstsEsssgABQSstsEwssgEAQSstsE0ssgEBQSstsE4ssgAAQistsE8ssgABQistsFAssgEAQistsFEssgEBQistsFIssgAAPistsFMssgABPistsFQssgEAPistsFUssgEBPistsFYssgAAQCstsFcssgABQCstsFgssgEAQCstsFkssgEBQCstsFossgAAQystsFsssgABQystsFwssgEAQystsF0ssgEBQystsF4ssgAAPystsF8ssgABPystsGAssgEAPystsGEssgEBPystsGIssDcrLrErARQrLbBjLLA3K7A7Ky2wZCywNyuwPCstsGUssAAWsDcrsD0rLbBmLLA4Ky6xKwEUKy2wZyywOCuwOystsGgssDgrsDwrLbBpLLA4K7A9Ky2waiywOSsusSsBFCstsGsssDkrsDsrLbBsLLA5K7A8Ky2wbSywOSuwPSstsG4ssDorLrErARQrLbBvLLA6K7A7Ky2wcCywOiuwPCstsHEssDorsD0rLbByLLMJBAIDRVghGyMhWUIrsAhlsAMkUHiwARUwLQBLuADIUlixAQGOWbABuQgACABjcLEABUKxAAAqsQAFQrEACCqxAAVCsQAIKrEABUK5AAAACSqxAAVCuQAAAAkqsQMARLEkAYhRWLBAiFixA2REsSYBiFFYugiAAAEEQIhjVFixAwBEWVlZWbEADCq4Af+FsASNsQIARAA=") format('truetype'), url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxtZXRhZGF0YT5Db3B5cmlnaHQgKEMpIDIwMTYgYnkgb3JpZ2luYWwgYXV0aG9ycyBAIGZvbnRlbGxvLmNvbTwvbWV0YWRhdGE+CjxkZWZzPgo8Zm9udCBpZD0iYnBtbi1pby1wcCIgaG9yaXotYWR2LXg9IjEwMDAiID4KPGZvbnQtZmFjZSBmb250LWZhbWlseT0iYnBtbi1pby1wcCIgZm9udC13ZWlnaHQ9IjQwMCIgZm9udC1zdHJldGNoPSJub3JtYWwiIHVuaXRzLXBlci1lbT0iMTAwMCIgYXNjZW50PSI4NTAiIGRlc2NlbnQ9Ii0xNTAiIC8+CjxtaXNzaW5nLWdseXBoIGhvcml6LWFkdi14PSIxMDAwIiAvPgo8Z2x5cGggZ2x5cGgtbmFtZT0iY2xlYXIiIHVuaWNvZGU9IiYjeGU4MDI7IiBkPSJNNDUyIDE5NHExOC0xOCAxOC00M3QtMTgtNDNxLTE4LTE2LTQzLTE2dC00MyAxNmwtMTMyIDE1Mi0xMzItMTUycS0xOC0xNi00My0xNnQtNDMgMTZxLTE2IDE4LTE2IDQzdDE2IDQzbDEzOCAxNTYtMTM4IDE1OHEtMTYgMTgtMTYgNDN0MTYgNDNxMTggMTYgNDMgMTZ0NDMtMTZsMTMyLTE1MiAxMzIgMTUycTE4IDE2IDQzIDE2dDQzLTE2cTE4LTE4IDE4LTQzdC0xOC00M2wtMTM4LTE1OHoiIGhvcml6LWFkdi14PSI0NzAiIC8+CjxnbHlwaCBnbHlwaC1uYW1lPSJhZGQiIHVuaWNvZGU9IiYjeGU4MDM7IiBkPSJNNTUwIDQwMHEzMCAwIDMwLTUwdC0zMC01MGwtMjEwIDAgMC0yMTBxMC0zMC01MC0zMHQtNTAgMzBsMCAyMTAtMjEwIDBxLTMwIDAtMzAgNTB0MzAgNTBsMjEwIDAgMCAyMTBxMCAzMCA1MCAzMHQ1MC0zMGwwLTIxMCAyMTAgMHoiIGhvcml6LWFkdi14PSI1ODAiIC8+CjxnbHlwaCBnbHlwaC1uYW1lPSJzZWFyY2giIHVuaWNvZGU9IiYjeGU4MDU7IiBkPSJNNzcyIDc4cTMwLTM0IDYtNjJsLTQ2LTQ2cS0zNi0zMi02OCAwbC0xOTAgMTkwcS03NC00Mi0xNTYtNDItMTI4IDAtMjIzIDk1dC05NSAyMjMgOTAgMjE5IDIxOCA5MSAyMjQtOTUgOTYtMjIzcTAtODgtNDYtMTYyeiBtLTY3OCAzNThxMC04OCA2OC0xNTZ0MTU2LTY4IDE1MSA2MyA2MyAxNTNxMCA4OC02OCAxNTV0LTE1NiA2Ny0xNTEtNjMtNjMtMTUxeiIgaG9yaXotYWR2LXg9Ijc4OSIgLz4KPGdseXBoIGdseXBoLW5hbWU9ImF0dGVudGlvbiIgdW5pY29kZT0iJiN4ZTgwNjsiIGQ9Ik05NTctMjRxMTAtMTYgMC0zNC0xMC0xNi0zMC0xNmwtODkyIDBxLTE4IDAtMjggMTYtMTMgMTgtMiAzNGw0NDYgNzgycTggMTggMzAgMTh0MzAtMTh6IG0tNDIwIDUwbDAgMTAwLTExMCAwIDAtMTAwIDExMCAweiBtMCAxNzRsMCAzMDAtMTEwIDAgMC0zMDAgMTEwIDB6IiBob3Jpei1hZHYteD0iOTYyIiAvPgo8Z2x5cGggZ2x5cGgtbmFtZT0iY2xlYXItY2lyY2xlZCIgdW5pY29kZT0iJiN4ZTkwMjsiIGQ9Ik00MjAgNzcwcTE3NCAwIDI5Ny0xMjN0MTIzLTI5Ny0xMjMtMjk3LTI5Ny0xMjMtMjk3IDEyMy0xMjMgMjk3IDEyMyAyOTcgMjk3IDEyM3ogbTg2LTQyMGwxNTQgMTU0LTg2IDg2LTE1NC0xNTItMTUyIDE1Mi04OC04NiAxNTQtMTU0LTE1NC0xNTIgODgtODYgMTUyIDE1MiAxNTQtMTUyIDg2IDg2eiIgaG9yaXotYWR2LXg9Ijg0MCIgLz4KPGdseXBoIGdseXBoLW5hbWU9ImFkZC1jaXJjbGVkIiB1bmljb2RlPSImI3hlOTAzOyIgZD0iTTQyMCA3NzBxMTc0IDAgMjk3LTEyM3QxMjMtMjk3LTEyMy0yOTctMjk3LTEyMy0yOTcgMTIzLTEyMyAyOTcgMTIzIDI5NyAyOTcgMTIzeiBtNTItNDcwbDIwMCAwIDAgMTAyLTIwMCAwIDAgMjAyLTEwMiAwIDAtMjAyLTIwMiAwIDAtMTAyIDIwMiAwIDAtMjAyIDEwMiAwIDAgMjAyeiIgaG9yaXotYWR2LXg9Ijg0MCIgLz4KPC9mb250Pgo8L2RlZnM+Cjwvc3ZnPg==") format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+/* line 16, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel {
+ background-color: #f8f8f8;
+ position: relative;
+}
+/* line 20, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel:empty {
+ display: none;
+}
+/* line 24, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel label,
+.bpp-properties-panel input {
+ vertical-align: middle;
+}
+/* line 29, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel input,
+.bpp-properties-panel button,
+.bpp-properties-panel textarea,
+.bpp-properties-panel [contenteditable] {
+ padding: 3px 6px;
+ border: 1px solid #ccc;
+}
+/* line 36, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel input:focus,
+.bpp-properties-panel button:focus,
+.bpp-properties-panel textarea:focus,
+.bpp-properties-panel [contenteditable]:focus {
+ outline: none;
+ border-color: #52B415;
+ box-shadow: 0 0 1px 2px rgba(82, 180, 21, 0.2);
+}
+/* line 40, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel input.invalid,
+.bpp-properties-panel button.invalid,
+.bpp-properties-panel textarea.invalid,
+.bpp-properties-panel [contenteditable].invalid {
+ border-color: #cc3333;
+ background: #f0c2c2;
+}
+/* line 42, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel input.invalid:focus,
+.bpp-properties-panel button.invalid:focus,
+.bpp-properties-panel textarea.invalid:focus,
+.bpp-properties-panel [contenteditable].invalid:focus {
+ box-shadow: 0 0 1px 2px rgba(204, 51, 51, 0.2);
+}
+/* line 48, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel [type=text],
+.bpp-properties-panel [contenteditable],
+.bpp-properties-panel textarea,
+.bpp-properties-panel select {
+ width: 100%;
+}
+/* line 55, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel [contenteditable],
+.bpp-properties-panel textarea {
+ resize: vertical;
+}
+/* line 60, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel [contenteditable] {
+ outline: 0px solid transparent;
+ background-color: white;
+ overflow-y: auto;
+ white-space: pre-wrap;
+ /* css-3 */
+ white-space: -moz-pre-wrap;
+ /* Mozilla, since 1999 */
+ white-space: -pre-wrap;
+ /* Opera 4-6 */
+ white-space: -o-pre-wrap;
+ /* Opera 7 */
+ word-wrap: break-word;
+ /* Internet Explorer 5.5+ */
+}
+/* line 72, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel [contenteditable]:before {
+ content: "\feff ";
+}
+/* line 77, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel [disabled] {
+ color: #808080;
+}
+/* line 81, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel label {
+ font-weight: bolder;
+ display: inline-block;
+ vertical-align: middle;
+ color: #666;
+ margin-bottom: 3px;
+}
+/* line 71, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-panel label[for] {
+ cursor: pointer;
+}
+/* line 74, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-panel label.bpp-hidden {
+ display: none;
+}
+/* line 87, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel .entry-label {
+ font-weight: bolder;
+ display: inline-block;
+ vertical-align: middle;
+ color: #666;
+ font-size: 120%;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ transition: margin 0.218s linear;
+ font-style: italic;
+}
+/* line 71, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-panel .entry-label[for] {
+ cursor: pointer;
+}
+/* line 74, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-panel .entry-label.bpp-hidden {
+ display: none;
+}
+/* line 95, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel .entry-label.divider {
+ border-top: 1px dotted #ccc;
+ padding-top: 8px;
+ margin-top: 16px;
+ width: 100%;
+}
+/* line 103, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-panel button {
+ position: absolute;
+ top: 0;
+ height: 23px;
+ width: 24px;
+ overflow: hidden;
+ cursor: pointer;
+ background-color: #f8f8f8;
+ border: 1px solid #ccc;
+}
+/* line 44, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-panel button > span {
+ display: none;
+}
+/* line 48, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-panel button:before {
+ font-family: "bpmn-js-pp";
+ font-style: normal;
+ font-weight: normal;
+ speak: none;
+ display: inline-block;
+ text-decoration: inherit;
+ text-align: center;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1em;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ position: relative;
+}
+/* line 53, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-panel button.add:before {
+ content: '\E803';
+}
+/* line 57, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-panel button.clear:before {
+ content: '\E802';
+}
+/* line 61, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-panel button:hover {
+ color: #52B415;
+}
+/* line 109, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-error-message,
+.bpp-error-message.bpp-entry-link {
+ margin-top: 5px;
+ color: #cc3333;
+}
+/* line 115, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-row {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+/* line 118, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-row:first-of-type {
+ margin-top: 0;
+}
+/* line 121, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-row:last-of-type {
+ margin-bottom: 0;
+}
+/* line 126, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-textfield,
+.bpp-textbox {
+ margin-bottom: 3px;
+}
+/* line 131, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-radios-group {
+ list-style: none;
+ padding: 0;
+ margin: 0 0 9px 0;
+}
+/* line 136, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-radios-group .bpp-radio-wrapper {
+ margin: 6px 0;
+}
+/* line 140, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-radios-group input,
+.bpp-radios-group label {
+ vertical-align: middle;
+}
+/* line 145, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-radios-group input {
+ margin-top: 0;
+ margin-left: 0;
+}
+/* line 153, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-radios-group input,
+.bpp-checkbox input {
+ margin-left: 0;
+}
+/* line 158, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-radios-group label:after,
+.bpp-checkbox label:after {
+ display: none;
+}
+/* line 165, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-textfield input {
+ padding-right: 28px;
+}
+/* line 169, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-textfield .clear {
+ background: transparent;
+ border: none;
+ top: 0;
+ right: 0;
+}
+/* line 177, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-combo-input {
+ margin-top: 7px;
+}
+/* line 182, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-select select {
+ height: 23px;
+}
+/* line 185, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-select button.add {
+ top: -22px;
+ right: 0;
+}
+/* line 195, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-select button.add,
+.bpp-element-list button.add,
+.bpp-select button.clear,
+.bpp-element-list button.clear {
+ top: -23px;
+ border-bottom: none;
+}
+/* line 202, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-select button.add,
+.bpp-element-list button.add {
+ right: 0px;
+}
+/* line 206, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-select button.clear,
+.bpp-element-list button.clear {
+ right: 23px;
+}
+/* line 211, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-entry {
+ margin-bottom: 9px;
+}
+/* line 214, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-entry .bpp-field-wrapper {
+ position: relative;
+}
+/* line 217, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-entry .bpp-field-wrapper input[readonly] + .clear {
+ display: none;
+}
+/* line 221, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-entry .bpp-field-wrapper select {
+ resize: vertical;
+}
+/* line 227, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-hidden {
+ display: none;
+}
+/* line 231, node_modules\bpmn-js-properties-panel\styles\properties.less */
+label.bpp-hidden {
+ display: none;
+}
+/* line 236, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-add-row > button {
+ position: relative;
+ margin-left: 10px;
+}
+/* line 242, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table {
+ margin-top: 10px;
+}
+/* line 246, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-row {
+ margin-bottom: 2px;
+ overflow: hidden;
+}
+/* line 250, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-row > input,
+.bpp-table-row > button {
+ float: left;
+}
+/* line 255, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-row > label {
+ padding-left: 5px;
+}
+/* line 262, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-row > label.bpp-table-row-columns-1,
+.bpp-table-row > input.bpp-table-row-columns-1 {
+ width: 100%;
+}
+/* line 264, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-row > label.bpp-table-row-columns-1.bpp-table-row-removable,
+.bpp-table-row > input.bpp-table-row-columns-1.bpp-table-row-removable {
+ width: calc(100% - 24px);
+}
+/* line 269, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-row > label.bpp-table-row-columns-2,
+.bpp-table-row > input.bpp-table-row-columns-2 {
+ width: 50%;
+}
+/* line 271, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-row > label.bpp-table-row-columns-2.bpp-table-row-removable,
+.bpp-table-row > input.bpp-table-row-columns-2.bpp-table-row-removable {
+ width: calc(50% - 12px);
+}
+/* line 274, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-row > label.bpp-table-row-columns-2:nth-child(2),
+.bpp-table-row > input.bpp-table-row-columns-2:nth-child(2) {
+ border-left: none;
+}
+/* line 280, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-table-row > button {
+ border-left: none;
+ position: static;
+}
+/* line 286, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-properties-static {
+ margin-bottom: 0;
+ margin-top: 0;
+ border: 1px solid #ccc;
+ background-color: white;
+ padding: 3px 6px;
+ font: 13.3333px Arial;
+ width: 100%;
+}
+/* line 296, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-entry-link {
+ cursor: pointer;
+ color: #52B415;
+}
+/* line 301, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-icon-warning:before {
+ font-family: "bpmn-js-pp";
+ font-style: normal;
+ font-weight: normal;
+ speak: none;
+ display: inline-block;
+ text-decoration: inherit;
+ text-align: center;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1em;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: '\E806';
+}
+/* line 306, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-field-description {
+ margin-top: 5px;
+ color: #999;
+}
+/* line 310, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-field-description a {
+ color: #3d8610;
+ text-decoration: none;
+}
+/* line 314, node_modules\bpmn-js-properties-panel\styles\properties.less */
+.bpp-field-description a:hover {
+ color: #52B415;
+}
+/* line 1, node_modules\bpmn-js-properties-panel\styles\header.less */
+.bpp-properties-header {
+ padding: 15px;
+ padding-bottom: 5px;
+}
+/* line 5, node_modules\bpmn-js-properties-panel\styles\header.less */
+.bpp-properties-header > .label {
+ font-size: 120%;
+ font-weight: bolder;
+}
+/* line 10, node_modules\bpmn-js-properties-panel\styles\header.less */
+.bpp-properties-header > .search {
+ display: none;
+ margin-top: 5px;
+ position: relative;
+}
+/* line 15, node_modules\bpmn-js-properties-panel\styles\header.less */
+.bpp-properties-header > .search input {
+ position: relative;
+ border-radius: 15px;
+ width: 100%;
+ z-index: 1;
+}
+/* line 22, node_modules\bpmn-js-properties-panel\styles\header.less */
+.bpp-properties-header > .search button {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ border: none;
+ background-color: transparent;
+ z-index: 2;
+}
+/* line 30, node_modules\bpmn-js-properties-panel\styles\header.less */
+.bpp-properties-header > .search button:before {
+ content: '\E805';
+}
+/* line 1, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group {
+ padding: 6px 15px 6px 15px;
+ position: relative;
+ max-height: 2000px;
+ overflow: hidden;
+ transition: max-height 0.218s ease-in-out, padding-top 0.218s ease-in-out, padding-bottom 0.218s ease-in-out;
+}
+/* line 10, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group:empty {
+ display: none;
+}
+/* line 14, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group > .group-toggle {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 4px;
+ cursor: pointer;
+ transition: background-color 0.218s linear;
+}
+/* line 22, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group > .group-toggle:hover {
+ background-color: #8fc071;
+}
+/* line 27, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group > .group-label {
+ font-weight: bolder;
+ display: inline-block;
+ vertical-align: middle;
+ color: #666;
+ font-size: 120%;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ transition: margin 0.218s linear;
+ font-style: italic;
+}
+/* line 71, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-group > .group-label[for] {
+ cursor: pointer;
+}
+/* line 74, node_modules\bpmn-js-properties-panel\styles\_mixins.less */
+.bpp-properties-group > .group-label.bpp-hidden {
+ display: none;
+}
+/* line 36, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group:hover > .group-toggle {
+ background-color: #ccc;
+}
+/* line 38, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group:hover > .group-toggle:hover {
+ background-color: #8fc071;
+}
+/* line 43, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group.group-closed {
+ max-height: 20px;
+ border-top: none;
+ cursor: pointer;
+ background-color: rgba(143, 192, 113, 0.2);
+ padding-top: 0;
+ padding-bottom: 0;
+}
+/* line 51, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group.group-closed > div {
+ visibility: hidden;
+}
+/* line 55, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group.group-closed > .group-label {
+ margin-top: 2px;
+ margin-bottom: 2px;
+}
+/* line 60, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group.group-closed:hover > .group-label {
+ color: #52B415;
+}
+/* line 65, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group + .bpp-properties-group {
+ border-top: 1px dotted #ccc;
+}
+/* line 69, node_modules\bpmn-js-properties-panel\styles\groups.less */
+.bpp-properties-group:last-child {
+ padding-bottom: 9px;
+}
+/* line 2, node_modules\bpmn-js-properties-panel\styles\listeners.less */
+.cam-add-listener > button {
+ position: relative;
+ margin-left: 10px;
+}
+/* line 8, node_modules\bpmn-js-properties-panel\styles\listeners.less */
+[data-list-entry-container] > .bpp-listener-area {
+ border: 1px solid #ccc;
+ margin: 10px 1px;
+ padding: 10px;
+}
+/* line 14, node_modules\bpmn-js-properties-panel\styles\listeners.less */
+.bpp-listener-area {
+ position: relative;
+}
+/* line 16, node_modules\bpmn-js-properties-panel\styles\listeners.less */
+.bpp-listener-area > button {
+ position: absolute;
+ right: 0;
+ top: 0;
+ border: none;
+ background: none;
+}
+/* line 25, node_modules\bpmn-js-properties-panel\styles\listeners.less */
+.bpp-listener-area + .bpp-listener-area {
+ margin-top: 20px;
+}
+/* line 1, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+.bpp-properties-tab-bar {
+ border-bottom: 1px solid #ccc;
+ padding: 0 15px;
+}
+/* line 5, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+.bpp-properties-tab-bar .scroll-tabs-button {
+ cursor: pointer;
+ font-size: 16px;
+ padding: 3px 4px 3px 4px;
+ color: #666;
+}
+/* line 11, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+.bpp-properties-tab-bar .scroll-tabs-button:hover {
+ font-weight: bold;
+}
+/* line 15, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+.bpp-properties-tab-bar .scroll-tabs-button.scroll-tabs-left {
+ float: left;
+ margin-left: -15px;
+}
+/* line 20, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+.bpp-properties-tab-bar .scroll-tabs-button.scroll-tabs-right {
+ float: right;
+ margin-right: -15px;
+}
+/* line 27, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+.bpp-properties-tab-bar:not(.scroll-tabs-overflow) .scroll-tabs-button {
+ display: none;
+}
+/* line 33, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+ul.bpp-properties-tabs-links {
+ margin: 5px 0 -1px 0;
+ padding: 0;
+ white-space: nowrap;
+ overflow: hidden;
+}
+/* line 39, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+ul.bpp-properties-tabs-links > li {
+ display: inline-block;
+ margin: 0;
+}
+/* line 43, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+ul.bpp-properties-tabs-links > li.bpp-hidden {
+ display: none;
+}
+/* line 47, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+ul.bpp-properties-tabs-links > li > a {
+ display: inline-block;
+ font-size: 12px;
+ padding: 4px 7px;
+ border: 1px solid #ccc;
+ border-radius: 3px 3px 0 0;
+ border-bottom: transparent;
+ background-color: #f8f8f8;
+ color: #666;
+ text-decoration: none;
+}
+/* line 62, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+ul.bpp-properties-tabs-links > li > a:hover {
+ color: #4d4d4d;
+}
+/* line 68, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+ul.bpp-properties-tabs-links > li + li {
+ margin-left: 4px;
+}
+/* line 74, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+ul.bpp-properties-tabs-links > li.bpp-active a {
+ padding-bottom: 5px;
+ border-top: 2px solid #52B415;
+ border-bottom: none;
+}
+/* line 83, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+.bpp-properties-tab,
+.bpp-properties-tab.bpp-hidden {
+ display: none;
+}
+/* line 88, node_modules\bpmn-js-properties-panel\styles\tabs.less */
+.bpp-properties-tab.bpp-active {
+ display: block;
+}
+/* line 3, styles/app.less */
+* {
+ box-sizing: border-box;
+}
+/* line 7, styles/app.less */
+body,
+html {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 12px;
+ height: 100%;
+ max-height: 100%;
+ padding: 0;
+ margin: 0;
+}
+/* line 20, styles/app.less */
+a:link {
+ text-decoration: none;
+}
+/* line 24, styles/app.less */
+.content {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+/* line 29, styles/app.less */
+.content > .message {
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ display: table;
+ font-size: 16px;
+ color: #111;
+}
+/* line 38, styles/app.less */
+.content > .message .note {
+ vertical-align: middle;
+ text-align: center;
+ display: table-cell;
+}
+/* line 45, styles/app.less */
+.content > .message.error .details {
+ max-width: 500px;
+ font-size: 12px;
+ margin: 20px auto;
+ text-align: left;
+ color: #BD2828;
+}
+/* line 53, styles/app.less */
+.content > .message.error pre {
+ border: solid 1px #BD2828;
+ background: #fefafa;
+ padding: 10px;
+ color: #BD2828;
+}
+/* line 61, styles/app.less */
+.content:not(.with-error) .error,
+.content.with-error .intro,
+.content.with-diagram .intro {
+ display: none;
+}
+/* line 67, styles/app.less */
+.content .canvas {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+/* line 75, styles/app.less */
+.content .canvas,
+.content .properties-panel-parent {
+ display: none;
+}
+/* line 81, styles/app.less */
+.content.with-diagram .canvas,
+.content.with-diagram .properties-panel-parent {
+ display: block;
+}
+/* line 89, styles/app.less */
+.buttons {
+ position: fixed;
+ bottom: 20px;
+ left: 20px;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+/* line 98, styles/app.less */
+.buttons > li {
+ display: inline-block;
+ margin-right: 10px;
+}
+/* line 102, styles/app.less */
+.buttons > li > a {
+ background: #DDD;
+ border: solid 1px #666;
+ display: inline-block;
+ padding: 5px;
+}
+/* line 110, styles/app.less */
+.buttons a {
+ opacity: 0.3;
+}
+/* line 114, styles/app.less */
+.buttons a.active {
+ opacity: 1.0;
+}
+/* line 119, styles/app.less */
+.properties-panel-parent {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ width: 260px;
+ z-index: 10;
+ border-left: 1px solid #ccc;
+ overflow: auto;
+}
+/* line 128, styles/app.less */
+.properties-panel-parent:empty {
+ display: none;
+}
+/* line 131, styles/app.less */
+.properties-panel-parent > .djs-properties-panel {
+ padding-bottom: 70px;
+ min-height: 100%;
+}
diff --git a/src/main/resources/static/css/diagram-js.css b/src/main/resources/static/css/diagram-js.css
new file mode 100644
index 0000000..7c6f320
--- /dev/null
+++ b/src/main/resources/static/css/diagram-js.css
@@ -0,0 +1,683 @@
+/**
+ * outline styles
+ */
+
+.djs-outline {
+ fill: none;
+ visibility: hidden;
+}
+
+.djs-element.hover .djs-outline,
+.djs-element.selected .djs-outline {
+ visibility: visible;
+ shape-rendering: crispEdges;
+ stroke-dasharray: 3,3;
+}
+
+.djs-element.selected .djs-outline {
+ stroke: #8888FF;
+ stroke-width: 1px;
+}
+
+.djs-element.hover .djs-outline {
+ stroke: #FF8888;
+ stroke-width: 1px;
+}
+
+.djs-shape.connect-ok .djs-visual > :nth-child(1) {
+ fill: #DCFECC /* light-green */ !important;
+}
+
+.djs-shape.connect-not-ok .djs-visual > :nth-child(1),
+.djs-shape.drop-not-ok .djs-visual > :nth-child(1) {
+ fill: #f9dee5 /* light-red */ !important;
+}
+
+.djs-shape.new-parent .djs-visual > :nth-child(1) {
+ fill: #F7F9FF !important;
+}
+
+svg.drop-not-ok {
+ background: #f9dee5 /* light-red */ !important;
+}
+
+svg.new-parent {
+ background: #F7F9FF /* light-blue */ !important;
+}
+
+.djs-connection.connect-ok .djs-visual > :nth-child(1),
+.djs-connection.drop-ok .djs-visual > :nth-child(1) {
+ stroke: #90DD5F /* light-green */ !important;
+}
+
+.djs-connection.connect-not-ok .djs-visual > :nth-child(1),
+.djs-connection.drop-not-ok .djs-visual > :nth-child(1) {
+ stroke: #E56283 /* light-red */ !important;
+}
+
+.drop-not-ok,
+.connect-not-ok {
+ cursor: not-allowed;
+}
+
+.djs-element.attach-ok .djs-visual > :nth-child(1) {
+ stroke-width: 5px !important;
+ stroke: rgba(255, 116, 0, 0.7) !important;
+}
+
+
+/**
+* Selection box style
+*
+*/
+.djs-lasso-overlay {
+ fill: rgb(255, 116, 0);
+ fill-opacity: 0.1;
+
+ stroke-dasharray: 5 1 3 1;
+ stroke: rgb(255, 116, 0);
+
+ shape-rendering: crispEdges;
+ pointer-events: none;
+}
+
+/**
+ * Resize styles
+ */
+.djs-resize-overlay {
+ fill: none;
+
+ stroke-dasharray: 5 1 3 1;
+ stroke: rgb(255, 116, 0);
+
+ pointer-events: none;
+}
+
+.djs-resizer-hit {
+ fill: none;
+ pointer-events: all;
+}
+
+.djs-resizer-visual {
+ fill: white;
+ stroke-width: 1px;
+ stroke: black;
+ shape-rendering: crispEdges;
+ stroke-opacity: 0.2;
+}
+
+.djs-cursor-resize-nwse,
+.djs-resizer-nw,
+.djs-resizer-se {
+ cursor: nwse-resize;
+}
+
+.djs-cursor-resize-nesw,
+.djs-resizer-ne,
+.djs-resizer-sw {
+ cursor: nesw-resize;
+}
+
+.djs-shape.djs-resizing > .djs-outline {
+ visibility: hidden !important;
+}
+
+.djs-shape.djs-resizing > .djs-resizer {
+ visibility: hidden;
+}
+
+.djs-dragger > .djs-resizer {
+ visibility: hidden;
+}
+
+/**
+ * drag styles
+ */
+.djs-dragger .djs-visual circle,
+.djs-dragger .djs-visual path,
+.djs-dragger .djs-visual polygon,
+.djs-dragger .djs-visual polyline,
+.djs-dragger .djs-visual rect,
+.djs-dragger .djs-visual text {
+ fill: none !important;
+ stroke: rgb(255, 116, 0) !important;
+}
+
+.djs-dragging {
+ opacity: 0.3;
+}
+
+.djs-dragging,
+.djs-dragging > * {
+ pointer-events: none !important;
+}
+
+.djs-dragging .djs-context-pad,
+.djs-dragging .djs-outline {
+ display: none !important;
+}
+
+/**
+ * no pointer events for visual
+ */
+.djs-visual,
+.djs-outline {
+ pointer-events: none;
+}
+
+/**
+ * all pointer events for hit shape
+ */
+.djs-shape .djs-hit {
+ pointer-events: all;
+}
+
+.djs-connection .djs-hit {
+ pointer-events: stroke;
+}
+
+/**
+ * shape / connection basic styles
+ */
+.djs-connection .djs-visual {
+ stroke-width: 2px;
+ fill: none;
+}
+
+.djs-cursor-grab {
+ cursor: -webkit-grab;
+ cursor: -moz-grab;
+ cursor: grab;
+}
+
+.djs-cursor-grabbing {
+ cursor: -webkit-grabbing;
+ cursor: -moz-grabbing;
+ cursor: grabbing;
+}
+
+.djs-cursor-crosshair {
+ cursor: crosshair;
+}
+
+.djs-cursor-move {
+ cursor: move;
+}
+
+.djs-cursor-resize-ns {
+ cursor: ns-resize;
+}
+
+.djs-cursor-resize-ew {
+ cursor: ew-resize;
+}
+
+
+/**
+ * snapping
+ */
+.djs-snap-line {
+ stroke: rgb(255, 195, 66);
+ stroke: rgba(255, 195, 66, 0.50);
+ stroke-linecap: round;
+ stroke-width: 2px;
+ pointer-events: none;
+}
+
+/**
+ * snapping
+ */
+.djs-crosshair {
+ stroke: #555;
+ stroke-linecap: round;
+ stroke-width: 1px;
+ pointer-events: none;
+ shape-rendering: crispEdges;
+ stroke-dasharray: 5, 5;
+}
+
+/**
+ * palette
+ */
+
+.djs-palette {
+ position: absolute;
+ left: 20px;
+ top: 20px;
+
+ box-sizing: border-box;
+ width: 48px;
+}
+
+.djs-palette .separator {
+ margin: 0 5px;
+ padding-top: 5px;
+
+ border: none;
+ border-bottom: solid 1px #DDD;
+
+ clear: both;
+}
+
+.djs-palette .entry:before {
+ vertical-align: middle;
+}
+
+.djs-palette .djs-palette-toggle {
+ cursor: pointer;
+}
+
+.djs-palette .entry,
+.djs-palette .djs-palette-toggle {
+ color: #333;
+ font-size: 30px;
+
+ text-align: center;
+}
+
+.djs-palette .entry {
+ float: left;
+}
+
+.djs-palette .entry img {
+ max-width: 100%;
+}
+
+.djs-palette .djs-palette-entries:after {
+ content: '';
+ display: table;
+ clear: both;
+}
+
+.djs-palette .djs-palette-toggle:hover {
+ background: #666;
+}
+
+.djs-palette .entry:hover {
+ color: rgb(255, 116, 0);
+}
+
+.djs-palette .highlighted-entry {
+ color: rgb(255, 116, 0) !important;
+}
+
+.djs-palette .entry,
+.djs-palette .djs-palette-toggle {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
+ cursor: default;
+}
+
+/**
+ * Palette open / two-column layout is controlled via
+ * classes on the palette. Events to hook into palette
+ * changed life-cycle are available in addition.
+ */
+.djs-palette.two-column.open {
+ width: 94px;
+}
+
+.djs-palette:not(.open) .djs-palette-entries {
+ display: none;
+}
+
+.djs-palette:not(.open) {
+ overflow: hidden;
+}
+
+.djs-palette.open .djs-palette-toggle {
+ display: none;
+}
+
+/**
+ * context-pad
+ */
+.djs-overlay-context-pad {
+ width: 72px;
+}
+
+.djs-context-pad {
+ position: absolute;
+ display: none;
+ pointer-events: none;
+}
+
+.djs-context-pad .entry {
+ width: 22px;
+ height: 22px;
+ text-align: center;
+ display: inline-block;
+ font-size: 22px;
+ margin: 0 2px 2px 0;
+
+ border-radius: 3px;
+
+ cursor: default;
+
+ background-color: #FEFEFE;
+ box-shadow: 0 0 2px 1px #FEFEFE;
+ pointer-events: all;
+}
+
+.djs-context-pad .entry:before {
+ vertical-align: top;
+}
+
+.djs-context-pad .entry:hover {
+ background: rgb(255, 252, 176);
+}
+
+.djs-context-pad.open {
+ display: block;
+}
+
+/**
+ * popup styles
+ */
+.djs-popup .entry {
+ line-height: 20px;
+ white-space: nowrap;
+ cursor: default;
+}
+
+/* larger font for prefixed icons */
+.djs-popup .entry:before {
+ vertical-align: middle;
+ font-size: 20px;
+}
+
+.djs-popup .entry > span {
+ vertical-align: middle;
+ font-size: 14px;
+}
+
+.djs-popup .entry:hover,
+.djs-popup .entry.active:hover {
+ background: rgb(255, 252, 176);
+}
+
+.djs-popup .entry.disabled {
+ background: inherit;
+}
+
+.djs-popup .djs-popup-header .entry {
+ display: inline-block;
+ padding: 2px 3px 2px 3px;
+
+ border: solid 1px transparent;
+ border-radius: 3px;
+}
+
+.djs-popup .djs-popup-header .entry.active {
+ color: rgb(255, 116, 0);
+ border: solid 1px rgb(255, 116, 0);
+ background-color: #F6F6F6;
+}
+
+.djs-popup-body .entry {
+ padding: 4px 10px 4px 5px;
+}
+
+.djs-popup-body .entry > span {
+ margin-left: 5px;
+}
+
+.djs-popup-body {
+ background-color: #FEFEFE;
+}
+
+.djs-popup-header {
+ border-bottom: 1px solid #DDD;
+}
+
+.djs-popup-header .entry {
+ margin: 1px;
+ margin-left: 3px;
+}
+
+.djs-popup-header .entry:last-child {
+ margin-right: 3px;
+}
+
+/**
+ * popup / palette styles
+ */
+.djs-popup, .djs-palette {
+ background: #FAFAFA;
+ border: solid 1px #CCC;
+ border-radius: 2px;
+}
+
+/**
+ * touch
+ */
+
+.djs-shape,
+.djs-connection {
+ touch-action: none;
+}
+
+.djs-segment-dragger,
+.djs-bendpoint {
+ display: none;
+}
+
+/**
+ * bendpoints
+ */
+.djs-segment-dragger .djs-visual {
+ fill: rgba(255, 255, 121, 0.2);
+ stroke-width: 1px;
+ stroke-opacity: 1;
+ stroke: rgba(255, 255, 121, 0.3);
+}
+
+.djs-bendpoint .djs-visual {
+ fill: rgba(255, 255, 121, 0.8);
+ stroke-width: 1px;
+ stroke-opacity: 0.5;
+ stroke: black;
+}
+
+.djs-segment-dragger:hover,
+.djs-bendpoints.hover .djs-segment-dragger,
+.djs-bendpoints.selected .djs-segment-dragger,
+.djs-bendpoint:hover,
+.djs-bendpoints.hover .djs-bendpoint,
+.djs-bendpoints.selected .djs-bendpoint {
+ display: block;
+}
+
+.djs-drag-active .djs-bendpoints * {
+ display: none;
+}
+
+.djs-bendpoints:not(.hover) .floating {
+ display: none;
+}
+
+.djs-segment-dragger:hover .djs-visual,
+.djs-segment-dragger.djs-dragging .djs-visual,
+.djs-bendpoint:hover .djs-visual,
+.djs-bendpoint.floating .djs-visual {
+ fill: yellow;
+ stroke-opacity: 0.5;
+ stroke: black;
+}
+
+.djs-bendpoint.floating .djs-hit {
+ pointer-events: none;
+}
+
+.djs-segment-dragger .djs-hit,
+.djs-bendpoint .djs-hit {
+ pointer-events: all;
+ fill: none;
+}
+
+.djs-segment-dragger.horizontal .djs-hit {
+ cursor: ns-resize;
+}
+
+.djs-segment-dragger.vertical .djs-hit {
+ cursor: ew-resize;
+}
+
+.djs-segment-dragger.djs-dragging .djs-hit {
+ pointer-events: none;
+}
+
+.djs-updating,
+.djs-updating > * {
+ pointer-events: none !important;
+}
+
+.djs-updating .djs-context-pad,
+.djs-updating .djs-outline,
+.djs-updating .djs-bendpoint,
+.connect-ok .djs-bendpoint,
+.connect-not-ok .djs-bendpoint,
+.drop-ok .djs-bendpoint,
+.drop-not-ok .djs-bendpoint {
+ display: none !important;
+}
+
+.djs-segment-dragger.djs-dragging,
+.djs-bendpoint.djs-dragging {
+ display: block;
+ opacity: 1.0;
+}
+
+.djs-segment-dragger.djs-dragging .djs-visual,
+.djs-bendpoint.djs-dragging .djs-visual {
+ fill: yellow;
+ stroke-opacity: 0.5;
+}
+
+
+/**
+ * tooltips
+ */
+.djs-tooltip-error {
+ font-size: 11px;
+ line-height: 18px;
+ text-align: left;
+
+ padding: 5px;
+
+ opacity: 0.7;
+}
+
+.djs-tooltip-error > * {
+ width: 160px;
+
+ background: rgb(252, 236, 240);
+ color: rgb(158, 76, 76);
+ padding: 3px 7px;
+ border-radius: 5px;
+ border-left: solid 5px rgb(174, 73, 73);
+}
+
+.djs-tooltip-error:hover {
+ opacity: 1;
+}
+
+
+/**
+ * search pad
+ */
+.djs-search-container {
+ position: absolute;
+ top: 20px;
+ left: 0;
+ right: 0;
+ margin-left: auto;
+ margin-right: auto;
+
+ width: 25%;
+ min-width: 300px;
+ max-width: 400px;
+ z-index: 10;
+
+ font-size: 1.05em;
+ opacity: 0.9;
+ background: #FAFAFA;
+ border: solid 1px #CCC;
+ border-radius: 2px;
+}
+
+.djs-search-container:not(.open) {
+ display: none;
+}
+
+.djs-search-input input {
+ font-size: 1.05em;
+ width: 100%;
+ padding: 6px 10px;
+ border: 1px solid #ccc;
+}
+
+.djs-search-input input:focus {
+ outline: none;
+ border-color: #52B415;
+}
+
+.djs-search-results {
+ position: relative;
+ overflow-y: auto;
+ max-height: 200px;
+}
+
+.djs-search-results:hover {
+ /*background: #fffdd7;*/
+ cursor: pointer;
+}
+
+.djs-search-result {
+ width: 100%;
+ padding: 6px 10px;
+ background: white;
+ border-bottom: solid 1px #AAA;
+ border-radius: 1px;
+}
+
+.djs-search-highlight {
+ color: black;
+}
+
+.djs-search-result-primary {
+ margin: 0 0 10px;
+}
+
+.djs-search-result-secondary {
+ font-family: monospace;
+ margin: 0;
+}
+
+.djs-search-result:hover {
+ background: #fdffd6;
+}
+
+.djs-search-result-selected {
+ background: #fffcb0;
+}
+
+.djs-search-result-selected:hover {
+ background: #f7f388;
+}
+
+.djs-search-overlay {
+ background: yellow;
+ opacity: 0.3;
+}
+
+/**
+ * hidden styles
+ */
+.djs-element-hidden,
+.djs-element-hidden .djs-hit,
+.djs-element-hidden .djs-outline,
+.djs-label-hidden .djs-label {
+ display: none !important;
+}
diff --git a/src/main/resources/static/index.js b/src/main/resources/static/index.js
new file mode 100644
index 0000000..c2d594a
--- /dev/null
+++ b/src/main/resources/static/index.js
@@ -0,0 +1,82378 @@
+(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 10.');
+} else {
+ registerFileDrop(container, openDiagram);
+}
+
+// bootstrap diagram functions
+
+(0, _jquery2.default)(function () {
+
+ (0, _jquery2.default)('#js-create-diagram').click(function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+
+ createNewDiagram();
+ });
+
+ var downloadLink = (0, _jquery2.default)('#js-download-diagram');
+ var downloadSvgLink = (0, _jquery2.default)('#js-download-svg');
+
+ (0, _jquery2.default)('.buttons a').click(function (e) {
+ if (!(0, _jquery2.default)(this).is('.active')) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ });
+
+ function setEncoded(link, name, data) {
+ var encodedData = encodeURIComponent(data);
+
+ if (data) {
+ link.addClass('active').attr({
+ 'href': 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData,
+ 'download': name
+ });
+ } else {
+ link.removeClass('active');
+ }
+ }
+
+ var exportArtifacts = (0, _minDash.debounce)(function () {
+
+ saveSVG(function (err, svg) {
+ setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg);
+ });
+
+ saveDiagram(function (err, xml) {
+ setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml);
+ });
+ }, 500);
+
+ bpmnModeler.on('commandStack.changed', exportArtifacts);
+});
+
+},{"../resources/newDiagram.bpmn":536,"bpmn-js-properties-panel":2,"bpmn-js-properties-panel/lib/provider/camunda":62,"bpmn-js/lib/Modeler":114,"camunda-bpmn-moddle/resources/camunda":229,"jquery":416,"min-dash":505}],2:[function(require,module,exports){
+'use strict';
+
+module.exports = require('./lib');
+
+},{"./lib":32}],3:[function(require,module,exports){
+'use strict';
+
+var DEFAULT_PRIORITY = 1000;
+
+/**
+ * A component that decides upon the visibility / editable
+ * state of properties in the properties panel.
+ *
+ * Implementors must subclass this component and override
+ * {@link PropertiesActivator#isEntryVisible} and
+ * {@link PropertiesActivator#isPropertyEditable} to provide
+ * custom behavior.
+ *
+ * @class
+ * @constructor
+ *
+ * @param {EventBus} eventBus
+ * @param {Number} [priority] at which priority to hook into the activation
+ */
+function PropertiesActivator(eventBus, priority) {
+ var self = this;
+
+ priority = priority || DEFAULT_PRIORITY;
+
+ eventBus.on('propertiesPanel.isEntryVisible', priority, function (e) {
+ return self.isEntryVisible(e.entry, e.element);
+ });
+
+ eventBus.on('propertiesPanel.isPropertyEditable', priority, function (e) {
+ return self.isPropertyEditable(e.entry, e.propertyName, e.element);
+ });
+}
+
+PropertiesActivator.$inject = ['eventBus'];
+
+module.exports = PropertiesActivator;
+
+/**
+ * Should the given entry be visible for the specified element.
+ *
+ * @method PropertiesActivator#isEntryVisible
+ *
+ * @param {EntryDescriptor} entry
+ * @param {ModdleElement} element
+ *
+ * @returns {Boolean}
+ */
+PropertiesActivator.prototype.isEntryVisible = function (entry, element) {
+ return true;
+};
+
+/**
+ * Should the given property be editable for the specified element
+ *
+ * @method PropertiesActivator#isPropertyEditable
+ *
+ * @param {EntryDescriptor} entry
+ * @param {String} propertyName
+ * @param {ModdleElement} element
+ *
+ * @returns {Boolean}
+ */
+PropertiesActivator.prototype.isPropertyEditable = function (entry, propertyName, element) {
+ return true;
+};
+
+},{}],4:[function(require,module,exports){
+'use strict';
+
+var domify = require('min-dom/lib/domify'),
+ domQuery = require('min-dom/lib/query'),
+ domRemove = require('min-dom/lib/remove'),
+ domClasses = require('min-dom/lib/classes'),
+ domClosest = require('min-dom/lib/closest'),
+ domAttr = require('min-dom/lib/attr'),
+ domDelegate = require('min-dom/lib/delegate'),
+ domMatches = require('min-dom/lib/matches');
+
+var forEach = require('lodash/collection/forEach'),
+ filter = require('lodash/collection/filter'),
+ get = require('lodash/object/get'),
+ keys = require('lodash/object/keys'),
+ isEmpty = require('lodash/lang/isEmpty'),
+ isArray = require('lodash/lang/isArray'),
+ xor = require('lodash/array/xor'),
+ debounce = require('lodash/function/debounce');
+
+var updateSelection = require('selection-update');
+
+var scrollTabs = require('scroll-tabs');
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var HIDE_CLASS = 'bpp-hidden';
+var DEBOUNCE_DELAY = 300;
+
+function isToggle(node) {
+ return node.type === 'checkbox' || node.type === 'radio';
+}
+
+function isSelect(node) {
+ return node.type === 'select-one';
+}
+
+function isContentEditable(node) {
+ return domAttr(node, 'contenteditable');
+}
+
+function getPropertyPlaceholders(node) {
+ var selector = 'input[name], textarea[name], [data-value], [contenteditable]';
+ var placeholders = domQuery.all(selector, node);
+ if ((!placeholders || !placeholders.length) && domMatches(node, selector)) {
+ placeholders = [node];
+ }
+ return placeholders;
+}
+
+/**
+ * Return all active form controls.
+ * This excludes the invisible controls unless all is true
+ *
+ * @param {Element} node
+ * @param {Boolean} [all=false]
+ */
+function getFormControls(node, all) {
+ var controls = domQuery.all('input[name], textarea[name], select[name], [contenteditable]', node);
+
+ if (!controls || !controls.length) {
+ controls = domMatches(node, 'option') ? [node] : controls;
+ }
+
+ if (!all) {
+ controls = filter(controls, function (node) {
+ return !domClosest(node, '.' + HIDE_CLASS);
+ });
+ }
+
+ return controls;
+}
+
+function getFormControlValuesInScope(entryNode) {
+ var values = {};
+
+ var controlNodes = getFormControls(entryNode);
+
+ forEach(controlNodes, function (controlNode) {
+ var value = controlNode.value;
+
+ var name = domAttr(controlNode, 'name') || domAttr(controlNode, 'data-name');
+
+ // take toggle state into account for radio / checkboxes
+ if (isToggle(controlNode)) {
+ if (controlNode.checked) {
+ if (!domAttr(controlNode, 'value')) {
+ value = true;
+ } else {
+ value = controlNode.value;
+ }
+ } else {
+ value = null;
+ }
+ } else if (isContentEditable(controlNode)) {
+ value = controlNode.innerText;
+ }
+
+ if (value !== null) {
+ // return the actual value
+ // handle serialization in entry provider
+ // (ie. if empty string should be serialized or not)
+ values[name] = value;
+ }
+ });
+
+ return values;
+}
+
+/**
+ * Extract input values from entry node
+ *
+ * @param {DOMElement} entryNode
+ * @returns {Object}
+ */
+function getFormControlValues(entryNode) {
+
+ var values;
+
+ var listContainer = domQuery('[data-list-entry-container]', entryNode);
+ if (listContainer) {
+ values = [];
+ var listNodes = listContainer.children || [];
+ forEach(listNodes, function (listNode) {
+ values.push(getFormControlValuesInScope(listNode));
+ });
+ } else {
+ values = getFormControlValuesInScope(entryNode);
+ }
+
+ return values;
+}
+
+/**
+ * Return true if the given form extracted value equals
+ * to an old cached version.
+ *
+ * @param {Object} value
+ * @param {Object} oldValue
+ * @return {Boolean}
+ */
+function valueEqual(value, oldValue) {
+
+ if (value && !oldValue) {
+ return false;
+ }
+
+ var allKeys = keys(value).concat(keys(oldValue));
+
+ return allKeys.every(function (key) {
+ return value[key] === oldValue[key];
+ });
+}
+
+/**
+ * Return true if the given form extracted value(s)
+ * equal an old cached version.
+ *
+ * @param {Array|Object} values
+ * @param {Array|Object} oldValues
+ * @return {Boolean}
+ */
+function valuesEqual(values, oldValues) {
+
+ if (isArray(values)) {
+
+ if (values.length !== oldValues.length) {
+ return false;
+ }
+
+ return values.every(function (v, idx) {
+ return valueEqual(v, oldValues[idx]);
+ });
+ }
+
+ return valueEqual(values, oldValues);
+}
+
+/**
+ * Return a mapping of { id: entry } for all entries in the given groups in the given tabs.
+ *
+ * @param {Object} tabs
+ * @return {Object}
+ */
+function extractEntries(tabs) {
+ return indexBy(flattenDeep(map(flattenDeep(map(tabs, 'groups')), 'entries')), 'id');
+}
+
+/**
+ * Return a mapping of { id: group } for all groups in the given tabs.
+ *
+ * @param {Object} tabs
+ * @return {Object}
+ */
+function extractGroups(tabs) {
+ return indexBy(flattenDeep(map(tabs, 'groups')), 'id');
+}
+
+/**
+ * A properties panel implementation.
+ *
+ * To use it provide a `propertiesProvider` component that knows
+ * about which properties to display.
+ *
+ * Properties edit state / visibility can be intercepted
+ * via a custom {@link PropertiesActivator}.
+ *
+ * @class
+ * @constructor
+ *
+ * @param {Object} config
+ * @param {EventBus} eventBus
+ * @param {Modeling} modeling
+ * @param {PropertiesProvider} propertiesProvider
+ * @param {Canvas} canvas
+ * @param {CommandStack} commandStack
+ */
+function PropertiesPanel(config, eventBus, modeling, propertiesProvider, commandStack, canvas) {
+
+ this._eventBus = eventBus;
+ this._modeling = modeling;
+ this._commandStack = commandStack;
+ this._canvas = canvas;
+ this._propertiesProvider = propertiesProvider;
+
+ this._init(config);
+}
+
+PropertiesPanel.$inject = ['config.propertiesPanel', 'eventBus', 'modeling', 'propertiesProvider', 'commandStack', 'canvas'];
+
+module.exports = PropertiesPanel;
+
+PropertiesPanel.prototype._init = function (config) {
+
+ var eventBus = this._eventBus;
+
+ var self = this;
+
+ /**
+ * Select the root element once it is added to the canvas
+ */
+ eventBus.on('root.added', function (e) {
+ self.update(e.element);
+ });
+
+ eventBus.on('selection.changed', function (e) {
+ var newElement = e.newSelection[0];
+
+ self.update(newElement);
+ });
+
+ // add / update tab-bar scrolling
+ eventBus.on(['propertiesPanel.changed', 'propertiesPanel.resized'], function (event) {
+
+ var tabBarNode = domQuery('.bpp-properties-tab-bar', self._container);
+
+ if (!tabBarNode) {
+ return;
+ }
+
+ var scroller = scrollTabs.get(tabBarNode);
+
+ if (!scroller) {
+
+ // we did not initialize yet, do that
+ // now and make sure we select the active
+ // tab on scroll update
+ scroller = scrollTabs(tabBarNode, {
+ selectors: {
+ tabsContainer: '.bpp-properties-tabs-links',
+ tab: '.bpp-properties-tabs-links li',
+ ignore: '.bpp-hidden',
+ active: '.bpp-active'
+ }
+ });
+
+ scroller.on('scroll', function (newActiveNode, oldActiveNode, direction) {
+
+ var linkNode = domQuery('[data-tab-target]', newActiveNode);
+
+ var tabId = domAttr(linkNode, 'data-tab-target');
+
+ self.activateTab(tabId);
+ });
+ }
+
+ // react on tab changes and or tabContainer resize
+ // and make sure the active tab is shown completely
+ scroller.update();
+ });
+
+ eventBus.on('elements.changed', function (e) {
+
+ var current = self._current;
+ var element = current && current.element;
+
+ if (element) {
+ if (e.elements.indexOf(element) !== -1) {
+ self.update(element);
+ }
+ }
+ });
+
+ eventBus.on('elementTemplates.changed', function () {
+ var current = self._current;
+ var element = current && current.element;
+
+ if (element) {
+ self.update(element);
+ }
+ });
+
+ eventBus.on('diagram.destroy', function () {
+ self.detach();
+ });
+
+ this._container = domify('
');
+
+ this._bindListeners(this._container);
+
+ if (config && config.parent) {
+ this.attachTo(config.parent);
+ }
+};
+
+PropertiesPanel.prototype.attachTo = function (parentNode) {
+
+ if (!parentNode) {
+ throw new Error('parentNode required');
+ }
+
+ // ensure we detach from the
+ // previous, old parent
+ this.detach();
+
+ // unwrap jQuery if provided
+ if (parentNode.get && parentNode.constructor.prototype.jquery) {
+ parentNode = parentNode.get(0);
+ }
+
+ if (typeof parentNode === 'string') {
+ parentNode = domQuery(parentNode);
+ }
+
+ var container = this._container;
+
+ parentNode.appendChild(container);
+
+ this._emit('attach');
+};
+
+PropertiesPanel.prototype.detach = function () {
+
+ var container = this._container,
+ parentNode = container.parentNode;
+
+ if (!parentNode) {
+ return;
+ }
+
+ this._emit('detach');
+
+ parentNode.removeChild(container);
+};
+
+/**
+ * Select the given tab within the properties panel.
+ *
+ * @param {Object|String} tab
+ */
+PropertiesPanel.prototype.activateTab = function (tab) {
+
+ var tabId = typeof tab === 'string' ? tab : tab.id;
+
+ var current = this._current;
+
+ var panelNode = current.panel;
+
+ var allTabNodes = domQuery.all('.bpp-properties-tab', panelNode),
+ allTabLinkNodes = domQuery.all('.bpp-properties-tab-link', panelNode);
+
+ forEach(allTabNodes, function (tabNode) {
+
+ var currentTabId = domAttr(tabNode, 'data-tab');
+
+ domClasses(tabNode).toggle('bpp-active', tabId === currentTabId);
+ });
+
+ forEach(allTabLinkNodes, function (tabLinkNode) {
+
+ var tabLink = domQuery('[data-tab-target]', tabLinkNode),
+ currentTabId = domAttr(tabLink, 'data-tab-target');
+
+ domClasses(tabLinkNode).toggle('bpp-active', tabId === currentTabId);
+ });
+};
+
+/**
+ * Update the DOM representation of the properties panel
+ */
+PropertiesPanel.prototype.update = function (element) {
+ var current = this._current;
+
+ // no actual selection change
+ var needsCreate = true;
+
+ if (typeof element === 'undefined') {
+
+ // use RootElement of BPMN diagram to generate properties panel if no element is selected
+ element = this._canvas.getRootElement();
+ }
+
+ var newTabs = this._propertiesProvider.getTabs(element);
+
+ if (current && current.element === element) {
+ // see if we can reuse the existing panel
+
+ needsCreate = this._entriesChanged(current, newTabs);
+ }
+
+ if (needsCreate) {
+
+ if (current) {
+
+ // get active tab from the existing panel before remove it
+ var activeTabNode = domQuery('.bpp-properties-tab.bpp-active', current.panel);
+
+ var activeTabId;
+ if (activeTabNode) {
+ activeTabId = domAttr(activeTabNode, 'data-tab');
+ }
+
+ // remove old panel
+ domRemove(current.panel);
+ }
+
+ this._current = this._create(element, newTabs);
+
+ // activate the saved active tab from the remove panel or the first tab
+ activeTabId ? this.activateTab(activeTabId) : this.activateTab(this._current.tabs[0]);
+ }
+
+ if (this._current) {
+ // make sure correct tab contents are visible
+ this._updateActivation(this._current);
+ }
+
+ this._emit('changed');
+};
+
+/**
+ * Returns true if one of two groups has different entries than the other.
+ *
+ * @param {Object} current
+ * @param {Object} newTabs
+ * @return {Booelan}
+ */
+PropertiesPanel.prototype._entriesChanged = function (current, newTabs) {
+
+ var oldEntryIds = keys(current.entries),
+ newEntryIds = keys(extractEntries(newTabs));
+
+ return !isEmpty(xor(oldEntryIds, newEntryIds));
+};
+
+PropertiesPanel.prototype._emit = function (event) {
+ this._eventBus.fire('propertiesPanel.' + event, { panel: this, current: this._current });
+};
+
+PropertiesPanel.prototype._bindListeners = function (container) {
+
+ var self = this;
+
+ // handles a change for a given event
+ var handleChange = function handleChange(event) {
+
+ // see if we handle a change inside a [data-entry] element.
+ // if not, drop out
+ var node = domClosest(event.delegateTarget, '[data-entry]'),
+ entryId,
+ entry;
+
+ // change from outside a [data-entry] element, simply ignore
+ if (!node) {
+ return;
+ }
+
+ entryId = domAttr(node, 'data-entry');
+ entry = self.getEntry(entryId);
+
+ var values = getFormControlValues(node);
+
+ if (event.type === 'change') {
+
+ // - if the "data-on-change" attribute is present and a value is changed,
+ // then the associated action is performed.
+ // - if the associated action returns "true" then an update to the business
+ // object is done
+ // - if it does not return "true", then only the DOM content is updated
+ var onChangeAction = event.delegateTarget.getAttribute('data-on-change');
+
+ if (onChangeAction) {
+ var isEntryDirty = self.executeAction(entry, node, onChangeAction, event);
+
+ if (!isEntryDirty) {
+ return self.update(self._current.element);
+ }
+ }
+ }
+ self.applyChanges(entry, values, node);
+ self.updateState(entry, node);
+ };
+
+ // debounce update only elements that are target of key events,
+ // i.e. INPUT and TEXTAREA. SELECTs will trigger an immediate update anyway.
+ domDelegate.bind(container, 'input, textarea, [contenteditable]', 'input', debounce(handleChange, DEBOUNCE_DELAY));
+ domDelegate.bind(container, 'input, textarea, select, [contenteditable]', 'change', handleChange);
+
+ domDelegate.bind(container, '[data-action]', 'click', function onClick(event) {
+
+ // triggers on all inputs
+ var inputNode = event.delegateTarget;
+ var entryNode = domClosest(inputNode, '[data-entry]');
+
+ var actionId = domAttr(inputNode, 'data-action'),
+ entryId = domAttr(entryNode, 'data-entry');
+
+ var entry = self.getEntry(entryId);
+
+ var isEntryDirty = self.executeAction(entry, entryNode, actionId, event);
+
+ if (isEntryDirty) {
+ var values = getFormControlValues(entryNode);
+
+ self.applyChanges(entry, values, entryNode);
+ }
+
+ self.updateState(entry, entryNode);
+ });
+
+ function handleInput(event, element) {
+ // triggers on all inputs
+ var inputNode = event.delegateTarget;
+
+ var entryNode = domClosest(inputNode, '[data-entry]');
+
+ // only work on data entries
+ if (!entryNode) {
+ return;
+ }
+
+ var eventHandlerId = domAttr(inputNode, 'data-blur'),
+ entryId = domAttr(entryNode, 'data-entry');
+
+ var entry = self.getEntry(entryId);
+
+ var isEntryDirty = self.executeAction(entry, entryNode, eventHandlerId, event);
+
+ if (isEntryDirty) {
+ var values = getFormControlValues(entryNode);
+
+ self.applyChanges(entry, values, entryNode);
+ }
+
+ self.updateState(entry, entryNode);
+ }
+
+ domDelegate.bind(container, '[data-blur]', 'blur', handleInput, true);
+
+ // make tab links interactive
+ domDelegate.bind(container, '.bpp-properties-tabs-links [data-tab-target]', 'click', function (event) {
+ event.preventDefault();
+
+ var delegateTarget = event.delegateTarget;
+
+ var tabId = domAttr(delegateTarget, 'data-tab-target');
+
+ // activate tab on link click
+ self.activateTab(tabId);
+ });
+};
+
+PropertiesPanel.prototype.updateState = function (entry, entryNode) {
+ this.updateShow(entry, entryNode);
+ this.updateDisable(entry, entryNode);
+};
+
+/**
+ * Update the visibility of the entry node in the DOM
+ */
+PropertiesPanel.prototype.updateShow = function (entry, node) {
+
+ var current = this._current;
+
+ if (!current) {
+ return;
+ }
+
+ var showNodes = domQuery.all('[data-show]', node) || [];
+
+ forEach(showNodes, function (showNode) {
+
+ var expr = domAttr(showNode, 'data-show');
+ var fn = get(entry, expr);
+ if (fn) {
+ var scope = domClosest(showNode, '[data-scope]') || node;
+ var shouldShow = fn(current.element, node, showNode, scope) || false;
+ if (shouldShow) {
+ domClasses(showNode).remove(HIDE_CLASS);
+ } else {
+ domClasses(showNode).add(HIDE_CLASS);
+ }
+ }
+ });
+};
+
+/**
+ * Evaluates a given function. If it returns true, then the
+ * node is marked as "disabled".
+ */
+PropertiesPanel.prototype.updateDisable = function (entry, node) {
+ var current = this._current;
+
+ if (!current) {
+ return;
+ }
+
+ var nodes = domQuery.all('[data-disable]', node) || [];
+
+ forEach(nodes, function (currentNode) {
+ var expr = domAttr(currentNode, 'data-disable');
+ var fn = get(entry, expr);
+ if (fn) {
+ var scope = domClosest(currentNode, '[data-scope]') || node;
+ var shouldDisable = fn(current.element, node, currentNode, scope) || false;
+ domAttr(currentNode, 'disabled', shouldDisable ? '' : null);
+ }
+ });
+};
+
+PropertiesPanel.prototype.executeAction = function (entry, entryNode, actionId, event) {
+ var current = this._current;
+
+ if (!current) {
+ return;
+ }
+
+ var fn = get(entry, actionId);
+ if (fn) {
+ var scopeNode = domClosest(event.target, '[data-scope]') || entryNode;
+ return fn.apply(entry, [current.element, entryNode, event, scopeNode]);
+ }
+};
+
+/**
+ * Apply changes to the business object by executing a command
+ */
+PropertiesPanel.prototype.applyChanges = function (entry, values, containerElement) {
+
+ var element = this._current.element;
+
+ // ensure we only update the model if we got dirty changes
+ if (valuesEqual(values, entry.oldValues)) {
+ return;
+ }
+
+ var command = entry.set(element, values, containerElement);
+
+ var commandToExecute;
+
+ if (isArray(command)) {
+ if (command.length) {
+ commandToExecute = {
+ cmd: 'properties-panel.multi-command-executor',
+ context: flattenDeep(command)
+ };
+ }
+ } else {
+ commandToExecute = command;
+ }
+
+ if (commandToExecute) {
+ this._commandStack.execute(commandToExecute.cmd, commandToExecute.context || { element: element });
+ } else {
+ this.update(element);
+ }
+};
+
+/**
+ * apply validation errors in the DOM and show or remove an error message near the entry node.
+ */
+PropertiesPanel.prototype.applyValidationErrors = function (validationErrors, entryNode) {
+
+ var valid = true;
+
+ var controlNodes = getFormControls(entryNode, true);
+
+ forEach(controlNodes, function (controlNode) {
+
+ var name = domAttr(controlNode, 'name') || domAttr(controlNode, 'data-name');
+
+ var error = validationErrors && validationErrors[name];
+
+ var errorMessageNode = domQuery('.bpp-error-message', controlNode.parentNode);
+
+ if (error) {
+ valid = false;
+
+ if (!errorMessageNode) {
+ errorMessageNode = domify('
');
+
+ domClasses(errorMessageNode).add('bpp-error-message');
+
+ // insert errorMessageNode after controlNode
+ controlNode.parentNode.insertBefore(errorMessageNode, controlNode.nextSibling);
+ }
+
+ errorMessageNode.innerHTML = error;
+
+ domClasses(controlNode).add('invalid');
+ } else {
+ domClasses(controlNode).remove('invalid');
+
+ if (errorMessageNode) {
+ controlNode.parentNode.removeChild(errorMessageNode);
+ }
+ }
+ });
+
+ return valid;
+};
+
+/**
+ * Check if the entry contains valid input
+ */
+PropertiesPanel.prototype.validate = function (entry, values, entryNode) {
+ var self = this;
+
+ var current = this._current;
+
+ var valid = true;
+
+ entryNode = entryNode || domQuery('[data-entry="' + entry.id + '"]', current.panel);
+
+ if (values instanceof Array) {
+ var listContainer = domQuery('[data-list-entry-container]', entryNode),
+ listEntryNodes = listContainer.children || [];
+
+ // create new elements
+ for (var i = 0; i < values.length; i++) {
+ var listValue = values[i];
+
+ if (entry.validateListItem) {
+
+ var validationErrors = entry.validateListItem(current.element, listValue, entryNode, i),
+ listEntryNode = listEntryNodes[i];
+
+ valid = self.applyValidationErrors(validationErrors, listEntryNode) && valid;
+ }
+ }
+ } else {
+ if (entry.validate) {
+ this.validationErrors = entry.validate(current.element, values, entryNode);
+
+ valid = self.applyValidationErrors(this.validationErrors, entryNode) && valid;
+ }
+ }
+
+ return valid;
+};
+
+PropertiesPanel.prototype.getEntry = function (id) {
+ return this._current && this._current.entries[id];
+};
+
+var flattenDeep = require('lodash/array/flattenDeep'),
+ indexBy = require('lodash/collection/indexBy'),
+ map = require('lodash/collection/map');
+
+PropertiesPanel.prototype._create = function (element, tabs) {
+
+ if (!element) {
+ return null;
+ }
+
+ var containerNode = this._container;
+
+ var panelNode = this._createPanel(element, tabs);
+
+ containerNode.appendChild(panelNode);
+
+ var entries = extractEntries(tabs);
+ var groups = extractGroups(tabs);
+
+ return {
+ tabs: tabs,
+ groups: groups,
+ entries: entries,
+ element: element,
+ panel: panelNode
+ };
+};
+
+/**
+ * Update variable parts of the entry node on element changes.
+ *
+ * @param {djs.model.Base} element
+ * @param {EntryDescriptor} entry
+ * @param {Object} values
+ * @param {HTMLElement} entryNode
+ * @param {Number} idx
+ */
+PropertiesPanel.prototype._bindTemplate = function (element, entry, values, entryNode, idx) {
+
+ var eventBus = this._eventBus;
+
+ function isPropertyEditable(entry, propertyName) {
+ return eventBus.fire('propertiesPanel.isPropertyEditable', {
+ entry: entry,
+ propertyName: propertyName,
+ element: element
+ });
+ }
+
+ var inputNodes = getPropertyPlaceholders(entryNode);
+
+ forEach(inputNodes, function (node) {
+
+ var name, newValue, editable;
+
+ // we deal with an input element
+ if ('value' in node || isContentEditable(node) === 'true') {
+ name = domAttr(node, 'name') || domAttr(node, 'data-name');
+ newValue = values[name];
+
+ editable = isPropertyEditable(entry, name);
+ if (editable && entry.editable) {
+ editable = entry.editable(element, entryNode, node, name, newValue, idx);
+ }
+
+ domAttr(node, 'readonly', editable ? null : '');
+ domAttr(node, 'disabled', editable ? null : '');
+
+ // take full control over setting the value
+ // and possibly updating the input in entry#setControlValue
+ if (entry.setControlValue) {
+ entry.setControlValue(element, entryNode, node, name, newValue, idx);
+ } else if (isToggle(node)) {
+ setToggleValue(node, newValue);
+ } else if (isSelect(node)) {
+ setSelectValue(node, newValue);
+ } else {
+ setInputValue(node, newValue);
+ }
+ }
+
+ // we deal with some non-editable html element
+ else {
+ name = domAttr(node, 'data-value');
+ newValue = values[name];
+ if (entry.setControlValue) {
+ entry.setControlValue(element, entryNode, node, name, newValue, idx);
+ } else {
+ setTextValue(node, newValue);
+ }
+ }
+ });
+};
+
+// TODO(nikku): WTF freaking name? Change / clarify.
+PropertiesPanel.prototype._updateActivation = function (current) {
+ var self = this;
+
+ var eventBus = this._eventBus;
+
+ var element = current.element;
+
+ function isEntryVisible(entry) {
+ return eventBus.fire('propertiesPanel.isEntryVisible', {
+ entry: entry,
+ element: element
+ });
+ }
+
+ function isGroupVisible(group, element, groupNode) {
+ if (typeof group.enabled === 'function') {
+ return group.enabled(element, groupNode);
+ } else {
+ return true;
+ }
+ }
+
+ function isTabVisible(tab, element) {
+ if (typeof tab.enabled === 'function') {
+ return tab.enabled(element);
+ } else {
+ return true;
+ }
+ }
+
+ function toggleVisible(node, visible) {
+ domClasses(node).toggle(HIDE_CLASS, !visible);
+ }
+
+ // check whether the active tab is visible
+ // if not: set the first tab as active tab
+ function checkActiveTabVisibility(node, visible) {
+ var isActive = domClasses(node).has('bpp-active');
+ if (!visible && isActive) {
+ self.activateTab(current.tabs[0]);
+ }
+ }
+
+ function updateLabel(element, selector, text) {
+ var labelNode = domQuery(selector, element);
+
+ if (!labelNode) {
+ return;
+ }
+
+ labelNode.textContent = text;
+ }
+
+ var panelNode = current.panel;
+
+ forEach(current.tabs, function (tab) {
+
+ var tabNode = domQuery('[data-tab=' + tab.id + ']', panelNode);
+ var tabLinkNode = domQuery('[data-tab-target=' + tab.id + ']', panelNode).parentNode;
+
+ var tabVisible = false;
+
+ forEach(tab.groups, function (group) {
+
+ var groupVisible = false;
+
+ var groupNode = domQuery('[data-group=' + group.id + ']', tabNode);
+
+ forEach(group.entries, function (entry) {
+
+ var entryNode = domQuery('[data-entry="' + entry.id + '"]', groupNode);
+
+ var entryVisible = isEntryVisible(entry);
+
+ groupVisible = groupVisible || entryVisible;
+
+ toggleVisible(entryNode, entryVisible);
+
+ var values = 'get' in entry ? entry.get(element, entryNode) : {};
+
+ if (values instanceof Array) {
+ var listEntryContainer = domQuery('[data-list-entry-container]', entryNode);
+ var existingElements = listEntryContainer.children || [];
+
+ for (var i = 0; i < values.length; i++) {
+ var listValue = values[i];
+ var listItemNode = existingElements[i];
+ if (!listItemNode) {
+ listItemNode = domify(entry.createListEntryTemplate(listValue, i, listEntryContainer));
+ listEntryContainer.appendChild(listItemNode);
+ }
+ domAttr(listItemNode, 'data-index', i);
+
+ self._bindTemplate(element, entry, listValue, listItemNode, i);
+ }
+
+ var entriesToRemove = existingElements.length - values.length;
+
+ for (var j = 0; j < entriesToRemove; j++) {
+ // remove orphaned element
+ listEntryContainer.removeChild(listEntryContainer.lastChild);
+ }
+ } else {
+ self._bindTemplate(element, entry, values, entryNode);
+ }
+
+ // update conditionally visible elements
+ self.updateState(entry, entryNode);
+ self.validate(entry, values, entryNode);
+
+ // remember initial state for later dirty checking
+ entry.oldValues = getFormControlValues(entryNode);
+ });
+
+ if (typeof group.label === 'function') {
+ updateLabel(groupNode, '.group-label', group.label(element, groupNode));
+ }
+
+ groupVisible = groupVisible && isGroupVisible(group, element, groupNode);
+
+ tabVisible = tabVisible || groupVisible;
+
+ toggleVisible(groupNode, groupVisible);
+ });
+
+ tabVisible = tabVisible && isTabVisible(tab, element);
+
+ toggleVisible(tabNode, tabVisible);
+ toggleVisible(tabLinkNode, tabVisible);
+
+ checkActiveTabVisibility(tabNode, tabVisible);
+ });
+
+ // inject elements id into header
+ updateLabel(panelNode, '[data-label-id]', getBusinessObject(element).id || '');
+};
+
+PropertiesPanel.prototype._createPanel = function (element, tabs) {
+ var self = this;
+
+ var panelNode = domify('
'),
+ headerNode = domify(''),
+ tabBarNode = domify('
'),
+ tabLinksNode = domify(''),
+ tabContainerNode = domify('
');
+
+ panelNode.appendChild(headerNode);
+
+ forEach(tabs, function (tab, tabIndex) {
+
+ if (!tab.id) {
+ throw new Error('tab must have an id');
+ }
+
+ var tabNode = domify('
'),
+ tabLinkNode = domify('' + '' + tab.label + ' ' + ' ');
+
+ var groups = tab.groups;
+
+ forEach(groups, function (group) {
+
+ if (!group.id) {
+ throw new Error('group must have an id');
+ }
+
+ var groupNode = domify('' + ' ' + '' + group.label + ' ' + '
');
+
+ // TODO(nre): use event delegation to handle that...
+ groupNode.querySelector('.group-toggle').addEventListener('click', function (evt) {
+ domClasses(groupNode).toggle('group-closed');
+ evt.preventDefault();
+ evt.stopPropagation();
+ });
+ groupNode.addEventListener('click', function (evt) {
+ if (!evt.defaultPrevented && domClasses(groupNode).has('group-closed')) {
+ domClasses(groupNode).remove('group-closed');
+ }
+ });
+
+ forEach(group.entries, function (entry) {
+
+ if (!entry.id) {
+ throw new Error('entry must have an id');
+ }
+
+ var html = entry.html;
+
+ if (typeof html === 'string') {
+ html = domify(html);
+ }
+
+ // unwrap jquery
+ if (html.get && html.constructor.prototype.jquery) {
+ html = html.get(0);
+ }
+
+ var entryNode = domify('
');
+
+ forEach(entry.cssClasses || [], function (cssClass) {
+ domClasses(entryNode).add(cssClass);
+ });
+
+ entryNode.appendChild(html);
+
+ groupNode.appendChild(entryNode);
+
+ // update conditionally visible elements
+ self.updateState(entry, entryNode);
+ });
+
+ tabNode.appendChild(groupNode);
+ });
+
+ tabLinksNode.appendChild(tabLinkNode);
+ tabContainerNode.appendChild(tabNode);
+ });
+
+ tabBarNode.appendChild(tabLinksNode);
+
+ panelNode.appendChild(tabBarNode);
+ panelNode.appendChild(tabContainerNode);
+
+ return panelNode;
+};
+
+function setInputValue(node, value) {
+
+ var contentEditable = isContentEditable(node);
+
+ var oldValue = contentEditable ? node.innerText : node.value;
+
+ var selection;
+
+ // prevents input fields from having the value 'undefined'
+ if (value === undefined) {
+ value = '';
+ }
+
+ if (oldValue === value) {
+ return;
+ }
+
+ // update selection on undo/redo
+ if (document.activeElement === node) {
+ selection = updateSelection(getSelection(node), oldValue, value);
+ }
+
+ if (contentEditable) {
+ node.innerText = value;
+ } else {
+ node.value = value;
+ }
+
+ if (selection) {
+ setSelection(node, selection);
+ }
+}
+
+function setSelectValue(node, value) {
+ if (value !== undefined) {
+ node.value = value;
+ }
+}
+
+function setToggleValue(node, value) {
+ var nodeValue = node.value;
+
+ node.checked = value === nodeValue || !domAttr(node, 'value') && value;
+}
+
+function setTextValue(node, value) {
+ node.textContent = value;
+}
+
+function getSelection(node) {
+
+ return isContentEditable(node) ? getContentEditableSelection(node) : {
+ start: node.selectionStart,
+ end: node.selectionEnd
+ };
+}
+
+function getContentEditableSelection(node) {
+
+ var selection = window.getSelection();
+
+ var focusNode = selection.focusNode,
+ focusOffset = selection.focusOffset,
+ anchorOffset = selection.anchorOffset;
+
+ if (!focusNode) {
+ throw new Error('not selected');
+ }
+
+ // verify we have selection on the current element
+ if (!node.contains(focusNode)) {
+ throw new Error('not selected');
+ }
+
+ return {
+ start: Math.min(focusOffset, anchorOffset),
+ end: Math.max(focusOffset, anchorOffset)
+ };
+}
+
+function setSelection(node, selection) {
+
+ if (isContentEditable(node)) {
+ setContentEditableSelection(node, selection);
+ } else {
+ node.selectionStart = selection.start;
+ node.selectionEnd = selection.end;
+ }
+}
+
+function setContentEditableSelection(node, selection) {
+
+ var focusNode, domRange, domSelection;
+
+ focusNode = node.firstChild || node, domRange = document.createRange();
+ domRange.setStart(focusNode, selection.start);
+ domRange.setEnd(focusNode, selection.end);
+
+ domSelection = window.getSelection();
+ domSelection.removeAllRanges();
+ domSelection.addRange(domRange);
+}
+
+},{"bpmn-js/lib/util/ModelUtil":216,"lodash/array/flattenDeep":417,"lodash/array/xor":419,"lodash/collection/filter":420,"lodash/collection/forEach":422,"lodash/collection/indexBy":423,"lodash/collection/map":424,"lodash/function/debounce":426,"lodash/lang/isArray":489,"lodash/lang/isEmpty":490,"lodash/object/get":497,"lodash/object/keys":498,"min-dom/lib/attr":105,"min-dom/lib/classes":106,"min-dom/lib/closest":108,"min-dom/lib/delegate":109,"min-dom/lib/domify":110,"min-dom/lib/matches":111,"min-dom/lib/query":112,"min-dom/lib/remove":113,"scroll-tabs":525,"selection-update":533}],5:[function(require,module,exports){
+'use strict';
+
+var domQuery = require('min-dom/lib/query'),
+ domClear = require('min-dom/lib/clear'),
+ is = require('bpmn-js/lib/util/ModelUtil').is,
+ forEach = require('lodash/collection/forEach'),
+ domify = require('min-dom/lib/domify'),
+ Ids = require('ids');
+
+var SPACE_REGEX = /\s/;
+
+// for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar
+var QNAME_REGEX = /^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i;
+
+// for ID validation as per BPMN Schema (QName - Namespace)
+var ID_REGEX = /^[a-z_][\w-.]*$/i;
+
+var PLACEHOLDER_REGEX = /\$\{([^\}]*)\}/g;
+
+function selectedOption(selectBox) {
+ if (selectBox.selectedIndex >= 0) {
+ return selectBox.options[selectBox.selectedIndex].value;
+ }
+}
+
+module.exports.selectedOption = selectedOption;
+
+function selectedType(elementSyntax, inputNode) {
+ var typeSelect = domQuery(elementSyntax, inputNode);
+ return selectedOption(typeSelect);
+}
+
+module.exports.selectedType = selectedType;
+
+/**
+ * Retrieve the root element the document this
+ * business object is contained in.
+ *
+ * @return {ModdleElement}
+ */
+function getRoot(businessObject) {
+ var parent = businessObject;
+ while (parent.$parent) {
+ parent = parent.$parent;
+ }
+ return parent;
+}
+
+module.exports.getRoot = getRoot;
+
+/**
+ * filters all elements in the list which have a given type.
+ * removes a new list
+ */
+function filterElementsByType(objectList, type) {
+ var list = objectList || [];
+ var result = [];
+ forEach(list, function (obj) {
+ if (is(obj, type)) {
+ result.push(obj);
+ }
+ });
+ return result;
+}
+
+module.exports.filterElementsByType = filterElementsByType;
+
+function findRootElementsByType(businessObject, referencedType) {
+ var root = getRoot(businessObject);
+
+ return filterElementsByType(root.rootElements, referencedType);
+}
+
+module.exports.findRootElementsByType = findRootElementsByType;
+
+function removeAllChildren(domElement) {
+ while (domElement.firstChild) {
+ domElement.removeChild(domElement.firstChild);
+ }
+}
+
+module.exports.removeAllChildren = removeAllChildren;
+
+/**
+ * adds an empty option to the list
+ */
+function addEmptyParameter(list) {
+ return list.push({ 'label': '', 'value': '', 'name': '' });
+}
+
+module.exports.addEmptyParameter = addEmptyParameter;
+
+/**
+ * returns a list with all root elements for the given parameter 'referencedType'
+ */
+function refreshOptionsModel(businessObject, referencedType) {
+ var model = [];
+ var referableObjects = findRootElementsByType(businessObject, referencedType);
+ forEach(referableObjects, function (obj) {
+ model.push({
+ label: (obj.name || '') + ' (id=' + obj.id + ')',
+ value: obj.id,
+ name: obj.name
+ });
+ });
+ return model;
+}
+
+module.exports.refreshOptionsModel = refreshOptionsModel;
+
+/**
+ * fills the drop down with options
+ */
+function updateOptionsDropDown(domSelector, businessObject, referencedType, entryNode) {
+ var options = refreshOptionsModel(businessObject, referencedType);
+ addEmptyParameter(options);
+ var selectBox = domQuery(domSelector, entryNode);
+ domClear(selectBox);
+
+ forEach(options, function (option) {
+ var optionEntry = domify('' + option.label + ' ');
+ selectBox.appendChild(optionEntry);
+ });
+ return options;
+}
+
+module.exports.updateOptionsDropDown = updateOptionsDropDown;
+
+/**
+ * checks whether the id value is valid
+ *
+ * @param {ModdleElement} bo
+ * @param {String} idValue
+ *
+ * @return {String} error message
+ */
+function isIdValid(bo, idValue) {
+ var assigned = bo.$model.ids.assigned(idValue);
+
+ var idExists = assigned && assigned !== bo;
+
+ if (!idValue || idExists) {
+ return 'Element must have an unique id.';
+ }
+
+ return validateId(idValue);
+}
+
+module.exports.isIdValid = isIdValid;
+
+function validateId(idValue) {
+
+ idValue = stripPlaceholders(idValue);
+
+ if (containsSpace(idValue)) {
+ return 'Id must not contain spaces.';
+ }
+
+ if (!ID_REGEX.test(idValue)) {
+
+ if (QNAME_REGEX.test(idValue)) {
+ return 'Id must not contain prefix.';
+ }
+
+ return 'Id must be a valid QName.';
+ }
+}
+
+module.exports.validateId = validateId;
+
+function containsSpace(value) {
+ return SPACE_REGEX.test(value);
+}
+
+module.exports.containsSpace = containsSpace;
+
+function stripPlaceholders(idValue) {
+
+ // replace expression e.g. ${VERSION_TAG}
+ // use only the content between ${}
+ // for the REGEX check
+ return idValue.replace(PLACEHOLDER_REGEX, '$1');
+}
+
+/**
+ * generate a semantic id with given prefix
+ */
+function nextId(prefix) {
+ var ids = new Ids([32, 32, 1]);
+
+ return ids.nextPrefixed(prefix);
+}
+
+module.exports.nextId = nextId;
+
+function triggerClickEvent(element) {
+ var evt;
+ var eventType = 'click';
+
+ if (document.createEvent) {
+ try {
+ // Chrome, Safari, Firefox
+ evt = new MouseEvent(eventType, { view: window, bubbles: true, cancelable: true });
+ } catch (e) {
+ // IE 11, PhantomJS (wat!)
+ evt = document.createEvent('MouseEvent');
+
+ evt.initEvent(eventType, true, true);
+ }
+ return element.dispatchEvent(evt);
+ } else {
+ // Welcome IE
+ evt = document.createEventObject();
+
+ return element.fireEvent('on' + eventType, evt);
+ }
+}
+
+module.exports.triggerClickEvent = triggerClickEvent;
+
+},{"bpmn-js/lib/util/ModelUtil":216,"ids":414,"lodash/collection/forEach":422,"min-dom/lib/clear":107,"min-dom/lib/domify":110,"min-dom/lib/query":112}],6:[function(require,module,exports){
+'use strict';
+
+var elementHelper = require('../helper/ElementHelper');
+
+/**
+ * A handler capable of creating a new element under a provided parent
+ * and updating / creating a reference to it in one atomic action.
+ *
+ * @class
+ * @constructor
+ */
+function CreateAndReferenceElementHandler(elementRegistry, bpmnFactory) {
+ this._elementRegistry = elementRegistry;
+ this._bpmnFactory = bpmnFactory;
+}
+
+CreateAndReferenceElementHandler.$inject = ['elementRegistry', 'bpmnFactory'];
+
+module.exports = CreateAndReferenceElementHandler;
+
+function ensureNotNull(prop, name) {
+ if (!prop) {
+ throw new Error(name + ' required');
+ }
+ return prop;
+}
+
+////// api /////////////////////////////////////////////
+
+/**
+ * Creates a new element under a provided parent and updates / creates a reference to it in
+ * one atomic action.
+ *
+ * @method CreateAndReferenceElementHandler#execute
+ *
+ * @param {Object} context
+ * @param {djs.model.Base} context.element which is the context for the reference
+ * @param {moddle.referencingObject} context.referencingObject the object which creates the reference
+ * @param {String} context.referenceProperty the property of the referencingObject which makes the reference
+ * @param {moddle.newObject} context.newObject the new object to add
+ * @param {moddle.newObjectContainer} context.newObjectContainer the container for the new object
+ *
+ * @returns {Array} the updated element
+ */
+CreateAndReferenceElementHandler.prototype.execute = function (context) {
+
+ var referencingObject = ensureNotNull(context.referencingObject, 'referencingObject'),
+ referenceProperty = ensureNotNull(context.referenceProperty, 'referenceProperty'),
+ newObject = ensureNotNull(context.newObject, 'newObject'),
+ newObjectContainer = ensureNotNull(context.newObjectContainer, 'newObjectContainer'),
+ newObjectParent = ensureNotNull(context.newObjectParent, 'newObjectParent'),
+ changed = [context.element]; // this will not change any diagram-js elements
+
+ // create new object
+ var referencedObject = elementHelper.createElement(newObject.type, newObject.properties, newObjectParent, this._bpmnFactory);
+ context.referencedObject = referencedObject;
+
+ // add to containing list
+ newObjectContainer.push(referencedObject);
+
+ // adjust reference attribute
+ context.previousReference = referencingObject[referenceProperty];
+ referencingObject[referenceProperty] = referencedObject;
+
+ context.changed = changed;
+
+ // indicate changed on objects affected by the update
+ return changed;
+};
+
+/**
+ * Reverts the update
+ *
+ * @method CreateAndReferenceElementHandler#revert
+ *
+ * @param {Object} context
+ *
+ * @returns {djs.mode.Base} the updated element
+ */
+CreateAndReferenceElementHandler.prototype.revert = function (context) {
+
+ var referencingObject = context.referencingObject,
+ referenceProperty = context.referenceProperty,
+ previousReference = context.previousReference,
+ referencedObject = context.referencedObject,
+ newObjectContainer = context.newObjectContainer;
+
+ // reset reference
+ referencingObject.set(referenceProperty, previousReference);
+
+ // remove new element
+ newObjectContainer.splice(newObjectContainer.indexOf(referencedObject), 1);
+
+ return context.changed;
+};
+
+},{"../helper/ElementHelper":25}],7:[function(require,module,exports){
+'use strict';
+
+var forEach = require('lodash/collection/forEach');
+
+var elementHelper = require('../helper/ElementHelper');
+
+/**
+ * A handler that implements a BPMN 2.0 property update
+ * for business objects which are not represented in the
+ * diagram.
+ *
+ * This is useful in the context of the properties panel in
+ * order to update child elements of elements visible in
+ * the diagram.
+ *
+ * Example: perform an update of a specific event definition
+ * of an intermediate event.
+ *
+ * @class
+ * @constructor
+ */
+function CreateBusinessObjectListHandler(elementRegistry, bpmnFactory) {
+ this._elementRegistry = elementRegistry;
+ this._bpmnFactory = bpmnFactory;
+}
+
+CreateBusinessObjectListHandler.$inject = ['elementRegistry', 'bpmnFactory'];
+
+module.exports = CreateBusinessObjectListHandler;
+
+function ensureNotNull(prop, name) {
+ if (!prop) {
+ throw new Error(name + ' required');
+ }
+ return prop;
+}
+function ensureList(prop, name) {
+ if (!prop || Object.prototype.toString.call(prop) !== '[object Array]') {
+ throw new Error(name + ' needs to be a list');
+ }
+ return prop;
+}
+
+////// api /////////////////////////////////////////////
+
+/**
+ * Creates a new element under a provided parent and updates / creates a reference to it in
+ * one atomic action.
+ *
+ * @method CreateBusinessObjectListHandler#execute
+ *
+ * @param {Object} context
+ * @param {djs.model.Base} context.element which is the context for the reference
+ * @param {moddle.referencingObject} context.referencingObject the object which creates the reference
+ * @param {String} context.referenceProperty the property of the referencingObject which makes the reference
+ * @param {moddle.newObject} context.newObject the new object to add
+ * @param {moddle.newObjectContainer} context.newObjectContainer the container for the new object
+ *
+ * @return {Array} the updated element
+ */
+CreateBusinessObjectListHandler.prototype.execute = function (context) {
+
+ var currentObject = ensureNotNull(context.currentObject, 'currentObject'),
+ propertyName = ensureNotNull(context.propertyName, 'propertyName'),
+ newObjects = ensureList(context.newObjects, 'newObjects'),
+ changed = [context.element]; // this will not change any diagram-js elements
+
+
+ var childObjects = [];
+ var self = this;
+
+ // create new array of business objects
+ forEach(newObjects, function (obj) {
+ var element = elementHelper.createElement(obj.type, obj.properties, currentObject, self._bpmnFactory);
+
+ childObjects.push(element);
+ });
+ context.childObject = childObjects;
+
+ // adjust array reference in the parent business object
+ context.previousChilds = currentObject[propertyName];
+ currentObject[propertyName] = childObjects;
+
+ context.changed = changed;
+
+ // indicate changed on objects affected by the update
+ return changed;
+};
+
+/**
+ * Reverts the update
+ *
+ * @method CreateBusinessObjectListHandler#revert
+ *
+ * @param {Object} context
+ *
+ * @return {djs.mode.Base} the updated element
+ */
+CreateBusinessObjectListHandler.prototype.revert = function (context) {
+
+ var currentObject = context.currentObject,
+ propertyName = context.propertyName,
+ previousChilds = context.previousChilds;
+
+ // remove new element
+ currentObject.set(propertyName, previousChilds);
+
+ return context.changed;
+};
+
+},{"../helper/ElementHelper":25,"lodash/collection/forEach":422}],8:[function(require,module,exports){
+'use strict';
+
+var forEach = require('lodash/collection/forEach');
+
+/**
+ * A handler that combines and executes multiple commands.
+ *
+ * All updates are bundled on the command stack and executed in one step.
+ * This also makes it possible to revert the changes in one step.
+ *
+ * Example use case: remove the camunda:formKey attribute and in addition
+ * add all form fields needed for the camunda:formData property.
+ *
+ * @class
+ * @constructor
+ */
+function MultiCommandHandler(commandStack) {
+ this._commandStack = commandStack;
+}
+
+MultiCommandHandler.$inject = ['commandStack'];
+
+module.exports = MultiCommandHandler;
+
+MultiCommandHandler.prototype.preExecute = function (context) {
+
+ var commandStack = this._commandStack;
+
+ forEach(context, function (command) {
+ commandStack.execute(command.cmd, command.context);
+ });
+};
+
+},{"lodash/collection/forEach":422}],9:[function(require,module,exports){
+'use strict';
+
+var reduce = require('lodash/object/transform'),
+ is = require('bpmn-js/lib/util/ModelUtil').is,
+ keys = require('lodash/object/keys'),
+ forEach = require('lodash/collection/forEach');
+
+/**
+ * A handler that implements a BPMN 2.0 property update
+ * for business objects which are not represented in the
+ * diagram.
+ *
+ * This is useful in the context of the properties panel in
+ * order to update child elements of elements visible in
+ * the diagram.
+ *
+ * Example: perform an update of a specific event definition
+ * of an intermediate event.
+ *
+ * @class
+ * @constructor
+ */
+function UpdateBusinessObjectHandler(elementRegistry) {
+ this._elementRegistry = elementRegistry;
+}
+
+UpdateBusinessObjectHandler.$inject = ['elementRegistry'];
+
+module.exports = UpdateBusinessObjectHandler;
+
+/**
+ * returns the root element
+ */
+function getRoot(businessObject) {
+ var parent = businessObject;
+ while (parent.$parent) {
+ parent = parent.$parent;
+ }
+ return parent;
+}
+
+function getProperties(businessObject, propertyNames) {
+ return reduce(propertyNames, function (result, key) {
+ result[key] = businessObject.get(key);
+ return result;
+ }, {});
+}
+
+function setProperties(businessObject, properties) {
+ forEach(properties, function (value, key) {
+ businessObject.set(key, value);
+ });
+}
+
+////// api /////////////////////////////////////////////
+
+/**
+ * Updates a business object with a list of new properties
+ *
+ * @method UpdateBusinessObjectHandler#execute
+ *
+ * @param {Object} context
+ * @param {djs.model.Base} context.element the element which has a child business object updated
+ * @param {moddle.businessObject} context.businessObject the businessObject to update
+ * @param {Object} context.properties a list of properties to set on the businessObject
+ *
+ * @return {Array} the updated element
+ */
+UpdateBusinessObjectHandler.prototype.execute = function (context) {
+
+ var element = context.element,
+ businessObject = context.businessObject,
+ rootElements = getRoot(businessObject).rootElements,
+ referenceType = context.referenceType,
+ referenceProperty = context.referenceProperty,
+ changed = [element]; // this will not change any diagram-js elements
+
+ if (!element) {
+ throw new Error('element required');
+ }
+
+ if (!businessObject) {
+ throw new Error('businessObject required');
+ }
+
+ var properties = context.properties,
+ oldProperties = context.oldProperties || getProperties(businessObject, keys(properties));
+
+ // check if there the update needs an external element for reference
+ if (typeof referenceType !== 'undefined' && typeof referenceProperty !== 'undefined') {
+ forEach(rootElements, function (rootElement) {
+ if (is(rootElement, referenceType)) {
+ if (rootElement.id === properties[referenceProperty]) {
+ properties[referenceProperty] = rootElement;
+ }
+ }
+ });
+ }
+
+ // update properties
+ setProperties(businessObject, properties);
+
+ // store old values
+ context.oldProperties = oldProperties;
+ context.changed = changed;
+
+ // indicate changed on objects affected by the update
+ return changed;
+};
+
+/**
+ * Reverts the update
+ *
+ * @method UpdateBusinessObjectHandler#revert
+ *
+ * @param {Object} context
+ *
+ * @return {djs.mode.Base} the updated element
+ */
+UpdateBusinessObjectHandler.prototype.revert = function (context) {
+
+ var oldProperties = context.oldProperties,
+ businessObject = context.businessObject;
+
+ // update properties
+ setProperties(businessObject, oldProperties);
+
+ return context.changed;
+};
+
+},{"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422,"lodash/object/keys":498,"lodash/object/transform":501}],10:[function(require,module,exports){
+'use strict';
+
+var forEach = require('lodash/collection/forEach');
+
+/**
+ * A handler that implements a BPMN 2.0 property update
+ * for business object lists which are not represented in the
+ * diagram.
+ *
+ * This is useful in the context of the properties panel in
+ * order to update child elements of elements visible in
+ * the diagram.
+ *
+ * Example: perform an update of a specific event definition
+ * of an intermediate event.
+ *
+ * @class
+ * @constructor
+ */
+function UpdateBusinessObjectListHandler(elementRegistry, bpmnFactory) {
+ this._elementRegistry = elementRegistry;
+ this._bpmnFactory = bpmnFactory;
+}
+
+UpdateBusinessObjectListHandler.$inject = ['elementRegistry', 'bpmnFactory'];
+
+module.exports = UpdateBusinessObjectListHandler;
+
+function ensureNotNull(prop, name) {
+ if (!prop) {
+ throw new Error(name + 'required');
+ }
+ return prop;
+}
+
+////// api /////////////////////////////////////////////
+
+/**
+ * Updates a element under a provided parent.
+ */
+UpdateBusinessObjectListHandler.prototype.execute = function (context) {
+
+ var currentObject = ensureNotNull(context.currentObject, 'currentObject'),
+ propertyName = ensureNotNull(context.propertyName, 'propertyName'),
+ updatedObjectList = context.updatedObjectList,
+ objectsToRemove = context.objectsToRemove || [],
+ objectsToAdd = context.objectsToAdd || [],
+ changed = [context.element],
+ // this will not change any diagram-js elements
+ referencePropertyName;
+
+ if (context.referencePropertyName) {
+ referencePropertyName = context.referencePropertyName;
+ }
+
+ var objectList = currentObject[propertyName];
+ // adjust array reference in the parent business object
+ context.previousList = currentObject[propertyName];
+
+ if (updatedObjectList) {
+ currentObject[propertyName] = updatedObjectList;
+ } else {
+ var listCopy = [];
+ // remove all objects which should be removed
+ forEach(objectList, function (object) {
+ if (objectsToRemove.indexOf(object) == -1) {
+ listCopy.push(object);
+ }
+ });
+ // add all objects which should be added
+ listCopy = listCopy.concat(objectsToAdd);
+
+ // set property to new list
+ if (listCopy.length > 0 || !referencePropertyName) {
+
+ // as long as there are elements in the list update the list
+ currentObject[propertyName] = listCopy;
+ } else if (referencePropertyName) {
+
+ // remove the list when it is empty
+ var parentObject = currentObject.$parent;
+ parentObject.set(referencePropertyName, undefined);
+ }
+ }
+
+ context.changed = changed;
+
+ // indicate changed on objects affected by the update
+ return changed;
+};
+
+/**
+ * Reverts the update
+ *
+ * @method CreateBusinessObjectListHandler#revert
+ *
+ * @param {Object} context
+ *
+ * @return {djs.mode.Base} the updated element
+ */
+UpdateBusinessObjectListHandler.prototype.revert = function (context) {
+
+ var currentObject = context.currentObject,
+ propertyName = context.propertyName,
+ previousList = context.previousList,
+ parentObject = currentObject.$parent;
+
+ if (context.referencePropertyName) {
+ parentObject.set(context.referencePropertyName, currentObject);
+ }
+
+ // remove new element
+ currentObject.set(propertyName, previousList);
+
+ return context.changed;
+};
+
+},{"lodash/collection/forEach":422}],11:[function(require,module,exports){
+'use strict';
+
+var forEach = require('lodash/collection/forEach');
+
+var HANDLERS = {
+ 'properties-panel.update-businessobject': require('./UpdateBusinessObjectHandler'),
+ 'properties-panel.create-and-reference': require('./CreateAndReferenceHandler'),
+ 'properties-panel.create-businessobject-list': require('./CreateBusinessObjectListHandler'),
+ 'properties-panel.update-businessobject-list': require('./UpdateBusinessObjectListHandler'),
+ 'properties-panel.multi-command-executor': require('./MultiCommandHandler')
+};
+
+function CommandInitializer(eventBus, commandStack) {
+
+ eventBus.on('diagram.init', function () {
+ forEach(HANDLERS, function (handler, id) {
+ commandStack.registerHandler(id, handler);
+ });
+ });
+}
+
+CommandInitializer.$inject = ['eventBus', 'commandStack'];
+
+module.exports = {
+ __init__: [CommandInitializer]
+};
+
+},{"./CreateAndReferenceHandler":6,"./CreateBusinessObjectListHandler":7,"./MultiCommandHandler":8,"./UpdateBusinessObjectHandler":9,"./UpdateBusinessObjectListHandler":10,"lodash/collection/forEach":422}],12:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ cmdHelper = require('../helper/CmdHelper');
+
+var entryFieldDescription = require('./EntryFieldDescription');
+
+var checkbox = function checkbox(options, defaultParameters) {
+ var resource = defaultParameters,
+ label = options.label || resource.id,
+ canBeDisabled = !!options.disabled && typeof options.disabled === 'function',
+ canBeHidden = !!options.hidden && typeof options.hidden === 'function',
+ description = options.description;
+
+ resource.html = ' ' + '' + label + ' ';
+
+ // add description below checkbox entry field
+ if (description) {
+ resource.html += entryFieldDescription(description);
+ }
+
+ resource.get = function (element) {
+ var bo = getBusinessObject(element),
+ res = {};
+
+ res[options.modelProperty] = bo.get(options.modelProperty);
+
+ return res;
+ };
+ resource.set = function (element, values) {
+ var res = {};
+
+ res[options.modelProperty] = !!values[options.modelProperty];
+
+ return cmdHelper.updateProperties(element, res);
+ };
+
+ if (typeof options.set === 'function') {
+ resource.set = options.set;
+ }
+
+ if (typeof options.get === 'function') {
+ resource.get = options.get;
+ }
+
+ if (canBeDisabled) {
+ resource.isDisabled = function () {
+ return options.disabled.apply(resource, arguments);
+ };
+ }
+
+ if (canBeHidden) {
+ resource.isHidden = function () {
+ return !options.hidden.apply(resource, arguments);
+ };
+ }
+
+ resource.cssClasses = ['bpp-checkbox'];
+
+ return resource;
+};
+
+module.exports = checkbox;
+
+},{"../helper/CmdHelper":24,"./EntryFieldDescription":15,"bpmn-js/lib/util/ModelUtil":216}],13:[function(require,module,exports){
+'use strict';
+
+var assign = require('lodash/object/assign'),
+ find = require('lodash/collection/find');
+
+var domQuery = require('min-dom/lib/query');
+
+var selectEntryFactory = require('./SelectEntryFactory'),
+ entryFieldDescription = require('./EntryFieldDescription');
+
+/**
+ * The combo box is a special implementation of the select entry and adds the option 'custom' to the
+ * select box. If 'custom' is selected, an additional text input field is shown which allows to define
+ * a custom value.
+ *
+ * @param {Object} options
+ * @param {string} options.id
+ * @param {string} options.label
+ * @param {Array} options.selectOptions list of name/value pairs
+ * @param {string} options.modelProperty
+ * @param {function} options.get
+ * @param {function} options.set
+ * @param {string} [options.customValue] custom select option value (default: 'custom')
+ * @param {string} [options.customName] custom select option name visible in the select box (default: 'custom')
+ *
+ * @return {Object}
+ */
+var comboBox = function comboBox(options) {
+
+ var selectOptions = options.selectOptions,
+ modelProperty = options.modelProperty,
+ customValue = options.customValue || 'custom',
+ customName = options.customName || 'custom ' + modelProperty,
+ description = options.description;
+
+ // check if a value is not a built in value
+ var isCustomValue = function isCustomValue(value) {
+ if (typeof value[modelProperty] === 'undefined') {
+ return false;
+ }
+
+ var isCustom = !find(selectOptions, function (option) {
+ return value[modelProperty] === option.value;
+ });
+
+ return isCustom;
+ };
+
+ var comboOptions = assign({}, options);
+
+ // true if the selected value in the select box is customValue
+ comboOptions.showCustomInput = function (element, node) {
+ var selectBox = domQuery('[data-entry="' + options.id + '"] select', node.parentNode);
+
+ if (selectBox) {
+ return selectBox.value === customValue;
+ }
+
+ return false;
+ };
+
+ comboOptions.get = function (element, node) {
+ var value = options.get(element, node);
+
+ var modifiedValues = {};
+
+ if (!isCustomValue(value)) {
+ modifiedValues[modelProperty] = value[modelProperty] || '';
+
+ return modifiedValues;
+ }
+
+ modifiedValues[modelProperty] = customValue;
+ modifiedValues['custom-' + modelProperty] = value[modelProperty];
+
+ return modifiedValues;
+ };
+
+ comboOptions.set = function (element, values, node) {
+ var modifiedValues = {};
+
+ // if the custom select option has been selected
+ // take the value from the text input field
+ if (values[modelProperty] === customValue) {
+ modifiedValues[modelProperty] = values['custom-' + modelProperty] || '';
+ } else if (options.emptyParameter && values[modelProperty] === '') {
+ modifiedValues[modelProperty] = undefined;
+ } else {
+ modifiedValues[modelProperty] = values[modelProperty];
+ }
+ return options.set(element, modifiedValues, node);
+ };
+
+ comboOptions.selectOptions.push({ name: customName, value: customValue });
+
+ var comboBoxEntry = assign({}, selectEntryFactory(comboOptions, comboOptions));
+
+ comboBoxEntry.html += '' + ' ' + '
';
+
+ // add description below combo box entry field
+ if (description) {
+ comboBoxEntry.html += entryFieldDescription(description);
+ }
+
+ return comboBoxEntry;
+};
+
+module.exports = comboBox;
+
+},{"./EntryFieldDescription":15,"./SelectEntryFactory":18,"lodash/collection/find":421,"lodash/object/assign":496,"min-dom/lib/query":112}],14:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+// input entities
+var textInputField = require('./TextInputEntryFactory'),
+ checkboxField = require('./CheckboxEntryFactory'),
+ selectBoxField = require('./SelectEntryFactory'),
+ comboBoxField = require('./ComboEntryFactory'),
+ textBoxField = require('./TextBoxEntryFactory'),
+ validationAwareTextInputField = require('./ValidationAwareTextInput'),
+ tableField = require('./TableEntryFactory'),
+ labelEntry = require('./LabelFactory'),
+ link = require('./LinkEntryFactory');
+
+var cmdHelper = require('../helper/CmdHelper');
+
+// helpers ////////////////////////////////////////
+
+function ensureNotNull(prop) {
+ if (!prop) {
+ throw new Error(prop + ' must be set.');
+ }
+
+ return prop;
+}
+
+/**
+ * sets the default parameters which are needed to create an entry
+ *
+ * @param options
+ * @returns {{id: *, description: (*|string), get: (*|Function), set: (*|Function),
+ * validate: (*|Function), html: string}}
+ */
+var setDefaultParameters = function setDefaultParameters(options) {
+
+ // default method to fetch the current value of the input field
+ var defaultGet = function defaultGet(element) {
+ var bo = getBusinessObject(element),
+ res = {},
+ prop = ensureNotNull(options.modelProperty);
+ res[prop] = bo.get(prop);
+
+ return res;
+ };
+
+ // default method to set a new value to the input field
+ var defaultSet = function defaultSet(element, values) {
+ var res = {},
+ prop = ensureNotNull(options.modelProperty);
+ if (values[prop] !== '') {
+ res[prop] = values[prop];
+ } else {
+ res[prop] = undefined;
+ }
+
+ return cmdHelper.updateProperties(element, res);
+ };
+
+ // default validation method
+ var defaultValidate = function defaultValidate() {
+ return {};
+ };
+
+ return {
+ id: options.id,
+ description: options.description || '',
+ get: options.get || defaultGet,
+ set: options.set || defaultSet,
+ validate: options.validate || defaultValidate,
+ html: ''
+ };
+};
+
+function EntryFactory() {}
+
+/**
+ * Generates an text input entry object for a property panel.
+ * options are:
+ * - id: id of the entry - String
+ *
+ * - description: description of the property - String
+ *
+ * - label: label for the input field - String
+ *
+ * - set: setter method - Function
+ *
+ * - get: getter method - Function
+ *
+ * - validate: validation mehtod - Function
+ *
+ * - modelProperty: name of the model property - String
+ *
+ * - buttonAction: Object which contains the following properties: - Object
+ * ---- name: name of the [data-action] callback - String
+ * ---- method: callback function for [data-action] - Function
+ *
+ * - buttonShow: Object which contains the following properties: - Object
+ * ---- name: name of the [data-show] callback - String
+ * ---- method: callback function for [data-show] - Function
+ *
+ * @param options
+ * @returns the propertyPanel entry resource object
+ */
+EntryFactory.textField = function (options) {
+ return textInputField(options, setDefaultParameters(options));
+};
+
+EntryFactory.validationAwareTextField = function (options) {
+ return validationAwareTextInputField(options, setDefaultParameters(options));
+};
+
+/**
+ * Generates a checkbox input entry object for a property panel.
+ * options are:
+ * - id: id of the entry - String
+ *
+ * - description: description of the property - String
+ *
+ * - label: label for the input field - String
+ *
+ * - set: setter method - Function
+ *
+ * - get: getter method - Function
+ *
+ * - validate: validation mehtod - Function
+ *
+ * - modelProperty: name of the model property - String
+ *
+ * @param options
+ * @returns the propertyPanel entry resource object
+ */
+EntryFactory.checkbox = function (options) {
+ return checkboxField(options, setDefaultParameters(options));
+};
+
+EntryFactory.textBox = function (options) {
+ return textBoxField(options, setDefaultParameters(options));
+};
+
+EntryFactory.selectBox = function (options) {
+ return selectBoxField(options, setDefaultParameters(options));
+};
+
+EntryFactory.comboBox = function (options) {
+ return comboBoxField(options);
+};
+
+EntryFactory.table = function (options) {
+ return tableField(options);
+};
+
+EntryFactory.label = function (options) {
+ return labelEntry(options);
+};
+
+EntryFactory.link = function (options) {
+ return link(options);
+};
+
+module.exports = EntryFactory;
+
+},{"../helper/CmdHelper":24,"./CheckboxEntryFactory":12,"./ComboEntryFactory":13,"./LabelFactory":16,"./LinkEntryFactory":17,"./SelectEntryFactory":18,"./TableEntryFactory":19,"./TextBoxEntryFactory":20,"./TextInputEntryFactory":21,"./ValidationAwareTextInput":22,"bpmn-js/lib/util/ModelUtil":216}],15:[function(require,module,exports){
+'use strict';
+
+var MARKDOWN_LINK_REGEX = /\[([^\)]+)\]\(([^\]]+)\)/g;
+
+/**
+ * Replace MarkDown Link Syntax with HTML Link Syntax
+ * [myLink](http://www.myLink.de) -> myLink
+ *
+ * @param {String} value
+ *
+ * @return {String}
+ */
+function linkify(text) {
+ return text.replace(MARKDOWN_LINK_REGEX, '$1 ');
+}
+
+module.exports = function entryFieldDescription(description) {
+ description = linkify(description);
+
+ return '' + description + '
';
+};
+
+},{}],16:[function(require,module,exports){
+'use strict';
+
+/**
+ * The label factory provides a label entry. For the label text
+ * it expects either a string provided by the options.labelText
+ * parameter or it could be generated programmatically using a
+ * function passed as the options.get parameter.
+ *
+ * @param {Object} options
+ * @param {string} options.id
+ * @param {string} [options.labelText]
+ * @param {Function} [options.get]
+ * @param {Function} [options.showLabel]
+ * @param {Boolean} [options.divider] adds a divider at the top of the label if true; default: false
+ */
+
+var label = function label(options) {
+ return {
+ id: options.id,
+ html: '' + ' ',
+ get: function get(element, node) {
+ if (typeof options.get === 'function') {
+ return options.get(element, node);
+ }
+ return { label: options.labelText };
+ },
+ showLabel: function showLabel(element, node) {
+ if (typeof options.showLabel === 'function') {
+ return options.showLabel(element, node);
+ }
+ return true;
+ }
+ };
+};
+
+module.exports = label;
+
+},{}],17:[function(require,module,exports){
+'use strict';
+
+var utils = require('../Utils');
+
+var entryFieldDescription = require('./EntryFieldDescription');
+
+var link = function link(options, defaultParameters) {
+
+ var id = options.id,
+ label = options.label || id,
+ hideLink = options.hideLink,
+ canBeHidden = typeof hideLink === 'function',
+ getClickableElement = options.getClickableElement,
+ description = options.description;
+
+ var resource = { id: id };
+
+ resource.html = '' + label + ' ';
+
+ // add description below link entry field
+ if (description) {
+ resource.html += entryFieldDescription(description);
+ }
+
+ resource.linkSelected = function (element, node, event, scopeNode) {
+ if (typeof getClickableElement === 'function') {
+
+ var link = getClickableElement.apply(resource, [element, node, event, scopeNode]);
+ link && utils.triggerClickEvent(link);
+ }
+
+ return false;
+ };
+
+ if (canBeHidden) {
+ resource.hideLink = function () {
+ return !hideLink.apply(resource, arguments);
+ };
+ }
+
+ return resource;
+};
+
+module.exports = link;
+
+},{"../Utils":5,"./EntryFieldDescription":15}],18:[function(require,module,exports){
+'use strict';
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+var domify = require('min-dom/lib/domify');
+
+var forEach = require('lodash/collection/forEach');
+
+var entryFieldDescription = require('./EntryFieldDescription');
+
+var isList = function isList(list) {
+ return !(!list || Object.prototype.toString.call(list) !== '[object Array]');
+};
+
+var addEmptyParameter = function addEmptyParameter(list) {
+ return list.concat([{ name: '', value: '' }]);
+};
+
+var createOption = function createOption(option) {
+ return '' + option.name + ' ';
+};
+
+/**
+ * @param {Object} options
+ * @param {string} options.id
+ * @param {string} [options.label]
+ * @param {Array} options.selectOptions
+ * @param {string} options.modelProperty
+ * @param {boolean} options.emptyParameter
+ * @param {function} options.disabled
+ * @param {function} options.hidden
+ * @param {Object} defaultParameters
+ *
+ * @return {Object}
+ */
+var selectbox = function selectbox(options, defaultParameters) {
+ var resource = defaultParameters,
+ label = options.label || resource.id,
+ selectOptions = options.selectOptions || [{ name: '', value: '' }],
+ modelProperty = options.modelProperty,
+ emptyParameter = options.emptyParameter,
+ canBeDisabled = !!options.disabled && typeof options.disabled === 'function',
+ canBeHidden = !!options.hidden && typeof options.hidden === 'function',
+ description = options.description;
+
+ if (emptyParameter) {
+ selectOptions = addEmptyParameter(selectOptions);
+ }
+
+ resource.html = '' + label + ' ' + '';
+
+ if (isList(selectOptions)) {
+ forEach(selectOptions, function (option) {
+ resource.html += '' + (option.name || '') + ' ';
+ });
+ }
+
+ resource.html += ' ';
+
+ // add description below select box entry field
+ if (description && !_typeof(options.showCustomInput) === 'function') {
+ resource.html += entryFieldDescription(description);
+ }
+
+ /**
+ * Fill the select box options dynamically.
+ *
+ * Calls the defined function #selectOptions in the entry to get the
+ * values for the options and set the value to the inputNode.
+ *
+ * @param {djs.model.Base} element
+ * @param {HTMLElement} entryNode
+ * @param {EntryDescriptor} inputNode
+ * @param {Object} inputName
+ * @param {Object} newValue
+ */
+ resource.setControlValue = function (element, entryNode, inputNode, inputName, newValue) {
+ if (typeof selectOptions === 'function') {
+
+ var options = selectOptions(element, inputNode);
+
+ if (options) {
+
+ // remove existing options
+ while (inputNode.firstChild) {
+ inputNode.removeChild(inputNode.firstChild);
+ }
+
+ // add options
+ forEach(options, function (option) {
+ var template = domify(createOption(option));
+
+ inputNode.appendChild(template);
+ });
+ }
+ }
+
+ // set select value
+ if (newValue !== undefined) {
+ inputNode.value = newValue;
+ }
+ };
+
+ if (canBeDisabled) {
+ resource.isDisabled = function () {
+ return options.disabled.apply(resource, arguments);
+ };
+ }
+
+ if (canBeHidden) {
+ resource.isHidden = function () {
+ return !options.hidden.apply(resource, arguments);
+ };
+ }
+
+ resource.cssClasses = ['bpp-dropdown'];
+
+ return resource;
+};
+
+module.exports = selectbox;
+
+},{"./EntryFieldDescription":15,"lodash/collection/forEach":422,"min-dom/lib/domify":110}],19:[function(require,module,exports){
+'use strict';
+
+var cmdHelper = require('../helper/CmdHelper');
+
+var domQuery = require('min-dom/lib/query'),
+ domAttr = require('min-dom/lib/attr'),
+ domClosest = require('min-dom/lib/closest');
+
+var filter = require('lodash/collection/filter'),
+ forEach = require('lodash/collection/forEach'),
+ keys = require('lodash/object/keys');
+
+var domify = require('min-dom/lib/domify');
+
+var entryFieldDescription = require('./EntryFieldDescription');
+
+var updateSelection = require('selection-update');
+
+var TABLE_ROW_DIV_SNIPPET = '';
+var DELETE_ROW_BUTTON_SNIPPET = '' + 'X ' + ' ';
+
+function createInputRowTemplate(properties, canRemove) {
+ var template = TABLE_ROW_DIV_SNIPPET;
+ template += createInputTemplate(properties, canRemove);
+ template += canRemove ? DELETE_ROW_BUTTON_SNIPPET : '';
+ template += '
';
+
+ return template;
+}
+
+function createInputTemplate(properties, canRemove) {
+ var columns = properties.length;
+ var template = '';
+ forEach(properties, function (prop) {
+ template += ' ';
+ });
+ return template;
+}
+
+function createLabelRowTemplate(labels) {
+ var template = TABLE_ROW_DIV_SNIPPET;
+ template += createLabelTemplate(labels);
+ template += '';
+
+ return template;
+}
+
+function createLabelTemplate(labels) {
+ var columns = labels.length;
+ var template = '';
+ forEach(labels, function (label) {
+ template += '' + label + ' ';
+ });
+ return template;
+}
+
+function pick(elements, properties) {
+ return (elements || []).map(function (elem) {
+ var newElement = {};
+ forEach(properties, function (prop) {
+ newElement[prop] = elem[prop] || '';
+ });
+ return newElement;
+ });
+}
+
+function diff(element, node, values, oldValues, editable) {
+ return filter(values, function (value, idx) {
+ return !valueEqual(element, node, value, oldValues[idx], editable, idx);
+ });
+}
+
+function valueEqual(element, node, value, oldValue, editable, idx) {
+ if (value && !oldValue) {
+ return false;
+ }
+ var allKeys = keys(value).concat(keys(oldValue));
+
+ return allKeys.every(function (key) {
+ var n = value[key] || undefined;
+ var o = oldValue[key] || undefined;
+ return !editable(element, node, key, idx) || n === o;
+ });
+}
+
+function getEntryNode(node) {
+ return domClosest(node, '[data-entry]', true);
+}
+
+function getContainer(node) {
+ return domQuery('div[data-list-entry-container]', node);
+}
+
+function getSelection(node) {
+ return {
+ start: node.selectionStart,
+ end: node.selectionEnd
+ };
+}
+
+function setSelection(node, selection) {
+ node.selectionStart = selection.start;
+ node.selectionEnd = selection.end;
+}
+
+/**
+ * @param {Object} options
+ * @param {string} options.id
+ * @param {string} options.description
+ * @param {Array} options.modelProperties
+ * @param {Array} options.labels
+ * @param {Function} options.getElements - this callback function must return a list of business object items
+ * @param {Function} options.removeElement
+ * @param {Function} options.addElement
+ * @param {Function} options.updateElement
+ * @param {Function} options.editable
+ * @param {Function} options.setControlValue
+ * @param {Function} options.show
+ *
+ * @return {Object}
+ */
+module.exports = function (options) {
+
+ var id = options.id,
+ modelProperties = options.modelProperties,
+ labels = options.labels,
+ description = options.description;
+
+ var labelRow = createLabelRowTemplate(labels);
+
+ var getElements = options.getElements;
+
+ var removeElement = options.removeElement,
+ canRemove = typeof removeElement === 'function';
+
+ var addElement = options.addElement,
+ canAdd = typeof addElement === 'function',
+ addLabel = options.addLabel || 'Add Value';
+
+ var updateElement = options.updateElement,
+ canUpdate = typeof updateElement === 'function';
+
+ var _editable = options.editable || function () {
+ return true;
+ },
+ setControlValue = options.setControlValue;
+
+ var _show = options.show,
+ canBeShown = typeof _show === 'function';
+
+ var elements = function elements(element, node) {
+ return pick(getElements(element, node), modelProperties);
+ };
+
+ var factory = {
+ id: id,
+ html: (canAdd ? '' + '' + addLabel + ' ' + '+ ' + '
' : '') + '' + '
' + labelRow + '
' + '
' + '
' + '
' + (
+
+ // add description below table entry field
+ description ? entryFieldDescription(description) : ''),
+
+ get: function get(element, node) {
+ var boElements = elements(element, node, this.__invalidValues);
+
+ var invalidValues = this.__invalidValues;
+
+ delete this.__invalidValues;
+
+ forEach(invalidValues, function (value, idx) {
+ var element = boElements[idx];
+
+ forEach(modelProperties, function (prop) {
+ element[prop] = value[prop];
+ });
+ });
+
+ return boElements;
+ },
+
+ set: function set(element, values, node) {
+ var action = this.__action || {};
+ delete this.__action;
+
+ if (action.id === 'delete-element') {
+ return removeElement(element, node, action.idx);
+ } else if (action.id === 'add-element') {
+ return addElement(element, node);
+ } else if (canUpdate) {
+ var commands = [],
+ valuesToValidate = values;
+
+ if (typeof options.validate !== 'function') {
+ valuesToValidate = diff(element, node, values, elements(element, node), _editable);
+ }
+
+ var self = this;
+
+ forEach(valuesToValidate, function (value) {
+ var validationError,
+ idx = values.indexOf(value);
+
+ if (typeof options.validate === 'function') {
+ validationError = options.validate(element, value, node, idx);
+ }
+
+ if (!validationError) {
+ var cmd = updateElement(element, value, node, idx);
+
+ if (cmd) {
+ commands.push(cmd);
+ }
+ } else {
+ // cache invalid value in an object by index as key
+ self.__invalidValues = self.__invalidValues || {};
+ self.__invalidValues[idx] = value;
+
+ // execute a command, which does not do anything
+ commands.push(cmdHelper.updateProperties(element, {}));
+ }
+ });
+
+ return commands;
+ }
+ },
+ createListEntryTemplate: function createListEntryTemplate(value, index, selectBox) {
+ return createInputRowTemplate(modelProperties, canRemove);
+ },
+
+ addElement: function addElement(element, node, event, scopeNode) {
+ var template = domify(createInputRowTemplate(modelProperties, canRemove));
+
+ var container = getContainer(node);
+ container.appendChild(template);
+
+ this.__action = {
+ id: 'add-element'
+ };
+
+ return true;
+ },
+
+ deleteElement: function deleteElement(element, node, event, scopeNode) {
+ var container = getContainer(node);
+ var rowToDelete = event.delegateTarget.parentNode;
+ var idx = parseInt(domAttr(rowToDelete, 'data-index'), 10);
+
+ container.removeChild(rowToDelete);
+
+ this.__action = {
+ id: 'delete-element',
+ idx: idx
+ };
+
+ return true;
+ },
+
+ editable: function editable(element, rowNode, input, prop, value, idx) {
+ var entryNode = domClosest(rowNode, '[data-entry]');
+ return _editable(element, entryNode, prop, idx);
+ },
+
+ show: function show(element, entryNode, node, scopeNode) {
+ entryNode = getEntryNode(entryNode);
+ return _show(element, entryNode, node, scopeNode);
+ },
+
+ showTable: function showTable(element, entryNode, node, scopeNode) {
+ entryNode = getEntryNode(entryNode);
+ var elems = elements(element, entryNode);
+ return elems && elems.length && (!canBeShown || _show(element, entryNode, node, scopeNode));
+ },
+
+ validateListItem: function validateListItem(element, value, node, idx) {
+ if (typeof options.validate === 'function') {
+ return options.validate(element, value, node, idx);
+ }
+ }
+
+ };
+
+ // Update/set the selection on the correct position.
+ // It's the same code like for an input value in the PropertiesPanel.js.
+ if (setControlValue) {
+ factory.setControlValue = function (element, rowNode, input, prop, value, idx) {
+ var entryNode = getEntryNode(rowNode);
+
+ var isReadOnly = domAttr(input, 'readonly');
+ var oldValue = input.value;
+
+ var selection;
+
+ // prevents input fields from having the value 'undefined'
+ if (value === undefined) {
+ value = '';
+ }
+
+ // when the attribute 'readonly' exists, ignore the comparison
+ // with 'oldValue' and 'value'
+ if (!!isReadOnly && oldValue === value) {
+ return;
+ }
+
+ // update selection on undo/redo
+ if (document.activeElement === input) {
+ selection = updateSelection(getSelection(input), oldValue, value);
+ }
+
+ setControlValue(element, entryNode, input, prop, value, idx);
+
+ if (selection) {
+ setSelection(input, selection);
+ }
+ };
+ }
+
+ return factory;
+};
+
+},{"../helper/CmdHelper":24,"./EntryFieldDescription":15,"lodash/collection/filter":420,"lodash/collection/forEach":422,"lodash/object/keys":498,"min-dom/lib/attr":105,"min-dom/lib/closest":108,"min-dom/lib/domify":110,"min-dom/lib/query":112,"selection-update":533}],20:[function(require,module,exports){
+'use strict';
+
+var entryFieldDescription = require('./EntryFieldDescription');
+
+var textBox = function textBox(options, defaultParameters) {
+
+ var resource = defaultParameters,
+ label = options.label || resource.id,
+ canBeShown = !!options.show && typeof options.show === 'function',
+ description = options.description;
+
+ resource.html = '' + label + ' ' + '';
+
+ // add description below text box entry field
+ if (description) {
+ resource.html += entryFieldDescription(description);
+ }
+
+ if (canBeShown) {
+ resource.isShown = function () {
+ return options.show.apply(resource, arguments);
+ };
+ }
+
+ resource.cssClasses = ['bpp-textbox'];
+
+ return resource;
+};
+
+module.exports = textBox;
+
+},{"./EntryFieldDescription":15}],21:[function(require,module,exports){
+'use strict';
+
+var domQuery = require('min-dom/lib/query');
+
+var entryFieldDescription = require('./EntryFieldDescription');
+
+var textField = function textField(options, defaultParameters) {
+
+ // Default action for the button next to the input-field
+ var defaultButtonAction = function defaultButtonAction(element, inputNode) {
+ var input = domQuery('input[name="' + options.modelProperty + '"]', inputNode);
+ input.value = '';
+
+ return true;
+ };
+
+ // default method to determine if the button should be visible
+ var defaultButtonShow = function defaultButtonShow(element, inputNode) {
+ var input = domQuery('input[name="' + options.modelProperty + '"]', inputNode);
+
+ return input.value !== '';
+ };
+
+ var resource = defaultParameters,
+ label = options.label || resource.id,
+ dataValueLabel = options.dataValueLabel,
+ buttonLabel = options.buttonLabel || 'X',
+ actionName = typeof options.buttonAction != 'undefined' ? options.buttonAction.name : 'clear',
+ actionMethod = typeof options.buttonAction != 'undefined' ? options.buttonAction.method : defaultButtonAction,
+ showName = typeof options.buttonShow != 'undefined' ? options.buttonShow.name : 'canClear',
+ showMethod = typeof options.buttonShow != 'undefined' ? options.buttonShow.method : defaultButtonShow,
+ canBeDisabled = !!options.disabled && typeof options.disabled === 'function',
+ canBeHidden = !!options.hidden && typeof options.hidden === 'function',
+ description = options.description;
+
+ resource.html = '' + label + ' ' + '' + ' ' + '' + '' + buttonLabel + ' ' + ' ' + '
';
+
+ // add description below text input entry field
+ if (description) {
+ resource.html += entryFieldDescription(description);
+ }
+
+ resource[actionName] = actionMethod;
+ resource[showName] = showMethod;
+
+ if (canBeDisabled) {
+ resource.isDisabled = function () {
+ return options.disabled.apply(resource, arguments);
+ };
+ }
+
+ if (canBeHidden) {
+ resource.isHidden = function () {
+ return !options.hidden.apply(resource, arguments);
+ };
+ }
+
+ resource.cssClasses = ['bpp-textfield'];
+
+ return resource;
+};
+
+module.exports = textField;
+
+},{"./EntryFieldDescription":15,"min-dom/lib/query":112}],22:[function(require,module,exports){
+'use strict';
+
+var textField = require('./TextInputEntryFactory');
+
+/**
+ * This function is a wrapper around TextInputEntryFactory.
+ * It adds functionality to cache an invalid value entered in the
+ * text input, instead of setting it on the business object.
+ */
+var validationAwareTextField = function validationAwareTextField(options, defaultParameters) {
+
+ var modelProperty = options.modelProperty;
+
+ defaultParameters.get = function (element, node) {
+ var value = this.__lastInvalidValue;
+
+ delete this.__lastInvalidValue;
+
+ var properties = {};
+
+ properties[modelProperty] = value !== undefined ? value : options.getProperty(element, node);
+
+ return properties;
+ };
+
+ defaultParameters.set = function (element, values, node) {
+ var validationErrors = validate.apply(this, [element, values, node]),
+ propertyValue = values[modelProperty];
+
+ // make sure we do not update the id
+ if (validationErrors && validationErrors[modelProperty]) {
+ this.__lastInvalidValue = propertyValue;
+
+ return options.setProperty(element, {}, node);
+ } else {
+ var properties = {};
+
+ properties[modelProperty] = propertyValue;
+
+ return options.setProperty(element, properties, node);
+ }
+ };
+
+ var validate = defaultParameters.validate = function (element, values, node) {
+ var value = values[modelProperty] || this.__lastInvalidValue;
+
+ var property = {};
+ property[modelProperty] = value;
+
+ return options.validate(element, property, node);
+ };
+
+ return textField(options, defaultParameters);
+};
+
+module.exports = validationAwareTextField;
+
+},{"./TextInputEntryFactory":21}],23:[function(require,module,exports){
+'use strict';
+
+var map = require('lodash/collection/map');
+
+var extensionElementsHelper = require('./ExtensionElementsHelper');
+
+/**
+ * Returns true if the attribute 'camunda:asyncBefore' is set
+ * to true.
+ *
+ * @param {ModdleElement} bo
+ *
+ * @return {boolean} a boolean value
+ */
+function isAsyncBefore(bo) {
+ return !!(bo.get('camunda:asyncBefore') || bo.get('camunda:async'));
+}
+
+module.exports.isAsyncBefore = isAsyncBefore;
+
+/**
+ * Returns true if the attribute 'camunda:asyncAfter' is set
+ * to true.
+ *
+ * @param {ModdleElement} bo
+ *
+ * @return {boolean} a boolean value
+ */
+function isAsyncAfter(bo) {
+ return !!bo.get('camunda:asyncAfter');
+}
+
+module.exports.isAsyncAfter = isAsyncAfter;
+
+/**
+ * Returns true if the attribute 'camunda:exclusive' is set
+ * to true.
+ *
+ * @param {ModdleElement} bo
+ *
+ * @return {boolean} a boolean value
+ */
+function isExclusive(bo) {
+ return !!bo.get('camunda:exclusive');
+}
+
+module.exports.isExclusive = isExclusive;
+
+/**
+ * Get first 'camunda:FailedJobRetryTimeCycle' from the business object.
+ *
+ * @param {ModdleElement} bo
+ *
+ * @return {Array} a list of 'camunda:FailedJobRetryTimeCycle'
+ */
+function getFailedJobRetryTimeCycle(bo) {
+ return (extensionElementsHelper.getExtensionElements(bo, 'camunda:FailedJobRetryTimeCycle') || [])[0];
+}
+
+module.exports.getFailedJobRetryTimeCycle = getFailedJobRetryTimeCycle;
+
+/**
+ * Removes all existing 'camunda:FailedJobRetryTimeCycle' from the business object
+ *
+ * @param {ModdleElement} bo
+ *
+ * @return {Array} a list of 'camunda:FailedJobRetryTimeCycle'
+ */
+function removeFailedJobRetryTimeCycle(bo, element) {
+ var retryTimeCycles = extensionElementsHelper.getExtensionElements(bo, 'camunda:FailedJobRetryTimeCycle');
+ return map(retryTimeCycles, function (cycle) {
+ return extensionElementsHelper.removeEntry(bo, element, cycle);
+ });
+}
+
+module.exports.removeFailedJobRetryTimeCycle = removeFailedJobRetryTimeCycle;
+
+},{"./ExtensionElementsHelper":27,"lodash/collection/map":424}],24:[function(require,module,exports){
+'use strict';
+
+var CmdHelper = {};
+module.exports = CmdHelper;
+
+CmdHelper.updateProperties = function (element, properties) {
+ return {
+ cmd: 'element.updateProperties',
+ context: { element: element, properties: properties }
+ };
+};
+
+CmdHelper.updateBusinessObject = function (element, businessObject, newProperties) {
+ return {
+ cmd: 'properties-panel.update-businessobject',
+ context: {
+ element: element,
+ businessObject: businessObject,
+ properties: newProperties
+ }
+ };
+};
+
+CmdHelper.addElementsTolist = function (element, businessObject, listPropertyName, objectsToAdd) {
+ return {
+ cmd: 'properties-panel.update-businessobject-list',
+ context: {
+ element: element,
+ currentObject: businessObject,
+ propertyName: listPropertyName,
+ objectsToAdd: objectsToAdd
+ }
+ };
+};
+
+CmdHelper.removeElementsFromList = function (element, businessObject, listPropertyName, referencePropertyName, objectsToRemove) {
+
+ return {
+ cmd: 'properties-panel.update-businessobject-list',
+ context: {
+ element: element,
+ currentObject: businessObject,
+ propertyName: listPropertyName,
+ referencePropertyName: referencePropertyName,
+ objectsToRemove: objectsToRemove
+ }
+ };
+};
+
+CmdHelper.addAndRemoveElementsFromList = function (element, businessObject, listPropertyName, referencePropertyName, objectsToAdd, objectsToRemove) {
+
+ return {
+ cmd: 'properties-panel.update-businessobject-list',
+ context: {
+ element: element,
+ currentObject: businessObject,
+ propertyName: listPropertyName,
+ referencePropertyName: referencePropertyName,
+ objectsToAdd: objectsToAdd,
+ objectsToRemove: objectsToRemove
+ }
+ };
+};
+
+CmdHelper.setList = function (element, businessObject, listPropertyName, updatedObjectList) {
+ return {
+ cmd: 'properties-panel.update-businessobject-list',
+ context: {
+ element: element,
+ currentObject: businessObject,
+ propertyName: listPropertyName,
+ updatedObjectList: updatedObjectList
+ }
+ };
+};
+
+},{}],25:[function(require,module,exports){
+'use strict';
+
+var ElementHelper = {};
+module.exports = ElementHelper;
+
+/**
+ * Creates a new element and set the parent to it
+ *
+ * @method ElementHelper#createElement
+ *
+ * @param {String} elementType of the new element
+ * @param {Object} properties of the new element in key-value pairs
+ * @param {moddle.object} parent of the new element
+ * @param {BpmnFactory} factory which creates the new element
+ *
+ * @returns {djs.model.Base} element which is created
+ */
+ElementHelper.createElement = function (elementType, properties, parent, factory) {
+ var element = factory.create(elementType, properties);
+ element.$parent = parent;
+
+ return element;
+};
+
+},{}],26:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ is = require('bpmn-js/lib/util/ModelUtil').is,
+ forEach = require('lodash/collection/forEach');
+
+var EventDefinitionHelper = {};
+
+module.exports = EventDefinitionHelper;
+
+EventDefinitionHelper.getEventDefinition = function (element, eventType) {
+
+ var bo = getBusinessObject(element),
+ eventDefinition = null;
+
+ if (bo.eventDefinitions) {
+ forEach(bo.eventDefinitions, function (event) {
+ if (is(event, eventType)) {
+ eventDefinition = event;
+ }
+ });
+ }
+
+ return eventDefinition;
+};
+
+EventDefinitionHelper.getTimerEventDefinition = function (element) {
+ return this.getEventDefinition(element, 'bpmn:TimerEventDefinition');
+};
+
+EventDefinitionHelper.getMessageEventDefinition = function (element) {
+ return this.getEventDefinition(element, 'bpmn:MessageEventDefinition');
+};
+
+EventDefinitionHelper.getSignalEventDefinition = function (element) {
+ return this.getEventDefinition(element, 'bpmn:SignalEventDefinition');
+};
+
+EventDefinitionHelper.getErrorEventDefinition = function (element) {
+ return this.getEventDefinition(element, 'bpmn:ErrorEventDefinition');
+};
+
+EventDefinitionHelper.getEscalationEventDefinition = function (element) {
+ return this.getEventDefinition(element, 'bpmn:EscalationEventDefinition');
+};
+
+EventDefinitionHelper.getCompensateEventDefinition = function (element) {
+ return this.getEventDefinition(element, 'bpmn:CompensateEventDefinition');
+};
+
+EventDefinitionHelper.getLinkEventDefinition = function (element) {
+ return this.getEventDefinition(element, 'bpmn:LinkEventDefinition');
+};
+
+EventDefinitionHelper.getConditionalEventDefinition = function (element) {
+ return this.getEventDefinition(element, 'bpmn:ConditionalEventDefinition');
+};
+
+},{"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422}],27:[function(require,module,exports){
+'use strict';
+
+var cmdHelper = require('./CmdHelper'),
+ elementHelper = require('./ElementHelper');
+
+var is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var ExtensionElementsHelper = {};
+
+var getExtensionElements = function getExtensionElements(bo) {
+ return bo.get('extensionElements');
+};
+
+ExtensionElementsHelper.getExtensionElements = function (bo, type) {
+ var extensionElements = getExtensionElements(bo);
+ if (typeof extensionElements !== 'undefined') {
+ var extensionValues = extensionElements.get('values');
+ if (typeof extensionValues !== 'undefined') {
+ var elements = extensionValues.filter(function (value) {
+ return is(value, type);
+ });
+ if (elements.length) {
+ return elements;
+ }
+ }
+ }
+};
+
+ExtensionElementsHelper.addEntry = function (bo, element, entry, bpmnFactory) {
+ var extensionElements = bo.get('extensionElements');
+
+ // if there is no extensionElements list, create one
+ if (!extensionElements) {
+ // TODO: Ask Daniel which operation costs more
+ extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [entry] }, bo, bpmnFactory);
+ return { extensionElements: extensionElements };
+ } else {
+ // add new failedJobRetryExtensionElement to existing extensionElements list
+ return cmdHelper.addElementsTolist(element, extensionElements, 'values', [entry]);
+ }
+};
+
+ExtensionElementsHelper.removeEntry = function (bo, element, entry) {
+ var extensionElements = bo.get('extensionElements');
+
+ if (!extensionElements) {
+ // return an empty command when there is no extensionElements list
+ return {};
+ }
+
+ return cmdHelper.removeElementsFromList(element, extensionElements, 'values', 'extensionElements', [entry]);
+};
+
+module.exports = ExtensionElementsHelper;
+
+},{"./CmdHelper":24,"./ElementHelper":25,"bpmn-js/lib/util/ModelUtil":216}],28:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ getExtensionElements = require('./ExtensionElementsHelper').getExtensionElements;
+
+var FormHelper = {};
+
+module.exports = FormHelper;
+
+/**
+ * Return form data from business object or undefined if none exist
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {ModdleElement|undefined} formData
+ */
+FormHelper.getFormData = function (element) {
+ var bo = getBusinessObject(element);
+
+ var formData = getExtensionElements(bo, 'camunda:FormData');
+
+ if (typeof formData !== 'undefined') {
+ return formData[0];
+ }
+};
+
+/**
+ * Return all form fields existing in the business object, and
+ * an empty array if none exist.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {Array} a list of form field objects
+ */
+FormHelper.getFormFields = function (element) {
+ var formData = this.getFormData(element);
+
+ if (typeof formData === 'undefined') {
+ return [];
+ }
+
+ return formData.fields;
+};
+
+/**
+ * Get a form field from the business object at given index
+ *
+ * @param {djs.model.Base} element
+ * @param {number} idx
+ *
+ * @return {ModdleElement} the form field
+ */
+FormHelper.getFormField = function (element, idx) {
+
+ var formFields = this.getFormFields(element);
+
+ return formFields[idx];
+};
+
+/**
+ * Get all constraints for a specific form field from the business object
+ *
+ * @param {ModdleElement} formField
+ *
+ * @return {Array} a list of constraint objects
+ */
+FormHelper.getConstraints = function (formField) {
+ if (formField && formField.validation && formField.validation.constraints) {
+ return formField.validation.constraints;
+ }
+ return [];
+};
+
+/**
+ * Get all camunda:value objects for a specific form field from the business object
+ *
+ * @param {ModdleElement} formField
+ *
+ * @return {Array} a list of camunda:value objects
+ */
+FormHelper.getEnumValues = function (formField) {
+ if (formField && formField.values) {
+ return formField.values;
+ }
+ return [];
+};
+
+},{"./ExtensionElementsHelper":27,"bpmn-js/lib/util/ModelUtil":216}],29:[function(require,module,exports){
+'use strict';
+
+var ModelUtil = require('bpmn-js/lib/util/ModelUtil'),
+ is = ModelUtil.is,
+ getBusinessObject = ModelUtil.getBusinessObject;
+
+var eventDefinitionHelper = require('./EventDefinitionHelper');
+var extensionsElementHelper = require('./ExtensionElementsHelper');
+
+var ImplementationTypeHelper = {};
+
+module.exports = ImplementationTypeHelper;
+
+/**
+ * Returns 'true' if the given element is 'camunda:ServiceTaskLike'
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {boolean} a boolean value
+ */
+ImplementationTypeHelper.isServiceTaskLike = function (element) {
+ return is(element, 'camunda:ServiceTaskLike');
+};
+
+/**
+ * Returns 'true' if the given element is 'camunda:DmnCapable'
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {boolean} a boolean value
+ */
+ImplementationTypeHelper.isDmnCapable = function (element) {
+ return is(element, 'camunda:DmnCapable');
+};
+
+/**
+ * Returns 'true' if the given element is 'camunda:ExternalCapable'
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {boolean} a boolean value
+ */
+ImplementationTypeHelper.isExternalCapable = function (element) {
+ return is(element, 'camunda:ExternalCapable');
+};
+
+/**
+ * Returns 'true' if the given element is 'camunda:TaskListener'
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {boolean} a boolean value
+ */
+ImplementationTypeHelper.isTaskListener = function (element) {
+ return is(element, 'camunda:TaskListener');
+};
+
+/**
+ * Returns 'true' if the given element is 'camunda:ExecutionListener'
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {boolean} a boolean value
+ */
+ImplementationTypeHelper.isExecutionListener = function (element) {
+ return is(element, 'camunda:ExecutionListener');
+};
+
+/**
+ * Returns 'true' if the given element is 'camunda:ExecutionListener' or
+ * 'camunda:TaskListener'
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {boolean} a boolean value
+ */
+ImplementationTypeHelper.isListener = function (element) {
+ return this.isTaskListener(element) || this.isExecutionListener(element);
+};
+
+/**
+ * Returns 'true' if the given element is 'bpmn:SequenceFlow'
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {boolean} a boolean value
+ */
+ImplementationTypeHelper.isSequenceFlow = function (element) {
+ return is(element, 'bpmn:SequenceFlow');
+};
+
+/**
+ * Get a 'camunda:ServiceTaskLike' business object.
+ *
+ * If the given element is not a 'camunda:ServiceTaskLike', then 'false'
+ * is returned.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {ModdleElement} the 'camunda:ServiceTaskLike' business object
+ */
+ImplementationTypeHelper.getServiceTaskLikeBusinessObject = function (element) {
+
+ if (is(element, 'bpmn:IntermediateThrowEvent') || is(element, 'bpmn:EndEvent')) {
+ /**
+ * change business object to 'messageEventDefinition' when
+ * the element is a message intermediate throw event or message end event
+ * because the camunda extensions (e.g. camunda:class) are in the message
+ * event definition tag and not in the intermediate throw event or end event tag
+ */
+ var messageEventDefinition = eventDefinitionHelper.getMessageEventDefinition(element);
+ if (messageEventDefinition) {
+ element = messageEventDefinition;
+ }
+ }
+
+ return this.isServiceTaskLike(element) && getBusinessObject(element);
+};
+
+/**
+ * Returns the implementation type of the given element.
+ *
+ * Possible implementation types are:
+ * - dmn
+ * - connector
+ * - external
+ * - class
+ * - expression
+ * - delegateExpression
+ * - script
+ * - or undefined, when no matching implementation type is found
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {String} the implementation type
+ */
+ImplementationTypeHelper.getImplementationType = function (element) {
+
+ var bo = this.getServiceTaskLikeBusinessObject(element);
+
+ if (!bo) {
+ if (this.isListener(element)) {
+ bo = element;
+ } else {
+ return;
+ }
+ }
+
+ if (this.isDmnCapable(bo)) {
+ var decisionRef = bo.get('camunda:decisionRef');
+ if (typeof decisionRef !== 'undefined') {
+ return 'dmn';
+ }
+ }
+
+ if (this.isServiceTaskLike(bo)) {
+ var connectors = extensionsElementHelper.getExtensionElements(bo, 'camunda:Connector');
+ if (typeof connectors !== 'undefined') {
+ return 'connector';
+ }
+ }
+
+ if (this.isExternalCapable(bo)) {
+ var type = bo.get('camunda:type');
+ if (type === 'external') {
+ return 'external';
+ }
+ }
+
+ var cls = bo.get('camunda:class');
+ if (typeof cls !== 'undefined') {
+ return 'class';
+ }
+
+ var expression = bo.get('camunda:expression');
+ if (typeof expression !== 'undefined') {
+ return 'expression';
+ }
+
+ var delegateExpression = bo.get('camunda:delegateExpression');
+ if (typeof delegateExpression !== 'undefined') {
+ return 'delegateExpression';
+ }
+
+ if (this.isListener(bo)) {
+ var script = bo.get('script');
+ if (typeof script !== 'undefined') {
+ return 'script';
+ }
+ }
+};
+
+},{"./EventDefinitionHelper":26,"./ExtensionElementsHelper":27,"bpmn-js/lib/util/ModelUtil":216}],30:[function(require,module,exports){
+'use strict';
+
+var ModelUtil = require('bpmn-js/lib/util/ModelUtil'),
+ is = ModelUtil.is,
+ getBusinessObject = ModelUtil.getBusinessObject;
+
+var extensionElementsHelper = require('./ExtensionElementsHelper'),
+ implementationTypeHelper = require('./ImplementationTypeHelper');
+
+var InputOutputHelper = {};
+
+module.exports = InputOutputHelper;
+
+function getElements(bo, type, prop) {
+ var elems = extensionElementsHelper.getExtensionElements(bo, type) || [];
+ return !prop ? elems : (elems[0] || {})[prop] || [];
+}
+
+function getParameters(element, prop, insideConnector) {
+ var inputOutput = InputOutputHelper.getInputOutput(element, insideConnector);
+ return inputOutput && inputOutput.get(prop) || [];
+}
+
+/**
+ * Get a inputOutput from the business object
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {ModdleElement} the inputOutput object
+ */
+InputOutputHelper.getInputOutput = function (element, insideConnector) {
+ if (!insideConnector) {
+ var bo = getBusinessObject(element);
+ return (getElements(bo, 'camunda:InputOutput') || [])[0];
+ }
+ var connector = this.getConnector(element);
+ return connector && connector.get('inputOutput');
+};
+
+/**
+ * Get a connector from the business object
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {ModdleElement} the connector object
+ */
+InputOutputHelper.getConnector = function (element) {
+ var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element);
+ return bo && (getElements(bo, 'camunda:Connector') || [])[0];
+};
+
+/**
+ * Return all input parameters existing in the business object, and
+ * an empty array if none exist.
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {Array} a list of input parameter objects
+ */
+InputOutputHelper.getInputParameters = function (element, insideConnector) {
+ return getParameters.apply(this, [element, 'inputParameters', insideConnector]);
+};
+
+/**
+ * Return all output parameters existing in the business object, and
+ * an empty array if none exist.
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {Array} a list of output parameter objects
+ */
+InputOutputHelper.getOutputParameters = function (element, insideConnector) {
+ return getParameters.apply(this, [element, 'outputParameters', insideConnector]);
+};
+
+/**
+ * Get a input parameter from the business object at given index
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ * @param {number} idx
+ *
+ * @return {ModdleElement} input parameter
+ */
+InputOutputHelper.getInputParameter = function (element, insideConnector, idx) {
+ return this.getInputParameters(element, insideConnector)[idx];
+};
+
+/**
+ * Get a output parameter from the business object at given index
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ * @param {number} idx
+ *
+ * @return {ModdleElement} output parameter
+ */
+InputOutputHelper.getOutputParameter = function (element, insideConnector, idx) {
+ return this.getOutputParameters(element, insideConnector)[idx];
+};
+
+/**
+ * Returns 'true' if the given element supports inputOutput
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {boolean} a boolean value
+ */
+InputOutputHelper.isInputOutputSupported = function (element, insideConnector) {
+ var bo = getBusinessObject(element);
+ return insideConnector || is(bo, 'bpmn:FlowNode') && !is(bo, 'bpmn:StartEvent') && !is(bo, 'bpmn:BoundaryEvent') && !(is(bo, 'bpmn:SubProcess') && bo.get('triggeredByEvent'));
+};
+
+/**
+ * Returns 'true' if the given element supports output parameters
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {boolean} a boolean value
+ */
+InputOutputHelper.areOutputParametersSupported = function (element, insideConnector) {
+ var bo = getBusinessObject(element);
+ return insideConnector || !is(bo, 'bpmn:EndEvent') && !bo.loopCharacteristics;
+};
+
+},{"./ExtensionElementsHelper":27,"./ImplementationTypeHelper":29,"bpmn-js/lib/util/ModelUtil":216}],31:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ cmdHelper = require('./CmdHelper');
+
+var ParticipantHelper = {};
+
+module.exports = ParticipantHelper;
+
+ParticipantHelper.modifyProcessBusinessObject = function (element, property, values) {
+ if (!is(element, 'bpmn:Participant')) {
+ return {};
+ }
+
+ var bo = getBusinessObject(element).get('processRef'),
+ properties = {};
+
+ properties[property] = values[property];
+
+ return cmdHelper.updateBusinessObject(element, bo, properties);
+};
+
+ParticipantHelper.getProcessBusinessObject = function (element, propertyName) {
+ if (!is(element, 'bpmn:Participant')) {
+ return {};
+ }
+
+ var bo = getBusinessObject(element).get('processRef'),
+ properties = {};
+
+ properties[propertyName] = bo.get(propertyName);
+
+ return properties;
+};
+
+},{"./CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216}],32:[function(require,module,exports){
+'use strict';
+
+module.exports = {
+ __depends__: [require('./cmd'), require('diagram-js/lib/i18n/translate')],
+ __init__: ['propertiesPanel'],
+ propertiesPanel: ['type', require('./PropertiesPanel')]
+};
+
+},{"./PropertiesPanel":4,"./cmd":11,"diagram-js/lib/i18n/translate":376}],33:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../factory/EntryFactory'),
+ cmdHelper = require('../../../helper/CmdHelper');
+
+var ModelUtil = require('bpmn-js/lib/util/ModelUtil'),
+ is = ModelUtil.is,
+ getBusinessObject = ModelUtil.getBusinessObject;
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ var getValue = function getValue(businessObject) {
+ return function (element) {
+ var documentations = businessObject && businessObject.get('documentation'),
+ text = documentations && documentations.length > 0 ? documentations[0].text : '';
+
+ return { documentation: text };
+ };
+ };
+
+ var setValue = function setValue(businessObject) {
+ return function (element, values) {
+ var newObjectList = [];
+
+ if (typeof values.documentation !== 'undefined' && values.documentation !== '') {
+ newObjectList.push(bpmnFactory.create('bpmn:Documentation', {
+ text: values.documentation
+ }));
+ }
+
+ return cmdHelper.setList(element, businessObject, 'documentation', newObjectList);
+ };
+ };
+
+ // Element Documentation
+ var elementDocuEntry = entryFactory.textBox({
+ id: 'documentation',
+ label: translate('Element Documentation'),
+ modelProperty: 'documentation'
+ });
+
+ elementDocuEntry.set = setValue(getBusinessObject(element));
+
+ elementDocuEntry.get = getValue(getBusinessObject(element));
+
+ group.entries.push(elementDocuEntry);
+
+ var processRef;
+
+ // Process Documentation when having a Collaboration Diagram
+ if (is(element, 'bpmn:Participant')) {
+
+ processRef = getBusinessObject(element).processRef;
+
+ // do not show for collapsed Pools/Participants
+ if (processRef) {
+ var processDocuEntry = entryFactory.textBox({
+ id: 'process-documentation',
+ label: translate('Process Documentation'),
+ modelProperty: 'documentation'
+ });
+
+ processDocuEntry.set = setValue(processRef);
+
+ processDocuEntry.get = getValue(processRef);
+
+ group.entries.push(processDocuEntry);
+ }
+ }
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216}],34:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny,
+ isEventSubProcess = require('bpmn-js/lib/util/DiUtil').isEventSubProcess,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ eventDefinitionHelper = require('../../../helper/EventDefinitionHelper');
+
+var forEach = require('lodash/collection/forEach');
+
+var message = require('./implementation/MessageEventDefinition'),
+ signal = require('./implementation/SignalEventDefinition'),
+ error = require('./implementation/ErrorEventDefinition'),
+ escalation = require('./implementation/EscalationEventDefinition'),
+ timer = require('./implementation/TimerEventDefinition'),
+ compensation = require('./implementation/CompensateEventDefinition'),
+ condition = require('./implementation/ConditionalEventDefinition');
+
+module.exports = function (group, element, bpmnFactory, elementRegistry, translate) {
+ var events = ['bpmn:StartEvent', 'bpmn:EndEvent', 'bpmn:IntermediateThrowEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateCatchEvent'];
+
+ // Message and Signal Event Definition
+ forEach(events, function (event) {
+ if (is(element, event)) {
+
+ var messageEventDefinition = eventDefinitionHelper.getMessageEventDefinition(element),
+ signalEventDefinition = eventDefinitionHelper.getSignalEventDefinition(element);
+
+ if (messageEventDefinition) {
+ message(group, element, bpmnFactory, messageEventDefinition);
+ }
+
+ if (signalEventDefinition) {
+ signal(group, element, bpmnFactory, signalEventDefinition);
+ }
+ }
+ });
+
+ // Special Case: Receive Task
+ if (is(element, 'bpmn:ReceiveTask')) {
+ message(group, element, bpmnFactory, getBusinessObject(element));
+ }
+
+ // Error Event Definition
+ var errorEvents = ['bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:EndEvent'];
+
+ forEach(errorEvents, function (event) {
+ if (is(element, event)) {
+
+ var errorEventDefinition = eventDefinitionHelper.getErrorEventDefinition(element);
+
+ if (errorEventDefinition) {
+ var isCatchingErrorEvent = is(element, 'bpmn:StartEvent') || is(element, 'bpmn:BoundaryEvent');
+
+ var showErrorCodeVariable = isCatchingErrorEvent,
+ showErrorMessageVariable = isCatchingErrorEvent;
+
+ error(group, element, bpmnFactory, errorEventDefinition, showErrorCodeVariable, showErrorMessageVariable);
+ }
+ }
+ });
+
+ // Escalation Event Definition
+ var escalationEvents = ['bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateThrowEvent', 'bpmn:EndEvent'];
+
+ forEach(escalationEvents, function (event) {
+ if (is(element, event)) {
+
+ var showEscalationCodeVariable = is(element, 'bpmn:StartEvent') || is(element, 'bpmn:BoundaryEvent');
+
+ // get business object
+ var escalationEventDefinition = eventDefinitionHelper.getEscalationEventDefinition(element);
+
+ if (escalationEventDefinition) {
+ escalation(group, element, bpmnFactory, escalationEventDefinition, showEscalationCodeVariable);
+ }
+ }
+ });
+
+ // Timer Event Definition
+ var timerEvents = ['bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateCatchEvent'];
+
+ forEach(timerEvents, function (event) {
+ if (is(element, event)) {
+
+ // get business object
+ var timerEventDefinition = eventDefinitionHelper.getTimerEventDefinition(element);
+
+ if (timerEventDefinition) {
+ timer(group, element, bpmnFactory, timerEventDefinition);
+ }
+ }
+ });
+
+ // Compensate Event Definition
+ var compensationEvents = ['bpmn:EndEvent', 'bpmn:IntermediateThrowEvent'];
+
+ forEach(compensationEvents, function (event) {
+ if (is(element, event)) {
+
+ // get business object
+ var compensateEventDefinition = eventDefinitionHelper.getCompensateEventDefinition(element);
+
+ if (compensateEventDefinition) {
+ compensation(group, element, bpmnFactory, compensateEventDefinition, elementRegistry);
+ }
+ }
+ });
+
+ // Conditional Event Defintion
+ var conditionalEvents = ['bpmn:BoundaryEvent', 'bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent'];
+
+ if (isAny(element, conditionalEvents) || is(element, 'bpmn:StartEvent') && isEventSubProcess(element.parent)) {
+
+ // get business object
+ var conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(element);
+
+ if (conditionalEventDefinition) {
+ condition(group, element, bpmnFactory, conditionalEventDefinition, elementRegistry);
+ }
+ }
+};
+
+},{"../../../helper/EventDefinitionHelper":26,"./implementation/CompensateEventDefinition":40,"./implementation/ConditionalEventDefinition":41,"./implementation/ErrorEventDefinition":43,"./implementation/EscalationEventDefinition":44,"./implementation/MessageEventDefinition":46,"./implementation/SignalEventDefinition":48,"./implementation/TimerEventDefinition":49,"bpmn-js/lib/features/modeling/util/ModelingUtil":189,"bpmn-js/lib/util/DiUtil":214,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422}],35:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var entryFactory = require('../../../factory/EntryFactory');
+
+var participantHelper = require('../../../helper/ParticipantHelper');
+
+module.exports = function (group, element, translate) {
+
+ var bo = getBusinessObject(element);
+
+ if (!bo) {
+ return;
+ }
+
+ if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && bo.get('processRef')) {
+
+ var executableEntry = entryFactory.checkbox({
+ id: 'process-is-executable',
+ label: translate('Executable'),
+ modelProperty: 'isExecutable'
+ });
+
+ // in participants we have to change the default behavior of set and get
+ if (is(element, 'bpmn:Participant')) {
+ executableEntry.get = function (element) {
+ return participantHelper.getProcessBusinessObject(element, 'isExecutable');
+ };
+
+ executableEntry.set = function (element, values) {
+ return participantHelper.modifyProcessBusinessObject(element, 'isExecutable', values);
+ };
+ }
+
+ group.entries.push(executableEntry);
+ }
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/ParticipantHelper":31,"bpmn-js/lib/util/ModelUtil":216}],36:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../factory/EntryFactory'),
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ utils = require('../../../Utils'),
+ cmdHelper = require('../../../helper/CmdHelper');
+
+module.exports = function (group, element, translate) {
+
+ // Id
+ group.entries.push(entryFactory.validationAwareTextField({
+ id: 'id',
+ label: translate('Id'),
+ modelProperty: 'id',
+ getProperty: function getProperty(element) {
+ return getBusinessObject(element).id;
+ },
+ setProperty: function setProperty(element, properties) {
+
+ element = element.labelTarget || element;
+
+ return cmdHelper.updateProperties(element, properties);
+ },
+ validate: function validate(element, values) {
+ var idValue = values.id;
+
+ var bo = getBusinessObject(element);
+
+ var idError = utils.isIdValid(bo, idValue);
+
+ return idError ? { id: idError } : {};
+ }
+ }));
+};
+
+},{"../../../Utils":5,"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216}],37:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ entryFactory = require('../../../factory/EntryFactory'),
+ cmdHelper = require('../../../helper/CmdHelper');
+
+var forEach = require('lodash/collection/forEach');
+
+function getLinkEventDefinition(element) {
+
+ var bo = getBusinessObject(element);
+
+ var linkEventDefinition = null;
+ if (bo.eventDefinitions) {
+ forEach(bo.eventDefinitions, function (eventDefinition) {
+ if (is(eventDefinition, 'bpmn:LinkEventDefinition')) {
+ linkEventDefinition = eventDefinition;
+ }
+ });
+ }
+
+ return linkEventDefinition;
+}
+
+module.exports = function (group, element, translate) {
+ var linkEvents = ['bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent'];
+
+ forEach(linkEvents, function (event) {
+ if (is(element, event)) {
+
+ var linkEventDefinition = getLinkEventDefinition(element);
+
+ if (linkEventDefinition) {
+ var entry = entryFactory.textField({
+ id: 'link-event',
+ label: translate('Link Name'),
+ modelProperty: 'link-name'
+ });
+
+ entry.get = function () {
+ return { 'link-name': linkEventDefinition.get('name') };
+ };
+
+ entry.set = function (element, values) {
+ var newProperties = {
+ name: values['link-name']
+ };
+ return cmdHelper.updateBusinessObject(element, linkEventDefinition, newProperties);
+ };
+
+ group.entries.push(entry);
+ }
+ }
+ });
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422}],38:[function(require,module,exports){
+'use strict';
+
+var nameEntryFactory = require('./implementation/Name'),
+ is = require('bpmn-js/lib/util/ModelUtil').is;
+
+module.exports = function (group, element, translate) {
+
+ if (!is(element, 'bpmn:Collaboration')) {
+
+ var options;
+ if (is(element, 'bpmn:TextAnnotation')) {
+ options = { modelProperty: 'text' };
+ }
+
+ // name
+ group.entries = group.entries.concat(nameEntryFactory(element, options, translate));
+ }
+};
+
+},{"./implementation/Name":47,"bpmn-js/lib/util/ModelUtil":216}],39:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ entryFactory = require('../../../factory/EntryFactory'),
+ participantHelper = require('../../../helper/ParticipantHelper'),
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ nameEntryFactory = require('./implementation/Name'),
+ utils = require('../../../Utils');
+
+module.exports = function (group, element, translate) {
+ var businessObject = getBusinessObject(element);
+
+ if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
+
+ /**
+ * processId
+ */
+ if (is(element, 'bpmn:Participant')) {
+ var idEntry = entryFactory.validationAwareTextField({
+ id: 'process-id',
+ label: translate('Process Id'),
+ modelProperty: 'processId'
+ });
+
+ // in participants we have to change the default behavior of set and get
+ idEntry.get = function (element) {
+ var properties = participantHelper.getProcessBusinessObject(element, 'id');
+ return { processId: properties.id };
+ };
+
+ idEntry.set = function (element, values) {
+ return participantHelper.modifyProcessBusinessObject(element, 'id', { id: values.processId });
+ };
+
+ idEntry.validate = function (element, values) {
+ var idValue = values.processId;
+
+ var bo = getBusinessObject(element);
+
+ var processIdError = utils.isIdValid(bo.processRef, idValue);
+
+ return processIdError ? { processId: processIdError } : {};
+ };
+
+ group.entries.push(idEntry);
+
+ /**
+ * process name
+ */
+ var processNameEntry = nameEntryFactory(element, {
+ id: 'process-name',
+ label: translate('Process Name')
+ })[0];
+
+ // in participants we have to change the default behavior of set and get
+ processNameEntry.get = function (element) {
+ return participantHelper.getProcessBusinessObject(element, 'name');
+ };
+
+ processNameEntry.set = function (element, values) {
+ return participantHelper.modifyProcessBusinessObject(element, 'name', values);
+ };
+
+ group.entries.push(processNameEntry);
+ }
+ }
+};
+
+},{"../../../Utils":5,"../../../factory/EntryFactory":14,"../../../helper/ParticipantHelper":31,"./implementation/Name":47,"bpmn-js/lib/util/ModelUtil":216}],40:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+var cmdHelper = require('../../../../helper/CmdHelper'),
+ eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'),
+ utils = require('../../../../Utils');
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var forEach = require('lodash/collection/forEach'),
+ find = require('lodash/collection/find'),
+ filter = require('lodash/collection/filter');
+
+function getContainedActivities(element) {
+ return getFlowElements(element, 'bpmn:Activity');
+}
+
+function getContainedBoundaryEvents(element) {
+ return getFlowElements(element, 'bpmn:BoundaryEvent');
+}
+
+function getFlowElements(element, type) {
+ return utils.filterElementsByType(element.flowElements, type);
+}
+
+function isCompensationEventAttachedToActivity(activity, boundaryEvents) {
+ var activityId = activity.id;
+ var boundaryEvent = find(boundaryEvents, function (boundaryEvent) {
+ var compensateEventDefinition = eventDefinitionHelper.getCompensateEventDefinition(boundaryEvent);
+ var attachedToRef = boundaryEvent.attachedToRef;
+ return compensateEventDefinition && attachedToRef && attachedToRef.id === activityId;
+ });
+ return !!boundaryEvent;
+}
+
+// subprocess: only when it is not triggeredByEvent
+// activity: only when it attach a compensation boundary event
+// callActivity: no limitation
+function canActivityBeCompensated(activity, boundaryEvents) {
+ return is(activity, 'bpmn:SubProcess') && !activity.triggeredByEvent || is(activity, 'bpmn:CallActivity') || isCompensationEventAttachedToActivity(activity, boundaryEvents);
+}
+
+function getActivitiesForCompensation(element) {
+ var boundaryEvents = getContainedBoundaryEvents(element);
+ return filter(getContainedActivities(element), function (activity) {
+ return canActivityBeCompensated(activity, boundaryEvents);
+ });
+}
+
+function getActivitiesForActivityRef(element) {
+ var bo = getBusinessObject(element);
+ var parent = bo.$parent;
+
+ var activitiesForActivityRef = getActivitiesForCompensation(parent);
+
+ // if throwing compensation event is in an event sub process:
+ // get also all activities outside of the event sub process
+ if (is(parent, 'bpmn:SubProcess') && parent.triggeredByEvent) {
+ parent = parent.$parent;
+ if (parent) {
+ activitiesForActivityRef = activitiesForActivityRef.concat(getActivitiesForCompensation(parent));
+ }
+ }
+
+ return activitiesForActivityRef;
+}
+
+function createActivityRefOptions(element) {
+ var options = [{ value: '' }];
+
+ var activities = getActivitiesForActivityRef(element);
+ forEach(activities, function (activity) {
+ var activityId = activity.id;
+ var name = (activity.name ? activity.name + ' ' : '') + '(id=' + activityId + ')';
+ options.push({ value: activityId, name: name });
+ });
+
+ return options;
+}
+
+module.exports = function (group, element, bpmnFactory, compensateEventDefinition, elementRegistry) {
+
+ group.entries.push(entryFactory.checkbox({
+ id: 'wait-for-completion',
+ label: 'Wait for Completion',
+ modelProperty: 'waitForCompletion',
+
+ get: function get(element, node) {
+ return {
+ waitForCompletion: compensateEventDefinition.waitForCompletion
+ };
+ },
+
+ set: function set(element, values) {
+ values.waitForCompletion = values.waitForCompletion || false;
+ return cmdHelper.updateBusinessObject(element, compensateEventDefinition, values);
+ }
+ }));
+
+ group.entries.push(entryFactory.selectBox({
+ id: 'activity-ref',
+ label: 'Activity Ref',
+ selectOptions: createActivityRefOptions(element),
+ modelProperty: 'activityRef',
+
+ get: function get(element, node) {
+ var activityRef = compensateEventDefinition.activityRef;
+ activityRef = activityRef && activityRef.id;
+ return {
+ activityRef: activityRef || ''
+ };
+ },
+
+ set: function set(element, values) {
+ var activityRef = values.activityRef || undefined;
+ activityRef = activityRef && getBusinessObject(elementRegistry.get(activityRef));
+ return cmdHelper.updateBusinessObject(element, compensateEventDefinition, {
+ activityRef: activityRef
+ });
+ }
+ }));
+};
+
+},{"../../../../Utils":5,"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/EventDefinitionHelper":26,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/filter":420,"lodash/collection/find":421,"lodash/collection/forEach":422}],41:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ elementHelper = require('../../../../helper/ElementHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+function createFormalExpression(parent, body, bpmnFactory) {
+ body = body || undefined;
+ return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory);
+}
+
+module.exports = function (group, element, bpmnFactory, conditionalEventDefinition) {
+
+ var getValue = function getValue(modelProperty) {
+ return function (element) {
+ var modelPropertyValue = conditionalEventDefinition.get('camunda:' + modelProperty);
+ var value = {};
+
+ value[modelProperty] = modelPropertyValue;
+ return value;
+ };
+ };
+
+ var setValue = function setValue(modelProperty) {
+ return function (element, values) {
+ var props = {};
+
+ props['camunda:' + modelProperty] = values[modelProperty] || undefined;
+
+ return cmdHelper.updateBusinessObject(element, conditionalEventDefinition, props);
+ };
+ };
+
+ group.entries.push(entryFactory.textField({
+ id: 'condition',
+ label: 'Condition',
+ modelProperty: 'condition',
+ get: function get(element) {
+ var condition = conditionalEventDefinition.get('condition'),
+ body = condition && condition.get('body');
+
+ return { condition: body || '' };
+ },
+ set: function set(element, values) {
+ var condition = conditionalEventDefinition.get('condition');
+
+ // remove condition expression from the business object when text field is empty
+ if (values.condition === '') {
+ return cmdHelper.updateBusinessObject(element, conditionalEventDefinition, { condition: undefined });
+ }
+
+ // if no condition expression is set yet, create one
+ if (!condition) {
+ condition = createFormalExpression(conditionalEventDefinition, values.condition, bpmnFactory);
+
+ return cmdHelper.updateBusinessObject(element, conditionalEventDefinition, { condition: condition });
+
+ // if a condition expression and a text field value exists, update business object
+ } else {
+ return cmdHelper.updateBusinessObject(element, condition, {
+ body: values.condition || undefined
+ });
+ }
+ },
+ validate: function validate(element, values) {
+ if (values['condition'] === '') {
+ return { condition: 'Must provide a value' };
+ }
+ }
+ }));
+
+ group.entries.push(entryFactory.textField({
+ id: 'variableName',
+ label: 'Variable Name',
+ modelProperty: 'variableName',
+
+ get: getValue('variableName'),
+ set: setValue('variableName')
+ }));
+
+ group.entries.push(entryFactory.textField({
+ id: 'variableEvent',
+ label: 'Variable Event',
+ description: 'Specify more than one variable change event as a comma separated list.',
+ modelProperty: 'variableEvent',
+
+ get: getValue('variableEvent'),
+ set: setValue('variableEvent')
+ }));
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25}],42:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+var cmdHelper = require('../../../../helper/CmdHelper');
+
+/**
+ * Create an entry to modify a property of an element which
+ * is referenced by a event definition.
+ *
+ * @param {djs.model.Base} element
+ * @param {ModdleElement} definition
+ * @param {BpmnFactory} bpmnFactory
+ * @param {Object} options
+ * @param {string} options.id the id of the entry
+ * @param {string} options.label the label of the entry
+ * @param {string} options.referenceProperty the name of referencing property
+ * @param {string} options.modelProperty the name of property to modify
+ * @param {string} options.shouldValidate a flag indicate whether to validate or not
+ *
+ * @return {Array} return an array containing the entries
+ */
+module.exports = function (element, definition, bpmnFactory, options) {
+
+ var id = options.id || 'element-property';
+ var label = options.label;
+ var referenceProperty = options.referenceProperty;
+ var modelProperty = options.modelProperty || 'name';
+ var shouldValidate = options.shouldValidate || false;
+
+ var entry = entryFactory.textField({
+ id: id,
+ label: label,
+ modelProperty: modelProperty,
+
+ get: function get(element, node) {
+ var reference = definition.get(referenceProperty);
+ var props = {};
+ props[modelProperty] = reference && reference.get(modelProperty);
+ return props;
+ },
+
+ set: function set(element, values, node) {
+ var reference = definition.get(referenceProperty);
+ var props = {};
+ props[modelProperty] = values[modelProperty] || undefined;
+ return cmdHelper.updateBusinessObject(element, reference, props);
+ },
+
+ hidden: function hidden(element, node) {
+ return !definition.get(referenceProperty);
+ }
+ });
+
+ if (shouldValidate) {
+ entry.validate = function (element, values, node) {
+ var reference = definition.get(referenceProperty);
+ if (reference && !values[modelProperty]) {
+ var validationErrors = {};
+ validationErrors[modelProperty] = 'Must provide a value';
+ return validationErrors;
+ }
+ };
+ }
+
+ return [entry];
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],43:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+var eventDefinitionReference = require('./EventDefinitionReference'),
+ elementReferenceProperty = require('./ElementReferenceProperty');
+
+module.exports = function (group, element, bpmnFactory, errorEventDefinition, showErrorCodeVariable, showErrorMessageVariable) {
+
+ var getValue = function getValue(modelProperty) {
+ return function (element) {
+ var modelPropertyValue = errorEventDefinition.get('camunda:' + modelProperty);
+ var value = {};
+
+ value[modelProperty] = modelPropertyValue;
+ return value;
+ };
+ };
+
+ var setValue = function setValue(modelProperty) {
+ return function (element, values) {
+ var props = {};
+
+ props['camunda:' + modelProperty] = values[modelProperty] || undefined;
+
+ return cmdHelper.updateBusinessObject(element, errorEventDefinition, props);
+ };
+ };
+
+ group.entries = group.entries.concat(eventDefinitionReference(element, errorEventDefinition, bpmnFactory, {
+ label: 'Error',
+ elementName: 'error',
+ elementType: 'bpmn:Error',
+ referenceProperty: 'errorRef',
+ newElementIdPrefix: 'Error_'
+ }));
+
+ group.entries = group.entries.concat(elementReferenceProperty(element, errorEventDefinition, bpmnFactory, {
+ id: 'error-element-name',
+ label: 'Error Name',
+ referenceProperty: 'errorRef',
+ modelProperty: 'name',
+ shouldValidate: true
+ }));
+
+ group.entries = group.entries.concat(elementReferenceProperty(element, errorEventDefinition, bpmnFactory, {
+ id: 'error-element-code',
+ label: 'Error Code',
+ referenceProperty: 'errorRef',
+ modelProperty: 'errorCode'
+ }));
+
+ if (showErrorCodeVariable) {
+ group.entries.push(entryFactory.textField({
+ id: 'errorCodeVariable',
+ label: 'Error Code Variable',
+ modelProperty: 'errorCodeVariable',
+
+ get: getValue('errorCodeVariable'),
+ set: setValue('errorCodeVariable')
+ }));
+ }
+
+ if (showErrorMessageVariable) {
+ group.entries.push(entryFactory.textField({
+ id: 'errorMessageVariable',
+ label: 'Error Message Variable',
+ modelProperty: 'errorMessageVariable',
+
+ get: getValue('errorMessageVariable'),
+ set: setValue('errorMessageVariable')
+ }));
+ }
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"./ElementReferenceProperty":42,"./EventDefinitionReference":45}],44:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+var eventDefinitionReference = require('./EventDefinitionReference'),
+ elementReferenceProperty = require('./ElementReferenceProperty');
+
+module.exports = function (group, element, bpmnFactory, escalationEventDefinition, showEscalationCodeVariable) {
+
+ group.entries = group.entries.concat(eventDefinitionReference(element, escalationEventDefinition, bpmnFactory, {
+ label: 'Escalation',
+ elementName: 'escalation',
+ elementType: 'bpmn:Escalation',
+ referenceProperty: 'escalationRef',
+ newElementIdPrefix: 'Escalation_'
+ }));
+
+ group.entries = group.entries.concat(elementReferenceProperty(element, escalationEventDefinition, bpmnFactory, {
+ id: 'escalation-element-name',
+ label: 'Escalation Name',
+ referenceProperty: 'escalationRef',
+ modelProperty: 'name',
+ shouldValidate: true
+ }));
+
+ group.entries = group.entries.concat(elementReferenceProperty(element, escalationEventDefinition, bpmnFactory, {
+ id: 'escalation-element-code',
+ label: 'Escalation Code',
+ referenceProperty: 'escalationRef',
+ modelProperty: 'escalationCode'
+ }));
+
+ if (showEscalationCodeVariable) {
+ group.entries.push(entryFactory.textField({
+ id: 'escalationCodeVariable',
+ label: 'Escalation Code Variable',
+ modelProperty: 'escalationCodeVariable',
+
+ get: function get(element) {
+ var codeVariable = escalationEventDefinition.get('camunda:escalationCodeVariable');
+ return {
+ escalationCodeVariable: codeVariable
+ };
+ },
+
+ set: function set(element, values) {
+ return cmdHelper.updateBusinessObject(element, escalationEventDefinition, {
+ 'camunda:escalationCodeVariable': values.escalationCodeVariable || undefined
+ });
+ }
+ }));
+ }
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"./ElementReferenceProperty":42,"./EventDefinitionReference":45}],45:[function(require,module,exports){
+'use strict';
+
+var cmdHelper = require('../../../../helper/CmdHelper');
+
+var domQuery = require('min-dom/lib/query'),
+ domify = require('min-dom/lib/domify'),
+ domAttr = require('min-dom/lib/attr');
+
+var forEach = require('lodash/collection/forEach'),
+ find = require('lodash/collection/find');
+
+var elementHelper = require('../../../../helper/ElementHelper');
+var utils = require('../../../../Utils');
+
+var selector = 'select[name=selectedElement]';
+
+/**
+ * Get select box containing all elements.
+ *
+ * @param {DOMElement} node
+ *
+ * @return {DOMElement} the select box
+ */
+function getSelectBox(node) {
+ return domQuery(selector, node.parentElement);
+}
+
+/**
+ * Find element by given id.
+ *
+ * @param {ModdleElement} eventDefinition
+ *
+ * @return {ModdleElement} an element
+ */
+function findElementById(eventDefinition, type, id) {
+ var elements = utils.findRootElementsByType(eventDefinition, type);
+ return find(elements, function (element) {
+ return element.id === id;
+ });
+}
+
+/**
+ * Create an entry to modify the reference to an element from an
+ * event definition.
+ *
+ * @param {djs.model.Base} element
+ * @param {ModdleElement} definition
+ * @param {BpmnFactory} bpmnFactory
+ * @param {Object} options
+ * @param {string} options.label the label of the entry
+ * @param {string} options.description the description of the entry
+ * @param {string} options.elementName the name of the element
+ * @param {string} options.elementType the type of the element
+ * @param {string} options.referenceProperty the name of referencing property
+ * @param {string} options.newElementIdPrefix the prefix of a new created element
+ *
+ * @return {Array} return an array containing the entries
+ */
+module.exports = function (element, definition, bpmnFactory, options) {
+
+ var elementName = options.elementName || '',
+ elementType = options.elementType,
+ referenceProperty = options.referenceProperty;
+
+ var newElementIdPrefix = options.newElementIdPrefix || 'elem_';
+
+ var label = options.label || '',
+ description = options.description || '';
+
+ var entries = [];
+
+ entries.push({
+
+ id: 'event-definitions-' + elementName,
+ description: description,
+ html: '' + '
' + label + ' ' + '
' + '' + ' ' + '+ ' + '
' + '
',
+
+ get: function get(element, entryNode) {
+ utils.updateOptionsDropDown(selector, definition, elementType, entryNode);
+ var reference = definition.get(referenceProperty);
+ return {
+ selectedElement: reference && reference.id || ''
+ };
+ },
+
+ set: function set(element, values) {
+ var selection = values.selectedElement;
+
+ var props = {};
+
+ if (!selection || typeof selection === 'undefined') {
+ // remove reference to element
+ props[referenceProperty] = undefined;
+ return cmdHelper.updateBusinessObject(element, definition, props);
+ }
+
+ var commands = [];
+
+ var selectedElement = findElementById(definition, elementType, selection);
+ if (!selectedElement) {
+ var root = utils.getRoot(definition);
+
+ // create a new element
+ selectedElement = elementHelper.createElement(elementType, { name: selection }, root, bpmnFactory);
+ commands.push(cmdHelper.addAndRemoveElementsFromList(element, root, 'rootElements', null, [selectedElement]));
+ }
+
+ // update reference to element
+ props[referenceProperty] = selectedElement;
+ commands.push(cmdHelper.updateBusinessObject(element, definition, props));
+
+ return commands;
+ },
+
+ addElement: function addElement(element, inputNode) {
+ // note: this generated id will be used as name
+ // of the element and not as id
+ var id = utils.nextId(newElementIdPrefix);
+
+ var optionTemplate = domify(' (id=' + id + ')' + ' ');
+
+ // add new option
+ var selectBox = getSelectBox(inputNode);
+ selectBox.insertBefore(optionTemplate, selectBox.firstChild);
+
+ // select new element in the select box
+ forEach(selectBox, function (option) {
+ if (option.value === id) {
+ domAttr(option, 'selected', 'selected');
+ } else {
+ domAttr(option, 'selected', null);
+ }
+ });
+
+ return true;
+ }
+
+ });
+
+ return entries;
+};
+
+},{"../../../../Utils":5,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"lodash/collection/find":421,"lodash/collection/forEach":422,"min-dom/lib/attr":105,"min-dom/lib/domify":110,"min-dom/lib/query":112}],46:[function(require,module,exports){
+'use strict';
+
+var eventDefinitionReference = require('./EventDefinitionReference'),
+ elementReferenceProperty = require('./ElementReferenceProperty');
+
+module.exports = function (group, element, bpmnFactory, messageEventDefinition) {
+
+ group.entries = group.entries.concat(eventDefinitionReference(element, messageEventDefinition, bpmnFactory, {
+ label: 'Message',
+ elementName: 'message',
+ elementType: 'bpmn:Message',
+ referenceProperty: 'messageRef',
+ newElementIdPrefix: 'Message_'
+ }));
+
+ group.entries = group.entries.concat(elementReferenceProperty(element, messageEventDefinition, bpmnFactory, {
+ id: 'message-element-name',
+ label: 'Message Name',
+ referenceProperty: 'messageRef',
+ modelProperty: 'name',
+ shouldValidate: true
+ }));
+};
+
+},{"./ElementReferenceProperty":42,"./EventDefinitionReference":45}],47:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+/**
+ * Create an entry to modify the name of an an element.
+ *
+ * @param {djs.model.Base} element
+ * @param {Object} options
+ * @param {string} options.id the id of the entry
+ * @param {string} options.label the label of the entry
+ *
+ * @return {Array} return an array containing
+ * the entry to modify the name
+ */
+module.exports = function (element, options, translate) {
+
+ options = options || {};
+ var id = options.id || 'name',
+ label = options.label || translate('Name'),
+ modelProperty = options.modelProperty || 'name';
+
+ var nameEntry = entryFactory.textBox({
+ id: id,
+ label: label,
+ modelProperty: modelProperty
+ });
+
+ return [nameEntry];
+};
+
+},{"../../../../factory/EntryFactory":14}],48:[function(require,module,exports){
+'use strict';
+
+var eventDefinitionReference = require('./EventDefinitionReference'),
+ elementReferenceProperty = require('./ElementReferenceProperty');
+
+module.exports = function (group, element, bpmnFactory, signalEventDefinition) {
+
+ group.entries = group.entries.concat(eventDefinitionReference(element, signalEventDefinition, bpmnFactory, {
+ label: 'Signal',
+ elementName: 'signal',
+ elementType: 'bpmn:Signal',
+ referenceProperty: 'signalRef',
+ newElementIdPrefix: 'Signal_'
+ }));
+
+ group.entries = group.entries.concat(elementReferenceProperty(element, signalEventDefinition, bpmnFactory, {
+ id: 'signal-element-name',
+ label: 'Signal Name',
+ referenceProperty: 'signalRef',
+ modelProperty: 'name',
+ shouldValidate: true
+ }));
+};
+
+},{"./ElementReferenceProperty":42,"./EventDefinitionReference":45}],49:[function(require,module,exports){
+'use strict';
+
+var elementHelper = require('../../../../helper/ElementHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+/**
+ * Get the timer definition type for a given timer event definition.
+ *
+ * @param {ModdleElement} timer
+ *
+ * @return {string|undefined} the timer definition type
+ */
+function getTimerDefinitionType(timer) {
+ var timeDate = timer.get('timeDate');
+ if (typeof timeDate !== 'undefined') {
+ return 'timeDate';
+ }
+
+ var timeCycle = timer.get('timeCycle');
+ if (typeof timeCycle !== 'undefined') {
+ return 'timeCycle';
+ }
+
+ var timeDuration = timer.get('timeDuration');
+ if (typeof timeDuration !== 'undefined') {
+ return 'timeDuration';
+ }
+}
+
+/**
+ * Creates 'bpmn:FormalExpression' element.
+ *
+ * @param {ModdleElement} parent
+ * @param {string} body
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {ModdleElement} a formal expression
+ */
+function createFormalExpression(parent, body, bpmnFactory) {
+ body = body || undefined;
+ return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory);
+}
+
+function TimerEventDefinition(group, element, bpmnFactory, timerEventDefinition) {
+
+ var selectOptions = [{ value: 'timeDate', name: 'Date' }, { value: 'timeDuration', name: 'Duration' }, { value: 'timeCycle', name: 'Cycle' }];
+
+ group.entries.push(entryFactory.selectBox({
+ id: 'timer-event-definition-type',
+ label: 'Timer Definition Type',
+ selectOptions: selectOptions,
+ emptyParameter: true,
+ modelProperty: 'timerDefinitionType',
+
+ get: function get(element, node) {
+ return {
+ timerDefinitionType: getTimerDefinitionType(timerEventDefinition) || ''
+ };
+ },
+
+ set: function set(element, values) {
+ var props = {
+ timeDuration: undefined,
+ timeDate: undefined,
+ timeCycle: undefined
+ };
+
+ var newType = values.timerDefinitionType;
+ if (values.timerDefinitionType) {
+ var oldType = getTimerDefinitionType(timerEventDefinition);
+
+ var value;
+ if (oldType) {
+ var definition = timerEventDefinition.get(oldType);
+ value = definition.get('body');
+ }
+
+ props[newType] = createFormalExpression(timerEventDefinition, value, bpmnFactory);
+ }
+
+ return cmdHelper.updateBusinessObject(element, timerEventDefinition, props);
+ }
+
+ }));
+
+ group.entries.push(entryFactory.textField({
+ id: 'timer-event-definition',
+ label: 'Timer Definition',
+ modelProperty: 'timerDefinition',
+
+ get: function get(element, node) {
+ var type = getTimerDefinitionType(timerEventDefinition);
+ var definition = type && timerEventDefinition.get(type);
+ var value = definition && definition.get('body');
+ return {
+ timerDefinition: value
+ };
+ },
+
+ set: function set(element, values) {
+ var type = getTimerDefinitionType(timerEventDefinition);
+ var definition = type && timerEventDefinition.get(type);
+
+ if (definition) {
+ return cmdHelper.updateBusinessObject(element, definition, {
+ body: values.timerDefinition || undefined
+ });
+ }
+ },
+
+ validate: function validate(element) {
+ var type = getTimerDefinitionType(timerEventDefinition);
+ var definition = type && timerEventDefinition.get(type);
+ if (definition) {
+ var value = definition.get('body');
+ if (!value) {
+ return {
+ timerDefinition: 'Must provide a value'
+ };
+ }
+ }
+ },
+
+ hidden: function hidden(element) {
+ return !getTimerDefinitionType(timerEventDefinition);
+ }
+
+ }));
+}
+
+module.exports = TimerEventDefinition;
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25}],50:[function(require,module,exports){
+'use strict';
+
+var inherits = require('inherits');
+
+var PropertiesActivator = require('../../PropertiesActivator');
+
+var asyncCapableHelper = require('../../helper/AsyncCapableHelper'),
+ ImplementationTypeHelper = require('../../helper/ImplementationTypeHelper');
+
+var is = require('bpmn-js/lib/util/ModelUtil').is;
+
+// bpmn properties
+var processProps = require('../bpmn/parts/ProcessProps'),
+ eventProps = require('../bpmn/parts/EventProps'),
+ linkProps = require('../bpmn/parts/LinkProps'),
+ documentationProps = require('../bpmn/parts/DocumentationProps'),
+ idProps = require('../bpmn/parts/IdProps'),
+ nameProps = require('../bpmn/parts/NameProps'),
+ executableProps = require('../bpmn/parts/ExecutableProps');
+
+// camunda properties
+var serviceTaskDelegateProps = require('./parts/ServiceTaskDelegateProps'),
+ userTaskProps = require('./parts/UserTaskProps'),
+ asynchronousContinuationProps = require('./parts/AsynchronousContinuationProps'),
+ callActivityProps = require('./parts/CallActivityProps'),
+ multiInstanceProps = require('./parts/MultiInstanceLoopProps'),
+ sequenceFlowProps = require('./parts/SequenceFlowProps'),
+ scriptProps = require('./parts/ScriptTaskProps'),
+ formProps = require('./parts/FormProps'),
+ startEventInitiator = require('./parts/StartEventInitiator'),
+ variableMapping = require('./parts/VariableMappingProps'),
+ versionTag = require('./parts/VersionTagProps');
+
+var listenerProps = require('./parts/ListenerProps'),
+ listenerDetails = require('./parts/ListenerDetailProps'),
+ listenerFields = require('./parts/ListenerFieldInjectionProps');
+
+var elementTemplateChooserProps = require('./element-templates/parts/ChooserProps'),
+ elementTemplateCustomProps = require('./element-templates/parts/CustomProps');
+
+// Input/Output
+var inputOutput = require('./parts/InputOutputProps'),
+ inputOutputParameter = require('./parts/InputOutputParameterProps');
+
+// Connector
+var connectorDetails = require('./parts/ConnectorDetailProps'),
+ connectorInputOutput = require('./parts/ConnectorInputOutputProps'),
+ connectorInputOutputParameter = require('./parts/ConnectorInputOutputParameterProps');
+
+// properties
+var properties = require('./parts/PropertiesProps');
+
+// job configuration
+var jobConfiguration = require('./parts/JobConfigurationProps');
+
+// history time to live
+var historyTimeToLive = require('./parts/HistoryTimeToLiveProps');
+
+// external task configuration
+var externalTaskConfiguration = require('./parts/ExternalTaskConfigurationProps');
+
+// field injection
+var fieldInjections = require('./parts/FieldInjectionProps');
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ eventDefinitionHelper = require('../../helper/EventDefinitionHelper'),
+ implementationTypeHelper = require('../../helper/ImplementationTypeHelper');
+
+// helpers ////////////////////////////////////////
+
+var isExternalTaskPriorityEnabled = function isExternalTaskPriorityEnabled(element) {
+ var businessObject = getBusinessObject(element);
+
+ // show only if element is a process, a participant ...
+ if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
+ return true;
+ }
+
+ var externalBo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element),
+ isExternalTask = ImplementationTypeHelper.getImplementationType(externalBo) === 'external';
+
+ // ... or an external task with selected external implementation type
+ return !!ImplementationTypeHelper.isExternalCapable(externalBo) && isExternalTask;
+};
+
+var isJobConfigEnabled = function isJobConfigEnabled(element) {
+ var businessObject = getBusinessObject(element);
+
+ if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
+ return true;
+ }
+
+ // async behavior
+ var bo = getBusinessObject(element);
+ if (asyncCapableHelper.isAsyncBefore(bo) || asyncCapableHelper.isAsyncAfter(bo)) {
+ return true;
+ }
+
+ // timer definition
+ if (is(element, 'bpmn:Event')) {
+ return !!eventDefinitionHelper.getTimerEventDefinition(element);
+ }
+
+ return false;
+};
+
+var getInputOutputParameterLabel = function getInputOutputParameterLabel(param, translate) {
+
+ if (is(param, 'camunda:InputParameter')) {
+ return translate('Input Parameter');
+ }
+
+ if (is(param, 'camunda:OutputParameter')) {
+ return translate('Output Parameter');
+ }
+
+ return '';
+};
+
+var getListenerLabel = function getListenerLabel(param, translate) {
+
+ if (is(param, 'camunda:ExecutionListener')) {
+ return translate('Execution Listener');
+ }
+
+ if (is(param, 'camunda:TaskListener')) {
+ return translate('Task Listener');
+ }
+
+ return '';
+};
+
+function createGeneralTabGroups(element, bpmnFactory, elementRegistry, elementTemplates, translate) {
+
+ var generalGroup = {
+ id: 'general',
+ label: translate('General'),
+ entries: []
+ };
+ idProps(generalGroup, element, translate);
+ nameProps(generalGroup, element, translate);
+ processProps(generalGroup, element, translate);
+ versionTag(generalGroup, element, translate);
+ executableProps(generalGroup, element, translate);
+ elementTemplateChooserProps(generalGroup, element, elementTemplates, translate);
+
+ var customFieldsGroups = elementTemplateCustomProps(element, elementTemplates, bpmnFactory, translate);
+
+ var detailsGroup = {
+ id: 'details',
+ label: translate('Details'),
+ entries: []
+ };
+ serviceTaskDelegateProps(detailsGroup, element, bpmnFactory, translate);
+ userTaskProps(detailsGroup, element, translate);
+ scriptProps(detailsGroup, element, bpmnFactory, translate);
+ linkProps(detailsGroup, element, translate);
+ callActivityProps(detailsGroup, element, bpmnFactory, translate);
+ eventProps(detailsGroup, element, bpmnFactory, elementRegistry, translate);
+ sequenceFlowProps(detailsGroup, element, bpmnFactory, translate);
+ startEventInitiator(detailsGroup, element, translate); // this must be the last element of the details group!
+
+ var multiInstanceGroup = {
+ id: 'multiInstance',
+ label: translate('Multi Instance'),
+ entries: []
+ };
+ multiInstanceProps(multiInstanceGroup, element, bpmnFactory, translate);
+
+ var asyncGroup = {
+ id: 'async',
+ label: translate('Asynchronous Continuations'),
+ entries: []
+ };
+ asynchronousContinuationProps(asyncGroup, element, bpmnFactory, translate);
+
+ var jobConfigurationGroup = {
+ id: 'jobConfiguration',
+ label: translate('Job Configuration'),
+ entries: [],
+ enabled: isJobConfigEnabled
+ };
+ jobConfiguration(jobConfigurationGroup, element, bpmnFactory, translate);
+
+ var externalTaskGroup = {
+ id: 'externalTaskConfiguration',
+ label: translate('External Task Configuration'),
+ entries: [],
+ enabled: isExternalTaskPriorityEnabled
+ };
+ externalTaskConfiguration(externalTaskGroup, element, bpmnFactory, translate);
+
+ var documentationGroup = {
+ id: 'documentation',
+ label: translate('Documentation'),
+ entries: []
+ };
+ documentationProps(documentationGroup, element, bpmnFactory, translate);
+
+ var historyTimeToLiveGroup = {
+ id: 'historyConfiguration',
+ label: translate('History Configuration'),
+ entries: []
+ };
+ historyTimeToLive(historyTimeToLiveGroup, element, bpmnFactory, translate);
+
+ var groups = [];
+ groups.push(generalGroup);
+ customFieldsGroups.forEach(function (group) {
+ groups.push(group);
+ });
+ groups.push(detailsGroup);
+ groups.push(externalTaskGroup);
+ groups.push(multiInstanceGroup);
+ groups.push(asyncGroup);
+ groups.push(jobConfigurationGroup);
+ groups.push(documentationGroup);
+ groups.push(historyTimeToLiveGroup);
+
+ return groups;
+}
+
+function createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate) {
+ var variablesGroup = {
+ id: 'variables',
+ label: translate('Variables'),
+ entries: []
+ };
+ variableMapping(variablesGroup, element, bpmnFactory, translate);
+
+ return [variablesGroup];
+}
+
+function createFormsTabGroups(element, bpmnFactory, elementRegistry, translate) {
+ var formGroup = {
+ id: 'forms',
+ label: translate('Forms'),
+ entries: []
+ };
+ formProps(formGroup, element, bpmnFactory, translate);
+
+ return [formGroup];
+}
+
+function createListenersTabGroups(element, bpmnFactory, elementRegistry, translate) {
+
+ var listenersGroup = {
+ id: 'listeners',
+ label: translate('Listeners'),
+ entries: []
+ };
+
+ var options = listenerProps(listenersGroup, element, bpmnFactory, translate);
+
+ var listenerDetailsGroup = {
+ id: 'listener-details',
+ entries: [],
+ enabled: function enabled(element, node) {
+ return options.getSelectedListener(element, node);
+ },
+ label: function label(element, node) {
+ var param = options.getSelectedListener(element, node);
+ return getListenerLabel(param, translate);
+ }
+ };
+
+ listenerDetails(listenerDetailsGroup, element, bpmnFactory, options, translate);
+
+ var listenerFieldsGroup = {
+ id: 'listener-fields',
+ label: translate('Field Injection'),
+ entries: [],
+ enabled: function enabled(element, node) {
+ return options.getSelectedListener(element, node);
+ }
+ };
+
+ listenerFields(listenerFieldsGroup, element, bpmnFactory, options, translate);
+
+ return [listenersGroup, listenerDetailsGroup, listenerFieldsGroup];
+}
+
+function createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate) {
+
+ var inputOutputGroup = {
+ id: 'input-output',
+ label: translate('Parameters'),
+ entries: []
+ };
+
+ var options = inputOutput(inputOutputGroup, element, bpmnFactory, translate);
+
+ var inputOutputParameterGroup = {
+ id: 'input-output-parameter',
+ entries: [],
+ enabled: function enabled(element, node) {
+ return options.getSelectedParameter(element, node);
+ },
+ label: function label(element, node) {
+ var param = options.getSelectedParameter(element, node);
+ return getInputOutputParameterLabel(param, translate);
+ }
+ };
+
+ inputOutputParameter(inputOutputParameterGroup, element, bpmnFactory, options, translate);
+
+ return [inputOutputGroup, inputOutputParameterGroup];
+}
+
+function createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate) {
+ var connectorDetailsGroup = {
+ id: 'connector-details',
+ label: translate('Details'),
+ entries: []
+ };
+
+ connectorDetails(connectorDetailsGroup, element, bpmnFactory, translate);
+
+ var connectorInputOutputGroup = {
+ id: 'connector-input-output',
+ label: translate('Input/Output'),
+ entries: []
+ };
+
+ var options = connectorInputOutput(connectorInputOutputGroup, element, bpmnFactory, translate);
+
+ var connectorInputOutputParameterGroup = {
+ id: 'connector-input-output-parameter',
+ entries: [],
+ enabled: function enabled(element, node) {
+ return options.getSelectedParameter(element, node);
+ },
+ label: function label(element, node) {
+ var param = options.getSelectedParameter(element, node);
+ return getInputOutputParameterLabel(param, translate);
+ }
+ };
+
+ connectorInputOutputParameter(connectorInputOutputParameterGroup, element, bpmnFactory, options, translate);
+
+ return [connectorDetailsGroup, connectorInputOutputGroup, connectorInputOutputParameterGroup];
+}
+
+function createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate) {
+
+ var fieldGroup = {
+ id: 'field-injections-properties',
+ label: translate('Field Injections'),
+ entries: []
+ };
+
+ fieldInjections(fieldGroup, element, bpmnFactory, translate);
+
+ return [fieldGroup];
+}
+
+function createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate) {
+
+ var propertiesGroup = {
+ id: 'extensionElements-properties',
+ label: translate('Properties'),
+ entries: []
+ };
+ properties(propertiesGroup, element, bpmnFactory, translate);
+
+ return [propertiesGroup];
+}
+
+// Camunda Properties Provider /////////////////////////////////////
+
+
+/**
+ * A properties provider for Camunda related properties.
+ *
+ * @param {EventBus} eventBus
+ * @param {BpmnFactory} bpmnFactory
+ * @param {ElementRegistry} elementRegistry
+ * @param {ElementTemplates} elementTemplates
+ */
+function CamundaPropertiesProvider(eventBus, bpmnFactory, elementRegistry, elementTemplates, translate) {
+
+ PropertiesActivator.call(this, eventBus);
+
+ this.getTabs = function (element) {
+
+ var generalTab = {
+ id: 'general',
+ label: translate('General'),
+ groups: createGeneralTabGroups(element, bpmnFactory, elementRegistry, elementTemplates, translate)
+ };
+
+ var variablesTab = {
+ id: 'variables',
+ label: translate('Variables'),
+ groups: createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate)
+ };
+
+ var formsTab = {
+ id: 'forms',
+ label: translate('Forms'),
+ groups: createFormsTabGroups(element, bpmnFactory, elementRegistry, translate)
+ };
+
+ var listenersTab = {
+ id: 'listeners',
+ label: translate('Listeners'),
+ groups: createListenersTabGroups(element, bpmnFactory, elementRegistry, translate),
+ enabled: function enabled(element) {
+ return !eventDefinitionHelper.getLinkEventDefinition(element) || !is(element, 'bpmn:IntermediateThrowEvent') && eventDefinitionHelper.getLinkEventDefinition(element);
+ }
+ };
+
+ var inputOutputTab = {
+ id: 'input-output',
+ label: translate('Input/Output'),
+ groups: createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate)
+ };
+
+ var connectorTab = {
+ id: 'connector',
+ label: translate('Connector'),
+ groups: createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate),
+ enabled: function enabled(element) {
+ var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element);
+ return bo && implementationTypeHelper.getImplementationType(bo) === 'connector';
+ }
+ };
+
+ var fieldInjectionsTab = {
+ id: 'field-injections',
+ label: translate('Field Injections'),
+ groups: createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate)
+ };
+
+ var extensionsTab = {
+ id: 'extensionElements',
+ label: translate('Extensions'),
+ groups: createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate)
+ };
+
+ return [generalTab, variablesTab, connectorTab, formsTab, listenersTab, inputOutputTab, fieldInjectionsTab, extensionsTab];
+ };
+}
+
+CamundaPropertiesProvider.$inject = ['eventBus', 'bpmnFactory', 'elementRegistry', 'elementTemplates', 'translate'];
+
+inherits(CamundaPropertiesProvider, PropertiesActivator);
+
+module.exports = CamundaPropertiesProvider;
+
+},{"../../PropertiesActivator":3,"../../helper/AsyncCapableHelper":23,"../../helper/EventDefinitionHelper":26,"../../helper/ImplementationTypeHelper":29,"../bpmn/parts/DocumentationProps":33,"../bpmn/parts/EventProps":34,"../bpmn/parts/ExecutableProps":35,"../bpmn/parts/IdProps":36,"../bpmn/parts/LinkProps":37,"../bpmn/parts/NameProps":38,"../bpmn/parts/ProcessProps":39,"./element-templates/parts/ChooserProps":60,"./element-templates/parts/CustomProps":61,"./parts/AsynchronousContinuationProps":63,"./parts/CallActivityProps":64,"./parts/ConnectorDetailProps":65,"./parts/ConnectorInputOutputParameterProps":66,"./parts/ConnectorInputOutputProps":67,"./parts/ExternalTaskConfigurationProps":68,"./parts/FieldInjectionProps":69,"./parts/FormProps":70,"./parts/HistoryTimeToLiveProps":71,"./parts/InputOutputParameterProps":72,"./parts/InputOutputProps":73,"./parts/JobConfigurationProps":74,"./parts/ListenerDetailProps":75,"./parts/ListenerFieldInjectionProps":76,"./parts/ListenerProps":77,"./parts/MultiInstanceLoopProps":78,"./parts/PropertiesProps":79,"./parts/ScriptTaskProps":80,"./parts/SequenceFlowProps":81,"./parts/ServiceTaskDelegateProps":82,"./parts/StartEventInitiator":83,"./parts/UserTaskProps":84,"./parts/VariableMappingProps":85,"./parts/VersionTagProps":86,"bpmn-js/lib/util/ModelUtil":216,"inherits":415}],51:[function(require,module,exports){
+'use strict';
+
+var assign = require('lodash/object/assign');
+
+/**
+ * Create an input parameter representing the given
+ * binding and value.
+ *
+ * @param {PropertyBinding} binding
+ * @param {String} value
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {ModdleElement}
+ */
+function createInputParameter(binding, value, bpmnFactory) {
+ var scriptFormat = binding.scriptFormat,
+ parameterValue,
+ parameterDefinition;
+
+ if (scriptFormat) {
+ parameterDefinition = bpmnFactory.create('camunda:Script', {
+ scriptFormat: scriptFormat,
+ value: value
+ });
+ } else {
+ parameterValue = value;
+ }
+
+ return bpmnFactory.create('camunda:InputParameter', {
+ name: binding.name,
+ value: parameterValue,
+ definition: parameterDefinition
+ });
+}
+
+module.exports.createInputParameter = createInputParameter;
+
+/**
+ * Create an output parameter representing the given
+ * binding and value.
+ *
+ * @param {PropertyBinding} binding
+ * @param {String} value
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {ModdleElement}
+ */
+function createOutputParameter(binding, value, bpmnFactory) {
+ var scriptFormat = binding.scriptFormat,
+ parameterValue,
+ parameterDefinition;
+
+ if (scriptFormat) {
+ parameterDefinition = bpmnFactory.create('camunda:Script', {
+ scriptFormat: scriptFormat,
+ value: binding.source
+ });
+ } else {
+ parameterValue = binding.source;
+ }
+
+ return bpmnFactory.create('camunda:OutputParameter', {
+ name: value,
+ value: parameterValue,
+ definition: parameterDefinition
+ });
+}
+
+module.exports.createOutputParameter = createOutputParameter;
+
+/**
+ * Create camunda property from the given binding.
+ *
+ * @param {PropertyBinding} binding
+ * @param {String} value
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {ModdleElement}
+ */
+function createCamundaProperty(binding, value, bpmnFactory) {
+ return bpmnFactory.create('camunda:Property', {
+ name: binding.name,
+ value: value || ''
+ });
+}
+
+module.exports.createCamundaProperty = createCamundaProperty;
+
+/**
+ * Create camunda:in element from given binding.
+ *
+ * @param {PropertyBinding} binding
+ * @param {String} value
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {ModdleElement}
+ */
+function createCamundaIn(binding, value, bpmnFactory) {
+
+ var properties = createCamundaInOutAttrs(binding, value);
+
+ return bpmnFactory.create('camunda:In', properties);
+}
+
+module.exports.createCamundaIn = createCamundaIn;
+
+/**
+ * Create camunda:in with businessKey element from given binding.
+ *
+ * @param {PropertyBinding} binding
+ * @param {String} value
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {ModdleElement}
+ */
+function createCamundaInWithBusinessKey(binding, value, bpmnFactory) {
+ return bpmnFactory.create('camunda:In', {
+ businessKey: value
+ });
+}
+
+module.exports.createCamundaInWithBusinessKey = createCamundaInWithBusinessKey;
+
+/**
+ * Create camunda:out element from given binding.
+ *
+ * @param {PropertyBinding} binding
+ * @param {String} value
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {ModdleElement}
+ */
+function createCamundaOut(binding, value, bpmnFactory) {
+ var properties = createCamundaInOutAttrs(binding, value);
+
+ return bpmnFactory.create('camunda:Out', properties);
+}
+
+module.exports.createCamundaOut = createCamundaOut;
+
+/**
+ * Create camunda:executionListener element containing an inline script from given binding.
+ *
+ * @param {PropertyBinding} binding
+ * @param {String} value
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {ModdleElement}
+ */
+function createCamundaExecutionListenerScript(binding, value, bpmnFactory) {
+ var scriptFormat = binding.scriptFormat,
+ parameterValue,
+ parameterDefinition;
+
+ if (scriptFormat) {
+ parameterDefinition = bpmnFactory.create('camunda:Script', {
+ scriptFormat: scriptFormat,
+ value: value
+ });
+ } else {
+ parameterValue = value;
+ }
+
+ return bpmnFactory.create('camunda:ExecutionListener', {
+ event: binding.event,
+ value: parameterValue,
+ script: parameterDefinition
+ });
+}
+
+module.exports.createCamundaExecutionListenerScript = createCamundaExecutionListenerScript;
+
+/**
+ * Create camunda:field element containing string or expression from given binding.
+ *
+ * @param {PropertyBinding} binding
+ * @param {String} value
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {ModdleElement}
+ */
+function createCamundaFieldInjection(binding, value, bpmnFactory) {
+ var DEFAULT_PROPS = {
+ 'string': undefined,
+ 'expression': undefined,
+ 'name': undefined
+ };
+
+ var props = assign({}, DEFAULT_PROPS);
+
+ if (!binding.expression) {
+ props.string = value;
+ } else {
+ props.expression = value;
+ }
+ props.name = binding.name;
+
+ return bpmnFactory.create('camunda:Field', props);
+}
+module.exports.createCamundaFieldInjection = createCamundaFieldInjection;
+
+/////////// helpers ////////////////////////////
+
+/**
+ * Create properties for camunda:in and camunda:out types.
+ */
+function createCamundaInOutAttrs(binding, value) {
+
+ var properties = {};
+
+ // camunda:in source(Expression) target
+ if (binding.target) {
+
+ properties.target = binding.target;
+
+ if (binding.expression) {
+ properties.sourceExpression = value;
+ } else {
+ properties.source = value;
+ }
+ } else
+
+ // camunda:(in|out) variables local
+ if (binding.variables) {
+ properties.variables = 'all';
+
+ if (binding.variables === 'local') {
+ properties.local = true;
+ }
+ }
+
+ // camunda:out source(Expression) target
+ else {
+ properties.target = value;
+
+ ['source', 'sourceExpression'].forEach(function (k) {
+ if (binding[k]) {
+ properties[k] = binding[k];
+ }
+ });
+ }
+
+ return properties;
+}
+
+},{"lodash/object/assign":496}],52:[function(require,module,exports){
+'use strict';
+
+var inherits = require('inherits');
+
+var getTemplate = require('./Helper').getTemplate;
+
+var PropertiesActivator = require('../../../PropertiesActivator');
+
+var HIGHER_PRIORITY = 1100;
+
+/**
+ * Applies template visibility settings.
+ *
+ * Controlled using `entriesVisible` on template config object:
+ *
+ * ```json
+ * "entriesVisible": {
+ * "_all": true|false,
+ * "entryName": true|false,
+ * ...
+ * }
+ * ```
+ *
+ * @param {EventBus} eventBus
+ * @param {ElementTemplates} elementTemplates
+ */
+function CustomElementsPropertiesActivator(eventBus, elementTemplates) {
+ PropertiesActivator.call(this, eventBus, HIGHER_PRIORITY);
+
+ this.isEntryVisible = function (entry, element) {
+
+ var template = getTemplate(element, elementTemplates);
+
+ if (template && !isEntryVisible(entry, template)) {
+ return false;
+ }
+ };
+
+ this.isPropertyEditable = function (entry, propertyName, element) {
+
+ var template = getTemplate(element, elementTemplates);
+
+ if (template && !isEntryEditable(entry, template)) {
+ return false;
+ }
+ };
+}
+
+CustomElementsPropertiesActivator.$inject = ['eventBus', 'elementTemplates'];
+
+inherits(CustomElementsPropertiesActivator, PropertiesActivator);
+
+module.exports = CustomElementsPropertiesActivator;
+
+////// helpers ////////////////////////////////////
+
+
+var CUSTOM_PROPERTIES_PATTERN = /^custom-/;
+
+var DEFAULT_ENTRIES_VISIBLE = {
+ _all: false,
+ id: true,
+ name: true
+};
+
+function isCustomEntry(entry) {
+ return CUSTOM_PROPERTIES_PATTERN.test(entry.id);
+}
+
+function isEntryVisible(entry, template) {
+
+ var entryId = entry.id;
+
+ if (entryId === 'elementTemplate-chooser' || isCustomEntry(entry)) {
+ return true;
+ }
+
+ var entriesVisible = template.entriesVisible || DEFAULT_ENTRIES_VISIBLE;
+
+ if (typeof entriesVisible === 'boolean') {
+ return entriesVisible;
+ }
+
+ var defaultVisible = entriesVisible._all || false,
+ entryVisible = entriesVisible[entryId];
+
+ // d = true, e = false => false
+ // d = false, e = true => true
+ // d = false, e = false
+ return defaultVisible === true && entryVisible !== false || defaultVisible === false && entryVisible === true;
+}
+
+function isEntryEditable(entry, template) {
+
+ var property;
+
+ if (isCustomEntry(entry)) {
+ property = getProperty(template, entry);
+
+ return property && property.editable !== false;
+ }
+
+ return true;
+}
+
+function getProperty(template, entry) {
+
+ var index;
+ var idx = entry.id.replace('custom-' + template.id + '-', '');
+ if (idx.indexOf('-') !== -1) {
+ var indexes = idx.split('-');
+ if (indexes.length == 2) {
+ var scopeName = indexes[0].replace(/_/g, ':');
+ index = parseInt(indexes[1], 10);
+ if (scopeName && !isNaN(index)) {
+ return template.scopes[scopeName].properties[index];
+ }
+ }
+ } else {
+ index = parseInt(idx, 10);
+ if (!isNaN(index)) {
+ return template.properties[index];
+ }
+ }
+
+ throw new Error('cannot extract property index for entry <' + entry.id + '>');
+}
+
+},{"../../../PropertiesActivator":3,"./Helper":55,"inherits":415}],53:[function(require,module,exports){
+'use strict';
+
+var values = require('lodash/object/values');
+
+/**
+ * The guy knowing all configured element templates.
+ *
+ * This registry won't validate. Use the {@link Validator}
+ * to verify a template is valid prior to adding it to
+ * this registry.
+ */
+function ElementTemplates() {
+
+ this._templates = {};
+
+ /**
+ * Sets the known element templates.
+ *
+ * @param {Array} descriptors
+ *
+ * @return {ElementTemplates}
+ */
+ this.set = function (descriptors) {
+
+ var templates = this._templates = {};
+
+ descriptors.forEach(function (descriptor) {
+ templates[descriptor.id] = descriptor;
+ });
+
+ return this;
+ };
+
+ /**
+ * Get template descriptor with given id.
+ *
+ * @param {String} id
+ *
+ * @return {TemplateDescriptor}
+ */
+ this.get = function (id) {
+ return this._templates[id];
+ };
+
+ /**
+ * Return all known template descriptors.
+ *
+ * @return {Array}
+ */
+ this.getAll = function () {
+ return values(this._templates);
+ };
+}
+
+module.exports = ElementTemplates;
+
+},{"lodash/object/values":502}],54:[function(require,module,exports){
+'use strict';
+
+var Validator = require('./Validator');
+
+/**
+ * The guy responsible for template loading.
+ *
+ * Provide the actual templates via the `config.elementTemplates`.
+ *
+ * That configuration can either be an array of template
+ * descriptors or a node style callback to retrieve
+ * the templates asynchronously.
+ *
+ * @param {Array|Function} loadTemplates
+ * @param {EventBus} eventBus
+ * @param {ElementTemplates} elementTemplates
+ */
+function ElementTemplatesLoader(loadTemplates, eventBus, elementTemplates) {
+ this._loadTemplates = loadTemplates;
+ this._eventBus = eventBus;
+ this._elementTemplates = elementTemplates;
+
+ var self = this;
+
+ eventBus.on('diagram.init', function () {
+ self.reload();
+ });
+}
+
+module.exports = ElementTemplatesLoader;
+
+ElementTemplatesLoader.$inject = ['config.elementTemplates', 'eventBus', 'elementTemplates'];
+
+ElementTemplatesLoader.prototype.reload = function () {
+
+ var self = this;
+
+ var loadTemplates = this._loadTemplates;
+
+ // no templates specified
+ if (typeof loadTemplates === 'undefined') {
+ return;
+ }
+
+ // template loader function specified
+ if (typeof loadTemplates === 'function') {
+
+ return loadTemplates(function (err, templates) {
+
+ if (err) {
+ return self.templateErrors([err]);
+ }
+
+ self.setTemplates(templates);
+ });
+ }
+
+ // templates array specified
+ if (loadTemplates.length) {
+ return this.setTemplates(loadTemplates);
+ }
+};
+
+ElementTemplatesLoader.prototype.setTemplates = function (templates) {
+
+ var elementTemplates = this._elementTemplates;
+
+ var validator = new Validator().addAll(templates);
+
+ var errors = validator.getErrors(),
+ validTemplates = validator.getValidTemplates();
+
+ elementTemplates.set(validTemplates);
+
+ if (errors.length) {
+ this.templateErrors(errors);
+ }
+
+ this.templatesChanged();
+};
+
+ElementTemplatesLoader.prototype.templatesChanged = function () {
+ this._eventBus.fire('elementTemplates.changed');
+};
+
+ElementTemplatesLoader.prototype.templateErrors = function (errors) {
+ this._eventBus.fire('elementTemplates.errors', {
+ errors: errors
+ });
+};
+
+},{"./Validator":56}],55:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny;
+
+var find = require('lodash/collection/find');
+
+var TEMPLATE_ATTR = 'camunda:modelerTemplate';
+
+/**
+ * The BPMN 2.0 extension attribute name under
+ * which the element template is stored.
+ *
+ * @type {String}
+ */
+module.exports.TEMPLATE_ATTR = TEMPLATE_ATTR;
+
+/**
+ * Get template id for a given diagram element.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {String}
+ */
+function getTemplateId(element) {
+
+ var bo = getBusinessObject(element);
+
+ if (bo) {
+ return bo.get(TEMPLATE_ATTR);
+ }
+}
+
+module.exports.getTemplateId = getTemplateId;
+
+/**
+ * Get template of a given element.
+ *
+ * @param {Element} element
+ * @param {ElementTemplates} elementTemplates
+ *
+ * @return {TemplateDefinition}
+ */
+function getTemplate(element, elementTemplates) {
+ var id = getTemplateId(element);
+
+ return id && elementTemplates.get(id);
+}
+
+module.exports.getTemplate = getTemplate;
+
+/**
+ * Get default template for a given element.
+ *
+ * @param {Element} element
+ * @param {ElementTemplates} elementTemplates
+ *
+ * @return {TemplateDefinition}
+ */
+function getDefaultTemplate(element, elementTemplates) {
+
+ // return first default template, if any exists
+ return elementTemplates.getAll().filter(function (t) {
+ return isAny(element, t.appliesTo) && t.isDefault;
+ })[0];
+}
+
+module.exports.getDefaultTemplate = getDefaultTemplate;
+
+/**
+ * Find extension with given type in
+ * BPMN element, diagram element or ExtensionElement.
+ *
+ * @param {ModdleElement|djs.model.Base} element
+ * @param {String} type
+ *
+ * @return {ModdleElement} the extension
+ */
+function findExtension(element, type) {
+ var bo = getBusinessObject(element);
+
+ var extensionElements;
+
+ if (is(bo, 'bpmn:ExtensionElements')) {
+ extensionElements = bo;
+ } else {
+ extensionElements = bo.extensionElements;
+ }
+
+ if (!extensionElements) {
+ return null;
+ }
+
+ return find(extensionElements.get('values'), function (e) {
+ return is(e, type);
+ });
+}
+
+module.exports.findExtension = findExtension;
+
+function findExtensions(element, types) {
+ var extensionElements = getExtensionElements(element);
+
+ if (!extensionElements) {
+ return [];
+ }
+
+ return extensionElements.get('values').filter(function (e) {
+ return isAny(e, types);
+ });
+}
+
+module.exports.findExtensions = findExtensions;
+
+function findCamundaInOut(element, binding) {
+
+ var extensionElements = getExtensionElements(element);
+
+ if (!extensionElements) {
+ return;
+ }
+
+ var matcher;
+
+ if (binding.type === 'camunda:in') {
+ matcher = function matcher(e) {
+ return is(e, 'camunda:In') && isInOut(e, binding);
+ };
+ } else if (binding.type === 'camunda:out') {
+ matcher = function matcher(e) {
+ return is(e, 'camunda:Out') && isInOut(e, binding);
+ };
+ } else if (binding.type === 'camunda:in:businessKey') {
+ matcher = function matcher(e) {
+ return is(e, 'camunda:In') && 'businessKey' in e;
+ };
+ }
+
+ return find(extensionElements.get('values'), matcher);
+}
+
+module.exports.findCamundaInOut = findCamundaInOut;
+
+function findCamundaProperty(camundaProperties, binding) {
+ return find(camundaProperties.get('values'), function (p) {
+ return p.name === binding.name;
+ });
+}
+
+module.exports.findCamundaProperty = findCamundaProperty;
+
+function findInputParameter(inputOutput, binding) {
+ var parameters = inputOutput.get('inputParameters');
+
+ return find(parameters, function (p) {
+ return p.name === binding.name;
+ });
+}
+
+module.exports.findInputParameter = findInputParameter;
+
+function findOutputParameter(inputOutput, binding) {
+ var parameters = inputOutput.get('outputParameters');
+
+ return find(parameters, function (p) {
+ var value = p.value;
+
+ if (!binding.scriptFormat) {
+ return value === binding.source;
+ }
+
+ var definition = p.definition;
+
+ if (!definition || binding.scriptFormat !== definition.scriptFormat) {
+ return false;
+ }
+
+ return definition.value === binding.source;
+ });
+}
+
+module.exports.findOutputParameter = findOutputParameter;
+
+//////// helpers /////////////////////////////////
+
+function getExtensionElements(element) {
+ var bo = getBusinessObject(element);
+
+ if (is(bo, 'bpmn:ExtensionElements')) {
+ return bo;
+ } else {
+ return bo.extensionElements;
+ }
+}
+
+function isInOut(element, binding) {
+
+ if (binding.type === 'camunda:in') {
+ // find based on target attribute
+ if (binding.target) {
+ return element.target === binding.target;
+ }
+ }
+
+ if (binding.type === 'camunda:out') {
+ // find based on source / sourceExpression
+ if (binding.source) {
+ return element.source === binding.source;
+ }
+
+ if (binding.sourceExpression) {
+ return element.sourceExpression === binding.sourceExpression;
+ }
+ }
+
+ // find based variables / local combination
+ if (binding.variables) {
+ return element.variables === 'all' && (binding.variables !== 'local' || element.local);
+ }
+}
+
+},{"bpmn-js/lib/features/modeling/util/ModelingUtil":189,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/find":421}],56:[function(require,module,exports){
+'use strict';
+
+var isArray = require('lodash/lang/isArray');
+var isObject = require('lodash/lang/isObject');
+
+var DROPDOWN_TYPE = 'Dropdown';
+
+var VALID_TYPES = ['String', 'Text', 'Boolean', 'Hidden', DROPDOWN_TYPE];
+
+var PROPERTY_TYPE = 'property',
+ CAMUNDA_PROPERTY_TYPE = 'camunda:property',
+ CAMUNDA_INPUT_PARAMETER_TYPE = 'camunda:inputParameter',
+ CAMUNDA_OUTPUT_PARAMETER_TYPE = 'camunda:outputParameter',
+ CAMUNDA_IN_TYPE = 'camunda:in',
+ CAMUNDA_OUT_TYPE = 'camunda:out',
+ CAMUNDA_IN_BUSINESS_KEY_TYPE = 'camunda:in:businessKey',
+ CAMUNDA_EXECUTION_LISTENER = 'camunda:executionListener',
+ CAMUNDA_FIELD = 'camunda:field';
+
+var VALID_BINDING_TYPES = [PROPERTY_TYPE, CAMUNDA_PROPERTY_TYPE, CAMUNDA_INPUT_PARAMETER_TYPE, CAMUNDA_OUTPUT_PARAMETER_TYPE, CAMUNDA_IN_TYPE, CAMUNDA_OUT_TYPE, CAMUNDA_IN_BUSINESS_KEY_TYPE, CAMUNDA_EXECUTION_LISTENER, CAMUNDA_FIELD];
+
+/**
+ * A element template validator.
+ */
+function Validator() {
+
+ this._templatesById = {};
+
+ this._validTemplates = [];
+ this._errors = [];
+
+ /**
+ * Adds the templates.
+ *
+ * @param {Array} templates
+ *
+ * @return {Validator} self
+ */
+ this.addAll = function (templates) {
+
+ if (!isArray(templates)) {
+ this._logError('templates must be []');
+ } else {
+ templates.forEach(this.add, this);
+ }
+
+ return this;
+ };
+
+ /**
+ * Add the given element template, if it is valid.
+ *
+ * @param {TemplateDescriptor} template
+ *
+ * @return {Validator} self
+ */
+ this.add = function (template) {
+
+ var err = this._validateTemplate(template);
+
+ if (!err) {
+ this._templatesById[template.id] = template;
+
+ this._validTemplates.push(template);
+ }
+
+ return this;
+ };
+
+ /**
+ * Validate given template and return error (if any).
+ *
+ * @param {TemplateDescriptor} template
+ *
+ * @return {Error} validation error, if any
+ */
+ this._validateTemplate = function (template) {
+
+ var err,
+ id = template.id,
+ appliesTo = template.appliesTo,
+ properties = template.properties,
+ scopes = template.scopes;
+
+ if (!id) {
+ return this._logError('missing template id');
+ }
+
+ if (id in this._templatesById) {
+ return this._logError('template id <' + id + '> already used');
+ }
+
+ if (!isArray(appliesTo)) {
+ err = this._logError('missing appliesTo=[]', template);
+ }
+
+ if (!isArray(properties)) {
+ err = this._logError('missing properties=[]', template);
+ } else {
+ if (!this._validateProperties(properties)) {
+ err = new Error('invalid properties');
+ }
+ }
+
+ if (scopes) {
+ err = this._validateScopes(template, scopes);
+ }
+
+ return err;
+ };
+
+ this._validateScopes = function (template, scopes) {
+
+ var err, scope, scopeName;
+
+ if (!isObject(scopes) || isArray(scopes)) {
+ return this._logError('invalid scopes, should be scopes={}', template);
+ }
+
+ for (scopeName in scopes) {
+ scope = scopes[scopeName];
+
+ if (!isObject(scope) || isArray(scope)) {
+ err = this._logError('invalid scope, should be scope={}', template);
+ }
+
+ if (!isArray(scope.properties)) {
+ err = this._logError('missing properties=[] in scope <' + scopeName + '>', template);
+ } else {
+ if (!this._validateProperties(scope.properties)) {
+ err = new Error('invalid properties in scope <' + scopeName + '>');
+ }
+ }
+ }
+
+ return err;
+ };
+
+ /**
+ * Validate properties and return false if any is invalid.
+ *
+ * @param {Array} properties
+ *
+ * @return {Boolean} true if all properties are valid
+ */
+ this._validateProperties = function (properties) {
+ var validProperties = properties.filter(this._validateProperty, this);
+
+ return properties.length === validProperties.length;
+ };
+
+ /**
+ * Validate property and return false, if there was
+ * a validation error.
+ *
+ * @param {PropertyDescriptor} property
+ *
+ * @return {Boolean} true if property is valid
+ */
+ this._validateProperty = function (property) {
+
+ var type = property.type,
+ binding = property.binding;
+
+ var err;
+
+ var bindingType = binding.type;
+
+ if (VALID_TYPES.indexOf(type) === -1) {
+ err = this._logError('invalid property type <' + type + '>; ' + 'must be any of { ' + VALID_TYPES.join(', ') + ' }');
+ }
+
+ if (type === DROPDOWN_TYPE && bindingType !== CAMUNDA_EXECUTION_LISTENER) {
+ if (!isArray(property.choices)) {
+ err = this._logError('must provide choices=[] with ' + DROPDOWN_TYPE + ' type');
+ } else if (!property.choices.every(isDropdownChoiceValid)) {
+ err = this._logError('{ name, value } must be specified for ' + DROPDOWN_TYPE + ' choices');
+ }
+ }
+
+ if (!binding) {
+ return this._logError('property missing binding');
+ }
+
+ if (VALID_BINDING_TYPES.indexOf(bindingType) === -1) {
+ err = this._logError('invalid property.binding type <' + bindingType + '>; ' + 'must be any of { ' + VALID_BINDING_TYPES.join(', ') + ' }');
+ }
+
+ if (bindingType === PROPERTY_TYPE || bindingType === CAMUNDA_PROPERTY_TYPE || bindingType === CAMUNDA_INPUT_PARAMETER_TYPE || bindingType === CAMUNDA_FIELD) {
+
+ if (!binding.name) {
+ err = this._logError('property.binding <' + bindingType + '> requires name');
+ }
+ }
+
+ if (bindingType === CAMUNDA_OUTPUT_PARAMETER_TYPE) {
+ if (!binding.source) {
+ err = this._logError('property.binding <' + bindingType + '> requires source');
+ }
+ }
+
+ if (bindingType === CAMUNDA_IN_TYPE) {
+
+ if (!binding.variables && !binding.target) {
+ err = this._logError('property.binding <' + bindingType + '> requires ' + 'variables or target');
+ }
+ }
+
+ if (bindingType === CAMUNDA_OUT_TYPE) {
+
+ if (!binding.variables && !binding.source && !binding.sourceExpression) {
+ err = this._logError('property.binding <' + bindingType + '> requires ' + 'variables, sourceExpression or source');
+ }
+ }
+
+ if (bindingType === CAMUNDA_EXECUTION_LISTENER) {
+
+ if (type !== 'Hidden') {
+ err = this._logError('invalid property type <' + type + '> for ' + CAMUNDA_EXECUTION_LISTENER + '; ' + 'must be ');
+ }
+ }
+
+ return !err;
+ };
+
+ this._logError = function (err, template) {
+
+ if (typeof err === 'string') {
+ if (template) {
+ err = 'template(id: ' + template.id + ') ' + err;
+ }
+
+ err = new Error(err);
+ }
+
+ this._errors.push(err);
+
+ return err;
+ };
+
+ this.getErrors = function () {
+ return this._errors;
+ };
+
+ this.getValidTemplates = function () {
+ return this._validTemplates;
+ };
+}
+
+module.exports = Validator;
+
+//////// helpers ///////////////////////////////////
+
+function isDropdownChoiceValid(c) {
+ return 'name' in c && 'value' in c;
+}
+
+},{"lodash/lang/isArray":489,"lodash/lang/isObject":493}],57:[function(require,module,exports){
+'use strict';
+
+var findExtension = require('../Helper').findExtension,
+ findExtensions = require('../Helper').findExtensions;
+
+var createCamundaProperty = require('../CreateHelper').createCamundaProperty,
+ createInputParameter = require('../CreateHelper').createInputParameter,
+ createOutputParameter = require('../CreateHelper').createOutputParameter,
+ createCamundaIn = require('../CreateHelper').createCamundaIn,
+ createCamundaOut = require('../CreateHelper').createCamundaOut,
+ createCamundaInWithBusinessKey = require('../CreateHelper').createCamundaInWithBusinessKey,
+ createCamundaExecutionListenerScript = require('../CreateHelper').createCamundaExecutionListenerScript,
+ createCamundaFieldInjection = require('../CreateHelper').createCamundaFieldInjection;
+
+var forEach = require('lodash/collection/forEach');
+
+var CAMUNDA_SERVICE_TASK_LIKE = ['camunda:class', 'camunda:delegateExpression', 'camunda:expression'];
+
+/**
+ * A handler that changes the modeling template of a BPMN element.
+ */
+function ChangeElementTemplateHandler(modeling, commandStack, bpmnFactory) {
+
+ function getOrCreateExtensionElements(element) {
+
+ var bo = element.businessObject;
+
+ var extensionElements = bo.extensionElements;
+
+ // add extension elements
+ if (!extensionElements) {
+ extensionElements = bpmnFactory.create('bpmn:ExtensionElements', {
+ values: []
+ });
+
+ modeling.updateProperties(element, {
+ extensionElements: extensionElements
+ });
+ }
+
+ return extensionElements;
+ }
+
+ function updateModelerTemplate(element, newTemplate) {
+ modeling.updateProperties(element, {
+ 'camunda:modelerTemplate': newTemplate && newTemplate.id
+ });
+ }
+
+ function updateIoMappings(element, newTemplate, context) {
+
+ var newMappings = createInputOutputMappings(newTemplate, bpmnFactory),
+ oldMappings;
+
+ if (!newMappings) {
+ return;
+ }
+
+ if (context) {
+ commandStack.execute('properties-panel.update-businessobject', {
+ element: element,
+ businessObject: context,
+ properties: { inputOutput: newMappings }
+ });
+ } else {
+ context = getOrCreateExtensionElements(element);
+ oldMappings = findExtension(element, 'camunda:InputOutput');
+ commandStack.execute('properties-panel.update-businessobject-list', {
+ element: element,
+ currentObject: context,
+ propertyName: 'values',
+ objectsToAdd: [newMappings],
+ objectsToRemove: oldMappings ? [oldMappings] : []
+ });
+ }
+ }
+
+ function updateCamundaField(element, newTemplate, context) {
+
+ var newMappings = createCamundaFieldInjections(newTemplate, bpmnFactory),
+ oldMappings;
+
+ if (!newMappings) {
+ return;
+ }
+ if (context) {
+ commandStack.execute('properties-panel.update-businessobject', {
+ element: element,
+ businessObject: context,
+ properties: { field: newMappings }
+ });
+ } else {
+ context = getOrCreateExtensionElements(element);
+ oldMappings = findExtensions(element, ['camunda:Field']);
+
+ commandStack.execute('properties-panel.update-businessobject-list', {
+ element: element,
+ currentObject: context,
+ propertyName: 'values',
+ objectsToAdd: newMappings,
+ objectsToRemove: oldMappings ? oldMappings : []
+ });
+ }
+ }
+
+ function updateCamundaProperties(element, newTemplate, context) {
+
+ var newProperties = createCamundaProperties(newTemplate, bpmnFactory),
+ oldProperties;
+
+ if (!newProperties) {
+ return;
+ }
+
+ if (context) {
+ commandStack.execute('properties-panel.update-businessobject', {
+ element: element,
+ businessObject: context,
+ properties: { properties: newProperties }
+ });
+ } else {
+ context = getOrCreateExtensionElements(element);
+ oldProperties = findExtension(element, 'camunda:Properties');
+
+ commandStack.execute('properties-panel.update-businessobject-list', {
+ element: element,
+ currentObject: context,
+ propertyName: 'values',
+ objectsToAdd: [newProperties],
+ objectsToRemove: oldProperties ? [oldProperties] : []
+ });
+ }
+ }
+
+ function updateProperties(element, newTemplate, context) {
+
+ var newProperties = createBpmnPropertyUpdates(newTemplate, bpmnFactory);
+
+ var newPropertiesCount = Object.keys(newProperties).length;
+
+ if (!newPropertiesCount) {
+ return;
+ }
+
+ if (context) {
+ commandStack.execute('properties-panel.update-businessobject', {
+ element: element,
+ businessObject: context,
+ properties: newProperties
+ });
+ } else {
+ modeling.updateProperties(element, newProperties);
+ }
+ }
+
+ function updateInOut(element, newTemplate, context) {
+
+ var newInOut = createCamundaInOut(newTemplate, bpmnFactory),
+ oldInOut;
+
+ if (!newInOut) {
+ return;
+ }
+
+ if (context) {
+ commandStack.execute('properties-panel.update-businessobject', {
+ element: element,
+ businessObject: context,
+ properties: { inout: newInOut }
+ });
+ } else {
+ context = getOrCreateExtensionElements(element);
+ oldInOut = findExtensions(context, ['camunda:In', 'camunda:Out']);
+
+ commandStack.execute('properties-panel.update-businessobject-list', {
+ element: element,
+ currentObject: context,
+ propertyName: 'values',
+ objectsToAdd: newInOut,
+ objectsToRemove: oldInOut
+ });
+ }
+ }
+
+ function updateExecutionListener(element, newTemplate, context) {
+
+ var newExecutionListeners = createCamundaExecutionListeners(newTemplate, bpmnFactory),
+ oldExecutionsListeners;
+
+ if (!newExecutionListeners.length) {
+ return;
+ }
+
+ if (context) {
+ commandStack.execute('properties-panel.update-businessobject', {
+ element: element,
+ businessObject: context,
+ properties: { executionListener: newExecutionListeners }
+ });
+ } else {
+ context = getOrCreateExtensionElements(element);
+ oldExecutionsListeners = findExtensions(context, ['camunda:ExecutionListener']);
+
+ commandStack.execute('properties-panel.update-businessobject-list', {
+ element: element,
+ currentObject: context,
+ propertyName: 'values',
+ objectsToAdd: newExecutionListeners,
+ objectsToRemove: oldExecutionsListeners
+ });
+ }
+ }
+
+ /**
+ * Update / recreate a scoped element.
+ *
+ * @param {djs.model.Base} element the diagram parent element
+ * @param {String} scopeName name of the scope, i.e. camunda:Connector
+ * @param {Object} scopeDefinition
+ */
+ function updateScopeElements(element, scopeName, scopeDefinition) {
+
+ var scopeElement = bpmnFactory.create(scopeName);
+
+ // update camunda:inputOutput
+ updateIoMappings(element, scopeDefinition, scopeElement);
+
+ // update camunda:field
+ updateCamundaField(element, scopeDefinition, scopeElement);
+
+ // update camunda:properties
+ updateCamundaProperties(element, scopeDefinition, scopeElement);
+
+ // update other properties (bpmn:condition, camunda:async, ...)
+ updateProperties(element, scopeDefinition, scopeElement);
+
+ // update camunda:in and camunda:out
+ updateInOut(element, scopeDefinition, scopeElement);
+
+ // update camunda:executionListener
+ updateExecutionListener(element, scopeDefinition, scopeElement);
+
+ var extensionElements = getOrCreateExtensionElements(element);
+ var oldScope = findExtension(extensionElements, scopeName);
+
+ commandStack.execute('properties-panel.update-businessobject-list', {
+ element: element,
+ currentObject: extensionElements,
+ propertyName: 'values',
+ objectsToAdd: [scopeElement],
+ objectsToRemove: oldScope ? [oldScope] : []
+ });
+ }
+
+ /**
+ * Compose an element template change action, updating all
+ * necessary underlying properties.
+ *
+ * @param {Object} context
+ * @param {Object} context.element
+ * @param {Object} context.oldTemplate
+ * @param {Object} context.newTemplate
+ */
+ this.preExecute = function (context) {
+
+ var element = context.element,
+ newTemplate = context.newTemplate;
+
+ // update camunda:modelerTemplate attribute
+ updateModelerTemplate(element, newTemplate);
+
+ if (newTemplate) {
+
+ // update camunda:inputOutput
+ updateIoMappings(element, newTemplate);
+
+ // update camunda:field
+ updateCamundaField(element, newTemplate);
+
+ // update camunda:properties
+ updateCamundaProperties(element, newTemplate);
+
+ // update other properties (bpmn:condition, camunda:async, ...)
+ updateProperties(element, newTemplate);
+
+ // update camunda:in and camunda:out
+ updateInOut(element, newTemplate);
+
+ // update camunda:executionListener
+ updateExecutionListener(element, newTemplate);
+
+ // loop on scopes properties
+ forEach(newTemplate.scopes, function (scopeDefinition, scopeName) {
+ updateScopeElements(element, scopeName, scopeDefinition);
+ });
+ }
+ };
+}
+
+ChangeElementTemplateHandler.$inject = ['modeling', 'commandStack', 'bpmnFactory'];
+
+module.exports = ChangeElementTemplateHandler;
+
+/////// helpers /////////////////////////////
+
+function createBpmnPropertyUpdates(template, bpmnFactory) {
+
+ var propertyUpdates = {};
+
+ template.properties.forEach(function (p) {
+
+ var binding = p.binding,
+ bindingTarget = binding.name,
+ propertyValue;
+
+ if (binding.type === 'property') {
+
+ if (bindingTarget === 'conditionExpression') {
+ propertyValue = bpmnFactory.create('bpmn:FormalExpression', {
+ body: p.value,
+ language: binding.scriptFormat
+ });
+ } else {
+ propertyValue = p.value;
+ }
+
+ // assigning camunda:async to true|false
+ // assigning bpmn:conditionExpression to { $type: 'bpmn:FormalExpression', ... }
+ propertyUpdates[bindingTarget] = propertyValue;
+
+ // make sure we unset other "implementation types"
+ // when applying a camunda:class template onto a preconfigured
+ // camunda:delegateExpression element
+ if (CAMUNDA_SERVICE_TASK_LIKE.indexOf(bindingTarget) !== -1) {
+ CAMUNDA_SERVICE_TASK_LIKE.forEach(function (prop) {
+ if (prop !== bindingTarget) {
+ propertyUpdates[prop] = undefined;
+ }
+ });
+ }
+ }
+ });
+
+ return propertyUpdates;
+}
+
+function createCamundaFieldInjections(template, bpmnFactory) {
+ var injections = [];
+
+ template.properties.forEach(function (p) {
+ var binding = p.binding,
+ bindingType = binding.type;
+ if (bindingType === 'camunda:field') {
+ injections.push(createCamundaFieldInjection(binding, p.value, bpmnFactory));
+ }
+ });
+
+ if (injections.length) {
+ return injections;
+ }
+}
+
+function createCamundaProperties(template, bpmnFactory) {
+
+ var properties = [];
+
+ template.properties.forEach(function (p) {
+ var binding = p.binding,
+ bindingType = binding.type;
+
+ if (bindingType === 'camunda:property') {
+ properties.push(createCamundaProperty(binding, p.value, bpmnFactory));
+ }
+ });
+
+ if (properties.length) {
+ return bpmnFactory.create('camunda:Properties', {
+ values: properties
+ });
+ }
+}
+
+function createInputOutputMappings(template, bpmnFactory) {
+
+ var inputParameters = [],
+ outputParameters = [];
+
+ template.properties.forEach(function (p) {
+ var binding = p.binding,
+ bindingType = binding.type;
+
+ if (bindingType === 'camunda:inputParameter') {
+ inputParameters.push(createInputParameter(binding, p.value, bpmnFactory));
+ }
+
+ if (bindingType === 'camunda:outputParameter') {
+ outputParameters.push(createOutputParameter(binding, p.value, bpmnFactory));
+ }
+ });
+
+ // do we need to create new ioMappings (?)
+ if (outputParameters.length || inputParameters.length) {
+ return bpmnFactory.create('camunda:InputOutput', {
+ inputParameters: inputParameters,
+ outputParameters: outputParameters
+ });
+ }
+}
+
+function createCamundaInOut(template, bpmnFactory) {
+
+ var inOuts = [];
+
+ template.properties.forEach(function (p) {
+ var binding = p.binding,
+ bindingType = binding.type;
+
+ if (bindingType === 'camunda:in') {
+ inOuts.push(createCamundaIn(binding, p.value, bpmnFactory));
+ } else if (bindingType === 'camunda:out') {
+ inOuts.push(createCamundaOut(binding, p.value, bpmnFactory));
+ } else if (bindingType === 'camunda:in:businessKey') {
+ inOuts.push(createCamundaInWithBusinessKey(binding, p.value, bpmnFactory));
+ }
+ });
+
+ return inOuts;
+}
+
+function createCamundaExecutionListeners(template, bpmnFactory) {
+
+ var executionListener = [];
+
+ template.properties.forEach(function (p) {
+ var binding = p.binding,
+ bindingType = binding.type;
+
+ if (bindingType === 'camunda:executionListener') {
+ executionListener.push(createCamundaExecutionListenerScript(binding, p.value, bpmnFactory));
+ }
+ });
+
+ return executionListener;
+}
+
+},{"../CreateHelper":51,"../Helper":55,"lodash/collection/forEach":422}],58:[function(require,module,exports){
+'use strict';
+
+var ChangeElementTemplateHandler = require('./ChangeElementTemplateHandler');
+
+var getTemplate = require('../Helper').getTemplate,
+ getDefaultTemplate = require('../Helper').getDefaultTemplate;
+
+function registerHandlers(commandStack, elementTemplates, eventBus, elementRegistry) {
+ commandStack.registerHandler('propertiesPanel.camunda.changeTemplate', ChangeElementTemplateHandler);
+
+ // apply default element templates on shape creation
+ eventBus.on(['commandStack.shape.create.postExecuted'], function (context) {
+ applyDefaultTemplate(context.context.shape, elementTemplates, commandStack);
+ });
+
+ // apply default element templates on connection creation
+ eventBus.on(['commandStack.connection.create.postExecuted'], function (context) {
+ applyDefaultTemplate(context.context.connection, elementTemplates, commandStack);
+ });
+}
+
+registerHandlers.$inject = ['commandStack', 'elementTemplates', 'eventBus', 'elementRegistry'];
+
+module.exports = {
+ __init__: [registerHandlers]
+};
+
+function applyDefaultTemplate(element, elementTemplates, commandStack) {
+
+ if (!getTemplate(element, elementTemplates) && getDefaultTemplate(element, elementTemplates)) {
+
+ var command = 'propertiesPanel.camunda.changeTemplate';
+ var commandContext = {
+ element: element,
+ newTemplate: getDefaultTemplate(element, elementTemplates)
+ };
+
+ commandStack.execute(command, commandContext);
+ }
+}
+
+},{"../Helper":55,"./ChangeElementTemplateHandler":57}],59:[function(require,module,exports){
+'use strict';
+
+module.exports = {
+ __depends__: [require('./cmd'), require('diagram-js/lib/i18n/translate')],
+ __init__: ['customElementsPropertiesActivator', 'elementTemplatesLoader'],
+ customElementsPropertiesActivator: ['type', require('./CustomElementsPropertiesActivator')],
+ elementTemplates: ['type', require('./ElementTemplates')],
+ elementTemplatesLoader: ['type', require('./ElementTemplatesLoader')]
+};
+
+},{"./CustomElementsPropertiesActivator":52,"./ElementTemplates":53,"./ElementTemplatesLoader":54,"./cmd":58,"diagram-js/lib/i18n/translate":376}],60:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ is = require('bpmn-js/lib/util/ModelUtil').is,
+ getTemplate = require('../Helper').getTemplate,
+ getTemplateId = require('../Helper').getTemplateId;
+
+var find = require('lodash/collection/find');
+
+var TEMPLATE_ATTR = require('../Helper').TEMPLATE_ATTR;
+
+function isAny(element, types) {
+ return types.reduce(function (result, type) {
+ return result || is(element, type);
+ }, false);
+}
+
+module.exports = function (group, element, elementTemplates, translate) {
+
+ var options = getTemplateOptions(element, elementTemplates);
+
+ if (options.length === 1 && !options[0].isDefault) {
+ return;
+ }
+
+ // select element template (via dropdown)
+ group.entries.push(entryFactory.selectBox({
+ id: 'elementTemplate-chooser',
+ label: translate('Element Template'),
+ modelProperty: 'camunda:modelerTemplate',
+ selectOptions: options,
+ set: function set(element, properties) {
+ return applyTemplate(element, properties[TEMPLATE_ATTR], elementTemplates);
+ },
+ disabled: function disabled() {
+ var template = getTemplate(element, elementTemplates);
+
+ return template && isDefaultTemplate(template);
+ }
+ }));
+};
+
+////// helpers //////////////////////////////////////
+
+function applyTemplate(element, newTemplateId, elementTemplates) {
+
+ // cleanup
+ // clear input output mappings
+ // undo changes to properties defined in template
+
+ // re-establish
+ // set input output mappings
+ // apply changes to properties as defined in new template
+
+ var oldTemplate = getTemplate(element, elementTemplates),
+ newTemplate = elementTemplates.get(newTemplateId);
+
+ if (oldTemplate === newTemplate) {
+ return;
+ }
+
+ return {
+ cmd: 'propertiesPanel.camunda.changeTemplate',
+ context: {
+ element: element,
+ oldTemplate: oldTemplate,
+ newTemplate: newTemplate
+ }
+ };
+}
+
+function getTemplateOptions(element, elementTemplates) {
+
+ var currentTemplateId = getTemplateId(element);
+
+ var emptyOption = {
+ name: '',
+ value: ''
+ };
+
+ var allOptions = elementTemplates.getAll().reduce(function (templates, t) {
+ if (!isAny(element, t.appliesTo)) {
+ return templates;
+ }
+
+ return templates.concat({
+ name: t.name,
+ value: t.id,
+ isDefault: t.isDefault
+ });
+ }, [emptyOption]);
+
+ var defaultOption = find(allOptions, function (option) {
+ return isDefaultTemplate(option);
+ });
+
+ var currentOption = find(allOptions, function (option) {
+ return option.value === currentTemplateId;
+ });
+
+ if (currentTemplateId && !currentOption) {
+ currentOption = unknownTemplate(currentTemplateId);
+
+ allOptions.push(currentOption);
+ }
+
+ if (!defaultOption) {
+
+ // return all options, including empty
+ // and optionally unknownTemplate option
+ return allOptions;
+ }
+
+ // special limited handling for
+ // default options
+
+ var options = [];
+
+ // current template not set
+ if (!currentTemplateId) {
+ options.push({
+ name: '',
+ value: ''
+ });
+ }
+
+ // current template not default
+ if (currentOption && currentOption !== defaultOption) {
+ options.push(currentOption);
+ }
+
+ options.push(defaultOption);
+
+ // [ (empty), (current), defaultOption ]
+ return options;
+}
+
+function unknownTemplate(templateId) {
+ return {
+ name: '[unknown template: ' + templateId + ']',
+ value: templateId
+ };
+}
+
+function isDefaultTemplate(elementTemplate) {
+ return elementTemplate.isDefault;
+}
+
+},{"../../../../factory/EntryFactory":14,"../Helper":55,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/find":421}],61:[function(require,module,exports){
+'use strict';
+
+var assign = require('lodash/object/assign');
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ getTemplate = require('../Helper').getTemplate,
+ cmdHelper = require('../../../../helper/CmdHelper'),
+ elementHelper = require('../../../../helper/ElementHelper');
+
+var findExtension = require('../Helper').findExtension,
+ findExtensions = require('../Helper').findExtensions,
+ findInputParameter = require('../Helper').findInputParameter,
+ findOutputParameter = require('../Helper').findOutputParameter,
+ findCamundaProperty = require('../Helper').findCamundaProperty,
+ findCamundaInOut = require('../Helper').findCamundaInOut;
+
+var createCamundaProperty = require('../CreateHelper').createCamundaProperty,
+ createInputParameter = require('../CreateHelper').createInputParameter,
+ createOutputParameter = require('../CreateHelper').createOutputParameter,
+ createCamundaIn = require('../CreateHelper').createCamundaIn,
+ createCamundaOut = require('../CreateHelper').createCamundaOut,
+ createCamundaInWithBusinessKey = require('../CreateHelper').createCamundaInWithBusinessKey,
+ createCamundaFieldInjection = require('../CreateHelper').createCamundaFieldInjection;
+
+var CAMUNDA_PROPERTY_TYPE = 'camunda:property',
+ CAMUNDA_INPUT_PARAMETER_TYPE = 'camunda:inputParameter',
+ CAMUNDA_OUTPUT_PARAMETER_TYPE = 'camunda:outputParameter',
+ CAMUNDA_IN_TYPE = 'camunda:in',
+ CAMUNDA_OUT_TYPE = 'camunda:out',
+ CAMUNDA_IN_BUSINESS_KEY_TYPE = 'camunda:in:businessKey',
+ CAMUNDA_EXECUTION_LISTENER_TYPE = 'camunda:executionListener',
+ CAMUNDA_FIELD = 'camunda:field';
+
+var BASIC_MODDLE_TYPES = ['Boolean', 'Integer', 'String'];
+
+var EXTENSION_BINDING_TYPES = [CAMUNDA_PROPERTY_TYPE, CAMUNDA_INPUT_PARAMETER_TYPE, CAMUNDA_OUTPUT_PARAMETER_TYPE, CAMUNDA_IN_TYPE, CAMUNDA_OUT_TYPE, CAMUNDA_IN_BUSINESS_KEY_TYPE, CAMUNDA_FIELD];
+
+var IO_BINDING_TYPES = [CAMUNDA_INPUT_PARAMETER_TYPE, CAMUNDA_OUTPUT_PARAMETER_TYPE];
+
+var IN_OUT_BINDING_TYPES = [CAMUNDA_IN_TYPE, CAMUNDA_OUT_TYPE, CAMUNDA_IN_BUSINESS_KEY_TYPE];
+
+/**
+ * Injects custom properties into the given group.
+ *
+ * @param {GroupDescriptor} group
+ * @param {djs.model.Base} element
+ * @param {ElementTemplates} elementTemplates
+ * @param {BpmnFactory} bpmnFactory
+ */
+module.exports = function (element, elementTemplates, bpmnFactory, translate) {
+
+ var template = getTemplate(element, elementTemplates);
+
+ if (!template) {
+ return [];
+ }
+
+ var renderCustomField = function renderCustomField(id, p, idx) {
+ var propertyType = p.type;
+
+ var entryOptions = {
+ id: id,
+ description: p.description,
+ label: p.label,
+ modelProperty: id,
+ get: propertyGetter(id, p),
+ set: propertySetter(id, p, bpmnFactory),
+ validate: propertyValidator(id, p)
+ };
+
+ var entry;
+
+ if (propertyType === 'Boolean') {
+ entry = entryFactory.checkbox(entryOptions);
+ }
+
+ if (propertyType === 'String') {
+ entry = entryFactory.textField(entryOptions);
+ }
+
+ if (propertyType === 'Text') {
+ entry = entryFactory.textBox(entryOptions);
+ }
+
+ if (propertyType === 'Dropdown') {
+ entryOptions.selectOptions = p.choices;
+
+ entry = entryFactory.selectBox(entryOptions);
+ }
+
+ return entry;
+ };
+
+ var groups = [];
+ var id, entry;
+
+ var customFieldsGroup = {
+ id: 'customField',
+ label: translate('Custom Fields'),
+ entries: []
+ };
+ template.properties.forEach(function (p, idx) {
+
+ id = 'custom-' + template.id + '-' + idx;
+
+ entry = renderCustomField(id, p, idx);
+ if (entry) {
+ customFieldsGroup.entries.push(entry);
+ }
+ });
+ if (customFieldsGroup.entries.length > 0) {
+ groups.push(customFieldsGroup);
+ }
+
+ if (template.scopes) {
+ for (var scopeName in template.scopes) {
+
+ var scope = template.scopes[scopeName];
+ var idScopeName = scopeName.replace(/:/g, '_');
+
+ var customScopeFieldsGroup = {
+ id: 'customField-' + idScopeName,
+ label: translate('Custom Fields for scope: ') + scopeName,
+ entries: []
+ };
+
+ scope.properties.forEach(function (p, idx) {
+
+ var propertyId = 'custom-' + template.id + '-' + idScopeName + '-' + idx;
+
+ var scopedProperty = propertyWithScope(p, scopeName);
+
+ entry = renderCustomField(propertyId, scopedProperty, idx);
+ if (entry) {
+ customScopeFieldsGroup.entries.push(entry);
+ }
+ });
+
+ if (customScopeFieldsGroup.entries.length > 0) {
+ groups.push(customScopeFieldsGroup);
+ }
+ }
+ }
+
+ return groups;
+};
+
+/////// getters, setters and validators ///////////////
+
+
+/**
+ * Return a getter that retrieves the given property.
+ *
+ * @param {String} name
+ * @param {PropertyDescriptor} property
+ *
+ * @return {Function}
+ */
+function propertyGetter(name, property) {
+
+ /* getter */
+ return function get(element) {
+ var value = getPropertyValue(element, property);
+
+ return objectWithKey(name, value);
+ };
+}
+
+/**
+ * Return a setter that updates the given property.
+ *
+ * @param {String} name
+ * @param {PropertyDescriptor} property
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {Function}
+ */
+function propertySetter(name, property, bpmnFactory) {
+
+ /* setter */
+ return function set(element, values) {
+
+ var value = values[name];
+
+ return setPropertyValue(element, property, value, bpmnFactory);
+ };
+}
+
+/**
+ * Return a validator that ensures the property is ok.
+ *
+ * @param {String} name
+ * @param {PropertyDescriptor} property
+ *
+ * @return {Function}
+ */
+function propertyValidator(name, property) {
+
+ /* validator */
+ return function validate(element, values) {
+ var value = values[name];
+
+ var error = validateValue(value, property);
+
+ if (error) {
+ return objectWithKey(name, error);
+ }
+ };
+}
+
+//////// get, set and validate helpers ///////////////////
+
+/**
+ * Return the value of the specified property descriptor,
+ * on the passed diagram element.
+ *
+ * @param {djs.model.Base} element
+ * @param {PropertyDescriptor} property
+ *
+ * @return {Any}
+ */
+function getPropertyValue(element, property) {
+
+ var bo = getBusinessObject(element);
+
+ var binding = property.binding,
+ scope = property.scope;
+
+ var bindingType = binding.type,
+ bindingName = binding.name;
+
+ var propertyValue = property.value || '';
+
+ if (scope) {
+ bo = findExtension(bo, scope.name);
+ if (!bo) {
+ return propertyValue;
+ }
+ }
+
+ // property
+ if (bindingType === 'property') {
+
+ var value = bo.get(bindingName);
+
+ if (bindingName === 'conditionExpression') {
+ if (value) {
+ return value.body;
+ } else {
+ // return defined default
+ return propertyValue;
+ }
+ } else {
+ // return value; default to defined default
+ return typeof value !== 'undefined' ? value : propertyValue;
+ }
+ }
+
+ var camundaProperties, camundaProperty;
+
+ if (bindingType === CAMUNDA_PROPERTY_TYPE) {
+ if (scope) {
+ camundaProperties = bo.get('properties');
+ } else {
+ camundaProperties = findExtension(bo, 'camunda:Properties');
+ }
+
+ if (camundaProperties) {
+ camundaProperty = findCamundaProperty(camundaProperties, binding);
+
+ if (camundaProperty) {
+ return camundaProperty.value;
+ }
+ }
+
+ return propertyValue;
+ }
+
+ var inputOutput, ioParameter;
+
+ if (IO_BINDING_TYPES.indexOf(bindingType) !== -1) {
+
+ if (scope) {
+ inputOutput = bo.get('inputOutput');
+ } else {
+ inputOutput = findExtension(bo, 'camunda:InputOutput');
+ }
+
+ if (!inputOutput) {
+ // ioParameter cannot exist yet, return property value
+ return propertyValue;
+ }
+ }
+
+ // camunda input parameter
+ if (bindingType === CAMUNDA_INPUT_PARAMETER_TYPE) {
+ ioParameter = findInputParameter(inputOutput, binding);
+
+ if (ioParameter) {
+ if (binding.scriptFormat) {
+ if (ioParameter.definition) {
+ return ioParameter.definition.value;
+ }
+ } else {
+ return ioParameter.value || '';
+ }
+ }
+
+ return propertyValue;
+ }
+
+ // camunda output parameter
+ if (binding.type === CAMUNDA_OUTPUT_PARAMETER_TYPE) {
+ ioParameter = findOutputParameter(inputOutput, binding);
+
+ if (ioParameter) {
+ return ioParameter.name;
+ }
+
+ return propertyValue;
+ }
+
+ var ioElement;
+
+ if (IN_OUT_BINDING_TYPES.indexOf(bindingType) != -1) {
+ ioElement = findCamundaInOut(bo, binding);
+
+ if (ioElement) {
+ if (bindingType === CAMUNDA_IN_BUSINESS_KEY_TYPE) {
+ return ioElement.businessKey;
+ } else if (bindingType === CAMUNDA_OUT_TYPE) {
+ return ioElement.target;
+ } else if (bindingType === CAMUNDA_IN_TYPE) {
+ return ioElement[binding.expression ? 'sourceExpression' : 'source'];
+ }
+ }
+
+ return propertyValue;
+ }
+
+ if (bindingType === CAMUNDA_EXECUTION_LISTENER_TYPE) {
+ var executionListener;
+ if (scope) {
+ executionListener = bo.get('executionListener');
+ } else {
+ executionListener = findExtension(bo, 'camunda:ExecutionListener');
+ }
+
+ return executionListener.script.value;
+ }
+
+ var fieldInjection;
+ if (CAMUNDA_FIELD === bindingType) {
+ var fieldInjections = findExtensions(bo, ['camunda:Field']);
+ fieldInjections.forEach(function (item) {
+ if (item.name === binding.name) {
+ fieldInjection = item;
+ }
+ });
+ if (fieldInjection) {
+ return fieldInjection.string || fieldInjection.expression;
+ } else {
+ return '';
+ }
+ }
+
+ throw unknownPropertyBinding(property);
+}
+
+module.exports.getPropertyValue = getPropertyValue;
+
+/**
+ * Return an update operation that changes the diagram
+ * element's custom property to the given value.
+ *
+ * The response of this method will be processed via
+ * {@link PropertiesPanel#applyChanges}.
+ *
+ * @param {djs.model.Base} element
+ * @param {PropertyDescriptor} property
+ * @param {String} value
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @return {Object|Array} results to be processed
+ */
+function setPropertyValue(element, property, value, bpmnFactory) {
+ var bo = getBusinessObject(element);
+
+ var binding = property.binding,
+ scope = property.scope;
+
+ var bindingType = binding.type,
+ bindingName = binding.name;
+
+ var propertyValue;
+
+ var updates = [];
+
+ var extensionElements;
+
+ if (EXTENSION_BINDING_TYPES.indexOf(bindingType) !== -1) {
+ extensionElements = bo.get('extensionElements');
+
+ // create extension elements, if they do not exist (yet)
+ if (!extensionElements) {
+ extensionElements = elementHelper.createElement('bpmn:ExtensionElements', null, element, bpmnFactory);
+
+ updates.push(cmdHelper.updateBusinessObject(element, bo, objectWithKey('extensionElements', extensionElements)));
+ }
+ }
+
+ if (scope) {
+ bo = findExtension(bo, scope.name);
+ if (!bo) {
+ bo = elementHelper.createElement(scope.name, null, element, bpmnFactory);
+
+ updates.push(cmdHelper.addElementsTolist(bo, extensionElements, 'values', [bo]));
+ }
+ }
+
+ // property
+ if (bindingType === 'property') {
+
+ if (bindingName === 'conditionExpression') {
+
+ propertyValue = elementHelper.createElement('bpmn:FormalExpression', {
+ body: value,
+ language: binding.scriptFormat
+ }, bo, bpmnFactory);
+ } else {
+
+ var moddlePropertyDescriptor = bo.$descriptor.propertiesByName[bindingName];
+
+ var moddleType = moddlePropertyDescriptor.type;
+
+ // make sure we only update String, Integer, Real and
+ // Boolean properties (do not accidentally override complex objects...)
+ if (BASIC_MODDLE_TYPES.indexOf(moddleType) === -1) {
+ throw new Error('cannot set moddle type <' + moddleType + '>');
+ }
+
+ if (moddleType === 'Boolean') {
+ propertyValue = !!value;
+ } else if (moddleType === 'Integer') {
+ propertyValue = parseInt(value, 10);
+
+ if (isNaN(propertyValue)) {
+ // do not write NaN value
+ propertyValue = undefined;
+ }
+ } else {
+ propertyValue = value;
+ }
+ }
+
+ if (propertyValue !== undefined) {
+ updates.push(cmdHelper.updateBusinessObject(element, bo, objectWithKey(bindingName, propertyValue)));
+ }
+ }
+
+ // camunda:property
+ var camundaProperties, existingCamundaProperty, newCamundaProperty;
+
+ if (bindingType === CAMUNDA_PROPERTY_TYPE) {
+
+ if (scope) {
+ camundaProperties = bo.get('properties');
+ } else {
+ camundaProperties = findExtension(extensionElements, 'camunda:Properties');
+ }
+
+ if (!camundaProperties) {
+ camundaProperties = elementHelper.createElement('camunda:Properties', null, bo, bpmnFactory);
+
+ if (scope) {
+ updates.push(cmdHelper.updateBusinessObject(element, bo, { properties: camundaProperties }));
+ } else {
+ updates.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', [camundaProperties]));
+ }
+ }
+
+ existingCamundaProperty = findCamundaProperty(camundaProperties, binding);
+
+ newCamundaProperty = createCamundaProperty(binding, value, bpmnFactory);
+
+ updates.push(cmdHelper.addAndRemoveElementsFromList(element, camundaProperties, 'values', null, [newCamundaProperty], existingCamundaProperty ? [existingCamundaProperty] : []));
+ }
+
+ // camunda:inputParameter
+ // camunda:outputParameter
+ var inputOutput, existingIoParameter, newIoParameter;
+
+ if (IO_BINDING_TYPES.indexOf(bindingType) !== -1) {
+
+ if (scope) {
+ inputOutput = bo.get('inputOutput');
+ } else {
+ inputOutput = findExtension(extensionElements, 'camunda:InputOutput');
+ }
+
+ // create inputOutput element, if it do not exist (yet)
+ if (!inputOutput) {
+ inputOutput = elementHelper.createElement('camunda:InputOutput', null, bo, bpmnFactory);
+
+ if (scope) {
+ updates.push(cmdHelper.updateBusinessObject(element, bo, { inputOutput: inputOutput }));
+ } else {
+ updates.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', inputOutput));
+ }
+ }
+ }
+
+ if (bindingType === CAMUNDA_INPUT_PARAMETER_TYPE) {
+
+ existingIoParameter = findInputParameter(inputOutput, binding);
+
+ newIoParameter = createInputParameter(binding, value, bpmnFactory);
+
+ updates.push(cmdHelper.addAndRemoveElementsFromList(element, inputOutput, 'inputParameters', null, [newIoParameter], existingIoParameter ? [existingIoParameter] : []));
+ }
+
+ if (bindingType === CAMUNDA_OUTPUT_PARAMETER_TYPE) {
+
+ existingIoParameter = findOutputParameter(inputOutput, binding);
+
+ newIoParameter = createOutputParameter(binding, value, bpmnFactory);
+
+ updates.push(cmdHelper.addAndRemoveElementsFromList(element, inputOutput, 'outputParameters', null, [newIoParameter], existingIoParameter ? [existingIoParameter] : []));
+ }
+
+ // camunda:in
+ // camunda:out
+ // camunda:in:businessKey
+ var existingInOut, newInOut;
+
+ if (IN_OUT_BINDING_TYPES.indexOf(bindingType) !== -1) {
+
+ existingInOut = findCamundaInOut(bo, binding);
+
+ if (bindingType === CAMUNDA_IN_TYPE) {
+ newInOut = createCamundaIn(binding, value, bpmnFactory);
+ } else if (bindingType === CAMUNDA_OUT_TYPE) {
+ newInOut = createCamundaOut(binding, value, bpmnFactory);
+ } else {
+ newInOut = createCamundaInWithBusinessKey(binding, value, bpmnFactory);
+ }
+
+ updates.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', null, [newInOut], existingInOut ? [existingInOut] : []));
+ }
+
+ if (bindingType === CAMUNDA_FIELD) {
+ var existingFieldInjections = findExtensions(bo, ['camunda:Field']);
+ var newFieldInjections = [];
+
+ if (existingFieldInjections.length > 0) {
+ existingFieldInjections.forEach(function (item) {
+ if (item.name === binding.name) {
+ newFieldInjections.push(createCamundaFieldInjection(binding, value, bpmnFactory));
+ } else {
+ newFieldInjections.push(item);
+ }
+ });
+ } else {
+ newFieldInjections.push(createCamundaFieldInjection(binding, value, bpmnFactory));
+ }
+
+ updates.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', null, newFieldInjections, existingFieldInjections ? existingFieldInjections : []));
+ }
+
+ if (updates.length) {
+ return updates;
+ }
+
+ // quick warning for better debugging
+ console.warn('no update', element, property, value);
+}
+
+/**
+ * Validate value of a given property.
+ *
+ * @param {String} value
+ * @param {PropertyDescriptor} property
+ *
+ * @return {Object} with validation errors
+ */
+function validateValue(value, property) {
+
+ var constraints = property.constraints || {};
+
+ if (constraints.notEmpty && isEmpty(value)) {
+ return 'Must not be empty';
+ }
+
+ if (constraints.maxLength && value.length > constraints.maxLength) {
+ return 'Must have max length ' + constraints.maxLength;
+ }
+
+ if (constraints.minLength && value.length < constraints.minLength) {
+ return 'Must have min length ' + constraints.minLength;
+ }
+
+ var pattern = constraints.pattern,
+ message;
+
+ if (pattern) {
+
+ if (typeof pattern !== 'string') {
+ message = pattern.message;
+ pattern = pattern.value;
+ }
+
+ if (!matchesPattern(value, pattern)) {
+ return message || 'Must match pattern ' + pattern;
+ }
+ }
+}
+
+//////// misc helpers ///////////////////////////////
+
+function propertyWithScope(property, scopeName) {
+ if (!scopeName) {
+ return property;
+ }
+
+ return assign({}, property, {
+ scope: {
+ name: scopeName
+ }
+ });
+}
+
+/**
+ * Return an object with a single key -> value association.
+ *
+ * @param {String} key
+ * @param {Any} value
+ *
+ * @return {Object}
+ */
+function objectWithKey(key, value) {
+ var obj = {};
+
+ obj[key] = value;
+
+ return obj;
+}
+
+/**
+ * Does the given string match the specified pattern?
+ *
+ * @param {String} str
+ * @param {String} pattern
+ *
+ * @return {Boolean}
+ */
+function matchesPattern(str, pattern) {
+ var regexp = new RegExp(pattern);
+
+ return regexp.test(str);
+}
+
+function isEmpty(str) {
+ return !str || /^\s*$/.test(str);
+}
+
+/**
+ * Create a new {@link Error} indicating an unknown
+ * property binding.
+ *
+ * @param {PropertyDescriptor} property
+ *
+ * @return {Error}
+ */
+function unknownPropertyBinding(property) {
+ var binding = property.binding;
+
+ return new Error('unknown binding: <' + binding.type + '>');
+}
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../CreateHelper":51,"../Helper":55,"bpmn-js/lib/util/ModelUtil":216,"lodash/object/assign":496}],62:[function(require,module,exports){
+'use strict';
+
+module.exports = {
+ __depends__: [require('./element-templates'), require('diagram-js/lib/i18n/translate')],
+ __init__: ['propertiesProvider'],
+ propertiesProvider: ['type', require('./CamundaPropertiesProvider')]
+};
+
+},{"./CamundaPropertiesProvider":50,"./element-templates":59,"diagram-js/lib/i18n/translate":376}],63:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ is = require('bpmn-js/lib/util/ModelUtil').is,
+ asyncContinuation = require('./implementation/AsyncContinuation');
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ if (is(element, 'camunda:AsyncCapable')) {
+
+ group.entries = group.entries.concat(asyncContinuation(element, bpmnFactory, {
+ getBusinessObject: getBusinessObject
+ }, translate));
+ }
+};
+
+},{"./implementation/AsyncContinuation":87,"bpmn-js/lib/util/ModelUtil":216}],64:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var entryFactory = require('../../../factory/EntryFactory');
+
+var callable = require('./implementation/Callable');
+
+var cmdHelper = require('../../../helper/CmdHelper');
+
+var flattenDeep = require('lodash/array/flattenDeep');
+var assign = require('lodash/object/assign');
+
+function getCallableType(element) {
+ var bo = getBusinessObject(element);
+
+ var boCalledElement = bo.get('calledElement'),
+ boCaseRef = bo.get('camunda:caseRef');
+
+ var callActivityType = '';
+ if (typeof boCalledElement !== 'undefined') {
+ callActivityType = 'bpmn';
+ } else if (typeof boCaseRef !== 'undefined') {
+ callActivityType = 'cmmn';
+ }
+
+ return callActivityType;
+}
+
+var DEFAULT_PROPS = {
+ calledElement: undefined,
+ 'camunda:calledElementBinding': 'latest',
+ 'camunda:calledElementVersion': undefined,
+ 'camunda:calledElementTenantId': undefined,
+ 'camunda:variableMappingClass': undefined,
+ 'camunda:variableMappingDelegateExpression': undefined,
+ 'camunda:caseRef': undefined,
+ 'camunda:caseBinding': 'latest',
+ 'camunda:caseVersion': undefined,
+ 'camunda:caseTenantId': undefined
+};
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ if (!is(element, 'camunda:CallActivity')) {
+ return;
+ }
+
+ group.entries.push(entryFactory.selectBox({
+ id: 'callActivity',
+ label: translate('CallActivity Type'),
+ selectOptions: [{ name: 'BPMN', value: 'bpmn' }, { name: 'CMMN', value: 'cmmn' }],
+ emptyParameter: true,
+ modelProperty: 'callActivityType',
+
+ get: function get(element, node) {
+ return {
+ callActivityType: getCallableType(element)
+ };
+ },
+
+ set: function set(element, values, node) {
+ var type = values.callActivityType;
+
+ var props = assign({}, DEFAULT_PROPS);
+
+ if (type === 'bpmn') {
+ props.calledElement = '';
+ } else if (type === 'cmmn') {
+ props['camunda:caseRef'] = '';
+ }
+
+ return cmdHelper.updateProperties(element, props);
+ }
+
+ }));
+
+ group.entries.push(callable(element, bpmnFactory, {
+ getCallableType: getCallableType
+ }, translate));
+
+ group.entries = flattenDeep(group.entries);
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"./implementation/Callable":88,"bpmn-js/lib/util/ModelUtil":216,"lodash/array/flattenDeep":417,"lodash/object/assign":496}],65:[function(require,module,exports){
+'use strict';
+
+var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'),
+ InputOutputHelper = require('../../../helper/InputOutputHelper');
+
+var entryFactory = require('../../../factory/EntryFactory'),
+ cmdHelper = require('../../../helper/CmdHelper');
+
+function getImplementationType(element) {
+ return ImplementationTypeHelper.getImplementationType(element);
+}
+
+function getBusinessObject(element) {
+ return ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element);
+}
+
+function getConnector(bo) {
+ return InputOutputHelper.getConnector(bo);
+}
+
+function isConnector(element) {
+ return getImplementationType(element) === 'connector';
+}
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ group.entries.push(entryFactory.textField({
+ id: 'connectorId',
+ label: translate('Connector Id'),
+ modelProperty: 'connectorId',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ var connector = bo && getConnector(bo);
+ var value = connector && connector.get('connectorId');
+ return { connectorId: value };
+ },
+
+ set: function set(element, values, node) {
+ var bo = getBusinessObject(element);
+ var connector = getConnector(bo);
+ return cmdHelper.updateBusinessObject(element, connector, {
+ connectorId: values.connectorId || undefined
+ });
+ },
+
+ validate: function validate(element, values, node) {
+ return isConnector(element) && !values.connectorId ? { connectorId: translate('Must provide a value') } : {};
+ },
+
+ hidden: function hidden(element, node) {
+ return !isConnector(element);
+ }
+
+ }));
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"../../../helper/ImplementationTypeHelper":29,"../../../helper/InputOutputHelper":30}],66:[function(require,module,exports){
+'use strict';
+
+var assign = require('lodash/object/assign');
+
+var inputOutputParameter = require('./implementation/InputOutputParameter');
+
+module.exports = function (group, element, bpmnFactory, options, translate) {
+
+ options = assign({
+ idPrefix: 'connector-',
+ insideConnector: true
+ }, options);
+
+ group.entries = group.entries.concat(inputOutputParameter(element, bpmnFactory, options, translate));
+};
+
+},{"./implementation/InputOutputParameter":97,"lodash/object/assign":496}],67:[function(require,module,exports){
+'use strict';
+
+var inputOutput = require('./implementation/InputOutput');
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ var inputOutputEntry = inputOutput(element, bpmnFactory, {
+ idPrefix: 'connector-',
+ insideConnector: true
+ }, translate);
+
+ group.entries = group.entries.concat(inputOutputEntry.entries);
+
+ return {
+ getSelectedParameter: inputOutputEntry.getSelectedParameter
+ };
+};
+
+},{"./implementation/InputOutput":96}],68:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper');
+
+var externalTaskPriority = require('./implementation/ExternalTaskPriority');
+
+function getServiceTaskLikeBusinessObject(element) {
+ var bo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element);
+
+ // if the element is not a serviceTaskLike element, fetch the normal business object
+ // This avoids the loss of the process / participant business object
+ if (!bo) {
+ bo = getBusinessObject(element);
+ }
+
+ return bo;
+}
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ var bo = getServiceTaskLikeBusinessObject(element);
+
+ if (!bo) {
+ return;
+ }
+
+ if (is(bo, 'camunda:TaskPriorized') || is(bo, 'bpmn:Participant') && bo.get('processRef')) {
+ group.entries = group.entries.concat(externalTaskPriority(element, bpmnFactory, {
+ getBusinessObject: function getBusinessObject(element) {
+ if (!is(bo, 'bpmn:Participant')) {
+ return bo;
+ }
+ return bo.get('processRef');
+ }
+ }, translate));
+ }
+};
+
+},{"../../../helper/ImplementationTypeHelper":29,"./implementation/ExternalTaskPriority":92,"bpmn-js/lib/util/ModelUtil":216}],69:[function(require,module,exports){
+'use strict';
+
+var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper');
+
+var fieldInjection = require('./implementation/FieldInjection');
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ var bo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element);
+
+ if (!bo) {
+ return;
+ }
+
+ var fieldInjectionEntry = fieldInjection(element, bpmnFactory, translate, { businessObject: bo });
+
+ if (fieldInjectionEntry && fieldInjectionEntry.length > 0) {
+ group.entries = group.entries.concat(fieldInjectionEntry);
+ }
+};
+
+},{"../../../helper/ImplementationTypeHelper":29,"./implementation/FieldInjection":93}],70:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ getExtensionElements = require('../../../helper/ExtensionElementsHelper').getExtensionElements,
+ extensionElements = require('./implementation/ExtensionElements'),
+ properties = require('./implementation/Properties'),
+ entryFactory = require('../../../factory/EntryFactory'),
+ elementHelper = require('../../../helper/ElementHelper'),
+ cmdHelper = require('../../../helper/CmdHelper'),
+ formHelper = require('../../../helper/FormHelper'),
+ utils = require('../../../Utils'),
+ is = require('bpmn-js/lib/util/ModelUtil').is,
+ find = require('lodash/collection/find'),
+ each = require('lodash/collection/forEach');
+
+function generateValueId() {
+ return utils.nextId('Value_');
+}
+
+/**
+ * Generate a form field specific textField using entryFactory.
+ *
+ * @param {string} options.id
+ * @param {string} options.label
+ * @param {string} options.modelProperty
+ * @param {function} options.validate
+ *
+ * @return {Object} an entryFactory.textField object
+ */
+function formFieldTextField(options, getSelectedFormField) {
+
+ var id = options.id,
+ label = options.label,
+ modelProperty = options.modelProperty,
+ validate = options.validate;
+
+ return entryFactory.textField({
+ id: id,
+ label: label,
+ modelProperty: modelProperty,
+ get: function get(element, node) {
+ var selectedFormField = getSelectedFormField(element, node) || {},
+ values = {};
+
+ values[modelProperty] = selectedFormField[modelProperty];
+
+ return values;
+ },
+
+ set: function set(element, values, node) {
+ var commands = [];
+
+ if (typeof options.set === 'function') {
+ var cmd = options.set(element, values, node);
+
+ if (cmd) {
+ commands.push(cmd);
+ }
+ }
+
+ var formField = getSelectedFormField(element, node),
+ properties = {};
+
+ properties[modelProperty] = values[modelProperty] || undefined;
+
+ commands.push(cmdHelper.updateBusinessObject(element, formField, properties));
+
+ return commands;
+ },
+ hidden: function hidden(element, node) {
+ return !getSelectedFormField(element, node);
+ },
+ validate: validate
+ });
+}
+
+function ensureFormKeyAndDataSupported(element) {
+ return is(element, 'bpmn:StartEvent') && !is(element.parent, 'bpmn:SubProcess') || is(element, 'bpmn:UserTask');
+}
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ if (!ensureFormKeyAndDataSupported(element)) {
+ return;
+ }
+
+ /**
+ * Return the currently selected form field querying the form field select box
+ * from the DOM.
+ *
+ * @param {djs.model.Base} element
+ * @param {DOMElement} node - DOM element of any form field text input
+ *
+ * @return {ModdleElement} the currently selected form field
+ */
+ function getSelectedFormField(element, node) {
+ var selected = formFieldsEntry.getSelected(element, node.parentNode);
+
+ if (selected.idx === -1) {
+ return;
+ }
+
+ return formHelper.getFormField(element, selected.idx);
+ }
+
+ //[FormKey] form key text input field
+ group.entries.push(entryFactory.textField({
+ id: 'form-key',
+ label: translate('Form Key'),
+ modelProperty: 'formKey',
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+
+ return {
+ formKey: bo.get('camunda:formKey')
+ };
+ },
+ set: function set(element, values, node) {
+ var bo = getBusinessObject(element),
+ formKey = values.formKey || undefined;
+
+ return cmdHelper.updateBusinessObject(element, bo, { 'camunda:formKey': formKey });
+ }
+ }));
+
+ // [FormData] form field select box
+ var formFieldsEntry = extensionElements(element, bpmnFactory, {
+ id: 'form-fields',
+ label: translate('Form Fields'),
+ modelProperty: 'id',
+ prefix: 'FormField',
+ createExtensionElement: function createExtensionElement(element, extensionElements, value) {
+ var bo = getBusinessObject(element),
+ commands = [];
+
+ if (!extensionElements) {
+ extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
+ commands.push(cmdHelper.updateProperties(element, { extensionElements: extensionElements }));
+ }
+
+ var formData = formHelper.getFormData(element);
+
+ if (!formData) {
+ formData = elementHelper.createElement('camunda:FormData', { fields: [] }, extensionElements, bpmnFactory);
+ commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [formData], []));
+ }
+
+ var field = elementHelper.createElement('camunda:FormField', { id: value }, formData, bpmnFactory);
+ if (typeof formData.fields !== 'undefined') {
+ commands.push(cmdHelper.addElementsTolist(element, formData, 'fields', [field]));
+ } else {
+ commands.push(cmdHelper.updateBusinessObject(element, formData, {
+ fields: [field]
+ }));
+ }
+ return commands;
+ },
+ removeExtensionElement: function removeExtensionElement(element, extensionElements, value, idx) {
+ var formData = getExtensionElements(getBusinessObject(element), 'camunda:FormData')[0],
+ entry = formData.fields[idx],
+ commands = [];
+
+ commands.push(cmdHelper.removeElementsFromList(element, formData, 'fields', null, [entry]));
+
+ if (entry.id === formData.get('businessKey')) {
+ commands.push(cmdHelper.updateBusinessObject(element, formData, { 'businessKey': undefined }));
+ }
+
+ return commands;
+ },
+ getExtensionElements: function getExtensionElements(element) {
+ return formHelper.getFormFields(element);
+ },
+ hideExtensionElements: function hideExtensionElements(element, node) {
+ return false;
+ }
+ });
+ group.entries.push(formFieldsEntry);
+
+ // [FormData] business key form field select box
+ var formBusinessKeyFormFieldEntry = entryFactory.selectBox({
+ id: 'form-business-key',
+ label: translate('Business Key'),
+ modelProperty: 'businessKey',
+ selectOptions: function selectOptions(element, inputNode) {
+ var selectOptions = [{ name: '', value: '' }];
+ var formFields = formHelper.getFormFields(element);
+ each(formFields, function (field) {
+ if (field.type !== 'boolean') {
+ selectOptions.push({ name: field.id, value: field.id });
+ }
+ });
+ return selectOptions;
+ },
+ get: function get(element, node) {
+ var result = { businessKey: '' };
+ var bo = getBusinessObject(element);
+ var formDataExtension = getExtensionElements(bo, 'camunda:FormData');
+ if (formDataExtension) {
+ var formData = formDataExtension[0];
+ var storedValue = formData.get('businessKey');
+ result = { businessKey: storedValue };
+ }
+ return result;
+ },
+ set: function set(element, values, node) {
+ var formData = getExtensionElements(getBusinessObject(element), 'camunda:FormData')[0];
+ return cmdHelper.updateBusinessObject(element, formData, { 'businessKey': values.businessKey || undefined });
+ },
+ hidden: function hidden(element, node) {
+ var isStartEvent = is(element, 'bpmn:StartEvent');
+ return !(isStartEvent && formHelper.getFormFields(element).length > 0);
+ }
+ });
+ group.entries.push(formBusinessKeyFormFieldEntry);
+
+ // [FormData] Form Field label
+ group.entries.push(entryFactory.label({
+ id: 'form-field-header',
+ labelText: translate('Form Field'),
+ showLabel: function showLabel(element, node) {
+ return !!getSelectedFormField(element, node);
+ }
+ }));
+
+ // [FormData] form field id text input field
+ group.entries.push(entryFactory.validationAwareTextField({
+ id: 'form-field-id',
+ label: translate('ID'),
+ modelProperty: 'id',
+
+ getProperty: function getProperty(element, node) {
+ var selectedFormField = getSelectedFormField(element, node) || {};
+
+ return selectedFormField.id;
+ },
+
+ setProperty: function setProperty(element, properties, node) {
+ var formField = getSelectedFormField(element, node);
+
+ return cmdHelper.updateBusinessObject(element, formField, properties);
+ },
+
+ hidden: function hidden(element, node) {
+ return !getSelectedFormField(element, node);
+ },
+
+ validate: function validate(element, values, node) {
+
+ var formField = getSelectedFormField(element, node);
+
+ if (formField) {
+
+ var idValue = values.id;
+
+ if (!idValue || idValue.trim() === '') {
+ return { id: 'Form field id must not be empty' };
+ }
+
+ var formFields = formHelper.getFormFields(element);
+
+ var existingFormField = find(formFields, function (f) {
+ return f !== formField && f.id === idValue;
+ });
+
+ if (existingFormField) {
+ return { id: 'Form field id already used in form data.' };
+ }
+ }
+ }
+ }));
+
+ // [FormData] form field type combo box
+ group.entries.push(entryFactory.comboBox({
+ id: 'form-field-type',
+ label: translate('Type'),
+ selectOptions: [{ name: 'string', value: 'string' }, { name: 'long', value: 'long' }, { name: 'boolean', value: 'boolean' }, { name: 'date', value: 'date' }, { name: 'enum', value: 'enum' }],
+ modelProperty: 'type',
+ emptyParameter: true,
+
+ get: function get(element, node) {
+ var selectedFormField = getSelectedFormField(element, node);
+
+ if (selectedFormField) {
+ return { type: selectedFormField.type };
+ } else {
+ return {};
+ }
+ },
+ set: function set(element, values, node) {
+ var selectedFormField = getSelectedFormField(element, node),
+ formData = getExtensionElements(getBusinessObject(element), 'camunda:FormData')[0],
+ commands = [];
+
+ if (selectedFormField.type === 'enum' && values.type !== 'enum') {
+ // delete camunda:value objects from formField.values when switching from type enum
+ commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, { values: undefined }));
+ }
+ if (values.type === 'boolean' && selectedFormField.get('id') === formData.get('businessKey')) {
+ commands.push(cmdHelper.updateBusinessObject(element, formData, { 'businessKey': undefined }));
+ }
+ commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, values));
+
+ return commands;
+ },
+ hidden: function hidden(element, node) {
+ return !getSelectedFormField(element, node);
+ }
+ }));
+
+ // [FormData] form field label text input field
+ group.entries.push(formFieldTextField({
+ id: 'form-field-label',
+ label: translate('Label'),
+ modelProperty: 'label'
+ }, getSelectedFormField));
+
+ // [FormData] form field defaultValue text input field
+ group.entries.push(formFieldTextField({
+ id: 'form-field-defaultValue',
+ label: translate('Default Value'),
+ modelProperty: 'defaultValue'
+ }, getSelectedFormField));
+
+ // [FormData] form field enum values label
+ group.entries.push(entryFactory.label({
+ id: 'form-field-enum-values-header',
+ labelText: translate('Values'),
+ divider: true,
+ showLabel: function showLabel(element, node) {
+ var selectedFormField = getSelectedFormField(element, node);
+
+ return selectedFormField && selectedFormField.type === 'enum';
+ }
+ }));
+
+ // [FormData] form field enum values table
+ group.entries.push(entryFactory.table({
+ id: 'form-field-enum-values',
+ labels: [translate('Id'), translate('Name')],
+ modelProperties: ['id', 'name'],
+ show: function show(element, node) {
+ var selectedFormField = getSelectedFormField(element, node);
+
+ return selectedFormField && selectedFormField.type === 'enum';
+ },
+ getElements: function getElements(element, node) {
+ var selectedFormField = getSelectedFormField(element, node);
+
+ return formHelper.getEnumValues(selectedFormField);
+ },
+ addElement: function addElement(element, node) {
+ var selectedFormField = getSelectedFormField(element, node),
+ id = generateValueId();
+
+ var enumValue = elementHelper.createElement('camunda:Value', { id: id, name: undefined }, getBusinessObject(element), bpmnFactory);
+
+ return cmdHelper.addElementsTolist(element, selectedFormField, 'values', [enumValue]);
+ },
+ removeElement: function removeElement(element, node, idx) {
+ var selectedFormField = getSelectedFormField(element, node),
+ enumValue = selectedFormField.values[idx];
+
+ return cmdHelper.removeElementsFromList(element, selectedFormField, 'values', null, [enumValue]);
+ },
+ updateElement: function updateElement(element, value, node, idx) {
+ var selectedFormField = getSelectedFormField(element, node),
+ enumValue = selectedFormField.values[idx];
+
+ value.name = value.name || undefined;
+ return cmdHelper.updateBusinessObject(element, enumValue, value);
+ },
+ validate: function validate(element, value, node, idx) {
+
+ var selectedFormField = getSelectedFormField(element, node),
+ enumValue = selectedFormField.values[idx];
+
+ if (enumValue) {
+ // check if id is valid
+ var validationError = utils.isIdValid(enumValue, value.id);
+
+ if (validationError) {
+ return { id: validationError };
+ }
+ }
+ }
+ }));
+
+ // [FormData] Validation label
+ group.entries.push(entryFactory.label({
+ id: 'form-field-validation-header',
+ labelText: translate('Validation'),
+ divider: true,
+ showLabel: function showLabel(element, node) {
+ return !!getSelectedFormField(element, node);
+ }
+ }));
+
+ // [FormData] form field constraints table
+ group.entries.push(entryFactory.table({
+ id: 'constraints-list',
+ modelProperties: ['name', 'config'],
+ labels: [translate('Name'), translate('Config')],
+ addLabel: translate('Add Constraint'),
+ getElements: function getElements(element, node) {
+ var formField = getSelectedFormField(element, node);
+
+ return formHelper.getConstraints(formField);
+ },
+ addElement: function addElement(element, node) {
+
+ var commands = [],
+ formField = getSelectedFormField(element, node),
+ validation = formField.validation;
+
+ if (!validation) {
+ // create validation business object and add it to form data, if it doesn't exist
+ validation = elementHelper.createElement('camunda:Validation', {}, getBusinessObject(element), bpmnFactory);
+
+ commands.push(cmdHelper.updateBusinessObject(element, formField, { 'validation': validation }));
+ }
+
+ var newConstraint = elementHelper.createElement('camunda:Constraint', { name: undefined, config: undefined }, validation, bpmnFactory);
+
+ commands.push(cmdHelper.addElementsTolist(element, validation, 'constraints', [newConstraint]));
+
+ return commands;
+ },
+ updateElement: function updateElement(element, value, node, idx) {
+ var formField = getSelectedFormField(element, node),
+ constraint = formHelper.getConstraints(formField)[idx];
+
+ value.name = value.name || undefined;
+ value.config = value.config || undefined;
+
+ return cmdHelper.updateBusinessObject(element, constraint, value);
+ },
+ removeElement: function removeElement(element, node, idx) {
+ var commands = [],
+ formField = getSelectedFormField(element, node),
+ constraints = formHelper.getConstraints(formField),
+ currentConstraint = constraints[idx];
+
+ commands.push(cmdHelper.removeElementsFromList(element, formField.validation, 'constraints', null, [currentConstraint]));
+
+ if (constraints.length === 1) {
+ // remove camunda:validation if the last existing constraint has been removed
+ commands.push(cmdHelper.updateBusinessObject(element, formField, { validation: undefined }));
+ }
+
+ return commands;
+ },
+ show: function show(element, node) {
+ return !!getSelectedFormField(element, node);
+ }
+ }));
+
+ // [FormData] Properties label
+ group.entries.push(entryFactory.label({
+ id: 'form-field-properties-header',
+ labelText: translate('Properties'),
+ divider: true,
+ showLabel: function showLabel(element, node) {
+ return !!getSelectedFormField(element, node);
+ }
+ }));
+
+ // [FormData] camunda:properties table
+ group.entries.push(properties(element, bpmnFactory, {
+ id: 'form-field-properties',
+ modelProperties: ['id', 'value'],
+ labels: [translate('Id'), translate('Value')],
+ getParent: function getParent(element, node) {
+ return getSelectedFormField(element, node);
+ },
+ show: function show(element, node) {
+ return !!getSelectedFormField(element, node);
+ }
+ }, translate));
+};
+
+},{"../../../Utils":5,"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"../../../helper/ElementHelper":25,"../../../helper/ExtensionElementsHelper":27,"../../../helper/FormHelper":28,"./implementation/ExtensionElements":90,"./implementation/Properties":102,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/find":421,"lodash/collection/forEach":422}],71:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ _getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var historyTimeToLive = require('./implementation/HistoryTimeToLive');
+
+module.exports = function (group, element, bpmnFactory, translate) {
+ var businessObject = _getBusinessObject(element);
+
+ if (is(element, 'camunda:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
+
+ group.entries = group.entries.concat(historyTimeToLive(element, bpmnFactory, {
+ getBusinessObject: function getBusinessObject(element) {
+ var bo = _getBusinessObject(element);
+
+ if (!is(bo, 'bpmn:Participant')) {
+ return bo;
+ }
+
+ return bo.get('processRef');
+ }
+ }, translate));
+ }
+};
+
+},{"./implementation/HistoryTimeToLive":94,"bpmn-js/lib/util/ModelUtil":216}],72:[function(require,module,exports){
+'use strict';
+
+var inputOutputParameter = require('./implementation/InputOutputParameter');
+
+var assign = require('lodash/object/assign');
+
+module.exports = function (group, element, bpmnFactory, options, translate) {
+
+ group.entries = group.entries.concat(inputOutputParameter(element, bpmnFactory, assign({}, options), translate));
+};
+
+},{"./implementation/InputOutputParameter":97,"lodash/object/assign":496}],73:[function(require,module,exports){
+'use strict';
+
+var inputOutput = require('./implementation/InputOutput');
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ var inputOutputEntry = inputOutput(element, bpmnFactory, {}, translate);
+
+ group.entries = group.entries.concat(inputOutputEntry.entries);
+
+ return {
+ getSelectedParameter: inputOutputEntry.getSelectedParameter
+ };
+};
+
+},{"./implementation/InputOutput":96}],74:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ _getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var jobPriority = require('./implementation/JobPriority'),
+ jobRetryTimeCycle = require('./implementation/JobRetryTimeCycle');
+
+module.exports = function (group, element, bpmnFactory, translate) {
+ var businessObject = _getBusinessObject(element);
+
+ if (is(element, 'camunda:JobPriorized') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
+
+ group.entries = group.entries.concat(jobPriority(element, bpmnFactory, {
+ getBusinessObject: function getBusinessObject(element) {
+ var bo = _getBusinessObject(element);
+
+ if (!is(bo, 'bpmn:Participant')) {
+ return bo;
+ }
+
+ return bo.get('processRef');
+ }
+ }, translate));
+ }
+
+ if (is(element, 'camunda:AsyncCapable')) {
+ group.entries = group.entries.concat(jobRetryTimeCycle(element, bpmnFactory, {
+ getBusinessObject: _getBusinessObject
+ }, translate));
+ }
+};
+
+},{"./implementation/JobPriority":98,"./implementation/JobRetryTimeCycle":99,"bpmn-js/lib/util/ModelUtil":216}],75:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../factory/EntryFactory');
+
+var cmdHelper = require('../../../helper/CmdHelper'),
+ ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'),
+ script = require('./implementation/Script')('scriptFormat', 'value', true);
+
+var LISTENER_TYPE_LABEL = {
+ class: 'Java Class',
+ expression: 'Expression',
+ delegateExpression: 'Delegate Expression',
+ script: 'Script'
+};
+
+module.exports = function (group, element, bpmnFactory, options, translate) {
+
+ options = options || {};
+
+ var getSelectedListener = options.getSelectedListener;
+
+ var classProp = 'class',
+ expressionProp = 'expression',
+ delegateExpressionProp = 'delegateExpression',
+ scriptProp = 'script';
+
+ var executionListenerEventTypeOptions = ImplementationTypeHelper.isSequenceFlow(element) ? [{ name: 'take', value: 'take' }] : [{ name: 'start', value: 'start' }, { name: 'end', value: 'end' }];
+
+ var taskListenerEventTypeOptions = [{ name: 'create', value: 'create' }, { name: 'assignment', value: 'assignment' }, { name: 'complete', value: 'complete' }, { name: 'delete', value: 'delete' }];
+
+ var isSelected = function isSelected(element, node) {
+ return getSelectedListener(element, node);
+ };
+
+ group.entries.push(entryFactory.selectBox({
+ id: 'listener-event-type',
+ label: translate('Event Type'),
+ modelProperty: 'eventType',
+ emptyParameter: false,
+
+ get: function get(element, node) {
+
+ var listener = getSelectedListener(element, node);
+
+ var eventType = listener && listener.get('event');
+
+ return {
+ eventType: eventType
+ };
+ },
+
+ set: function set(element, values, node) {
+ var eventType = values.eventType;
+
+ return cmdHelper.updateBusinessObject(element, getSelectedListener(element, node), { event: eventType });
+ },
+
+ selectOptions: function selectOptions(element, node) {
+ var eventTypeOptions;
+
+ var selectedListener = getSelectedListener(element, node);
+ if (ImplementationTypeHelper.isTaskListener(selectedListener)) {
+ eventTypeOptions = taskListenerEventTypeOptions;
+ } else if (ImplementationTypeHelper.isExecutionListener(selectedListener)) {
+ eventTypeOptions = executionListenerEventTypeOptions;
+ }
+
+ return eventTypeOptions;
+ },
+
+ hidden: function hidden(element, node) {
+ return !isSelected(element, node);
+ }
+
+ }));
+
+ group.entries.push(entryFactory.selectBox({
+ id: 'listener-type',
+ label: translate('Listener Type'),
+ selectOptions: [{ value: classProp, name: translate('Java Class') }, { value: expressionProp, name: translate('Expression') }, { value: delegateExpressionProp, name: translate('Delegate Expression') }, { value: scriptProp, name: translate('Script') }],
+ modelProperty: 'listenerType',
+ emptyParameter: false,
+
+ get: function get(element, node) {
+ var listener = getSelectedListener(element, node);
+ return {
+ listenerType: ImplementationTypeHelper.getImplementationType(listener)
+ };
+ },
+
+ set: function set(element, values, node) {
+ var listener = getSelectedListener(element, node),
+ listenerType = values.listenerType || undefined,
+ update = {};
+
+ update[classProp] = listenerType === classProp ? '' : undefined;
+ update[expressionProp] = listenerType === expressionProp ? '' : undefined;
+ update[delegateExpressionProp] = listenerType === delegateExpressionProp ? '' : undefined;
+ update[scriptProp] = listenerType === scriptProp ? bpmnFactory.create('camunda:Script') : undefined;
+
+ return cmdHelper.updateBusinessObject(element, listener, update);
+ },
+
+ hidden: function hidden(element, node) {
+ return !isSelected(element, node);
+ }
+
+ }));
+
+ group.entries.push(entryFactory.textField({
+ id: 'listener-value',
+ dataValueLabel: 'listenerValueLabel',
+ modelProperty: 'listenerValue',
+
+ get: function get(element, node) {
+ var value = {},
+ listener = getSelectedListener(element, node),
+ listenerType = ImplementationTypeHelper.getImplementationType(listener);
+
+ value.listenerValueLabel = LISTENER_TYPE_LABEL[listenerType] || '';
+ value.listenerValue = listener && listener.get(listenerType) || undefined;
+
+ return value;
+ },
+
+ set: function set(element, values, node) {
+ var update = {},
+ listener = getSelectedListener(element, node),
+ listenerType = ImplementationTypeHelper.getImplementationType(listener);
+
+ update[listenerType] = values.listenerValue || '';
+
+ return cmdHelper.updateBusinessObject(element, listener, update);
+ },
+
+ hidden: function hidden(element, node) {
+ var listener = getSelectedListener(element, node);
+ return !listener || listener.script;
+ },
+
+ validate: function validate(element, values) {
+ var value = values.listenerValue,
+ validate = {};
+
+ if (!value) {
+ validate.listenerValue = translate('Must provide a value');
+ }
+
+ return validate;
+ }
+
+ }));
+
+ group.entries.push({
+ id: 'listener-script-value',
+ html: '' + script.template + '
',
+
+ get: function get(element, node) {
+ var listener = getSelectedListener(element, node);
+ return listener && listener.script ? script.get(element, listener.script) : {};
+ },
+
+ set: function set(element, values, node) {
+ var listener = getSelectedListener(element, node);
+ var update = script.set(element, values, listener);
+ return cmdHelper.updateBusinessObject(element, listener.script, update);
+ },
+
+ validate: function validate(element, values, node) {
+ var listener = getSelectedListener(element, node);
+ return listener && listener.script ? script.validate(element, values) : {};
+ },
+
+ isScript: function isScript(element, node) {
+ var listener = getSelectedListener(element, node);
+ return listener && listener.script;
+ },
+
+ script: script
+
+ });
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"../../../helper/ImplementationTypeHelper":29,"./implementation/Script":104}],76:[function(require,module,exports){
+'use strict';
+
+var assign = require('lodash/object/assign');
+
+var fieldInjection = require('./implementation/FieldInjection');
+
+module.exports = function (group, element, bpmnFactory, options, translate) {
+
+ options = assign({
+ idPrefix: 'listener-',
+ insideListener: true
+ }, options);
+
+ var fieldInjectionEntry = fieldInjection(element, bpmnFactory, translate, options);
+
+ if (fieldInjectionEntry && fieldInjectionEntry.length > 0) {
+ group.entries = group.entries.concat(fieldInjectionEntry);
+ }
+};
+
+},{"./implementation/FieldInjection":93,"lodash/object/assign":496}],77:[function(require,module,exports){
+'use strict';
+
+var listener = require('./implementation/Listener');
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ var listenerEntry = listener(element, bpmnFactory, {}, translate);
+
+ group.entries = group.entries.concat(listenerEntry.entries);
+
+ return {
+ getSelectedListener: listenerEntry.getSelectedListener
+ };
+};
+
+},{"./implementation/Listener":100}],78:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var multiInstanceLoopCharacteristics = require('./implementation/MultiInstanceLoopCharacteristics');
+
+var jobRetryTimeCycle = require('./implementation/JobRetryTimeCycle'),
+ asyncContinuation = require('./implementation/AsyncContinuation');
+
+function getLoopCharacteristics(element) {
+ var bo = getBusinessObject(element);
+ return bo.loopCharacteristics;
+}
+
+function ensureMultiInstanceSupported(element) {
+ var loopCharacteristics = getLoopCharacteristics(element);
+ return !!loopCharacteristics && is(loopCharacteristics, 'camunda:Collectable');
+}
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ if (!ensureMultiInstanceSupported(element)) {
+ return;
+ }
+
+ // multi instance properties
+ group.entries = group.entries.concat(multiInstanceLoopCharacteristics(element, bpmnFactory, translate));
+
+ // async continuation ///////////////////////////////////////////////////////
+ group.entries = group.entries.concat(asyncContinuation(element, bpmnFactory, {
+ getBusinessObject: getLoopCharacteristics,
+ idPrefix: 'multiInstance-',
+ labelPrefix: translate('Multi Instance ')
+ }, translate));
+
+ // retry time cycle //////////////////////////////////////////////////////////
+ group.entries = group.entries.concat(jobRetryTimeCycle(element, bpmnFactory, {
+ getBusinessObject: getLoopCharacteristics,
+ idPrefix: 'multiInstance-',
+ labelPrefix: translate('Multi Instance ')
+ }, translate));
+};
+
+},{"./implementation/AsyncContinuation":87,"./implementation/JobRetryTimeCycle":99,"./implementation/MultiInstanceLoopCharacteristics":101,"bpmn-js/lib/util/ModelUtil":216}],79:[function(require,module,exports){
+'use strict';
+
+var properties = require('./implementation/Properties'),
+ elementHelper = require('../../../helper/ElementHelper'),
+ cmdHelper = require('../../../helper/CmdHelper');
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ var propertiesEntry = properties(element, bpmnFactory, {
+ id: 'properties',
+ modelProperties: ['name', 'value'],
+ labels: [translate('Name'), translate('Value')],
+
+ getParent: function getParent(element, node, bo) {
+ return bo.extensionElements;
+ },
+
+ createParent: function createParent(element, bo) {
+ var parent = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
+ var cmd = cmdHelper.updateBusinessObject(element, bo, { extensionElements: parent });
+ return {
+ cmd: cmd,
+ parent: parent
+ };
+ }
+ }, translate);
+
+ if (propertiesEntry) {
+ group.entries.push(propertiesEntry);
+ }
+};
+
+},{"../../../helper/CmdHelper":24,"../../../helper/ElementHelper":25,"./implementation/Properties":102}],80:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ is = require('bpmn-js/lib/util/ModelUtil').is,
+ entryFactory = require('../../../factory/EntryFactory'),
+ cmdHelper = require('../../../helper/CmdHelper'),
+ script = require('./implementation/Script')('scriptFormat', 'script', false);
+
+module.exports = function (group, element, bpmnFactory, translate) {
+ var bo;
+
+ if (is(element, 'bpmn:ScriptTask')) {
+ bo = getBusinessObject(element);
+ }
+
+ if (!bo) {
+ return;
+ }
+
+ group.entries.push({
+ id: 'script-implementation',
+ label: translate('Script'),
+ html: script.template,
+
+ get: function get(element) {
+ return script.get(element, bo);
+ },
+
+ set: function set(element, values, containerElement) {
+ var properties = script.set(element, values, containerElement);
+
+ return cmdHelper.updateProperties(element, properties);
+ },
+
+ validate: function validate(element, values) {
+ return script.validate(element, values);
+ },
+
+ script: script,
+
+ cssClasses: ['bpp-textfield']
+
+ });
+
+ group.entries.push(entryFactory.textField({
+ id: 'scriptResultVariable',
+ label: translate('Result Variable'),
+ modelProperty: 'scriptResultVariable',
+
+ get: function get(element, propertyName) {
+ var boResultVariable = bo.get('camunda:resultVariable');
+
+ return { scriptResultVariable: boResultVariable };
+ },
+
+ set: function set(element, values, containerElement) {
+ return cmdHelper.updateProperties(element, {
+ 'camunda:resultVariable': values.scriptResultVariable.length ? values.scriptResultVariable : undefined
+ });
+ }
+
+ }));
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"./implementation/Script":104,"bpmn-js/lib/util/ModelUtil":216}],81:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ domQuery = require('min-dom/lib/query'),
+ cmdHelper = require('../../../helper/CmdHelper'),
+ elementHelper = require('../../../helper/ElementHelper'),
+ script = require('./implementation/Script')('language', 'body', true);
+
+module.exports = function (group, element, bpmnFactory, translate) {
+ var bo;
+
+ if (is(element, 'bpmn:SequenceFlow')) {
+ bo = getBusinessObject(element);
+ }
+
+ if (!bo) {
+ return;
+ }
+
+ if (!isConditionalSource(element.source)) {
+ return;
+ }
+
+ group.entries.push({
+ id: 'condition',
+ label: translate('Condition'),
+ html: '' + '
' + translate('Condition Type') + ' ' + '
' + '' + '' + translate('Expression') + ' ' + '' + translate('Script') + ' ' + ' ' + ' ' + '
' + '
' +
+
+ // expression
+ '' + '
' + translate('Expression') + ' ' + '
' + ' ' + '' + 'X ' + ' ' + '
' + '
' + script.template + '
' + '
',
+
+ get: function get(element, propertyName) {
+
+ // read values from xml:
+ var conditionExpression = bo.conditionExpression;
+
+ var values = {},
+ conditionType = '';
+
+ if (conditionExpression) {
+ var conditionLanguage = conditionExpression.language;
+ if (typeof conditionLanguage !== 'undefined') {
+ conditionType = 'script';
+ values = script.get(element, conditionExpression);
+ } else {
+ conditionType = 'expression';
+ values.condition = conditionExpression.get('body');
+ }
+ }
+
+ values.conditionType = conditionType;
+
+ return values;
+ },
+
+ set: function set(element, values, containerElement) {
+ var conditionType = values.conditionType;
+ var commands = [];
+
+ var conditionProps = {
+ body: undefined
+ };
+
+ if (conditionType === 'script') {
+ conditionProps = script.set(element, values, containerElement);
+ } else {
+ var condition = values.condition;
+ conditionProps.body = condition;
+ }
+
+ var update = {
+ 'conditionExpression': undefined
+ };
+
+ if (conditionType) {
+ update.conditionExpression = elementHelper.createElement('bpmn:FormalExpression', conditionProps, bo, bpmnFactory);
+
+ var source = element.source;
+
+ // if default-flow, remove default-property from source
+ if (source.businessObject.default === bo) {
+ commands.push(cmdHelper.updateProperties(source, { 'default': undefined }));
+ }
+ }
+
+ commands.push(cmdHelper.updateBusinessObject(element, bo, update));
+
+ return commands;
+ },
+
+ validate: function validate(element, values) {
+ var validationResult = {};
+
+ if (!values.condition && values.conditionType === 'expression') {
+ validationResult.condition = 'Must provide a value';
+ } else if (values.conditionType === 'script') {
+ validationResult = script.validate(element, values);
+ }
+
+ return validationResult;
+ },
+
+ isExpression: function isExpression(element, inputNode) {
+ var conditionType = domQuery('select[name=conditionType]', inputNode);
+ if (conditionType.selectedIndex >= 0) {
+ return conditionType.options[conditionType.selectedIndex].value === 'expression';
+ }
+ },
+
+ isScript: function isScript(element, inputNode) {
+ var conditionType = domQuery('select[name=conditionType]', inputNode);
+ if (conditionType.selectedIndex >= 0) {
+ return conditionType.options[conditionType.selectedIndex].value === 'script';
+ }
+ },
+
+ clear: function clear(element, inputNode) {
+ // clear text input
+ domQuery('input[name=condition]', inputNode).value = '';
+
+ return true;
+ },
+
+ canClear: function canClear(element, inputNode) {
+ var input = domQuery('input[name=condition]', inputNode);
+
+ return input.value !== '';
+ },
+
+ script: script,
+
+ cssClasses: ['bpp-textfield']
+ });
+};
+
+////// utilities //////////////////////////
+
+var CONDITIONAL_SOURCES = ['bpmn:Activity', 'bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:ComplexGateway'];
+
+function isConditionalSource(element) {
+ return isAny(element, CONDITIONAL_SOURCES);
+}
+
+},{"../../../helper/CmdHelper":24,"../../../helper/ElementHelper":25,"./implementation/Script":104,"bpmn-js/lib/features/modeling/util/ModelingUtil":189,"bpmn-js/lib/util/ModelUtil":216,"min-dom/lib/query":112}],82:[function(require,module,exports){
+'use strict';
+
+var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'),
+ InputOutputHelper = require('../../../helper/InputOutputHelper');
+
+var implementationType = require('./implementation/ImplementationType'),
+ delegate = require('./implementation/Delegate'),
+ external = require('./implementation/External'),
+ callable = require('./implementation/Callable'),
+ resultVariable = require('./implementation/ResultVariable');
+
+var entryFactory = require('../../../factory/EntryFactory');
+
+var domQuery = require('min-dom/lib/query'),
+ domClosest = require('min-dom/lib/closest'),
+ domClasses = require('min-dom/lib/classes');
+
+function getImplementationType(element) {
+ return ImplementationTypeHelper.getImplementationType(element);
+}
+
+function getBusinessObject(element) {
+ return ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element);
+}
+
+function isDmnCapable(element) {
+ return ImplementationTypeHelper.isDmnCapable(element);
+}
+
+function isExternalCapable(element) {
+ return ImplementationTypeHelper.isExternalCapable(element);
+}
+
+function isServiceTaskLike(element) {
+ return ImplementationTypeHelper.isServiceTaskLike(element);
+}
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ if (!isServiceTaskLike(getBusinessObject(element))) {
+ return;
+ }
+
+ var hasDmnSupport = isDmnCapable(element);
+ var hasExternalSupport = isExternalCapable(getBusinessObject(element));
+
+ // implementation type ////////////////////////////////////
+
+ group.entries = group.entries.concat(implementationType(element, bpmnFactory, {
+ getBusinessObject: getBusinessObject,
+ getImplementationType: getImplementationType,
+ hasDmnSupport: hasDmnSupport,
+ hasExternalSupport: hasExternalSupport,
+ hasServiceTaskLikeSupport: true
+ }, translate));
+
+ // delegate (class, expression, delegateExpression) //////////
+
+ group.entries = group.entries.concat(delegate(element, bpmnFactory, {
+ getBusinessObject: getBusinessObject,
+ getImplementationType: getImplementationType
+ }, translate));
+
+ // result variable /////////////////////////////////////////
+
+ group.entries = group.entries.concat(resultVariable(element, bpmnFactory, {
+ getBusinessObject: getBusinessObject,
+ getImplementationType: getImplementationType,
+ hideResultVariable: function hideResultVariable(element, node) {
+ return getImplementationType(element) !== 'expression';
+ }
+ }, translate));
+
+ // external //////////////////////////////////////////////////
+
+ if (hasExternalSupport) {
+ group.entries = group.entries.concat(external(element, bpmnFactory, {
+ getBusinessObject: getBusinessObject,
+ getImplementationType: getImplementationType
+ }, translate));
+ }
+
+ // dmn ////////////////////////////////////////////////////////
+
+ if (hasDmnSupport) {
+ group.entries = group.entries.concat(callable(element, bpmnFactory, {
+ getCallableType: getImplementationType
+ }, translate));
+ }
+
+ // connector ////////////////////////////////////////////////
+
+ var isConnector = function isConnector(element) {
+ return getImplementationType(element) === 'connector';
+ };
+
+ group.entries.push(entryFactory.link({
+ id: 'configureConnectorLink',
+ label: translate('Configure Connector'),
+ getClickableElement: function getClickableElement(element, node) {
+ var panel = domClosest(node, 'div.bpp-properties-panel');
+ return domQuery('a[data-tab-target="connector"]', panel);
+ },
+ hideLink: function hideLink(element, node) {
+ var link = domQuery('a', node);
+ link.innerHTML = link.textContent = '';
+ domClasses(link).remove('bpp-error-message');
+
+ if (isConnector(element)) {
+ var connectorId = InputOutputHelper.getConnector(element).get('connectorId');
+ if (connectorId) {
+ link.textContent = translate('Configure Connector');
+ } else {
+ link.innerHTML = ' Must configure Connector';
+ domClasses(link).add('bpp-error-message');
+ }
+
+ return false;
+ }
+ return true;
+ }
+ }));
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/ImplementationTypeHelper":29,"../../../helper/InputOutputHelper":30,"./implementation/Callable":88,"./implementation/Delegate":89,"./implementation/External":91,"./implementation/ImplementationType":95,"./implementation/ResultVariable":103,"min-dom/lib/classes":106,"min-dom/lib/closest":108,"min-dom/lib/query":112}],83:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../factory/EntryFactory'),
+ is = require('bpmn-js/lib/util/ModelUtil').is,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+module.exports = function (group, element, translate) {
+
+ var bo = getBusinessObject(element);
+
+ if (!bo) {
+ return;
+ }
+
+ if (is(element, 'camunda:Initiator') && !is(element.parent, 'bpmn:SubProcess')) {
+ group.entries.push(entryFactory.textField({
+ id: 'initiator',
+ label: translate('Initiator'),
+ modelProperty: 'initiator'
+ }));
+ }
+};
+
+},{"../../../factory/EntryFactory":14,"bpmn-js/lib/util/ModelUtil":216}],84:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ entryFactory = require('../../../factory/EntryFactory');
+
+module.exports = function (group, element, translate) {
+ if (is(element, 'camunda:Assignable')) {
+
+ // Assignee
+ group.entries.push(entryFactory.textField({
+ id: 'assignee',
+ label: translate('Assignee'),
+ modelProperty: 'assignee'
+ }));
+
+ // Candidate Users
+ group.entries.push(entryFactory.textField({
+ id: 'candidateUsers',
+ label: translate('Candidate Users'),
+ modelProperty: 'candidateUsers'
+ }));
+
+ // Candidate Groups
+ group.entries.push(entryFactory.textField({
+ id: 'candidateGroups',
+ label: translate('Candidate Groups'),
+ modelProperty: 'candidateGroups'
+ }));
+
+ // Due Date
+ group.entries.push(entryFactory.textField({
+ id: 'dueDate',
+ description: translate('The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)'),
+ label: translate('Due Date'),
+ modelProperty: 'dueDate'
+ }));
+
+ // FollowUp Date
+ group.entries.push(entryFactory.textField({
+ id: 'followUpDate',
+ description: translate('The follow up date as an EL expression (e.g. ${someDate} or an ' + 'ISO date (e.g. 2015-06-26T09:54:00)'),
+ label: translate('Follow Up Date'),
+ modelProperty: 'followUpDate'
+ }));
+
+ // priority
+ group.entries.push(entryFactory.textField({
+ id: 'priority',
+ label: translate('Priority'),
+ modelProperty: 'priority'
+ }));
+ }
+};
+
+},{"../../../factory/EntryFactory":14,"bpmn-js/lib/util/ModelUtil":216}],85:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var filter = require('lodash/collection/filter');
+
+var extensionElementsHelper = require('../../../helper/ExtensionElementsHelper'),
+ cmdHelper = require('../../../helper/CmdHelper'),
+ elementHelper = require('../../../helper/ElementHelper');
+
+var extensionElementsEntry = require('./implementation/ExtensionElements');
+
+var entryFactory = require('../../../factory/EntryFactory');
+
+var inOutTypeOptions = [{
+ name: 'Source',
+ value: 'source'
+}, {
+ name: 'Source Expression',
+ value: 'sourceExpression'
+}, {
+ name: 'All',
+ value: 'variables'
+}];
+
+/**
+ * return depend on parameter 'type' camunda:in or camunda:out extension elements
+ */
+function getCamundaInOutMappings(element, type) {
+ var bo = getBusinessObject(element);
+ return extensionElementsHelper.getExtensionElements(bo, type) || [];
+}
+
+/**
+ * return depend on parameter 'type' camunda:in or camunda:out extension elements
+ * with source or sourceExpression attribute
+ */
+function getVariableMappings(element, type) {
+ var camundaMappings = getCamundaInOutMappings(element, type);
+ return filter(camundaMappings, function (mapping) {
+ return !mapping.businessKey;
+ });
+}
+
+function getInOutType(mapping) {
+ var inOutType = 'source';
+
+ if (mapping.variables === 'all') {
+ inOutType = 'variables';
+ } else if (typeof mapping.source !== 'undefined') {
+ inOutType = 'source';
+ } else if (typeof mapping.sourceExpression !== 'undefined') {
+ inOutType = 'sourceExpression';
+ }
+
+ return inOutType;
+}
+
+var CAMUNDA_IN_EXTENSION_ELEMENT = 'camunda:In',
+ CAMUNDA_OUT_EXTENSION_ELEMENT = 'camunda:Out';
+
+module.exports = function (group, element, bpmnFactory, translate) {
+
+ if (!is(element, 'camunda:CallActivity')) {
+ return;
+ }
+
+ var isSelected = function isSelected(element, node) {
+ return !!getSelected(element, node);
+ };
+
+ var getSelected = function getSelected(element, node) {
+ var parentNode = node.parentNode;
+ var selection = inEntry.getSelected(element, parentNode);
+
+ var parameter = getVariableMappings(element, CAMUNDA_IN_EXTENSION_ELEMENT)[selection.idx];
+ if (!parameter && outEntry) {
+ selection = outEntry.getSelected(element, parentNode);
+ parameter = getVariableMappings(element, CAMUNDA_OUT_EXTENSION_ELEMENT)[selection.idx];
+ }
+ return parameter;
+ };
+
+ var setOptionLabelValue = function setOptionLabelValue(type) {
+ return function (element, node, option, property, value, idx) {
+ var label = idx + ' : ';
+
+ var variableMappings = getVariableMappings(element, type);
+ var mappingValue = variableMappings[idx];
+ var mappingType = getInOutType(mappingValue);
+
+ if (mappingType === 'variables') {
+ label = label + 'all';
+ } else if (mappingType === 'source') {
+ label = label + (mappingValue.source || '');
+ } else if (mappingType === 'sourceExpression') {
+ label = label + (mappingValue.sourceExpression || '');
+ } else {
+ label = label + '';
+ }
+
+ option.text = label;
+ };
+ };
+
+ var newElement = function newElement(type) {
+ return function (element, extensionElements, value) {
+ var newElem = elementHelper.createElement(type, { source: '' }, extensionElements, bpmnFactory);
+ return cmdHelper.addElementsTolist(element, extensionElements, 'values', [newElem]);
+ };
+ };
+
+ var removeElement = function removeElement(type) {
+ return function (element, extensionElements, value, idx) {
+ var variablesMappings = getVariableMappings(element, type);
+ var mapping = variablesMappings[idx];
+ if (mapping) {
+ return extensionElementsHelper.removeEntry(getBusinessObject(element), element, mapping);
+ }
+ };
+ };
+
+ // in mapping for source and sourceExpression ///////////////////////////////////////////////////////////////
+
+ var inEntry = extensionElementsEntry(element, bpmnFactory, {
+ id: 'variableMapping-in',
+ label: translate('In Mapping'),
+ modelProperty: 'source',
+ prefix: 'In',
+ idGeneration: false,
+ resizable: true,
+
+ createExtensionElement: newElement(CAMUNDA_IN_EXTENSION_ELEMENT),
+ removeExtensionElement: removeElement(CAMUNDA_IN_EXTENSION_ELEMENT),
+
+ getExtensionElements: function getExtensionElements(element) {
+ return getVariableMappings(element, CAMUNDA_IN_EXTENSION_ELEMENT);
+ },
+
+ onSelectionChange: function onSelectionChange(element, node, event, scope) {
+ outEntry && outEntry.deselect(element, node.parentNode);
+ },
+
+ setOptionLabelValue: setOptionLabelValue(CAMUNDA_IN_EXTENSION_ELEMENT)
+ });
+ group.entries.push(inEntry);
+
+ // out mapping for source and sourceExpression ///////////////////////////////////////////////////////
+
+ var outEntry = extensionElementsEntry(element, bpmnFactory, {
+ id: 'variableMapping-out',
+ label: translate('Out Mapping'),
+ modelProperty: 'source',
+ prefix: 'Out',
+ idGeneration: false,
+ resizable: true,
+
+ createExtensionElement: newElement(CAMUNDA_OUT_EXTENSION_ELEMENT),
+ removeExtensionElement: removeElement(CAMUNDA_OUT_EXTENSION_ELEMENT),
+
+ getExtensionElements: function getExtensionElements(element) {
+ return getVariableMappings(element, CAMUNDA_OUT_EXTENSION_ELEMENT);
+ },
+
+ onSelectionChange: function onSelectionChange(element, node, event, scope) {
+ inEntry.deselect(element, node.parentNode);
+ },
+
+ setOptionLabelValue: setOptionLabelValue(CAMUNDA_OUT_EXTENSION_ELEMENT)
+ });
+ group.entries.push(outEntry);
+
+ // label for selected mapping ///////////////////////////////////////////////////////
+
+ group.entries.push(entryFactory.label({
+ id: 'variableMapping-typeLabel',
+ get: function get(element, node) {
+ var mapping = getSelected(element, node);
+
+ var value = '';
+ if (is(mapping, CAMUNDA_IN_EXTENSION_ELEMENT)) {
+ value = translate('In Mapping');
+ } else if (is(mapping, CAMUNDA_OUT_EXTENSION_ELEMENT)) {
+ value = translate('Out Mapping');
+ }
+
+ return {
+ label: value
+ };
+ },
+
+ showLabel: function showLabel(element, node) {
+ return isSelected(element, node);
+ }
+ }));
+
+ group.entries.push(entryFactory.selectBox({
+ id: 'variableMapping-inOutType',
+ label: translate('Type'),
+ selectOptions: inOutTypeOptions,
+ modelProperty: 'inOutType',
+ get: function get(element, node) {
+ var mapping = getSelected(element, node) || {};
+ return {
+ inOutType: getInOutType(mapping)
+ };
+ },
+ set: function set(element, values, node) {
+ var inOutType = values.inOutType;
+
+ var props = {
+ 'source': undefined,
+ 'sourceExpression': undefined,
+ 'variables': undefined
+ };
+
+ if (inOutType === 'source') {
+ props.source = '';
+ } else if (inOutType === 'sourceExpression') {
+ props.sourceExpression = '';
+ } else if (inOutType === 'variables') {
+ props.variables = 'all';
+ }
+
+ var mapping = getSelected(element, node);
+ return cmdHelper.updateBusinessObject(element, mapping, props);
+ },
+ hidden: function hidden(element, node) {
+ return !isSelected(element, node);
+ }
+
+ }));
+
+ group.entries.push(entryFactory.textField({
+ id: 'variableMapping-source',
+ dataValueLabel: 'sourceLabel',
+ modelProperty: 'source',
+ get: function get(element, node) {
+ var mapping = getSelected(element, node) || {};
+
+ var label = '';
+ var inOutType = getInOutType(mapping);
+ if (inOutType === 'source') {
+ label = 'Source';
+ } else if (inOutType === 'sourceExpression') {
+ label = 'Source Expression';
+ }
+
+ return {
+ source: mapping[inOutType],
+ sourceLabel: label
+ };
+ },
+ set: function set(element, values, node) {
+ values.source = values.source || undefined;
+
+ var mapping = getSelected(element, node);
+ var inOutType = getInOutType(mapping);
+
+ var props = {};
+ props[inOutType] = values.source || '';
+
+ return cmdHelper.updateBusinessObject(element, mapping, props);
+ },
+ // one of both (source or sourceExpression) must have a value to make
+ // the configuration easier and more understandable
+ // it is not engine conform
+ validate: function validate(element, values, node) {
+ var mapping = getSelected(element, node);
+
+ var validation = {};
+ if (mapping) {
+ if (!values.source) {
+ validation.source = 'Mapping must have a ' + values.sourceLabel.toLowerCase() || 'value';
+ }
+ }
+
+ return validation;
+ },
+ hidden: function hidden(element, node) {
+ var selectedMapping = getSelected(element, node);
+ return !selectedMapping || selectedMapping && selectedMapping.variables;
+ }
+ }));
+
+ group.entries.push(entryFactory.textField({
+ id: 'variableMapping-target',
+ label: translate('Target'),
+ modelProperty: 'target',
+ get: function get(element, node) {
+ return {
+ target: (getSelected(element, node) || {}).target
+ };
+ },
+ set: function set(element, values, node) {
+ values.target = values.target || undefined;
+ var mapping = getSelected(element, node);
+ return cmdHelper.updateBusinessObject(element, mapping, values);
+ },
+ validate: function validate(element, values, node) {
+ var mapping = getSelected(element, node);
+
+ var validation = {};
+ if (mapping) {
+ var mappingType = getInOutType(mapping);
+ if (!values.target && mappingType !== 'variables') {
+ validation.target = 'Mapping must have a target';
+ }
+ }
+
+ return validation;
+ },
+ hidden: function hidden(element, node) {
+ var selectedMapping = getSelected(element, node);
+ return !selectedMapping || selectedMapping && selectedMapping.variables;
+ }
+ }));
+
+ group.entries.push(entryFactory.checkbox({
+ id: 'variableMapping-local',
+ label: translate('Local'),
+ modelProperty: 'local',
+ get: function get(element, node) {
+ return {
+ local: (getSelected(element, node) || {}).local
+ };
+ },
+ set: function set(element, values, node) {
+ values.local = values.local || false;
+ var mapping = getSelected(element, node);
+ return cmdHelper.updateBusinessObject(element, mapping, values);
+ },
+ hidden: function hidden(element, node) {
+ return !isSelected(element, node);
+ }
+ }));
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"../../../helper/ElementHelper":25,"../../../helper/ExtensionElementsHelper":27,"./implementation/ExtensionElements":90,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/filter":420}],86:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../factory/EntryFactory'),
+ cmdHelper = require('../../../helper/CmdHelper'),
+ is = require('bpmn-js/lib/util/ModelUtil').is,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+module.exports = function (group, element, translate) {
+
+ var bo = getBusinessObject(element);
+
+ if (!bo) {
+ return;
+ }
+
+ if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && bo.get('processRef')) {
+ var versionTagEntry = entryFactory.textField({
+ id: 'versionTag',
+ label: translate('Version Tag'),
+ modelProperty: 'versionTag'
+ });
+
+ // in participants we have to change the default behavior of set and get
+ if (is(element, 'bpmn:Participant')) {
+ versionTagEntry.get = function (element) {
+ var processBo = bo.get('processRef');
+
+ return {
+ versionTag: processBo.get('camunda:versionTag')
+ };
+ };
+
+ versionTagEntry.set = function (element, values) {
+ var processBo = bo.get('processRef');
+
+ return cmdHelper.updateBusinessObject(element, processBo, {
+ 'camunda:versionTag': values.versionTag || undefined
+ });
+ };
+ }
+
+ group.entries.push(versionTagEntry);
+ }
+};
+
+},{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216}],87:[function(require,module,exports){
+'use strict';
+
+var assign = require('lodash/object/assign');
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper'),
+ eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+function isAsyncBefore(bo) {
+ return asyncCapableHelper.isAsyncBefore(bo);
+}
+
+function isAsyncAfter(bo) {
+ return asyncCapableHelper.isAsyncAfter(bo);
+}
+
+function isExclusive(bo) {
+ return asyncCapableHelper.isExclusive(bo);
+}
+
+function removeFailedJobRetryTimeCycle(bo, element) {
+ return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element);
+}
+
+function canRemoveFailedJobRetryTimeCycle(element) {
+ return !eventDefinitionHelper.getTimerEventDefinition(element);
+}
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getBusinessObject = options.getBusinessObject;
+
+ var idPrefix = options.idPrefix || '',
+ labelPrefix = options.labelPrefix || '';
+
+ var asyncBeforeEntry = entryFactory.checkbox({
+ id: idPrefix + 'asyncBefore',
+ label: labelPrefix + translate('Asynchronous Before'),
+ modelProperty: 'asyncBefore',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ return {
+ asyncBefore: isAsyncBefore(bo)
+ };
+ },
+
+ set: function set(element, values) {
+ var bo = getBusinessObject(element);
+ var asyncBefore = !!values.asyncBefore;
+
+ var props = {
+ 'camunda:asyncBefore': asyncBefore,
+ 'camunda:async': false
+ };
+
+ var commands = [];
+ if (!isAsyncAfter(bo) && !asyncBefore) {
+ props = assign({ 'camunda:exclusive': true }, props);
+ if (canRemoveFailedJobRetryTimeCycle(element)) {
+ commands.push(removeFailedJobRetryTimeCycle(bo, element));
+ }
+ }
+
+ commands.push(cmdHelper.updateBusinessObject(element, bo, props));
+ return commands;
+ }
+ });
+
+ var asyncAfterEntry = entryFactory.checkbox({
+ id: idPrefix + 'asyncAfter',
+ label: labelPrefix + translate('Asynchronous After'),
+ modelProperty: 'asyncAfter',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ return {
+ asyncAfter: isAsyncAfter(bo)
+ };
+ },
+
+ set: function set(element, values) {
+ var bo = getBusinessObject(element);
+ var asyncAfter = !!values.asyncAfter;
+
+ var props = {
+ 'camunda:asyncAfter': asyncAfter
+ };
+
+ var commands = [];
+ if (!isAsyncBefore(bo) && !asyncAfter) {
+ props = assign({ 'camunda:exclusive': true }, props);
+ if (canRemoveFailedJobRetryTimeCycle(element)) {
+ commands.push(removeFailedJobRetryTimeCycle(bo, element));
+ }
+ }
+
+ commands.push(cmdHelper.updateBusinessObject(element, bo, props));
+ return commands;
+ }
+ });
+
+ var exclusiveEntry = entryFactory.checkbox({
+ id: idPrefix + 'exclusive',
+ label: labelPrefix + translate('Exclusive'),
+ modelProperty: 'exclusive',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ return { exclusive: isExclusive(bo) };
+ },
+
+ set: function set(element, values) {
+ var bo = getBusinessObject(element);
+ return cmdHelper.updateBusinessObject(element, bo, { 'camunda:exclusive': !!values.exclusive });
+ },
+
+ hidden: function hidden(element) {
+ var bo = getBusinessObject(element);
+ return bo && !isAsyncAfter(bo) && !isAsyncBefore(bo);
+ }
+ });
+
+ return [asyncBeforeEntry, asyncAfterEntry, exclusiveEntry];
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/AsyncCapableHelper":23,"../../../../helper/CmdHelper":24,"../../../../helper/EventDefinitionHelper":26,"lodash/object/assign":496}],88:[function(require,module,exports){
+'use strict';
+
+var cmdHelper = require('../../../../helper/CmdHelper'),
+ entryFactory = require('../../../../factory/EntryFactory'),
+ elementHelper = require('../../../../helper/ElementHelper'),
+ extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper');
+
+var resultVariable = require('./ResultVariable');
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+var is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var forEach = require('lodash/collection/forEach');
+
+var attributeInfo = {
+ bpmn: {
+ element: 'calledElement',
+ binding: 'camunda:calledElementBinding',
+ version: 'camunda:calledElementVersion',
+ tenantId: 'camunda:calledElementTenantId'
+ },
+
+ cmmn: {
+ element: 'camunda:caseRef',
+ binding: 'camunda:caseBinding',
+ version: 'camunda:caseVersion',
+ tenantId: 'camunda:caseTenantId'
+ },
+
+ dmn: {
+ element: 'camunda:decisionRef',
+ binding: 'camunda:decisionRefBinding',
+ version: 'camunda:decisionRefVersion',
+ tenantId: 'camunda:decisionRefTenantId'
+ }
+};
+
+var bindingOptions = [{
+ name: 'latest',
+ value: 'latest'
+}, {
+ name: 'deployment',
+ value: 'deployment'
+}, {
+ name: 'version',
+ value: 'version'
+}];
+
+var mapDecisionResultOptions = [{
+ name: 'singleEntry',
+ value: 'singleEntry'
+}, {
+ name: 'singleResult',
+ value: 'singleResult'
+}, {
+ name: 'collectEntries',
+ value: 'collectEntries'
+}, {
+ name: 'resultList',
+ value: 'resultList'
+}];
+
+var delegateVariableMappingOptions = [{
+ name: 'variableMappingClass',
+ value: 'variableMappingClass'
+}, {
+ name: 'variableMappingDelegateExpression',
+ value: 'variableMappingDelegateExpression'
+}];
+
+function getCamundaInWithBusinessKey(element) {
+ var camundaIn = [],
+ bo = getBusinessObject(element);
+
+ var camundaInParams = extensionElementsHelper.getExtensionElements(bo, 'camunda:In');
+ if (camundaInParams) {
+ forEach(camundaInParams, function (param) {
+ if (param.businessKey) {
+ camundaIn.push(param);
+ }
+ });
+ }
+ return camundaIn;
+}
+
+function setBusinessKey(element, bpmnFactory) {
+ var bo = getBusinessObject(element);
+ var commands = [];
+
+ var extensionElements = bo.extensionElements;
+ if (!extensionElements) {
+ extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
+ commands.push(cmdHelper.updateProperties(element, { extensionElements: extensionElements }));
+ }
+
+ var camundaIn = elementHelper.createElement('camunda:In', { 'businessKey': '#{execution.processBusinessKey}' }, extensionElements, bpmnFactory);
+
+ commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [camundaIn], []));
+
+ return commands;
+}
+
+function deleteBusinessKey(element) {
+ var camundaInExtensions = getCamundaInWithBusinessKey(element);
+ var commands = [];
+ forEach(camundaInExtensions, function (elem) {
+ commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, elem));
+ });
+ return commands;
+}
+
+function isSupportedCallableType(type) {
+ return ['bpmn', 'cmmn', 'dmn'].indexOf(type) !== -1;
+}
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getCallableType = options.getCallableType;
+
+ var entries = [];
+
+ function getAttribute(element, prop) {
+ var type = getCallableType(element);
+ return (attributeInfo[type] || {})[prop];
+ }
+
+ function getCallActivityBindingValue(element) {
+ var type = getCallableType(element);
+ var bo = getBusinessObject(element);
+ var attr = (attributeInfo[type] || {}).binding;
+ return bo.get(attr);
+ }
+
+ function getDelegateVariableMappingType(element) {
+ var bo = getBusinessObject(element);
+
+ var boVariableMappingClass = bo.get('camunda:variableMappingClass'),
+ boVariableMappingDelegateExpression = bo.get('camunda:variableMappingDelegateExpression');
+
+ var delegateVariableMappingType = '';
+ if (typeof boVariableMappingClass !== 'undefined') {
+ delegateVariableMappingType = 'variableMappingClass';
+ } else if (typeof boVariableMappingDelegateExpression !== 'undefined') {
+ delegateVariableMappingType = 'variableMappingDelegateExpression';
+ }
+
+ return delegateVariableMappingType;
+ }
+
+ entries.push(entryFactory.textField({
+ id: 'callable-element-ref',
+ dataValueLabel: 'callableElementLabel',
+ modelProperty: 'callableElementRef',
+
+ get: function get(element, node) {
+ var callableElementRef;
+
+ var attr = getAttribute(element, 'element');
+ if (attr) {
+ var bo = getBusinessObject(element);
+ callableElementRef = bo.get(attr);
+ }
+
+ var label = '';
+ var type = getCallableType(element);
+ if (type === 'bpmn') {
+ label = translate('Called Element');
+ } else if (type === 'cmmn') {
+ label = translate('Case Ref');
+ } else if (type === 'dmn') {
+ label = translate('Decision Ref');
+ }
+
+ return {
+ callableElementRef: callableElementRef,
+ callableElementLabel: label
+ };
+ },
+
+ set: function set(element, values, node) {
+ var newCallableElementRef = values.callableElementRef;
+ var attr = getAttribute(element, 'element');
+
+ var props = {};
+ props[attr] = newCallableElementRef || '';
+
+ return cmdHelper.updateProperties(element, props);
+ },
+
+ validate: function validate(element, values, node) {
+ var elementRef = values.callableElementRef;
+ var type = getCallableType(element);
+ return isSupportedCallableType(type) && !elementRef ? { callableElementRef: 'Value must provide a value.' } : {};
+ },
+
+ hidden: function hidden(element, node) {
+ return !isSupportedCallableType(getCallableType(element));
+ }
+
+ }));
+
+ entries.push(entryFactory.selectBox({
+ id: 'callable-binding',
+ label: translate('Binding'),
+ selectOptions: bindingOptions,
+ modelProperty: 'callableBinding',
+
+ get: function get(element, node) {
+ var callableBinding;
+
+ var attr = getAttribute(element, 'binding');
+ if (attr) {
+ var bo = getBusinessObject(element);
+ callableBinding = bo.get(attr) || 'latest';
+ }
+
+ return {
+ callableBinding: callableBinding
+ };
+ },
+
+ set: function set(element, values, node) {
+ var binding = values.callableBinding;
+ var attr = getAttribute(element, 'binding'),
+ attrVer = getAttribute(element, 'version');
+
+ var props = {};
+ props[attr] = binding;
+ // set version value always on undefined to delete the existing value
+ props[attrVer] = undefined;
+
+ return cmdHelper.updateProperties(element, props);
+ },
+
+ hidden: function hidden(element, node) {
+ return !isSupportedCallableType(getCallableType(element));
+ }
+
+ }));
+
+ entries.push(entryFactory.textField({
+ id: 'callable-version',
+ label: translate('Version'),
+ modelProperty: 'callableVersion',
+
+ get: function get(element, node) {
+ var callableVersion;
+
+ var attr = getAttribute(element, 'version');
+ if (attr) {
+ var bo = getBusinessObject(element);
+ callableVersion = bo.get(attr);
+ }
+
+ return {
+ callableVersion: callableVersion
+ };
+ },
+
+ set: function set(element, values, node) {
+ var version = values.callableVersion;
+ var attr = getAttribute(element, 'version');
+
+ var props = {};
+ props[attr] = version || undefined;
+
+ return cmdHelper.updateProperties(element, props);
+ },
+
+ validate: function validate(element, values, node) {
+ var version = values.callableVersion;
+
+ var type = getCallableType(element);
+ return isSupportedCallableType(type) && getCallActivityBindingValue(element) === 'version' && !version ? { callableVersion: translate('Value must provide a value.') } : {};
+ },
+
+ hidden: function hidden(element, node) {
+ var type = getCallableType(element);
+ return !isSupportedCallableType(type) || getCallActivityBindingValue(element) !== 'version';
+ }
+
+ }));
+
+ entries.push(entryFactory.textField({
+ id: 'tenant-id',
+ label: translate('Tenant Id'),
+ modelProperty: 'tenantId',
+
+ get: function get(element, node) {
+ var tenantId;
+
+ var attr = getAttribute(element, 'tenantId');
+ if (attr) {
+ var bo = getBusinessObject(element);
+ tenantId = bo.get(attr);
+ }
+
+ return {
+ tenantId: tenantId
+ };
+ },
+
+ set: function set(element, values, node) {
+ var tenantId = values.tenantId;
+ var attr = getAttribute(element, 'tenantId');
+
+ var props = {};
+ props[attr] = tenantId || undefined;
+
+ return cmdHelper.updateProperties(element, props);
+ },
+
+ hidden: function hidden(element, node) {
+ var type = getCallableType(element);
+ return !isSupportedCallableType(type);
+ }
+
+ }));
+
+ if (is(getBusinessObject(element), 'bpmn:CallActivity')) {
+ entries.push(entryFactory.checkbox({
+ id: 'callable-business-key',
+ label: translate('Business Key'),
+ modelProperty: 'callableBusinessKey',
+
+ get: function get(element, node) {
+ var camundaIn = getCamundaInWithBusinessKey(element);
+ return {
+ callableBusinessKey: !!(camundaIn && camundaIn.length > 0)
+ };
+ },
+
+ set: function set(element, values, node) {
+ if (values.callableBusinessKey) {
+ return setBusinessKey(element, bpmnFactory);
+ } else {
+ return deleteBusinessKey(element);
+ }
+ }
+ }));
+ }
+
+ entries = entries.concat(resultVariable(element, bpmnFactory, {
+ id: 'dmn-resultVariable',
+ getBusinessObject: getBusinessObject,
+ getImplementationType: getCallableType,
+ hideResultVariable: function hideResultVariable(element, node) {
+ return getCallableType(element) !== 'dmn';
+ }
+ }, translate));
+
+ entries.push(entryFactory.selectBox({
+ id: 'dmn-map-decision-result',
+ label: translate('Map Decision Result'),
+ selectOptions: mapDecisionResultOptions,
+ modelProperty: 'mapDecisionResult',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ return {
+ mapDecisionResult: bo.get('camunda:mapDecisionResult') || 'resultList'
+ };
+ },
+
+ set: function set(element, values, node) {
+ return cmdHelper.updateProperties(element, {
+ 'camunda:mapDecisionResult': values.mapDecisionResult || 'resultList'
+ });
+ },
+
+ hidden: function hidden(element, node) {
+ var bo = getBusinessObject(element);
+ var resultVariable = bo.get('camunda:resultVariable');
+ return !(getCallableType(element) === 'dmn' && typeof resultVariable !== 'undefined');
+ }
+
+ }));
+
+ entries.push(entryFactory.selectBox({
+ id: 'delegateVariableMappingType',
+ label: translate('Delegate Variable Mapping'),
+ selectOptions: delegateVariableMappingOptions,
+ emptyParameter: true,
+ modelProperty: 'delegateVariableMappingType',
+
+ get: function get(element, node) {
+ return {
+ delegateVariableMappingType: getDelegateVariableMappingType(element)
+ };
+ },
+
+ set: function set(element, values, node) {
+ var delegateVariableMappingType = values.delegateVariableMappingType;
+
+ var props = {
+ 'camunda:variableMappingClass': undefined,
+ 'camunda:variableMappingDelegateExpression': undefined
+ };
+
+ if (delegateVariableMappingType === 'variableMappingClass') {
+ props['camunda:variableMappingClass'] = '';
+ } else if (delegateVariableMappingType === 'variableMappingDelegateExpression') {
+ props['camunda:variableMappingDelegateExpression'] = '';
+ }
+
+ return cmdHelper.updateProperties(element, props);
+ },
+
+ hidden: function hidden(element, node) {
+ return getCallableType(element) !== 'bpmn';
+ }
+
+ }));
+
+ entries.push(entryFactory.textField({
+ id: 'delegateVariableMapping',
+ dataValueLabel: 'delegateVariableMappingLabel',
+ modelProperty: 'delegateVariableMapping',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+
+ var label = '';
+ var delegateVariableMapping = undefined;
+ var type = getDelegateVariableMappingType(element);
+
+ if (type === 'variableMappingClass') {
+ label = translate('Class');
+ delegateVariableMapping = bo.get('camunda:variableMappingClass');
+ } else if (type === 'variableMappingDelegateExpression') {
+ label = translate('Delegate Expression');
+ delegateVariableMapping = bo.get('camunda:variableMappingDelegateExpression');
+ }
+
+ return {
+ delegateVariableMapping: delegateVariableMapping,
+ delegateVariableMappingLabel: label
+ };
+ },
+
+ set: function set(element, values, node) {
+ var delegateVariableMapping = values.delegateVariableMapping;
+
+ var attr = 'camunda:' + getDelegateVariableMappingType(element);
+
+ var props = {};
+ props[attr] = delegateVariableMapping || undefined;
+
+ return cmdHelper.updateProperties(element, props);
+ },
+
+ validate: function validate(element, values, node) {
+ var delegateVariableMapping = values.delegateVariableMapping;
+ return getCallableType(element) === 'bpmn' && !delegateVariableMapping ? { delegateVariableMapping: translate('Must provide a value.') } : {};
+ },
+
+ hidden: function hidden(element, node) {
+ return !(getCallableType(element) === 'bpmn' && getDelegateVariableMappingType(element) !== '');
+ }
+
+ }));
+
+ return entries;
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"./ResultVariable":103,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422}],89:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+var DELEGATE_TYPES = ['class', 'expression', 'delegateExpression'];
+
+var PROPERTIES = {
+ class: 'camunda:class',
+ expression: 'camunda:expression',
+ delegateExpression: 'camunda:delegateExpression'
+};
+
+function isDelegate(type) {
+ return DELEGATE_TYPES.indexOf(type) !== -1;
+}
+
+function getAttribute(type) {
+ return PROPERTIES[type];
+}
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getImplementationType = options.getImplementationType,
+ getBusinessObject = options.getBusinessObject;
+
+ function getDelegationLabel(type) {
+ switch (type) {
+ case 'class':
+ return translate('Java Class');
+ case 'expression':
+ return translate('Expression');
+ case 'delegateExpression':
+ return translate('Delegate Expression');
+ default:
+ return '';
+ }
+ }
+
+ var delegateEntry = entryFactory.textField({
+ id: 'delegate',
+ label: translate('Value'),
+ dataValueLabel: 'delegationLabel',
+ modelProperty: 'delegate',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ var type = getImplementationType(element);
+ var attr = getAttribute(type);
+ var label = getDelegationLabel(type);
+ return {
+ delegate: bo.get(attr),
+ delegationLabel: label
+ };
+ },
+
+ set: function set(element, values, node) {
+ var bo = getBusinessObject(element);
+ var type = getImplementationType(element);
+ var attr = getAttribute(type);
+ var prop = {};
+ prop[attr] = values.delegate || '';
+ return cmdHelper.updateBusinessObject(element, bo, prop);
+ },
+
+ validate: function validate(element, values, node) {
+ return isDelegate(getImplementationType(element)) && !values.delegate ? { delegate: 'Must provide a value' } : {};
+ },
+
+ hidden: function hidden(element, node) {
+ return !isDelegate(getImplementationType(element));
+ }
+
+ });
+
+ return [delegateEntry];
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],90:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var domQuery = require('min-dom/lib/query'),
+ domClosest = require('min-dom/lib/closest'),
+ domify = require('min-dom/lib/domify'),
+ forEach = require('lodash/collection/forEach');
+
+var elementHelper = require('../../../../helper/ElementHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper'),
+ utils = require('../../../../Utils');
+
+function getSelectBox(node, id) {
+ var currentTab = domClosest(node, 'div.bpp-properties-tab');
+ var query = 'select[name=selectedExtensionElement]' + (id ? '[id=cam-extensionElements-' + id + ']' : '');
+ return domQuery(query, currentTab);
+}
+
+function _getSelected(node, id) {
+ var selectBox = getSelectBox(node, id);
+ return {
+ value: (selectBox || {}).value,
+ idx: (selectBox || {}).selectedIndex
+ };
+}
+
+function generateElementId(prefix) {
+ prefix = prefix + '_';
+ return utils.nextId(prefix);
+}
+
+var CREATE_EXTENSION_ELEMENT_ACTION = 'create-extension-element',
+ REMOVE_EXTENSION_ELEMENT_ACTION = 'remove-extension-element';
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var id = options.id,
+ prefix = options.prefix || 'elem',
+ label = options.label || id,
+ idGeneration = options.idGeneration === false ? options.idGeneration : true,
+ businessObject = options.businessObject || getBusinessObject(element);
+
+ var modelProperty = options.modelProperty || 'id';
+
+ var getElements = options.getExtensionElements;
+
+ var createElement = options.createExtensionElement,
+ canCreate = typeof createElement === 'function';
+
+ var removeElement = options.removeExtensionElement,
+ canRemove = typeof removeElement === 'function';
+
+ var onSelectionChange = options.onSelectionChange;
+
+ var _hideElements = options.hideExtensionElements,
+ canBeHidden = typeof _hideElements === 'function';
+
+ var setOptionLabelValue = options.setOptionLabelValue;
+
+ var defaultSize = options.size || 5,
+ resizable = options.resizable;
+
+ var reference = options.reference || undefined;
+
+ var selectionChanged = function selectionChanged(element, node, event, scope) {
+ if (typeof onSelectionChange === 'function') {
+ return onSelectionChange(element, node, event, scope);
+ }
+ };
+
+ var createOption = function createOption(value) {
+ return '' + value + ' ';
+ };
+
+ var initSelectionSize = function initSelectionSize(selectBox, optionsLength) {
+ if (resizable) {
+ selectBox.size = optionsLength > defaultSize ? optionsLength : defaultSize;
+ }
+ };
+
+ return {
+ id: id,
+ html: '' + '
' + label + ' ' + '
' + '' + ' ' + (canCreate ? '' + '+ ' + ' ' : '') + (canRemove ? '' + '- ' + ' ' : '') + '
' + '
',
+
+ get: function get(element, node) {
+ var elements = getElements(element, node);
+
+ var result = [];
+ forEach(elements, function (elem) {
+ result.push({
+ extensionElementValue: elem.get(modelProperty)
+ });
+ });
+
+ var selectBox = getSelectBox(node.parentNode, id);
+ initSelectionSize(selectBox, result.length);
+
+ return result;
+ },
+
+ set: function set(element, values, node) {
+ var action = this.__action;
+ delete this.__action;
+
+ businessObject = businessObject || getBusinessObject(element);
+
+ var bo = reference && businessObject.get(reference) ? businessObject.get(reference) : businessObject;
+
+ var extensionElements = bo.get('extensionElements');
+
+ if (action.id === CREATE_EXTENSION_ELEMENT_ACTION) {
+ var commands = [];
+ if (!extensionElements) {
+ extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
+ commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
+ }
+ commands.push(createElement(element, extensionElements, action.value, node));
+ return commands;
+ } else if (action.id === REMOVE_EXTENSION_ELEMENT_ACTION) {
+ return removeElement(element, extensionElements, action.value, action.idx, node);
+ }
+ },
+
+ createListEntryTemplate: function createListEntryTemplate(value, index, selectBox) {
+ initSelectionSize(selectBox, selectBox.options.length + 1);
+ return createOption(value.extensionElementValue);
+ },
+
+ deselect: function deselect(element, node) {
+ var selectBox = getSelectBox(node, id);
+ selectBox.selectedIndex = -1;
+ },
+
+ getSelected: function getSelected(element, node) {
+ return _getSelected(node, id);
+ },
+
+ setControlValue: function setControlValue(element, node, option, property, value, idx) {
+ node.value = value;
+
+ if (!setOptionLabelValue) {
+ node.text = value;
+ } else {
+ setOptionLabelValue(element, node, option, property, value, idx);
+ }
+ },
+
+ createElement: function createElement(element, node) {
+ // create option template
+ var generatedId;
+ if (idGeneration) {
+ generatedId = generateElementId(prefix);
+ }
+
+ var selectBox = getSelectBox(node, id);
+ var template = domify(createOption(generatedId));
+
+ // add new empty option as last child element
+ selectBox.appendChild(template);
+
+ // select last child element
+ selectBox.lastChild.selected = 'selected';
+ selectionChanged(element, node);
+
+ // update select box size
+ initSelectionSize(selectBox, selectBox.options.length);
+
+ this.__action = {
+ id: CREATE_EXTENSION_ELEMENT_ACTION,
+ value: generatedId
+ };
+
+ return true;
+ },
+
+ removeElement: function removeElement(element, node) {
+ var selection = _getSelected(node, id);
+
+ var selectBox = getSelectBox(node, id);
+ selectBox.removeChild(selectBox.options[selection.idx]);
+
+ // update select box size
+ initSelectionSize(selectBox, selectBox.options.length);
+
+ this.__action = {
+ id: REMOVE_EXTENSION_ELEMENT_ACTION,
+ value: selection.value,
+ idx: selection.idx
+ };
+
+ return true;
+ },
+
+ hideElements: function hideElements(element, entryNode, node, scopeNode) {
+ return !_hideElements(element, entryNode, node, scopeNode);
+ },
+
+ disableRemove: function disableRemove(element, entryNode, node, scopeNode) {
+ return (_getSelected(entryNode, id) || {}).idx < 0;
+ },
+
+ selectElement: selectionChanged
+ };
+};
+
+},{"../../../../Utils":5,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422,"min-dom/lib/closest":108,"min-dom/lib/domify":110,"min-dom/lib/query":112}],91:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getImplementationType = options.getImplementationType,
+ getBusinessObject = options.getBusinessObject;
+
+ function isExternal(element) {
+ return getImplementationType(element) === 'external';
+ }
+
+ var topicEntry = entryFactory.textField({
+ id: 'externalTopic',
+ label: translate('Topic'),
+ modelProperty: 'externalTopic',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ return { externalTopic: bo.get('camunda:topic') };
+ },
+
+ set: function set(element, values, node) {
+ var bo = getBusinessObject(element);
+ return cmdHelper.updateBusinessObject(element, bo, {
+ 'camunda:topic': values.externalTopic
+ });
+ },
+
+ validate: function validate(element, values, node) {
+ return isExternal(element) && !values.externalTopic ? { externalTopic: 'Must provide a value' } : {};
+ },
+
+ hidden: function hidden(element, node) {
+ return !isExternal(element);
+ }
+
+ });
+
+ return [topicEntry];
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],92:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+var cmdHelper = require('../../../../helper/CmdHelper');
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getBusinessObject = options.getBusinessObject;
+
+ var externalTaskPriorityEntry = entryFactory.textField({
+ id: 'externalTaskPriority',
+ label: translate('Task Priority'),
+ modelProperty: 'taskPriority',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ return {
+ taskPriority: bo.get('camunda:taskPriority')
+ };
+ },
+
+ set: function set(element, values) {
+ var bo = getBusinessObject(element);
+ return cmdHelper.updateBusinessObject(element, bo, {
+ 'camunda:taskPriority': values.taskPriority || undefined
+ });
+ }
+
+ });
+
+ return [externalTaskPriorityEntry];
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],93:[function(require,module,exports){
+'use strict';
+
+var extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
+ elementHelper = require('../../../../helper/ElementHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+var utils = require('../../../../Utils');
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+var extensionElementsEntry = require('./ExtensionElements');
+
+var ModelUtil = require('bpmn-js/lib/util/ModelUtil'),
+ getBusinessObject = ModelUtil.getBusinessObject;
+
+var assign = require('lodash/object/assign');
+
+var DEFAULT_PROPS = {
+ 'stringValue': undefined,
+ 'string': undefined,
+ 'expression': undefined
+};
+
+var CAMUNDA_FIELD_EXTENSION_ELEMENT = 'camunda:Field';
+
+module.exports = function (element, bpmnFactory, translate, options) {
+
+ options = options || {};
+
+ var insideListener = !!options.insideListener,
+ idPrefix = options.idPrefix || '',
+ getSelectedListener = options.getSelectedListener,
+ businessObject = options.businessObject || getBusinessObject(element);
+
+ var entries = [];
+
+ var isSelected = function isSelected(element, node) {
+ return getSelectedField(element, node);
+ };
+
+ function getSelectedField(element, node) {
+ var selected = fieldEntry.getSelected(element, node.parentNode);
+
+ if (selected.idx === -1) {
+ return;
+ }
+
+ var fields = getCamundaFields(element, node);
+
+ return fields[selected.idx];
+ }
+
+ function getCamundaFields(element, node) {
+ if (!insideListener) {
+ return businessObject && extensionElementsHelper.getExtensionElements(businessObject, CAMUNDA_FIELD_EXTENSION_ELEMENT) || [];
+ }
+ return getCamundaListenerFields(element, node);
+ }
+
+ function getCamundaListenerFields(element, node) {
+ var selectedListener = getSelectedListener(element, node);
+ return selectedListener && selectedListener.fields || [];
+ }
+
+ function getFieldType(bo) {
+ var fieldType = 'string';
+
+ var expressionValue = bo && bo.expression;
+ var stringValue = bo && (bo.string || bo.stringValue);
+
+ if (typeof stringValue !== 'undefined') {
+ fieldType = 'string';
+ } else if (typeof expressionValue !== 'undefined') {
+ fieldType = 'expression';
+ }
+
+ return fieldType;
+ }
+
+ var setOptionLabelValue = function setOptionLabelValue() {
+ return function (element, node, option, property, value, idx) {
+ var camundaFields = getCamundaFields(element, node);
+ var field = camundaFields[idx];
+
+ value = field.name ? field.name : '';
+
+ var label = idx + ' : ' + value;
+
+ option.text = label;
+ };
+ };
+
+ var newElement = function newElement() {
+ return function (element, extensionElements, value, node) {
+
+ var props = {
+ name: '',
+ string: ''
+ };
+
+ var newFieldElem;
+
+ if (!insideListener) {
+
+ newFieldElem = elementHelper.createElement(CAMUNDA_FIELD_EXTENSION_ELEMENT, props, extensionElements, bpmnFactory);
+ return cmdHelper.addElementsTolist(element, extensionElements, 'values', [newFieldElem]);
+ } else {
+
+ var selectedListener = getSelectedListener(element, node);
+ newFieldElem = elementHelper.createElement(CAMUNDA_FIELD_EXTENSION_ELEMENT, props, selectedListener, bpmnFactory);
+ return cmdHelper.addElementsTolist(element, selectedListener, 'fields', [newFieldElem]);
+ }
+ };
+ };
+
+ var removeElement = function removeElement() {
+ return function (element, extensionElements, value, idx, node) {
+ var camundaFields = getCamundaFields(element, node);
+ var field = camundaFields[idx];
+ if (field) {
+ if (!insideListener) {
+ return extensionElementsHelper.removeEntry(businessObject, element, field);
+ }
+ var selectedListener = getSelectedListener(element, node);
+ return cmdHelper.removeElementsFromList(element, selectedListener, 'fields', null, [field]);
+ }
+ };
+ };
+
+ var fieldEntry = extensionElementsEntry(element, bpmnFactory, {
+ id: idPrefix + 'fields',
+ label: translate('Fields'),
+ modelProperty: 'fieldName',
+ idGeneration: 'false',
+
+ businessObject: businessObject,
+
+ createExtensionElement: newElement(),
+ removeExtensionElement: removeElement(),
+
+ getExtensionElements: function getExtensionElements(element, node) {
+ return getCamundaFields(element, node);
+ },
+
+ setOptionLabelValue: setOptionLabelValue()
+
+ });
+ entries.push(fieldEntry);
+
+ entries.push(entryFactory.validationAwareTextField({
+ id: idPrefix + 'field-name',
+ label: translate('Name'),
+ modelProperty: 'fieldName',
+
+ getProperty: function getProperty(element, node) {
+ return (getSelectedField(element, node) || {}).name;
+ },
+
+ setProperty: function setProperty(element, values, node) {
+ var selectedField = getSelectedField(element, node);
+ return cmdHelper.updateBusinessObject(element, selectedField, { name: values.fieldName });
+ },
+
+ validate: function validate(element, values, node) {
+ var bo = getSelectedField(element, node);
+
+ var validation = {};
+ if (bo) {
+ var nameValue = values.fieldName;
+
+ if (nameValue) {
+ if (utils.containsSpace(nameValue)) {
+ validation.fieldName = translate('Name must not contain spaces');
+ }
+ } else {
+ validation.fieldName = translate('Parameter must have a name');
+ }
+ }
+
+ return validation;
+ },
+
+ hidden: function hidden(element, node) {
+ return !isSelected(element, node);
+ }
+
+ }));
+
+ var fieldTypeOptions = [{
+ name: translate('String'),
+ value: 'string'
+ }, {
+ name: translate('Expression'),
+ value: 'expression'
+ }];
+
+ entries.push(entryFactory.selectBox({
+ id: idPrefix + 'field-type',
+ label: translate('Type'),
+ selectOptions: fieldTypeOptions,
+ modelProperty: 'fieldType',
+
+ get: function get(element, node) {
+ var bo = getSelectedField(element, node);
+
+ var fieldType = getFieldType(bo);
+
+ return {
+ fieldType: fieldType
+ };
+ },
+
+ set: function set(element, values, node) {
+ var props = assign({}, DEFAULT_PROPS);
+
+ var fieldType = values.fieldType;
+
+ if (fieldType === 'string') {
+ props.string = '';
+ } else if (fieldType === 'expression') {
+ props.expression = '';
+ }
+
+ return cmdHelper.updateBusinessObject(element, getSelectedField(element, node), props);
+ },
+
+ hidden: function hidden(element, node) {
+ return !isSelected(element, node);
+ }
+
+ }));
+
+ entries.push(entryFactory.textBox({
+ id: idPrefix + 'field-value',
+ label: translate('Value'),
+ modelProperty: 'fieldValue',
+
+ get: function get(element, node) {
+ var bo = getSelectedField(element, node);
+ var fieldType = getFieldType(bo);
+
+ var fieldValue;
+
+ if (fieldType === 'string') {
+ fieldValue = bo && (bo.string || bo.stringValue);
+ } else if (fieldType === 'expression') {
+ fieldValue = bo && bo.expression;
+ }
+
+ return {
+ fieldValue: fieldValue
+ };
+ },
+
+ set: function set(element, values, node) {
+ var bo = getSelectedField(element, node);
+ var fieldType = getFieldType(bo);
+
+ var props = assign({}, DEFAULT_PROPS);
+
+ var fieldValue = values.fieldValue || undefined;
+
+ if (fieldType === 'string') {
+ props.string = fieldValue;
+ } else if (fieldType === 'expression') {
+ props.expression = fieldValue;
+ }
+
+ return cmdHelper.updateBusinessObject(element, bo, props);
+ },
+
+ validate: function validate(element, values, node) {
+ var bo = getSelectedField(element, node);
+
+ var validation = {};
+ if (bo) {
+ if (!values.fieldValue) {
+ validation.fieldValue = translate('Must provide a value');
+ }
+ }
+
+ return validation;
+ },
+
+ show: function show(element, node) {
+ return isSelected(element, node);
+ }
+
+ }));
+
+ return entries;
+};
+
+},{"../../../../Utils":5,"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"./ExtensionElements":90,"bpmn-js/lib/util/ModelUtil":216,"lodash/object/assign":496}],94:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+var cmdHelper = require('../../../../helper/CmdHelper');
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getBusinessObject = options.getBusinessObject;
+
+ var historyTimeToLiveEntry = entryFactory.textField({
+ id: 'historyTimeToLive',
+ label: translate('History Time To Live'),
+ modelProperty: 'historyTimeToLive',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ var historyTimeToLive = bo.get('camunda:historyTimeToLive');
+
+ return {
+ historyTimeToLive: historyTimeToLive ? historyTimeToLive : ''
+ };
+ },
+
+ set: function set(element, values) {
+ var bo = getBusinessObject(element);
+ return cmdHelper.updateBusinessObject(element, bo, {
+ 'camunda:historyTimeToLive': values.historyTimeToLive || undefined
+ });
+ }
+
+ });
+
+ return [historyTimeToLiveEntry];
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],95:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ cmdHelper = require('../../../../helper/CmdHelper'),
+ extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
+ elementHelper = require('../../../../helper/ElementHelper');
+
+var assign = require('lodash/object/assign');
+var map = require('lodash/collection/map');
+
+var DEFAULT_DELEGATE_PROPS = ['class', 'expression', 'delegateExpression'];
+
+var DELEGATE_PROPS = {
+ 'camunda:class': undefined,
+ 'camunda:expression': undefined,
+ 'camunda:delegateExpression': undefined,
+ 'camunda:resultVariable': undefined
+};
+
+var DMN_CAPABLE_PROPS = {
+ 'camunda:decisionRef': undefined,
+ 'camunda:decisionRefBinding': 'latest',
+ 'camunda:decisionRefVersion': undefined,
+ 'camunda:mapDecisionResult': 'resultList',
+ 'camunda:decisionRefTenantId': undefined
+};
+
+var EXTERNAL_CAPABLE_PROPS = {
+ 'camunda:type': undefined,
+ 'camunda:topic': undefined
+};
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var DEFAULT_OPTIONS = [{ value: 'class', name: translate('Java Class') }, { value: 'expression', name: translate('Expression') }, { value: 'delegateExpression', name: translate('Delegate Expression') }];
+
+ var DMN_OPTION = [{ value: 'dmn', name: translate('DMN') }];
+
+ var EXTERNAL_OPTION = [{ value: 'external', name: translate('External') }];
+
+ var CONNECTOR_OPTION = [{ value: 'connector', name: translate('Connector') }];
+
+ var SCRIPT_OPTION = [{ value: 'script', name: translate('Script') }];
+
+ var getType = options.getImplementationType,
+ getBusinessObject = options.getBusinessObject;
+
+ var hasDmnSupport = options.hasDmnSupport,
+ hasExternalSupport = options.hasExternalSupport,
+ hasServiceTaskLikeSupport = options.hasServiceTaskLikeSupport,
+ hasScriptSupport = options.hasScriptSupport;
+
+ var entries = [];
+
+ var selectOptions = DEFAULT_OPTIONS.concat([]);
+
+ if (hasDmnSupport) {
+ selectOptions = selectOptions.concat(DMN_OPTION);
+ }
+
+ if (hasExternalSupport) {
+ selectOptions = selectOptions.concat(EXTERNAL_OPTION);
+ }
+
+ if (hasServiceTaskLikeSupport) {
+ selectOptions = selectOptions.concat(CONNECTOR_OPTION);
+ }
+
+ if (hasScriptSupport) {
+ selectOptions = selectOptions.concat(SCRIPT_OPTION);
+ }
+
+ selectOptions.push({ value: '' });
+
+ entries.push(entryFactory.selectBox({
+ id: 'implementation',
+ label: translate('Implementation'),
+ selectOptions: selectOptions,
+ modelProperty: 'implType',
+
+ get: function get(element, node) {
+ return {
+ implType: getType(element) || ''
+ };
+ },
+
+ set: function set(element, values, node) {
+ var bo = getBusinessObject(element);
+ var oldType = getType(element);
+ var newType = values.implType;
+
+ var props = assign({}, DELEGATE_PROPS);
+
+ if (DEFAULT_DELEGATE_PROPS.indexOf(newType) !== -1) {
+
+ var newValue = '';
+ if (DEFAULT_DELEGATE_PROPS.indexOf(oldType) !== -1) {
+ newValue = bo.get('camunda:' + oldType);
+ }
+ props['camunda:' + newType] = newValue;
+ }
+
+ if (hasDmnSupport) {
+ props = assign(props, DMN_CAPABLE_PROPS);
+ if (newType === 'dmn') {
+ props['camunda:decisionRef'] = '';
+ }
+ }
+
+ if (hasExternalSupport) {
+ props = assign(props, EXTERNAL_CAPABLE_PROPS);
+ if (newType === 'external') {
+ props['camunda:type'] = 'external';
+ props['camunda:topic'] = '';
+ }
+ }
+
+ if (hasScriptSupport) {
+ props['camunda:script'] = undefined;
+
+ if (newType === 'script') {
+ props['camunda:script'] = elementHelper.createElement('camunda:Script', {}, bo, bpmnFactory);
+ }
+ }
+
+ var commands = [];
+ commands.push(cmdHelper.updateBusinessObject(element, bo, props));
+
+ if (hasServiceTaskLikeSupport) {
+ var connectors = extensionElementsHelper.getExtensionElements(bo, 'camunda:Connector');
+ commands.push(map(connectors, function (connector) {
+ return extensionElementsHelper.removeEntry(bo, element, connector);
+ }));
+
+ if (newType === 'connector') {
+ var extensionElements = bo.get('extensionElements');
+ if (!extensionElements) {
+ extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
+ commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
+ }
+ var connector = elementHelper.createElement('camunda:Connector', {}, extensionElements, bpmnFactory);
+ commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [connector], []));
+ }
+ }
+
+ return commands;
+ }
+ }));
+
+ return entries;
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"lodash/collection/map":424,"lodash/object/assign":496}],96:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var elementHelper = require('../../../../helper/ElementHelper'),
+ extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
+ inputOutputHelper = require('../../../../helper/InputOutputHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+var extensionElementsEntry = require('./ExtensionElements');
+
+function getInputOutput(element, insideConnector) {
+ return inputOutputHelper.getInputOutput(element, insideConnector);
+}
+
+function getConnector(element) {
+ return inputOutputHelper.getConnector(element);
+}
+
+function getInputParameters(element, insideConnector) {
+ return inputOutputHelper.getInputParameters(element, insideConnector);
+}
+
+function getOutputParameters(element, insideConnector) {
+ return inputOutputHelper.getOutputParameters(element, insideConnector);
+}
+
+function getInputParameter(element, insideConnector, idx) {
+ return inputOutputHelper.getInputParameter(element, insideConnector, idx);
+}
+
+function getOutputParameter(element, insideConnector, idx) {
+ return inputOutputHelper.getOutputParameter(element, insideConnector, idx);
+}
+
+function createElement(type, parent, factory, properties) {
+ return elementHelper.createElement(type, properties, parent, factory);
+}
+
+function createInputOutput(parent, bpmnFactory, properties) {
+ return createElement('camunda:InputOutput', parent, bpmnFactory, properties);
+}
+
+function createParameter(type, parent, bpmnFactory, properties) {
+ return createElement(type, parent, bpmnFactory, properties);
+}
+
+function ensureInputOutputSupported(element, insideConnector) {
+ return inputOutputHelper.isInputOutputSupported(element, insideConnector);
+}
+
+function ensureOutparameterSupported(element, insideConnector) {
+ return inputOutputHelper.areOutputParametersSupported(element, insideConnector);
+}
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var TYPE_LABEL = {
+ 'camunda:Map': translate('Map'),
+ 'camunda:List': translate('List'),
+ 'camunda:Script': translate('Script')
+ };
+
+ options = options || {};
+
+ var insideConnector = !!options.insideConnector,
+ idPrefix = options.idPrefix || '';
+
+ var getSelected = function getSelected(element, node) {
+ var selection = inputEntry && inputEntry.getSelected(element, node) || { idx: -1 };
+
+ var parameter = getInputParameter(element, insideConnector, selection.idx);
+ if (!parameter && outputEntry) {
+ selection = outputEntry.getSelected(element, node);
+ parameter = getOutputParameter(element, insideConnector, selection.idx);
+ }
+ return parameter;
+ };
+
+ var result = {
+ getSelectedParameter: getSelected
+ };
+
+ var entries = result.entries = [];
+
+ if (!ensureInputOutputSupported(element)) {
+ return result;
+ }
+
+ var newElement = function newElement(type, prop, factory) {
+
+ return function (element, extensionElements, value) {
+ var commands = [];
+
+ var inputOutput = getInputOutput(element, insideConnector);
+ if (!inputOutput) {
+ var parent = !insideConnector ? extensionElements : getConnector(element);
+ inputOutput = createInputOutput(parent, bpmnFactory, {
+ inputParameters: [],
+ outputParameters: []
+ });
+
+ if (!insideConnector) {
+ commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [inputOutput], []));
+ } else {
+ commands.push(cmdHelper.updateBusinessObject(element, parent, { inputOutput: inputOutput }));
+ }
+ }
+
+ var newElem = createParameter(type, inputOutput, bpmnFactory, { name: value });
+ commands.push(cmdHelper.addElementsTolist(element, inputOutput, prop, [newElem]));
+
+ return commands;
+ };
+ };
+
+ var removeElement = function removeElement(getter, prop, otherProp) {
+ return function (element, extensionElements, value, idx) {
+ var inputOutput = getInputOutput(element, insideConnector);
+ var parameter = getter(element, insideConnector, idx);
+
+ var commands = [];
+ commands.push(cmdHelper.removeElementsFromList(element, inputOutput, prop, null, [parameter]));
+
+ var firstLength = inputOutput.get(prop).length - 1;
+ var secondLength = (inputOutput.get(otherProp) || []).length;
+
+ if (!firstLength && !secondLength) {
+
+ if (!insideConnector) {
+ commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, inputOutput));
+ } else {
+ var connector = getConnector(element);
+ commands.push(cmdHelper.updateBusinessObject(element, connector, { inputOutput: undefined }));
+ }
+ }
+
+ return commands;
+ };
+ };
+
+ var setOptionLabelValue = function setOptionLabelValue(getter) {
+ return function (element, node, option, property, value, idx) {
+ var parameter = getter(element, insideConnector, idx);
+
+ var suffix = 'Text';
+
+ var definition = parameter.get('definition');
+ if (typeof definition !== 'undefined') {
+ var type = definition.$type;
+ suffix = TYPE_LABEL[type];
+ }
+
+ option.text = (value || '') + ' : ' + suffix;
+ };
+ };
+
+ // input parameters ///////////////////////////////////////////////////////////////
+
+ var inputEntry = extensionElementsEntry(element, bpmnFactory, {
+ id: idPrefix + 'inputs',
+ label: translate('Input Parameters'),
+ modelProperty: 'name',
+ prefix: 'Input',
+ resizable: true,
+
+ createExtensionElement: newElement('camunda:InputParameter', 'inputParameters'),
+ removeExtensionElement: removeElement(getInputParameter, 'inputParameters', 'outputParameters'),
+
+ getExtensionElements: function getExtensionElements(element) {
+ return getInputParameters(element, insideConnector);
+ },
+
+ onSelectionChange: function onSelectionChange(element, node, event, scope) {
+ outputEntry && outputEntry.deselect(element, node);
+ },
+
+ setOptionLabelValue: setOptionLabelValue(getInputParameter)
+
+ });
+ entries.push(inputEntry);
+
+ // output parameters ///////////////////////////////////////////////////////
+
+ if (ensureOutparameterSupported(element, insideConnector)) {
+ var outputEntry = extensionElementsEntry(element, bpmnFactory, {
+ id: idPrefix + 'outputs',
+ label: translate('Output Parameters'),
+ modelProperty: 'name',
+ prefix: 'Output',
+ resizable: true,
+
+ createExtensionElement: newElement('camunda:OutputParameter', 'outputParameters'),
+ removeExtensionElement: removeElement(getOutputParameter, 'outputParameters', 'inputParameters'),
+
+ getExtensionElements: function getExtensionElements(element) {
+ return getOutputParameters(element, insideConnector);
+ },
+
+ onSelectionChange: function onSelectionChange(element, node, event, scope) {
+ inputEntry.deselect(element, node);
+ },
+
+ setOptionLabelValue: setOptionLabelValue(getOutputParameter)
+
+ });
+ entries.push(outputEntry);
+ }
+
+ return result;
+};
+
+},{"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"../../../../helper/InputOutputHelper":30,"./ExtensionElements":90,"bpmn-js/lib/util/ModelUtil":216}],97:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var elementHelper = require('../../../../helper/ElementHelper'),
+ inputOutputHelper = require('../../../../helper/InputOutputHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper'),
+ utils = require('../../../../Utils');
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ script = require('./Script')('scriptFormat', 'value', true);
+
+function createElement(type, parent, factory, properties) {
+ return elementHelper.createElement(type, properties, parent, factory);
+}
+
+function _isScript(elem) {
+ return is(elem, 'camunda:Script');
+}
+
+function isList(elem) {
+ return is(elem, 'camunda:List');
+}
+
+function isMap(elem) {
+ return is(elem, 'camunda:Map');
+}
+
+function ensureInputOutputSupported(element, insideConnector) {
+ return inputOutputHelper.isInputOutputSupported(element, insideConnector);
+}
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var typeInfo = {
+ 'camunda:Map': {
+ value: 'map',
+ label: translate('Map')
+ },
+ 'camunda:List': {
+ value: 'list',
+ label: translate('List')
+ },
+ 'camunda:Script': {
+ value: 'script',
+ label: translate('Script')
+ }
+ };
+
+ options = options || {};
+
+ var insideConnector = !!options.insideConnector,
+ idPrefix = options.idPrefix || '';
+
+ var getSelected = options.getSelectedParameter;
+
+ if (!ensureInputOutputSupported(element, insideConnector)) {
+ return [];
+ }
+
+ var entries = [];
+
+ var isSelected = function isSelected(element, node) {
+ return getSelected(element, node);
+ };
+
+ // parameter name ////////////////////////////////////////////////////////
+
+ entries.push(entryFactory.validationAwareTextField({
+ id: idPrefix + 'parameterName',
+ label: 'Name',
+ modelProperty: 'name',
+
+ getProperty: function getProperty(element, node) {
+ return (getSelected(element, node) || {}).name;
+ },
+
+ setProperty: function setProperty(element, values, node) {
+ var param = getSelected(element, node);
+ return cmdHelper.updateBusinessObject(element, param, values);
+ },
+
+ validate: function validate(element, values, node) {
+ var bo = getSelected(element, node);
+
+ var validation = {};
+ if (bo) {
+ var nameValue = values.name;
+
+ if (nameValue) {
+ if (utils.containsSpace(nameValue)) {
+ validation.name = 'Name must not contain spaces';
+ }
+ } else {
+ validation.name = 'Parameter must have a name';
+ }
+ }
+
+ return validation;
+ },
+
+ hidden: function hidden(element, node) {
+ return !isSelected(element, node);
+ }
+ }));
+
+ // parameter type //////////////////////////////////////////////////////
+
+ var selectOptions = [{ value: 'text', name: 'Text' }, { value: 'script', name: 'Script' }, { value: 'list', name: 'List' }, { value: 'map', name: 'Map' }];
+
+ entries.push(entryFactory.selectBox({
+ id: idPrefix + 'parameterType',
+ label: 'Type',
+ selectOptions: selectOptions,
+ modelProperty: 'parameterType',
+
+ get: function get(element, node) {
+ var bo = getSelected(element, node);
+
+ var parameterType = 'text';
+
+ if (typeof bo !== 'undefined') {
+ var definition = bo.get('definition');
+ if (typeof definition !== 'undefined') {
+ var type = definition.$type;
+ parameterType = typeInfo[type].value;
+ }
+ }
+
+ return {
+ parameterType: parameterType
+ };
+ },
+
+ set: function set(element, values, node) {
+ var bo = getSelected(element, node);
+
+ var properties = {
+ value: undefined,
+ definition: undefined
+ };
+
+ var createParameterTypeElem = function createParameterTypeElem(type) {
+ return createElement(type, bo, bpmnFactory);
+ };
+
+ var parameterType = values.parameterType;
+
+ if (parameterType === 'script') {
+ properties.definition = createParameterTypeElem('camunda:Script');
+ } else if (parameterType === 'list') {
+ properties.definition = createParameterTypeElem('camunda:List');
+ } else if (parameterType === 'map') {
+ properties.definition = createParameterTypeElem('camunda:Map');
+ }
+
+ return cmdHelper.updateBusinessObject(element, bo, properties);
+ },
+
+ show: function show(element, node) {
+ return isSelected(element, node);
+ }
+
+ }));
+
+ // parameter value (type = text) ///////////////////////////////////////////////////////
+
+ entries.push(entryFactory.textBox({
+ id: idPrefix + 'parameterType-text',
+ label: 'Value',
+ modelProperty: 'value',
+ get: function get(element, node) {
+ return {
+ value: (getSelected(element, node) || {}).value
+ };
+ },
+
+ set: function set(element, values, node) {
+ var param = getSelected(element, node);
+ values.value = values.value || undefined;
+ return cmdHelper.updateBusinessObject(element, param, values);
+ },
+
+ show: function show(element, node) {
+ var bo = getSelected(element, node);
+ return bo && !bo.definition;
+ }
+
+ }));
+
+ // parameter value (type = script) ///////////////////////////////////////////////////////
+
+ entries.push({
+ id: idPrefix + 'parameterType-script',
+ html: '' + script.template + '
',
+ get: function get(element, node) {
+ var bo = getSelected(element, node);
+ return bo && _isScript(bo.definition) ? script.get(element, bo.definition) : {};
+ },
+
+ set: function set(element, values, node) {
+ var bo = getSelected(element, node);
+ var update = script.set(element, values);
+ return cmdHelper.updateBusinessObject(element, bo.definition, update);
+ },
+
+ validate: function validate(element, values, node) {
+ var bo = getSelected(element, node);
+ return bo && _isScript(bo.definition) ? script.validate(element, bo.definition) : {};
+ },
+
+ isScript: function isScript(element, node) {
+ var bo = getSelected(element, node);
+ return bo && _isScript(bo.definition);
+ },
+
+ script: script
+
+ });
+
+ // parameter value (type = list) ///////////////////////////////////////////////////////
+
+ entries.push(entryFactory.table({
+ id: idPrefix + 'parameterType-list',
+ modelProperties: ['value'],
+ labels: ['Value'],
+
+ getElements: function getElements(element, node) {
+ var bo = getSelected(element, node);
+
+ if (bo && isList(bo.definition)) {
+ return bo.definition.items;
+ }
+
+ return [];
+ },
+
+ updateElement: function updateElement(element, values, node, idx) {
+ var bo = getSelected(element, node);
+ var item = bo.definition.items[idx];
+ return cmdHelper.updateBusinessObject(element, item, values);
+ },
+
+ addElement: function addElement(element, node) {
+ var bo = getSelected(element, node);
+ var newValue = createElement('camunda:Value', bo.definition, bpmnFactory, { value: undefined });
+ return cmdHelper.addElementsTolist(element, bo.definition, 'items', [newValue]);
+ },
+
+ removeElement: function removeElement(element, node, idx) {
+ var bo = getSelected(element, node);
+ return cmdHelper.removeElementsFromList(element, bo.definition, 'items', null, [bo.definition.items[idx]]);
+ },
+
+ editable: function editable(element, node, prop, idx) {
+ var bo = getSelected(element, node);
+ var item = bo.definition.items[idx];
+ return !isMap(item) && !isList(item) && !_isScript(item);
+ },
+
+ setControlValue: function setControlValue(element, node, input, prop, value, idx) {
+ var bo = getSelected(element, node);
+ var item = bo.definition.items[idx];
+
+ if (!isMap(item) && !isList(item) && !_isScript(item)) {
+ input.value = value;
+ } else {
+ input.value = typeInfo[item.$type].label;
+ }
+ },
+
+ show: function show(element, node) {
+ var bo = getSelected(element, node);
+ return bo && bo.definition && isList(bo.definition);
+ }
+
+ }));
+
+ // parameter value (type = map) ///////////////////////////////////////////////////////
+
+ entries.push(entryFactory.table({
+ id: idPrefix + 'parameterType-map',
+ modelProperties: ['key', 'value'],
+ labels: ['Key', 'Value'],
+ addLabel: 'Add Entry',
+
+ getElements: function getElements(element, node) {
+ var bo = getSelected(element, node);
+
+ if (bo && isMap(bo.definition)) {
+ return bo.definition.entries;
+ }
+
+ return [];
+ },
+
+ updateElement: function updateElement(element, values, node, idx) {
+ var bo = getSelected(element, node);
+ var entry = bo.definition.entries[idx];
+
+ if (isMap(entry.definition) || isList(entry.definition) || _isScript(entry.definition)) {
+ values = {
+ key: values.key
+ };
+ }
+
+ return cmdHelper.updateBusinessObject(element, entry, values);
+ },
+
+ addElement: function addElement(element, node) {
+ var bo = getSelected(element, node);
+ var newEntry = createElement('camunda:Entry', bo.definition, bpmnFactory, { key: undefined, value: undefined });
+ return cmdHelper.addElementsTolist(element, bo.definition, 'entries', [newEntry]);
+ },
+
+ removeElement: function removeElement(element, node, idx) {
+ var bo = getSelected(element, node);
+ return cmdHelper.removeElementsFromList(element, bo.definition, 'entries', null, [bo.definition.entries[idx]]);
+ },
+
+ editable: function editable(element, node, prop, idx) {
+ var bo = getSelected(element, node);
+ var entry = bo.definition.entries[idx];
+ return prop === 'key' || !isMap(entry.definition) && !isList(entry.definition) && !_isScript(entry.definition);
+ },
+
+ setControlValue: function setControlValue(element, node, input, prop, value, idx) {
+ var bo = getSelected(element, node);
+ var entry = bo.definition.entries[idx];
+
+ if (prop === 'key' || !isMap(entry.definition) && !isList(entry.definition) && !_isScript(entry.definition)) {
+ input.value = value;
+ } else {
+ input.value = typeInfo[entry.definition.$type].label;
+ }
+ },
+
+ show: function show(element, node) {
+ var bo = getSelected(element, node);
+ return bo && bo.definition && isMap(bo.definition);
+ }
+
+ }));
+
+ return entries;
+};
+
+},{"../../../../Utils":5,"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/InputOutputHelper":30,"./Script":104,"bpmn-js/lib/util/ModelUtil":216}],98:[function(require,module,exports){
+'use strict';
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+var cmdHelper = require('../../../../helper/CmdHelper');
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getBusinessObject = options.getBusinessObject;
+
+ var jobPriorityEntry = entryFactory.textField({
+ id: 'jobPriority',
+ label: translate('Job Priority'),
+ modelProperty: 'jobPriority',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ return {
+ jobPriority: bo.get('camunda:jobPriority')
+ };
+ },
+
+ set: function set(element, values) {
+ var bo = getBusinessObject(element);
+ return cmdHelper.updateBusinessObject(element, bo, {
+ 'camunda:jobPriority': values.jobPriority || undefined
+ });
+ }
+
+ });
+
+ return [jobPriorityEntry];
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],99:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper');
+
+var elementHelper = require('../../../../helper/ElementHelper'),
+ eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+function isAsyncBefore(bo) {
+ return asyncCapableHelper.isAsyncBefore(bo);
+}
+
+function isAsyncAfter(bo) {
+ return asyncCapableHelper.isAsyncAfter(bo);
+}
+
+function getFailedJobRetryTimeCycle(bo) {
+ return asyncCapableHelper.getFailedJobRetryTimeCycle(bo);
+}
+
+function removeFailedJobRetryTimeCycle(bo, element) {
+ return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element);
+}
+
+function createExtensionElements(parent, bpmnFactory) {
+ return elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, parent, bpmnFactory);
+}
+
+function createFailedJobRetryTimeCycle(parent, bpmnFactory, cycle) {
+ return elementHelper.createElement('camunda:FailedJobRetryTimeCycle', { body: cycle }, parent, bpmnFactory);
+}
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getBusinessObject = options.getBusinessObject;
+
+ var idPrefix = options.idPrefix || '',
+ labelPrefix = options.labelPrefix || '';
+
+ var retryTimeCycleEntry = entryFactory.textField({
+ id: idPrefix + 'retryTimeCycle',
+ label: labelPrefix + translate('Retry Time Cycle'),
+ modelProperty: 'cycle',
+
+ get: function get(element, node) {
+ var retryTimeCycle = getFailedJobRetryTimeCycle(getBusinessObject(element));
+ var value = retryTimeCycle && retryTimeCycle.get('body');
+ return {
+ cycle: value
+ };
+ },
+
+ set: function set(element, values, node) {
+ var newCycle = values.cycle;
+ var bo = getBusinessObject(element);
+
+ if (newCycle === '' || typeof newCycle === 'undefined') {
+ // remove retry time cycle element(s)
+ return removeFailedJobRetryTimeCycle(bo, element);
+ }
+
+ var retryTimeCycle = getFailedJobRetryTimeCycle(bo);
+
+ if (!retryTimeCycle) {
+ // add new retry time cycle element
+ var commands = [];
+
+ var extensionElements = bo.get('extensionElements');
+ if (!extensionElements) {
+ extensionElements = createExtensionElements(bo, bpmnFactory);
+ commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
+ }
+
+ retryTimeCycle = createFailedJobRetryTimeCycle(extensionElements, bpmnFactory, newCycle);
+ commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [retryTimeCycle], []));
+
+ return commands;
+ }
+
+ // update existing retry time cycle element
+ return cmdHelper.updateBusinessObject(element, retryTimeCycle, { body: newCycle });
+ },
+
+ hidden: function hidden(element) {
+ var bo = getBusinessObject(element);
+
+ if (bo && (isAsyncBefore(bo) || isAsyncAfter(bo))) {
+ return false;
+ }
+
+ if (is(element, 'bpmn:Event')) {
+ return !eventDefinitionHelper.getTimerEventDefinition(element);
+ }
+
+ return true;
+ }
+
+ });
+
+ return [retryTimeCycleEntry];
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/AsyncCapableHelper":23,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/EventDefinitionHelper":26,"bpmn-js/lib/util/ModelUtil":216}],100:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is,
+ getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var extensionElementsEntry = require('./ExtensionElements'),
+ extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper'),
+ elementHelper = require('../../../../helper/ElementHelper'),
+ ImplementationTypeHelper = require('../../../../helper/ImplementationTypeHelper');
+
+function getListeners(bo, type) {
+ return bo && extensionElementsHelper.getExtensionElements(bo, type) || [];
+}
+
+var CAMUNDA_EXECUTION_LISTENER_ELEMENT = 'camunda:ExecutionListener';
+var CAMUNDA_TASK_LISTENER_ELEMENT = 'camunda:TaskListener';
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var LISTENER_TYPE_LABEL = {
+ class: translate('Java Class'),
+ expression: translate('Expression'),
+ delegateExpression: translate('Delegate Expression'),
+ script: translate('Script')
+ };
+
+ var bo;
+
+ var result = {
+ getSelectedListener: getSelectedListener
+ };
+
+ var entries = result.entries = [];
+
+ var isSequenceFlow = ImplementationTypeHelper.isSequenceFlow(element);
+
+ function getSelectedListener(element, node) {
+ var selection = executionListenerEntry && executionListenerEntry.getSelected(element, node) || { idx: -1 };
+
+ var listener = getListeners(bo, CAMUNDA_EXECUTION_LISTENER_ELEMENT)[selection.idx];
+ if (!listener && taskListenerEntry) {
+ selection = taskListenerEntry.getSelected(element, node);
+ listener = getListeners(bo, CAMUNDA_TASK_LISTENER_ELEMENT)[selection.idx];
+ }
+ return listener;
+ }
+
+ var setOptionLabelValue = function setOptionLabelValue(type) {
+ return function (element, node, option, property, value, idx) {
+ var listeners = getListeners(bo, type);
+ var listener = listeners[idx];
+ var listenerType = ImplementationTypeHelper.getImplementationType(listener);
+
+ var event = listener.get('event') ? listener.get('event') : '';
+
+ var label = (event || '*') + ' : ' + (LISTENER_TYPE_LABEL[listenerType] || '');
+
+ option.text = label;
+ };
+ };
+
+ var newElement = function newElement(element, type, initialEvent) {
+ return function (element, extensionElements, value) {
+ var props = {
+ event: initialEvent,
+ class: ''
+ };
+
+ var newElem = elementHelper.createElement(type, props, extensionElements, bpmnFactory);
+
+ return cmdHelper.addElementsTolist(element, extensionElements, 'values', [newElem]);
+ };
+ };
+
+ var removeElement = function removeElement(element, type) {
+ return function (element, extensionElements, value, idx) {
+ var listeners = getListeners(bo, type);
+ var listener = listeners[idx];
+ if (listener) {
+ return extensionElementsHelper.removeEntry(bo, element, listener);
+ }
+ };
+ };
+
+ ////////// Execution Listener
+
+ if (is(element, 'bpmn:FlowElement') || is(element, 'bpmn:Process') || is(element, 'bpmn:Participant')) {
+ bo = getBusinessObject(element);
+ if (is(element, 'bpmn:Participant')) {
+ element = element.processRef;
+ bo = bo.get('processRef');
+ }
+
+ if (bo) {
+
+ var executionListenerEntry = extensionElementsEntry(element, bpmnFactory, {
+ id: 'executionListeners',
+ label: translate('Execution Listener'),
+ modelProperty: 'name',
+ idGeneration: 'false',
+ reference: 'processRef',
+
+ createExtensionElement: newElement(element, CAMUNDA_EXECUTION_LISTENER_ELEMENT, isSequenceFlow ? 'take' : 'start'),
+ removeExtensionElement: removeElement(element, CAMUNDA_EXECUTION_LISTENER_ELEMENT),
+
+ getExtensionElements: function getExtensionElements(element) {
+ return getListeners(bo, CAMUNDA_EXECUTION_LISTENER_ELEMENT);
+ },
+
+ onSelectionChange: function onSelectionChange(element, node, event, scope) {
+ taskListenerEntry && taskListenerEntry.deselect(element, node);
+ },
+
+ setOptionLabelValue: setOptionLabelValue(CAMUNDA_EXECUTION_LISTENER_ELEMENT)
+
+ });
+ entries.push(executionListenerEntry);
+ }
+ }
+
+ ////////// Task Listener
+
+ if (is(element, 'bpmn:UserTask')) {
+ bo = getBusinessObject(element);
+
+ var taskListenerEntry = extensionElementsEntry(element, bpmnFactory, {
+ id: 'taskListeners',
+ label: translate('Task Listener'),
+ modelProperty: 'name',
+ idGeneration: 'false',
+
+ createExtensionElement: newElement(element, CAMUNDA_TASK_LISTENER_ELEMENT, 'create'),
+ removeExtensionElement: removeElement(element, CAMUNDA_TASK_LISTENER_ELEMENT),
+
+ getExtensionElements: function getExtensionElements(element) {
+ return getListeners(bo, CAMUNDA_TASK_LISTENER_ELEMENT);
+ },
+
+ onSelectionChange: function onSelectionChange(element, node, event, scope) {
+ executionListenerEntry.deselect(element, node);
+ },
+
+ setOptionLabelValue: setOptionLabelValue(CAMUNDA_TASK_LISTENER_ELEMENT)
+
+ });
+ entries.push(taskListenerEntry);
+ }
+
+ return result;
+};
+
+},{"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"../../../../helper/ImplementationTypeHelper":29,"./ExtensionElements":90,"bpmn-js/lib/util/ModelUtil":216}],101:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var entryFactory = require('../../../../factory/EntryFactory');
+
+var elementHelper = require('../../../../helper/ElementHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+var domClasses = require('min-dom/lib/classes');
+
+/**
+ * Get a property value of the loop characteristics.
+ *
+ * @param {djs.model.Base} element
+ * @param {string} propertyName
+ *
+ * @return {any} the property value
+ */
+function getProperty(element, propertyName) {
+ var loopCharacteristics = getLoopCharacteristics(element);
+ return loopCharacteristics && loopCharacteristics.get(propertyName);
+}
+
+/**
+ * Get the body of a given expression.
+ *
+ * @param {ModdleElement} expression
+ *
+ * @return {string} the body (value) of the expression
+ */
+function getBody(expression) {
+ return expression && expression.get('body');
+}
+
+/**
+ * Get the loop characteristics of an element.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {ModdleElement} the loop characteristics
+ */
+function getLoopCharacteristics(element) {
+ var bo = getBusinessObject(element);
+ return bo.loopCharacteristics;
+}
+
+/**
+ * Get the loop cardinality of the loop characteristics.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {ModdleElement} an expression representing the loop cardinality
+ */
+function getLoopCardinality(element) {
+ return getProperty(element, 'loopCardinality');
+}
+
+/**
+ * Get the loop cardinality value of the loop characteristics.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {string} the loop cardinality value
+ */
+function getLoopCardinalityValue(element) {
+ var loopCardinality = getLoopCardinality(element);
+ return getBody(loopCardinality);
+}
+
+/**
+ * Get the completion condition of the loop characteristics.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {ModdleElement} an expression representing the completion condition
+ */
+function getCompletionCondition(element) {
+ return getProperty(element, 'completionCondition');
+}
+
+/**
+ * Get the completion condition value of the loop characteristics.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {string} the completion condition value
+ */
+function getCompletionConditionValue(element) {
+ var completionCondition = getCompletionCondition(element);
+ return getBody(completionCondition);
+}
+
+/**
+ * Get the 'camunda:collection' attribute value of the loop characteristics.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {string} the 'camunda:collection' value
+ */
+function getCollection(element) {
+ return getProperty(element, 'camunda:collection');
+}
+
+/**
+ * Get the 'camunda:elementVariable' attribute value of the loop characteristics.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {string} the 'camunda:elementVariable' value
+ */
+function getElementVariable(element) {
+ return getProperty(element, 'camunda:elementVariable');
+}
+
+/**
+ * Creates 'bpmn:FormalExpression' element.
+ *
+ * @param {ModdleElement} parent
+ * @param {string} body
+ * @param {BpmnFactory} bpmnFactory
+ *
+ * @result {ModdleElement} a formal expression
+ */
+function createFormalExpression(parent, body, bpmnFactory) {
+ return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory);
+}
+
+/**
+ * Updates a specific formal expression of the loop characteristics.
+ *
+ * @param {djs.model.Base} element
+ * @param {string} propertyName
+ * @param {string} newValue
+ * @param {BpmnFactory} bpmnFactory
+ */
+function updateFormalExpression(element, propertyName, newValue, bpmnFactory) {
+ var loopCharacteristics = getLoopCharacteristics(element);
+
+ var expressionProps = {};
+
+ if (!newValue) {
+ // remove formal expression
+ expressionProps[propertyName] = undefined;
+ return cmdHelper.updateBusinessObject(element, loopCharacteristics, expressionProps);
+ }
+
+ var existingExpression = loopCharacteristics.get(propertyName);
+
+ if (!existingExpression) {
+ // add formal expression
+ expressionProps[propertyName] = createFormalExpression(loopCharacteristics, newValue, bpmnFactory);
+ return cmdHelper.updateBusinessObject(element, loopCharacteristics, expressionProps);
+ }
+
+ // edit existing formal expression
+ return cmdHelper.updateBusinessObject(element, existingExpression, {
+ body: newValue
+ });
+}
+
+module.exports = function (element, bpmnFactory, translate) {
+
+ var entries = [];
+
+ // error message /////////////////////////////////////////////////////////////////
+
+ entries.push({
+ id: 'multiInstance-errorMessage',
+ html: '' + ' ' + translate('Must provide either loop cardinality or collection') + '
',
+
+ isValid: function isValid(element, node, notification, scope) {
+ var loopCharacteristics = getLoopCharacteristics(element);
+
+ var isValid = true;
+ if (loopCharacteristics) {
+ var loopCardinality = getLoopCardinalityValue(element);
+ var collection = getCollection(element);
+
+ isValid = !loopCardinality && !collection;
+ }
+
+ domClasses(node).toggle('bpp-hidden', !isValid);
+ domClasses(notification).toggle('bpp-error-message', isValid);
+
+ return isValid;
+ }
+ });
+
+ // loop cardinality //////////////////////////////////////////////////////////////
+
+ entries.push(entryFactory.textField({
+ id: 'multiInstance-loopCardinality',
+ label: translate('Loop Cardinality'),
+ modelProperty: 'loopCardinality',
+
+ get: function get(element, node) {
+ return {
+ loopCardinality: getLoopCardinalityValue(element)
+ };
+ },
+
+ set: function set(element, values) {
+ return updateFormalExpression(element, 'loopCardinality', values.loopCardinality, bpmnFactory);
+ }
+ }));
+
+ // collection //////////////////////////////////////////////////////////////////
+
+ entries.push(entryFactory.textField({
+ id: 'multiInstance-collection',
+ label: translate('Collection'),
+ modelProperty: 'collection',
+
+ get: function get(element, node) {
+ return {
+ collection: getCollection(element)
+ };
+ },
+
+ set: function set(element, values) {
+ var loopCharacteristics = getLoopCharacteristics(element);
+ return cmdHelper.updateBusinessObject(element, loopCharacteristics, {
+ 'camunda:collection': values.collection || undefined
+ });
+ },
+
+ validate: function validate(element, values, node) {
+ var collection = getCollection(element);
+ var elementVariable = getElementVariable(element);
+
+ if (!collection && elementVariable) {
+ return { collection: 'Must provide a value' };
+ }
+ }
+ }));
+
+ // element variable ////////////////////////////////////////////////////////////
+
+ entries.push(entryFactory.textField({
+ id: 'multiInstance-elementVariable',
+ label: translate('Element Variable'),
+ modelProperty: 'elementVariable',
+
+ get: function get(element, node) {
+ return {
+ elementVariable: getElementVariable(element)
+ };
+ },
+
+ set: function set(element, values) {
+ var loopCharacteristics = getLoopCharacteristics(element);
+ return cmdHelper.updateBusinessObject(element, loopCharacteristics, {
+ 'camunda:elementVariable': values.elementVariable || undefined
+ });
+ }
+ }));
+
+ // Completion Condition //////////////////////////////////////////////////////
+
+ entries.push(entryFactory.textField({
+ id: 'multiInstance-completionCondition',
+ label: translate('Completion Condition'),
+ modelProperty: 'completionCondition',
+
+ get: function get(element) {
+ return {
+ completionCondition: getCompletionConditionValue(element)
+ };
+ },
+
+ set: function set(element, values) {
+ return updateFormalExpression(element, 'completionCondition', values.completionCondition, bpmnFactory);
+ }
+ }));
+
+ return entries;
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"bpmn-js/lib/util/ModelUtil":216,"min-dom/lib/classes":106}],102:[function(require,module,exports){
+'use strict';
+
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
+ is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var factory = require('../../../../factory/EntryFactory');
+
+var elementHelper = require('../../../../helper/ElementHelper'),
+ extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
+ cmdHelper = require('../../../../helper/CmdHelper'),
+ utils = require('../../../../Utils');
+
+var assign = require('lodash/object/assign'),
+ forEach = require('lodash/collection/forEach'),
+ find = require('lodash/collection/find');
+
+function generatePropertyId() {
+ return utils.nextId('Property_');
+}
+
+/**
+ * Get all camunda:property objects for a specific business object
+ *
+ * @param {ModdleElement} parent
+ *
+ * @return {Array} a list of camunda:property objects
+ */
+function getPropertyValues(parent) {
+ var properties = parent && getPropertiesElement(parent);
+ if (properties && properties.values) {
+ return properties.values;
+ }
+ return [];
+}
+
+/**
+ * Get all camunda:Properties object for a specific business object
+ *
+ * @param {ModdleElement} parent
+ *
+ * @return {ModdleElement} a camunda:Properties object
+ */
+function getPropertiesElement(element) {
+ if (!isExtensionElements(element)) {
+ return element.properties;
+ } else {
+ return getPropertiesElementInsideExtensionElements(element);
+ }
+}
+
+/**
+ * Get first camunda:Properties object for a specific bpmn:ExtensionElements
+ * business object.
+ *
+ * @param {ModdleElement} extensionElements
+ *
+ * @return {ModdleElement} a camunda:Properties object
+ */
+function getPropertiesElementInsideExtensionElements(extensionElements) {
+ return find(extensionElements.values, function (elem) {
+ return is(elem, 'camunda:Properties');
+ });
+}
+
+/**
+ * Returns true, if the given business object is a bpmn:ExtensionElements.
+ *
+ * @param {ModdleElement} element
+ *
+ * @return {boolean} a boolean value
+ */
+function isExtensionElements(element) {
+ return is(element, 'bpmn:ExtensionElements');
+}
+
+/**
+ * Create a camunda:property entry using tableEntryFactory
+ *
+ * @param {djs.model.Base} element
+ * @param {BpmnFactory} bpmnFactory
+ * @param {Object} options
+ * @param {string} options.id
+ * @param {Array} options.modelProperties
+ * @param {Array} options.labels
+ * @param {function} options.getParent Gets the parent business object
+ * @param {function} options.show Indicate when the entry will be shown, should return boolean
+ */
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getParent = options.getParent;
+
+ var modelProperties = options.modelProperties,
+ createParent = options.createParent;
+
+ var bo = getBusinessObject(element);
+ if (is(element, 'bpmn:Participant')) {
+ bo = bo.get('processRef');
+ }
+
+ // build properties group only when the participant have a processRef
+ if (!bo) {
+ return;
+ }
+
+ assign(options, {
+ addLabel: translate('Add Property'),
+ getElements: function getElements(element, node) {
+ var parent = getParent(element, node, bo);
+ return getPropertyValues(parent);
+ },
+ addElement: function addElement(element, node) {
+ var commands = [],
+ parent = getParent(element, node, bo);
+
+ if (!parent && typeof createParent === 'function') {
+ var result = createParent(element, bo);
+ parent = result.parent;
+ commands.push(result.cmd);
+ }
+
+ var properties = getPropertiesElement(parent);
+ if (!properties) {
+ properties = elementHelper.createElement('camunda:Properties', {}, parent, bpmnFactory);
+
+ if (!isExtensionElements(parent)) {
+ commands.push(cmdHelper.updateBusinessObject(element, parent, { 'properties': properties }));
+ } else {
+ commands.push(cmdHelper.addAndRemoveElementsFromList(element, parent, 'values', 'extensionElements', [properties], []));
+ }
+ }
+
+ var propertyProps = {};
+ forEach(modelProperties, function (prop) {
+ propertyProps[prop] = undefined;
+ });
+
+ // create id if necessary
+ if (modelProperties.indexOf('id') >= 0) {
+ propertyProps.id = generatePropertyId();
+ }
+
+ var property = elementHelper.createElement('camunda:Property', propertyProps, properties, bpmnFactory);
+ commands.push(cmdHelper.addElementsTolist(element, properties, 'values', [property]));
+
+ return commands;
+ },
+ updateElement: function updateElement(element, value, node, idx) {
+ var parent = getParent(element, node, bo),
+ property = getPropertyValues(parent)[idx];
+
+ forEach(modelProperties, function (prop) {
+ value[prop] = value[prop] || undefined;
+ });
+
+ return cmdHelper.updateBusinessObject(element, property, value);
+ },
+ validate: function validate(element, value, node, idx) {
+ // validate id if necessary
+ if (modelProperties.indexOf('id') >= 0) {
+
+ var parent = getParent(element, node, bo),
+ properties = getPropertyValues(parent),
+ property = properties[idx];
+
+ if (property) {
+ // check if id is valid
+ var validationError = utils.isIdValid(property, value.id);
+
+ if (validationError) {
+ return { id: validationError };
+ }
+ }
+ }
+ },
+ removeElement: function removeElement(element, node, idx) {
+ var commands = [],
+ parent = getParent(element, node, bo),
+ properties = getPropertiesElement(parent),
+ propertyValues = getPropertyValues(parent),
+ currentProperty = propertyValues[idx];
+
+ commands.push(cmdHelper.removeElementsFromList(element, properties, 'values', null, [currentProperty]));
+
+ if (propertyValues.length === 1) {
+ // remove camunda:properties if the last existing property has been removed
+ if (!isExtensionElements(parent)) {
+ commands.push(cmdHelper.updateBusinessObject(element, parent, { properties: undefined }));
+ } else {
+ forEach(parent.values, function (value) {
+ if (is(value, 'camunda:Properties')) {
+ commands.push(extensionElementsHelper.removeEntry(bo, element, value));
+ }
+ });
+ }
+ }
+
+ return commands;
+ }
+ });
+
+ return factory.table(options);
+};
+
+},{"../../../../Utils":5,"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/find":421,"lodash/collection/forEach":422,"lodash/object/assign":496}],103:[function(require,module,exports){
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var assign = require('lodash/object/assign');
+
+var entryFactory = require('../../../../factory/EntryFactory'),
+ cmdHelper = require('../../../../helper/CmdHelper');
+
+module.exports = function (element, bpmnFactory, options, translate) {
+
+ var getBusinessObject = options.getBusinessObject,
+ hideResultVariable = options.hideResultVariable,
+ id = options.id || 'resultVariable';
+
+ var resultVariableEntry = entryFactory.textField({
+ id: id,
+ label: translate('Result Variable'),
+ modelProperty: 'resultVariable',
+
+ get: function get(element, node) {
+ var bo = getBusinessObject(element);
+ return { resultVariable: bo.get('camunda:resultVariable') };
+ },
+
+ set: function set(element, values, node) {
+ var bo = getBusinessObject(element);
+
+ var resultVariable = values.resultVariable || undefined;
+
+ var props = {
+ 'camunda:resultVariable': resultVariable
+ };
+
+ if (is(bo, 'camunda:DmnCapable') && !resultVariable) {
+ props = assign({ 'camunda:mapDecisionResult': 'resultList' }, props);
+ }
+
+ return cmdHelper.updateBusinessObject(element, bo, props);
+ },
+
+ hidden: function hidden(element, node) {
+ if (typeof hideResultVariable === 'function') {
+ return hideResultVariable.apply(resultVariableEntry, arguments);
+ }
+ }
+
+ });
+
+ return [resultVariableEntry];
+};
+
+},{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216,"lodash/object/assign":496}],104:[function(require,module,exports){
+'use strict';
+
+var domQuery = require('min-dom/lib/query'),
+ utils = require('../../../../Utils');
+
+function getScriptType(node) {
+ return utils.selectedType('select[name=scriptType]', node.parentElement);
+}
+
+module.exports = function (scriptLanguagePropName, scriptValuePropName, isFormatRequired) {
+
+ return {
+ template: '' + '
Script Format ' + '
' + ' ' + '' + 'X ' + ' ' + '
' + '
' + '' + '
Script Type ' + '
' + '' + 'Inline Script ' + 'External Resource ' + ' ' + '
' + '
' + '' + '
Resource ' + '
' + ' ' + '' + 'X ' + ' ' + '
' + '
' + '' + '
Script ' + '
' + '' + '
' + '
',
+
+ get: function get(element, bo) {
+ var values = {};
+
+ // read values from xml:
+ var boScriptResource = bo.get('camunda:resource'),
+ boScript = bo.get(scriptValuePropName),
+ boScriptFormat = bo.get(scriptLanguagePropName);
+
+ if (typeof boScriptResource !== 'undefined') {
+ values.scriptResourceValue = boScriptResource;
+ values.scriptType = 'scriptResource';
+ } else {
+ values.scriptValue = boScript;
+ values.scriptType = 'script';
+ }
+
+ values.scriptFormat = boScriptFormat;
+
+ return values;
+ },
+
+ set: function set(element, values, containerElement) {
+ var scriptFormat = values.scriptFormat,
+ scriptType = values.scriptType,
+ scriptResourceValue = values.scriptResourceValue,
+ scriptValue = values.scriptValue;
+
+ // init update
+ var update = {
+ 'camunda:resource': undefined
+ };
+ update[scriptValuePropName] = undefined;
+ update[scriptLanguagePropName] = undefined;
+
+ if (isFormatRequired) {
+ // always set language
+ update[scriptLanguagePropName] = scriptFormat || '';
+ } else
+ // set language only when scriptFormat has a value
+ if (scriptFormat !== '') {
+ update[scriptLanguagePropName] = scriptFormat;
+ }
+
+ // set either inline script or resource
+ if ('scriptResource' === scriptType) {
+ update['camunda:resource'] = scriptResourceValue || '';
+ } else {
+ update[scriptValuePropName] = scriptValue || '';
+ }
+
+ return update;
+ },
+
+ validate: function validate(element, values) {
+ var validationResult = {};
+
+ if (values.scriptType === 'script' && !values.scriptValue) {
+ validationResult.scriptValue = 'Must provide a value';
+ }
+
+ if (values.scriptType === 'scriptResource' && !values.scriptResourceValue) {
+ validationResult.scriptResourceValue = 'Must provide a value';
+ }
+
+ if (isFormatRequired && (!values.scriptFormat || values.scriptFormat.length === 0)) {
+ validationResult.scriptFormat = 'Must provide a value';
+ }
+
+ return validationResult;
+ },
+
+ clearScriptFormat: function clearScriptFormat(element, inputNode, btnNode, scopeNode) {
+ domQuery('input[name=scriptFormat]', scopeNode).value = '';
+
+ return true;
+ },
+
+ canClearScriptFormat: function canClearScriptFormat(element, inputNode, btnNode, scopeNode) {
+ var input = domQuery('input[name=scriptFormat]', scopeNode);
+
+ return input.value !== '';
+ },
+
+ clearScriptResource: function clearScriptResource(element, inputNode, btnNode, scopeNode) {
+ domQuery('input[name=scriptResourceValue]', scopeNode).value = '';
+
+ return true;
+ },
+
+ canClearScriptResource: function canClearScriptResource(element, inputNode, btnNode, scopeNode) {
+ var input = domQuery('input[name=scriptResourceValue]', scopeNode);
+
+ return input.value !== '';
+ },
+
+ clearScript: function clearScript(element, inputNode, btnNode, scopeNode) {
+ domQuery('textarea[name=scriptValue]', scopeNode).value = '';
+
+ return true;
+ },
+
+ canClearScript: function canClearScript(element, inputNode, btnNode, scopeNode) {
+ var input = domQuery('textarea[name=scriptValue]', scopeNode);
+
+ return input.value !== '';
+ },
+
+ isScriptResource: function isScriptResource(element, inputNode, btnNode, scopeNode) {
+ var scriptType = getScriptType(scopeNode);
+ return scriptType === 'scriptResource';
+ },
+
+ isScript: function isScript(element, inputNode, btnNode, scopeNode) {
+ var scriptType = getScriptType(scopeNode);
+ return scriptType === 'script';
+ }
+
+ };
+};
+
+},{"../../../../Utils":5,"min-dom/lib/query":112}],105:[function(require,module,exports){
+"use strict";
+
+/**
+ * Set attribute `name` to `val`, or get attr `name`.
+ *
+ * @param {Element} el
+ * @param {String} name
+ * @param {String} [val]
+ * @api public
+ */
+
+module.exports = function (el, name, val) {
+ // get
+ if (arguments.length == 2) {
+ return el.getAttribute(name);
+ }
+
+ // remove
+ if (val === null) {
+ return el.removeAttribute(name);
+ }
+
+ // set
+ el.setAttribute(name, val);
+
+ return el;
+};
+
+},{}],106:[function(require,module,exports){
+'use strict';
+
+module.exports = require('component-classes');
+
+},{"component-classes":230}],107:[function(require,module,exports){
+"use strict";
+
+module.exports = function (el) {
+
+ var c;
+
+ while (el.childNodes.length) {
+ c = el.childNodes[0];
+ el.removeChild(c);
+ }
+
+ return el;
+};
+
+},{}],108:[function(require,module,exports){
+'use strict';
+
+module.exports = require('component-closest');
+
+},{"component-closest":231}],109:[function(require,module,exports){
+'use strict';
+
+module.exports = require('component-delegate');
+
+},{"component-delegate":232}],110:[function(require,module,exports){
+'use strict';
+
+module.exports = require('domify');
+
+},{"domify":411}],111:[function(require,module,exports){
+'use strict';
+
+module.exports = require('component-matches-selector');
+
+},{"component-matches-selector":235}],112:[function(require,module,exports){
+'use strict';
+
+module.exports = require('component-query');
+
+},{"component-query":236}],113:[function(require,module,exports){
+"use strict";
+
+module.exports = function (el) {
+ el.parentNode && el.parentNode.removeChild(el);
+};
+
+},{}],114:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Modeler;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _ids = require('ids');
+
+var _ids2 = _interopRequireDefault(_ids);
+
+var _Viewer = require('./Viewer');
+
+var _Viewer2 = _interopRequireDefault(_Viewer);
+
+var _NavigatedViewer = require('./NavigatedViewer');
+
+var _NavigatedViewer2 = _interopRequireDefault(_NavigatedViewer);
+
+var _keyboardMove = require('diagram-js/lib/navigation/keyboard-move');
+
+var _keyboardMove2 = _interopRequireDefault(_keyboardMove);
+
+var _movecanvas = require('diagram-js/lib/navigation/movecanvas');
+
+var _movecanvas2 = _interopRequireDefault(_movecanvas);
+
+var _touch = require('diagram-js/lib/navigation/touch');
+
+var _touch2 = _interopRequireDefault(_touch);
+
+var _zoomscroll = require('diagram-js/lib/navigation/zoomscroll');
+
+var _zoomscroll2 = _interopRequireDefault(_zoomscroll);
+
+var _alignElements = require('diagram-js/lib/features/align-elements');
+
+var _alignElements2 = _interopRequireDefault(_alignElements);
+
+var _autoPlace = require('./features/auto-place');
+
+var _autoPlace2 = _interopRequireDefault(_autoPlace);
+
+var _autoResize = require('./features/auto-resize');
+
+var _autoResize2 = _interopRequireDefault(_autoResize);
+
+var _autoScroll = require('diagram-js/lib/features/auto-scroll');
+
+var _autoScroll2 = _interopRequireDefault(_autoScroll);
+
+var _bendpoints = require('diagram-js/lib/features/bendpoints');
+
+var _bendpoints2 = _interopRequireDefault(_bendpoints);
+
+var _contextPad = require('./features/context-pad');
+
+var _contextPad2 = _interopRequireDefault(_contextPad);
+
+var _copyPaste = require('./features/copy-paste');
+
+var _copyPaste2 = _interopRequireDefault(_copyPaste);
+
+var _distributeElements = require('./features/distribute-elements');
+
+var _distributeElements2 = _interopRequireDefault(_distributeElements);
+
+var _editorActions = require('./features/editor-actions');
+
+var _editorActions2 = _interopRequireDefault(_editorActions);
+
+var _keyboard = require('./features/keyboard');
+
+var _keyboard2 = _interopRequireDefault(_keyboard);
+
+var _keyboardMoveSelection = require('diagram-js/lib/features/keyboard-move-selection');
+
+var _keyboardMoveSelection2 = _interopRequireDefault(_keyboardMoveSelection);
+
+var _labelEditing = require('./features/label-editing');
+
+var _labelEditing2 = _interopRequireDefault(_labelEditing);
+
+var _modeling = require('./features/modeling');
+
+var _modeling2 = _interopRequireDefault(_modeling);
+
+var _move = require('diagram-js/lib/features/move');
+
+var _move2 = _interopRequireDefault(_move);
+
+var _palette = require('./features/palette');
+
+var _palette2 = _interopRequireDefault(_palette);
+
+var _replacePreview = require('./features/replace-preview');
+
+var _replacePreview2 = _interopRequireDefault(_replacePreview);
+
+var _resize = require('diagram-js/lib/features/resize');
+
+var _resize2 = _interopRequireDefault(_resize);
+
+var _snapping = require('./features/snapping');
+
+var _snapping2 = _interopRequireDefault(_snapping);
+
+var _search = require('./features/search');
+
+var _search2 = _interopRequireDefault(_search);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var initialDiagram = '' + '' + '' + ' ' + ' ' + '' + '' + '' + ' ' + ' ' + ' ' + ' ' + ' ';
+
+/**
+ * A modeler for BPMN 2.0 diagrams.
+ *
+ *
+ * ## Extending the Modeler
+ *
+ * In order to extend the viewer pass extension modules to bootstrap via the
+ * `additionalModules` option. An extension module is an object that exposes
+ * named services.
+ *
+ * The following example depicts the integration of a simple
+ * logging component that integrates with interaction events:
+ *
+ *
+ * ```javascript
+ *
+ * // logging component
+ * function InteractionLogger(eventBus) {
+ * eventBus.on('element.hover', function(event) {
+ * console.log()
+ * })
+ * }
+ *
+ * InteractionLogger.$inject = [ 'eventBus' ]; // minification save
+ *
+ * // extension module
+ * var extensionModule = {
+ * __init__: [ 'interactionLogger' ],
+ * interactionLogger: [ 'type', InteractionLogger ]
+ * };
+ *
+ * // extend the viewer
+ * var bpmnModeler = new Modeler({ additionalModules: [ extensionModule ] });
+ * bpmnModeler.importXML(...);
+ * ```
+ *
+ *
+ * ## Customizing / Replacing Components
+ *
+ * You can replace individual diagram components by redefining them in override modules.
+ * This works for all components, including those defined in the core.
+ *
+ * Pass in override modules via the `options.additionalModules` flag like this:
+ *
+ * ```javascript
+ * function CustomContextPadProvider(contextPad) {
+ *
+ * contextPad.registerProvider(this);
+ *
+ * this.getContextPadEntries = function(element) {
+ * // no entries, effectively disable the context pad
+ * return {};
+ * };
+ * }
+ *
+ * CustomContextPadProvider.$inject = [ 'contextPad' ];
+ *
+ * var overrideModule = {
+ * contextPadProvider: [ 'type', CustomContextPadProvider ]
+ * };
+ *
+ * var bpmnModeler = new Modeler({ additionalModules: [ overrideModule ]});
+ * ```
+ *
+ * @param {Object} [options] configuration options to pass to the viewer
+ * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
+ * @param {String|Number} [options.width] the width of the viewer
+ * @param {String|Number} [options.height] the height of the viewer
+ * @param {Object} [options.moddleExtensions] extension packages to provide
+ * @param {Array} [options.modules] a list of modules to override the default modules
+ * @param {Array} [options.additionalModules] a list of modules to use with the default modules
+ */
+function Modeler(options) {
+ _Viewer2.default.call(this, options);
+
+ // hook ID collection into the modeler
+ this.on('import.parse.complete', function (event) {
+ if (!event.error) {
+ this._collectIds(event.definitions, event.context);
+ }
+ }, this);
+
+ this.on('diagram.destroy', function () {
+ this.get('moddle').ids.clear();
+ }, this);
+}
+
+(0, _inherits2.default)(Modeler, _Viewer2.default);
+
+Modeler.Viewer = _Viewer2.default;
+Modeler.NavigatedViewer = _NavigatedViewer2.default;
+
+/**
+ * Create a new diagram to start modeling.
+ *
+ * @param {Function} [done]
+ */
+Modeler.prototype.createDiagram = function (done) {
+ return this.importXML(initialDiagram, done);
+};
+
+/**
+ * Create a moddle instance, attaching ids to it.
+ *
+ * @param {Object} options
+ */
+Modeler.prototype._createModdle = function (options) {
+ var moddle = _Viewer2.default.prototype._createModdle.call(this, options);
+
+ // attach ids to moddle to be able to track
+ // and validated ids in the BPMN 2.0 XML document
+ // tree
+ moddle.ids = new _ids2.default([32, 36, 1]);
+
+ return moddle;
+};
+
+/**
+ * Collect ids processed during parsing of the
+ * definitions object.
+ *
+ * @param {ModdleElement} definitions
+ * @param {Context} context
+ */
+Modeler.prototype._collectIds = function (definitions, context) {
+
+ var moddle = definitions.$model,
+ ids = moddle.ids,
+ id;
+
+ // remove references from previous import
+ ids.clear();
+
+ for (id in context.elementsById) {
+ ids.claim(id, context.elementsById[id]);
+ }
+};
+
+Modeler.prototype._interactionModules = [
+// non-modeling components
+_keyboardMove2.default, _movecanvas2.default, _touch2.default, _zoomscroll2.default];
+
+Modeler.prototype._modelingModules = [
+// modeling components
+_alignElements2.default, _autoPlace2.default, _autoScroll2.default, _autoResize2.default, _bendpoints2.default, _contextPad2.default, _copyPaste2.default, _distributeElements2.default, _editorActions2.default, _keyboard2.default, _keyboardMoveSelection2.default, _labelEditing2.default, _modeling2.default, _move2.default, _palette2.default, _replacePreview2.default, _resize2.default, _snapping2.default, _search2.default];
+
+// modules the modeler is composed of
+//
+// - viewer modules
+// - interaction modules
+// - modeling modules
+
+Modeler.prototype._modules = [].concat(Modeler.prototype._modules, Modeler.prototype._interactionModules, Modeler.prototype._modelingModules);
+
+},{"./NavigatedViewer":115,"./Viewer":116,"./features/auto-place":126,"./features/auto-resize":129,"./features/context-pad":131,"./features/copy-paste":133,"./features/distribute-elements":135,"./features/editor-actions":137,"./features/keyboard":139,"./features/label-editing":144,"./features/modeling":187,"./features/palette":193,"./features/replace-preview":198,"./features/search":205,"./features/snapping":208,"diagram-js/lib/features/align-elements":257,"diagram-js/lib/features/auto-scroll":263,"diagram-js/lib/features/bendpoints":269,"diagram-js/lib/features/keyboard-move-selection":296,"diagram-js/lib/features/move":334,"diagram-js/lib/features/resize":352,"diagram-js/lib/navigation/keyboard-move":384,"diagram-js/lib/navigation/movecanvas":386,"diagram-js/lib/navigation/touch":387,"diagram-js/lib/navigation/zoomscroll":390,"ids":414,"inherits":415}],115:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = NavigatedViewer;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _Viewer = require('./Viewer');
+
+var _Viewer2 = _interopRequireDefault(_Viewer);
+
+var _keyboardMove = require('diagram-js/lib/navigation/keyboard-move');
+
+var _keyboardMove2 = _interopRequireDefault(_keyboardMove);
+
+var _movecanvas = require('diagram-js/lib/navigation/movecanvas');
+
+var _movecanvas2 = _interopRequireDefault(_movecanvas);
+
+var _zoomscroll = require('diagram-js/lib/navigation/zoomscroll');
+
+var _zoomscroll2 = _interopRequireDefault(_zoomscroll);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A viewer that includes mouse navigation facilities
+ *
+ * @param {Object} options
+ */
+function NavigatedViewer(options) {
+ _Viewer2.default.call(this, options);
+}
+
+(0, _inherits2.default)(NavigatedViewer, _Viewer2.default);
+
+NavigatedViewer.prototype._navigationModules = [_keyboardMove2.default, _movecanvas2.default, _zoomscroll2.default];
+
+NavigatedViewer.prototype._modules = [].concat(NavigatedViewer.prototype._modules, NavigatedViewer.prototype._navigationModules);
+
+},{"./Viewer":116,"diagram-js/lib/navigation/keyboard-move":384,"diagram-js/lib/navigation/movecanvas":386,"diagram-js/lib/navigation/zoomscroll":390,"inherits":415}],116:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Viewer;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var _tinySvg = require('tiny-svg');
+
+var _diagramJs = require('diagram-js');
+
+var _diagramJs2 = _interopRequireDefault(_diagramJs);
+
+var _bpmnModdle = require('bpmn-moddle');
+
+var _bpmnModdle2 = _interopRequireDefault(_bpmnModdle);
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _Importer = require('./import/Importer');
+
+var _core = require('./core');
+
+var _core2 = _interopRequireDefault(_core);
+
+var _translate = require('diagram-js/lib/i18n/translate');
+
+var _translate2 = _interopRequireDefault(_translate);
+
+var _selection = require('diagram-js/lib/features/selection');
+
+var _selection2 = _interopRequireDefault(_selection);
+
+var _overlays = require('diagram-js/lib/features/overlays');
+
+var _overlays2 = _interopRequireDefault(_overlays);
+
+var _PoweredByUtil = require('./util/PoweredByUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function checkValidationError(err) {
+
+ // check if we can help the user by indicating wrong BPMN 2.0 xml
+ // (in case he or the exporting tool did not get that right)
+
+ var pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/;
+ var match = pattern.exec(err.message);
+
+ if (match) {
+ err.message = 'unparsable content <' + match[1] + '> detected; ' + 'this may indicate an invalid BPMN 2.0 diagram file' + match[2];
+ }
+
+ return err;
+} /**
+ * The code in the area
+ * must not be changed.
+ *
+ * @see http://bpmn.io/license for more information.
+ */
+
+
+var DEFAULT_OPTIONS = {
+ width: '100%',
+ height: '100%',
+ position: 'relative'
+};
+
+/**
+ * Ensure the passed argument is a proper unit (defaulting to px)
+ */
+function ensureUnit(val) {
+ return val + ((0, _minDash.isNumber)(val) ? 'px' : '');
+}
+
+/**
+ * A viewer for BPMN 2.0 diagrams.
+ *
+ * Have a look at {@link NavigatedViewer} or {@link Modeler} for bundles that include
+ * additional features.
+ *
+ *
+ * ## Extending the Viewer
+ *
+ * In order to extend the viewer pass extension modules to bootstrap via the
+ * `additionalModules` option. An extension module is an object that exposes
+ * named services.
+ *
+ * The following example depicts the integration of a simple
+ * logging component that integrates with interaction events:
+ *
+ *
+ * ```javascript
+ *
+ * // logging component
+ * function InteractionLogger(eventBus) {
+ * eventBus.on('element.hover', function(event) {
+ * console.log()
+ * })
+ * }
+ *
+ * InteractionLogger.$inject = [ 'eventBus' ]; // minification save
+ *
+ * // extension module
+ * var extensionModule = {
+ * __init__: [ 'interactionLogger' ],
+ * interactionLogger: [ 'type', InteractionLogger ]
+ * };
+ *
+ * // extend the viewer
+ * var bpmnViewer = new Viewer({ additionalModules: [ extensionModule ] });
+ * bpmnViewer.importXML(...);
+ * ```
+ *
+ * @param {Object} [options] configuration options to pass to the viewer
+ * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
+ * @param {String|Number} [options.width] the width of the viewer
+ * @param {String|Number} [options.height] the height of the viewer
+ * @param {Object} [options.moddleExtensions] extension packages to provide
+ * @param {Array} [options.modules] a list of modules to override the default modules
+ * @param {Array} [options.additionalModules] a list of modules to use with the default modules
+ */
+function Viewer(options) {
+
+ options = (0, _minDash.assign)({}, DEFAULT_OPTIONS, options);
+
+ this._moddle = this._createModdle(options);
+
+ this._container = this._createContainer(options);
+
+ /* */
+
+ addProjectLogo(this._container);
+
+ /* */
+
+ this._init(this._container, this._moddle, options);
+}
+
+(0, _inherits2.default)(Viewer, _diagramJs2.default);
+
+/**
+ * Parse and render a BPMN 2.0 diagram.
+ *
+ * Once finished the viewer reports back the result to the
+ * provided callback function with (err, warnings).
+ *
+ * ## Life-Cycle Events
+ *
+ * During import the viewer will fire life-cycle events:
+ *
+ * * import.parse.start (about to read model from xml)
+ * * import.parse.complete (model read; may have worked or not)
+ * * import.render.start (graphical import start)
+ * * import.render.complete (graphical import finished)
+ * * import.done (everything done)
+ *
+ * You can use these events to hook into the life-cycle.
+ *
+ * @param {String} xml the BPMN 2.0 xml
+ * @param {Function} [done] invoked with (err, warnings=[])
+ */
+Viewer.prototype.importXML = function (xml, done) {
+
+ // done is optional
+ done = done || function () {};
+
+ var self = this;
+
+ // hook in pre-parse listeners +
+ // allow xml manipulation
+ xml = this._emit('import.parse.start', { xml: xml }) || xml;
+
+ this._moddle.fromXML(xml, 'bpmn:Definitions', function (err, definitions, context) {
+
+ // hook in post parse listeners +
+ // allow definitions manipulation
+ definitions = self._emit('import.parse.complete', {
+ error: err,
+ definitions: definitions,
+ context: context
+ }) || definitions;
+
+ var parseWarnings = context.warnings;
+
+ if (err) {
+ err = checkValidationError(err);
+
+ self._emit('import.done', { error: err, warnings: parseWarnings });
+
+ return done(err, parseWarnings);
+ }
+
+ self.importDefinitions(definitions, function (err, importWarnings) {
+ var allWarnings = [].concat(parseWarnings, importWarnings || []);
+
+ self._emit('import.done', { error: err, warnings: allWarnings });
+
+ done(err, allWarnings);
+ });
+ });
+};
+
+/**
+ * Export the currently displayed BPMN 2.0 diagram as
+ * a BPMN 2.0 XML document.
+ *
+ * ## Life-Cycle Events
+ *
+ * During XML saving the viewer will fire life-cycle events:
+ *
+ * * saveXML.start (before serialization)
+ * * saveXML.serialized (after xml generation)
+ * * saveXML.done (everything done)
+ *
+ * You can use these events to hook into the life-cycle.
+ *
+ * @param {Object} [options] export options
+ * @param {Boolean} [options.format=false] output formated XML
+ * @param {Boolean} [options.preamble=true] output preamble
+ *
+ * @param {Function} done invoked with (err, xml)
+ */
+Viewer.prototype.saveXML = function (options, done) {
+
+ if (!done) {
+ done = options;
+ options = {};
+ }
+
+ var self = this;
+
+ var definitions = this._definitions;
+
+ if (!definitions) {
+ return done(new Error('no definitions loaded'));
+ }
+
+ // allow to fiddle around with definitions
+ definitions = this._emit('saveXML.start', {
+ definitions: definitions
+ }) || definitions;
+
+ this._moddle.toXML(definitions, options, function (err, xml) {
+
+ try {
+ xml = self._emit('saveXML.serialized', {
+ error: err,
+ xml: xml
+ }) || xml;
+
+ self._emit('saveXML.done', {
+ error: err,
+ xml: xml
+ });
+ } catch (e) {
+ console.error('error in saveXML life-cycle listener', e);
+ }
+
+ done(err, xml);
+ });
+};
+
+/**
+ * Export the currently displayed BPMN 2.0 diagram as
+ * an SVG image.
+ *
+ * ## Life-Cycle Events
+ *
+ * During SVG saving the viewer will fire life-cycle events:
+ *
+ * * saveSVG.start (before serialization)
+ * * saveSVG.done (everything done)
+ *
+ * You can use these events to hook into the life-cycle.
+ *
+ * @param {Object} [options]
+ * @param {Function} done invoked with (err, svgStr)
+ */
+Viewer.prototype.saveSVG = function (options, done) {
+
+ if (!done) {
+ done = options;
+ options = {};
+ }
+
+ this._emit('saveSVG.start');
+
+ var svg, err;
+
+ try {
+ var canvas = this.get('canvas');
+
+ var contentNode = canvas.getDefaultLayer(),
+ defsNode = (0, _minDom.query)('defs', canvas._svg);
+
+ var contents = (0, _tinySvg.innerSVG)(contentNode),
+ defs = defsNode ? '' + (0, _tinySvg.innerSVG)(defsNode) + ' ' : '';
+
+ var bbox = contentNode.getBBox();
+
+ svg = '\n' + '\n' + '\n' + '' + defs + contents + ' ';
+ } catch (e) {
+ err = e;
+ }
+
+ this._emit('saveSVG.done', {
+ error: err,
+ svg: svg
+ });
+
+ done(err, svg);
+};
+
+/**
+ * Get a named diagram service.
+ *
+ * @example
+ *
+ * var elementRegistry = viewer.get('elementRegistry');
+ * var startEventShape = elementRegistry.get('StartEvent_1');
+ *
+ * @param {String} name
+ *
+ * @return {Object} diagram service instance
+ *
+ * @method Viewer#get
+ */
+
+/**
+ * Invoke a function in the context of this viewer.
+ *
+ * @example
+ *
+ * viewer.invoke(function(elementRegistry) {
+ * var startEventShape = elementRegistry.get('StartEvent_1');
+ * });
+ *
+ * @param {Function} fn to be invoked
+ *
+ * @return {Object} the functions return value
+ *
+ * @method Viewer#invoke
+ */
+
+/**
+ * Remove all drawn elements from the viewer.
+ *
+ * After calling this method the viewer can still
+ * be reused for opening another diagram.
+ *
+ * @method Viewer#clear
+ */
+
+Viewer.prototype.importDefinitions = function (definitions, done) {
+
+ // catch synchronous exceptions during #clear()
+ try {
+ if (this._definitions) {
+ // clear existing rendered diagram
+ this.clear();
+ }
+
+ // update definitions
+ this._definitions = definitions;
+ } catch (e) {
+ return done(e);
+ }
+
+ // perform graphical import
+ return (0, _Importer.importBpmnDiagram)(this, definitions, done);
+};
+
+Viewer.prototype.getModules = function () {
+ return this._modules;
+};
+
+/**
+ * Destroy the viewer instance and remove all its
+ * remainders from the document tree.
+ */
+Viewer.prototype.destroy = function () {
+
+ // diagram destroy
+ _diagramJs2.default.prototype.destroy.call(this);
+
+ // dom detach
+ (0, _minDom.remove)(this._container);
+};
+
+/**
+ * Register an event listener
+ *
+ * Remove a previously added listener via {@link #off(event, callback)}.
+ *
+ * @param {String} event
+ * @param {Number} [priority]
+ * @param {Function} callback
+ * @param {Object} [that]
+ */
+Viewer.prototype.on = function (event, priority, callback, target) {
+ return this.get('eventBus').on(event, priority, callback, target);
+};
+
+/**
+ * De-register an event listener
+ *
+ * @param {String} event
+ * @param {Function} callback
+ */
+Viewer.prototype.off = function (event, callback) {
+ this.get('eventBus').off(event, callback);
+};
+
+Viewer.prototype.attachTo = function (parentNode) {
+
+ if (!parentNode) {
+ throw new Error('parentNode required');
+ }
+
+ // ensure we detach from the
+ // previous, old parent
+ this.detach();
+
+ // unwrap jQuery if provided
+ if (parentNode.get && parentNode.constructor.prototype.jquery) {
+ parentNode = parentNode.get(0);
+ }
+
+ if (typeof parentNode === 'string') {
+ parentNode = (0, _minDom.query)(parentNode);
+ }
+
+ parentNode.appendChild(this._container);
+
+ this._emit('attach', {});
+
+ this.get('canvas').resized();
+};
+
+Viewer.prototype.getDefinitions = function () {
+ return this._definitions;
+};
+
+Viewer.prototype.detach = function () {
+
+ var container = this._container,
+ parentNode = container.parentNode;
+
+ if (!parentNode) {
+ return;
+ }
+
+ this._emit('detach', {});
+
+ parentNode.removeChild(container);
+};
+
+Viewer.prototype._init = function (container, moddle, options) {
+
+ var baseModules = options.modules || this.getModules(),
+ additionalModules = options.additionalModules || [],
+ staticModules = [{
+ bpmnjs: ['value', this],
+ moddle: ['value', moddle]
+ }];
+
+ var diagramModules = [].concat(staticModules, baseModules, additionalModules);
+
+ var diagramOptions = (0, _minDash.assign)((0, _minDash.omit)(options, ['additionalModules']), {
+ canvas: (0, _minDash.assign)({}, options.canvas, { container: container }),
+ modules: diagramModules
+ });
+
+ // invoke diagram constructor
+ _diagramJs2.default.call(this, diagramOptions);
+
+ if (options && options.container) {
+ this.attachTo(options.container);
+ }
+};
+
+/**
+ * Emit an event on the underlying {@link EventBus}
+ *
+ * @param {String} type
+ * @param {Object} event
+ *
+ * @return {Object} event processing result (if any)
+ */
+Viewer.prototype._emit = function (type, event) {
+ return this.get('eventBus').fire(type, event);
+};
+
+Viewer.prototype._createContainer = function (options) {
+
+ var container = (0, _minDom.domify)('
');
+
+ (0, _minDash.assign)(container.style, {
+ width: ensureUnit(options.width),
+ height: ensureUnit(options.height),
+ position: options.position
+ });
+
+ return container;
+};
+
+Viewer.prototype._createModdle = function (options) {
+ var moddleOptions = (0, _minDash.assign)({}, this._moddleExtensions, options.moddleExtensions);
+
+ return new _bpmnModdle2.default(moddleOptions);
+};
+
+// modules the viewer is composed of
+Viewer.prototype._modules = [_core2.default, _translate2.default, _selection2.default, _overlays2.default];
+
+// default moddle extensions the viewer is composed of
+Viewer.prototype._moddleExtensions = {};
+
+/* */
+
+/**
+ * Adds the project logo to the diagram container as
+ * required by the bpmn.io license.
+ *
+ * @see http://bpmn.io/license
+ *
+ * @param {Element} container
+ */
+function addProjectLogo(container) {
+ var img = _PoweredByUtil.BPMNIO_IMG;
+
+ var linkMarkup = '' + img + ' ';
+
+ var linkElement = (0, _minDom.domify)(linkMarkup);
+
+ container.appendChild(linkElement);
+
+ _minDom.event.bind(linkElement, 'click', function (event) {
+ (0, _PoweredByUtil.open)();
+
+ event.preventDefault();
+ });
+}
+
+/* */
+
+},{"./core":117,"./import/Importer":211,"./util/PoweredByUtil":217,"bpmn-moddle":220,"diagram-js":241,"diagram-js/lib/features/overlays":339,"diagram-js/lib/features/selection":361,"diagram-js/lib/i18n/translate":376,"inherits":415,"min-dash":505,"min-dom":506,"tiny-svg":535}],117:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _draw = require('../draw');
+
+var _draw2 = _interopRequireDefault(_draw);
+
+var _import = require('../import');
+
+var _import2 = _interopRequireDefault(_import);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_draw2.default, _import2.default]
+};
+
+},{"../draw":122,"../import":213}],118:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.isTypedEvent = isTypedEvent;
+exports.isThrowEvent = isThrowEvent;
+exports.isCollection = isCollection;
+exports.getDi = getDi;
+exports.getSemantic = getSemantic;
+exports.getFillColor = getFillColor;
+exports.getStrokeColor = getStrokeColor;
+exports.getCirclePath = getCirclePath;
+exports.getRoundRectPath = getRoundRectPath;
+exports.getDiamondPath = getDiamondPath;
+exports.getRectPath = getRectPath;
+
+var _minDash = require('min-dash');
+
+var _RenderUtil = require('diagram-js/lib/util/RenderUtil');
+
+// element utils //////////////////////
+
+/**
+ * Checks if eventDefinition of the given element matches with semantic type.
+ *
+ * @return {boolean} true if element is of the given semantic type
+ */
+function isTypedEvent(event, eventDefinitionType, filter) {
+
+ function matches(definition, filter) {
+ return (0, _minDash.every)(filter, function (val, key) {
+
+ // we want a == conversion here, to be able to catch
+ // undefined == false and friends
+ /* jshint -W116 */
+ return definition[key] == val;
+ });
+ }
+
+ return (0, _minDash.some)(event.eventDefinitions, function (definition) {
+ return definition.$type === eventDefinitionType && matches(event, filter);
+ });
+}
+
+function isThrowEvent(event) {
+ return event.$type === 'bpmn:IntermediateThrowEvent' || event.$type === 'bpmn:EndEvent';
+}
+
+function isCollection(element) {
+ var dataObject = element.dataObjectRef;
+
+ return element.isCollection || dataObject && dataObject.isCollection;
+}
+
+function getDi(element) {
+ return element.businessObject.di;
+}
+
+function getSemantic(element) {
+ return element.businessObject;
+}
+
+// color access //////////////////////
+
+function getFillColor(element, defaultColor) {
+ return getDi(element).get('bioc:fill') || defaultColor || 'white';
+}
+
+function getStrokeColor(element, defaultColor) {
+ return getDi(element).get('bioc:stroke') || defaultColor || 'black';
+}
+
+// cropping path customizations //////////////////////
+
+function getCirclePath(shape) {
+
+ var cx = shape.x + shape.width / 2,
+ cy = shape.y + shape.height / 2,
+ radius = shape.width / 2;
+
+ var circlePath = [['M', cx, cy], ['m', 0, -radius], ['a', radius, radius, 0, 1, 1, 0, 2 * radius], ['a', radius, radius, 0, 1, 1, 0, -2 * radius], ['z']];
+
+ return (0, _RenderUtil.componentsToPath)(circlePath);
+}
+
+function getRoundRectPath(shape, borderRadius) {
+
+ var x = shape.x,
+ y = shape.y,
+ width = shape.width,
+ height = shape.height;
+
+ var roundRectPath = [['M', x + borderRadius, y], ['l', width - borderRadius * 2, 0], ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, borderRadius], ['l', 0, height - borderRadius * 2], ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, borderRadius], ['l', borderRadius * 2 - width, 0], ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, -borderRadius], ['l', 0, borderRadius * 2 - height], ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, -borderRadius], ['z']];
+
+ return (0, _RenderUtil.componentsToPath)(roundRectPath);
+}
+
+function getDiamondPath(shape) {
+
+ var width = shape.width,
+ height = shape.height,
+ x = shape.x,
+ y = shape.y,
+ halfWidth = width / 2,
+ halfHeight = height / 2;
+
+ var diamondPath = [['M', x + halfWidth, y], ['l', halfWidth, halfHeight], ['l', -halfWidth, halfHeight], ['l', -halfWidth, -halfHeight], ['z']];
+
+ return (0, _RenderUtil.componentsToPath)(diamondPath);
+}
+
+function getRectPath(shape) {
+ var x = shape.x,
+ y = shape.y,
+ width = shape.width,
+ height = shape.height;
+
+ var rectPath = [['M', x, y], ['l', width, 0], ['l', 0, height], ['l', -width, 0], ['z']];
+
+ return (0, _RenderUtil.componentsToPath)(rectPath);
+}
+
+},{"diagram-js/lib/util/RenderUtil":407,"min-dash":505}],119:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnRenderer;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _minDash = require('min-dash');
+
+var _BaseRenderer = require('diagram-js/lib/draw/BaseRenderer');
+
+var _BaseRenderer2 = _interopRequireDefault(_BaseRenderer);
+
+var _DiUtil = require('../util/DiUtil');
+
+var _ModelUtil = require('../util/ModelUtil');
+
+var _RenderUtil = require('diagram-js/lib/util/RenderUtil');
+
+var _BpmnRenderUtil = require('./BpmnRenderUtil');
+
+var _minDom = require('min-dom');
+
+var _tinySvg = require('tiny-svg');
+
+var _SvgTransformUtil = require('diagram-js/lib/util/SvgTransformUtil');
+
+var _ids = require('ids');
+
+var _ids2 = _interopRequireDefault(_ids);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var RENDERER_IDS = new _ids2.default();
+
+var TASK_BORDER_RADIUS = 10;
+var INNER_OUTER_DIST = 3;
+
+var DEFAULT_FILL_OPACITY = .95,
+ HIGH_FILL_OPACITY = .35;
+
+function BpmnRenderer(config, eventBus, styles, pathMap, canvas, textRenderer, priority) {
+
+ _BaseRenderer2.default.call(this, eventBus, priority);
+
+ var defaultFillColor = config && config.defaultFillColor,
+ defaultStrokeColor = config && config.defaultStrokeColor;
+
+ var rendererId = RENDERER_IDS.next();
+
+ var markers = {};
+
+ var computeStyle = styles.computeStyle;
+
+ function addMarker(id, options) {
+ var attrs = (0, _minDash.assign)({
+ fill: 'black',
+ strokeWidth: 1,
+ strokeLinecap: 'round',
+ strokeDasharray: 'none'
+ }, options.attrs);
+
+ var ref = options.ref || { x: 0, y: 0 };
+
+ var scale = options.scale || 1;
+
+ // fix for safari / chrome / firefox bug not correctly
+ // resetting stroke dash array
+ if (attrs.strokeDasharray === 'none') {
+ attrs.strokeDasharray = [10000, 1];
+ }
+
+ var marker = (0, _tinySvg.create)('marker');
+
+ (0, _tinySvg.attr)(options.element, attrs);
+
+ (0, _tinySvg.append)(marker, options.element);
+
+ (0, _tinySvg.attr)(marker, {
+ id: id,
+ viewBox: '0 0 20 20',
+ refX: ref.x,
+ refY: ref.y,
+ markerWidth: 20 * scale,
+ markerHeight: 20 * scale,
+ orient: 'auto'
+ });
+
+ var defs = (0, _minDom.query)('defs', canvas._svg);
+
+ if (!defs) {
+ defs = (0, _tinySvg.create)('defs');
+
+ (0, _tinySvg.append)(canvas._svg, defs);
+ }
+
+ (0, _tinySvg.append)(defs, marker);
+
+ markers[id] = marker;
+ }
+
+ function marker(type, fill, stroke) {
+ var id = type + '-' + fill + '-' + stroke + '-' + rendererId;
+
+ if (!markers[id]) {
+ createMarker(type, fill, stroke);
+ }
+
+ return 'url(#' + id + ')';
+ }
+
+ function createMarker(type, fill, stroke) {
+ var id = type + '-' + fill + '-' + stroke + '-' + rendererId;
+
+ if (type === 'sequenceflow-end') {
+ var sequenceflowEnd = (0, _tinySvg.create)('path');
+ (0, _tinySvg.attr)(sequenceflowEnd, { d: 'M 1 5 L 11 10 L 1 15 Z' });
+
+ addMarker(id, {
+ element: sequenceflowEnd,
+ ref: { x: 11, y: 10 },
+ scale: 0.5,
+ attrs: {
+ fill: stroke,
+ stroke: stroke
+ }
+ });
+ }
+
+ if (type === 'messageflow-start') {
+ var messageflowStart = (0, _tinySvg.create)('circle');
+ (0, _tinySvg.attr)(messageflowStart, { cx: 6, cy: 6, r: 3.5 });
+
+ addMarker(id, {
+ element: messageflowStart,
+ attrs: {
+ fill: fill,
+ stroke: stroke
+ },
+ ref: { x: 6, y: 6 }
+ });
+ }
+
+ if (type === 'messageflow-end') {
+ var messageflowEnd = (0, _tinySvg.create)('path');
+ (0, _tinySvg.attr)(messageflowEnd, { d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z' });
+
+ addMarker(id, {
+ element: messageflowEnd,
+ attrs: {
+ fill: fill,
+ stroke: stroke,
+ strokeLinecap: 'butt'
+ },
+ ref: { x: 8.5, y: 5 }
+ });
+ }
+
+ if (type === 'association-start') {
+ var associationStart = (0, _tinySvg.create)('path');
+ (0, _tinySvg.attr)(associationStart, { d: 'M 11 5 L 1 10 L 11 15' });
+
+ addMarker(id, {
+ element: associationStart,
+ attrs: {
+ fill: 'none',
+ stroke: stroke,
+ strokeWidth: 1.5
+ },
+ ref: { x: 1, y: 10 },
+ scale: 0.5
+ });
+ }
+
+ if (type === 'association-end') {
+ var associationEnd = (0, _tinySvg.create)('path');
+ (0, _tinySvg.attr)(associationEnd, { d: 'M 1 5 L 11 10 L 1 15' });
+
+ addMarker(id, {
+ element: associationEnd,
+ attrs: {
+ fill: 'none',
+ stroke: stroke,
+ strokeWidth: 1.5
+ },
+ ref: { x: 12, y: 10 },
+ scale: 0.5
+ });
+ }
+
+ if (type === 'conditional-flow-marker') {
+ var conditionalflowMarker = (0, _tinySvg.create)('path');
+ (0, _tinySvg.attr)(conditionalflowMarker, { d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z' });
+
+ addMarker(id, {
+ element: conditionalflowMarker,
+ attrs: {
+ fill: fill,
+ stroke: stroke
+ },
+ ref: { x: -1, y: 10 },
+ scale: 0.5
+ });
+ }
+
+ if (type === 'conditional-default-flow-marker') {
+ var conditionaldefaultflowMarker = (0, _tinySvg.create)('path');
+ (0, _tinySvg.attr)(conditionaldefaultflowMarker, { d: 'M 6 4 L 10 16' });
+
+ addMarker(id, {
+ element: conditionaldefaultflowMarker,
+ attrs: {
+ stroke: stroke
+ },
+ ref: { x: 0, y: 10 },
+ scale: 0.5
+ });
+ }
+ }
+
+ function drawCircle(parentGfx, width, height, offset, attrs) {
+
+ if ((0, _minDash.isObject)(offset)) {
+ attrs = offset;
+ offset = 0;
+ }
+
+ offset = offset || 0;
+
+ attrs = computeStyle(attrs, {
+ stroke: 'black',
+ strokeWidth: 2,
+ fill: 'white'
+ });
+
+ if (attrs.fill === 'none') {
+ delete attrs.fillOpacity;
+ }
+
+ var cx = width / 2,
+ cy = height / 2;
+
+ var circle = (0, _tinySvg.create)('circle');
+ (0, _tinySvg.attr)(circle, {
+ cx: cx,
+ cy: cy,
+ r: Math.round((width + height) / 4 - offset)
+ });
+ (0, _tinySvg.attr)(circle, attrs);
+
+ (0, _tinySvg.append)(parentGfx, circle);
+
+ return circle;
+ }
+
+ function drawRect(parentGfx, width, height, r, offset, attrs) {
+
+ if ((0, _minDash.isObject)(offset)) {
+ attrs = offset;
+ offset = 0;
+ }
+
+ offset = offset || 0;
+
+ attrs = computeStyle(attrs, {
+ stroke: 'black',
+ strokeWidth: 2,
+ fill: 'white'
+ });
+
+ var rect = (0, _tinySvg.create)('rect');
+ (0, _tinySvg.attr)(rect, {
+ x: offset,
+ y: offset,
+ width: width - offset * 2,
+ height: height - offset * 2,
+ rx: r,
+ ry: r
+ });
+ (0, _tinySvg.attr)(rect, attrs);
+
+ (0, _tinySvg.append)(parentGfx, rect);
+
+ return rect;
+ }
+
+ function drawDiamond(parentGfx, width, height, attrs) {
+
+ var x_2 = width / 2;
+ var y_2 = height / 2;
+
+ var points = [{ x: x_2, y: 0 }, { x: width, y: y_2 }, { x: x_2, y: height }, { x: 0, y: y_2 }];
+
+ var pointsString = points.map(function (point) {
+ return point.x + ',' + point.y;
+ }).join(' ');
+
+ attrs = computeStyle(attrs, {
+ stroke: 'black',
+ strokeWidth: 2,
+ fill: 'white'
+ });
+
+ var polygon = (0, _tinySvg.create)('polygon');
+ (0, _tinySvg.attr)(polygon, {
+ points: pointsString
+ });
+ (0, _tinySvg.attr)(polygon, attrs);
+
+ (0, _tinySvg.append)(parentGfx, polygon);
+
+ return polygon;
+ }
+
+ function drawLine(parentGfx, waypoints, attrs) {
+ attrs = computeStyle(attrs, ['no-fill'], {
+ stroke: 'black',
+ strokeWidth: 2,
+ fill: 'none'
+ });
+
+ var line = (0, _RenderUtil.createLine)(waypoints, attrs);
+
+ (0, _tinySvg.append)(parentGfx, line);
+
+ return line;
+ }
+
+ function drawPath(parentGfx, d, attrs) {
+
+ attrs = computeStyle(attrs, ['no-fill'], {
+ strokeWidth: 2,
+ stroke: 'black'
+ });
+
+ var path = (0, _tinySvg.create)('path');
+ (0, _tinySvg.attr)(path, { d: d });
+ (0, _tinySvg.attr)(path, attrs);
+
+ (0, _tinySvg.append)(parentGfx, path);
+
+ return path;
+ }
+
+ function drawMarker(type, parentGfx, path, attrs) {
+ return drawPath(parentGfx, path, (0, _minDash.assign)({ 'data-marker': type }, attrs));
+ }
+
+ function as(type) {
+ return function (parentGfx, element) {
+ return handlers[type](parentGfx, element);
+ };
+ }
+
+ function renderer(type) {
+ return handlers[type];
+ }
+
+ function renderEventContent(element, parentGfx) {
+
+ var event = (0, _BpmnRenderUtil.getSemantic)(element);
+ var isThrowing = (0, _BpmnRenderUtil.isThrowEvent)(event);
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:MessageEventDefinition')) {
+ return renderer('bpmn:MessageEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TimerEventDefinition')) {
+ return renderer('bpmn:TimerEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:ConditionalEventDefinition')) {
+ return renderer('bpmn:ConditionalEventDefinition')(parentGfx, element);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:SignalEventDefinition')) {
+ return renderer('bpmn:SignalEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CancelEventDefinition') && (0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TerminateEventDefinition', { parallelMultiple: false })) {
+ return renderer('bpmn:MultipleEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CancelEventDefinition') && (0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TerminateEventDefinition', { parallelMultiple: true })) {
+ return renderer('bpmn:ParallelMultipleEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:EscalationEventDefinition')) {
+ return renderer('bpmn:EscalationEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:LinkEventDefinition')) {
+ return renderer('bpmn:LinkEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:ErrorEventDefinition')) {
+ return renderer('bpmn:ErrorEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CancelEventDefinition')) {
+ return renderer('bpmn:CancelEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CompensateEventDefinition')) {
+ return renderer('bpmn:CompensateEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TerminateEventDefinition')) {
+ return renderer('bpmn:TerminateEventDefinition')(parentGfx, element, isThrowing);
+ }
+
+ return null;
+ }
+
+ function renderLabel(parentGfx, label, options) {
+
+ options = (0, _minDash.assign)({
+ size: {
+ width: 100
+ }
+ }, options);
+
+ var text = textRenderer.createText(label || '', options);
+
+ (0, _tinySvg.classes)(text).add('djs-label');
+
+ (0, _tinySvg.append)(parentGfx, text);
+
+ return text;
+ }
+
+ function renderEmbeddedLabel(parentGfx, element, align) {
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
+
+ return renderLabel(parentGfx, semantic.name, {
+ box: element,
+ align: align,
+ padding: 5,
+ style: {
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ }
+ });
+ }
+
+ function renderExternalLabel(parentGfx, element) {
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
+ var box = {
+ width: 90,
+ height: 30,
+ x: element.width / 2 + element.x,
+ y: element.height / 2 + element.y
+ };
+
+ return renderLabel(parentGfx, semantic.name, {
+ box: box,
+ fitBox: true,
+ style: (0, _minDash.assign)({}, textRenderer.getExternalStyle(), {
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ })
+ });
+ }
+
+ function renderLaneLabel(parentGfx, text, element) {
+ var textBox = renderLabel(parentGfx, text, {
+ box: {
+ height: 30,
+ width: element.height
+ },
+ align: 'center-middle',
+ style: {
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ }
+ });
+
+ var top = -1 * element.height;
+
+ (0, _SvgTransformUtil.transform)(textBox, 0, -top, 270);
+ }
+
+ function createPathFromConnection(connection) {
+ var waypoints = connection.waypoints;
+
+ var pathData = 'm ' + waypoints[0].x + ',' + waypoints[0].y;
+ for (var i = 1; i < waypoints.length; i++) {
+ pathData += 'L' + waypoints[i].x + ',' + waypoints[i].y + ' ';
+ }
+ return pathData;
+ }
+
+ var handlers = this.handlers = {
+ 'bpmn:Event': function bpmnEvent(parentGfx, element, attrs) {
+
+ if (!('fillOpacity' in attrs)) {
+ attrs.fillOpacity = DEFAULT_FILL_OPACITY;
+ }
+
+ return drawCircle(parentGfx, element.width, element.height, attrs);
+ },
+ 'bpmn:StartEvent': function bpmnStartEvent(parentGfx, element) {
+ var attrs = {
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ };
+
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
+
+ if (!semantic.isInterrupting) {
+ attrs = {
+ strokeDasharray: '6',
+ strokeLinecap: 'round',
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ };
+ }
+
+ var circle = renderer('bpmn:Event')(parentGfx, element, attrs);
+
+ renderEventContent(element, parentGfx);
+
+ return circle;
+ },
+ 'bpmn:MessageEventDefinition': function bpmnMessageEventDefinition(parentGfx, element, isThrowing) {
+ var pathData = pathMap.getScaledPath('EVENT_MESSAGE', {
+ xScaleFactor: 0.9,
+ yScaleFactor: 0.9,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.235,
+ my: 0.315
+ }
+ });
+
+ var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) : (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor);
+ var stroke = isThrowing ? (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor) : (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
+
+ var messagePath = drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: fill,
+ stroke: stroke
+ });
+
+ return messagePath;
+ },
+ 'bpmn:TimerEventDefinition': function bpmnTimerEventDefinition(parentGfx, element) {
+ var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, {
+ strokeWidth: 2,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', {
+ xScaleFactor: 0.75,
+ yScaleFactor: 0.75,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.5,
+ my: 0.5
+ }
+ });
+
+ drawPath(parentGfx, pathData, {
+ strokeWidth: 2,
+ strokeLinecap: 'square',
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ for (var i = 0; i < 12; i++) {
+
+ var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', {
+ xScaleFactor: 0.75,
+ yScaleFactor: 0.75,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.5,
+ my: 0.5
+ }
+ });
+
+ var width = element.width / 2;
+ var height = element.height / 2;
+
+ drawPath(parentGfx, linePathData, {
+ strokeWidth: 1,
+ strokeLinecap: 'square',
+ transform: 'rotate(' + i * 30 + ',' + height + ',' + width + ')',
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ }
+
+ return circle;
+ },
+ 'bpmn:EscalationEventDefinition': function bpmnEscalationEventDefinition(parentGfx, event, isThrowing) {
+ var pathData = pathMap.getScaledPath('EVENT_ESCALATION', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: event.width,
+ containerHeight: event.height,
+ position: {
+ mx: 0.5,
+ my: 0.2
+ }
+ });
+
+ var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
+
+ return drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: fill,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
+ });
+ },
+ 'bpmn:ConditionalEventDefinition': function bpmnConditionalEventDefinition(parentGfx, event) {
+ var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: event.width,
+ containerHeight: event.height,
+ position: {
+ mx: 0.5,
+ my: 0.222
+ }
+ });
+
+ return drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
+ });
+ },
+ 'bpmn:LinkEventDefinition': function bpmnLinkEventDefinition(parentGfx, event, isThrowing) {
+ var pathData = pathMap.getScaledPath('EVENT_LINK', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: event.width,
+ containerHeight: event.height,
+ position: {
+ mx: 0.57,
+ my: 0.263
+ }
+ });
+
+ var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
+
+ return drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: fill,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
+ });
+ },
+ 'bpmn:ErrorEventDefinition': function bpmnErrorEventDefinition(parentGfx, event, isThrowing) {
+ var pathData = pathMap.getScaledPath('EVENT_ERROR', {
+ xScaleFactor: 1.1,
+ yScaleFactor: 1.1,
+ containerWidth: event.width,
+ containerHeight: event.height,
+ position: {
+ mx: 0.2,
+ my: 0.722
+ }
+ });
+
+ var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
+
+ return drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: fill,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
+ });
+ },
+ 'bpmn:CancelEventDefinition': function bpmnCancelEventDefinition(parentGfx, event, isThrowing) {
+ var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', {
+ xScaleFactor: 1.0,
+ yScaleFactor: 1.0,
+ containerWidth: event.width,
+ containerHeight: event.height,
+ position: {
+ mx: 0.638,
+ my: -0.055
+ }
+ });
+
+ var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
+
+ var path = drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: fill,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
+ });
+
+ (0, _SvgTransformUtil.rotate)(path, 45);
+
+ return path;
+ },
+ 'bpmn:CompensateEventDefinition': function bpmnCompensateEventDefinition(parentGfx, event, isThrowing) {
+ var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: event.width,
+ containerHeight: event.height,
+ position: {
+ mx: 0.22,
+ my: 0.5
+ }
+ });
+
+ var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
+
+ return drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: fill,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
+ });
+ },
+ 'bpmn:SignalEventDefinition': function bpmnSignalEventDefinition(parentGfx, event, isThrowing) {
+ var pathData = pathMap.getScaledPath('EVENT_SIGNAL', {
+ xScaleFactor: 0.9,
+ yScaleFactor: 0.9,
+ containerWidth: event.width,
+ containerHeight: event.height,
+ position: {
+ mx: 0.5,
+ my: 0.2
+ }
+ });
+
+ var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
+
+ return drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: fill,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
+ });
+ },
+ 'bpmn:MultipleEventDefinition': function bpmnMultipleEventDefinition(parentGfx, event, isThrowing) {
+ var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', {
+ xScaleFactor: 1.1,
+ yScaleFactor: 1.1,
+ containerWidth: event.width,
+ containerHeight: event.height,
+ position: {
+ mx: 0.222,
+ my: 0.36
+ }
+ });
+
+ var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
+
+ return drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: fill
+ });
+ },
+ 'bpmn:ParallelMultipleEventDefinition': function bpmnParallelMultipleEventDefinition(parentGfx, event) {
+ var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', {
+ xScaleFactor: 1.2,
+ yScaleFactor: 1.2,
+ containerWidth: event.width,
+ containerHeight: event.height,
+ position: {
+ mx: 0.458,
+ my: 0.194
+ }
+ });
+
+ return drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
+ });
+ },
+ 'bpmn:EndEvent': function bpmnEndEvent(parentGfx, element) {
+ var circle = renderer('bpmn:Event')(parentGfx, element, {
+ strokeWidth: 4,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ renderEventContent(element, parentGfx, true);
+
+ return circle;
+ },
+ 'bpmn:TerminateEventDefinition': function bpmnTerminateEventDefinition(parentGfx, element) {
+ var circle = drawCircle(parentGfx, element.width, element.height, 8, {
+ strokeWidth: 4,
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return circle;
+ },
+ 'bpmn:IntermediateEvent': function bpmnIntermediateEvent(parentGfx, element) {
+ var outer = renderer('bpmn:Event')(parentGfx, element, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ /* inner */
+ drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, 'none'),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ renderEventContent(element, parentGfx);
+
+ return outer;
+ },
+ 'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'),
+ 'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'),
+
+ 'bpmn:Activity': function bpmnActivity(parentGfx, element, attrs) {
+
+ attrs = attrs || {};
+
+ if (!('fillOpacity' in attrs)) {
+ attrs.fillOpacity = DEFAULT_FILL_OPACITY;
+ }
+
+ return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, attrs);
+ },
+
+ 'bpmn:Task': function bpmnTask(parentGfx, element) {
+ var attrs = {
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ };
+
+ var rect = renderer('bpmn:Activity')(parentGfx, element, attrs);
+
+ renderEmbeddedLabel(parentGfx, element, 'center-middle');
+ attachTaskMarkers(parentGfx, element);
+
+ return rect;
+ },
+ 'bpmn:ServiceTask': function bpmnServiceTask(parentGfx, element) {
+ var task = renderer('bpmn:Task')(parentGfx, element);
+
+ var pathDataBG = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
+ abspos: {
+ x: 12,
+ y: 18
+ }
+ });
+
+ /* service bg */drawPath(parentGfx, pathDataBG, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ var fillPathData = pathMap.getScaledPath('TASK_TYPE_SERVICE_FILL', {
+ abspos: {
+ x: 17.2,
+ y: 18
+ }
+ });
+
+ /* service fill */drawPath(parentGfx, fillPathData, {
+ strokeWidth: 0,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor)
+ });
+
+ var pathData = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
+ abspos: {
+ x: 17,
+ y: 22
+ }
+ });
+
+ /* service */drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return task;
+ },
+ 'bpmn:UserTask': function bpmnUserTask(parentGfx, element) {
+ var task = renderer('bpmn:Task')(parentGfx, element);
+
+ var x = 15;
+ var y = 12;
+
+ var pathData = pathMap.getScaledPath('TASK_TYPE_USER_1', {
+ abspos: {
+ x: x,
+ y: y
+ }
+ });
+
+ /* user path */drawPath(parentGfx, pathData, {
+ strokeWidth: 0.5,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ var pathData2 = pathMap.getScaledPath('TASK_TYPE_USER_2', {
+ abspos: {
+ x: x,
+ y: y
+ }
+ });
+
+ /* user2 path */drawPath(parentGfx, pathData2, {
+ strokeWidth: 0.5,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ var pathData3 = pathMap.getScaledPath('TASK_TYPE_USER_3', {
+ abspos: {
+ x: x,
+ y: y
+ }
+ });
+
+ /* user3 path */drawPath(parentGfx, pathData3, {
+ strokeWidth: 0.5,
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return task;
+ },
+ 'bpmn:ManualTask': function bpmnManualTask(parentGfx, element) {
+ var task = renderer('bpmn:Task')(parentGfx, element);
+
+ var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', {
+ abspos: {
+ x: 17,
+ y: 15
+ }
+ });
+
+ /* manual path */drawPath(parentGfx, pathData, {
+ strokeWidth: 0.5, // 0.25,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return task;
+ },
+ 'bpmn:SendTask': function bpmnSendTask(parentGfx, element) {
+ var task = renderer('bpmn:Task')(parentGfx, element);
+
+ var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: 21,
+ containerHeight: 14,
+ position: {
+ mx: 0.285,
+ my: 0.357
+ }
+ });
+
+ /* send path */drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
+ stroke: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor)
+ });
+
+ return task;
+ },
+ 'bpmn:ReceiveTask': function bpmnReceiveTask(parentGfx, element) {
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
+
+ var task = renderer('bpmn:Task')(parentGfx, element);
+ var pathData;
+
+ if (semantic.instantiate) {
+ drawCircle(parentGfx, 28, 28, 20 * 0.22, { strokeWidth: 1 });
+
+ pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', {
+ abspos: {
+ x: 7.77,
+ y: 9.52
+ }
+ });
+ } else {
+
+ pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
+ xScaleFactor: 0.9,
+ yScaleFactor: 0.9,
+ containerWidth: 21,
+ containerHeight: 14,
+ position: {
+ mx: 0.3,
+ my: 0.4
+ }
+ });
+ }
+
+ /* receive path */drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return task;
+ },
+ 'bpmn:ScriptTask': function bpmnScriptTask(parentGfx, element) {
+ var task = renderer('bpmn:Task')(parentGfx, element);
+
+ var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', {
+ abspos: {
+ x: 15,
+ y: 20
+ }
+ });
+
+ /* script path */drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return task;
+ },
+ 'bpmn:BusinessRuleTask': function bpmnBusinessRuleTask(parentGfx, element) {
+ var task = renderer('bpmn:Task')(parentGfx, element);
+
+ var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', {
+ abspos: {
+ x: 8,
+ y: 8
+ }
+ });
+
+ var businessHeaderPath = drawPath(parentGfx, headerPathData);
+ (0, _tinySvg.attr)(businessHeaderPath, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, '#aaaaaa'),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', {
+ abspos: {
+ x: 8,
+ y: 8
+ }
+ });
+
+ var businessPath = drawPath(parentGfx, headerData);
+ (0, _tinySvg.attr)(businessPath, {
+ strokeWidth: 1,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return task;
+ },
+ 'bpmn:SubProcess': function bpmnSubProcess(parentGfx, element, attrs) {
+ attrs = (0, _minDash.assign)({
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ }, attrs);
+
+ var rect = renderer('bpmn:Activity')(parentGfx, element, attrs);
+
+ var expanded = (0, _DiUtil.isExpanded)(element);
+
+ if ((0, _DiUtil.isEventSubProcess)(element)) {
+ (0, _tinySvg.attr)(rect, {
+ strokeDasharray: '1,2'
+ });
+ }
+
+ renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle');
+
+ if (expanded) {
+ attachTaskMarkers(parentGfx, element);
+ } else {
+ attachTaskMarkers(parentGfx, element, ['SubProcessMarker']);
+ }
+
+ return rect;
+ },
+ 'bpmn:AdHocSubProcess': function bpmnAdHocSubProcess(parentGfx, element) {
+ return renderer('bpmn:SubProcess')(parentGfx, element);
+ },
+ 'bpmn:Transaction': function bpmnTransaction(parentGfx, element) {
+ var outer = renderer('bpmn:SubProcess')(parentGfx, element);
+
+ var innerAttrs = styles.style(['no-fill', 'no-events'], {
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ /* inner path */drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs);
+
+ return outer;
+ },
+ 'bpmn:CallActivity': function bpmnCallActivity(parentGfx, element) {
+ return renderer('bpmn:SubProcess')(parentGfx, element, {
+ strokeWidth: 5
+ });
+ },
+ 'bpmn:Participant': function bpmnParticipant(parentGfx, element) {
+
+ var attrs = {
+ fillOpacity: DEFAULT_FILL_OPACITY,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ };
+
+ var lane = renderer('bpmn:Lane')(parentGfx, element, attrs);
+
+ var expandedPool = (0, _DiUtil.isExpanded)(element);
+
+ if (expandedPool) {
+ drawLine(parentGfx, [{ x: 30, y: 0 }, { x: 30, y: element.height }], {
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ var text = (0, _BpmnRenderUtil.getSemantic)(element).name;
+ renderLaneLabel(parentGfx, text, element);
+ } else {
+ // Collapsed pool draw text inline
+ var text2 = (0, _BpmnRenderUtil.getSemantic)(element).name;
+ renderLabel(parentGfx, text2, {
+ box: element, align: 'center-middle',
+ style: {
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ }
+ });
+ }
+
+ var participantMultiplicity = !!(0, _BpmnRenderUtil.getSemantic)(element).participantMultiplicity;
+
+ if (participantMultiplicity) {
+ renderer('ParticipantMultiplicityMarker')(parentGfx, element);
+ }
+
+ return lane;
+ },
+ 'bpmn:Lane': function bpmnLane(parentGfx, element, attrs) {
+ var rect = drawRect(parentGfx, element.width, element.height, 0, (0, _minDash.assign)({
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ fillOpacity: HIGH_FILL_OPACITY,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ }, attrs));
+
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
+
+ if (semantic.$type === 'bpmn:Lane') {
+ var text = semantic.name;
+ renderLaneLabel(parentGfx, text, element);
+ }
+
+ return rect;
+ },
+ 'bpmn:InclusiveGateway': function bpmnInclusiveGateway(parentGfx, element) {
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
+
+ /* circle path */
+ drawCircle(parentGfx, element.width, element.height, element.height * 0.24, {
+ strokeWidth: 2.5,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return diamond;
+ },
+ 'bpmn:ExclusiveGateway': function bpmnExclusiveGateway(parentGfx, element) {
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
+
+ var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', {
+ xScaleFactor: 0.4,
+ yScaleFactor: 0.4,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.32,
+ my: 0.3
+ }
+ });
+
+ if ((0, _BpmnRenderUtil.getDi)(element).isMarkerVisible) {
+ drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ }
+
+ return diamond;
+ },
+ 'bpmn:ComplexGateway': function bpmnComplexGateway(parentGfx, element) {
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
+
+ var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', {
+ xScaleFactor: 0.5,
+ yScaleFactor: 0.5,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.46,
+ my: 0.26
+ }
+ });
+
+ /* complex path */drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return diamond;
+ },
+ 'bpmn:ParallelGateway': function bpmnParallelGateway(parentGfx, element) {
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
+
+ var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
+ xScaleFactor: 0.6,
+ yScaleFactor: 0.6,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.46,
+ my: 0.2
+ }
+ });
+
+ /* parallel path */drawPath(parentGfx, pathData, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return diamond;
+ },
+ 'bpmn:EventBasedGateway': function bpmnEventBasedGateway(parentGfx, element) {
+
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
+
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
+
+ /* outer circle path */drawCircle(parentGfx, element.width, element.height, element.height * 0.20, {
+ strokeWidth: 1,
+ fill: 'none',
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ var type = semantic.eventGatewayType;
+ var instantiate = !!semantic.instantiate;
+
+ function drawEvent() {
+
+ var pathData = pathMap.getScaledPath('GATEWAY_EVENT_BASED', {
+ xScaleFactor: 0.18,
+ yScaleFactor: 0.18,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.36,
+ my: 0.44
+ }
+ });
+
+ var attrs = {
+ strokeWidth: 2,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, 'none'),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ };
+
+ /* event path */drawPath(parentGfx, pathData, attrs);
+ }
+
+ if (type === 'Parallel') {
+
+ var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
+ xScaleFactor: 0.4,
+ yScaleFactor: 0.4,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.474,
+ my: 0.296
+ }
+ });
+
+ var parallelPath = drawPath(parentGfx, pathData);
+ (0, _tinySvg.attr)(parallelPath, {
+ strokeWidth: 1,
+ fill: 'none'
+ });
+ } else if (type === 'Exclusive') {
+
+ if (!instantiate) {
+ var innerCircle = drawCircle(parentGfx, element.width, element.height, element.height * 0.26);
+ (0, _tinySvg.attr)(innerCircle, {
+ strokeWidth: 1,
+ fill: 'none',
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ }
+
+ drawEvent();
+ }
+
+ return diamond;
+ },
+ 'bpmn:Gateway': function bpmnGateway(parentGfx, element) {
+ var attrs = {
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ fillOpacity: DEFAULT_FILL_OPACITY,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ };
+
+ return drawDiamond(parentGfx, element.width, element.height, attrs);
+ },
+ 'bpmn:SequenceFlow': function bpmnSequenceFlow(parentGfx, element) {
+ var pathData = createPathFromConnection(element);
+
+ var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
+
+ var attrs = {
+ strokeLinejoin: 'round',
+ markerEnd: marker('sequenceflow-end', fill, stroke),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ };
+
+ var path = drawPath(parentGfx, pathData, attrs);
+
+ var sequenceFlow = (0, _BpmnRenderUtil.getSemantic)(element);
+
+ var source;
+
+ if (element.source) {
+ source = element.source.businessObject;
+
+ // conditional flow marker
+ if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Activity')) {
+ (0, _tinySvg.attr)(path, {
+ markerStart: marker('conditional-flow-marker', fill, stroke)
+ });
+ }
+
+ // default marker
+ if (source.default && (source.$instanceOf('bpmn:Gateway') || source.$instanceOf('bpmn:Activity')) && source.default === sequenceFlow) {
+ (0, _tinySvg.attr)(path, {
+ markerStart: marker('conditional-default-flow-marker', fill, stroke)
+ });
+ }
+ }
+
+ return path;
+ },
+ 'bpmn:Association': function bpmnAssociation(parentGfx, element, attrs) {
+
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
+
+ var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
+
+ attrs = (0, _minDash.assign)({
+ strokeDasharray: '0.5, 5',
+ strokeLinecap: 'round',
+ strokeLinejoin: 'round',
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ }, attrs || {});
+
+ if (semantic.associationDirection === 'One' || semantic.associationDirection === 'Both') {
+ attrs.markerEnd = marker('association-end', fill, stroke);
+ }
+
+ if (semantic.associationDirection === 'Both') {
+ attrs.markerStart = marker('association-start', fill, stroke);
+ }
+
+ return drawLine(parentGfx, element.waypoints, attrs);
+ },
+ 'bpmn:DataInputAssociation': function bpmnDataInputAssociation(parentGfx, element) {
+ var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
+
+ return renderer('bpmn:Association')(parentGfx, element, {
+ markerEnd: marker('association-end', fill, stroke)
+ });
+ },
+ 'bpmn:DataOutputAssociation': function bpmnDataOutputAssociation(parentGfx, element) {
+ var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
+
+ return renderer('bpmn:Association')(parentGfx, element, {
+ markerEnd: marker('association-end', fill, stroke)
+ });
+ },
+ 'bpmn:MessageFlow': function bpmnMessageFlow(parentGfx, element) {
+
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element),
+ di = (0, _BpmnRenderUtil.getDi)(element);
+
+ var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
+
+ var pathData = createPathFromConnection(element);
+
+ var attrs = {
+ markerEnd: marker('messageflow-end', fill, stroke),
+ markerStart: marker('messageflow-start', fill, stroke),
+ strokeDasharray: '10, 12',
+ strokeLinecap: 'round',
+ strokeLinejoin: 'round',
+ strokeWidth: '1.5px',
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ };
+
+ var path = drawPath(parentGfx, pathData, attrs);
+
+ if (semantic.messageRef) {
+ var midPoint = path.getPointAtLength(path.getTotalLength() / 2);
+
+ var markerPathData = pathMap.getScaledPath('MESSAGE_FLOW_MARKER', {
+ abspos: {
+ x: midPoint.x,
+ y: midPoint.y
+ }
+ });
+
+ var messageAttrs = { strokeWidth: 1 };
+
+ if (di.messageVisibleKind === 'initiating') {
+ messageAttrs.fill = 'white';
+ messageAttrs.stroke = 'black';
+ } else {
+ messageAttrs.fill = '#888';
+ messageAttrs.stroke = 'white';
+ }
+
+ drawPath(parentGfx, markerPathData, messageAttrs);
+ }
+
+ return path;
+ },
+ 'bpmn:DataObject': function bpmnDataObject(parentGfx, element) {
+ var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.474,
+ my: 0.296
+ }
+ });
+
+ var elementObject = drawPath(parentGfx, pathData, {
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ fillOpacity: DEFAULT_FILL_OPACITY,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
+
+ if ((0, _BpmnRenderUtil.isCollection)(semantic)) {
+ renderDataItemCollection(parentGfx, element);
+ }
+
+ return elementObject;
+ },
+ 'bpmn:DataObjectReference': as('bpmn:DataObject'),
+ 'bpmn:DataInput': function bpmnDataInput(parentGfx, element) {
+
+ var arrowPathData = pathMap.getRawPath('DATA_ARROW');
+
+ // page
+ var elementObject = renderer('bpmn:DataObject')(parentGfx, element);
+
+ /* input arrow path */drawPath(parentGfx, arrowPathData, { strokeWidth: 1 });
+
+ return elementObject;
+ },
+ 'bpmn:DataOutput': function bpmnDataOutput(parentGfx, element) {
+ var arrowPathData = pathMap.getRawPath('DATA_ARROW');
+
+ // page
+ var elementObject = renderer('bpmn:DataObject')(parentGfx, element);
+
+ /* output arrow path */drawPath(parentGfx, arrowPathData, {
+ strokeWidth: 1,
+ fill: 'black'
+ });
+
+ return elementObject;
+ },
+ 'bpmn:DataStoreReference': function bpmnDataStoreReference(parentGfx, element) {
+ var DATA_STORE_PATH = pathMap.getScaledPath('DATA_STORE', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0,
+ my: 0.133
+ }
+ });
+
+ var elementStore = drawPath(parentGfx, DATA_STORE_PATH, {
+ strokeWidth: 2,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ fillOpacity: DEFAULT_FILL_OPACITY,
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ return elementStore;
+ },
+ 'bpmn:BoundaryEvent': function bpmnBoundaryEvent(parentGfx, element) {
+
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element),
+ cancel = semantic.cancelActivity;
+
+ var attrs = {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ };
+
+ if (!cancel) {
+ attrs.strokeDasharray = '6';
+ attrs.strokeLinecap = 'round';
+ }
+
+ // apply fillOpacity
+ var outerAttrs = (0, _minDash.assign)({}, attrs, {
+ fillOpacity: 1
+ });
+
+ // apply no-fill
+ var innerAttrs = (0, _minDash.assign)({}, attrs, {
+ fill: 'none'
+ });
+
+ var outer = renderer('bpmn:Event')(parentGfx, element, outerAttrs);
+
+ /* inner path */drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, innerAttrs);
+
+ renderEventContent(element, parentGfx);
+
+ return outer;
+ },
+ 'bpmn:Group': function bpmnGroup(parentGfx, element) {
+ var semantic = (0, _BpmnRenderUtil.getSemantic)(element),
+ di = (0, _BpmnRenderUtil.getDi)(element);
+
+ var group = drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, {
+ strokeWidth: 1,
+ strokeDasharray: '8,3,1,3',
+ fill: 'none',
+ pointerEvents: 'none'
+ });
+
+ var categoryValueRef = semantic.categoryValueRef || {};
+
+ if (categoryValueRef.value) {
+ var box = di.label ? di.label.bounds : element;
+
+ renderLabel(parentGfx, categoryValueRef.value, {
+ box: box,
+ style: {
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ }
+ });
+ }
+
+ return group;
+ },
+ 'label': function label(parentGfx, element) {
+ return renderExternalLabel(parentGfx, element);
+ },
+ 'bpmn:TextAnnotation': function bpmnTextAnnotation(parentGfx, element) {
+ var style = {
+ 'fill': 'none',
+ 'stroke': 'none'
+ };
+
+ var textElement = drawRect(parentGfx, element.width, element.height, 0, 0, style);
+
+ var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.0,
+ my: 0.0
+ }
+ });
+
+ drawPath(parentGfx, textPathData, {
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ var text = (0, _BpmnRenderUtil.getSemantic)(element).text || '';
+ renderLabel(parentGfx, text, {
+ box: element,
+ align: 'left-top',
+ padding: 5,
+ style: {
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ }
+ });
+
+ return textElement;
+ },
+ 'ParticipantMultiplicityMarker': function ParticipantMultiplicityMarker(parentGfx, element) {
+ var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: element.width / 2 / element.width,
+ my: (element.height - 15) / element.height
+ }
+ });
+
+ drawMarker('participant-multiplicity', parentGfx, markerPath, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ },
+ 'SubProcessMarker': function SubProcessMarker(parentGfx, element) {
+ var markerRect = drawRect(parentGfx, 14, 14, 0, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+
+ // Process marker is placed in the middle of the box
+ // therefore fixed values can be used here
+ (0, _SvgTransformUtil.translate)(markerRect, element.width / 2 - 7.5, element.height - 20);
+
+ var markerPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', {
+ xScaleFactor: 1.5,
+ yScaleFactor: 1.5,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: (element.width / 2 - 7.5) / element.width,
+ my: (element.height - 20) / element.height
+ }
+ });
+
+ drawMarker('sub-process', parentGfx, markerPath, {
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ },
+ 'ParallelMarker': function ParallelMarker(parentGfx, element, position) {
+ var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: (element.width / 2 + position.parallel) / element.width,
+ my: (element.height - 20) / element.height
+ }
+ });
+
+ drawMarker('parallel', parentGfx, markerPath, {
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ },
+ 'SequentialMarker': function SequentialMarker(parentGfx, element, position) {
+ var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: (element.width / 2 + position.seq) / element.width,
+ my: (element.height - 19) / element.height
+ }
+ });
+
+ drawMarker('sequential', parentGfx, markerPath, {
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ },
+ 'CompensationMarker': function CompensationMarker(parentGfx, element, position) {
+ var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: (element.width / 2 + position.compensation) / element.width,
+ my: (element.height - 13) / element.height
+ }
+ });
+
+ drawMarker('compensation', parentGfx, markerMath, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ },
+ 'LoopMarker': function LoopMarker(parentGfx, element, position) {
+ var markerPath = pathMap.getScaledPath('MARKER_LOOP', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: (element.width / 2 + position.loop) / element.width,
+ my: (element.height - 7) / element.height
+ }
+ });
+
+ drawMarker('loop', parentGfx, markerPath, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
+ strokeLinecap: 'round',
+ strokeMiterlimit: 0.5
+ });
+ },
+ 'AdhocMarker': function AdhocMarker(parentGfx, element, position) {
+ var markerPath = pathMap.getScaledPath('MARKER_ADHOC', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: (element.width / 2 + position.adhoc) / element.width,
+ my: (element.height - 15) / element.height
+ }
+ });
+
+ drawMarker('adhoc', parentGfx, markerPath, {
+ strokeWidth: 1,
+ fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
+ stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
+ });
+ }
+ };
+
+ function attachTaskMarkers(parentGfx, element, taskMarkers) {
+ var obj = (0, _BpmnRenderUtil.getSemantic)(element);
+
+ var subprocess = taskMarkers && taskMarkers.indexOf('SubProcessMarker') !== -1;
+ var position;
+
+ if (subprocess) {
+ position = {
+ seq: -21,
+ parallel: -22,
+ compensation: -42,
+ loop: -18,
+ adhoc: 10
+ };
+ } else {
+ position = {
+ seq: -3,
+ parallel: -6,
+ compensation: -27,
+ loop: 0,
+ adhoc: 10
+ };
+ }
+
+ (0, _minDash.forEach)(taskMarkers, function (marker) {
+ renderer(marker)(parentGfx, element, position);
+ });
+
+ if (obj.isForCompensation) {
+ renderer('CompensationMarker')(parentGfx, element, position);
+ }
+
+ if (obj.$type === 'bpmn:AdHocSubProcess') {
+ renderer('AdhocMarker')(parentGfx, element, position);
+ }
+
+ var loopCharacteristics = obj.loopCharacteristics,
+ isSequential = loopCharacteristics && loopCharacteristics.isSequential;
+
+ if (loopCharacteristics) {
+
+ if (isSequential === undefined) {
+ renderer('LoopMarker')(parentGfx, element, position);
+ }
+
+ if (isSequential === false) {
+ renderer('ParallelMarker')(parentGfx, element, position);
+ }
+
+ if (isSequential === true) {
+ renderer('SequentialMarker')(parentGfx, element, position);
+ }
+ }
+ }
+
+ function renderDataItemCollection(parentGfx, element) {
+
+ var yPosition = (element.height - 16) / element.height;
+
+ var pathData = pathMap.getScaledPath('DATA_OBJECT_COLLECTION_PATH', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.451,
+ my: yPosition
+ }
+ });
+
+ /* collection path */drawPath(parentGfx, pathData, {
+ strokeWidth: 2
+ });
+ }
+
+ // extension API, use at your own risk
+ this._drawPath = drawPath;
+}
+
+(0, _inherits2.default)(BpmnRenderer, _BaseRenderer2.default);
+
+BpmnRenderer.$inject = ['config.bpmnRenderer', 'eventBus', 'styles', 'pathMap', 'canvas', 'textRenderer'];
+
+BpmnRenderer.prototype.canRender = function (element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:BaseElement');
+};
+
+BpmnRenderer.prototype.drawShape = function (parentGfx, element) {
+ var type = element.type;
+ var h = this.handlers[type];
+
+ /* jshint -W040 */
+ return h(parentGfx, element);
+};
+
+BpmnRenderer.prototype.drawConnection = function (parentGfx, element) {
+ var type = element.type;
+ var h = this.handlers[type];
+
+ /* jshint -W040 */
+ return h(parentGfx, element);
+};
+
+BpmnRenderer.prototype.getShapePath = function (element) {
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:Event')) {
+ return (0, _BpmnRenderUtil.getCirclePath)(element);
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:Activity')) {
+ return (0, _BpmnRenderUtil.getRoundRectPath)(element, TASK_BORDER_RADIUS);
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:Gateway')) {
+ return (0, _BpmnRenderUtil.getDiamondPath)(element);
+ }
+
+ return (0, _BpmnRenderUtil.getRectPath)(element);
+};
+
+},{"../util/DiUtil":214,"../util/ModelUtil":216,"./BpmnRenderUtil":118,"diagram-js/lib/draw/BaseRenderer":252,"diagram-js/lib/util/RenderUtil":407,"diagram-js/lib/util/SvgTransformUtil":408,"ids":414,"inherits":415,"min-dash":505,"min-dom":506,"tiny-svg":535}],120:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = PathMap;
+/**
+ * Map containing SVG paths needed by BpmnRenderer.
+ */
+
+function PathMap() {
+
+ /**
+ * Contains a map of path elements
+ *
+ * Path definition
+ * A parameterized path is defined like this:
+ *
+ * 'GATEWAY_PARALLEL': {
+ * d: 'm {mx},{my} {e.x0},0 0,{e.x1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
+ '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
+ * height: 17.5,
+ * width: 17.5,
+ * heightElements: [2.5, 7.5],
+ * widthElements: [2.5, 7.5]
+ * }
+ *
+ * It's important to specify a correct height and width for the path as the scaling
+ * is based on the ratio between the specified height and width in this object and the
+ * height and width that is set as scale target (Note x,y coordinates will be scaled with
+ * individual ratios).
+ * The 'heightElements ' and 'widthElements ' array must contain the values that will be scaled.
+ * The scaling is based on the computed ratios.
+ * Coordinates on the y axis should be in the heightElement 's array, they will be scaled using
+ * the computed ratio coefficient.
+ * In the parameterized path the scaled values can be accessed through the 'e' object in {} brackets.
+ *
+ * The values for the y axis can be accessed in the path string using {e.y0}, {e.y1}, ....
+ * The values for the x axis can be accessed in the path string using {e.x0}, {e.x1}, ....
+ *
+ * The numbers x0, x1 respectively y0, y1, ... map to the corresponding array index.
+ *
+ */
+ this.pathMap = {
+ 'EVENT_MESSAGE': {
+ d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
+ height: 36,
+ width: 36,
+ heightElements: [6, 14],
+ widthElements: [10.5, 21]
+ },
+ 'EVENT_SIGNAL': {
+ d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x1},0 Z',
+ height: 36,
+ width: 36,
+ heightElements: [18],
+ widthElements: [10, 20]
+ },
+ 'EVENT_ESCALATION': {
+ d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x0},-{e.y1} l -{e.x0},{e.y1} Z',
+ height: 36,
+ width: 36,
+ heightElements: [20, 7],
+ widthElements: [8]
+ },
+ 'EVENT_CONDITIONAL': {
+ d: 'M {e.x0},{e.y0} l {e.x1},0 l 0,{e.y2} l -{e.x1},0 Z ' + 'M {e.x2},{e.y3} l {e.x0},0 ' + 'M {e.x2},{e.y4} l {e.x0},0 ' + 'M {e.x2},{e.y5} l {e.x0},0 ' + 'M {e.x2},{e.y6} l {e.x0},0 ' + 'M {e.x2},{e.y7} l {e.x0},0 ' + 'M {e.x2},{e.y8} l {e.x0},0 ',
+ height: 36,
+ width: 36,
+ heightElements: [8.5, 14.5, 18, 11.5, 14.5, 17.5, 20.5, 23.5, 26.5],
+ widthElements: [10.5, 14.5, 12.5]
+ },
+ 'EVENT_LINK': {
+ d: 'm {mx},{my} 0,{e.y0} -{e.x1},0 0,{e.y1} {e.x1},0 0,{e.y0} {e.x0},-{e.y2} -{e.x0},-{e.y2} z',
+ height: 36,
+ width: 36,
+ heightElements: [4.4375, 6.75, 7.8125],
+ widthElements: [9.84375, 13.5]
+ },
+ 'EVENT_ERROR': {
+ d: 'm {mx},{my} {e.x0},-{e.y0} {e.x1},-{e.y1} {e.x2},{e.y2} {e.x3},-{e.y3} -{e.x4},{e.y4} -{e.x5},-{e.y5} z',
+ height: 36,
+ width: 36,
+ heightElements: [0.023, 8.737, 8.151, 16.564, 10.591, 8.714],
+ widthElements: [0.085, 6.672, 6.97, 4.273, 5.337, 6.636]
+ },
+ 'EVENT_CANCEL_45': {
+ d: 'm {mx},{my} -{e.x1},0 0,{e.x0} {e.x1},0 0,{e.y1} {e.x0},0 ' + '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
+ height: 36,
+ width: 36,
+ heightElements: [4.75, 8.5],
+ widthElements: [4.75, 8.5]
+ },
+ 'EVENT_COMPENSATION': {
+ d: 'm {mx},{my} {e.x0},-{e.y0} 0,{e.y1} z m {e.x1},-{e.y2} {e.x2},-{e.y3} 0,{e.y1} -{e.x2},-{e.y3} z',
+ height: 36,
+ width: 36,
+ heightElements: [6.5, 13, 0.4, 6.1],
+ widthElements: [9, 9.3, 8.7]
+ },
+ 'EVENT_TIMER_WH': {
+ d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ',
+ height: 36,
+ width: 36,
+ heightElements: [10, 2],
+ widthElements: [3, 7]
+ },
+ 'EVENT_TIMER_LINE': {
+ d: 'M {mx},{my} ' + 'm {e.x0},{e.y0} l -{e.x1},{e.y1} ',
+ height: 36,
+ width: 36,
+ heightElements: [10, 3],
+ widthElements: [0, 0]
+ },
+ 'EVENT_MULTIPLE': {
+ d: 'm {mx},{my} {e.x1},-{e.y0} {e.x1},{e.y0} -{e.x0},{e.y1} -{e.x2},0 z',
+ height: 36,
+ width: 36,
+ heightElements: [6.28099, 12.56199],
+ widthElements: [3.1405, 9.42149, 12.56198]
+ },
+ 'EVENT_PARALLEL_MULTIPLE': {
+ d: 'm {mx},{my} {e.x0},0 0,{e.y1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' + '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
+ height: 36,
+ width: 36,
+ heightElements: [2.56228, 7.68683],
+ widthElements: [2.56228, 7.68683]
+ },
+ 'GATEWAY_EXCLUSIVE': {
+ d: 'm {mx},{my} {e.x0},{e.y0} {e.x1},{e.y0} {e.x2},0 {e.x4},{e.y2} ' + '{e.x4},{e.y1} {e.x2},0 {e.x1},{e.y3} {e.x0},{e.y3} ' + '{e.x3},0 {e.x5},{e.y1} {e.x5},{e.y2} {e.x3},0 z',
+ height: 17.5,
+ width: 17.5,
+ heightElements: [8.5, 6.5312, -6.5312, -8.5],
+ widthElements: [6.5, -6.5, 3, -3, 5, -5]
+ },
+ 'GATEWAY_PARALLEL': {
+ d: 'm {mx},{my} 0,{e.y1} -{e.x1},0 0,{e.y0} {e.x1},0 0,{e.y1} {e.x0},0 ' + '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
+ height: 30,
+ width: 30,
+ heightElements: [5, 12.5],
+ widthElements: [5, 12.5]
+ },
+ 'GATEWAY_EVENT_BASED': {
+ d: 'm {mx},{my} {e.x0},{e.y0} {e.x0},{e.y1} {e.x1},{e.y2} {e.x2},0 z',
+ height: 11,
+ width: 11,
+ heightElements: [-6, 6, 12, -12],
+ widthElements: [9, -3, -12]
+ },
+ 'GATEWAY_COMPLEX': {
+ d: 'm {mx},{my} 0,{e.y0} -{e.x0},-{e.y1} -{e.x1},{e.y2} {e.x0},{e.y1} -{e.x2},0 0,{e.y3} ' + '{e.x2},0 -{e.x0},{e.y1} l {e.x1},{e.y2} {e.x0},-{e.y1} 0,{e.y0} {e.x3},0 0,-{e.y0} {e.x0},{e.y1} ' + '{e.x1},-{e.y2} -{e.x0},-{e.y1} {e.x2},0 0,-{e.y3} -{e.x2},0 {e.x0},-{e.y1} -{e.x1},-{e.y2} ' + '-{e.x0},{e.y1} 0,-{e.y0} -{e.x3},0 z',
+ height: 17.125,
+ width: 17.125,
+ heightElements: [4.875, 3.4375, 2.125, 3],
+ widthElements: [3.4375, 2.125, 4.875, 3]
+ },
+ 'DATA_OBJECT_PATH': {
+ d: 'm 0,0 {e.x1},0 {e.x0},{e.y0} 0,{e.y1} -{e.x2},0 0,-{e.y2} {e.x1},0 0,{e.y0} {e.x0},0',
+ height: 61,
+ width: 51,
+ heightElements: [10, 50, 60],
+ widthElements: [10, 40, 50, 60]
+ },
+ 'DATA_OBJECT_COLLECTION_PATH': {
+ d: 'm {mx}, {my} ' + 'm 0 15 l 0 -15 ' + 'm 4 15 l 0 -15 ' + 'm 4 15 l 0 -15 ',
+ height: 61,
+ width: 51,
+ heightElements: [12],
+ widthElements: [1, 6, 12, 15]
+ },
+ 'DATA_ARROW': {
+ d: 'm 5,9 9,0 0,-3 5,5 -5,5 0,-3 -9,0 z',
+ height: 61,
+ width: 51,
+ heightElements: [],
+ widthElements: []
+ },
+ 'DATA_STORE': {
+ d: 'm {mx},{my} ' + 'l 0,{e.y2} ' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' + 'l 0,-{e.y2} ' + 'c -{e.x0},-{e.y1} -{e.x1},-{e.y1} -{e.x2},0' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' + 'm -{e.x2},{e.y0}' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0' + 'm -{e.x2},{e.y0}' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0',
+ height: 61,
+ width: 61,
+ heightElements: [7, 10, 45],
+ widthElements: [2, 58, 60]
+ },
+ 'TEXT_ANNOTATION': {
+ d: 'm {mx}, {my} m 10,0 l -10,0 l 0,{e.y0} l 10,0',
+ height: 30,
+ width: 10,
+ heightElements: [30],
+ widthElements: [10]
+ },
+ 'MARKER_SUB_PROCESS': {
+ d: 'm{mx},{my} m 7,2 l 0,10 m -5,-5 l 10,0',
+ height: 10,
+ width: 10,
+ heightElements: [],
+ widthElements: []
+ },
+ 'MARKER_PARALLEL': {
+ d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10',
+ height: 10,
+ width: 10,
+ heightElements: [],
+ widthElements: []
+ },
+ 'MARKER_SEQUENTIAL': {
+ d: 'm{mx},{my} m 0,3 l 10,0 m -10,3 l 10,0 m -10,3 l 10,0',
+ height: 10,
+ width: 10,
+ heightElements: [],
+ widthElements: []
+ },
+ 'MARKER_COMPENSATION': {
+ d: 'm {mx},{my} 7,-5 0,10 z m 7.1,-0.3 6.9,-4.7 0,10 -6.9,-4.7 z',
+ height: 10,
+ width: 21,
+ heightElements: [],
+ widthElements: []
+ },
+ 'MARKER_LOOP': {
+ d: 'm {mx},{my} c 3.526979,0 6.386161,-2.829858 6.386161,-6.320661 0,-3.490806 -2.859182,-6.320661 ' + '-6.386161,-6.320661 -3.526978,0 -6.38616,2.829855 -6.38616,6.320661 0,1.745402 ' + '0.714797,3.325567 1.870463,4.469381 0.577834,0.571908 1.265885,1.034728 2.029916,1.35457 ' + 'l -0.718163,-3.909793 m 0.718163,3.909793 -3.885211,0.802902',
+ height: 13.9,
+ width: 13.7,
+ heightElements: [],
+ widthElements: []
+ },
+ 'MARKER_ADHOC': {
+ d: 'm {mx},{my} m 0.84461,2.64411 c 1.05533,-1.23780996 2.64337,-2.07882 4.29653,-1.97997996 2.05163,0.0805 ' + '3.85579,1.15803 5.76082,1.79107 1.06385,0.34139996 2.24454,0.1438 3.18759,-0.43767 0.61743,-0.33642 ' + '1.2775,-0.64078 1.7542,-1.17511 0,0.56023 0,1.12046 0,1.6807 -0.98706,0.96237996 -2.29792,1.62393996 ' + '-3.6918,1.66181996 -1.24459,0.0927 -2.46671,-0.2491 -3.59505,-0.74812 -1.35789,-0.55965 ' + '-2.75133,-1.33436996 -4.27027,-1.18121996 -1.37741,0.14601 -2.41842,1.13685996 -3.44288,1.96782996 z',
+ height: 4,
+ width: 15,
+ heightElements: [],
+ widthElements: []
+ },
+ 'TASK_TYPE_SEND': {
+ d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
+ height: 14,
+ width: 21,
+ heightElements: [6, 14],
+ widthElements: [10.5, 21]
+ },
+ 'TASK_TYPE_SCRIPT': {
+ d: 'm {mx},{my} c 9.966553,-6.27276 -8.000926,-7.91932 2.968968,-14.938 l -8.802728,0 ' + 'c -10.969894,7.01868 6.997585,8.66524 -2.968967,14.938 z ' + 'm -7,-12 l 5,0 ' + 'm -4.5,3 l 4.5,0 ' + 'm -3,3 l 5,0' + 'm -4,3 l 5,0',
+ height: 15,
+ width: 12.6,
+ heightElements: [6, 14],
+ widthElements: [10.5, 21]
+ },
+ 'TASK_TYPE_USER_1': {
+ d: 'm {mx},{my} c 0.909,-0.845 1.594,-2.049 1.594,-3.385 0,-2.554 -1.805,-4.62199999 ' + '-4.357,-4.62199999 -2.55199998,0 -4.28799998,2.06799999 -4.28799998,4.62199999 0,1.348 ' + '0.974,2.562 1.89599998,3.405 -0.52899998,0.187 -5.669,2.097 -5.794,4.7560005 v 6.718 ' + 'h 17 v -6.718 c 0,-2.2980005 -5.5279996,-4.5950005 -6.0509996,-4.7760005 z' + 'm -8,6 l 0,5.5 m 11,0 l 0,-5'
+ },
+ 'TASK_TYPE_USER_2': {
+ d: 'm {mx},{my} m 2.162,1.009 c 0,2.4470005 -2.158,4.4310005 -4.821,4.4310005 ' + '-2.66499998,0 -4.822,-1.981 -4.822,-4.4310005 '
+ },
+ 'TASK_TYPE_USER_3': {
+ d: 'm {mx},{my} m -6.9,-3.80 c 0,0 2.25099998,-2.358 4.27399998,-1.177 2.024,1.181 4.221,1.537 ' + '4.124,0.965 -0.098,-0.57 -0.117,-3.79099999 -4.191,-4.13599999 -3.57499998,0.001 ' + '-4.20799998,3.36699999 -4.20699998,4.34799999 z'
+ },
+ 'TASK_TYPE_MANUAL': {
+ d: 'm {mx},{my} c 0.234,-0.01 5.604,0.008 8.029,0.004 0.808,0 1.271,-0.172 1.417,-0.752 0.227,-0.898 ' + '-0.334,-1.314 -1.338,-1.316 -2.467,-0.01 -7.886,-0.004 -8.108,-0.004 -0.014,-0.079 0.016,-0.533 0,-0.61 ' + '0.195,-0.042 8.507,0.006 9.616,0.002 0.877,-0.007 1.35,-0.438 1.353,-1.208 0.003,-0.768 -0.479,-1.09 ' + '-1.35,-1.091 -2.968,-0.002 -9.619,-0.013 -9.619,-0.013 v -0.591 c 0,0 5.052,-0.016 7.225,-0.016 ' + '0.888,-0.002 1.354,-0.416 1.351,-1.193 -0.006,-0.761 -0.492,-1.196 -1.361,-1.196 -3.473,-0.005 ' + '-10.86,-0.003 -11.0829995,-0.003 -0.022,-0.047 -0.045,-0.094 -0.069,-0.139 0.3939995,-0.319 ' + '2.0409995,-1.626 2.4149995,-2.017 0.469,-0.4870005 0.519,-1.1650005 0.162,-1.6040005 -0.414,-0.511 ' + '-0.973,-0.5 -1.48,-0.236 -1.4609995,0.764 -6.5999995,3.6430005 -7.7329995,4.2710005 -0.9,0.499 ' + '-1.516,1.253 -1.882,2.19 -0.37000002,0.95 -0.17,2.01 -0.166,2.979 0.004,0.718 -0.27300002,1.345 ' + '-0.055,2.063 0.629,2.087 2.425,3.312 4.859,3.318 4.6179995,0.014 9.2379995,-0.139 13.8569995,-0.158 ' + '0.755,-0.004 1.171,-0.301 1.182,-1.033 0.012,-0.754 -0.423,-0.969 -1.183,-0.973 -1.778,-0.01 ' + '-5.824,-0.004 -6.04,-0.004 10e-4,-0.084 0.003,-0.586 10e-4,-0.67 z'
+ },
+ 'TASK_TYPE_INSTANTIATING_SEND': {
+ d: 'm {mx},{my} l 0,8.4 l 12.6,0 l 0,-8.4 z l 6.3,3.6 l 6.3,-3.6'
+ },
+ 'TASK_TYPE_SERVICE': {
+ d: 'm {mx},{my} v -1.71335 c 0.352326,-0.0705 0.703932,-0.17838 1.047628,-0.32133 ' + '0.344416,-0.14465 0.665822,-0.32133 0.966377,-0.52145 l 1.19431,1.18005 1.567487,-1.57688 ' + '-1.195028,-1.18014 c 0.403376,-0.61394 0.683079,-1.29908 0.825447,-2.01824 l 1.622133,-0.01 ' + 'v -2.2196 l -1.636514,0.01 c -0.07333,-0.35153 -0.178319,-0.70024 -0.323564,-1.04372 ' + '-0.145244,-0.34406 -0.321407,-0.6644 -0.522735,-0.96217 l 1.131035,-1.13631 -1.583305,-1.56293 ' + '-1.129598,1.13589 c -0.614052,-0.40108 -1.302883,-0.68093 -2.022633,-0.82247 l 0.0093,-1.61852 ' + 'h -2.241173 l 0.0042,1.63124 c -0.353763,0.0736 -0.705369,0.17977 -1.049785,0.32371 -0.344415,0.14437 ' + '-0.665102,0.32092 -0.9635006,0.52046 l -1.1698628,-1.15823 -1.5667691,1.5792 1.1684265,1.15669 ' + 'c -0.4026573,0.61283 -0.68308,1.29797 -0.8247287,2.01713 l -1.6588041,0.003 v 2.22174 ' + 'l 1.6724648,-0.006 c 0.073327,0.35077 0.1797598,0.70243 0.3242851,1.04472 0.1452428,0.34448 ' + '0.3214064,0.6644 0.5227339,0.96066 l -1.1993431,1.19723 1.5840256,1.56011 1.1964668,-1.19348 ' + 'c 0.6140517,0.40346 1.3028827,0.68232 2.0233517,0.82331 l 7.19e-4,1.69892 h 2.226848 z ' + 'm 0.221462,-3.9957 c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' + '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' + '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
+ },
+ 'TASK_TYPE_SERVICE_FILL': {
+ d: 'm {mx},{my} c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' + '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' + '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
+ },
+ 'TASK_TYPE_BUSINESS_RULE_HEADER': {
+ d: 'm {mx},{my} 0,4 20,0 0,-4 z'
+ },
+ 'TASK_TYPE_BUSINESS_RULE_MAIN': {
+ d: 'm {mx},{my} 0,12 20,0 0,-12 z' + 'm 0,8 l 20,0 ' + 'm -13,-4 l 0,8'
+ },
+ 'MESSAGE_FLOW_MARKER': {
+ d: 'm {mx},{my} m -10.5 ,-7 l 0,14 l 21,0 l 0,-14 z l 10.5,6 l 10.5,-6'
+ }
+ };
+
+ this.getRawPath = function getRawPath(pathId) {
+ return this.pathMap[pathId].d;
+ };
+
+ /**
+ * Scales the path to the given height and width.
+ * Use case
+ * Use case is to scale the content of elements (event, gateways) based
+ * on the element bounding box's size.
+ *
+ * Why not transform
+ * Scaling a path with transform() will also scale the stroke and IE does not support
+ * the option 'non-scaling-stroke' to prevent this.
+ * Also there are use cases where only some parts of a path should be
+ * scaled.
+ *
+ * @param {String} pathId The ID of the path.
+ * @param {Object} param
+ * Example param object scales the path to 60% size of the container (data.width, data.height).
+ *
+ * {
+ * xScaleFactor: 0.6,
+ * yScaleFactor:0.6,
+ * containerWidth: data.width,
+ * containerHeight: data.height,
+ * position: {
+ * mx: 0.46,
+ * my: 0.2,
+ * }
+ * }
+ *
+ *
+ * targetpathwidth = xScaleFactor * containerWidth
+ * targetpathheight = yScaleFactor * containerHeight
+ * Position is used to set the starting coordinate of the path. M is computed:
+ *
+ * position.x * containerWidth
+ * position.y * containerHeight
+ *
+ * Center of the container position: {
+ * mx: 0.5,
+ * my: 0.5,
+ * }
+ * Upper left corner of the container
+ * position: {
+ * mx: 0.0,
+ * my: 0.0,
+ * }
+ *
+ *
+ *
+ *
+ */
+ this.getScaledPath = function getScaledPath(pathId, param) {
+ var rawPath = this.pathMap[pathId];
+
+ // positioning
+ // compute the start point of the path
+ var mx, my;
+
+ if (param.abspos) {
+ mx = param.abspos.x;
+ my = param.abspos.y;
+ } else {
+ mx = param.containerWidth * param.position.mx;
+ my = param.containerHeight * param.position.my;
+ }
+
+ var coordinates = {}; // map for the scaled coordinates
+ if (param.position) {
+
+ // path
+ var heightRatio = param.containerHeight / rawPath.height * param.yScaleFactor;
+ var widthRatio = param.containerWidth / rawPath.width * param.xScaleFactor;
+
+ // Apply height ratio
+ for (var heightIndex = 0; heightIndex < rawPath.heightElements.length; heightIndex++) {
+ coordinates['y' + heightIndex] = rawPath.heightElements[heightIndex] * heightRatio;
+ }
+
+ // Apply width ratio
+ for (var widthIndex = 0; widthIndex < rawPath.widthElements.length; widthIndex++) {
+ coordinates['x' + widthIndex] = rawPath.widthElements[widthIndex] * widthRatio;
+ }
+ }
+
+ // Apply value to raw path
+ var path = format(rawPath.d, {
+ mx: mx,
+ my: my,
+ e: coordinates
+ });
+ return path;
+ };
+}
+
+// helpers //////////////////////
+
+// copied from https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js
+var tokenRegex = /\{([^}]+)\}/g,
+ objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g; // matches .xxxxx or ["xxxxx"] to run over object properties
+
+function replacer(all, key, obj) {
+ var res = obj;
+ key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {
+ name = name || quotedName;
+ if (res) {
+ if (name in res) {
+ res = res[name];
+ }
+ typeof res == 'function' && isFunc && (res = res());
+ }
+ });
+ res = (res == null || res == obj ? all : res) + '';
+
+ return res;
+}
+
+function format(str, obj) {
+ return String(str).replace(tokenRegex, function (all, key) {
+ return replacer(all, key, obj);
+ });
+}
+
+},{}],121:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = TextRenderer;
+
+var _minDash = require('min-dash');
+
+var _Text = require('diagram-js/lib/util/Text');
+
+var _Text2 = _interopRequireDefault(_Text);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var DEFAULT_FONT_SIZE = 12;
+var LINE_HEIGHT_RATIO = 1.2;
+
+var MIN_TEXT_ANNOTATION_HEIGHT = 30;
+
+function TextRenderer(config) {
+
+ var defaultStyle = (0, _minDash.assign)({
+ fontFamily: 'Arial, sans-serif',
+ fontSize: DEFAULT_FONT_SIZE,
+ fontWeight: 'normal',
+ lineHeight: LINE_HEIGHT_RATIO
+ }, config && config.defaultStyle || {});
+
+ var fontSize = parseInt(defaultStyle.fontSize, 10) - 1;
+
+ var externalStyle = (0, _minDash.assign)({}, defaultStyle, {
+ fontSize: fontSize
+ }, config && config.externalStyle || {});
+
+ var textUtil = new _Text2.default({
+ style: defaultStyle
+ });
+
+ /**
+ * Get the new bounds of an externally rendered,
+ * layouted label.
+ *
+ * @param {Bounds} bounds
+ * @param {String} text
+ *
+ * @return {Bounds}
+ */
+ this.getExternalLabelBounds = function (bounds, text) {
+
+ var layoutedDimensions = textUtil.getDimensions(text, {
+ box: {
+ width: 90,
+ height: 30,
+ x: bounds.width / 2 + bounds.x,
+ y: bounds.height / 2 + bounds.y
+ },
+ style: externalStyle
+ });
+
+ // resize label shape to fit label text
+ return {
+ x: Math.round(bounds.x + bounds.width / 2 - layoutedDimensions.width / 2),
+ y: Math.round(bounds.y),
+ width: Math.ceil(layoutedDimensions.width),
+ height: Math.ceil(layoutedDimensions.height)
+ };
+ };
+
+ /**
+ * Get the new bounds of text annotation.
+ *
+ * @param {Bounds} bounds
+ * @param {String} text
+ *
+ * @return {Bounds}
+ */
+ this.getTextAnnotationBounds = function (bounds, text) {
+
+ var layoutedDimensions = textUtil.getDimensions(text, {
+ box: bounds,
+ style: defaultStyle,
+ align: 'left-top',
+ padding: 5
+ });
+
+ return {
+ x: bounds.x,
+ y: bounds.y,
+ width: bounds.width,
+ height: Math.max(MIN_TEXT_ANNOTATION_HEIGHT, Math.round(layoutedDimensions.height))
+ };
+ };
+
+ /**
+ * Create a layouted text element.
+ *
+ * @param {String} text
+ * @param {Object} [options]
+ *
+ * @return {SVGElement} rendered text
+ */
+ this.createText = function (text, options) {
+ return textUtil.createText(text, options || {});
+ };
+
+ /**
+ * Get default text style.
+ */
+ this.getDefaultStyle = function () {
+ return defaultStyle;
+ };
+
+ /**
+ * Get the external text style.
+ */
+ this.getExternalStyle = function () {
+ return externalStyle;
+ };
+}
+
+TextRenderer.$inject = ['config.textRenderer'];
+
+},{"diagram-js/lib/util/Text":409,"min-dash":505}],122:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _BpmnRenderer = require('./BpmnRenderer');
+
+var _BpmnRenderer2 = _interopRequireDefault(_BpmnRenderer);
+
+var _TextRenderer = require('./TextRenderer');
+
+var _TextRenderer2 = _interopRequireDefault(_TextRenderer);
+
+var _PathMap = require('./PathMap');
+
+var _PathMap2 = _interopRequireDefault(_PathMap);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['bpmnRenderer'],
+ bpmnRenderer: ['type', _BpmnRenderer2.default],
+ textRenderer: ['type', _TextRenderer2.default],
+ pathMap: ['type', _PathMap2.default]
+};
+
+},{"./BpmnRenderer":119,"./PathMap":120,"./TextRenderer":121}],123:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AutoPlace;
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _ModelingUtil = require('../modeling/util/ModelingUtil');
+
+var _AutoPlaceUtil = require('./AutoPlaceUtil');
+
+/**
+ * A service that places elements connected to existing ones
+ * to an appropriate position in an _automated_ fashion.
+ *
+ * @param {EventBus} eventBus
+ * @param {Modeling} modeling
+ */
+function AutoPlace(eventBus, modeling) {
+
+ function emit(event, payload) {
+ return eventBus.fire(event, payload);
+ }
+
+ /**
+ * Append shape to source at appropriate position.
+ *
+ * @param {djs.model.Shape} source
+ * @param {djs.model.Shape} shape
+ *
+ * @return {djs.model.Shape} appended shape
+ */
+ this.append = function (source, shape) {
+
+ // allow others to provide the position
+ var position = emit('autoPlace', {
+ source: source,
+ shape: shape
+ });
+
+ if (!position) {
+ position = getNewShapePosition(source, shape);
+ }
+
+ var newShape = modeling.appendShape(source, shape, position, source.parent);
+
+ // notify interested parties on new shape placed
+ emit('autoPlace.end', {
+ shape: newShape
+ });
+
+ return newShape;
+ };
+}
+
+AutoPlace.$inject = ['eventBus', 'modeling'];
+
+// helpers //////////////////////
+
+/**
+ * Find the new position for the target element to
+ * connect to source.
+ *
+ * @param {djs.model.Shape} source
+ * @param {djs.model.Shape} element
+ *
+ * @return {Point}
+ */
+function getNewShapePosition(source, element) {
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
+ return (0, _AutoPlaceUtil.getTextAnnotationPosition)(source, element);
+ }
+
+ if ((0, _ModelingUtil.isAny)(element, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) {
+ return (0, _AutoPlaceUtil.getDataElementPosition)(source, element);
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:FlowNode')) {
+ return (0, _AutoPlaceUtil.getFlowNodePosition)(source, element);
+ }
+
+ return (0, _AutoPlaceUtil.getDefaultPosition)(source, element);
+}
+
+},{"../../util/ModelUtil":216,"../modeling/util/ModelingUtil":189,"./AutoPlaceUtil":125}],124:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AutoPlaceSelectionBehavior;
+/**
+ * Select element after auto placement.
+ *
+ * @param {EventBus} eventBus
+ * @param {Selection} selection
+ */
+function AutoPlaceSelectionBehavior(eventBus, selection) {
+
+ eventBus.on('autoPlace.end', 500, function (e) {
+ selection.select(e.shape);
+ });
+}
+
+AutoPlaceSelectionBehavior.$inject = ['eventBus', 'selection'];
+
+},{}],125:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.getFlowNodePosition = getFlowNodePosition;
+exports.getFlowNodeDistance = getFlowNodeDistance;
+exports.getTextAnnotationPosition = getTextAnnotationPosition;
+exports.getDataElementPosition = getDataElementPosition;
+exports.getDefaultPosition = getDefaultPosition;
+exports.getConnectedAtPosition = getConnectedAtPosition;
+exports.deconflictPosition = deconflictPosition;
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _minDash = require('min-dash');
+
+var DEFAULT_HORIZONTAL_DISTANCE = 50;
+
+var MAX_HORIZONTAL_DISTANCE = 250;
+
+// padding to detect element placement
+var PLACEMENT_DETECTION_PAD = 10;
+
+/**
+ * Always try to place element right of source;
+ * compute actual distance from previous nodes in flow.
+ */
+function getFlowNodePosition(source, element) {
+
+ var sourceTrbl = (0, _LayoutUtil.asTRBL)(source);
+ var sourceMid = (0, _LayoutUtil.getMid)(source);
+
+ var horizontalDistance = getFlowNodeDistance(source, element);
+
+ var orientation = 'left',
+ rowSize = 80,
+ margin = 30;
+
+ if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) {
+ orientation = (0, _LayoutUtil.getOrientation)(source, source.host, -25);
+
+ if (orientation.indexOf('top') !== -1) {
+ margin *= -1;
+ }
+ }
+
+ function getVerticalDistance(orient) {
+ if (orient.indexOf('top') != -1) {
+ return -1 * rowSize;
+ } else if (orient.indexOf('bottom') != -1) {
+ return rowSize;
+ } else {
+ return 0;
+ }
+ }
+
+ var position = {
+ x: sourceTrbl.right + horizontalDistance + element.width / 2,
+ y: sourceMid.y + getVerticalDistance(orientation)
+ };
+
+ var escapeDirection = {
+ y: {
+ margin: margin,
+ rowSize: rowSize
+ }
+ };
+
+ return deconflictPosition(source, element, position, escapeDirection);
+}
+
+/**
+ * Compute best distance between source and target,
+ * based on existing connections to and from source.
+ *
+ * @param {djs.model.Shape} source
+ * @param {djs.model.Shape} element
+ *
+ * @return {Number} distance
+ */
+function getFlowNodeDistance(source, element) {
+
+ var sourceTrbl = (0, _LayoutUtil.asTRBL)(source);
+
+ // is connection a reference to consider?
+ function isReference(c) {
+ return (0, _ModelUtil.is)(c, 'bpmn:SequenceFlow');
+ }
+
+ function toTargetNode(weight) {
+
+ return function (shape) {
+ return {
+ shape: shape,
+ weight: weight,
+ distanceTo: function distanceTo(shape) {
+ var shapeTrbl = (0, _LayoutUtil.asTRBL)(shape);
+
+ return shapeTrbl.left - sourceTrbl.right;
+ }
+ };
+ };
+ }
+
+ function toSourceNode(weight) {
+ return function (shape) {
+ return {
+ shape: shape,
+ weight: weight,
+ distanceTo: function distanceTo(shape) {
+ var shapeTrbl = (0, _LayoutUtil.asTRBL)(shape);
+
+ return sourceTrbl.left - shapeTrbl.right;
+ }
+ };
+ };
+ }
+
+ // we create a list of nodes to take into consideration
+ // for calculating the optimal flow node distance
+ //
+ // * weight existing target nodes higher than source nodes
+ // * only take into account individual nodes once
+ //
+ var nodes = (0, _minDash.reduce)([].concat(getTargets(source, isReference).map(toTargetNode(5)), getSources(source, isReference).map(toSourceNode(1))), function (nodes, node) {
+ // filter out shapes connected twice via source or target
+ nodes[node.shape.id + '__weight_' + node.weight] = node;
+
+ return nodes;
+ }, {});
+
+ // compute distances between source and incoming nodes;
+ // group at the same time by distance and expose the
+ // favourite distance as { fav: { count, value } }.
+ var distancesGrouped = (0, _minDash.reduce)(nodes, function (result, node) {
+
+ var shape = node.shape,
+ weight = node.weight,
+ distanceTo = node.distanceTo;
+
+ var fav = result.fav,
+ currentDistance,
+ currentDistanceCount,
+ currentDistanceEntry;
+
+ currentDistance = distanceTo(shape);
+
+ // ignore too far away peers
+ // or non-left to right modeled nodes
+ if (currentDistance < 0 || currentDistance > MAX_HORIZONTAL_DISTANCE) {
+ return result;
+ }
+
+ currentDistanceEntry = result[String(currentDistance)] = result[String(currentDistance)] || {
+ value: currentDistance,
+ count: 0
+ };
+
+ // inc diff count
+ currentDistanceCount = currentDistanceEntry.count += 1 * weight;
+
+ if (!fav || fav.count < currentDistanceCount) {
+ result.fav = currentDistanceEntry;
+ }
+
+ return result;
+ }, {});
+
+ if (distancesGrouped.fav) {
+ return distancesGrouped.fav.value;
+ } else {
+ return DEFAULT_HORIZONTAL_DISTANCE;
+ }
+}
+
+/**
+ * Always try to place text annotations top right of source.
+ */
+function getTextAnnotationPosition(source, element) {
+
+ var sourceTrbl = (0, _LayoutUtil.asTRBL)(source);
+
+ var position = {
+ x: sourceTrbl.right + element.width / 2,
+ y: sourceTrbl.top - 50 - element.height / 2
+ };
+
+ var escapeDirection = {
+ y: {
+ margin: -30,
+ rowSize: 20
+ }
+ };
+
+ return deconflictPosition(source, element, position, escapeDirection);
+}
+
+/**
+ * Always put element bottom right of source.
+ */
+function getDataElementPosition(source, element) {
+
+ var sourceTrbl = (0, _LayoutUtil.asTRBL)(source);
+
+ var position = {
+ x: sourceTrbl.right - 10 + element.width / 2,
+ y: sourceTrbl.bottom + 40 + element.width / 2
+ };
+
+ var escapeDirection = {
+ x: {
+ margin: 30,
+ rowSize: 30
+ }
+ };
+
+ return deconflictPosition(source, element, position, escapeDirection);
+}
+
+/**
+ * Always put element right of source per default.
+ */
+function getDefaultPosition(source, element) {
+
+ var sourceTrbl = (0, _LayoutUtil.asTRBL)(source);
+
+ var sourceMid = (0, _LayoutUtil.getMid)(source);
+
+ // simply put element right next to source
+ return {
+ x: sourceTrbl.right + DEFAULT_HORIZONTAL_DISTANCE + element.width / 2,
+ y: sourceMid.y
+ };
+}
+
+/**
+ * Returns all connected elements around the given source.
+ *
+ * This includes:
+ *
+ * - connected elements
+ * - host connected elements
+ * - attachers connected elements
+ *
+ * @param {djs.model.Shape} source
+ * @param {djs.model.Shape} element
+ *
+ * @return {Array}
+ */
+function getAutoPlaceClosure(source, element) {
+
+ var allConnected = getConnected(source);
+
+ if (source.host) {
+ allConnected = allConnected.concat(getConnected(source.host));
+ }
+
+ if (source.attachers) {
+ allConnected = allConnected.concat(source.attachers.reduce(function (shapes, attacher) {
+ return shapes.concat(getConnected(attacher));
+ }, []));
+ }
+
+ return allConnected;
+}
+
+/**
+ * Return target at given position, if defined.
+ *
+ * This takes connected elements from host and attachers
+ * into account, too.
+ */
+function getConnectedAtPosition(source, position, element) {
+
+ var bounds = {
+ x: position.x - element.width / 2,
+ y: position.y - element.height / 2,
+ width: element.width,
+ height: element.height
+ };
+
+ var closure = getAutoPlaceClosure(source, element);
+
+ return (0, _minDash.find)(closure, function (target) {
+
+ if (target === element) {
+ return false;
+ }
+
+ var orientation = (0, _LayoutUtil.getOrientation)(target, bounds, PLACEMENT_DETECTION_PAD);
+
+ return orientation === 'intersect';
+ });
+}
+
+/**
+ * Returns a new, position for the given element
+ * based on the given element that is not occupied
+ * by some element connected to source.
+ *
+ * Take into account the escapeDirection (where to move
+ * on positining clashes) in the computation.
+ *
+ * @param {djs.model.Shape} source
+ * @param {djs.model.Shape} element
+ * @param {Point} position
+ * @param {Object} escapeDelta
+ *
+ * @return {Point}
+ */
+function deconflictPosition(source, element, position, escapeDelta) {
+
+ function nextPosition(existingElement) {
+
+ var newPosition = {
+ x: position.x,
+ y: position.y
+ };
+
+ ['x', 'y'].forEach(function (axis) {
+
+ var axisDelta = escapeDelta[axis];
+
+ if (!axisDelta) {
+ return;
+ }
+
+ var dimension = axis === 'x' ? 'width' : 'height';
+
+ var margin = axisDelta.margin,
+ rowSize = axisDelta.rowSize;
+
+ if (margin < 0) {
+ newPosition[axis] = Math.min(existingElement[axis] + margin - element[dimension] / 2, position[axis] - rowSize + margin);
+ } else {
+ newPosition[axis] = Math.max(existingTarget[axis] + existingTarget[dimension] + margin + element[dimension] / 2, position[axis] + rowSize + margin);
+ }
+ });
+
+ return newPosition;
+ }
+
+ var existingTarget;
+
+ // deconflict position until free slot is found
+ while (existingTarget = getConnectedAtPosition(source, position, element)) {
+ position = nextPosition(existingTarget);
+ }
+
+ return position;
+}
+
+// helpers //////////////////////
+
+function noneFilter() {
+ return true;
+}
+
+function getConnected(element, connectionFilter) {
+ return [].concat(getTargets(element, connectionFilter), getSources(element, connectionFilter));
+}
+
+function getSources(shape, connectionFilter) {
+
+ if (!connectionFilter) {
+ connectionFilter = noneFilter;
+ }
+
+ return shape.incoming.filter(connectionFilter).map(function (c) {
+ return c.source;
+ });
+}
+
+function getTargets(shape, connectionFilter) {
+
+ if (!connectionFilter) {
+ connectionFilter = noneFilter;
+ }
+
+ return shape.outgoing.filter(connectionFilter).map(function (c) {
+ return c.target;
+ });
+}
+
+},{"../../util/ModelUtil":216,"diagram-js/lib/layout/LayoutUtil":380,"min-dash":505}],126:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _AutoPlace = require('./AutoPlace');
+
+var _AutoPlace2 = _interopRequireDefault(_AutoPlace);
+
+var _AutoPlaceSelectionBehavior = require('./AutoPlaceSelectionBehavior');
+
+var _AutoPlaceSelectionBehavior2 = _interopRequireDefault(_AutoPlaceSelectionBehavior);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['autoPlaceSelectionBehavior'],
+ autoPlace: ['type', _AutoPlace2.default],
+ autoPlaceSelectionBehavior: ['type', _AutoPlaceSelectionBehavior2.default]
+};
+
+},{"./AutoPlace":123,"./AutoPlaceSelectionBehavior":124}],127:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnAutoResize;
+
+var _AutoResize = require('diagram-js/lib/features/auto-resize/AutoResize');
+
+var _AutoResize2 = _interopRequireDefault(_AutoResize);
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Sub class of the AutoResize module which implements a BPMN
+ * specific resize function.
+ */
+function BpmnAutoResize(injector) {
+
+ injector.invoke(_AutoResize2.default, this);
+}
+
+BpmnAutoResize.$inject = ['injector'];
+
+(0, _inherits2.default)(BpmnAutoResize, _AutoResize2.default);
+
+/**
+ * Resize shapes and lanes
+ *
+ * @param {djs.model.Shape} target
+ * @param {Object} newBounds
+ */
+BpmnAutoResize.prototype.resize = function (target, newBounds) {
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:Participant')) {
+ this._modeling.resizeLane(target, newBounds);
+ } else {
+ this._modeling.resizeShape(target, newBounds);
+ }
+};
+
+},{"../../util/ModelUtil":216,"diagram-js/lib/features/auto-resize/AutoResize":260,"inherits":415}],128:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnAutoResizeProvider;
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _minDash = require('min-dash');
+
+var _AutoResizeProvider = require('diagram-js/lib/features/auto-resize/AutoResizeProvider');
+
+var _AutoResizeProvider2 = _interopRequireDefault(_AutoResizeProvider);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * This module is a provider for automatically resizing parent BPMN elements
+ */
+function BpmnAutoResizeProvider(eventBus, modeling) {
+ _AutoResizeProvider2.default.call(this, eventBus);
+
+ this._modeling = modeling;
+}
+
+(0, _inherits2.default)(BpmnAutoResizeProvider, _AutoResizeProvider2.default);
+
+BpmnAutoResizeProvider.$inject = ['eventBus', 'modeling'];
+
+/**
+ * Check if the given target can be expanded
+ *
+ * @param {djs.model.Shape} target
+ *
+ * @return {boolean}
+ */
+BpmnAutoResizeProvider.prototype.canResize = function (elements, target) {
+
+ if (!(0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _ModelUtil.is)(target, 'bpmn:Lane') && !(0, _ModelUtil.is)(target, 'bpmn:SubProcess')) {
+ return false;
+ }
+
+ var canResize = true;
+
+ (0, _minDash.forEach)(elements, function (element) {
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || element.labelTarget) {
+ canResize = false;
+ return;
+ }
+ });
+
+ return canResize;
+};
+
+},{"../../util/ModelUtil":216,"diagram-js/lib/features/auto-resize/AutoResizeProvider":261,"inherits":415,"min-dash":505}],129:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _BpmnAutoResize = require('./BpmnAutoResize');
+
+var _BpmnAutoResize2 = _interopRequireDefault(_BpmnAutoResize);
+
+var _BpmnAutoResizeProvider = require('./BpmnAutoResizeProvider');
+
+var _BpmnAutoResizeProvider2 = _interopRequireDefault(_BpmnAutoResizeProvider);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['bpmnAutoResize', 'bpmnAutoResizeProvider'],
+ bpmnAutoResize: ['type', _BpmnAutoResize2.default],
+ bpmnAutoResizeProvider: ['type', _BpmnAutoResizeProvider2.default]
+};
+
+},{"./BpmnAutoResize":127,"./BpmnAutoResizeProvider":128}],130:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ContextPadProvider;
+
+var _minDash = require('min-dash');
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _DiUtil = require('../../util/DiUtil');
+
+var _ModelingUtil = require('../modeling/util/ModelingUtil');
+
+var _LaneUtil = require('../modeling/util/LaneUtil');
+
+var _Mouse = require('diagram-js/lib/util/Mouse');
+
+/**
+ * A provider for BPMN 2.0 elements context pad
+ */
+function ContextPadProvider(config, injector, eventBus, contextPad, modeling, elementFactory, connect, create, popupMenu, canvas, rules, translate) {
+
+ config = config || {};
+
+ contextPad.registerProvider(this);
+
+ this._contextPad = contextPad;
+
+ this._modeling = modeling;
+
+ this._elementFactory = elementFactory;
+ this._connect = connect;
+ this._create = create;
+ this._popupMenu = popupMenu;
+ this._canvas = canvas;
+ this._rules = rules;
+ this._translate = translate;
+
+ if (config.autoPlace !== false) {
+ this._autoPlace = injector.get('autoPlace', false);
+ }
+
+ eventBus.on('create.end', 250, function (event) {
+ var shape = event.context.shape;
+
+ if (!(0, _Mouse.hasPrimaryModifier)(event)) {
+ return;
+ }
+
+ var entries = contextPad.getEntries(shape);
+
+ if (entries.replace) {
+ entries.replace.action.click(event, shape);
+ }
+ });
+}
+
+ContextPadProvider.$inject = ['config.contextPad', 'injector', 'eventBus', 'contextPad', 'modeling', 'elementFactory', 'connect', 'create', 'popupMenu', 'canvas', 'rules', 'translate'];
+
+ContextPadProvider.prototype.getContextPadEntries = function (element) {
+
+ var contextPad = this._contextPad,
+ modeling = this._modeling,
+ elementFactory = this._elementFactory,
+ connect = this._connect,
+ create = this._create,
+ popupMenu = this._popupMenu,
+ canvas = this._canvas,
+ rules = this._rules,
+ autoPlace = this._autoPlace,
+ translate = this._translate;
+
+ var actions = {};
+
+ if (element.type === 'label') {
+ return actions;
+ }
+
+ var businessObject = element.businessObject;
+
+ function startConnect(event, element) {
+ connect.start(event, element);
+ }
+
+ function removeElement(e) {
+ modeling.removeElements([element]);
+ }
+
+ function getReplaceMenuPosition(element) {
+
+ var Y_OFFSET = 5;
+
+ var diagramContainer = canvas.getContainer(),
+ pad = contextPad.getPad(element).html;
+
+ var diagramRect = diagramContainer.getBoundingClientRect(),
+ padRect = pad.getBoundingClientRect();
+
+ var top = padRect.top - diagramRect.top;
+ var left = padRect.left - diagramRect.left;
+
+ var pos = {
+ x: left,
+ y: top + padRect.height + Y_OFFSET
+ };
+
+ return pos;
+ }
+
+ /**
+ * Create an append action
+ *
+ * @param {String} type
+ * @param {String} className
+ * @param {String} [title]
+ * @param {Object} [options]
+ *
+ * @return {Object} descriptor
+ */
+ function appendAction(type, className, title, options) {
+
+ if (typeof title !== 'string') {
+ options = title;
+ title = translate('Append {type}', { type: type.replace(/^bpmn:/, '') });
+ }
+
+ function appendStart(event, element) {
+
+ var shape = elementFactory.createShape((0, _minDash.assign)({ type: type }, options));
+ create.start(event, shape, element);
+ }
+
+ var append = autoPlace ? function (event, element) {
+ var shape = elementFactory.createShape((0, _minDash.assign)({ type: type }, options));
+
+ autoPlace.append(element, shape);
+ } : appendStart;
+
+ return {
+ group: 'model',
+ className: className,
+ title: title,
+ action: {
+ dragstart: appendStart,
+ click: append
+ }
+ };
+ }
+
+ function splitLaneHandler(count) {
+
+ return function (event, element) {
+ // actual split
+ modeling.splitLane(element, count);
+
+ // refresh context pad after split to
+ // get rid of split icons
+ contextPad.open(element, true);
+ };
+ }
+
+ if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:Lane', 'bpmn:Participant']) && (0, _DiUtil.isExpanded)(businessObject)) {
+
+ var childLanes = (0, _LaneUtil.getChildLanes)(element);
+
+ (0, _minDash.assign)(actions, {
+ 'lane-insert-above': {
+ group: 'lane-insert-above',
+ className: 'bpmn-icon-lane-insert-above',
+ title: translate('Add Lane above'),
+ action: {
+ click: function click(event, element) {
+ modeling.addLane(element, 'top');
+ }
+ }
+ }
+ });
+
+ if (childLanes.length < 2) {
+
+ if (element.height >= 120) {
+ (0, _minDash.assign)(actions, {
+ 'lane-divide-two': {
+ group: 'lane-divide',
+ className: 'bpmn-icon-lane-divide-two',
+ title: translate('Divide into two Lanes'),
+ action: {
+ click: splitLaneHandler(2)
+ }
+ }
+ });
+ }
+
+ if (element.height >= 180) {
+ (0, _minDash.assign)(actions, {
+ 'lane-divide-three': {
+ group: 'lane-divide',
+ className: 'bpmn-icon-lane-divide-three',
+ title: translate('Divide into three Lanes'),
+ action: {
+ click: splitLaneHandler(3)
+ }
+ }
+ });
+ }
+ }
+
+ (0, _minDash.assign)(actions, {
+ 'lane-insert-below': {
+ group: 'lane-insert-below',
+ className: 'bpmn-icon-lane-insert-below',
+ title: translate('Add Lane below'),
+ action: {
+ click: function click(event, element) {
+ modeling.addLane(element, 'bottom');
+ }
+ }
+ }
+ });
+ }
+
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowNode')) {
+
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:EventBasedGateway')) {
+
+ (0, _minDash.assign)(actions, {
+ 'append.receive-task': appendAction('bpmn:ReceiveTask', 'bpmn-icon-receive-task'),
+ 'append.message-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-message', translate('Append MessageIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:MessageEventDefinition' }),
+ 'append.timer-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-timer', translate('Append TimerIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:TimerEventDefinition' }),
+ 'append.condtion-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-condition', translate('Append ConditionIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:ConditionalEventDefinition' }),
+ 'append.signal-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-signal', translate('Append SignalIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:SignalEventDefinition' })
+ });
+ } else if (isEventType(businessObject, 'bpmn:BoundaryEvent', 'bpmn:CompensateEventDefinition')) {
+
+ (0, _minDash.assign)(actions, {
+ 'append.compensation-activity': appendAction('bpmn:Task', 'bpmn-icon-task', translate('Append compensation activity'), {
+ isForCompensation: true
+ })
+ });
+ } else if (!(0, _ModelUtil.is)(businessObject, 'bpmn:EndEvent') && !businessObject.isForCompensation && !isEventType(businessObject, 'bpmn:IntermediateThrowEvent', 'bpmn:LinkEventDefinition') && !(0, _DiUtil.isEventSubProcess)(businessObject)) {
+
+ (0, _minDash.assign)(actions, {
+ 'append.end-event': appendAction('bpmn:EndEvent', 'bpmn-icon-end-event-none'),
+ 'append.gateway': appendAction('bpmn:ExclusiveGateway', 'bpmn-icon-gateway-none', translate('Append Gateway')),
+ 'append.append-task': appendAction('bpmn:Task', 'bpmn-icon-task'),
+ 'append.intermediate-event': appendAction('bpmn:IntermediateThrowEvent', 'bpmn-icon-intermediate-event-none', translate('Append Intermediate/Boundary Event'))
+ });
+ }
+ }
+
+ if (!popupMenu.isEmpty(element, 'bpmn-replace')) {
+ // Replace menu entry
+ (0, _minDash.assign)(actions, {
+ 'replace': {
+ group: 'edit',
+ className: 'bpmn-icon-screw-wrench',
+ title: translate('Change type'),
+ action: {
+ click: function click(event, element) {
+
+ var position = (0, _minDash.assign)(getReplaceMenuPosition(element), {
+ cursor: { x: event.x, y: event.y }
+ });
+
+ popupMenu.open(element, 'bpmn-replace', position);
+ }
+ }
+ }
+ });
+ }
+
+ if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:FlowNode', 'bpmn:InteractionNode', 'bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) {
+
+ (0, _minDash.assign)(actions, {
+ 'append.text-annotation': appendAction('bpmn:TextAnnotation', 'bpmn-icon-text-annotation'),
+
+ 'connect': {
+ group: 'connect',
+ className: 'bpmn-icon-connection-multi',
+ title: translate('Connect using ' + (businessObject.isForCompensation ? '' : 'Sequence/MessageFlow or ') + 'Association'),
+ action: {
+ click: startConnect,
+ dragstart: startConnect
+ }
+ }
+ });
+ }
+
+ if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) {
+ (0, _minDash.assign)(actions, {
+ 'connect': {
+ group: 'connect',
+ className: 'bpmn-icon-connection-multi',
+ title: translate('Connect using DataInputAssociation'),
+ action: {
+ click: startConnect,
+ dragstart: startConnect
+ }
+ }
+ });
+ }
+
+ // delete element entry, only show if allowed by rules
+ var deleteAllowed = rules.allowed('elements.delete', { elements: [element] });
+
+ if ((0, _minDash.isArray)(deleteAllowed)) {
+ // was the element returned as a deletion candidate?
+ deleteAllowed = deleteAllowed[0] === element;
+ }
+
+ if (deleteAllowed) {
+ (0, _minDash.assign)(actions, {
+ 'delete': {
+ group: 'edit',
+ className: 'bpmn-icon-trash',
+ title: translate('Remove'),
+ action: {
+ click: removeElement
+ }
+ }
+ });
+ }
+
+ return actions;
+};
+
+function isEventType(eventBo, type, definition) {
+
+ var isType = eventBo.$instanceOf(type);
+ var isDefinition = false;
+
+ var definitions = eventBo.eventDefinitions || [];
+ (0, _minDash.forEach)(definitions, function (def) {
+ if (def.$type === definition) {
+ isDefinition = true;
+ }
+ });
+
+ return isType && isDefinition;
+}
+
+},{"../../util/DiUtil":214,"../../util/ModelUtil":216,"../modeling/util/LaneUtil":188,"../modeling/util/ModelingUtil":189,"diagram-js/lib/util/Mouse":403,"min-dash":505}],131:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _diagramJsDirectEditing = require('diagram-js-direct-editing');
+
+var _diagramJsDirectEditing2 = _interopRequireDefault(_diagramJsDirectEditing);
+
+var _contextPad = require('diagram-js/lib/features/context-pad');
+
+var _contextPad2 = _interopRequireDefault(_contextPad);
+
+var _selection = require('diagram-js/lib/features/selection');
+
+var _selection2 = _interopRequireDefault(_selection);
+
+var _connect = require('diagram-js/lib/features/connect');
+
+var _connect2 = _interopRequireDefault(_connect);
+
+var _create = require('diagram-js/lib/features/create');
+
+var _create2 = _interopRequireDefault(_create);
+
+var _popupMenu = require('../popup-menu');
+
+var _popupMenu2 = _interopRequireDefault(_popupMenu);
+
+var _ContextPadProvider = require('./ContextPadProvider');
+
+var _ContextPadProvider2 = _interopRequireDefault(_ContextPadProvider);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_diagramJsDirectEditing2.default, _contextPad2.default, _selection2.default, _connect2.default, _create2.default, _popupMenu2.default],
+ __init__: ['contextPadProvider'],
+ contextPadProvider: ['type', _ContextPadProvider2.default]
+};
+
+},{"../popup-menu":195,"./ContextPadProvider":130,"diagram-js-direct-editing":238,"diagram-js/lib/features/connect":275,"diagram-js/lib/features/context-pad":277,"diagram-js/lib/features/create":281,"diagram-js/lib/features/selection":361}],132:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnCopyPaste;
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _ModelCloneHelper = require('../../util/model/ModelCloneHelper');
+
+var _ModelCloneHelper2 = _interopRequireDefault(_ModelCloneHelper);
+
+var _ModelCloneUtils = require('../../util/model/ModelCloneUtils');
+
+var _minDash = require('min-dash');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function setProperties(descriptor, data, properties) {
+ (0, _minDash.forEach)(properties, function (property) {
+ if (data[property] !== undefined) {
+ descriptor[property] = data[property];
+ }
+ });
+}
+
+function removeProperties(element, properties) {
+ (0, _minDash.forEach)(properties, function (prop) {
+ if (element[prop]) {
+ delete element[prop];
+ }
+ });
+}
+
+function BpmnCopyPaste(bpmnFactory, eventBus, copyPaste, clipboard, canvas, bpmnRules) {
+
+ var helper = new _ModelCloneHelper2.default(eventBus, bpmnFactory);
+
+ copyPaste.registerDescriptor(function (element, descriptor) {
+ var businessObject = descriptor.oldBusinessObject = (0, _ModelUtil.getBusinessObject)(element);
+
+ var colors = {};
+
+ descriptor.type = element.type;
+
+ setProperties(descriptor, businessObject.di, ['isExpanded']);
+
+ setProperties(colors, businessObject.di, ['fill', 'stroke']);
+
+ descriptor.colors = colors;
+
+ if (element.type === 'label') {
+ return descriptor;
+ }
+
+ setProperties(descriptor, businessObject, ['processRef', 'triggeredByEvent']);
+
+ if (businessObject.default) {
+ descriptor.default = businessObject.default.id;
+ }
+
+ return descriptor;
+ });
+
+ eventBus.on('element.paste', function (context) {
+ var descriptor = context.descriptor,
+ createdElements = context.createdElements,
+ parent = descriptor.parent,
+ rootElement = canvas.getRootElement(),
+ oldBusinessObject = descriptor.oldBusinessObject,
+ newBusinessObject,
+ source,
+ target,
+ canConnect;
+
+ newBusinessObject = bpmnFactory.create(oldBusinessObject.$type);
+
+ var properties = (0, _ModelCloneUtils.getProperties)(oldBusinessObject.$descriptor);
+
+ properties = (0, _minDash.filter)(properties, function (property) {
+ return _ModelCloneUtils.IGNORED_PROPERTIES.indexOf(property.replace(/bpmn:/, '')) === -1;
+ });
+
+ descriptor.businessObject = helper.clone(oldBusinessObject, newBusinessObject, properties);
+
+ if (descriptor.type === 'label') {
+ return;
+ }
+
+ if ((0, _ModelUtil.is)(parent, 'bpmn:Process')) {
+ descriptor.parent = (0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration') ? rootElement : parent;
+ }
+
+ if (descriptor.type === 'bpmn:DataOutputAssociation' || descriptor.type === 'bpmn:DataInputAssociation' || descriptor.type === 'bpmn:MessageFlow') {
+ descriptor.parent = rootElement;
+ }
+
+ if ((0, _ModelUtil.is)(parent, 'bpmn:Lane')) {
+ descriptor.parent = parent.parent;
+ }
+
+ // make sure that the correct type of connection is created
+ if (descriptor.waypoints) {
+ source = createdElements[descriptor.source];
+ target = createdElements[descriptor.target];
+
+ if (source && target) {
+ source = source.element;
+ target = target.element;
+ }
+
+ canConnect = bpmnRules.canConnect(source, target);
+
+ if (canConnect) {
+ descriptor.type = canConnect.type;
+ }
+ }
+
+ // remove the id or else we cannot paste multiple times
+ delete newBusinessObject.id;
+
+ // assign an ID
+ bpmnFactory._ensureId(newBusinessObject);
+
+ if (descriptor.type === 'bpmn:Participant' && descriptor.processRef) {
+ descriptor.processRef = newBusinessObject.processRef = bpmnFactory.create('bpmn:Process');
+ }
+
+ setProperties(newBusinessObject, descriptor, ['isExpanded', 'triggeredByEvent']);
+
+ removeProperties(descriptor, ['triggeredByEvent']);
+ });
+}
+
+BpmnCopyPaste.$inject = ['bpmnFactory', 'eventBus', 'copyPaste', 'clipboard', 'canvas', 'bpmnRules'];
+
+},{"../../util/ModelUtil":216,"../../util/model/ModelCloneHelper":218,"../../util/model/ModelCloneUtils":219,"min-dash":505}],133:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _copyPaste = require('diagram-js/lib/features/copy-paste');
+
+var _copyPaste2 = _interopRequireDefault(_copyPaste);
+
+var _BpmnCopyPaste = require('./BpmnCopyPaste');
+
+var _BpmnCopyPaste2 = _interopRequireDefault(_BpmnCopyPaste);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_copyPaste2.default],
+ __init__: ['bpmnCopyPaste'],
+ bpmnCopyPaste: ['type', _BpmnCopyPaste2.default]
+};
+
+},{"./BpmnCopyPaste":132,"diagram-js/lib/features/copy-paste":279}],134:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnDistributeElements;
+
+var _minDash = require('min-dash');
+
+var _ModelingUtil = require('../modeling/util/ModelingUtil');
+
+/**
+ * Registers element exclude filters for elements that
+ * currently do not support distribution.
+ */
+function BpmnDistributeElements(distributeElements) {
+
+ distributeElements.registerFilter(function (elements) {
+ return (0, _minDash.filter)(elements, function (element) {
+ var cannotDistribute = (0, _ModelingUtil.isAny)(element, ['bpmn:Association', 'bpmn:BoundaryEvent', 'bpmn:DataInputAssociation', 'bpmn:DataOutputAssociation', 'bpmn:Lane', 'bpmn:MessageFlow', 'bpmn:Participant', 'bpmn:SequenceFlow', 'bpmn:TextAnnotation']);
+
+ return !(element.labelTarget || cannotDistribute);
+ });
+ });
+}
+
+BpmnDistributeElements.$inject = ['distributeElements'];
+
+},{"../modeling/util/ModelingUtil":189,"min-dash":505}],135:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _distributeElements = require('diagram-js/lib/features/distribute-elements');
+
+var _distributeElements2 = _interopRequireDefault(_distributeElements);
+
+var _BpmnDistributeElements = require('./BpmnDistributeElements');
+
+var _BpmnDistributeElements2 = _interopRequireDefault(_BpmnDistributeElements);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_distributeElements2.default],
+ __init__: ['bpmnDistributeElements'],
+ bpmnDistributeElements: ['type', _BpmnDistributeElements2.default]
+};
+
+},{"./BpmnDistributeElements":134,"diagram-js/lib/features/distribute-elements":283}],136:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnEditorActions;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _EditorActions = require('diagram-js/lib/features/editor-actions/EditorActions');
+
+var _EditorActions2 = _interopRequireDefault(_EditorActions);
+
+var _minDash = require('min-dash');
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _Elements = require('diagram-js/lib/util/Elements');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Registers and executes BPMN specific editor actions.
+ *
+ * @param {Injector} injector
+ */
+function BpmnEditorActions(injector) {
+ injector.invoke(_EditorActions2.default, this);
+}
+
+(0, _inherits2.default)(BpmnEditorActions, _EditorActions2.default);
+
+BpmnEditorActions.$inject = ['injector'];
+
+/**
+ * Register default actions.
+ *
+ * @param {Injector} injector
+ */
+BpmnEditorActions.prototype._registerDefaultActions = function (injector) {
+
+ // (0) invoke super method
+
+ _EditorActions2.default.prototype._registerDefaultActions.call(this, injector);
+
+ // (1) retrieve optional components to integrate with
+
+ var canvas = injector.get('canvas', false);
+ var elementRegistry = injector.get('elementRegistry', false);
+ var selection = injector.get('selection', false);
+ var spaceTool = injector.get('spaceTool', false);
+ var lassoTool = injector.get('lassoTool', false);
+ var handTool = injector.get('handTool', false);
+ var globalConnect = injector.get('globalConnect', false);
+ var distributeElements = injector.get('distributeElements', false);
+ var alignElements = injector.get('alignElements', false);
+ var directEditing = injector.get('directEditing', false);
+ var searchPad = injector.get('searchPad', false);
+ var modeling = injector.get('modeling', false);
+
+ // (2) check components and register actions
+
+ if (canvas && elementRegistry && selection) {
+ this._registerAction('selectElements', function () {
+ // select all elements except for the invisible
+ // root element
+ var rootElement = canvas.getRootElement();
+
+ var elements = elementRegistry.filter(function (element) {
+ return element !== rootElement;
+ });
+
+ selection.select(elements);
+
+ return elements;
+ });
+ }
+
+ if (spaceTool) {
+ this._registerAction('spaceTool', function () {
+ spaceTool.toggle();
+ });
+ }
+
+ if (lassoTool) {
+ this._registerAction('lassoTool', function () {
+ lassoTool.toggle();
+ });
+ }
+
+ if (handTool) {
+ this._registerAction('handTool', function () {
+ handTool.toggle();
+ });
+ }
+
+ if (globalConnect) {
+ this._registerAction('globalConnectTool', function () {
+ globalConnect.toggle();
+ });
+ }
+
+ if (selection && distributeElements) {
+ this._registerAction('distributeElements', function (opts) {
+ var currentSelection = selection.get(),
+ type = opts.type;
+
+ if (currentSelection.length) {
+ distributeElements.trigger(currentSelection, type);
+ }
+ });
+ }
+
+ if (selection && alignElements) {
+ this._registerAction('alignElements', function (opts) {
+ var currentSelection = selection.get(),
+ aligneableElements = [],
+ type = opts.type;
+
+ if (currentSelection.length) {
+ aligneableElements = (0, _minDash.filter)(currentSelection, function (element) {
+ return !(0, _ModelUtil.is)(element, 'bpmn:Lane');
+ });
+
+ alignElements.trigger(aligneableElements, type);
+ }
+ });
+ }
+
+ if (selection && modeling) {
+ this._registerAction('setColor', function (opts) {
+ var currentSelection = selection.get();
+
+ if (currentSelection.length) {
+ modeling.setColor(currentSelection, opts);
+ }
+ });
+ }
+
+ if (selection && directEditing) {
+ this._registerAction('directEditing', function () {
+ var currentSelection = selection.get();
+
+ if (currentSelection.length) {
+ directEditing.activate(currentSelection[0]);
+ }
+ });
+ }
+
+ if (searchPad) {
+ this._registerAction('find', function () {
+ searchPad.toggle();
+ });
+ }
+
+ if (canvas && modeling) {
+ this._registerAction('moveToOrigin', function () {
+ var rootElement = canvas.getRootElement(),
+ boundingBox,
+ elements;
+
+ if ((0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) {
+ elements = elementRegistry.filter(function (element) {
+ return (0, _ModelUtil.is)(element.parent, 'bpmn:Collaboration');
+ });
+ } else {
+ elements = elementRegistry.filter(function (element) {
+ return element !== rootElement && !(0, _ModelUtil.is)(element.parent, 'bpmn:SubProcess');
+ });
+ }
+
+ boundingBox = (0, _Elements.getBBox)(elements);
+
+ modeling.moveElements(elements, { x: -boundingBox.x, y: -boundingBox.y }, rootElement);
+ });
+ }
+};
+
+},{"../../util/ModelUtil":216,"diagram-js/lib/features/editor-actions/EditorActions":287,"diagram-js/lib/util/Elements":396,"inherits":415,"min-dash":505}],137:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _editorActions = require('diagram-js/lib/features/editor-actions');
+
+var _editorActions2 = _interopRequireDefault(_editorActions);
+
+var _BpmnEditorActions = require('./BpmnEditorActions');
+
+var _BpmnEditorActions2 = _interopRequireDefault(_BpmnEditorActions);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_editorActions2.default],
+ editorActions: ['type', _BpmnEditorActions2.default]
+};
+
+},{"./BpmnEditorActions":136,"diagram-js/lib/features/editor-actions":288}],138:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnKeyboardBindings;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _KeyboardBindings = require('diagram-js/lib/features/keyboard/KeyboardBindings');
+
+var _KeyboardBindings2 = _interopRequireDefault(_KeyboardBindings);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * BPMN 2.0 specific keyboard bindings.
+ *
+ * @param {Injector} injector
+ */
+function BpmnKeyboardBindings(injector) {
+ injector.invoke(_KeyboardBindings2.default, this);
+}
+
+(0, _inherits2.default)(BpmnKeyboardBindings, _KeyboardBindings2.default);
+
+BpmnKeyboardBindings.$inject = ['injector'];
+
+/**
+ * Register available keyboard bindings.
+ *
+ * @param {Keyboard} keyboard
+ * @param {EditorActions} editorActions
+ */
+BpmnKeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) {
+
+ // inherit default bindings
+ _KeyboardBindings2.default.prototype.registerBindings.call(this, keyboard, editorActions);
+
+ /**
+ * Add keyboard binding if respective editor action
+ * is registered.
+ *
+ * @param {String} action name
+ * @param {Function} fn that implements the key binding
+ */
+ function addListener(action, fn) {
+
+ if (editorActions.isRegistered(action)) {
+ keyboard.addListener(fn);
+ }
+ }
+
+ // select all elements
+ // CTRL + A
+ addListener('selectElements', function (context) {
+
+ var event = context.keyEvent;
+
+ if (keyboard.isKey(['a', 'A'], event) && keyboard.isCmd(event)) {
+ editorActions.trigger('selectElements');
+
+ return true;
+ }
+ });
+
+ // search labels
+ // CTRL + F
+ addListener('find', function (context) {
+
+ var event = context.keyEvent;
+
+ if (keyboard.isKey(['f', 'F'], event) && keyboard.isCmd(event)) {
+ editorActions.trigger('find');
+
+ return true;
+ }
+ });
+
+ // activate space tool
+ // S
+ addListener('spaceTool', function (context) {
+
+ var event = context.keyEvent;
+
+ if (keyboard.hasModifier(event)) {
+ return;
+ }
+
+ if (keyboard.isKey(['s', 'S'], event)) {
+ editorActions.trigger('spaceTool');
+
+ return true;
+ }
+ });
+
+ // activate lasso tool
+ // L
+ addListener('lassoTool', function (context) {
+
+ var event = context.keyEvent;
+
+ if (keyboard.hasModifier(event)) {
+ return;
+ }
+
+ if (keyboard.isKey(['l', 'L'], event)) {
+ editorActions.trigger('lassoTool');
+
+ return true;
+ }
+ });
+
+ // activate hand tool
+ // H
+ addListener('handTool', function (context) {
+
+ var event = context.keyEvent;
+
+ if (keyboard.hasModifier(event)) {
+ return;
+ }
+
+ if (keyboard.isKey(['h', 'H'], event)) {
+ editorActions.trigger('handTool');
+
+ return true;
+ }
+ });
+
+ // activate global connect tool
+ // C
+ addListener('globalConnectTool', function (context) {
+
+ var event = context.keyEvent;
+
+ if (keyboard.hasModifier(event)) {
+ return;
+ }
+
+ if (keyboard.isKey(['c', 'C'], event)) {
+ editorActions.trigger('globalConnectTool');
+
+ return true;
+ }
+ });
+
+ // activate direct editing
+ // E
+ addListener('directEditing', function (context) {
+
+ var event = context.keyEvent;
+
+ if (keyboard.hasModifier(event)) {
+ return;
+ }
+
+ if (keyboard.isKey(['e', 'E'], event)) {
+ editorActions.trigger('directEditing');
+
+ return true;
+ }
+ });
+};
+
+},{"diagram-js/lib/features/keyboard/KeyboardBindings":298,"inherits":415}],139:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _keyboard = require('diagram-js/lib/features/keyboard');
+
+var _keyboard2 = _interopRequireDefault(_keyboard);
+
+var _BpmnKeyboardBindings = require('./BpmnKeyboardBindings');
+
+var _BpmnKeyboardBindings2 = _interopRequireDefault(_BpmnKeyboardBindings);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_keyboard2.default],
+ __init__: ['keyboardBindings'],
+ keyboardBindings: ['type', _BpmnKeyboardBindings2.default]
+};
+
+},{"./BpmnKeyboardBindings":138,"diagram-js/lib/features/keyboard":300}],140:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = LabelEditingPreview;
+
+var _tinySvg = require('tiny-svg');
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _SvgTransformUtil = require('diagram-js/lib/util/SvgTransformUtil');
+
+var MARKER_HIDDEN = 'djs-element-hidden',
+ MARKER_LABEL_HIDDEN = 'djs-label-hidden';
+
+function LabelEditingPreview(eventBus, canvas, elementRegistry, pathMap) {
+
+ var self = this;
+
+ var defaultLayer = canvas.getDefaultLayer();
+
+ var element, absoluteElementBBox, gfx;
+
+ eventBus.on('directEditing.activate', function (context) {
+ var activeProvider = context.active;
+
+ element = activeProvider.element.label || activeProvider.element;
+
+ // text annotation
+ if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
+ absoluteElementBBox = canvas.getAbsoluteBBox(element);
+
+ gfx = (0, _tinySvg.create)('g');
+
+ var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: element.height,
+ position: {
+ mx: 0.0,
+ my: 0.0
+ }
+ });
+
+ var path = self.path = (0, _tinySvg.create)('path');
+
+ (0, _tinySvg.attr)(path, {
+ d: textPathData,
+ strokeWidth: 2,
+ stroke: getStrokeColor(element)
+ });
+
+ (0, _tinySvg.append)(gfx, path);
+
+ (0, _tinySvg.append)(defaultLayer, gfx);
+
+ (0, _SvgTransformUtil.translate)(gfx, element.x, element.y);
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation') || element.labelTarget) {
+ canvas.addMarker(element, MARKER_HIDDEN);
+ } else if ((0, _ModelUtil.is)(element, 'bpmn:Task') || (0, _ModelUtil.is)(element, 'bpmn:CallActivity') || (0, _ModelUtil.is)(element, 'bpmn:SubProcess') || (0, _ModelUtil.is)(element, 'bpmn:Participant')) {
+ canvas.addMarker(element, MARKER_LABEL_HIDDEN);
+ }
+ });
+
+ eventBus.on('directEditing.resize', function (context) {
+
+ // text annotation
+ if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
+ var height = context.height,
+ dy = context.dy;
+
+ var newElementHeight = Math.max(element.height / absoluteElementBBox.height * (height + dy), 0);
+
+ var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
+ xScaleFactor: 1,
+ yScaleFactor: 1,
+ containerWidth: element.width,
+ containerHeight: newElementHeight,
+ position: {
+ mx: 0.0,
+ my: 0.0
+ }
+ });
+
+ (0, _tinySvg.attr)(self.path, {
+ d: textPathData
+ });
+ }
+ });
+
+ eventBus.on(['directEditing.complete', 'directEditing.cancel'], function (context) {
+ var activeProvider = context.active;
+
+ if (activeProvider) {
+ canvas.removeMarker(activeProvider.element.label || activeProvider.element, MARKER_HIDDEN);
+ canvas.removeMarker(element, MARKER_LABEL_HIDDEN);
+ }
+
+ element = undefined;
+ absoluteElementBBox = undefined;
+
+ if (gfx) {
+ (0, _tinySvg.remove)(gfx);
+
+ gfx = undefined;
+ }
+ });
+}
+
+LabelEditingPreview.$inject = ['eventBus', 'canvas', 'elementRegistry', 'pathMap'];
+
+// helpers ///////////////////
+
+function getStrokeColor(element, defaultColor) {
+ var bo = (0, _ModelUtil.getBusinessObject)(element);
+
+ return bo.di.get('stroke') || defaultColor || 'black';
+}
+
+},{"../../util/ModelUtil":216,"diagram-js/lib/util/SvgTransformUtil":408,"tiny-svg":535}],141:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = LabelEditingProvider;
+
+var _minDash = require('min-dash');
+
+var _LabelUtil = require('./LabelUtil');
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _ModelingUtil = require('../modeling/util/ModelingUtil');
+
+var _DiUtil = require('../../util/DiUtil');
+
+var _LabelUtil2 = require('../../util/LabelUtil');
+
+function LabelEditingProvider(eventBus, canvas, directEditing, modeling, resizeHandles, textRenderer) {
+
+ this._canvas = canvas;
+ this._modeling = modeling;
+ this._textRenderer = textRenderer;
+
+ directEditing.registerProvider(this);
+
+ // listen to dblclick on non-root elements
+ eventBus.on('element.dblclick', function (event) {
+ activateDirectEdit(event.element, true);
+ });
+
+ // complete on followup canvas operation
+ eventBus.on(['element.mousedown', 'drag.init', 'canvas.viewbox.changing', 'autoPlace', 'popupMenu.open'], function (event) {
+
+ if (directEditing.isActive()) {
+ directEditing.complete();
+ }
+ });
+
+ // cancel on command stack changes
+ eventBus.on(['commandStack.changed'], function (e) {
+ if (directEditing.isActive()) {
+ directEditing.cancel();
+ }
+ });
+
+ eventBus.on('directEditing.activate', function (event) {
+ resizeHandles.removeResizers();
+ });
+
+ eventBus.on('create.end', 500, function (event) {
+
+ var element = event.shape,
+ canExecute = event.context.canExecute,
+ isTouch = event.isTouch;
+
+ // TODO(nikku): we need to find a way to support the
+ // direct editing on mobile devices; right now this will
+ // break for desworkflowediting on mobile devices
+ // as it breaks the user interaction workflow
+
+ // TODO(nre): we should temporarily focus the edited element
+ // here and release the focused viewport after the direct edit
+ // operation is finished
+ if (isTouch) {
+ return;
+ }
+
+ if (!canExecute) {
+ return;
+ }
+
+ activateDirectEdit(element);
+ });
+
+ eventBus.on('autoPlace.end', 500, function (event) {
+ activateDirectEdit(event.shape);
+ });
+
+ function activateDirectEdit(element, force) {
+ if (force || (0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:TextAnnotation']) || isCollapsedSubProcess(element)) {
+
+ directEditing.activate(element);
+ }
+ }
+}
+
+LabelEditingProvider.$inject = ['eventBus', 'canvas', 'directEditing', 'modeling', 'resizeHandles', 'textRenderer'];
+
+/**
+ * Activate direct editing for activities and text annotations.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {Object} an object with properties bounds (position and size), text and options
+ */
+LabelEditingProvider.prototype.activate = function (element) {
+
+ // text
+ var text = (0, _LabelUtil.getLabel)(element);
+
+ if (text === undefined) {
+ return;
+ }
+
+ var context = {
+ text: text
+ };
+
+ // bounds
+ var bounds = this.getEditingBBox(element);
+
+ (0, _minDash.assign)(context, bounds);
+
+ var options = {};
+
+ // tasks
+ if ((0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:Participant', 'bpmn:Lane', 'bpmn:CallActivity']) || isCollapsedSubProcess(element)) {
+ (0, _minDash.assign)(options, {
+ centerVertically: true
+ });
+ }
+
+ // external labels
+ if ((0, _LabelUtil2.isLabelExternal)(element)) {
+ (0, _minDash.assign)(options, {
+ autoResize: true
+ });
+ }
+
+ // text annotations
+ if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
+ (0, _minDash.assign)(options, {
+ resizable: true,
+ autoResize: true
+ });
+ }
+
+ (0, _minDash.assign)(context, {
+ options: options
+ });
+
+ return context;
+};
+
+/**
+ * Get the editing bounding box based on the element's size and position
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {Object} an object containing information about position
+ * and size (fixed or minimum and/or maximum)
+ */
+LabelEditingProvider.prototype.getEditingBBox = function (element) {
+ var canvas = this._canvas;
+
+ var target = element.label || element;
+
+ var bbox = canvas.getAbsoluteBBox(target);
+
+ var mid = {
+ x: bbox.x + bbox.width / 2,
+ y: bbox.y + bbox.height / 2
+ };
+
+ // default position
+ var bounds = { x: bbox.x, y: bbox.y };
+
+ var zoom = canvas.zoom();
+
+ var defaultStyle = this._textRenderer.getDefaultStyle(),
+ externalStyle = this._textRenderer.getExternalStyle();
+
+ // take zoom into account
+ var externalFontSize = externalStyle.fontSize * zoom,
+ externalLineHeight = externalStyle.lineHeight,
+ defaultFontSize = defaultStyle.fontSize * zoom,
+ defaultLineHeight = defaultStyle.lineHeight;
+
+ var style = {
+ fontFamily: this._textRenderer.getDefaultStyle().fontFamily,
+ fontWeight: this._textRenderer.getDefaultStyle().fontWeight
+ };
+
+ // adjust for expanded pools AND lanes
+ if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || isExpandedPool(element)) {
+
+ (0, _minDash.assign)(bounds, {
+ width: bbox.height,
+ height: 30 * zoom,
+ x: bbox.x - bbox.height / 2 + 15 * zoom,
+ y: mid.y - 30 * zoom / 2
+ });
+
+ (0, _minDash.assign)(style, {
+ fontSize: defaultFontSize + 'px',
+ lineHeight: defaultLineHeight,
+ paddingTop: 7 * zoom + 'px',
+ paddingBottom: 7 * zoom + 'px',
+ paddingLeft: 5 * zoom + 'px',
+ paddingRight: 5 * zoom + 'px',
+ transform: 'rotate(-90deg)'
+ });
+ }
+
+ // internal labels for tasks and collapsed call activities,
+ // sub processes and participants
+ if ((0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:CallActivity']) || isCollapsedPool(element) || isCollapsedSubProcess(element)) {
+
+ (0, _minDash.assign)(bounds, {
+ width: bbox.width,
+ height: bbox.height
+ });
+
+ (0, _minDash.assign)(style, {
+ fontSize: defaultFontSize + 'px',
+ lineHeight: defaultLineHeight,
+ paddingTop: 7 * zoom + 'px',
+ paddingBottom: 7 * zoom + 'px',
+ paddingLeft: 5 * zoom + 'px',
+ paddingRight: 5 * zoom + 'px'
+ });
+ }
+
+ // internal labels for expanded sub processes
+ if (isExpandedSubProcess(element)) {
+ (0, _minDash.assign)(bounds, {
+ width: bbox.width,
+ x: bbox.x
+ });
+
+ (0, _minDash.assign)(style, {
+ fontSize: defaultFontSize + 'px',
+ lineHeight: defaultLineHeight,
+ paddingTop: 7 * zoom + 'px',
+ paddingBottom: 7 * zoom + 'px',
+ paddingLeft: 5 * zoom + 'px',
+ paddingRight: 5 * zoom + 'px'
+ });
+ }
+
+ var width = 90 * zoom,
+ paddingTop = 7 * zoom,
+ paddingBottom = 4 * zoom;
+
+ // external labels for events, data elements, gateways and connections
+ if (target.labelTarget) {
+ (0, _minDash.assign)(bounds, {
+ width: width,
+ height: bbox.height + paddingTop + paddingBottom,
+ x: mid.x - width / 2,
+ y: bbox.y - paddingTop
+ });
+
+ (0, _minDash.assign)(style, {
+ fontSize: externalFontSize + 'px',
+ lineHeight: externalLineHeight,
+ paddingTop: paddingTop + 'px',
+ paddingBottom: paddingBottom + 'px'
+ });
+ }
+
+ // external label not yet created
+ if ((0, _LabelUtil2.isLabelExternal)(target) && !(0, _LabelUtil2.hasExternalLabel)(target) && !(0, _LabelUtil2.isLabel)(target)) {
+
+ var externalLabelMid = (0, _LabelUtil2.getExternalLabelMid)(element);
+
+ var absoluteBBox = canvas.getAbsoluteBBox({
+ x: externalLabelMid.x,
+ y: externalLabelMid.y,
+ width: 0,
+ height: 0
+ });
+
+ var height = externalFontSize + paddingTop + paddingBottom;
+
+ (0, _minDash.assign)(bounds, {
+ width: width,
+ height: height,
+ x: absoluteBBox.x - width / 2,
+ y: absoluteBBox.y - height / 2
+ });
+
+ (0, _minDash.assign)(style, {
+ fontSize: externalFontSize + 'px',
+ lineHeight: externalLineHeight,
+ paddingTop: paddingTop + 'px',
+ paddingBottom: paddingBottom + 'px'
+ });
+ }
+
+ // text annotations
+ if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
+ (0, _minDash.assign)(bounds, {
+ width: bbox.width,
+ height: bbox.height,
+ minWidth: 30 * zoom,
+ minHeight: 10 * zoom
+ });
+
+ (0, _minDash.assign)(style, {
+ textAlign: 'left',
+ paddingTop: 5 * zoom + 'px',
+ paddingBottom: 7 * zoom + 'px',
+ paddingLeft: 7 * zoom + 'px',
+ paddingRight: 5 * zoom + 'px',
+ fontSize: defaultFontSize + 'px',
+ lineHeight: defaultLineHeight
+ });
+ }
+
+ return { bounds: bounds, style: style };
+};
+
+LabelEditingProvider.prototype.update = function (element, newLabel, activeContextText, bounds) {
+
+ var newBounds, bbox;
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
+
+ bbox = this._canvas.getAbsoluteBBox(element);
+
+ newBounds = {
+ x: element.x,
+ y: element.y,
+ width: element.width / bbox.width * bounds.width,
+ height: element.height / bbox.height * bounds.height
+ };
+ }
+
+ if (isEmptyText(newLabel)) {
+ newLabel = null;
+ }
+
+ this._modeling.updateLabel(element, newLabel, newBounds);
+};
+
+// helpers //////////////////////
+
+function isCollapsedSubProcess(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && !(0, _DiUtil.isExpanded)(element);
+}
+
+function isExpandedSubProcess(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element);
+}
+
+function isCollapsedPool(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(element);
+}
+
+function isExpandedPool(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:Participant') && (0, _DiUtil.isExpanded)(element);
+}
+
+function isEmptyText(label) {
+ return !label || !label.trim();
+}
+
+},{"../../util/DiUtil":214,"../../util/LabelUtil":215,"../../util/ModelUtil":216,"../modeling/util/ModelingUtil":189,"./LabelUtil":142,"min-dash":505}],142:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.getLabel = getLabel;
+exports.setLabel = setLabel;
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+function getLabelAttr(semantic) {
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:FlowElement') || (0, _ModelUtil.is)(semantic, 'bpmn:Participant') || (0, _ModelUtil.is)(semantic, 'bpmn:Lane') || (0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:MessageFlow')) {
+
+ return 'name';
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:TextAnnotation')) {
+ return 'text';
+ }
+}
+
+function getLabel(element) {
+ var semantic = element.businessObject,
+ attr = getLabelAttr(semantic);
+
+ if (attr) {
+ return semantic[attr] || '';
+ }
+}
+
+function setLabel(element, text, isExternal) {
+ var semantic = element.businessObject,
+ attr = getLabelAttr(semantic);
+
+ if (attr) {
+ semantic[attr] = text;
+ }
+
+ return element;
+}
+
+},{"../../util/ModelUtil":216}],143:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = UpdateLabelHandler;
+
+var _LabelUtil = require('../LabelUtil');
+
+var _LabelUtil2 = require('../../../util/LabelUtil');
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var NULL_DIMENSIONS = {
+ width: 0,
+ height: 0
+};
+
+/**
+ * A handler that updates the text of a BPMN element.
+ */
+function UpdateLabelHandler(modeling, textRenderer) {
+
+ /**
+ * Set the label and return the changed elements.
+ *
+ * Element parameter can be label itself or connection (i.e. sequence flow).
+ *
+ * @param {djs.model.Base} element
+ * @param {String} text
+ */
+ function setText(element, text) {
+
+ // external label if present
+ var label = element.label || element;
+
+ var labelTarget = element.labelTarget || element;
+
+ (0, _LabelUtil.setLabel)(label, text, labelTarget !== label);
+
+ return [label, labelTarget];
+ }
+
+ function preExecute(ctx) {
+ var element = ctx.element,
+ businessObject = element.businessObject,
+ newLabel = ctx.newLabel;
+
+ if (!(0, _LabelUtil2.isLabel)(element) && (0, _LabelUtil2.isLabelExternal)(element) && !(0, _LabelUtil2.hasExternalLabel)(element) && !isEmptyText(newLabel)) {
+
+ // create label
+ var paddingTop = 7;
+
+ var labelCenter = (0, _LabelUtil2.getExternalLabelMid)(element);
+
+ labelCenter = {
+ x: labelCenter.x,
+ y: labelCenter.y + paddingTop
+ };
+
+ modeling.createLabel(element, labelCenter, {
+ id: businessObject.id + '_label',
+ businessObject: businessObject
+ });
+ }
+ }
+
+ function execute(ctx) {
+ ctx.oldLabel = (0, _LabelUtil.getLabel)(ctx.element);
+ return setText(ctx.element, ctx.newLabel);
+ }
+
+ function revert(ctx) {
+ return setText(ctx.element, ctx.oldLabel);
+ }
+
+ function postExecute(ctx) {
+ var element = ctx.element,
+ label = element.label || element,
+ newLabel = ctx.newLabel,
+ newBounds = ctx.newBounds,
+ hints = ctx.hints || {};
+
+ if ((0, _LabelUtil2.isLabel)(label) && isEmptyText(newLabel)) {
+
+ if (hints.removeShape !== false) {
+ modeling.removeShape(label, { unsetLabel: false });
+ }
+
+ return;
+ }
+
+ // ignore internal labels for elements except text annotations
+ if (!(0, _LabelUtil2.isLabelExternal)(element) && !(0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
+ return;
+ }
+
+ var bo = (0, _ModelUtil.getBusinessObject)(label);
+
+ var text = bo.name || bo.text;
+
+ // don't resize without text
+ if (!text) {
+ return;
+ }
+
+ // resize element based on label _or_ pre-defined bounds
+ if (typeof newBounds === 'undefined') {
+ newBounds = textRenderer.getExternalLabelBounds(label, text);
+ }
+
+ // setting newBounds to false or _null_ will
+ // disable the postExecute resize operation
+ if (newBounds) {
+ modeling.resizeShape(label, newBounds, NULL_DIMENSIONS);
+ }
+ }
+
+ // API
+
+ this.preExecute = preExecute;
+ this.execute = execute;
+ this.revert = revert;
+ this.postExecute = postExecute;
+}
+
+UpdateLabelHandler.$inject = ['modeling', 'textRenderer'];
+
+// helpers ///////////////////////
+
+function isEmptyText(label) {
+ return !label || !label.trim();
+}
+
+},{"../../../util/LabelUtil":215,"../../../util/ModelUtil":216,"../LabelUtil":142}],144:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _changeSupport = require('diagram-js/lib/features/change-support');
+
+var _changeSupport2 = _interopRequireDefault(_changeSupport);
+
+var _resize = require('diagram-js/lib/features/resize');
+
+var _resize2 = _interopRequireDefault(_resize);
+
+var _diagramJsDirectEditing = require('diagram-js-direct-editing');
+
+var _diagramJsDirectEditing2 = _interopRequireDefault(_diagramJsDirectEditing);
+
+var _LabelEditingProvider = require('./LabelEditingProvider');
+
+var _LabelEditingProvider2 = _interopRequireDefault(_LabelEditingProvider);
+
+var _LabelEditingPreview = require('./LabelEditingPreview');
+
+var _LabelEditingPreview2 = _interopRequireDefault(_LabelEditingPreview);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_changeSupport2.default, _resize2.default, _diagramJsDirectEditing2.default],
+ __init__: ['labelEditingProvider', 'labelEditingPreview'],
+ labelEditingProvider: ['type', _LabelEditingProvider2.default],
+ labelEditingPreview: ['type', _LabelEditingPreview2.default]
+};
+
+},{"./LabelEditingPreview":140,"./LabelEditingProvider":141,"diagram-js-direct-editing":238,"diagram-js/lib/features/change-support":271,"diagram-js/lib/features/resize":352}],145:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnFactory;
+
+var _minDash = require('min-dash');
+
+var _ModelingUtil = require('./util/ModelingUtil');
+
+function BpmnFactory(moddle) {
+ this._model = moddle;
+}
+
+BpmnFactory.$inject = ['moddle'];
+
+BpmnFactory.prototype._needsId = function (element) {
+ return (0, _ModelingUtil.isAny)(element, ['bpmn:RootElement', 'bpmn:FlowElement', 'bpmn:MessageFlow', 'bpmn:DataAssociation', 'bpmn:Artifact', 'bpmn:Participant', 'bpmn:Lane', 'bpmn:LaneSet', 'bpmn:Process', 'bpmn:Collaboration', 'bpmndi:BPMNShape', 'bpmndi:BPMNEdge', 'bpmndi:BPMNDiagram', 'bpmndi:BPMNPlane', 'bpmn:Property']);
+};
+
+BpmnFactory.prototype._ensureId = function (element) {
+
+ // generate semantic ids for elements
+ // bpmn:SequenceFlow -> SequenceFlow_ID
+ var prefix = (element.$type || '').replace(/^[^:]*:/g, '') + '_';
+
+ if (!element.id && this._needsId(element)) {
+ element.id = this._model.ids.nextPrefixed(prefix, element);
+ }
+};
+
+BpmnFactory.prototype.create = function (type, attrs) {
+ var element = this._model.create(type, attrs || {});
+
+ this._ensureId(element);
+
+ return element;
+};
+
+BpmnFactory.prototype.createDiLabel = function () {
+ return this.create('bpmndi:BPMNLabel', {
+ bounds: this.createDiBounds()
+ });
+};
+
+BpmnFactory.prototype.createDiShape = function (semantic, bounds, attrs) {
+
+ return this.create('bpmndi:BPMNShape', (0, _minDash.assign)({
+ bpmnElement: semantic,
+ bounds: this.createDiBounds(bounds)
+ }, attrs));
+};
+
+BpmnFactory.prototype.createDiBounds = function (bounds) {
+ return this.create('dc:Bounds', bounds);
+};
+
+BpmnFactory.prototype.createDiWaypoints = function (waypoints) {
+ var self = this;
+
+ return (0, _minDash.map)(waypoints, function (pos) {
+ return self.createDiWaypoint(pos);
+ });
+};
+
+BpmnFactory.prototype.createDiWaypoint = function (point) {
+ return this.create('dc:Point', (0, _minDash.pick)(point, ['x', 'y']));
+};
+
+BpmnFactory.prototype.createDiEdge = function (semantic, waypoints, attrs) {
+ return this.create('bpmndi:BPMNEdge', (0, _minDash.assign)({
+ bpmnElement: semantic
+ }, attrs));
+};
+
+BpmnFactory.prototype.createDiPlane = function (semantic) {
+ return this.create('bpmndi:BPMNPlane', {
+ bpmnElement: semantic
+ });
+};
+
+},{"./util/ModelingUtil":189,"min-dash":505}],146:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnLayouter;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _minDash = require('min-dash');
+
+var _BaseLayouter = require('diagram-js/lib/layout/BaseLayouter');
+
+var _BaseLayouter2 = _interopRequireDefault(_BaseLayouter);
+
+var _ManhattanLayout = require('diagram-js/lib/layout/ManhattanLayout');
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _DiUtil = require('../../util/DiUtil');
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function BpmnLayouter() {}
+
+(0, _inherits2.default)(BpmnLayouter, _BaseLayouter2.default);
+
+BpmnLayouter.prototype.layoutConnection = function (connection, hints) {
+ hints = hints || {};
+
+ var source = connection.source,
+ target = connection.target,
+ waypoints = connection.waypoints,
+ start = hints.connectionStart,
+ end = hints.connectionEnd;
+
+ var manhattanOptions, updatedWaypoints;
+
+ if (!start) {
+ start = getConnectionDocking(waypoints && waypoints[0], source);
+ }
+
+ if (!end) {
+ end = getConnectionDocking(waypoints && waypoints[waypoints.length - 1], target);
+ }
+
+ // TODO(nikku): support vertical modeling
+ // and invert preferredLayouts accordingly
+
+ if ((0, _ModelUtil.is)(connection, 'bpmn:Association') || (0, _ModelUtil.is)(connection, 'bpmn:DataAssociation')) {
+
+ if (waypoints && !isCompensationAssociation(connection)) {
+ return [].concat([start], waypoints.slice(1, -1), [end]);
+ }
+ }
+
+ // manhattan layout sequence / message flows
+ if ((0, _ModelUtil.is)(connection, 'bpmn:MessageFlow')) {
+ manhattanOptions = getMessageFlowManhattanOptions(source, target);
+ } else
+
+ // layout all connection between flow elements h:h,
+ //
+ // except for
+ //
+ // (1) outgoing of BoundaryEvents -> layout based on attach orientation and target orientation
+ // (2) incoming / outgoing of Gateway -> v:h (outgoing), h:v (incoming)
+ // (3) loops from / to the same element
+ //
+ if ((0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow') || isCompensationAssociation(connection)) {
+
+ if (source === target) {
+ manhattanOptions = {
+ preferredLayouts: ['b:l']
+ };
+ } else if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) {
+
+ manhattanOptions = {
+ preferredLayouts: getBoundaryEventPreferredLayouts(source, target)
+ };
+ } else if ((0, _ModelUtil.is)(source, 'bpmn:Gateway')) {
+
+ manhattanOptions = {
+ preferredLayouts: ['v:h']
+ };
+ } else if ((0, _ModelUtil.is)(target, 'bpmn:Gateway')) {
+
+ manhattanOptions = {
+ preferredLayouts: ['h:v']
+ };
+ } else {
+ manhattanOptions = {
+ preferredLayouts: ['h:h']
+ };
+ }
+ }
+
+ if (manhattanOptions) {
+
+ manhattanOptions = (0, _minDash.assign)(manhattanOptions, hints);
+
+ updatedWaypoints = (0, _ManhattanLayout.withoutRedundantPoints)((0, _ManhattanLayout.repairConnection)(source, target, start, end, waypoints, manhattanOptions));
+ }
+
+ return updatedWaypoints || [start, end];
+};
+
+function getAttachOrientation(attachedElement) {
+
+ var hostElement = attachedElement.host,
+ padding = -10;
+
+ return (0, _LayoutUtil.getOrientation)((0, _LayoutUtil.getMid)(attachedElement), hostElement, padding);
+}
+
+function getMessageFlowManhattanOptions(source, target) {
+ return {
+ preferredLayouts: ['straight', 'v:v'],
+ preserveDocking: getMessageFlowPreserveDocking(source, target)
+ };
+}
+
+function getMessageFlowPreserveDocking(source, target) {
+
+ // (1) docking element connected to participant has precedence
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:Participant')) {
+ return 'source';
+ }
+
+ if ((0, _ModelUtil.is)(source, 'bpmn:Participant')) {
+ return 'target';
+ }
+
+ // (2) docking element connected to expanded sub-process has precedence
+
+ if (isExpandedSubProcess(target)) {
+ return 'source';
+ }
+
+ if (isExpandedSubProcess(source)) {
+ return 'target';
+ }
+
+ // (3) docking event has precedence
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:Event')) {
+ return 'target';
+ }
+
+ if ((0, _ModelUtil.is)(source, 'bpmn:Event')) {
+ return 'source';
+ }
+
+ return null;
+}
+
+function getConnectionDocking(point, shape) {
+ return point ? point.original || point : (0, _LayoutUtil.getMid)(shape);
+}
+
+function isCompensationAssociation(connection) {
+
+ var source = connection.source,
+ target = connection.target;
+
+ return (0, _ModelUtil.is)(target, 'bpmn:Activity') && (0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent') && target.businessObject.isForCompensation;
+}
+
+function isExpandedSubProcess(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element);
+}
+
+function isSame(a, b) {
+ return a === b;
+}
+
+function isAnyOrientation(orientation, orientations) {
+ return orientations.indexOf(orientation) !== -1;
+}
+
+var oppositeOrientationMapping = {
+ 'top': 'bottom',
+ 'top-right': 'bottom-left',
+ 'top-left': 'bottom-right',
+ 'right': 'left',
+ 'bottom': 'top',
+ 'bottom-right': 'top-left',
+ 'bottom-left': 'top-right',
+ 'left': 'right'
+};
+
+var orientationDirectionMapping = {
+ top: 't',
+ right: 'r',
+ bottom: 'b',
+ left: 'l'
+};
+
+function getHorizontalOrientation(orientation) {
+ var matches = /right|left/.exec(orientation);
+
+ return matches && matches[0];
+}
+
+function getVerticalOrientation(orientation) {
+ var matches = /top|bottom/.exec(orientation);
+
+ return matches && matches[0];
+}
+
+function isOppositeOrientation(a, b) {
+ return oppositeOrientationMapping[a] === b;
+}
+
+function isOppositeHorizontalOrientation(a, b) {
+ var horizontalOrientation = getHorizontalOrientation(a);
+
+ var oppositeHorizontalOrientation = oppositeOrientationMapping[horizontalOrientation];
+
+ return b.indexOf(oppositeHorizontalOrientation) !== -1;
+}
+
+function isOppositeVerticalOrientation(a, b) {
+ var verticalOrientation = getVerticalOrientation(a);
+
+ var oppositeVerticalOrientation = oppositeOrientationMapping[verticalOrientation];
+
+ return b.indexOf(oppositeVerticalOrientation) !== -1;
+}
+
+function isHorizontalOrientation(orientation) {
+ return orientation === 'right' || orientation === 'left';
+}
+
+function getBoundaryEventPreferredLayouts(source, target) {
+ var sourceMid = (0, _LayoutUtil.getMid)(source),
+ targetMid = (0, _LayoutUtil.getMid)(target),
+ attachOrientation = getAttachOrientation(source),
+ sourceLayout,
+ targetlayout;
+
+ var isLoop = isSame(source.host, target);
+
+ var attachedToSide = isAnyOrientation(attachOrientation, ['top', 'right', 'bottom', 'left']);
+
+ var isHorizontalAttachOrientation = isHorizontalOrientation(attachOrientation);
+
+ var targetOrientation = (0, _LayoutUtil.getOrientation)(targetMid, sourceMid, {
+ x: source.width / 2 + target.width / 2,
+ y: source.height / 2 + target.height / 2
+ });
+
+ // source layout
+
+ // attached to either top, right, bottom or left side
+ if (attachedToSide) {
+
+ sourceLayout = orientationDirectionMapping[isHorizontalAttachOrientation ? getHorizontalOrientation(attachOrientation) : getVerticalOrientation(attachOrientation)];
+ } else
+
+ // attached to either top-right, top-left, bottom-right or bottom-left corner
+ {
+
+ // loop, same vertical or opposite horizontal orientation
+ if (isLoop || isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) || isOppositeOrientation(getHorizontalOrientation(attachOrientation), getHorizontalOrientation(targetOrientation))) {
+ sourceLayout = orientationDirectionMapping[getVerticalOrientation(attachOrientation)];
+ } else {
+ sourceLayout = orientationDirectionMapping[getHorizontalOrientation(attachOrientation)];
+ }
+ }
+
+ // target layout
+
+ // attached to either top, right, bottom or left side
+ if (attachedToSide) {
+
+ // loop or opposite horizontal/vertical orientation
+ if (isLoop || (isHorizontalAttachOrientation ? isOppositeHorizontalOrientation(attachOrientation, targetOrientation) : isOppositeVerticalOrientation(attachOrientation, targetOrientation))) {
+ targetlayout = isHorizontalAttachOrientation ? 'h' : 'v';
+ } else {
+ targetlayout = isHorizontalAttachOrientation ? 'v' : 'h';
+ }
+ } else
+
+ // attached to either top-right, top-left, bottom-right or bottom-left corner
+ {
+
+ // orientation is 'right', 'left'
+ // or same vertical orientation but also 'right' or 'left'
+ if (isHorizontalOrientation(targetOrientation) || isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) && getHorizontalOrientation(targetOrientation)) {
+ targetlayout = 'h';
+ } else {
+ targetlayout = 'v';
+ }
+ }
+
+ return [sourceLayout + ':' + targetlayout];
+}
+
+},{"../../util/DiUtil":214,"../../util/ModelUtil":216,"diagram-js/lib/layout/BaseLayouter":378,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/layout/ManhattanLayout":381,"inherits":415,"min-dash":505}],147:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnUpdater;
+
+var _minDash = require('min-dash');
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _Collections = require('diagram-js/lib/util/Collections');
+
+var _model = require('diagram-js/lib/model');
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A handler responsible for updating the underlying BPMN 2.0 XML + DI
+ * once changes on the diagram happen
+ */
+function BpmnUpdater(eventBus, bpmnFactory, connectionDocking, translate) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ this._bpmnFactory = bpmnFactory;
+ this._translate = translate;
+
+ var self = this;
+
+ // connection cropping //////////////////////
+
+ // crop connection ends during create/update
+ function cropConnection(e) {
+ var context = e.context,
+ connection;
+
+ if (!context.cropped) {
+ connection = context.connection;
+ connection.waypoints = connectionDocking.getCroppedWaypoints(connection);
+ context.cropped = true;
+ }
+ }
+
+ this.executed(['connection.layout', 'connection.create', 'connection.reconnectEnd', 'connection.reconnectStart'], cropConnection);
+
+ this.reverted(['connection.layout'], function (e) {
+ delete e.context.cropped;
+ });
+
+ // BPMN + DI update //////////////////////
+
+
+ // update parent
+ function updateParent(e) {
+ var context = e.context;
+
+ self.updateParent(context.shape || context.connection, context.oldParent);
+ }
+
+ function reverseUpdateParent(e) {
+ var context = e.context;
+
+ var element = context.shape || context.connection,
+
+ // oldParent is the (old) new parent, because we are undoing
+ oldParent = context.parent || context.newParent;
+
+ self.updateParent(element, oldParent);
+ }
+
+ this.executed(['shape.move', 'shape.create', 'shape.delete', 'connection.create', 'connection.move', 'connection.delete'], ifBpmn(updateParent));
+
+ this.reverted(['shape.move', 'shape.create', 'shape.delete', 'connection.create', 'connection.move', 'connection.delete'], ifBpmn(reverseUpdateParent));
+
+ /*
+ * ## Updating Parent
+ *
+ * When morphing a Process into a Collaboration or vice-versa,
+ * make sure that both the *semantic* and *di* parent of each element
+ * is updated.
+ *
+ */
+ function updateRoot(event) {
+ var context = event.context,
+ oldRoot = context.oldRoot,
+ children = oldRoot.children;
+
+ (0, _minDash.forEach)(children, function (child) {
+ if ((0, _ModelUtil.is)(child, 'bpmn:BaseElement')) {
+ self.updateParent(child);
+ }
+ });
+ }
+
+ this.executed(['canvas.updateRoot'], updateRoot);
+ this.reverted(['canvas.updateRoot'], updateRoot);
+
+ // update bounds
+ function updateBounds(e) {
+ var shape = e.context.shape;
+
+ if (!(0, _ModelUtil.is)(shape, 'bpmn:BaseElement')) {
+ return;
+ }
+
+ self.updateBounds(shape);
+ }
+
+ this.executed(['shape.move', 'shape.create', 'shape.resize'], ifBpmn(function (event) {
+
+ // exclude labels because they're handled separately during shape.changed
+ if (event.context.shape.type === 'label') {
+ return;
+ }
+
+ updateBounds(event);
+ }));
+
+ this.reverted(['shape.move', 'shape.create', 'shape.resize'], ifBpmn(function (event) {
+
+ // exclude labels because they're handled separately during shape.changed
+ if (event.context.shape.type === 'label') {
+ return;
+ }
+
+ updateBounds(event);
+ }));
+
+ // Handle labels separately. This is necessary, because the label bounds have to be updated
+ // every time its shape changes, not only on move, create and resize.
+ eventBus.on('shape.changed', function (event) {
+ if (event.element.type === 'label') {
+ updateBounds({ context: { shape: event.element } });
+ }
+ });
+
+ // attach / detach connection
+ function updateConnection(e) {
+ self.updateConnection(e.context);
+ }
+
+ this.executed(['connection.create', 'connection.move', 'connection.delete', 'connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(updateConnection));
+
+ this.reverted(['connection.create', 'connection.move', 'connection.delete', 'connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(updateConnection));
+
+ // update waypoints
+ function updateConnectionWaypoints(e) {
+ self.updateConnectionWaypoints(e.context.connection);
+ }
+
+ this.executed(['connection.layout', 'connection.move', 'connection.updateWaypoints', 'connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(updateConnectionWaypoints));
+
+ this.reverted(['connection.layout', 'connection.move', 'connection.updateWaypoints', 'connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(updateConnectionWaypoints));
+
+ // update Default & Conditional flows
+ this.executed(['connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(function (e) {
+ var context = e.context,
+ connection = context.connection,
+ businessObject = (0, _ModelUtil.getBusinessObject)(connection),
+ oldSource = (0, _ModelUtil.getBusinessObject)(context.oldSource),
+ oldTarget = (0, _ModelUtil.getBusinessObject)(context.oldTarget),
+ newSource = (0, _ModelUtil.getBusinessObject)(connection.source),
+ newTarget = (0, _ModelUtil.getBusinessObject)(connection.target);
+
+ if (oldSource === newSource || oldTarget === newTarget) {
+ return;
+ }
+
+ // on reconnectStart -> default flow
+ if (oldSource && oldSource.default === businessObject) {
+ context.default = oldSource.default;
+ oldSource.default = undefined;
+ }
+
+ // on reconnectEnd -> default flow
+ if (businessObject.sourceRef && businessObject.sourceRef.default && !((0, _ModelUtil.is)(newTarget, 'bpmn:Activity') || (0, _ModelUtil.is)(newTarget, 'bpmn:EndEvent') || (0, _ModelUtil.is)(newTarget, 'bpmn:Gateway') || (0, _ModelUtil.is)(newTarget, 'bpmn:IntermediateThrowEvent'))) {
+ context.default = businessObject.sourceRef.default;
+ businessObject.sourceRef.default = undefined;
+ }
+
+ // on reconnectStart -> conditional flow
+ if (oldSource && businessObject.conditionExpression && !((0, _ModelUtil.is)(newSource, 'bpmn:Activity') || (0, _ModelUtil.is)(newSource, 'bpmn:Gateway'))) {
+ context.conditionExpression = businessObject.conditionExpression;
+ businessObject.conditionExpression = undefined;
+ }
+
+ // on reconnectEnd -> conditional flow
+ if (oldTarget && businessObject.conditionExpression && !((0, _ModelUtil.is)(newTarget, 'bpmn:Activity') || (0, _ModelUtil.is)(newTarget, 'bpmn:EndEvent') || (0, _ModelUtil.is)(newTarget, 'bpmn:Gateway') || (0, _ModelUtil.is)(newTarget, 'bpmn:IntermediateThrowEvent'))) {
+ context.conditionExpression = businessObject.conditionExpression;
+ businessObject.conditionExpression = undefined;
+ }
+ }));
+
+ this.reverted(['connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(function (e) {
+ var context = e.context,
+ connection = context.connection,
+ businessObject = (0, _ModelUtil.getBusinessObject)(connection),
+ newSource = (0, _ModelUtil.getBusinessObject)(connection.source);
+
+ // default flow
+ if (context.default) {
+ if ((0, _ModelUtil.is)(newSource, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(newSource, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(newSource, 'bpmn:Activity')) {
+ newSource.default = context.default;
+ }
+ }
+
+ // conditional flow
+ if (context.conditionExpression && (0, _ModelUtil.is)(newSource, 'bpmn:Activity')) {
+ businessObject.conditionExpression = context.conditionExpression;
+ }
+ }));
+
+ // update attachments
+ function updateAttachment(e) {
+ self.updateAttachment(e.context);
+ }
+
+ this.executed(['element.updateAttachment'], ifBpmn(updateAttachment));
+ this.reverted(['element.updateAttachment'], ifBpmn(updateAttachment));
+}
+
+(0, _inherits2.default)(BpmnUpdater, _CommandInterceptor2.default);
+
+BpmnUpdater.$inject = ['eventBus', 'bpmnFactory', 'connectionDocking', 'translate'];
+
+// implementation //////////////////////
+
+BpmnUpdater.prototype.updateAttachment = function (context) {
+
+ var shape = context.shape,
+ businessObject = shape.businessObject,
+ host = shape.host;
+
+ businessObject.attachedToRef = host && host.businessObject;
+};
+
+BpmnUpdater.prototype.updateParent = function (element, oldParent) {
+ // do not update BPMN 2.0 label parent
+ if (element instanceof _model.Label) {
+ return;
+ }
+
+ // data stores in collaborations are handled seperately by DataStoreBehavior
+ if ((0, _ModelUtil.is)(element, 'bpmn:DataStoreReference') && element.parent && (0, _ModelUtil.is)(element.parent, 'bpmn:Collaboration')) {
+ return;
+ }
+
+ var parentShape = element.parent;
+
+ var businessObject = element.businessObject,
+ parentBusinessObject = parentShape && parentShape.businessObject,
+ parentDi = parentBusinessObject && parentBusinessObject.di;
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:FlowNode')) {
+ this.updateFlowNodeRefs(businessObject, parentBusinessObject, oldParent && oldParent.businessObject);
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:DataOutputAssociation')) {
+ if (element.source) {
+ parentBusinessObject = element.source.businessObject;
+ } else {
+ parentBusinessObject = null;
+ }
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:DataInputAssociation')) {
+ if (element.target) {
+ parentBusinessObject = element.target.businessObject;
+ } else {
+ parentBusinessObject = null;
+ }
+ }
+
+ this.updateSemanticParent(businessObject, parentBusinessObject);
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:DataObjectReference') && businessObject.dataObjectRef) {
+ this.updateSemanticParent(businessObject.dataObjectRef, parentBusinessObject);
+ }
+
+ this.updateDiParent(businessObject.di, parentDi);
+};
+
+BpmnUpdater.prototype.updateBounds = function (shape) {
+
+ var di = shape.businessObject.di;
+
+ var target = shape instanceof _model.Label ? this._getLabel(di) : di;
+
+ var bounds = target.bounds;
+
+ if (!bounds) {
+ bounds = this._bpmnFactory.createDiBounds();
+ target.set('bounds', bounds);
+ }
+
+ (0, _minDash.assign)(bounds, {
+ x: shape.x,
+ y: shape.y,
+ width: shape.width,
+ height: shape.height
+ });
+};
+
+BpmnUpdater.prototype.updateFlowNodeRefs = function (businessObject, newContainment, oldContainment) {
+
+ if (oldContainment === newContainment) {
+ return;
+ }
+
+ var oldRefs, newRefs;
+
+ if ((0, _ModelUtil.is)(oldContainment, 'bpmn:Lane')) {
+ oldRefs = oldContainment.get('flowNodeRef');
+ (0, _Collections.remove)(oldRefs, businessObject);
+ }
+
+ if ((0, _ModelUtil.is)(newContainment, 'bpmn:Lane')) {
+ newRefs = newContainment.get('flowNodeRef');
+ (0, _Collections.add)(newRefs, businessObject);
+ }
+};
+
+// update existing sourceElement and targetElement di information
+BpmnUpdater.prototype.updateDiConnection = function (di, newSource, newTarget) {
+
+ if (di.sourceElement && di.sourceElement.bpmnElement !== newSource) {
+ di.sourceElement = newSource && newSource.di;
+ }
+
+ if (di.targetElement && di.targetElement.bpmnElement !== newTarget) {
+ di.targetElement = newTarget && newTarget.di;
+ }
+};
+
+BpmnUpdater.prototype.updateDiParent = function (di, parentDi) {
+
+ if (parentDi && !(0, _ModelUtil.is)(parentDi, 'bpmndi:BPMNPlane')) {
+ parentDi = parentDi.$parent;
+ }
+
+ if (di.$parent === parentDi) {
+ return;
+ }
+
+ var planeElements = (parentDi || di.$parent).get('planeElement');
+
+ if (parentDi) {
+ planeElements.push(di);
+ di.$parent = parentDi;
+ } else {
+ (0, _Collections.remove)(planeElements, di);
+ di.$parent = null;
+ }
+};
+
+function getDefinitions(element) {
+ while (element && !(0, _ModelUtil.is)(element, 'bpmn:Definitions')) {
+ element = element.$parent;
+ }
+
+ return element;
+}
+
+BpmnUpdater.prototype.getLaneSet = function (container) {
+
+ var laneSet, laneSets;
+
+ // bpmn:Lane
+ if ((0, _ModelUtil.is)(container, 'bpmn:Lane')) {
+ laneSet = container.childLaneSet;
+
+ if (!laneSet) {
+ laneSet = this._bpmnFactory.create('bpmn:LaneSet');
+ container.childLaneSet = laneSet;
+ laneSet.$parent = container;
+ }
+
+ return laneSet;
+ }
+
+ // bpmn:Participant
+ if ((0, _ModelUtil.is)(container, 'bpmn:Participant')) {
+ container = container.processRef;
+ }
+
+ // bpmn:FlowElementsContainer
+ laneSets = container.get('laneSets');
+ laneSet = laneSets[0];
+
+ if (!laneSet) {
+ laneSet = this._bpmnFactory.create('bpmn:LaneSet');
+ laneSet.$parent = container;
+ laneSets.push(laneSet);
+ }
+
+ return laneSet;
+};
+
+BpmnUpdater.prototype.updateSemanticParent = function (businessObject, newParent, visualParent) {
+
+ var containment,
+ translate = this._translate;
+
+ if (businessObject.$parent === newParent) {
+ return;
+ }
+
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:Lane')) {
+
+ if (newParent) {
+ newParent = this.getLaneSet(newParent);
+ }
+
+ containment = 'lanes';
+ } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowElement')) {
+
+ if (newParent) {
+
+ if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant')) {
+ newParent = newParent.processRef;
+ } else if ((0, _ModelUtil.is)(newParent, 'bpmn:Lane')) {
+ do {
+ // unwrap Lane -> LaneSet -> (Lane | FlowElementsContainer)
+ newParent = newParent.$parent.$parent;
+ } while ((0, _ModelUtil.is)(newParent, 'bpmn:Lane'));
+ }
+ }
+
+ containment = 'flowElements';
+ } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:Artifact')) {
+
+ while (newParent && !(0, _ModelUtil.is)(newParent, 'bpmn:Process') && !(0, _ModelUtil.is)(newParent, 'bpmn:SubProcess') && !(0, _ModelUtil.is)(newParent, 'bpmn:Collaboration')) {
+
+ if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant')) {
+ newParent = newParent.processRef;
+ break;
+ } else {
+ newParent = newParent.$parent;
+ }
+ }
+
+ containment = 'artifacts';
+ } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:MessageFlow')) {
+ containment = 'messageFlows';
+ } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:Participant')) {
+ containment = 'participants';
+
+ // make sure the participants process is properly attached / detached
+ // from the XML document
+
+ var process = businessObject.processRef,
+ definitions;
+
+ if (process) {
+ definitions = getDefinitions(businessObject.$parent || newParent);
+
+ if (businessObject.$parent) {
+ (0, _Collections.remove)(definitions.get('rootElements'), process);
+ process.$parent = null;
+ }
+
+ if (newParent) {
+ (0, _Collections.add)(definitions.get('rootElements'), process);
+ process.$parent = definitions;
+ }
+ }
+ } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataOutputAssociation')) {
+ containment = 'dataOutputAssociations';
+ } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInputAssociation')) {
+ containment = 'dataInputAssociations';
+ }
+
+ if (!containment) {
+ throw new Error(translate('no parent for {element} in {parent}', {
+ element: businessObject.id,
+ parent: newParent.id
+ }));
+ }
+
+ var children;
+
+ if (businessObject.$parent) {
+ // remove from old parent
+ children = businessObject.$parent.get(containment);
+ (0, _Collections.remove)(children, businessObject);
+ }
+
+ if (!newParent) {
+ businessObject.$parent = null;
+ } else {
+ // add to new parent
+ children = newParent.get(containment);
+ children.push(businessObject);
+ businessObject.$parent = newParent;
+ }
+
+ if (visualParent) {
+ var diChildren = visualParent.get(containment);
+
+ (0, _Collections.remove)(children, businessObject);
+
+ if (newParent) {
+
+ if (!diChildren) {
+ diChildren = [];
+ newParent.set(containment, diChildren);
+ }
+
+ diChildren.push(businessObject);
+ }
+ }
+};
+
+BpmnUpdater.prototype.updateConnectionWaypoints = function (connection) {
+ connection.businessObject.di.set('waypoint', this._bpmnFactory.createDiWaypoints(connection.waypoints));
+};
+
+BpmnUpdater.prototype.updateConnection = function (context) {
+
+ var connection = context.connection,
+ businessObject = (0, _ModelUtil.getBusinessObject)(connection),
+ newSource = (0, _ModelUtil.getBusinessObject)(connection.source),
+ newTarget = (0, _ModelUtil.getBusinessObject)(connection.target),
+ visualParent;
+
+ if (!(0, _ModelUtil.is)(businessObject, 'bpmn:DataAssociation')) {
+
+ var inverseSet = (0, _ModelUtil.is)(businessObject, 'bpmn:SequenceFlow');
+
+ if (businessObject.sourceRef !== newSource) {
+ if (inverseSet) {
+ (0, _Collections.remove)(businessObject.sourceRef && businessObject.sourceRef.get('outgoing'), businessObject);
+
+ if (newSource && newSource.get('outgoing')) {
+ newSource.get('outgoing').push(businessObject);
+ }
+ }
+
+ businessObject.sourceRef = newSource;
+ }
+
+ if (businessObject.targetRef !== newTarget) {
+ if (inverseSet) {
+ (0, _Collections.remove)(businessObject.targetRef && businessObject.targetRef.get('incoming'), businessObject);
+
+ if (newTarget && newTarget.get('incoming')) {
+ newTarget.get('incoming').push(businessObject);
+ }
+ }
+
+ businessObject.targetRef = newTarget;
+ }
+ } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInputAssociation')) {
+ // handle obnoxious isMsome sourceRef
+ businessObject.get('sourceRef')[0] = newSource;
+
+ visualParent = context.parent || context.newParent || newTarget;
+
+ this.updateSemanticParent(businessObject, newTarget, parent.businessObject);
+ } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataOutputAssociation')) {
+ visualParent = context.parent || context.newParent || newSource;
+
+ this.updateSemanticParent(businessObject, newSource, visualParent);
+
+ // targetRef = new target
+ businessObject.targetRef = newTarget;
+ }
+
+ this.updateConnectionWaypoints(connection);
+
+ this.updateDiConnection(businessObject.di, newSource, newTarget);
+};
+
+// helpers //////////////////////
+
+BpmnUpdater.prototype._getLabel = function (di) {
+ if (!di.label) {
+ di.label = this._bpmnFactory.createDiLabel();
+ }
+
+ return di.label;
+};
+
+/**
+ * Make sure the event listener is only called
+ * if the touched element is a BPMN element.
+ *
+ * @param {Function} fn
+ * @return {Function} guarded function
+ */
+function ifBpmn(fn) {
+
+ return function (event) {
+
+ var context = event.context,
+ element = context.shape || context.connection;
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:BaseElement')) {
+ fn(event);
+ }
+ };
+}
+
+},{"../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/model":382,"diagram-js/lib/util/Collections":393,"inherits":415,"min-dash":505}],148:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ElementFactory;
+
+var _minDash = require('min-dash');
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _DiUtil = require('../../util/DiUtil');
+
+var _ElementFactory = require('diagram-js/lib/core/ElementFactory');
+
+var _ElementFactory2 = _interopRequireDefault(_ElementFactory);
+
+var _LabelUtil = require('../../util/LabelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A bpmn-aware factory for diagram-js shapes
+ */
+function ElementFactory(bpmnFactory, moddle, translate) {
+ _ElementFactory2.default.call(this);
+
+ this._bpmnFactory = bpmnFactory;
+ this._moddle = moddle;
+ this._translate = translate;
+}
+
+(0, _inherits2.default)(ElementFactory, _ElementFactory2.default);
+
+ElementFactory.$inject = ['bpmnFactory', 'moddle', 'translate'];
+
+ElementFactory.prototype.baseCreate = _ElementFactory2.default.prototype.create;
+
+ElementFactory.prototype.create = function (elementType, attrs) {
+ // no special magic for labels,
+ // we assume their businessObjects have already been created
+ // and wired via attrs
+ if (elementType === 'label') {
+ return this.baseCreate(elementType, (0, _minDash.assign)({ type: 'label' }, _LabelUtil.DEFAULT_LABEL_SIZE, attrs));
+ }
+
+ return this.createBpmnElement(elementType, attrs);
+};
+
+ElementFactory.prototype.createBpmnElement = function (elementType, attrs) {
+ var size,
+ translate = this._translate;
+
+ attrs = attrs || {};
+
+ var businessObject = attrs.businessObject;
+
+ if (!businessObject) {
+ if (!attrs.type) {
+ throw new Error(translate('no shape type specified'));
+ }
+
+ businessObject = this._bpmnFactory.create(attrs.type);
+ }
+
+ if (!businessObject.di) {
+ if (elementType === 'root') {
+ businessObject.di = this._bpmnFactory.createDiPlane(businessObject, [], {
+ id: businessObject.id + '_di'
+ });
+ } else if (elementType === 'connection') {
+ businessObject.di = this._bpmnFactory.createDiEdge(businessObject, [], {
+ id: businessObject.id + '_di'
+ });
+ } else {
+ businessObject.di = this._bpmnFactory.createDiShape(businessObject, {}, {
+ id: businessObject.id + '_di'
+ });
+ }
+ }
+
+ if (attrs.colors) {
+ (0, _minDash.assign)(businessObject.di, attrs.colors);
+
+ delete attrs.colors;
+ }
+
+ applyAttributes(businessObject, attrs, ['processRef', 'isInterrupting', 'associationDirection', 'isForCompensation']);
+
+ if (attrs.isExpanded) {
+ applyAttribute(businessObject.di, attrs, 'isExpanded');
+ }
+
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:ExclusiveGateway')) {
+ businessObject.di.isMarkerVisible = true;
+ }
+
+ var eventDefinitions, newEventDefinition;
+
+ if (attrs.eventDefinitionType) {
+ eventDefinitions = businessObject.get('eventDefinitions') || [];
+ newEventDefinition = this._moddle.create(attrs.eventDefinitionType);
+
+ if (attrs.eventDefinitionType === 'bpmn:ConditionalEventDefinition') {
+ newEventDefinition.condition = this._moddle.create('bpmn:FormalExpression');
+ }
+
+ eventDefinitions.push(newEventDefinition);
+
+ newEventDefinition.$parent = businessObject;
+ businessObject.eventDefinitions = eventDefinitions;
+
+ delete attrs.eventDefinitionType;
+ }
+
+ size = this._getDefaultSize(businessObject);
+
+ attrs = (0, _minDash.assign)({
+ businessObject: businessObject,
+ id: businessObject.id
+ }, size, attrs);
+
+ return this.baseCreate(elementType, attrs);
+};
+
+ElementFactory.prototype._getDefaultSize = function (semantic) {
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:SubProcess')) {
+
+ if ((0, _DiUtil.isExpanded)(semantic)) {
+ return { width: 350, height: 200 };
+ } else {
+ return { width: 100, height: 80 };
+ }
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:Task')) {
+ return { width: 100, height: 80 };
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:Gateway')) {
+ return { width: 50, height: 50 };
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:Event')) {
+ return { width: 36, height: 36 };
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:Participant')) {
+ if (!(0, _DiUtil.isExpanded)(semantic)) {
+ return { width: 400, height: 100 };
+ } else {
+ return { width: 600, height: 250 };
+ }
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:Lane')) {
+ return { width: 400, height: 100 };
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:DataObjectReference')) {
+ return { width: 36, height: 50 };
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference')) {
+ return { width: 50, height: 50 };
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:TextAnnotation')) {
+ return { width: 100, height: 30 };
+ }
+
+ return { width: 100, height: 80 };
+};
+
+ElementFactory.prototype.createParticipantShape = function (collapsed) {
+
+ var attrs = { type: 'bpmn:Participant' };
+
+ if (!collapsed) {
+ attrs.processRef = this._bpmnFactory.create('bpmn:Process');
+ }
+
+ return this.createShape(attrs);
+};
+
+// helpers //////////////////////
+
+/**
+ * Apply attributes from a map to the given element,
+ * remove attribute from the map on application.
+ *
+ * @param {Base} element
+ * @param {Object} attrs (in/out map of attributes)
+ * @param {Array} attributeNames name of attributes to apply
+ */
+function applyAttributes(element, attrs, attributeNames) {
+
+ (0, _minDash.forEach)(attributeNames, function (property) {
+ if (attrs[property] !== undefined) {
+ applyAttribute(element, attrs, property);
+ }
+ });
+}
+
+/**
+ * Apply named property to element and drain it from the attrs
+ * collection.
+ *
+ * @param {Base} element
+ * @param {Object} attrs (in/out map of attributes)
+ * @param {String} attributeName to apply
+ */
+function applyAttribute(element, attrs, attributeName) {
+ element[attributeName] = attrs[attributeName];
+
+ delete attrs[attributeName];
+}
+
+},{"../../util/DiUtil":214,"../../util/LabelUtil":215,"../../util/ModelUtil":216,"diagram-js/lib/core/ElementFactory":247,"inherits":415,"min-dash":505}],149:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Modeling;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _Modeling = require('diagram-js/lib/features/modeling/Modeling');
+
+var _Modeling2 = _interopRequireDefault(_Modeling);
+
+var _UpdatePropertiesHandler = require('./cmd/UpdatePropertiesHandler');
+
+var _UpdatePropertiesHandler2 = _interopRequireDefault(_UpdatePropertiesHandler);
+
+var _UpdateCanvasRootHandler = require('./cmd/UpdateCanvasRootHandler');
+
+var _UpdateCanvasRootHandler2 = _interopRequireDefault(_UpdateCanvasRootHandler);
+
+var _AddLaneHandler = require('./cmd/AddLaneHandler');
+
+var _AddLaneHandler2 = _interopRequireDefault(_AddLaneHandler);
+
+var _SplitLaneHandler = require('./cmd/SplitLaneHandler');
+
+var _SplitLaneHandler2 = _interopRequireDefault(_SplitLaneHandler);
+
+var _ResizeLaneHandler = require('./cmd/ResizeLaneHandler');
+
+var _ResizeLaneHandler2 = _interopRequireDefault(_ResizeLaneHandler);
+
+var _UpdateFlowNodeRefsHandler = require('./cmd/UpdateFlowNodeRefsHandler');
+
+var _UpdateFlowNodeRefsHandler2 = _interopRequireDefault(_UpdateFlowNodeRefsHandler);
+
+var _IdClaimHandler = require('./cmd/IdClaimHandler');
+
+var _IdClaimHandler2 = _interopRequireDefault(_IdClaimHandler);
+
+var _SetColorHandler = require('./cmd/SetColorHandler');
+
+var _SetColorHandler2 = _interopRequireDefault(_SetColorHandler);
+
+var _UpdateLabelHandler = require('../label-editing/cmd/UpdateLabelHandler');
+
+var _UpdateLabelHandler2 = _interopRequireDefault(_UpdateLabelHandler);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * BPMN 2.0 modeling features activator
+ *
+ * @param {EventBus} eventBus
+ * @param {ElementFactory} elementFactory
+ * @param {CommandStack} commandStack
+ * @param {BpmnRules} bpmnRules
+ */
+function Modeling(eventBus, elementFactory, commandStack, bpmnRules) {
+
+ _Modeling2.default.call(this, eventBus, elementFactory, commandStack);
+
+ this._bpmnRules = bpmnRules;
+}
+
+(0, _inherits2.default)(Modeling, _Modeling2.default);
+
+Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack', 'bpmnRules'];
+
+Modeling.prototype.getHandlers = function () {
+ var handlers = _Modeling2.default.prototype.getHandlers.call(this);
+
+ handlers['element.updateProperties'] = _UpdatePropertiesHandler2.default;
+ handlers['canvas.updateRoot'] = _UpdateCanvasRootHandler2.default;
+ handlers['lane.add'] = _AddLaneHandler2.default;
+ handlers['lane.resize'] = _ResizeLaneHandler2.default;
+ handlers['lane.split'] = _SplitLaneHandler2.default;
+ handlers['lane.updateRefs'] = _UpdateFlowNodeRefsHandler2.default;
+ handlers['id.updateClaim'] = _IdClaimHandler2.default;
+ handlers['element.setColor'] = _SetColorHandler2.default;
+ handlers['element.updateLabel'] = _UpdateLabelHandler2.default;
+
+ return handlers;
+};
+
+Modeling.prototype.updateLabel = function (element, newLabel, newBounds, hints) {
+ this._commandStack.execute('element.updateLabel', {
+ element: element,
+ newLabel: newLabel,
+ newBounds: newBounds,
+ hints: hints || {}
+ });
+};
+
+Modeling.prototype.connect = function (source, target, attrs, hints) {
+
+ var bpmnRules = this._bpmnRules;
+
+ if (!attrs) {
+ attrs = bpmnRules.canConnect(source, target);
+ }
+
+ if (!attrs) {
+ return;
+ }
+
+ return this.createConnection(source, target, attrs, source.parent, hints);
+};
+
+Modeling.prototype.updateProperties = function (element, properties) {
+ this._commandStack.execute('element.updateProperties', {
+ element: element,
+ properties: properties
+ });
+};
+
+Modeling.prototype.resizeLane = function (laneShape, newBounds, balanced) {
+ this._commandStack.execute('lane.resize', {
+ shape: laneShape,
+ newBounds: newBounds,
+ balanced: balanced
+ });
+};
+
+Modeling.prototype.addLane = function (targetLaneShape, location) {
+ var context = {
+ shape: targetLaneShape,
+ location: location
+ };
+
+ this._commandStack.execute('lane.add', context);
+
+ return context.newLane;
+};
+
+Modeling.prototype.splitLane = function (targetLane, count) {
+ this._commandStack.execute('lane.split', {
+ shape: targetLane,
+ count: count
+ });
+};
+
+/**
+ * Transform the current diagram into a collaboration.
+ *
+ * @return {djs.model.Root} the new root element
+ */
+Modeling.prototype.makeCollaboration = function () {
+
+ var collaborationElement = this._create('root', {
+ type: 'bpmn:Collaboration'
+ });
+
+ var context = {
+ newRoot: collaborationElement
+ };
+
+ this._commandStack.execute('canvas.updateRoot', context);
+
+ return collaborationElement;
+};
+
+Modeling.prototype.updateLaneRefs = function (flowNodeShapes, laneShapes) {
+
+ this._commandStack.execute('lane.updateRefs', {
+ flowNodeShapes: flowNodeShapes,
+ laneShapes: laneShapes
+ });
+};
+
+/**
+ * Transform the current diagram into a process.
+ *
+ * @return {djs.model.Root} the new root element
+ */
+Modeling.prototype.makeProcess = function () {
+
+ var processElement = this._create('root', {
+ type: 'bpmn:Process'
+ });
+
+ var context = {
+ newRoot: processElement
+ };
+
+ this._commandStack.execute('canvas.updateRoot', context);
+};
+
+Modeling.prototype.claimId = function (id, moddleElement) {
+ this._commandStack.execute('id.updateClaim', {
+ id: id,
+ element: moddleElement,
+ claiming: true
+ });
+};
+
+Modeling.prototype.unclaimId = function (id, moddleElement) {
+ this._commandStack.execute('id.updateClaim', {
+ id: id,
+ element: moddleElement
+ });
+};
+
+Modeling.prototype.setColor = function (elements, colors) {
+ if (!elements.length) {
+ elements = [elements];
+ }
+
+ this._commandStack.execute('element.setColor', {
+ elements: elements,
+ colors: colors
+ });
+};
+
+},{"../label-editing/cmd/UpdateLabelHandler":143,"./cmd/AddLaneHandler":178,"./cmd/IdClaimHandler":179,"./cmd/ResizeLaneHandler":180,"./cmd/SetColorHandler":181,"./cmd/SplitLaneHandler":182,"./cmd/UpdateCanvasRootHandler":183,"./cmd/UpdateFlowNodeRefsHandler":184,"./cmd/UpdatePropertiesHandler":185,"diagram-js/lib/features/modeling/Modeling":305,"inherits":415}],150:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AdaptiveLabelPositioningBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _Math = require('diagram-js/lib/util/Math');
+
+var _LabelUtil = require('../../../util/LabelUtil');
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A component that makes sure that external labels are added
+ * together with respective elements and properly updated (DI wise)
+ * during move.
+ *
+ * @param {EventBus} eventBus
+ * @param {Modeling} modeling
+ */
+function AdaptiveLabelPositioningBehavior(eventBus, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ this.postExecuted(['connection.create', 'connection.layout', 'connection.reconnectEnd', 'connection.reconnectStart', 'connection.updateWaypoints'], function (event) {
+
+ var context = event.context,
+ connection = context.connection;
+
+ var source = connection.source,
+ target = connection.target;
+
+ checkLabelAdjustment(source);
+ checkLabelAdjustment(target);
+ });
+
+ this.postExecuted(['label.create'], function (event) {
+ checkLabelAdjustment(event.context.shape.labelTarget);
+ });
+
+ function checkLabelAdjustment(element) {
+
+ // skip non-existing labels
+ if (!(0, _LabelUtil.hasExternalLabel)(element)) {
+ return;
+ }
+
+ var optimalPosition = getOptimalPosition(element);
+
+ // no optimal position found
+ if (!optimalPosition) {
+ return;
+ }
+
+ adjustLabelPosition(element, optimalPosition);
+ }
+
+ var ELEMENT_LABEL_DISTANCE = 10;
+
+ function adjustLabelPosition(element, orientation) {
+
+ var elementMid = (0, _LayoutUtil.getMid)(element),
+ label = element.label,
+ labelMid = (0, _LayoutUtil.getMid)(label);
+
+ var elementTrbl = (0, _LayoutUtil.asTRBL)(element);
+
+ var newLabelMid;
+
+ switch (orientation) {
+ case 'top':
+ newLabelMid = {
+ x: elementMid.x,
+ y: elementTrbl.top - ELEMENT_LABEL_DISTANCE - label.height / 2
+ };
+
+ break;
+
+ case 'left':
+
+ newLabelMid = {
+ x: elementTrbl.left - ELEMENT_LABEL_DISTANCE - label.width / 2,
+ y: elementMid.y
+ };
+
+ break;
+
+ case 'bottom':
+
+ newLabelMid = {
+ x: elementMid.x,
+ y: elementTrbl.bottom + ELEMENT_LABEL_DISTANCE + label.height / 2
+ };
+
+ break;
+
+ case 'right':
+
+ newLabelMid = {
+ x: elementTrbl.right + ELEMENT_LABEL_DISTANCE + label.width / 2,
+ y: elementMid.y
+ };
+
+ break;
+ }
+
+ var delta = (0, _Math.substract)(newLabelMid, labelMid);
+
+ modeling.moveShape(label, delta);
+ }
+}
+
+(0, _inherits2.default)(AdaptiveLabelPositioningBehavior, _CommandInterceptor2.default);
+
+AdaptiveLabelPositioningBehavior.$inject = ['eventBus', 'modeling'];
+
+/**
+ * Return the optimal label position around an element
+ * or _undefined_, if none was found.
+ *
+ * @param {Shape} element
+ *
+ * @return {String} positioning identifier
+ */
+function getOptimalPosition(element) {
+
+ var labelMid = (0, _LayoutUtil.getMid)(element.label);
+
+ var elementMid = (0, _LayoutUtil.getMid)(element);
+
+ var labelOrientation = getApproximateOrientation(elementMid, labelMid);
+
+ if (!isAligned(labelOrientation)) {
+ return;
+ }
+
+ var takenAlignments = [].concat(element.incoming.map(function (c) {
+ return c.waypoints[c.waypoints.length - 2];
+ }), element.outgoing.map(function (c) {
+ return c.waypoints[1];
+ })).map(function (point) {
+ return getApproximateOrientation(elementMid, point);
+ });
+
+ var freeAlignments = ALIGNMENTS.filter(function (alignment) {
+
+ return takenAlignments.indexOf(alignment) === -1;
+ });
+
+ // NOTHING TO DO; label already aligned a.O.K.
+ if (freeAlignments.indexOf(labelOrientation) !== -1) {
+ return;
+ }
+
+ return freeAlignments[0];
+}
+
+var ALIGNMENTS = ['top', 'bottom', 'left', 'right'];
+
+function getApproximateOrientation(p0, p1) {
+ return (0, _LayoutUtil.getOrientation)(p1, p0, 5);
+}
+
+function isAligned(orientation) {
+ return ALIGNMENTS.indexOf(orientation) !== -1;
+}
+
+},{"../../../util/LabelUtil":215,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Math":402,"inherits":415}],151:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AppendBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function AppendBehavior(eventBus, elementFactory, bpmnRules) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ // assign correct shape position unless already set
+
+ this.preExecute('shape.append', function (context) {
+
+ var source = context.source,
+ shape = context.shape;
+
+ if (!context.position) {
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) {
+ context.position = {
+ x: source.x + source.width / 2 + 75,
+ y: source.y - 50 - shape.height / 2
+ };
+ } else {
+ context.position = {
+ x: source.x + source.width + 80 + shape.width / 2,
+ y: source.y + source.height / 2
+ };
+ }
+ }
+ }, true);
+}
+
+(0, _inherits2.default)(AppendBehavior, _CommandInterceptor2.default);
+
+AppendBehavior.$inject = ['eventBus', 'elementFactory', 'bpmnRules'];
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],152:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BoundaryEventBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _minDash = require('min-dash');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * BPMN specific boundary event behavior
+ */
+function BoundaryEventBehavior(eventBus, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ function getBoundaryEvents(element) {
+ return (0, _minDash.filter)(element.attachers, function (attacher) {
+ return (0, _ModelUtil.is)(attacher, 'bpmn:BoundaryEvent');
+ });
+ }
+
+ // remove after connecting to event-based gateway
+ this.postExecute('connection.create', function (event) {
+ var source = event.context.source,
+ target = event.context.target,
+ boundaryEvents = getBoundaryEvents(target);
+
+ if ((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && (0, _ModelUtil.is)(target, 'bpmn:ReceiveTask') && boundaryEvents.length > 0) {
+ modeling.removeElements(boundaryEvents);
+ }
+ });
+
+ // remove after replacing connected gateway with event-based gateway
+ this.postExecute('connection.reconnectStart', function (event) {
+ var oldSource = event.context.oldSource,
+ newSource = event.context.newSource;
+
+ if ((0, _ModelUtil.is)(oldSource, 'bpmn:Gateway') && (0, _ModelUtil.is)(newSource, 'bpmn:EventBasedGateway')) {
+ (0, _minDash.forEach)(newSource.outgoing, function (connection) {
+ var target = connection.target,
+ attachedboundaryEvents = getBoundaryEvents(target);
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:ReceiveTask') && attachedboundaryEvents.length > 0) {
+ modeling.removeElements(attachedboundaryEvents);
+ }
+ });
+ }
+ });
+}
+
+BoundaryEventBehavior.$inject = ['eventBus', 'modeling'];
+
+(0, _inherits2.default)(BoundaryEventBehavior, _CommandInterceptor2.default);
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],153:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CopyPasteBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _minDash = require('min-dash');
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function CopyPasteBehavior(eventBus, modeling, canvas) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ this.preExecute('elements.paste', 1500, function (context) {
+ var topParent = context.topParent;
+
+ // always grab the latest root
+ if (!topParent.parent) {
+ context.topParent = canvas.getRootElement();
+ }
+
+ if ((0, _ModelUtil.is)(topParent, 'bpmn:Lane')) {
+ do {
+ // unwrap Lane -> LaneSet -> (Lane | FlowElementsContainer)
+ topParent = context.topParent = topParent.parent;
+ } while ((0, _ModelUtil.is)(topParent, 'bpmn:Lane') || !(0, _ModelUtil.is)(topParent, 'bpmn:Participant'));
+ }
+ }, true);
+
+ this.postExecute('elements.paste', function (context) {
+
+ var tree = context.tree,
+ createdElements = tree.createdElements;
+
+ (0, _minDash.forEach)(createdElements, function (data) {
+ var element = data.element,
+ businessObject = element.businessObject,
+ descriptor = data.descriptor,
+ defaultFlow;
+
+ if (((0, _ModelUtil.is)(businessObject, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject, 'bpmn:Activity')) && descriptor.default) {
+
+ defaultFlow = createdElements[descriptor.default];
+
+ // if the default flow wasn't created, means that it wasn't copied
+ if (defaultFlow) {
+ defaultFlow = defaultFlow.element;
+ } else {
+ defaultFlow = undefined;
+ }
+
+ delete element.default;
+
+ modeling.updateProperties(element, { default: defaultFlow });
+ }
+ });
+ }, true);
+}
+
+CopyPasteBehavior.$inject = ['eventBus', 'modeling', 'canvas'];
+
+(0, _inherits2.default)(CopyPasteBehavior, _CommandInterceptor2.default);
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],154:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CreateBoundaryEventBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * BPMN specific create boundary event behavior
+ */
+function CreateBoundaryEventBehavior(eventBus, modeling, elementFactory, bpmnFactory) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ /**
+ * replace intermediate event with boundary event when
+ * attaching it to a shape
+ */
+
+ this.preExecute('shape.create', function (context) {
+ var shape = context.shape,
+ host = context.host,
+ businessObject,
+ boundaryEvent;
+
+ var attrs = {
+ cancelActivity: true
+ };
+
+ if (host && (0, _ModelUtil.is)(shape, 'bpmn:IntermediateThrowEvent')) {
+ attrs.attachedToRef = host.businessObject;
+
+ businessObject = bpmnFactory.create('bpmn:BoundaryEvent', attrs);
+
+ boundaryEvent = {
+ type: 'bpmn:BoundaryEvent',
+ businessObject: businessObject
+ };
+
+ context.shape = elementFactory.createShape(boundaryEvent);
+ }
+ }, true);
+}
+
+CreateBoundaryEventBehavior.$inject = ['eventBus', 'modeling', 'elementFactory', 'bpmnFactory'];
+
+(0, _inherits2.default)(CreateBoundaryEventBehavior, _CommandInterceptor2.default);
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],155:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CreateDataObjectBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * BPMN specific create data object behavior
+ */
+function CreateDataObjectBehavior(eventBus, bpmnFactory, moddle) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ this.preExecute('shape.create', function (event) {
+
+ var context = event.context,
+ shape = context.shape;
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') {
+
+ // create a DataObject every time a DataObjectReference is created
+ var dataObject = bpmnFactory.create('bpmn:DataObject');
+
+ // set the reference to the DataObject
+ shape.businessObject.dataObjectRef = dataObject;
+ }
+ });
+}
+
+CreateDataObjectBehavior.$inject = ['eventBus', 'bpmnFactory', 'moddle'];
+
+(0, _inherits2.default)(CreateDataObjectBehavior, _CommandInterceptor2.default);
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],156:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CreateParticipantBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * BPMN specific create participant behavior
+ */
+function CreateParticipantBehavior(eventBus, modeling, elementFactory, bpmnFactory, canvas) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ /**
+ * morph process into collaboration before adding
+ * participant onto collaboration
+ */
+
+ this.preExecute('shape.create', function (context) {
+
+ var parent = context.parent,
+ shape = context.shape,
+ position = context.position;
+
+ var rootElement = canvas.getRootElement();
+
+ if ((0, _ModelUtil.is)(parent, 'bpmn:Process') && (0, _ModelUtil.is)(shape, 'bpmn:Participant') && !(0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) {
+
+ // this is going to detach the process root
+ // and set the returned collaboration element
+ // as the new root element
+ var collaborationElement = modeling.makeCollaboration();
+
+ // monkey patch the create context
+ // so that the participant is being dropped
+ // onto the new collaboration root instead
+ context.position = position;
+ context.parent = collaborationElement;
+
+ context.processRoot = parent;
+ }
+ }, true);
+
+ this.execute('shape.create', function (context) {
+
+ var processRoot = context.processRoot,
+ shape = context.shape;
+
+ if (processRoot) {
+ context.oldProcessRef = shape.businessObject.processRef;
+
+ // assign the participant processRef
+ shape.businessObject.processRef = processRoot.businessObject;
+ }
+ }, true);
+
+ this.revert('shape.create', function (context) {
+ var processRoot = context.processRoot,
+ shape = context.shape;
+
+ if (processRoot) {
+ // assign the participant processRef
+ shape.businessObject.processRef = context.oldProcessRef;
+ }
+ }, true);
+
+ this.postExecute('shape.create', function (context) {
+
+ var processRoot = context.processRoot,
+ shape = context.shape;
+
+ if (processRoot) {
+ // process root is already detached at this point
+ var processChildren = processRoot.children.slice();
+ modeling.moveElements(processChildren, { x: 0, y: 0 }, shape);
+ }
+ }, true);
+}
+
+CreateParticipantBehavior.$inject = ['eventBus', 'modeling', 'elementFactory', 'bpmnFactory', 'canvas'];
+
+(0, _inherits2.default)(CreateParticipantBehavior, _CommandInterceptor2.default);
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],157:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DataInputAssociationBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _Collections = require('diagram-js/lib/util/Collections');
+
+var _minDash = require('min-dash');
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var TARGET_REF_PLACEHOLDER_NAME = '__targetRef_placeholder';
+
+/**
+ * This behavior makes sure we always set a fake
+ * DataInputAssociation#targetRef as demanded by the BPMN 2.0
+ * XSD schema.
+ *
+ * The reference is set to a bpmn:Property{ name: '__targetRef_placeholder' }
+ * which is created on the fly and cleaned up afterwards if not needed
+ * anymore.
+ *
+ * @param {EventBus} eventBus
+ * @param {BpmnFactory} bpmnFactory
+ */
+function DataInputAssociationBehavior(eventBus, bpmnFactory) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ this.executed(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnectEnd'], ifDataInputAssociation(fixTargetRef));
+
+ this.reverted(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnectEnd'], ifDataInputAssociation(fixTargetRef));
+
+ function usesTargetRef(element, targetRef, removedConnection) {
+
+ var inputAssociations = element.get('dataInputAssociations');
+
+ return (0, _minDash.find)(inputAssociations, function (association) {
+ return association !== removedConnection && association.targetRef === targetRef;
+ });
+ }
+
+ function getTargetRef(element, create) {
+
+ var properties = element.get('properties');
+
+ var targetRefProp = (0, _minDash.find)(properties, function (p) {
+ return p.name === TARGET_REF_PLACEHOLDER_NAME;
+ });
+
+ if (!targetRefProp && create) {
+ targetRefProp = bpmnFactory.create('bpmn:Property', {
+ name: TARGET_REF_PLACEHOLDER_NAME
+ });
+
+ (0, _Collections.add)(properties, targetRefProp);
+ }
+
+ return targetRefProp;
+ }
+
+ function cleanupTargetRef(element, connection) {
+
+ var targetRefProp = getTargetRef(element);
+
+ if (!targetRefProp) {
+ return;
+ }
+
+ if (!usesTargetRef(element, targetRefProp, connection)) {
+ (0, _Collections.remove)(element.get('properties'), targetRefProp);
+ }
+ }
+
+ /**
+ * Make sure targetRef is set to a valid property or
+ * `null` if the connection is detached.
+ *
+ * @param {Event} event
+ */
+ function fixTargetRef(event) {
+
+ var context = event.context,
+ connection = context.connection,
+ connectionBo = connection.businessObject,
+ target = connection.target,
+ targetBo = target && target.businessObject,
+ newTarget = context.newTarget,
+ newTargetBo = newTarget && newTarget.businessObject,
+ oldTarget = context.oldTarget || context.target,
+ oldTargetBo = oldTarget && oldTarget.businessObject;
+
+ var dataAssociation = connection.businessObject,
+ targetRefProp;
+
+ if (oldTargetBo && oldTargetBo !== targetBo) {
+ cleanupTargetRef(oldTargetBo, connectionBo);
+ }
+
+ if (newTargetBo && newTargetBo !== targetBo) {
+ cleanupTargetRef(newTargetBo, connectionBo);
+ }
+
+ if (targetBo) {
+ targetRefProp = getTargetRef(targetBo, true);
+ dataAssociation.targetRef = targetRefProp;
+ } else {
+ dataAssociation.targetRef = null;
+ }
+ }
+}
+
+DataInputAssociationBehavior.$inject = ['eventBus', 'bpmnFactory'];
+
+(0, _inherits2.default)(DataInputAssociationBehavior, _CommandInterceptor2.default);
+
+/**
+ * Only call the given function when the event
+ * touches a bpmn:DataInputAssociation.
+ *
+ * @param {Function} fn
+ * @return {Function}
+ */
+function ifDataInputAssociation(fn) {
+
+ return function (event) {
+ var context = event.context,
+ connection = context.connection;
+
+ if ((0, _ModelUtil.is)(connection, 'bpmn:DataInputAssociation')) {
+ return fn(event);
+ }
+ };
+}
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/util/Collections":393,"inherits":415,"min-dash":505}],158:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DataStoreBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _ModelingUtil = require('../util/ModelingUtil');
+
+var _UpdateSemanticParentHandler = require('../cmd/UpdateSemanticParentHandler');
+
+var _UpdateSemanticParentHandler2 = _interopRequireDefault(_UpdateSemanticParentHandler);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * BPMN specific data store behavior
+ */
+function DataStoreBehavior(canvas, commandStack, elementRegistry, eventBus) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ commandStack.registerHandler('dataStore.updateContainment', _UpdateSemanticParentHandler2.default);
+
+ function getFirstParticipant() {
+ return elementRegistry.filter(function (element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:Participant');
+ })[0];
+ }
+
+ function getDataStores(element) {
+ return element.children.filter(function (child) {
+ return (0, _ModelUtil.is)(child, 'bpmn:DataStoreReference') && !child.labelTarget;
+ });
+ }
+
+ function updateDataStoreParent(dataStore, newDataStoreParent) {
+ var dataStoreBo = dataStore.businessObject || dataStore;
+
+ newDataStoreParent = newDataStoreParent || getFirstParticipant();
+
+ if (newDataStoreParent) {
+ var newDataStoreParentBo = newDataStoreParent.businessObject || newDataStoreParent;
+
+ commandStack.execute('dataStore.updateContainment', {
+ dataStoreBo: dataStoreBo,
+ newSemanticParent: newDataStoreParentBo.processRef || newDataStoreParentBo,
+ newDiParent: newDataStoreParentBo.di
+ });
+ }
+ }
+
+ // disable auto-resize for data stores
+ this.preExecute('shape.create', function (event) {
+
+ var context = event.context,
+ shape = context.shape;
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label') {
+
+ if (!context.hints) {
+ context.hints = {};
+ }
+
+ // prevent auto resizing
+ context.hints.autoResize = false;
+ }
+ });
+
+ // disable auto-resize for data stores
+ this.preExecute('elements.move', function (event) {
+ var context = event.context,
+ shapes = context.shapes;
+
+ var dataStoreReferences = shapes.filter(function (shape) {
+ return (0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference');
+ });
+
+ if (dataStoreReferences.length) {
+ if (!context.hints) {
+ context.hints = {};
+ }
+
+ // prevent auto resizing for data store references
+ context.hints.autoResize = shapes.filter(function (shape) {
+ return !(0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference');
+ });
+ }
+ });
+
+ // update parent on data store created
+ this.postExecute('shape.create', function (event) {
+ var context = event.context,
+ shape = context.shape,
+ parent = shape.parent;
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label' && (0, _ModelUtil.is)(parent, 'bpmn:Collaboration')) {
+
+ updateDataStoreParent(shape);
+ }
+ });
+
+ // update parent on data store moved
+ this.postExecute('shape.move', function (event) {
+ var context = event.context,
+ shape = context.shape,
+ oldParent = context.oldParent,
+ parent = shape.parent;
+
+ if ((0, _ModelUtil.is)(oldParent, 'bpmn:Collaboration')) {
+
+ // do nothing if not necessary
+ return;
+ }
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label' && (0, _ModelUtil.is)(parent, 'bpmn:Collaboration')) {
+
+ var participant = (0, _ModelUtil.is)(oldParent, 'bpmn:Participant') ? oldParent : getAncestor(oldParent, 'bpmn:Participant');
+
+ updateDataStoreParent(shape, participant);
+ }
+ });
+
+ // update data store parents on participant or subprocess deleted
+ this.postExecute('shape.delete', function (event) {
+ var context = event.context,
+ shape = context.shape,
+ rootElement = canvas.getRootElement();
+
+ if ((0, _ModelingUtil.isAny)(shape, ['bpmn:Participant', 'bpmn:SubProcess']) && (0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) {
+ getDataStores(rootElement).filter(function (dataStore) {
+ return isDescendant(dataStore, shape);
+ }).forEach(function (dataStore) {
+ updateDataStoreParent(dataStore);
+ });
+ }
+ });
+
+ // update data store parents on collaboration -> process
+ this.postExecute('canvas.updateRoot', function (event) {
+ var context = event.context,
+ oldRoot = context.oldRoot,
+ newRoot = context.newRoot;
+
+ var dataStores = getDataStores(oldRoot);
+
+ dataStores.forEach(function (dataStore) {
+
+ if ((0, _ModelUtil.is)(newRoot, 'bpmn:Process')) {
+ updateDataStoreParent(dataStore, newRoot);
+ }
+ });
+ });
+}
+
+DataStoreBehavior.$inject = ['canvas', 'commandStack', 'elementRegistry', 'eventBus'];
+
+(0, _inherits2.default)(DataStoreBehavior, _CommandInterceptor2.default);
+
+// helpers //////////
+
+function isDescendant(descendant, ancestor) {
+ var descendantBo = descendant.businessObject || descendant,
+ ancestorBo = ancestor.businessObject || ancestor;
+
+ while (descendantBo.$parent) {
+ if (descendantBo.$parent === ancestorBo.processRef || ancestorBo) {
+ return true;
+ }
+
+ descendantBo = descendantBo.$parent;
+ }
+
+ return false;
+}
+
+function getAncestor(element, type) {
+
+ while (element.parent) {
+ if ((0, _ModelUtil.is)(element.parent, type)) {
+ return element.parent;
+ }
+
+ element = element.parent;
+ }
+}
+
+},{"../../../util/ModelUtil":216,"../cmd/UpdateSemanticParentHandler":186,"../util/ModelingUtil":189,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],159:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DeleteLaneBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _LaneUtil = require('../util/LaneUtil');
+
+var _Elements = require('diagram-js/lib/util/Elements');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var LOW_PRIORITY = 500;
+
+/**
+ * BPMN specific delete lane behavior
+ */
+function DeleteLaneBehavior(eventBus, modeling, spaceTool) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ function compensateLaneDelete(shape, oldParent) {
+
+ var siblings = (0, _LaneUtil.getChildLanes)(oldParent);
+
+ var topAffected = [];
+ var bottomAffected = [];
+
+ (0, _Elements.eachElement)(siblings, function (element) {
+
+ if (element.y > shape.y) {
+ bottomAffected.push(element);
+ } else {
+ topAffected.push(element);
+ }
+
+ return element.children;
+ });
+
+ if (!siblings.length) {
+ return;
+ }
+
+ var offset;
+
+ if (bottomAffected.length && topAffected.length) {
+ offset = shape.height / 2;
+ } else {
+ offset = shape.height;
+ }
+
+ var topAdjustments, bottomAdjustments;
+
+ if (topAffected.length) {
+ topAdjustments = spaceTool.calculateAdjustments(topAffected, 'y', offset, shape.y - 10);
+
+ spaceTool.makeSpace(topAdjustments.movingShapes, topAdjustments.resizingShapes, { x: 0, y: offset }, 's');
+ }
+
+ if (bottomAffected.length) {
+ bottomAdjustments = spaceTool.calculateAdjustments(bottomAffected, 'y', -offset, shape.y + shape.height + 10);
+
+ spaceTool.makeSpace(bottomAdjustments.movingShapes, bottomAdjustments.resizingShapes, { x: 0, y: -offset }, 'n');
+ }
+ }
+
+ /**
+ * Adjust sizes of other lanes after lane deletion
+ */
+ this.postExecuted('shape.delete', LOW_PRIORITY, function (event) {
+
+ var context = event.context,
+ hints = context.hints,
+ shape = context.shape,
+ oldParent = context.oldParent;
+
+ // only compensate lane deletes
+ if (!(0, _ModelUtil.is)(shape, 'bpmn:Lane')) {
+ return;
+ }
+
+ // compensate root deletes only
+ if (hints && hints.nested) {
+ return;
+ }
+
+ compensateLaneDelete(shape, oldParent);
+ });
+}
+
+DeleteLaneBehavior.$inject = ['eventBus', 'modeling', 'spaceTool'];
+
+(0, _inherits2.default)(DeleteLaneBehavior, _CommandInterceptor2.default);
+
+},{"../../../util/ModelUtil":216,"../util/LaneUtil":188,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/util/Elements":396,"inherits":415}],160:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DropOnFlowBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _minDash = require('min-dash');
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _LineIntersection = require('diagram-js/lib/util/LineIntersection');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function DropOnFlowBehavior(eventBus, bpmnRules, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ /**
+ * Reconnect start / end of a connection after
+ * dropping an element on a flow.
+ */
+
+ function insertShape(shape, targetFlow, position) {
+ var waypoints = targetFlow.waypoints,
+ waypointsBefore,
+ waypointsAfter,
+ dockingPoint,
+ source,
+ target,
+ incomingConnection,
+ outgoingConnection,
+ oldOutgoing = shape.outgoing.slice(),
+ oldIncoming = shape.incoming.slice();
+
+ var intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, position);
+
+ if (intersection) {
+ waypointsBefore = waypoints.slice(0, intersection.index);
+ waypointsAfter = waypoints.slice(intersection.index + (intersection.bendpoint ? 1 : 0));
+
+ // due to inaccuracy intersection might have been found
+ if (!waypointsBefore.length || !waypointsAfter.length) {
+ return;
+ }
+
+ dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : position;
+
+ // if last waypointBefore is inside shape's bounds, ignore docking point
+ if (!isPointInsideBBox(shape, waypointsBefore[waypointsBefore.length - 1])) {
+ waypointsBefore.push(copy(dockingPoint));
+ }
+
+ // if first waypointAfter is inside shape's bounds, ignore docking point
+ if (!isPointInsideBBox(shape, waypointsAfter[0])) {
+ waypointsAfter.unshift(copy(dockingPoint));
+ }
+ }
+
+ source = targetFlow.source;
+ target = targetFlow.target;
+
+ if (bpmnRules.canConnect(source, shape, targetFlow)) {
+ // reconnect source -> inserted shape
+ modeling.reconnectEnd(targetFlow, shape, waypointsBefore || position);
+
+ incomingConnection = targetFlow;
+ }
+
+ if (bpmnRules.canConnect(shape, target, targetFlow)) {
+
+ if (!incomingConnection) {
+ // reconnect inserted shape -> end
+ modeling.reconnectStart(targetFlow, shape, waypointsAfter || position);
+
+ outgoingConnection = targetFlow;
+ } else {
+ outgoingConnection = modeling.connect(shape, target, { type: targetFlow.type, waypoints: waypointsAfter });
+ }
+ }
+
+ var duplicateConnections = [].concat(incomingConnection && (0, _minDash.filter)(oldIncoming, function (connection) {
+ return connection.source === incomingConnection.source;
+ }) || [], outgoingConnection && (0, _minDash.filter)(oldOutgoing, function (connection) {
+ return connection.source === outgoingConnection.source;
+ }) || []);
+
+ if (duplicateConnections.length) {
+ modeling.removeElements(duplicateConnections);
+ }
+ }
+
+ this.preExecute('elements.move', function (context) {
+
+ var newParent = context.newParent,
+ shapes = context.shapes,
+ delta = context.delta,
+ shape = shapes[0];
+
+ if (!shape || !newParent) {
+ return;
+ }
+
+ // if the new parent is a connection,
+ // change it to the new parent's parent
+ if (newParent && newParent.waypoints) {
+ context.newParent = newParent = newParent.parent;
+ }
+
+ var shapeMid = getMid(shape);
+ var newShapeMid = {
+ x: shapeMid.x + delta.x,
+ y: shapeMid.y + delta.y
+ };
+
+ // find a connection which intersects with the
+ // element's mid point
+ var connection = (0, _minDash.find)(newParent.children, function (element) {
+ var canInsert = bpmnRules.canInsert(shapes, element);
+
+ return canInsert && (0, _LineIntersection.getApproxIntersection)(element.waypoints, newShapeMid);
+ });
+
+ if (connection) {
+ context.targetFlow = connection;
+ context.position = newShapeMid;
+ }
+ }, true);
+
+ this.postExecuted('elements.move', function (context) {
+
+ var shapes = context.shapes,
+ targetFlow = context.targetFlow,
+ position = context.position;
+
+ if (targetFlow) {
+ insertShape(shapes[0], targetFlow, position);
+ }
+ }, true);
+
+ this.preExecute('shape.create', function (context) {
+
+ var parent = context.parent,
+ shape = context.shape;
+
+ if (bpmnRules.canInsert(shape, parent)) {
+ context.targetFlow = parent;
+ context.parent = parent.parent;
+ }
+ }, true);
+
+ this.postExecuted('shape.create', function (context) {
+
+ var shape = context.shape,
+ targetFlow = context.targetFlow,
+ position = context.position;
+
+ if (targetFlow) {
+ insertShape(shape, targetFlow, position);
+ }
+ }, true);
+}
+
+(0, _inherits2.default)(DropOnFlowBehavior, _CommandInterceptor2.default);
+
+DropOnFlowBehavior.$inject = ['eventBus', 'bpmnRules', 'modeling'];
+
+// helpers /////////////////////
+
+function isPointInsideBBox(bbox, point) {
+ var x = point.x,
+ y = point.y;
+
+ return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height;
+}
+
+function copy(obj) {
+ return (0, _minDash.assign)({}, obj);
+}
+
+function getMid(bounds) {
+
+ return {
+ x: Math.round(bounds.x + bounds.width / 2),
+ y: Math.round(bounds.y + bounds.height / 2)
+ };
+}
+
+},{"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/util/LineIntersection":401,"inherits":415,"min-dash":505}],161:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ImportDockingFix;
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _LineIntersect = require('./util/LineIntersect');
+
+var _LineIntersect2 = _interopRequireDefault(_LineIntersect);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Fix broken dockings after DI imports.
+ *
+ * @param {EventBus} eventBus
+ */
+function ImportDockingFix(eventBus) {
+
+ function adjustDocking(startPoint, nextPoint, elementMid) {
+
+ var elementTop = {
+ x: elementMid.x,
+ y: elementMid.y - 50
+ };
+
+ var elementLeft = {
+ x: elementMid.x - 50,
+ y: elementMid.y
+ };
+
+ var verticalIntersect = (0, _LineIntersect2.default)(startPoint, nextPoint, elementMid, elementTop),
+ horizontalIntersect = (0, _LineIntersect2.default)(startPoint, nextPoint, elementMid, elementLeft);
+
+ // original is horizontal or vertical center cross intersection
+ var centerIntersect;
+
+ if (verticalIntersect && horizontalIntersect) {
+ if (getDistance(verticalIntersect, elementMid) > getDistance(horizontalIntersect, elementMid)) {
+ centerIntersect = horizontalIntersect;
+ } else {
+ centerIntersect = verticalIntersect;
+ }
+ } else {
+ centerIntersect = verticalIntersect || horizontalIntersect;
+ }
+
+ startPoint.original = centerIntersect;
+ }
+
+ function fixDockings(connection) {
+ var waypoints = connection.waypoints;
+
+ adjustDocking(waypoints[0], waypoints[1], (0, _LayoutUtil.getMid)(connection.source));
+
+ adjustDocking(waypoints[waypoints.length - 1], waypoints[waypoints.length - 2], (0, _LayoutUtil.getMid)(connection.target));
+ }
+
+ eventBus.on('bpmnElement.added', function (e) {
+
+ var element = e.element;
+
+ if (element.waypoints) {
+ fixDockings(element);
+ }
+ });
+}
+
+ImportDockingFix.$inject = ['eventBus'];
+
+// helpers //////////////////////
+
+function getDistance(p1, p2) {
+ return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
+}
+
+},{"./util/LineIntersect":177,"diagram-js/lib/layout/LayoutUtil":380}],162:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = LabelBehavior;
+
+var _minDash = require('min-dash');
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _LabelUtil = require('../../../util/LabelUtil');
+
+var _LabelLayoutUtil = require('./util/LabelLayoutUtil');
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var DEFAULT_LABEL_DIMENSIONS = {
+ width: 90,
+ height: 20
+};
+
+var NAME_PROPERTY = 'name';
+var TEXT_PROPERTY = 'text';
+
+/**
+ * A component that makes sure that external labels are added
+ * together with respective elements and properly updated (DI wise)
+ * during move.
+ *
+ * @param {EventBus} eventBus
+ * @param {Modeling} modeling
+ * @param {BpmnFactory} bpmnFactory
+ * @param {TextRenderer} textRenderer
+ */
+function LabelBehavior(eventBus, modeling, bpmnFactory, textRenderer) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ // update label if name property was updated
+ this.postExecute('element.updateProperties', function (e) {
+ var context = e.context,
+ element = context.element,
+ properties = context.properties;
+
+ if (NAME_PROPERTY in properties) {
+ modeling.updateLabel(element, properties[NAME_PROPERTY]);
+ }
+
+ if (TEXT_PROPERTY in properties && (0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
+
+ var newBounds = textRenderer.getTextAnnotationBounds({
+ x: element.x,
+ y: element.y,
+ width: element.width,
+ height: element.height
+ }, properties[TEXT_PROPERTY] || '');
+
+ modeling.updateLabel(element, properties.text, newBounds);
+ }
+ });
+
+ // create label shape after shape/connection was created
+ this.postExecute(['shape.create', 'connection.create'], function (e) {
+ var context = e.context;
+
+ var element = context.shape || context.connection,
+ businessObject = element.businessObject;
+
+ if (!(0, _LabelUtil.isLabelExternal)(element)) {
+ return;
+ }
+
+ // only create label if name
+ if (!businessObject.name) {
+ return;
+ }
+
+ var labelCenter = (0, _LabelUtil.getExternalLabelMid)(element);
+
+ // we don't care about x and y
+ var labelDimensions = textRenderer.getExternalLabelBounds(DEFAULT_LABEL_DIMENSIONS, businessObject.name || '');
+
+ modeling.createLabel(element, labelCenter, {
+ id: businessObject.id + '_label',
+ businessObject: businessObject,
+ width: labelDimensions.width,
+ height: labelDimensions.height
+ });
+ });
+
+ // update label after label shape was deleted
+ this.postExecute('shape.delete', function (event) {
+ var context = event.context,
+ labelTarget = context.labelTarget,
+ hints = context.hints || {};
+
+ // check if label
+ if (labelTarget && hints.unsetLabel !== false) {
+ modeling.updateLabel(labelTarget, null, null, { removeShape: false });
+ }
+ });
+
+ // update di information on label creation
+ this.postExecute(['label.create'], function (event) {
+
+ var context = event.context,
+ element = context.shape,
+ businessObject,
+ di;
+
+ // we want to trigger on real labels only
+ if (!element.labelTarget) {
+ return;
+ }
+
+ // we want to trigger on BPMN elements only
+ if (!(0, _ModelUtil.is)(element.labelTarget || element, 'bpmn:BaseElement')) {
+ return;
+ }
+
+ businessObject = element.businessObject, di = businessObject.di;
+
+ if (!di.label) {
+ di.label = bpmnFactory.create('bpmndi:BPMNLabel', {
+ bounds: bpmnFactory.create('dc:Bounds')
+ });
+ }
+
+ (0, _minDash.assign)(di.label.bounds, {
+ x: element.x,
+ y: element.y,
+ width: element.width,
+ height: element.height
+ });
+ });
+
+ function getVisibleLabelAdjustment(event) {
+
+ var command = event.command,
+ context = event.context,
+ connection = context.connection,
+ label = connection.label,
+ hints = (0, _minDash.assign)({}, context.hints),
+ newWaypoints = context.newWaypoints || connection.waypoints,
+ oldWaypoints = context.oldWaypoints;
+
+ if (typeof hints.startChanged === 'undefined') {
+ hints.startChanged = command === 'connection.reconnectStart';
+ }
+
+ if (typeof hints.endChanged === 'undefined') {
+ hints.endChanged = command === 'connection.reconnectEnd';
+ }
+
+ return (0, _LabelLayoutUtil.getLabelAdjustment)(label, newWaypoints, oldWaypoints, hints);
+ }
+
+ this.postExecute(['connection.layout', 'connection.reconnectEnd', 'connection.reconnectStart', 'connection.updateWaypoints'], function (event) {
+
+ var label = event.context.connection.label,
+ labelAdjustment;
+
+ if (!label) {
+ return;
+ }
+
+ labelAdjustment = getVisibleLabelAdjustment(event);
+
+ modeling.moveShape(label, labelAdjustment);
+ });
+
+ // keep label position on shape replace
+ this.postExecute(['shape.replace'], function (event) {
+ var context = event.context,
+ newShape = context.newShape,
+ oldShape = context.oldShape;
+
+ var businessObject = (0, _ModelUtil.getBusinessObject)(newShape);
+
+ if (businessObject && (0, _LabelUtil.isLabelExternal)(businessObject) && oldShape.label && newShape.label) {
+ newShape.label.x = oldShape.label.x;
+ newShape.label.y = oldShape.label.y;
+ }
+ });
+}
+
+(0, _inherits2.default)(LabelBehavior, _CommandInterceptor2.default);
+
+LabelBehavior.$inject = ['eventBus', 'modeling', 'bpmnFactory', 'textRenderer'];
+
+},{"../../../util/LabelUtil":215,"../../../util/ModelUtil":216,"./util/LabelLayoutUtil":175,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],163:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ModelingFeedback;
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var COLLAB_ERR_MSG = 'flow elements must be children of pools/participants',
+ PROCESS_ERR_MSG = 'participants cannot be pasted onto a non-empty process diagram';
+
+function ModelingFeedback(eventBus, tooltips, translate) {
+
+ function showError(position, message, timeout) {
+ tooltips.add({
+ position: {
+ x: position.x + 5,
+ y: position.y + 5
+ },
+ type: 'error',
+ timeout: timeout || 2000,
+ html: '' + message + '
'
+ });
+ }
+
+ eventBus.on(['shape.move.rejected', 'create.rejected'], function (event) {
+ var context = event.context,
+ shape = context.shape,
+ target = context.target;
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration') && (0, _ModelUtil.is)(shape, 'bpmn:FlowNode')) {
+ showError(event, translate(COLLAB_ERR_MSG));
+ }
+ });
+
+ eventBus.on(['elements.paste.rejected'], function (event) {
+ var context = event.context,
+ position = context.position,
+ target = context.target;
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration')) {
+ showError(position, translate(COLLAB_ERR_MSG));
+ }
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:Process')) {
+ showError(position, translate(PROCESS_ERR_MSG), 3000);
+ }
+ });
+}
+
+ModelingFeedback.$inject = ['eventBus', 'tooltips', 'translate'];
+
+},{"../../../util/ModelUtil":216}],164:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = RemoveElementBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _LineIntersect = require('./util/LineIntersect');
+
+var _LineIntersect2 = _interopRequireDefault(_LineIntersect);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function RemoveElementBehavior(eventBus, bpmnRules, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ /**
+ * Combine sequence flows when deleting an element
+ * if there is one incoming and one outgoing
+ * sequence flow
+ */
+ this.preExecute('shape.delete', function (e) {
+
+ var shape = e.context.shape;
+
+ // only handle [a] -> [shape] -> [b] patterns
+ if (shape.incoming.length !== 1 || shape.outgoing.length !== 1) {
+ return;
+ }
+
+ var inConnection = shape.incoming[0],
+ outConnection = shape.outgoing[0];
+
+ // only handle sequence flows
+ if (!(0, _ModelUtil.is)(inConnection, 'bpmn:SequenceFlow') || !(0, _ModelUtil.is)(outConnection, 'bpmn:SequenceFlow')) {
+ return;
+ }
+
+ if (bpmnRules.canConnect(inConnection.source, outConnection.target, inConnection)) {
+
+ // compute new, combined waypoints
+ var newWaypoints = getNewWaypoints(inConnection.waypoints, outConnection.waypoints);
+
+ modeling.reconnectEnd(inConnection, outConnection.target, newWaypoints);
+ }
+ });
+}
+
+(0, _inherits2.default)(RemoveElementBehavior, _CommandInterceptor2.default);
+
+RemoveElementBehavior.$inject = ['eventBus', 'bpmnRules', 'modeling'];
+
+// helpers //////////////////////
+
+function getDocking(point) {
+ return point.original || point;
+}
+
+function getNewWaypoints(inWaypoints, outWaypoints) {
+
+ var intersection = (0, _LineIntersect2.default)(getDocking(inWaypoints[inWaypoints.length - 2]), getDocking(inWaypoints[inWaypoints.length - 1]), getDocking(outWaypoints[1]), getDocking(outWaypoints[0]));
+
+ if (intersection) {
+ return [].concat(inWaypoints.slice(0, inWaypoints.length - 1), [intersection], outWaypoints.slice(1));
+ } else {
+ return [getDocking(inWaypoints[0]), getDocking(outWaypoints[outWaypoints.length - 1])];
+ }
+}
+
+},{"../../../util/ModelUtil":216,"./util/LineIntersect":177,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],165:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = RemoveParticipantBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * BPMN specific remove behavior
+ */
+function RemoveParticipantBehavior(eventBus, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ /**
+ * morph collaboration diagram into process diagram
+ * after the last participant has been removed
+ */
+
+ this.preExecute('shape.delete', function (context) {
+
+ var shape = context.shape,
+ parent = shape.parent;
+
+ // activate the behavior if the shape to be removed
+ // is a participant
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
+ context.collaborationRoot = parent;
+ }
+ }, true);
+
+ this.postExecute('shape.delete', function (context) {
+
+ var collaborationRoot = context.collaborationRoot;
+
+ if (collaborationRoot && !collaborationRoot.businessObject.participants.length) {
+ // replace empty collaboration with process diagram
+ modeling.makeProcess();
+ }
+ }, true);
+}
+
+RemoveParticipantBehavior.$inject = ['eventBus', 'modeling'];
+
+(0, _inherits2.default)(RemoveParticipantBehavior, _CommandInterceptor2.default);
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],166:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ReplaceConnectionBehavior;
+
+var _minDash = require('min-dash');
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function ReplaceConnectionBehavior(eventBus, modeling, bpmnRules) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ function fixConnection(connection) {
+
+ var source = connection.source,
+ target = connection.target,
+ parent = connection.parent;
+
+ // do not do anything if connection
+ // is already deleted (may happen due to other
+ // behaviors plugged-in before)
+ if (!parent) {
+ return;
+ }
+
+ var replacementType, remove;
+
+ /**
+ * Check if incoming or outgoing connections
+ * can stay or could be substituted with an
+ * appropriate replacement.
+ *
+ * This holds true for SequenceFlow <> MessageFlow.
+ */
+
+ if ((0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow')) {
+ if (!bpmnRules.canConnectSequenceFlow(source, target)) {
+ remove = true;
+ }
+
+ if (bpmnRules.canConnectMessageFlow(source, target)) {
+ replacementType = 'bpmn:MessageFlow';
+ }
+ }
+
+ // transform message flows into sequence flows, if possible
+
+ if ((0, _ModelUtil.is)(connection, 'bpmn:MessageFlow')) {
+
+ if (!bpmnRules.canConnectMessageFlow(source, target)) {
+ remove = true;
+ }
+
+ if (bpmnRules.canConnectSequenceFlow(source, target)) {
+ replacementType = 'bpmn:SequenceFlow';
+ }
+ }
+
+ if ((0, _ModelUtil.is)(connection, 'bpmn:Association') && !bpmnRules.canConnectAssociation(source, target)) {
+ remove = true;
+ }
+
+ // remove invalid connection,
+ // unless it has been removed already
+ if (remove) {
+ modeling.removeConnection(connection);
+ }
+
+ // replace SequenceFlow <> MessageFlow
+
+ if (replacementType) {
+ modeling.connect(source, target, {
+ type: replacementType,
+ waypoints: connection.waypoints.slice()
+ });
+ }
+ }
+
+ this.postExecuted('elements.move', function (context) {
+
+ var closure = context.closure,
+ allConnections = closure.allConnections;
+
+ (0, _minDash.forEach)(allConnections, fixConnection);
+ }, true);
+
+ this.postExecuted(['connection.reconnectStart', 'connection.reconnectEnd'], function (event) {
+
+ var connection = event.context.connection;
+
+ fixConnection(connection);
+ });
+
+ this.postExecuted('element.updateProperties', function (event) {
+ var context = event.context,
+ properties = context.properties,
+ element = context.element,
+ businessObject = element.businessObject,
+ connection;
+
+ // remove condition expression when morphing to default flow
+ if (properties.default) {
+ connection = (0, _minDash.find)(element.outgoing, (0, _minDash.matchPattern)({ id: element.businessObject.default.id }));
+
+ if (connection) {
+ modeling.updateProperties(connection, { conditionExpression: undefined });
+ }
+ }
+
+ // remove default property from source when morphing to conditional flow
+ if (properties.conditionExpression && businessObject.sourceRef.default === businessObject) {
+ modeling.updateProperties(element.source, { default: undefined });
+ }
+ });
+}
+
+(0, _inherits2.default)(ReplaceConnectionBehavior, _CommandInterceptor2.default);
+
+ReplaceConnectionBehavior.$inject = ['eventBus', 'modeling', 'bpmnRules'];
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],167:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ReplaceElementBehaviour;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _minDash = require('min-dash');
+
+var _DiUtil = require('../../../util/DiUtil');
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Defines the behaviour of what happens to the elements inside a container
+ * that morphs into another BPMN element
+ */
+function ReplaceElementBehaviour(eventBus, bpmnReplace, bpmnRules, elementRegistry, selection, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ this._bpmnReplace = bpmnReplace;
+ this._elementRegistry = elementRegistry;
+ this._selection = selection;
+ this._modeling = modeling;
+
+ this.postExecuted(['elements.move'], 500, function (event) {
+
+ var context = event.context,
+ target = context.newParent,
+ newHost = context.newHost,
+ elements = [];
+
+ (0, _minDash.forEach)(context.closure.topLevel, function (topLevelElements) {
+ if ((0, _DiUtil.isEventSubProcess)(topLevelElements)) {
+ elements = elements.concat(topLevelElements.children);
+ } else {
+ elements = elements.concat(topLevelElements);
+ }
+ });
+
+ // Change target to host when the moving element is a `bpmn:BoundaryEvent`
+ if (elements.length === 1 && newHost) {
+ target = newHost;
+ }
+
+ var canReplace = bpmnRules.canReplace(elements, target);
+
+ if (canReplace) {
+ this.replaceElements(elements, canReplace.replacements, newHost);
+ }
+ }, this);
+
+ // update attachments if the host is replaced
+ this.postExecute(['shape.replace'], 1500, function (e) {
+
+ var context = e.context,
+ oldShape = context.oldShape,
+ newShape = context.newShape,
+ attachers = oldShape.attachers,
+ canReplace;
+
+ if (attachers && attachers.length) {
+ canReplace = bpmnRules.canReplace(attachers, newShape);
+
+ this.replaceElements(attachers, canReplace.replacements);
+ }
+ }, this);
+
+ this.postExecuted(['shape.replace'], 1500, function (e) {
+ var context = e.context,
+ oldShape = context.oldShape,
+ newShape = context.newShape;
+
+ modeling.unclaimId(oldShape.businessObject.id, oldShape.businessObject);
+ modeling.updateProperties(newShape, { id: oldShape.id });
+ });
+}
+
+(0, _inherits2.default)(ReplaceElementBehaviour, _CommandInterceptor2.default);
+
+ReplaceElementBehaviour.prototype.replaceElements = function (elements, newElements, newHost) {
+ var elementRegistry = this._elementRegistry,
+ bpmnReplace = this._bpmnReplace,
+ selection = this._selection,
+ modeling = this._modeling;
+
+ (0, _minDash.forEach)(newElements, function (replacement) {
+
+ var newElement = {
+ type: replacement.newElementType
+ };
+
+ var oldElement = elementRegistry.get(replacement.oldElementId);
+
+ if (newHost && (0, _ModelUtil.is)(oldElement, 'bpmn:BoundaryEvent')) {
+ modeling.updateAttachment(oldElement, null);
+ }
+
+ var idx = elements.indexOf(oldElement);
+
+ elements[idx] = bpmnReplace.replaceElement(oldElement, newElement, { select: false });
+
+ if (newHost && (0, _ModelUtil.is)(elements[idx], 'bpmn:BoundaryEvent')) {
+ modeling.updateAttachment(elements[idx], newHost);
+ }
+ });
+
+ if (newElements) {
+ selection.select(elements);
+ }
+};
+
+ReplaceElementBehaviour.$inject = ['eventBus', 'bpmnReplace', 'bpmnRules', 'elementRegistry', 'selection', 'modeling'];
+
+},{"../../../util/DiUtil":214,"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],168:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ResizeLaneBehavior;
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _Mouse = require('diagram-js/lib/util/Mouse');
+
+var SLIGHTLY_HIGHER_PRIORITY = 1001;
+
+/**
+ * Invoke {@link Modeling#resizeLane} instead of
+ * {@link Modeling#resizeShape} when resizing a Lane
+ * or Participant shape.
+ */
+function ResizeLaneBehavior(eventBus, modeling) {
+
+ eventBus.on('resize.start', SLIGHTLY_HIGHER_PRIORITY + 500, function (event) {
+ var context = event.context,
+ shape = context.shape;
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
+
+ // should we resize the opposite lane(s) in
+ // order to compensate for the resize operation?
+ context.balanced = !(0, _Mouse.hasPrimaryModifier)(event);
+ }
+ });
+
+ /**
+ * Intercept resize end and call resize lane function instead.
+ */
+ eventBus.on('resize.end', SLIGHTLY_HIGHER_PRIORITY, function (event) {
+ var context = event.context,
+ shape = context.shape,
+ canExecute = context.canExecute,
+ newBounds = context.newBounds;
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
+
+ if (canExecute) {
+ // ensure we have actual pixel values for new bounds
+ // (important when zoom level was > 1 during move)
+ newBounds = (0, _LayoutUtil.roundBounds)(newBounds);
+
+ // perform the actual resize
+ modeling.resizeLane(shape, newBounds, context.balanced);
+ }
+
+ // stop propagation
+ return false;
+ }
+ });
+}
+
+ResizeLaneBehavior.$inject = ['eventBus', 'modeling'];
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Mouse":403}],169:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ToggleElementCollapseBehaviour;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _ResizeUtil = require('diagram-js/lib/features/resize/ResizeUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var LOW_PRIORITY = 500;
+
+function ToggleElementCollapseBehaviour(eventBus, elementFactory, modeling, resize) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ function hideEmptyLables(children) {
+ if (children.length) {
+ children.forEach(function (child) {
+ if (child.type === 'label' && !child.businessObject.name) {
+ child.hidden = true;
+ }
+ });
+ }
+ }
+
+ function expandedBounds(shape, defaultSize) {
+ var children = shape.children,
+ newBounds = defaultSize,
+ visibleElements,
+ visibleBBox;
+
+ visibleElements = filterVisible(children).concat([shape]);
+
+ visibleBBox = (0, _ResizeUtil.computeChildrenBBox)(visibleElements);
+
+ if (visibleBBox) {
+ // center to visibleBBox with max(defaultSize, childrenBounds)
+ newBounds.width = Math.max(visibleBBox.width, newBounds.width);
+ newBounds.height = Math.max(visibleBBox.height, newBounds.height);
+
+ newBounds.x = visibleBBox.x + (visibleBBox.width - newBounds.width) / 2;
+ newBounds.y = visibleBBox.y + (visibleBBox.height - newBounds.height) / 2;
+ } else {
+ // center to collapsed shape with defaultSize
+ newBounds.x = shape.x + (shape.width - newBounds.width) / 2;
+ newBounds.y = shape.y + (shape.height - newBounds.height) / 2;
+ }
+
+ return newBounds;
+ }
+
+ function collapsedBounds(shape, defaultSize) {
+
+ return {
+ x: shape.x + (shape.width - defaultSize.width) / 2,
+ y: shape.y + (shape.height - defaultSize.height) / 2,
+ width: defaultSize.width,
+ height: defaultSize.height
+ };
+ }
+
+ this.executed(['shape.toggleCollapse'], LOW_PRIORITY, function (e) {
+
+ var context = e.context,
+ shape = context.shape;
+
+ if (!(0, _ModelUtil.is)(shape, 'bpmn:SubProcess')) {
+ return;
+ }
+
+ if (!shape.collapsed) {
+ // all children got made visible through djs, hide empty labels
+ hideEmptyLables(shape.children);
+
+ // remove collapsed marker
+ (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = true;
+ } else {
+ // place collapsed marker
+ (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = false;
+ }
+ });
+
+ this.reverted(['shape.toggleCollapse'], LOW_PRIORITY, function (e) {
+
+ var context = e.context;
+ var shape = context.shape;
+
+ // revert removing/placing collapsed marker
+ if (!shape.collapsed) {
+ (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = true;
+ } else {
+ (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = false;
+ }
+ });
+
+ this.postExecuted(['shape.toggleCollapse'], LOW_PRIORITY, function (e) {
+ var shape = e.context.shape,
+ defaultSize = elementFactory._getDefaultSize(shape),
+ newBounds;
+
+ if (shape.collapsed) {
+
+ // resize to default size of collapsed shapes
+ newBounds = collapsedBounds(shape, defaultSize);
+ } else {
+
+ // resize to bounds of max(visible children, defaultSize)
+ newBounds = expandedBounds(shape, defaultSize);
+ }
+
+ modeling.resizeShape(shape, newBounds);
+ });
+}
+
+(0, _inherits2.default)(ToggleElementCollapseBehaviour, _CommandInterceptor2.default);
+
+ToggleElementCollapseBehaviour.$inject = ['eventBus', 'elementFactory', 'modeling'];
+
+// helpers //////////////////////
+
+function filterVisible(elements) {
+ return elements.filter(function (e) {
+ return !e.hidden;
+ });
+}
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/features/resize/ResizeUtil":351,"inherits":415}],170:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = UnclaimIdBehavior;
+
+var _minDash = require('min-dash');
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Unclaims model IDs on element deletion.
+ *
+ * @param {EventBus} eventBus
+ * @param {Modeling} modeling
+ */
+function UnclaimIdBehavior(eventBus, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ this.preExecute('elements.delete', function (event) {
+ var context = event.context,
+ elements = context.elements;
+
+ (0, _minDash.forEach)(elements, function (element) {
+ modeling.unclaimId(element.businessObject.id, element.businessObject);
+ });
+ });
+}
+
+(0, _inherits2.default)(UnclaimIdBehavior, _CommandInterceptor2.default);
+
+UnclaimIdBehavior.$inject = ['eventBus', 'modeling'];
+
+},{"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],171:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DeleteSequenceFlowBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A behavior that unsets the Default property of
+ * sequence flow source on element delete, if the
+ * removed element is the Gateway or Task's default flow.
+ *
+ * @param {EventBus} eventBus
+ * @param {Modeling} modeling
+ */
+function DeleteSequenceFlowBehavior(eventBus, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ this.preExecute('connection.delete', function (event) {
+ var context = event.context,
+ connection = context.connection,
+ source = connection.source;
+
+ if (isDefaultFlow(connection, source)) {
+ modeling.updateProperties(source, {
+ 'default': null
+ });
+ }
+ });
+}
+
+(0, _inherits2.default)(DeleteSequenceFlowBehavior, _CommandInterceptor2.default);
+
+DeleteSequenceFlowBehavior.$inject = ['eventBus', 'modeling'];
+
+// helpers //////////////////////
+
+function isDefaultFlow(connection, source) {
+
+ if (!(0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow')) {
+ return false;
+ }
+
+ var sourceBo = (0, _ModelUtil.getBusinessObject)(source),
+ sequenceFlow = (0, _ModelUtil.getBusinessObject)(connection);
+
+ return sourceBo.get('default') === sequenceFlow;
+}
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],172:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = UpdateFlowNodeRefsBehavior;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var LOW_PRIORITY = 500,
+ HIGH_PRIORITY = 5000;
+
+/**
+ * BPMN specific delete lane behavior
+ */
+function UpdateFlowNodeRefsBehavior(eventBus, modeling, translate) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ /**
+ * Ok, this is it:
+ *
+ * We have to update the Lane#flowNodeRefs _and_
+ * FlowNode#lanes with every FlowNode move/resize and
+ * Lane move/resize.
+ *
+ * We want to group that stuff to recompute containments
+ * as efficient as possible.
+ *
+ * Yea!
+ */
+
+ // the update context
+ var context;
+
+ function initContext() {
+ context = context || new UpdateContext();
+ context.enter();
+
+ return context;
+ }
+
+ function getContext() {
+ if (!context) {
+ throw new Error(translate('out of bounds release'));
+ }
+
+ return context;
+ }
+
+ function releaseContext() {
+
+ if (!context) {
+ throw new Error(translate('out of bounds release'));
+ }
+
+ var triggerUpdate = context.leave();
+
+ if (triggerUpdate) {
+ modeling.updateLaneRefs(context.flowNodes, context.lanes);
+
+ context = null;
+ }
+
+ return triggerUpdate;
+ }
+
+ var laneRefUpdateEvents = ['spaceTool', 'lane.add', 'lane.resize', 'lane.split', 'elements.move', 'elements.delete', 'shape.create', 'shape.delete', 'shape.move', 'shape.resize'];
+
+ // listen to a lot of stuff to group lane updates
+
+ this.preExecute(laneRefUpdateEvents, HIGH_PRIORITY, function (event) {
+ initContext();
+ });
+
+ this.postExecuted(laneRefUpdateEvents, LOW_PRIORITY, function (event) {
+ releaseContext();
+ });
+
+ // Mark flow nodes + lanes that need an update
+
+ this.preExecute(['shape.create', 'shape.move', 'shape.delete', 'shape.resize'], function (event) {
+
+ var context = event.context,
+ shape = context.shape;
+
+ var updateContext = getContext();
+
+ // no need to update labels
+ if (shape.labelTarget) {
+ return;
+ }
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) {
+ updateContext.addLane(shape);
+ }
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:FlowNode')) {
+ updateContext.addFlowNode(shape);
+ }
+ });
+}
+
+UpdateFlowNodeRefsBehavior.$inject = ['eventBus', 'modeling', 'translate'];
+
+(0, _inherits2.default)(UpdateFlowNodeRefsBehavior, _CommandInterceptor2.default);
+
+function UpdateContext() {
+
+ this.flowNodes = [];
+ this.lanes = [];
+
+ this.counter = 0;
+
+ this.addLane = function (lane) {
+ this.lanes.push(lane);
+ };
+
+ this.addFlowNode = function (flowNode) {
+ this.flowNodes.push(flowNode);
+ };
+
+ this.enter = function () {
+ this.counter++;
+ };
+
+ this.leave = function () {
+ this.counter--;
+
+ return !this.counter;
+ };
+}
+
+},{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],173:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _AdaptiveLabelPositioningBehavior = require('./AdaptiveLabelPositioningBehavior');
+
+var _AdaptiveLabelPositioningBehavior2 = _interopRequireDefault(_AdaptiveLabelPositioningBehavior);
+
+var _AppendBehavior = require('./AppendBehavior');
+
+var _AppendBehavior2 = _interopRequireDefault(_AppendBehavior);
+
+var _BoundaryEventBehavior = require('./BoundaryEventBehavior');
+
+var _BoundaryEventBehavior2 = _interopRequireDefault(_BoundaryEventBehavior);
+
+var _CopyPasteBehavior = require('./CopyPasteBehavior');
+
+var _CopyPasteBehavior2 = _interopRequireDefault(_CopyPasteBehavior);
+
+var _CreateBoundaryEventBehavior = require('./CreateBoundaryEventBehavior');
+
+var _CreateBoundaryEventBehavior2 = _interopRequireDefault(_CreateBoundaryEventBehavior);
+
+var _CreateDataObjectBehavior = require('./CreateDataObjectBehavior');
+
+var _CreateDataObjectBehavior2 = _interopRequireDefault(_CreateDataObjectBehavior);
+
+var _CreateParticipantBehavior = require('./CreateParticipantBehavior');
+
+var _CreateParticipantBehavior2 = _interopRequireDefault(_CreateParticipantBehavior);
+
+var _DataInputAssociationBehavior = require('./DataInputAssociationBehavior');
+
+var _DataInputAssociationBehavior2 = _interopRequireDefault(_DataInputAssociationBehavior);
+
+var _DataStoreBehavior = require('./DataStoreBehavior');
+
+var _DataStoreBehavior2 = _interopRequireDefault(_DataStoreBehavior);
+
+var _DeleteLaneBehavior = require('./DeleteLaneBehavior');
+
+var _DeleteLaneBehavior2 = _interopRequireDefault(_DeleteLaneBehavior);
+
+var _DropOnFlowBehavior = require('./DropOnFlowBehavior');
+
+var _DropOnFlowBehavior2 = _interopRequireDefault(_DropOnFlowBehavior);
+
+var _ImportDockingFix = require('./ImportDockingFix');
+
+var _ImportDockingFix2 = _interopRequireDefault(_ImportDockingFix);
+
+var _LabelBehavior = require('./LabelBehavior');
+
+var _LabelBehavior2 = _interopRequireDefault(_LabelBehavior);
+
+var _ModelingFeedback = require('./ModelingFeedback');
+
+var _ModelingFeedback2 = _interopRequireDefault(_ModelingFeedback);
+
+var _ReplaceConnectionBehavior = require('./ReplaceConnectionBehavior');
+
+var _ReplaceConnectionBehavior2 = _interopRequireDefault(_ReplaceConnectionBehavior);
+
+var _RemoveParticipantBehavior = require('./RemoveParticipantBehavior');
+
+var _RemoveParticipantBehavior2 = _interopRequireDefault(_RemoveParticipantBehavior);
+
+var _ReplaceElementBehaviour = require('./ReplaceElementBehaviour');
+
+var _ReplaceElementBehaviour2 = _interopRequireDefault(_ReplaceElementBehaviour);
+
+var _ResizeLaneBehavior = require('./ResizeLaneBehavior');
+
+var _ResizeLaneBehavior2 = _interopRequireDefault(_ResizeLaneBehavior);
+
+var _RemoveElementBehavior = require('./RemoveElementBehavior');
+
+var _RemoveElementBehavior2 = _interopRequireDefault(_RemoveElementBehavior);
+
+var _ToggleElementCollapseBehaviour = require('./ToggleElementCollapseBehaviour');
+
+var _ToggleElementCollapseBehaviour2 = _interopRequireDefault(_ToggleElementCollapseBehaviour);
+
+var _UnclaimIdBehavior = require('./UnclaimIdBehavior');
+
+var _UnclaimIdBehavior2 = _interopRequireDefault(_UnclaimIdBehavior);
+
+var _UpdateFlowNodeRefsBehavior = require('./UpdateFlowNodeRefsBehavior');
+
+var _UpdateFlowNodeRefsBehavior2 = _interopRequireDefault(_UpdateFlowNodeRefsBehavior);
+
+var _UnsetDefaultFlowBehavior = require('./UnsetDefaultFlowBehavior');
+
+var _UnsetDefaultFlowBehavior2 = _interopRequireDefault(_UnsetDefaultFlowBehavior);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['adaptiveLabelPositioningBehavior', 'appendBehavior', 'boundaryEventBehavior', 'copyPasteBehavior', 'createBoundaryEventBehavior', 'createDataObjectBehavior', 'dataStoreBehavior', 'createParticipantBehavior', 'dataInputAssociationBehavior', 'deleteLaneBehavior', 'dropOnFlowBehavior', 'importDockingFix', 'labelBehavior', 'modelingFeedback', 'removeElementBehavior', 'removeParticipantBehavior', 'replaceConnectionBehavior', 'replaceElementBehaviour', 'resizeLaneBehavior', 'toggleElementCollapseBehaviour', 'unclaimIdBehavior', 'unsetDefaultFlowBehavior', 'updateFlowNodeRefsBehavior'],
+ adaptiveLabelPositioningBehavior: ['type', _AdaptiveLabelPositioningBehavior2.default],
+ appendBehavior: ['type', _AppendBehavior2.default],
+ boundaryEventBehavior: ['type', _BoundaryEventBehavior2.default],
+ copyPasteBehavior: ['type', _CopyPasteBehavior2.default],
+ createBoundaryEventBehavior: ['type', _CreateBoundaryEventBehavior2.default],
+ createDataObjectBehavior: ['type', _CreateDataObjectBehavior2.default],
+ createParticipantBehavior: ['type', _CreateParticipantBehavior2.default],
+ dataInputAssociationBehavior: ['type', _DataInputAssociationBehavior2.default],
+ dataStoreBehavior: ['type', _DataStoreBehavior2.default],
+ deleteLaneBehavior: ['type', _DeleteLaneBehavior2.default],
+ dropOnFlowBehavior: ['type', _DropOnFlowBehavior2.default],
+ importDockingFix: ['type', _ImportDockingFix2.default],
+ labelBehavior: ['type', _LabelBehavior2.default],
+ modelingFeedback: ['type', _ModelingFeedback2.default],
+ replaceConnectionBehavior: ['type', _ReplaceConnectionBehavior2.default],
+ removeParticipantBehavior: ['type', _RemoveParticipantBehavior2.default],
+ replaceElementBehaviour: ['type', _ReplaceElementBehaviour2.default],
+ resizeLaneBehavior: ['type', _ResizeLaneBehavior2.default],
+ removeElementBehavior: ['type', _RemoveElementBehavior2.default],
+ toggleElementCollapseBehaviour: ['type', _ToggleElementCollapseBehaviour2.default],
+ unclaimIdBehavior: ['type', _UnclaimIdBehavior2.default],
+ updateFlowNodeRefsBehavior: ['type', _UpdateFlowNodeRefsBehavior2.default],
+ unsetDefaultFlowBehavior: ['type', _UnsetDefaultFlowBehavior2.default]
+};
+
+},{"./AdaptiveLabelPositioningBehavior":150,"./AppendBehavior":151,"./BoundaryEventBehavior":152,"./CopyPasteBehavior":153,"./CreateBoundaryEventBehavior":154,"./CreateDataObjectBehavior":155,"./CreateParticipantBehavior":156,"./DataInputAssociationBehavior":157,"./DataStoreBehavior":158,"./DeleteLaneBehavior":159,"./DropOnFlowBehavior":160,"./ImportDockingFix":161,"./LabelBehavior":162,"./ModelingFeedback":163,"./RemoveElementBehavior":164,"./RemoveParticipantBehavior":165,"./ReplaceConnectionBehavior":166,"./ReplaceElementBehaviour":167,"./ResizeLaneBehavior":168,"./ToggleElementCollapseBehaviour":169,"./UnclaimIdBehavior":170,"./UnsetDefaultFlowBehavior":171,"./UpdateFlowNodeRefsBehavior":172}],174:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.vectorLength = vectorLength;
+exports.getAngle = getAngle;
+exports.rotateVector = rotateVector;
+exports.perpendicularFoot = perpendicularFoot;
+exports.getDistancePointLine = getDistancePointLine;
+exports.getDistancePointPoint = getDistancePointPoint;
+/**
+ * Returns the length of a vector
+ *
+ * @param {Vector}
+ * @return {Float}
+ */
+function vectorLength(v) {
+ return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2));
+}
+
+/**
+ * Calculates the angle between a line a the yAxis
+ *
+ * @param {Array}
+ * @return {Float}
+ */
+function getAngle(line) {
+ // return value is between 0, 180 and -180, -0
+ // @janstuemmel: maybe replace return a/b with b/a
+ return Math.atan((line[1].y - line[0].y) / (line[1].x - line[0].x));
+}
+
+/**
+ * Rotates a vector by a given angle
+ *
+ * @param {Vector}
+ * @param {Float} Angle in radians
+ * @return {Vector}
+ */
+function rotateVector(vector, angle) {
+ return !angle ? vector : {
+ x: Math.cos(angle) * vector.x - Math.sin(angle) * vector.y,
+ y: Math.sin(angle) * vector.x + Math.cos(angle) * vector.y
+ };
+}
+
+/**
+ * Solves a 2D equation system
+ * a + r*b = c, where a,b,c are 2D vectors
+ *
+ * @param {Vector}
+ * @param {Vector}
+ * @param {Vector}
+ * @return {Float}
+ */
+function solveLambaSystem(a, b, c) {
+
+ // the 2d system
+ var system = [{ n: a[0] - c[0], lambda: b[0] }, { n: a[1] - c[1], lambda: b[1] }];
+
+ // solve
+ var n = system[0].n * b[0] + system[1].n * b[1],
+ l = system[0].lambda * b[0] + system[1].lambda * b[1];
+
+ return -n / l;
+}
+
+/**
+ * Position of perpendicular foot
+ *
+ * @param {Point}
+ * @param [ {Point}, {Point} ] line defined throug two points
+ * @return {Point} the perpendicular foot position
+ */
+function perpendicularFoot(point, line) {
+
+ var a = line[0],
+ b = line[1];
+
+ // relative position of b from a
+ var bd = { x: b.x - a.x, y: b.y - a.y };
+
+ // solve equation system to the parametrized vectors param real value
+ var r = solveLambaSystem([a.x, a.y], [bd.x, bd.y], [point.x, point.y]);
+
+ return { x: a.x + r * bd.x, y: a.y + r * bd.y };
+}
+
+/**
+ * Calculates the distance between a point and a line
+ *
+ * @param {Point}
+ * @param [ {Point}, {Point} ] line defined throug two points
+ * @return {Float} distance
+ */
+function getDistancePointLine(point, line) {
+
+ var pfPoint = perpendicularFoot(point, line);
+
+ // distance vector
+ var connectionVector = {
+ x: pfPoint.x - point.x,
+ y: pfPoint.y - point.y
+ };
+
+ return vectorLength(connectionVector);
+}
+
+/**
+ * Calculates the distance between two points
+ *
+ * @param {Point}
+ * @param {Point}
+ * @return {Float} distance
+ */
+function getDistancePointPoint(point1, point2) {
+
+ return vectorLength({
+ x: point1.x - point2.x,
+ y: point1.y - point2.y
+ });
+}
+
+},{}],175:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.findNewLabelLineStartIndex = findNewLabelLineStartIndex;
+exports.getLabelAdjustment = getLabelAdjustment;
+
+var _GeometricUtil = require('./GeometricUtil');
+
+var _LineAttachmentUtil = require('./LineAttachmentUtil');
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+function findNewLabelLineStartIndex(oldWaypoints, newWaypoints, attachment, hints) {
+
+ var index = attachment.segmentIndex;
+
+ var offset = newWaypoints.length - oldWaypoints.length;
+
+ // segmentMove happend
+ if (hints.segmentMove) {
+
+ var oldSegmentStartIndex = hints.segmentMove.segmentStartIndex,
+ newSegmentStartIndex = hints.segmentMove.newSegmentStartIndex;
+
+ // if label was on moved segment return new segment index
+ if (index === oldSegmentStartIndex) {
+ return newSegmentStartIndex;
+ }
+
+ // label is after new segment index
+ if (index >= newSegmentStartIndex) {
+ return index + offset < newSegmentStartIndex ? newSegmentStartIndex : index + offset;
+ }
+
+ // if label is before new segment index
+ return index;
+ }
+
+ // bendpointMove happend
+ if (hints.bendpointMove) {
+
+ var insert = hints.bendpointMove.insert,
+ bendpointIndex = hints.bendpointMove.bendpointIndex,
+ newIndex;
+
+ // waypoints length didnt change
+ if (offset === 0) {
+ return index;
+ }
+
+ // label behind new/removed bendpoint
+ if (index >= bendpointIndex) {
+ newIndex = insert ? index + 1 : index - 1;
+ }
+
+ // label before new/removed bendpoint
+ if (index < bendpointIndex) {
+
+ newIndex = index;
+
+ // decide label should take right or left segment
+ if (insert && attachment.type !== 'bendpoint' && bendpointIndex - 1 === index) {
+
+ var rel = relativePositionMidWaypoint(newWaypoints, bendpointIndex);
+
+ if (rel < attachment.relativeLocation) {
+ newIndex++;
+ }
+ }
+ }
+
+ return newIndex;
+ }
+
+ // start/end changed
+ if (offset === 0) {
+ return index;
+ }
+
+ if (hints.connectionStart) {
+ return index === 0 ? 0 : null;
+ }
+
+ if (hints.connectionEnd) {
+ return index === oldWaypoints.length - 2 ? newWaypoints.length - 2 : null;
+ }
+
+ // if nothing fits, return null
+ return null;
+}
+
+/**
+ * Calculate the required adjustment (move delta) for the given label
+ * after the connection waypoints got updated.
+ *
+ * @param {djs.model.Label} label
+ * @param {Array} newWaypoints
+ * @param {Array} oldWaypoints
+ * @param {Object} hints
+ *
+ * @return {Point} delta
+ */
+function getLabelAdjustment(label, newWaypoints, oldWaypoints, hints) {
+
+ var x = 0,
+ y = 0;
+
+ var labelPosition = getLabelMid(label);
+
+ // get closest attachment
+ var attachment = (0, _LineAttachmentUtil.getAttachment)(labelPosition, oldWaypoints),
+ oldLabelLineIndex = attachment.segmentIndex,
+ newLabelLineIndex = findNewLabelLineStartIndex(oldWaypoints, newWaypoints, attachment, hints);
+
+ if (newLabelLineIndex === null) {
+ return { x: x, y: y };
+ }
+
+ // should never happen
+ // TODO(@janstuemmel): throw an error here when connectionSegmentMove is refactored
+ if (newLabelLineIndex < 0 || newLabelLineIndex > newWaypoints.length - 2) {
+ return { x: x, y: y };
+ }
+
+ var oldLabelLine = getLine(oldWaypoints, oldLabelLineIndex),
+ newLabelLine = getLine(newWaypoints, newLabelLineIndex),
+ oldFoot = attachment.position;
+
+ var relativeFootPosition = getRelativeFootPosition(oldLabelLine, oldFoot),
+ angleDelta = getAngleDelta(oldLabelLine, newLabelLine);
+
+ // special rule if label on bendpoint
+ if (attachment.type === 'bendpoint') {
+
+ var offset = newWaypoints.length - oldWaypoints.length,
+ oldBendpointIndex = attachment.bendpointIndex,
+ oldBendpoint = oldWaypoints[oldBendpointIndex];
+
+ // bendpoint position hasnt changed, return same position
+ if (newWaypoints.indexOf(oldBendpoint) !== -1) {
+ return { x: x, y: y };
+ }
+
+ // new bendpoint and old bendpoint have same index, then just return the offset
+ if (offset === 0) {
+ var newBendpoint = newWaypoints[oldBendpointIndex];
+
+ return {
+ x: newBendpoint.x - attachment.position.x,
+ y: newBendpoint.y - attachment.position.y
+ };
+ }
+
+ // if bendpoints get removed
+ if (offset < 0 && oldBendpointIndex !== 0 && oldBendpointIndex < oldWaypoints.length - 1) {
+ relativeFootPosition = relativePositionMidWaypoint(oldWaypoints, oldBendpointIndex);
+ }
+ }
+
+ var newFoot = {
+ x: (newLabelLine[1].x - newLabelLine[0].x) * relativeFootPosition + newLabelLine[0].x,
+ y: (newLabelLine[1].y - newLabelLine[0].y) * relativeFootPosition + newLabelLine[0].y
+ };
+
+ // the rotated vector to label
+ var newLabelVector = (0, _GeometricUtil.rotateVector)({
+ x: labelPosition.x - oldFoot.x,
+ y: labelPosition.y - oldFoot.y
+ }, angleDelta);
+
+ // the new relative position
+ x = newFoot.x + newLabelVector.x - labelPosition.x;
+ y = newFoot.y + newLabelVector.y - labelPosition.y;
+
+ return (0, _LayoutUtil.roundPoint)({
+ x: x,
+ y: y
+ });
+}
+
+// HELPERS //////////////////////
+
+function relativePositionMidWaypoint(waypoints, idx) {
+
+ var distanceSegment1 = (0, _GeometricUtil.getDistancePointPoint)(waypoints[idx - 1], waypoints[idx]),
+ distanceSegment2 = (0, _GeometricUtil.getDistancePointPoint)(waypoints[idx], waypoints[idx + 1]);
+
+ var relativePosition = distanceSegment1 / (distanceSegment1 + distanceSegment2);
+
+ return relativePosition;
+}
+
+function getLabelMid(label) {
+ return {
+ x: label.x + label.width / 2,
+ y: label.y + label.height / 2
+ };
+}
+
+function getAngleDelta(l1, l2) {
+ var a1 = (0, _GeometricUtil.getAngle)(l1),
+ a2 = (0, _GeometricUtil.getAngle)(l2);
+ return a2 - a1;
+}
+
+function getLine(waypoints, idx) {
+ return [waypoints[idx], waypoints[idx + 1]];
+}
+
+function getRelativeFootPosition(line, foot) {
+
+ var length = (0, _GeometricUtil.getDistancePointPoint)(line[0], line[1]),
+ lengthToFoot = (0, _GeometricUtil.getDistancePointPoint)(line[0], foot);
+
+ return length === 0 ? 0 : lengthToFoot / length;
+}
+
+},{"./GeometricUtil":174,"./LineAttachmentUtil":176,"diagram-js/lib/layout/LayoutUtil":380}],176:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.getAttachment = getAttachment;
+var sqrt = Math.sqrt,
+ min = Math.min,
+ max = Math.max,
+ abs = Math.abs;
+
+/**
+ * Calculate the square (power to two) of a number.
+ *
+ * @param {Number} n
+ *
+ * @return {Number}
+ */
+function sq(n) {
+ return Math.pow(n, 2);
+}
+
+/**
+ * Get distance between two points.
+ *
+ * @param {Point} p1
+ * @param {Point} p2
+ *
+ * @return {Number}
+ */
+function getDistance(p1, p2) {
+ return sqrt(sq(p1.x - p2.x) + sq(p1.y - p2.y));
+}
+
+/**
+ * Return the attachment of the given point on the specified line.
+ *
+ * The attachment is either a bendpoint (attached to the given point)
+ * or segment (attached to a location on a line segment) attachment:
+ *
+ * ```javascript
+ * var pointAttachment = {
+ * type: 'bendpoint',
+ * bendpointIndex: 3,
+ * position: { x: 10, y: 10 } // the attach point on the line
+ * };
+ *
+ * var segmentAttachment = {
+ * type: 'segment',
+ * segmentIndex: 2,
+ * relativeLocation: 0.31, // attach point location between 0 (at start) and 1 (at end)
+ * position: { x: 10, y: 10 } // the attach point on the line
+ * };
+ * ```
+ *
+ * @param {Point} point
+ * @param {Array} line
+ *
+ * @return {Object} attachment
+ */
+function getAttachment(point, line) {
+
+ var idx = 0,
+ segmentStart,
+ segmentEnd,
+ segmentStartDistance,
+ segmentEndDistance,
+ attachmentPosition,
+ minDistance,
+ intersections,
+ attachment,
+ attachmentDistance,
+ closestAttachmentDistance,
+ closestAttachment;
+
+ for (idx = 0; idx < line.length - 1; idx++) {
+
+ segmentStart = line[idx];
+ segmentEnd = line[idx + 1];
+
+ if (pointsEqual(segmentStart, segmentEnd)) {
+ intersections = [segmentStart];
+ } else {
+ segmentStartDistance = getDistance(point, segmentStart);
+ segmentEndDistance = getDistance(point, segmentEnd);
+
+ minDistance = min(segmentStartDistance, segmentEndDistance);
+
+ intersections = getCircleSegmentIntersections(segmentStart, segmentEnd, point, minDistance);
+ }
+
+ if (intersections.length < 1) {
+ throw new Error('expected between [1, 2] circle -> line intersections');
+ }
+
+ // one intersection -> bendpoint attachment
+ if (intersections.length === 1) {
+ attachment = {
+ type: 'bendpoint',
+ position: intersections[0],
+ segmentIndex: idx,
+ bendpointIndex: pointsEqual(segmentStart, intersections[0]) ? idx : idx + 1
+ };
+ }
+
+ // two intersections -> segment attachment
+ if (intersections.length === 2) {
+
+ attachmentPosition = mid(intersections[0], intersections[1]);
+
+ attachment = {
+ type: 'segment',
+ position: attachmentPosition,
+ segmentIndex: idx,
+ relativeLocation: getDistance(segmentStart, attachmentPosition) / getDistance(segmentStart, segmentEnd)
+ };
+ }
+
+ attachmentDistance = getDistance(attachment.position, point);
+
+ if (!closestAttachment || closestAttachmentDistance > attachmentDistance) {
+ closestAttachment = attachment;
+ closestAttachmentDistance = attachmentDistance;
+ }
+ }
+
+ return closestAttachment;
+}
+
+/**
+ * Gets the intersection between a circle and a line segment.
+ *
+ * @param {Point} s1 segment start
+ * @param {Point} s2 segment end
+ * @param {Point} cc circle center
+ * @param {Number} cr circle radius
+ *
+ * @return {Array} intersections
+ */
+function getCircleSegmentIntersections(s1, s2, cc, cr) {
+
+ var baX = s2.x - s1.x;
+ var baY = s2.y - s1.y;
+ var caX = cc.x - s1.x;
+ var caY = cc.y - s1.y;
+
+ var a = baX * baX + baY * baY;
+ var bBy2 = baX * caX + baY * caY;
+ var c = caX * caX + caY * caY - cr * cr;
+
+ var pBy2 = bBy2 / a;
+ var q = c / a;
+
+ var disc = pBy2 * pBy2 - q;
+
+ // check against negative value to work around
+ // negative, very close to zero results (-4e-15)
+ // being produced in some environments
+ if (disc < 0 && disc > -0.000001) {
+ disc = 0;
+ }
+
+ if (disc < 0) {
+ return [];
+ }
+
+ // if disc == 0 ... dealt with later
+ var tmpSqrt = sqrt(disc);
+ var abScalingFactor1 = -pBy2 + tmpSqrt;
+ var abScalingFactor2 = -pBy2 - tmpSqrt;
+
+ var i1 = {
+ x: s1.x - baX * abScalingFactor1,
+ y: s1.y - baY * abScalingFactor1
+ };
+
+ if (disc === 0) {
+ // abScalingFactor1 == abScalingFactor2
+ return [i1];
+ }
+
+ var i2 = {
+ x: s1.x - baX * abScalingFactor2,
+ y: s1.y - baY * abScalingFactor2
+ };
+
+ // return only points on line segment
+ return [i1, i2].filter(function (p) {
+ return isPointInSegment(p, s1, s2);
+ });
+}
+
+function isPointInSegment(p, segmentStart, segmentEnd) {
+ return fenced(p.x, segmentStart.x, segmentEnd.x) && fenced(p.y, segmentStart.y, segmentEnd.y);
+}
+
+function fenced(n, rangeStart, rangeEnd) {
+
+ // use matching threshold to work around
+ // precisison errors in intersection computation
+
+ return n >= min(rangeStart, rangeEnd) - EQUAL_THRESHOLD && n <= max(rangeStart, rangeEnd) + EQUAL_THRESHOLD;
+}
+
+/**
+ * Calculate mid of two points.
+ *
+ * @param {Point} p1
+ * @param {Point} p2
+ *
+ * @return {Point}
+ */
+function mid(p1, p2) {
+
+ return {
+ x: (p1.x + p2.x) / 2,
+ y: (p1.y + p2.y) / 2
+ };
+}
+
+var EQUAL_THRESHOLD = 0.1;
+
+function pointsEqual(p1, p2) {
+
+ return abs(p1.x - p2.x) <= EQUAL_THRESHOLD && abs(p1.y - p2.y) <= EQUAL_THRESHOLD;
+}
+
+},{}],177:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = lineIntersect;
+/**
+ * Returns the intersection between two line segments a and b.
+ *
+ * @param {Point} l1s
+ * @param {Point} l1e
+ * @param {Point} l2s
+ * @param {Point} l2e
+ *
+ * @return {Point}
+ */
+function lineIntersect(l1s, l1e, l2s, l2e) {
+ // if the lines intersect, the result contains the x and y of the
+ // intersection (treating the lines as infinite) and booleans for
+ // whether line segment 1 or line segment 2 contain the point
+ var denominator, a, b, c, numerator;
+
+ denominator = (l2e.y - l2s.y) * (l1e.x - l1s.x) - (l2e.x - l2s.x) * (l1e.y - l1s.y);
+
+ if (denominator == 0) {
+ return null;
+ }
+
+ a = l1s.y - l2s.y;
+ b = l1s.x - l2s.x;
+ numerator = (l2e.x - l2s.x) * a - (l2e.y - l2s.y) * b;
+
+ c = numerator / denominator;
+
+ // if we cast these lines infinitely in
+ // both directions, they intersect here
+ return {
+ x: Math.round(l1s.x + c * (l1e.x - l1s.x)),
+ y: Math.round(l1s.y + c * (l1e.y - l1s.y))
+ };
+}
+
+},{}],178:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AddLaneHandler;
+
+var _minDash = require('min-dash');
+
+var _Elements = require('diagram-js/lib/util/Elements');
+
+var _LaneUtil = require('../util/LaneUtil');
+
+/**
+ * A handler that allows us to add a new lane
+ * above or below an existing one.
+ *
+ * @param {Modeling} modeling
+ */
+function AddLaneHandler(modeling, spaceTool) {
+ this._modeling = modeling;
+ this._spaceTool = spaceTool;
+}
+
+AddLaneHandler.$inject = ['modeling', 'spaceTool'];
+
+AddLaneHandler.prototype.preExecute = function (context) {
+
+ var spaceTool = this._spaceTool,
+ modeling = this._modeling;
+
+ var shape = context.shape,
+ location = context.location;
+
+ var lanesRoot = (0, _LaneUtil.getLanesRoot)(shape);
+
+ var isRoot = lanesRoot === shape,
+ laneParent = isRoot ? shape : shape.parent;
+
+ var existingChildLanes = (0, _LaneUtil.getChildLanes)(laneParent);
+
+ // (0) add a lane if we currently got none and are adding to root
+ if (!existingChildLanes.length) {
+ modeling.createShape({ type: 'bpmn:Lane' }, {
+ x: shape.x + _LaneUtil.LANE_INDENTATION,
+ y: shape.y,
+ width: shape.width - _LaneUtil.LANE_INDENTATION,
+ height: shape.height
+ }, laneParent);
+ }
+
+ // (1) collect affected elements to create necessary space
+ var allAffected = [];
+
+ (0, _Elements.eachElement)(lanesRoot, function (element) {
+ allAffected.push(element);
+
+ if (element === shape) {
+ return [];
+ }
+
+ return (0, _minDash.filter)(element.children, function (c) {
+ return c !== shape;
+ });
+ });
+
+ var offset = location === 'top' ? -120 : 120,
+ lanePosition = location === 'top' ? shape.y : shape.y + shape.height,
+ spacePos = lanePosition + (location === 'top' ? 10 : -10),
+ direction = location === 'top' ? 'n' : 's';
+
+ var adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos);
+
+ spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: 0, y: offset }, direction);
+
+ // (2) create new lane at open space
+ context.newLane = modeling.createShape({ type: 'bpmn:Lane' }, {
+ x: shape.x + (isRoot ? _LaneUtil.LANE_INDENTATION : 0),
+ y: lanePosition - (location === 'top' ? 120 : 0),
+ width: shape.width - (isRoot ? _LaneUtil.LANE_INDENTATION : 0),
+ height: 120
+ }, laneParent);
+};
+
+},{"../util/LaneUtil":188,"diagram-js/lib/util/Elements":396,"min-dash":505}],179:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = IdClaimHandler;
+function IdClaimHandler(moddle) {
+ this._moddle = moddle;
+}
+
+IdClaimHandler.$inject = ['moddle'];
+
+IdClaimHandler.prototype.execute = function (context) {
+ var ids = this._moddle.ids,
+ id = context.id,
+ element = context.element,
+ claiming = context.claiming;
+
+ if (claiming) {
+ ids.claim(id, element);
+ } else {
+ ids.unclaim(id);
+ }
+};
+
+/**
+ * Command revert implementation.
+ */
+IdClaimHandler.prototype.revert = function (context) {
+ var ids = this._moddle.ids,
+ id = context.id,
+ element = context.element,
+ claiming = context.claiming;
+
+ if (claiming) {
+ ids.unclaim(id);
+ } else {
+ ids.claim(id, element);
+ }
+};
+
+},{}],180:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ResizeLaneHandler;
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _LaneUtil = require('../util/LaneUtil');
+
+var _Elements = require('diagram-js/lib/util/Elements');
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _ResizeUtil = require('diagram-js/lib/features/resize/ResizeUtil');
+
+/**
+ * A handler that resizes a lane.
+ *
+ * @param {Modeling} modeling
+ */
+function ResizeLaneHandler(modeling, spaceTool) {
+ this._modeling = modeling;
+ this._spaceTool = spaceTool;
+}
+
+ResizeLaneHandler.$inject = ['modeling', 'spaceTool'];
+
+ResizeLaneHandler.prototype.preExecute = function (context) {
+
+ var shape = context.shape,
+ newBounds = context.newBounds,
+ balanced = context.balanced;
+
+ if (balanced !== false) {
+ this.resizeBalanced(shape, newBounds);
+ } else {
+ this.resizeSpace(shape, newBounds);
+ }
+};
+
+/**
+ * Resize balanced, adjusting next / previous lane sizes.
+ *
+ * @param {djs.model.Shape} shape
+ * @param {Bounds} newBounds
+ */
+ResizeLaneHandler.prototype.resizeBalanced = function (shape, newBounds) {
+
+ var modeling = this._modeling;
+
+ var resizeNeeded = (0, _LaneUtil.computeLanesResize)(shape, newBounds);
+
+ // resize the lane
+ modeling.resizeShape(shape, newBounds);
+
+ // resize other lanes as needed
+ resizeNeeded.forEach(function (r) {
+ modeling.resizeShape(r.shape, r.newBounds);
+ });
+};
+
+/**
+ * Resize, making actual space and moving below / above elements.
+ *
+ * @param {djs.model.Shape} shape
+ * @param {Bounds} newBounds
+ */
+ResizeLaneHandler.prototype.resizeSpace = function (shape, newBounds) {
+ var spaceTool = this._spaceTool;
+
+ var shapeTrbl = (0, _LayoutUtil.asTRBL)(shape),
+ newTrbl = (0, _LayoutUtil.asTRBL)(newBounds);
+
+ var trblDiff = (0, _ResizeUtil.substractTRBL)(newTrbl, shapeTrbl);
+
+ var lanesRoot = (0, _LaneUtil.getLanesRoot)(shape);
+
+ var allAffected = [],
+ allLanes = [];
+
+ (0, _Elements.eachElement)(lanesRoot, function (element) {
+ allAffected.push(element);
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || (0, _ModelUtil.is)(element, 'bpmn:Participant')) {
+ allLanes.push(element);
+ }
+
+ return element.children;
+ });
+
+ var change, spacePos, direction, offset, adjustments;
+
+ if (trblDiff.bottom || trblDiff.top) {
+
+ change = trblDiff.bottom || trblDiff.top;
+ spacePos = shape.y + (trblDiff.bottom ? shape.height : 0) + (trblDiff.bottom ? -10 : 10);
+ direction = trblDiff.bottom ? 's' : 'n';
+
+ offset = trblDiff.top > 0 || trblDiff.bottom < 0 ? -change : change;
+
+ adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos);
+
+ spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: 0, y: change }, direction);
+ }
+
+ if (trblDiff.left || trblDiff.right) {
+
+ change = trblDiff.right || trblDiff.left;
+ spacePos = shape.x + (trblDiff.right ? shape.width : 0) + (trblDiff.right ? -10 : 100);
+ direction = trblDiff.right ? 'e' : 'w';
+
+ offset = trblDiff.left > 0 || trblDiff.right < 0 ? -change : change;
+
+ adjustments = spaceTool.calculateAdjustments(allLanes, 'x', offset, spacePos);
+
+ spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: change, y: 0 }, direction);
+ }
+};
+
+},{"../../../util/ModelUtil":216,"../util/LaneUtil":188,"diagram-js/lib/features/resize/ResizeUtil":351,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Elements":396}],181:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = SetColorHandler;
+
+var _minDash = require('min-dash');
+
+var DEFAULT_COLORS = {
+ fill: undefined,
+ stroke: undefined
+};
+
+function SetColorHandler(commandStack) {
+ this._commandStack = commandStack;
+}
+
+SetColorHandler.$inject = ['commandStack'];
+
+SetColorHandler.prototype.postExecute = function (context) {
+ var elements = context.elements,
+ colors = context.colors || DEFAULT_COLORS;
+
+ var self = this;
+
+ var di = {};
+
+ if ('fill' in colors) {
+ (0, _minDash.assign)(di, { fill: colors.fill });
+ }
+
+ if ('stroke' in colors) {
+ (0, _minDash.assign)(di, { stroke: colors.stroke });
+ }
+
+ (0, _minDash.forEach)(elements, function (element) {
+
+ self._commandStack.execute('element.updateProperties', {
+ element: element,
+ properties: {
+ di: di
+ }
+ });
+ });
+};
+
+},{"min-dash":505}],182:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = SplitLaneHandler;
+
+var _LaneUtil = require('../util/LaneUtil');
+
+/**
+ * A handler that splits a lane into a number of sub-lanes,
+ * creating new sub lanes, if neccessary.
+ *
+ * @param {Modeling} modeling
+ */
+function SplitLaneHandler(modeling, translate) {
+ this._modeling = modeling;
+ this._translate = translate;
+}
+
+SplitLaneHandler.$inject = ['modeling', 'translate'];
+
+SplitLaneHandler.prototype.preExecute = function (context) {
+
+ var modeling = this._modeling,
+ translate = this._translate;
+
+ var shape = context.shape,
+ newLanesCount = context.count;
+
+ var childLanes = (0, _LaneUtil.getChildLanes)(shape),
+ existingLanesCount = childLanes.length;
+
+ if (existingLanesCount > newLanesCount) {
+ throw new Error(translate('more than {count} child lanes', { count: newLanesCount }));
+ }
+
+ var newLanesHeight = Math.round(shape.height / newLanesCount);
+
+ // Iterate from top to bottom in child lane order,
+ // resizing existing lanes and creating new ones
+ // so that they split the parent proportionally.
+ //
+ // Due to rounding related errors, the bottom lane
+ // needs to take up all the remaining space.
+ var laneY, laneHeight, laneBounds, newLaneAttrs, idx;
+
+ for (idx = 0; idx < newLanesCount; idx++) {
+
+ laneY = shape.y + idx * newLanesHeight;
+
+ // if bottom lane
+ if (idx === newLanesCount - 1) {
+ laneHeight = shape.height - newLanesHeight * idx;
+ } else {
+ laneHeight = newLanesHeight;
+ }
+
+ laneBounds = {
+ x: shape.x + _LaneUtil.LANE_INDENTATION,
+ y: laneY,
+ width: shape.width - _LaneUtil.LANE_INDENTATION,
+ height: laneHeight
+ };
+
+ if (idx < existingLanesCount) {
+ // resize existing lane
+ modeling.resizeShape(childLanes[idx], laneBounds);
+ } else {
+ // create a new lane at position
+ newLaneAttrs = {
+ type: 'bpmn:Lane'
+ };
+
+ modeling.createShape(newLaneAttrs, laneBounds, shape);
+ }
+ }
+};
+
+},{"../util/LaneUtil":188}],183:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = UpdateCanvasRootHandler;
+
+var _Collections = require('diagram-js/lib/util/Collections');
+
+function UpdateCanvasRootHandler(canvas, modeling) {
+ this._canvas = canvas;
+ this._modeling = modeling;
+}
+
+UpdateCanvasRootHandler.$inject = ['canvas', 'modeling'];
+
+UpdateCanvasRootHandler.prototype.execute = function (context) {
+
+ var canvas = this._canvas;
+
+ var newRoot = context.newRoot,
+ newRootBusinessObject = newRoot.businessObject,
+ oldRoot = canvas.getRootElement(),
+ oldRootBusinessObject = oldRoot.businessObject,
+ bpmnDefinitions = oldRootBusinessObject.$parent,
+ diPlane = oldRootBusinessObject.di;
+
+ // (1) replace process old <> new root
+ canvas.setRootElement(newRoot, true);
+
+ // (2) update root elements
+ (0, _Collections.add)(bpmnDefinitions.rootElements, newRootBusinessObject);
+ newRootBusinessObject.$parent = bpmnDefinitions;
+
+ (0, _Collections.remove)(bpmnDefinitions.rootElements, oldRootBusinessObject);
+ oldRootBusinessObject.$parent = null;
+
+ // (3) wire di
+ oldRootBusinessObject.di = null;
+
+ diPlane.bpmnElement = newRootBusinessObject;
+ newRootBusinessObject.di = diPlane;
+
+ context.oldRoot = oldRoot;
+
+ // TODO(nikku): return changed elements?
+ // return [ newRoot, oldRoot ];
+};
+
+UpdateCanvasRootHandler.prototype.revert = function (context) {
+
+ var canvas = this._canvas;
+
+ var newRoot = context.newRoot,
+ newRootBusinessObject = newRoot.businessObject,
+ oldRoot = context.oldRoot,
+ oldRootBusinessObject = oldRoot.businessObject,
+ bpmnDefinitions = newRootBusinessObject.$parent,
+ diPlane = newRootBusinessObject.di;
+
+ // (1) replace process old <> new root
+ canvas.setRootElement(oldRoot, true);
+
+ // (2) update root elements
+ (0, _Collections.remove)(bpmnDefinitions.rootElements, newRootBusinessObject);
+ newRootBusinessObject.$parent = null;
+
+ (0, _Collections.add)(bpmnDefinitions.rootElements, oldRootBusinessObject);
+ oldRootBusinessObject.$parent = bpmnDefinitions;
+
+ // (3) wire di
+ newRootBusinessObject.di = null;
+
+ diPlane.bpmnElement = oldRootBusinessObject;
+ oldRootBusinessObject.di = diPlane;
+
+ // TODO(nikku): return changed elements?
+ // return [ newRoot, oldRoot ];
+};
+
+},{"diagram-js/lib/util/Collections":393}],184:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = UpdateFlowNodeRefsHandler;
+
+var _LaneUtil = require('../util/LaneUtil');
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _Collections = require('diagram-js/lib/util/Collections');
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var FLOW_NODE_REFS_ATTR = 'flowNodeRef',
+ LANES_ATTR = 'lanes';
+
+/**
+ * A handler that updates lane refs on changed elements
+ */
+function UpdateFlowNodeRefsHandler(elementRegistry) {
+ this._elementRegistry = elementRegistry;
+}
+
+UpdateFlowNodeRefsHandler.$inject = ['elementRegistry'];
+
+UpdateFlowNodeRefsHandler.prototype.computeUpdates = function (flowNodeShapes, laneShapes) {
+
+ var handledNodes = {};
+
+ var updates = [];
+
+ var participantCache = {};
+
+ var allFlowNodeShapes = [];
+
+ function isInLaneShape(element, laneShape) {
+
+ var laneTrbl = (0, _LayoutUtil.asTRBL)(laneShape);
+
+ var elementMid = {
+ x: element.x + element.width / 2,
+ y: element.y + element.height / 2
+ };
+
+ return elementMid.x > laneTrbl.left && elementMid.x < laneTrbl.right && elementMid.y > laneTrbl.top && elementMid.y < laneTrbl.bottom;
+ }
+
+ function addFlowNodeShape(flowNodeShape) {
+ if (!handledNodes[flowNodeShape.id]) {
+ allFlowNodeShapes.push(flowNodeShape);
+ handledNodes[flowNodeShape.id] = flowNodeShape;
+ }
+ }
+
+ function getAllLaneShapes(flowNodeShape) {
+
+ var root = (0, _LaneUtil.getLanesRoot)(flowNodeShape);
+
+ if (!participantCache[root.id]) {
+ participantCache[root.id] = (0, _LaneUtil.collectLanes)(root);
+ }
+
+ return participantCache[root.id];
+ }
+
+ function getNewLanes(flowNodeShape) {
+ if (!flowNodeShape.parent) {
+ return [];
+ }
+
+ var allLaneShapes = getAllLaneShapes(flowNodeShape);
+
+ return allLaneShapes.filter(function (l) {
+ return isInLaneShape(flowNodeShape, l);
+ }).map(function (shape) {
+ return shape.businessObject;
+ });
+ }
+
+ laneShapes.forEach(function (laneShape) {
+ var root = (0, _LaneUtil.getLanesRoot)(laneShape);
+
+ if (!root || handledNodes[root.id]) {
+ return;
+ }
+
+ var children = root.children.filter(function (c) {
+ return (0, _ModelUtil.is)(c, 'bpmn:FlowNode');
+ });
+
+ children.forEach(addFlowNodeShape);
+
+ handledNodes[root.id] = root;
+ });
+
+ flowNodeShapes.forEach(addFlowNodeShape);
+
+ allFlowNodeShapes.forEach(function (flowNodeShape) {
+
+ var flowNode = flowNodeShape.businessObject;
+
+ var lanes = flowNode.get(LANES_ATTR),
+ remove = lanes.slice(),
+ add = getNewLanes(flowNodeShape);
+
+ updates.push({ flowNode: flowNode, remove: remove, add: add });
+ });
+
+ laneShapes.forEach(function (laneShape) {
+
+ var lane = laneShape.businessObject;
+
+ // lane got removed XX-)
+ if (!laneShape.parent) {
+ lane.get(FLOW_NODE_REFS_ATTR).forEach(function (flowNode) {
+ updates.push({ flowNode: flowNode, remove: [lane], add: [] });
+ });
+ }
+ });
+
+ return updates;
+};
+
+UpdateFlowNodeRefsHandler.prototype.execute = function (context) {
+
+ var updates = context.updates;
+
+ if (!updates) {
+ updates = context.updates = this.computeUpdates(context.flowNodeShapes, context.laneShapes);
+ }
+
+ updates.forEach(function (update) {
+
+ var flowNode = update.flowNode,
+ lanes = flowNode.get(LANES_ATTR);
+
+ // unwire old
+ update.remove.forEach(function (oldLane) {
+ (0, _Collections.remove)(lanes, oldLane);
+ (0, _Collections.remove)(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode);
+ });
+
+ // wire new
+ update.add.forEach(function (newLane) {
+ (0, _Collections.add)(lanes, newLane);
+ (0, _Collections.add)(newLane.get(FLOW_NODE_REFS_ATTR), flowNode);
+ });
+ });
+
+ // TODO(nikku): return changed elements
+ // return [ ... ];
+};
+
+UpdateFlowNodeRefsHandler.prototype.revert = function (context) {
+
+ var updates = context.updates;
+
+ updates.forEach(function (update) {
+
+ var flowNode = update.flowNode,
+ lanes = flowNode.get(LANES_ATTR);
+
+ // unwire new
+ update.add.forEach(function (newLane) {
+ (0, _Collections.remove)(lanes, newLane);
+ (0, _Collections.remove)(newLane.get(FLOW_NODE_REFS_ATTR), flowNode);
+ });
+
+ // wire old
+ update.remove.forEach(function (oldLane) {
+ (0, _Collections.add)(lanes, oldLane);
+ (0, _Collections.add)(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode);
+ });
+ });
+
+ // TODO(nikku): return changed elements
+ // return [ ... ];
+};
+
+},{"../../../util/ModelUtil":216,"../util/LaneUtil":188,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Collections":393}],185:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = UpdatePropertiesHandler;
+
+var _minDash = require('min-dash');
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var DEFAULT_FLOW = 'default',
+ ID = 'id',
+ DI = 'di';
+
+var NULL_DIMENSIONS = {
+ width: 0,
+ height: 0
+};
+
+/**
+ * A handler that implements a BPMN 2.0 property update.
+ *
+ * This should be used to set simple properties on elements with
+ * an underlying BPMN business object.
+ *
+ * Use respective diagram-js provided handlers if you would
+ * like to perform automated modeling.
+ */
+function UpdatePropertiesHandler(elementRegistry, moddle, translate, modeling, textRenderer) {
+
+ this._elementRegistry = elementRegistry;
+ this._moddle = moddle;
+ this._translate = translate;
+ this._modeling = modeling;
+ this._textRenderer = textRenderer;
+}
+
+UpdatePropertiesHandler.$inject = ['elementRegistry', 'moddle', 'translate', 'modeling', 'textRenderer'];
+
+// api //////////////////////
+
+/**
+ * Updates a BPMN element with a list of new properties
+ *
+ * @param {Object} context
+ * @param {djs.model.Base} context.element the element to update
+ * @param {Object} context.properties a list of properties to set on the element's
+ * businessObject (the BPMN model element)
+ *
+ * @return {Array} the updated element
+ */
+UpdatePropertiesHandler.prototype.execute = function (context) {
+
+ var element = context.element,
+ changed = [element],
+ translate = this._translate;
+
+ if (!element) {
+ throw new Error(translate('element required'));
+ }
+
+ var elementRegistry = this._elementRegistry,
+ ids = this._moddle.ids;
+
+ var businessObject = element.businessObject,
+ properties = unwrapBusinessObjects(context.properties),
+ oldProperties = context.oldProperties || getProperties(businessObject, properties);
+
+ if (isIdChange(properties, businessObject)) {
+ ids.unclaim(businessObject[ID]);
+
+ elementRegistry.updateId(element, properties[ID]);
+
+ ids.claim(properties[ID], businessObject);
+ }
+
+ // correctly indicate visual changes on default flow updates
+ if (DEFAULT_FLOW in properties) {
+
+ if (properties[DEFAULT_FLOW]) {
+ changed.push(elementRegistry.get(properties[DEFAULT_FLOW].id));
+ }
+
+ if (businessObject[DEFAULT_FLOW]) {
+ changed.push(elementRegistry.get(businessObject[DEFAULT_FLOW].id));
+ }
+ }
+
+ // update properties
+ setProperties(businessObject, properties);
+
+ // store old values
+ context.oldProperties = oldProperties;
+ context.changed = changed;
+
+ // indicate changed on objects affected by the update
+ return changed;
+};
+
+UpdatePropertiesHandler.prototype.postExecute = function (context) {
+ var element = context.element,
+ label = element.label;
+
+ var text = label && (0, _ModelUtil.getBusinessObject)(label).name;
+
+ if (!text) {
+ return;
+ }
+
+ // get layouted text bounds and resize external
+ // external label accordingly
+ var newLabelBounds = this._textRenderer.getExternalLabelBounds(label, text);
+
+ this._modeling.resizeShape(label, newLabelBounds, NULL_DIMENSIONS);
+};
+
+/**
+ * Reverts the update on a BPMN elements properties.
+ *
+ * @param {Object} context
+ *
+ * @return {djs.model.Base} the updated element
+ */
+UpdatePropertiesHandler.prototype.revert = function (context) {
+
+ var element = context.element,
+ properties = context.properties,
+ oldProperties = context.oldProperties,
+ businessObject = element.businessObject,
+ elementRegistry = this._elementRegistry,
+ ids = this._moddle.ids;
+
+ // update properties
+ setProperties(businessObject, oldProperties);
+
+ if (isIdChange(properties, businessObject)) {
+ ids.unclaim(properties[ID]);
+
+ elementRegistry.updateId(element, oldProperties[ID]);
+
+ ids.claim(oldProperties[ID], businessObject);
+ }
+
+ return context.changed;
+};
+
+function isIdChange(properties, businessObject) {
+ return ID in properties && properties[ID] !== businessObject[ID];
+}
+
+function getProperties(businessObject, properties) {
+ var propertyNames = (0, _minDash.keys)(properties);
+
+ return (0, _minDash.reduce)(propertyNames, function (result, key) {
+
+ // handle DI seperately
+ if (key !== DI) {
+ result[key] = businessObject.get(key);
+ } else {
+ result[key] = getDiProperties(businessObject.di, (0, _minDash.keys)(properties.di));
+ }
+
+ return result;
+ }, {});
+}
+
+function getDiProperties(di, propertyNames) {
+ return (0, _minDash.reduce)(propertyNames, function (result, key) {
+ result[key] = di.get(key);
+
+ return result;
+ }, {});
+}
+
+function setProperties(businessObject, properties) {
+ (0, _minDash.forEach)(properties, function (value, key) {
+
+ if (key !== DI) {
+ businessObject.set(key, value);
+ } else {
+ // only update, if businessObject.di exists
+ if (businessObject.di) {
+ setDiProperties(businessObject.di, value);
+ }
+ }
+ });
+}
+
+function setDiProperties(di, properties) {
+ (0, _minDash.forEach)(properties, function (value, key) {
+ di.set(key, value);
+ });
+}
+
+var referencePropertyNames = ['default'];
+
+/**
+ * Make sure we unwrap the actual business object
+ * behind diagram element that may have been
+ * passed as arguments.
+ *
+ * @param {Object} properties
+ *
+ * @return {Object} unwrappedProps
+ */
+function unwrapBusinessObjects(properties) {
+
+ var unwrappedProps = (0, _minDash.assign)({}, properties);
+
+ referencePropertyNames.forEach(function (name) {
+ if (name in properties) {
+ unwrappedProps[name] = (0, _ModelUtil.getBusinessObject)(unwrappedProps[name]);
+ }
+ });
+
+ return unwrappedProps;
+}
+
+},{"../../../util/ModelUtil":216,"min-dash":505}],186:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = UpdateSemanticParentHandler;
+function UpdateSemanticParentHandler(bpmnUpdater) {
+ this._bpmnUpdater = bpmnUpdater;
+}
+
+UpdateSemanticParentHandler.$inject = ['bpmnUpdater'];
+
+UpdateSemanticParentHandler.prototype.execute = function (context) {
+ var dataStoreBo = context.dataStoreBo,
+ newSemanticParent = context.newSemanticParent,
+ newDiParent = context.newDiParent;
+
+ context.oldSemanticParent = dataStoreBo.$parent;
+ context.oldDiParent = dataStoreBo.di.$parent;
+
+ // update semantic parent
+ this._bpmnUpdater.updateSemanticParent(dataStoreBo, newSemanticParent);
+
+ // update DI parent
+ this._bpmnUpdater.updateDiParent(dataStoreBo.di, newDiParent);
+};
+
+UpdateSemanticParentHandler.prototype.revert = function (context) {
+ var dataStoreBo = context.dataStoreBo,
+ oldSemanticParent = context.oldSemanticParent,
+ oldDiParent = context.oldDiParent;
+
+ // update semantic parent
+ this._bpmnUpdater.updateSemanticParent(dataStoreBo, oldSemanticParent);
+
+ // update DI parent
+ this._bpmnUpdater.updateDiParent(dataStoreBo.di, oldDiParent);
+};
+
+},{}],187:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _behavior = require('./behavior');
+
+var _behavior2 = _interopRequireDefault(_behavior);
+
+var _rules = require('../rules');
+
+var _rules2 = _interopRequireDefault(_rules);
+
+var _ordering = require('../ordering');
+
+var _ordering2 = _interopRequireDefault(_ordering);
+
+var _replace = require('../replace');
+
+var _replace2 = _interopRequireDefault(_replace);
+
+var _command = require('diagram-js/lib/command');
+
+var _command2 = _interopRequireDefault(_command);
+
+var _tooltips = require('diagram-js/lib/features/tooltips');
+
+var _tooltips2 = _interopRequireDefault(_tooltips);
+
+var _labelSupport = require('diagram-js/lib/features/label-support');
+
+var _labelSupport2 = _interopRequireDefault(_labelSupport);
+
+var _attachSupport = require('diagram-js/lib/features/attach-support');
+
+var _attachSupport2 = _interopRequireDefault(_attachSupport);
+
+var _selection = require('diagram-js/lib/features/selection');
+
+var _selection2 = _interopRequireDefault(_selection);
+
+var _changeSupport = require('diagram-js/lib/features/change-support');
+
+var _changeSupport2 = _interopRequireDefault(_changeSupport);
+
+var _spaceTool = require('diagram-js/lib/features/space-tool');
+
+var _spaceTool2 = _interopRequireDefault(_spaceTool);
+
+var _BpmnFactory = require('./BpmnFactory');
+
+var _BpmnFactory2 = _interopRequireDefault(_BpmnFactory);
+
+var _BpmnUpdater = require('./BpmnUpdater');
+
+var _BpmnUpdater2 = _interopRequireDefault(_BpmnUpdater);
+
+var _ElementFactory = require('./ElementFactory');
+
+var _ElementFactory2 = _interopRequireDefault(_ElementFactory);
+
+var _Modeling = require('./Modeling');
+
+var _Modeling2 = _interopRequireDefault(_Modeling);
+
+var _BpmnLayouter = require('./BpmnLayouter');
+
+var _BpmnLayouter2 = _interopRequireDefault(_BpmnLayouter);
+
+var _CroppingConnectionDocking = require('diagram-js/lib/layout/CroppingConnectionDocking');
+
+var _CroppingConnectionDocking2 = _interopRequireDefault(_CroppingConnectionDocking);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['modeling', 'bpmnUpdater'],
+ __depends__: [_behavior2.default, _rules2.default, _ordering2.default, _replace2.default, _command2.default, _tooltips2.default, _labelSupport2.default, _attachSupport2.default, _selection2.default, _changeSupport2.default, _spaceTool2.default],
+ bpmnFactory: ['type', _BpmnFactory2.default],
+ bpmnUpdater: ['type', _BpmnUpdater2.default],
+ elementFactory: ['type', _ElementFactory2.default],
+ modeling: ['type', _Modeling2.default],
+ layouter: ['type', _BpmnLayouter2.default],
+ connectionDocking: ['type', _CroppingConnectionDocking2.default]
+};
+
+},{"../ordering":191,"../replace":201,"../rules":203,"./BpmnFactory":145,"./BpmnLayouter":146,"./BpmnUpdater":147,"./ElementFactory":148,"./Modeling":149,"./behavior":173,"diagram-js/lib/command":245,"diagram-js/lib/features/attach-support":259,"diagram-js/lib/features/change-support":271,"diagram-js/lib/features/label-support":302,"diagram-js/lib/features/selection":361,"diagram-js/lib/features/space-tool":368,"diagram-js/lib/features/tooltips":372,"diagram-js/lib/layout/CroppingConnectionDocking":379}],188:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.LANE_INDENTATION = undefined;
+exports.collectLanes = collectLanes;
+exports.getChildLanes = getChildLanes;
+exports.getLanesRoot = getLanesRoot;
+exports.computeLanesResize = computeLanesResize;
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _ModelingUtil = require('./ModelingUtil');
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _ResizeUtil = require('diagram-js/lib/features/resize/ResizeUtil');
+
+var abs = Math.abs;
+
+function getTRBLResize(oldBounds, newBounds) {
+ return (0, _ResizeUtil.substractTRBL)((0, _LayoutUtil.asTRBL)(newBounds), (0, _LayoutUtil.asTRBL)(oldBounds));
+}
+
+var LANE_PARENTS = ['bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess'];
+
+var LANE_INDENTATION = exports.LANE_INDENTATION = 30;
+
+/**
+ * Collect all lane shapes in the given paren
+ *
+ * @param {djs.model.Shape} shape
+ * @param {Array} [collectedShapes]
+ *
+ * @return {Array}
+ */
+function collectLanes(shape, collectedShapes) {
+
+ collectedShapes = collectedShapes || [];
+
+ shape.children.filter(function (s) {
+ if ((0, _ModelUtil.is)(s, 'bpmn:Lane')) {
+ collectLanes(s, collectedShapes);
+
+ collectedShapes.push(s);
+ }
+ });
+
+ return collectedShapes;
+}
+
+/**
+ * Return the lane children of the given element.
+ *
+ * @param {djs.model.Shape} shape
+ *
+ * @return {Array}
+ */
+function getChildLanes(shape) {
+ return shape.children.filter(function (c) {
+ return (0, _ModelUtil.is)(c, 'bpmn:Lane');
+ });
+}
+
+/**
+ * Return the root element containing the given lane shape
+ *
+ * @param {djs.model.Shape} shape
+ *
+ * @return {djs.model.Shape}
+ */
+function getLanesRoot(shape) {
+ return (0, _ModelingUtil.getParent)(shape, LANE_PARENTS) || shape;
+}
+
+/**
+ * Compute the required resize operations for lanes
+ * adjacent to the given shape, assuming it will be
+ * resized to the given new bounds.
+ *
+ * @param {djs.model.Shape} shape
+ * @param {Bounds} newBounds
+ *
+ * @return {Array}
+ */
+function computeLanesResize(shape, newBounds) {
+
+ var rootElement = getLanesRoot(shape);
+
+ var initialShapes = (0, _ModelUtil.is)(rootElement, 'bpmn:Process') ? [] : [rootElement];
+
+ var allLanes = collectLanes(rootElement, initialShapes),
+ shapeTrbl = (0, _LayoutUtil.asTRBL)(shape),
+ shapeNewTrbl = (0, _LayoutUtil.asTRBL)(newBounds),
+ trblResize = getTRBLResize(shape, newBounds),
+ resizeNeeded = [];
+
+ allLanes.forEach(function (other) {
+
+ if (other === shape) {
+ return;
+ }
+
+ var topResize = 0,
+ rightResize = trblResize.right,
+ bottomResize = 0,
+ leftResize = trblResize.left;
+
+ var otherTrbl = (0, _LayoutUtil.asTRBL)(other);
+
+ if (trblResize.top) {
+ if (abs(otherTrbl.bottom - shapeTrbl.top) < 10) {
+ bottomResize = shapeNewTrbl.top - otherTrbl.bottom;
+ }
+
+ if (abs(otherTrbl.top - shapeTrbl.top) < 5) {
+ topResize = shapeNewTrbl.top - otherTrbl.top;
+ }
+ }
+
+ if (trblResize.bottom) {
+ if (abs(otherTrbl.top - shapeTrbl.bottom) < 10) {
+ topResize = shapeNewTrbl.bottom - otherTrbl.top;
+ }
+
+ if (abs(otherTrbl.bottom - shapeTrbl.bottom) < 5) {
+ bottomResize = shapeNewTrbl.bottom - otherTrbl.bottom;
+ }
+ }
+
+ if (topResize || rightResize || bottomResize || leftResize) {
+
+ resizeNeeded.push({
+ shape: other,
+ newBounds: (0, _ResizeUtil.resizeTRBL)(other, {
+ top: topResize,
+ right: rightResize,
+ bottom: bottomResize,
+ left: leftResize
+ })
+ });
+ }
+ });
+
+ return resizeNeeded;
+}
+
+},{"../../../util/ModelUtil":216,"./ModelingUtil":189,"diagram-js/lib/features/resize/ResizeUtil":351,"diagram-js/lib/layout/LayoutUtil":380}],189:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.isAny = isAny;
+exports.getParent = getParent;
+
+var _minDash = require('min-dash');
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+/**
+ * Return true if element has any of the given types.
+ *
+ * @param {djs.model.Base} element
+ * @param {Array} types
+ *
+ * @return {Boolean}
+ */
+function isAny(element, types) {
+ return (0, _minDash.some)(types, function (t) {
+ return (0, _ModelUtil.is)(element, t);
+ });
+}
+
+/**
+ * Return the parent of the element with any of the given types.
+ *
+ * @param {djs.model.Base} element
+ * @param {String|Array} anyType
+ *
+ * @return {djs.model.Base}
+ */
+function getParent(element, anyType) {
+
+ if (typeof anyType === 'string') {
+ anyType = [anyType];
+ }
+
+ while (element = element.parent) {
+ if (isAny(element, anyType)) {
+ return element;
+ }
+ }
+
+ return null;
+}
+
+},{"../../../util/ModelUtil":216,"min-dash":505}],190:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnOrderingProvider;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _OrderingProvider = require('diagram-js/lib/features/ordering/OrderingProvider');
+
+var _OrderingProvider2 = _interopRequireDefault(_OrderingProvider);
+
+var _ModelingUtil = require('../modeling/util/ModelingUtil');
+
+var _minDash = require('min-dash');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * a simple ordering provider that makes sure:
+ *
+ * (0) labels are rendered always on top
+ * (1) elements are ordered by a {level} property
+ */
+function BpmnOrderingProvider(eventBus, canvas, translate) {
+
+ _OrderingProvider2.default.call(this, eventBus);
+
+ var orders = [{ type: 'bpmn:SubProcess', order: { level: 6 } }, {
+ type: 'bpmn:SequenceFlow',
+ order: {
+ level: 3,
+ containers: ['bpmn:Participant', 'bpmn:FlowElementsContainer']
+ }
+ },
+ // handle DataAssociation(s) like message flows and render them always on top
+ {
+ type: 'bpmn:DataAssociation',
+ order: {
+ level: 9,
+ containers: ['bpmn:Collaboration', 'bpmn:Process']
+ }
+ }, {
+ type: 'bpmn:MessageFlow', order: {
+ level: 9,
+ containers: ['bpmn:Collaboration']
+ }
+ }, {
+ type: 'bpmn:Association',
+ order: {
+ level: 6,
+ containers: ['bpmn:Participant', 'bpmn:FlowElementsContainer', 'bpmn:Collaboration']
+ }
+ }, { type: 'bpmn:BoundaryEvent', order: { level: 8 } }, { type: 'bpmn:FlowElement', order: { level: 5 } }, { type: 'bpmn:Participant', order: { level: -2 } }, { type: 'bpmn:Lane', order: { level: -1 } }];
+
+ function computeOrder(element) {
+ if (element.labelTarget) {
+ return { level: 10 };
+ }
+
+ var entry = (0, _minDash.find)(orders, function (o) {
+ return (0, _ModelingUtil.isAny)(element, [o.type]);
+ });
+
+ return entry && entry.order || { level: 1 };
+ }
+
+ function getOrder(element) {
+
+ var order = element.order;
+
+ if (!order) {
+ element.order = order = computeOrder(element);
+ }
+
+ return order;
+ }
+
+ function findActualParent(element, newParent, containers) {
+
+ var actualParent = newParent;
+
+ while (actualParent) {
+
+ if ((0, _ModelingUtil.isAny)(actualParent, containers)) {
+ break;
+ }
+
+ actualParent = actualParent.parent;
+ }
+
+ if (!actualParent) {
+ throw new Error(translate('no parent for {element} in {parent}', {
+ element: element.id,
+ parent: newParent.id
+ }));
+ }
+
+ return actualParent;
+ }
+
+ this.getOrdering = function (element, newParent) {
+
+ // render labels always on top
+ if (element.labelTarget) {
+ return {
+ parent: canvas.getRootElement(),
+ index: -1
+ };
+ }
+
+ var elementOrder = getOrder(element);
+
+ if (elementOrder.containers) {
+ newParent = findActualParent(element, newParent, elementOrder.containers);
+ }
+
+ var currentIndex = newParent.children.indexOf(element);
+
+ var insertIndex = (0, _minDash.findIndex)(newParent.children, function (child) {
+
+ // do not compare with labels, they are created
+ // in the wrong order (right after elements) during import and
+ // mess up the positioning.
+ if (!element.labelTarget && child.labelTarget) {
+ return false;
+ }
+
+ return elementOrder.level < getOrder(child).level;
+ });
+
+ // if the element is already in the child list at
+ // a smaller index, we need to adjust the inser index.
+ // this takes into account that the element is being removed
+ // before being re-inserted
+ if (insertIndex !== -1) {
+ if (currentIndex !== -1 && currentIndex < insertIndex) {
+ insertIndex -= 1;
+ }
+ }
+
+ return {
+ index: insertIndex,
+ parent: newParent
+ };
+ };
+}
+
+BpmnOrderingProvider.$inject = ['eventBus', 'canvas', 'translate'];
+
+(0, _inherits2.default)(BpmnOrderingProvider, _OrderingProvider2.default);
+
+},{"../modeling/util/ModelingUtil":189,"diagram-js/lib/features/ordering/OrderingProvider":335,"inherits":415,"min-dash":505}],191:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _translate = require('diagram-js/lib/i18n/translate');
+
+var _translate2 = _interopRequireDefault(_translate);
+
+var _BpmnOrderingProvider = require('./BpmnOrderingProvider');
+
+var _BpmnOrderingProvider2 = _interopRequireDefault(_BpmnOrderingProvider);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_translate2.default],
+ __init__: ['bpmnOrderingProvider'],
+ bpmnOrderingProvider: ['type', _BpmnOrderingProvider2.default]
+};
+
+},{"./BpmnOrderingProvider":190,"diagram-js/lib/i18n/translate":376}],192:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = PaletteProvider;
+
+var _minDash = require('min-dash');
+
+/**
+ * A palette provider for BPMN 2.0 elements.
+ */
+function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect, translate) {
+
+ this._palette = palette;
+ this._create = create;
+ this._elementFactory = elementFactory;
+ this._spaceTool = spaceTool;
+ this._lassoTool = lassoTool;
+ this._handTool = handTool;
+ this._globalConnect = globalConnect;
+ this._translate = translate;
+
+ palette.registerProvider(this);
+}
+
+PaletteProvider.$inject = ['palette', 'create', 'elementFactory', 'spaceTool', 'lassoTool', 'handTool', 'globalConnect', 'translate'];
+
+PaletteProvider.prototype.getPaletteEntries = function (element) {
+
+ var actions = {},
+ create = this._create,
+ elementFactory = this._elementFactory,
+ spaceTool = this._spaceTool,
+ lassoTool = this._lassoTool,
+ handTool = this._handTool,
+ globalConnect = this._globalConnect,
+ translate = this._translate;
+
+ function createAction(type, group, className, title, options) {
+
+ function createListener(event) {
+ var shape = elementFactory.createShape((0, _minDash.assign)({ type: type }, options));
+
+ if (options) {
+ shape.businessObject.di.isExpanded = options.isExpanded;
+ }
+
+ create.start(event, shape);
+ }
+
+ var shortType = type.replace(/^bpmn:/, '');
+
+ return {
+ group: group,
+ className: className,
+ title: title || translate('Create {type}', { type: shortType }),
+ action: {
+ dragstart: createListener,
+ click: createListener
+ }
+ };
+ }
+
+ function createParticipant(event, collapsed) {
+ create.start(event, elementFactory.createParticipantShape(collapsed));
+ }
+
+ (0, _minDash.assign)(actions, {
+ 'hand-tool': {
+ group: 'tools',
+ className: 'bpmn-icon-hand-tool',
+ title: translate('Activate the hand tool'),
+ action: {
+ click: function click(event) {
+ handTool.activateHand(event);
+ }
+ }
+ },
+ 'lasso-tool': {
+ group: 'tools',
+ className: 'bpmn-icon-lasso-tool',
+ title: translate('Activate the lasso tool'),
+ action: {
+ click: function click(event) {
+ lassoTool.activateSelection(event);
+ }
+ }
+ },
+ 'space-tool': {
+ group: 'tools',
+ className: 'bpmn-icon-space-tool',
+ title: translate('Activate the create/remove space tool'),
+ action: {
+ click: function click(event) {
+ spaceTool.activateSelection(event);
+ }
+ }
+ },
+ 'global-connect-tool': {
+ group: 'tools',
+ className: 'bpmn-icon-connection-multi',
+ title: translate('Activate the global connect tool'),
+ action: {
+ click: function click(event) {
+ globalConnect.toggle(event);
+ }
+ }
+ },
+ 'tool-separator': {
+ group: 'tools',
+ separator: true
+ },
+ 'create.start-event': createAction('bpmn:StartEvent', 'event', 'bpmn-icon-start-event-none'),
+ 'create.intermediate-event': createAction('bpmn:IntermediateThrowEvent', 'event', 'bpmn-icon-intermediate-event-none', translate('Create Intermediate/Boundary Event')),
+ 'create.end-event': createAction('bpmn:EndEvent', 'event', 'bpmn-icon-end-event-none'),
+ 'create.exclusive-gateway': createAction('bpmn:ExclusiveGateway', 'gateway', 'bpmn-icon-gateway-none', translate('Create Gateway')),
+ 'create.task': createAction('bpmn:Task', 'activity', 'bpmn-icon-task'),
+ 'create.data-object': createAction('bpmn:DataObjectReference', 'data-object', 'bpmn-icon-data-object'),
+ 'create.data-store': createAction('bpmn:DataStoreReference', 'data-store', 'bpmn-icon-data-store'),
+ 'create.subprocess-expanded': createAction('bpmn:SubProcess', 'activity', 'bpmn-icon-subprocess-expanded', translate('Create expanded SubProcess'), { isExpanded: true }),
+ 'create.participant-expanded': {
+ group: 'collaboration',
+ className: 'bpmn-icon-participant',
+ title: translate('Create Pool/Participant'),
+ action: {
+ dragstart: createParticipant,
+ click: createParticipant
+ }
+ }
+ });
+
+ return actions;
+};
+
+},{"min-dash":505}],193:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _palette = require('diagram-js/lib/features/palette');
+
+var _palette2 = _interopRequireDefault(_palette);
+
+var _create = require('diagram-js/lib/features/create');
+
+var _create2 = _interopRequireDefault(_create);
+
+var _spaceTool = require('diagram-js/lib/features/space-tool');
+
+var _spaceTool2 = _interopRequireDefault(_spaceTool);
+
+var _lassoTool = require('diagram-js/lib/features/lasso-tool');
+
+var _lassoTool2 = _interopRequireDefault(_lassoTool);
+
+var _handTool = require('diagram-js/lib/features/hand-tool');
+
+var _handTool2 = _interopRequireDefault(_handTool);
+
+var _globalConnect = require('diagram-js/lib/features/global-connect');
+
+var _globalConnect2 = _interopRequireDefault(_globalConnect);
+
+var _translate = require('diagram-js/lib/i18n/translate');
+
+var _translate2 = _interopRequireDefault(_translate);
+
+var _PaletteProvider = require('./PaletteProvider');
+
+var _PaletteProvider2 = _interopRequireDefault(_PaletteProvider);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_palette2.default, _create2.default, _spaceTool2.default, _lassoTool2.default, _handTool2.default, _globalConnect2.default, _translate2.default],
+ __init__: ['paletteProvider'],
+ paletteProvider: ['type', _PaletteProvider2.default]
+};
+
+},{"./PaletteProvider":192,"diagram-js/lib/features/create":281,"diagram-js/lib/features/global-connect":290,"diagram-js/lib/features/hand-tool":292,"diagram-js/lib/features/lasso-tool":304,"diagram-js/lib/features/palette":341,"diagram-js/lib/features/space-tool":368,"diagram-js/lib/i18n/translate":376}],194:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ReplaceMenuProvider;
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _DiUtil = require('../../util/DiUtil');
+
+var _TypeUtil = require('./util/TypeUtil');
+
+var _minDash = require('min-dash');
+
+var _ReplaceOptions = require('../replace/ReplaceOptions');
+
+var replaceOptions = _interopRequireWildcard(_ReplaceOptions);
+
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+
+/**
+ * This module is an element agnostic replace menu provider for the popup menu.
+ */
+function ReplaceMenuProvider(popupMenu, modeling, moddle, bpmnReplace, rules, translate) {
+
+ this._popupMenu = popupMenu;
+ this._modeling = modeling;
+ this._moddle = moddle;
+ this._bpmnReplace = bpmnReplace;
+ this._rules = rules;
+ this._translate = translate;
+
+ this.register();
+}
+
+ReplaceMenuProvider.$inject = ['popupMenu', 'modeling', 'moddle', 'bpmnReplace', 'rules', 'translate'];
+
+/**
+ * Register replace menu provider in the popup menu
+ */
+ReplaceMenuProvider.prototype.register = function () {
+ this._popupMenu.registerProvider('bpmn-replace', this);
+};
+
+/**
+ * Get all entries from replaceOptions for the given element and apply filters
+ * on them. Get for example only elements, which are different from the current one.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {Array} a list of menu entry items
+ */
+ReplaceMenuProvider.prototype.getEntries = function (element) {
+
+ var businessObject = element.businessObject;
+
+ var rules = this._rules;
+
+ var entries;
+
+ if (!rules.allowed('shape.replace', { element: element })) {
+ return [];
+ }
+
+ var differentType = (0, _TypeUtil.isDifferentType)(element);
+
+ // start events outside event sub processes
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && !(0, _DiUtil.isEventSubProcess)(businessObject.$parent)) {
+
+ entries = (0, _minDash.filter)(replaceOptions.START_EVENT, differentType);
+
+ return this._createEntries(element, entries);
+ }
+
+ // expanded/collapsed pools
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:Participant')) {
+
+ entries = (0, _minDash.filter)(replaceOptions.PARTICIPANT, function (entry) {
+ return (0, _DiUtil.isExpanded)(businessObject) !== entry.target.isExpanded;
+ });
+
+ return this._createEntries(element, entries);
+ }
+
+ // start events inside event sub processes
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && (0, _DiUtil.isEventSubProcess)(businessObject.$parent)) {
+
+ entries = (0, _minDash.filter)(replaceOptions.EVENT_SUB_PROCESS_START_EVENT, function (entry) {
+
+ var target = entry.target;
+
+ var isInterrupting = target.isInterrupting !== false;
+
+ var isInterruptingEqual = (0, _ModelUtil.getBusinessObject)(element).isInterrupting === isInterrupting;
+
+ // filters elements which types and event definition are equal but have have different interrupting types
+ return differentType(entry) || !differentType(entry) && !isInterruptingEqual;
+ });
+
+ return this._createEntries(element, entries);
+ }
+
+ // end events
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:EndEvent')) {
+
+ entries = (0, _minDash.filter)(replaceOptions.END_EVENT, function (entry) {
+ var target = entry.target;
+
+ // hide cancel end events outside transactions
+ if (target.eventDefinitionType == 'bpmn:CancelEventDefinition' && !(0, _ModelUtil.is)(businessObject.$parent, 'bpmn:Transaction')) {
+ return false;
+ }
+
+ return differentType(entry);
+ });
+
+ return this._createEntries(element, entries);
+ }
+
+ // boundary events
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:BoundaryEvent')) {
+
+ entries = (0, _minDash.filter)(replaceOptions.BOUNDARY_EVENT, function (entry) {
+
+ var target = entry.target;
+
+ if (target.eventDefinition == 'bpmn:CancelEventDefinition' && !(0, _ModelUtil.is)(businessObject.attachedToRef, 'bpmn:Transaction')) {
+ return false;
+ }
+ var cancelActivity = target.cancelActivity !== false;
+
+ var isCancelActivityEqual = businessObject.cancelActivity == cancelActivity;
+
+ return differentType(entry) || !differentType(entry) && !isCancelActivityEqual;
+ });
+
+ return this._createEntries(element, entries);
+ }
+
+ // intermediate events
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:IntermediateCatchEvent') || (0, _ModelUtil.is)(businessObject, 'bpmn:IntermediateThrowEvent')) {
+
+ entries = (0, _minDash.filter)(replaceOptions.INTERMEDIATE_EVENT, differentType);
+
+ return this._createEntries(element, entries);
+ }
+
+ // gateways
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:Gateway')) {
+
+ entries = (0, _minDash.filter)(replaceOptions.GATEWAY, differentType);
+
+ return this._createEntries(element, entries);
+ }
+
+ // transactions
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:Transaction')) {
+
+ entries = (0, _minDash.filter)(replaceOptions.TRANSACTION, differentType);
+
+ return this._createEntries(element, entries);
+ }
+
+ // expanded event sub processes
+ if ((0, _DiUtil.isEventSubProcess)(businessObject) && (0, _DiUtil.isExpanded)(businessObject)) {
+
+ entries = (0, _minDash.filter)(replaceOptions.EVENT_SUB_PROCESS, differentType);
+
+ return this._createEntries(element, entries);
+ }
+
+ // expanded sub processes
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(businessObject)) {
+
+ entries = (0, _minDash.filter)(replaceOptions.SUBPROCESS_EXPANDED, differentType);
+
+ return this._createEntries(element, entries);
+ }
+
+ // collapsed ad hoc sub processes
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:AdHocSubProcess') && !(0, _DiUtil.isExpanded)(businessObject)) {
+
+ entries = (0, _minDash.filter)(replaceOptions.TASK, function (entry) {
+
+ var target = entry.target;
+
+ var isTargetSubProcess = target.type === 'bpmn:SubProcess';
+
+ var isTargetExpanded = target.isExpanded === true;
+
+ return (0, _TypeUtil.isDifferentType)(element, target) && (!isTargetSubProcess || isTargetExpanded);
+ });
+
+ return this._createEntries(element, entries);
+ }
+
+ // sequence flows
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:SequenceFlow')) {
+ return this._createSequenceFlowEntries(element, replaceOptions.SEQUENCE_FLOW);
+ }
+
+ // flow nodes
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowNode')) {
+ entries = (0, _minDash.filter)(replaceOptions.TASK, differentType);
+
+ // collapsed SubProcess can not be replaced with itself
+ if ((0, _ModelUtil.is)(businessObject, 'bpmn:SubProcess') && !(0, _DiUtil.isExpanded)(businessObject)) {
+ entries = (0, _minDash.filter)(entries, function (entry) {
+ return entry.label !== 'Sub Process (collapsed)';
+ });
+ }
+
+ return this._createEntries(element, entries);
+ }
+
+ return [];
+};
+
+/**
+ * Get a list of header items for the given element. This includes buttons
+ * for multi instance markers and for the ad hoc marker.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {Array} a list of menu entry items
+ */
+ReplaceMenuProvider.prototype.getHeaderEntries = function (element) {
+
+ var headerEntries = [];
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:Activity') && !(0, _DiUtil.isEventSubProcess)(element)) {
+ headerEntries = headerEntries.concat(this._getLoopEntries(element));
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess') && !(0, _ModelUtil.is)(element, 'bpmn:Transaction') && !(0, _DiUtil.isEventSubProcess)(element)) {
+ headerEntries.push(this._getAdHocEntry(element));
+ }
+
+ return headerEntries;
+};
+
+/**
+ * Creates an array of menu entry objects for a given element and filters the replaceOptions
+ * according to a filter function.
+ *
+ * @param {djs.model.Base} element
+ * @param {Object} replaceOptions
+ *
+ * @return {Array} a list of menu items
+ */
+ReplaceMenuProvider.prototype._createEntries = function (element, replaceOptions) {
+ var menuEntries = [];
+
+ var self = this;
+
+ (0, _minDash.forEach)(replaceOptions, function (definition) {
+ var entry = self._createMenuEntry(definition, element);
+
+ menuEntries.push(entry);
+ });
+
+ return menuEntries;
+};
+
+/**
+ * Creates an array of menu entry objects for a given sequence flow.
+ *
+ * @param {djs.model.Base} element
+ * @param {Object} replaceOptions
+
+ * @return {Array} a list of menu items
+ */
+ReplaceMenuProvider.prototype._createSequenceFlowEntries = function (element, replaceOptions) {
+
+ var businessObject = (0, _ModelUtil.getBusinessObject)(element);
+
+ var menuEntries = [];
+
+ var modeling = this._modeling,
+ moddle = this._moddle;
+
+ var self = this;
+
+ (0, _minDash.forEach)(replaceOptions, function (entry) {
+
+ switch (entry.actionName) {
+ case 'replace-with-default-flow':
+ if (businessObject.sourceRef.default !== businessObject && ((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ComplexGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity'))) {
+
+ menuEntries.push(self._createMenuEntry(entry, element, function () {
+ modeling.updateProperties(element.source, { default: businessObject });
+ }));
+ }
+ break;
+ case 'replace-with-conditional-flow':
+ if (!businessObject.conditionExpression && (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity')) {
+
+ menuEntries.push(self._createMenuEntry(entry, element, function () {
+ var conditionExpression = moddle.create('bpmn:FormalExpression', { body: '' });
+
+ modeling.updateProperties(element, { conditionExpression: conditionExpression });
+ }));
+ }
+ break;
+ default:
+ // default flows
+ if ((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity') && businessObject.conditionExpression) {
+ return menuEntries.push(self._createMenuEntry(entry, element, function () {
+ modeling.updateProperties(element, { conditionExpression: undefined });
+ }));
+ }
+ // conditional flows
+ if (((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ComplexGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity')) && businessObject.sourceRef.default === businessObject) {
+
+ return menuEntries.push(self._createMenuEntry(entry, element, function () {
+ modeling.updateProperties(element.source, { default: undefined });
+ }));
+ }
+ }
+ });
+
+ return menuEntries;
+};
+
+/**
+ * Creates and returns a single menu entry item.
+ *
+ * @param {Object} definition a single replace options definition object
+ * @param {djs.model.Base} element
+ * @param {Function} [action] an action callback function which gets called when
+ * the menu entry is being triggered.
+ *
+ * @return {Object} menu entry item
+ */
+ReplaceMenuProvider.prototype._createMenuEntry = function (definition, element, action) {
+ var translate = this._translate;
+ var replaceElement = this._bpmnReplace.replaceElement;
+
+ var replaceAction = function replaceAction() {
+ return replaceElement(element, definition.target);
+ };
+
+ action = action || replaceAction;
+
+ var menuEntry = {
+ label: translate(definition.label),
+ className: definition.className,
+ id: definition.actionName,
+ action: action
+ };
+
+ return menuEntry;
+};
+
+/**
+ * Get a list of menu items containing buttons for multi instance markers
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {Array} a list of menu items
+ */
+ReplaceMenuProvider.prototype._getLoopEntries = function (element) {
+
+ var self = this;
+ var translate = this._translate;
+
+ function toggleLoopEntry(event, entry) {
+ var loopCharacteristics;
+
+ if (entry.active) {
+ loopCharacteristics = undefined;
+ } else {
+ loopCharacteristics = self._moddle.create(entry.options.loopCharacteristics);
+
+ if (entry.options.isSequential) {
+ loopCharacteristics.isSequential = entry.options.isSequential;
+ }
+ }
+ self._modeling.updateProperties(element, { loopCharacteristics: loopCharacteristics });
+ }
+
+ var businessObject = (0, _ModelUtil.getBusinessObject)(element),
+ loopCharacteristics = businessObject.loopCharacteristics;
+
+ var isSequential, isLoop, isParallel;
+
+ if (loopCharacteristics) {
+ isSequential = loopCharacteristics.isSequential;
+ isLoop = loopCharacteristics.isSequential === undefined;
+ isParallel = loopCharacteristics.isSequential !== undefined && !loopCharacteristics.isSequential;
+ }
+
+ var loopEntries = [{
+ id: 'toggle-parallel-mi',
+ className: 'bpmn-icon-parallel-mi-marker',
+ title: translate('Parallel Multi Instance'),
+ active: isParallel,
+ action: toggleLoopEntry,
+ options: {
+ loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics',
+ isSequential: false
+ }
+ }, {
+ id: 'toggle-sequential-mi',
+ className: 'bpmn-icon-sequential-mi-marker',
+ title: translate('Sequential Multi Instance'),
+ active: isSequential,
+ action: toggleLoopEntry,
+ options: {
+ loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics',
+ isSequential: true
+ }
+ }, {
+ id: 'toggle-loop',
+ className: 'bpmn-icon-loop-marker',
+ title: translate('Loop'),
+ active: isLoop,
+ action: toggleLoopEntry,
+ options: {
+ loopCharacteristics: 'bpmn:StandardLoopCharacteristics'
+ }
+ }];
+ return loopEntries;
+};
+
+/**
+ * Get the menu items containing a button for the ad hoc marker
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {Object} a menu item
+ */
+ReplaceMenuProvider.prototype._getAdHocEntry = function (element) {
+ var translate = this._translate;
+ var businessObject = (0, _ModelUtil.getBusinessObject)(element);
+
+ var isAdHoc = (0, _ModelUtil.is)(businessObject, 'bpmn:AdHocSubProcess');
+
+ var replaceElement = this._bpmnReplace.replaceElement;
+
+ var adHocEntry = {
+ id: 'toggle-adhoc',
+ className: 'bpmn-icon-ad-hoc-marker',
+ title: translate('Ad-hoc'),
+ active: isAdHoc,
+ action: function action(event, entry) {
+ if (isAdHoc) {
+ return replaceElement(element, { type: 'bpmn:SubProcess' });
+ } else {
+ return replaceElement(element, { type: 'bpmn:AdHocSubProcess' });
+ }
+ }
+ };
+
+ return adHocEntry;
+};
+
+},{"../../util/DiUtil":214,"../../util/ModelUtil":216,"../replace/ReplaceOptions":200,"./util/TypeUtil":196,"min-dash":505}],195:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _popupMenu = require('diagram-js/lib/features/popup-menu');
+
+var _popupMenu2 = _interopRequireDefault(_popupMenu);
+
+var _replace = require('../replace');
+
+var _replace2 = _interopRequireDefault(_replace);
+
+var _ReplaceMenuProvider = require('./ReplaceMenuProvider');
+
+var _ReplaceMenuProvider2 = _interopRequireDefault(_ReplaceMenuProvider);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_popupMenu2.default, _replace2.default],
+ __init__: ['replaceMenuProvider'],
+ replaceMenuProvider: ['type', _ReplaceMenuProvider2.default]
+};
+
+},{"../replace":201,"./ReplaceMenuProvider":194,"diagram-js/lib/features/popup-menu":343}],196:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.isDifferentType = isDifferentType;
+
+var _ModelUtil = require('../../../util/ModelUtil');
+
+var _DiUtil = require('../../../util/DiUtil');
+
+/**
+ * Returns true, if an element is from a different type
+ * than a target definition. Takes into account the type,
+ * event definition type and triggeredByEvent property.
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {Boolean}
+ */
+function isDifferentType(element) {
+
+ return function (entry) {
+ var target = entry.target;
+
+ var businessObject = (0, _ModelUtil.getBusinessObject)(element),
+ eventDefinition = businessObject.eventDefinitions && businessObject.eventDefinitions[0];
+
+ var isTypeEqual = businessObject.$type === target.type;
+
+ var isEventDefinitionEqual = (eventDefinition && eventDefinition.$type) === target.eventDefinitionType;
+
+ var isTriggeredByEventEqual = businessObject.triggeredByEvent === target.triggeredByEvent;
+
+ var isExpandedEqual = target.isExpanded === undefined || target.isExpanded === (0, _DiUtil.isExpanded)(businessObject);
+
+ return !isTypeEqual || !isEventDefinitionEqual || !isTriggeredByEventEqual || !isExpandedEqual;
+ };
+}
+
+},{"../../../util/DiUtil":214,"../../../util/ModelUtil":216}],197:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnReplacePreview;
+
+var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _css = require('css.escape');
+
+var _css2 = _interopRequireDefault(_css);
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var _tinySvg = require('tiny-svg');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var LOW_PRIORITY = 250;
+
+function BpmnReplacePreview(eventBus, elementRegistry, elementFactory, canvas, previewSupport) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ /**
+ * Replace the visuals of all elements in the context which can be replaced
+ *
+ * @param {Object} context
+ */
+ function replaceVisual(context) {
+
+ var replacements = context.canExecute.replacements;
+
+ (0, _minDash.forEach)(replacements, function (replacement) {
+
+ var id = replacement.oldElementId;
+
+ var newElement = {
+ type: replacement.newElementType
+ };
+
+ // if the visual of the element is already replaced
+ if (context.visualReplacements[id]) {
+ return;
+ }
+
+ var element = elementRegistry.get(id);
+
+ (0, _minDash.assign)(newElement, { x: element.x, y: element.y });
+
+ // create a temporary shape
+ var tempShape = elementFactory.createShape(newElement);
+
+ canvas.addShape(tempShape, element.parent);
+
+ // select the original SVG element related to the element and hide it
+ var gfx = (0, _minDom.query)('[data-element-id="' + (0, _css2.default)(element.id) + '"]', context.dragGroup);
+
+ if (gfx) {
+ (0, _tinySvg.attr)(gfx, { display: 'none' });
+ }
+
+ // clone the gfx of the temporary shape and add it to the drag group
+ var dragger = previewSupport.addDragger(tempShape, context.dragGroup);
+
+ context.visualReplacements[id] = dragger;
+
+ canvas.removeShape(tempShape);
+ });
+ }
+
+ /**
+ * Restore the original visuals of the previously replaced elements
+ *
+ * @param {Object} context
+ */
+ function restoreVisual(context) {
+
+ var visualReplacements = context.visualReplacements;
+
+ (0, _minDash.forEach)(visualReplacements, function (dragger, id) {
+
+ var originalGfx = (0, _minDom.query)('[data-element-id="' + (0, _css2.default)(id) + '"]', context.dragGroup);
+
+ if (originalGfx) {
+ (0, _tinySvg.attr)(originalGfx, { display: 'inline' });
+ }
+
+ dragger.remove();
+
+ if (visualReplacements[id]) {
+ delete visualReplacements[id];
+ }
+ });
+ }
+
+ eventBus.on('shape.move.move', LOW_PRIORITY, function (event) {
+
+ var context = event.context,
+ canExecute = context.canExecute;
+
+ if (!context.visualReplacements) {
+ context.visualReplacements = {};
+ }
+
+ if (canExecute.replacements) {
+ replaceVisual(context);
+ } else {
+ restoreVisual(context);
+ }
+ });
+}
+
+BpmnReplacePreview.$inject = ['eventBus', 'elementRegistry', 'elementFactory', 'canvas', 'previewSupport'];
+
+(0, _inherits2.default)(BpmnReplacePreview, _CommandInterceptor2.default);
+
+},{"css.escape":237,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505,"min-dom":506,"tiny-svg":535}],198:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _previewSupport = require('diagram-js/lib/features/preview-support');
+
+var _previewSupport2 = _interopRequireDefault(_previewSupport);
+
+var _BpmnReplacePreview = require('./BpmnReplacePreview');
+
+var _BpmnReplacePreview2 = _interopRequireDefault(_BpmnReplacePreview);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_previewSupport2.default],
+ __init__: ['bpmnReplacePreview'],
+ bpmnReplacePreview: ['type', _BpmnReplacePreview2.default]
+};
+
+},{"./BpmnReplacePreview":197,"diagram-js/lib/features/preview-support":345}],199:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnReplace;
+
+var _minDash = require('min-dash');
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _ModelingUtil = require('../modeling/util/ModelingUtil');
+
+var _DiUtil = require('../../util/DiUtil');
+
+var _ModelCloneUtils = require('../../util/model/ModelCloneUtils');
+
+var _ModelCloneHelper = require('../../util/model/ModelCloneHelper');
+
+var _ModelCloneHelper2 = _interopRequireDefault(_ModelCloneHelper);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var CUSTOM_PROPERTIES = ['cancelActivity', 'instantiate', 'eventGatewayType', 'triggeredByEvent', 'isInterrupting'];
+
+function toggeling(element, target) {
+
+ var oldCollapsed = element && (0, _minDash.has)(element, 'collapsed') ? element.collapsed : !(0, _DiUtil.isExpanded)(element);
+
+ var targetCollapsed;
+
+ if (target && ((0, _minDash.has)(target, 'collapsed') || (0, _minDash.has)(target, 'isExpanded'))) {
+ // property is explicitly set so use it
+ targetCollapsed = (0, _minDash.has)(target, 'collapsed') ? target.collapsed : !target.isExpanded;
+ } else {
+ // keep old state
+ targetCollapsed = oldCollapsed;
+ }
+
+ if (oldCollapsed !== targetCollapsed) {
+ element.collapsed = oldCollapsed;
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * This module takes care of replacing BPMN elements
+ */
+function BpmnReplace(bpmnFactory, replace, selection, modeling, eventBus) {
+
+ var helper = new _ModelCloneHelper2.default(eventBus, bpmnFactory);
+
+ /**
+ * Prepares a new business object for the replacement element
+ * and triggers the replace operation.
+ *
+ * @param {djs.model.Base} element
+ * @param {Object} target
+ * @param {Object} [hints]
+ *
+ * @return {djs.model.Base} the newly created element
+ */
+ function replaceElement(element, target, hints) {
+
+ hints = hints || {};
+
+ var type = target.type,
+ oldBusinessObject = element.businessObject;
+
+ if (isSubProcess(oldBusinessObject)) {
+ if (type === 'bpmn:SubProcess') {
+ if (toggeling(element, target)) {
+ // expanding or collapsing process
+ modeling.toggleCollapse(element);
+
+ return element;
+ }
+ }
+ }
+
+ var newBusinessObject = bpmnFactory.create(type);
+
+ var newElement = {
+ type: type,
+ businessObject: newBusinessObject
+ };
+
+ var elementProps = (0, _ModelCloneUtils.getProperties)(oldBusinessObject.$descriptor),
+ newElementProps = (0, _ModelCloneUtils.getProperties)(newBusinessObject.$descriptor, true),
+ copyProps = intersection(elementProps, newElementProps);
+
+ // initialize special properties defined in target definition
+ (0, _minDash.assign)(newBusinessObject, (0, _minDash.pick)(target, CUSTOM_PROPERTIES));
+
+ var properties = (0, _minDash.filter)(copyProps, function (property) {
+ var propName = property.replace(/bpmn:/, '');
+
+ // copying event definitions, unless we replace
+ if (propName === 'eventDefinitions') {
+ return hasEventDefinition(element, target.eventDefinitionType);
+ }
+
+ // retain loop characteristics if the target element
+ // is not an event sub process
+ if (propName === 'loopCharacteristics') {
+ return !(0, _DiUtil.isEventSubProcess)(newBusinessObject);
+ }
+
+ // so the applied properties from 'target' don't get lost
+ if (property in newBusinessObject) {
+ return false;
+ }
+
+ if (propName === 'processRef' && target.isExpanded === false) {
+ return false;
+ }
+
+ if (propName === 'triggeredByEvent') {
+ return false;
+ }
+
+ return _ModelCloneUtils.IGNORED_PROPERTIES.indexOf(propName) === -1;
+ });
+
+ newBusinessObject = helper.clone(oldBusinessObject, newBusinessObject, properties);
+
+ // initialize custom BPMN extensions
+ if (target.eventDefinitionType) {
+
+ // only initialize with new eventDefinition
+ // if we did not set an event definition yet,
+ // i.e. because we cloned it
+ if (!hasEventDefinition(newBusinessObject, target.eventDefinitionType)) {
+ newElement.eventDefinitionType = target.eventDefinitionType;
+ }
+ }
+
+ if ((0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Activity')) {
+
+ if (isSubProcess(oldBusinessObject)) {
+ // no toggeling, so keep old state
+ newElement.isExpanded = (0, _DiUtil.isExpanded)(oldBusinessObject);
+ }
+ // else if property is explicitly set, use it
+ else if (target && (0, _minDash.has)(target, 'isExpanded')) {
+ newElement.isExpanded = target.isExpanded;
+ }
+
+ // TODO: need also to respect min/max Size
+ // copy size, from an expanded subprocess to an expanded alternative subprocess
+ // except bpmn:Task, because Task is always expanded
+ if ((0, _DiUtil.isExpanded)(oldBusinessObject) && !(0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Task') && newElement.isExpanded) {
+ newElement.width = element.width;
+ newElement.height = element.height;
+ }
+ }
+
+ // remove children if not expanding sub process
+ if (isSubProcess(oldBusinessObject) && !isSubProcess(newBusinessObject)) {
+ hints.moveChildren = false;
+ }
+
+ // transform collapsed/expanded pools
+ if ((0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Participant')) {
+
+ // create expanded pool
+ if (target.isExpanded === true) {
+ newBusinessObject.processRef = bpmnFactory.create('bpmn:Process');
+ } else {
+ // remove children when transforming to collapsed pool
+ hints.moveChildren = false;
+ }
+
+ // apply same size
+ newElement.width = element.width;
+ newElement.height = element.height;
+ }
+
+ newBusinessObject.name = oldBusinessObject.name;
+
+ // retain default flow's reference between inclusive <-> exclusive gateways and activities
+ if ((0, _ModelingUtil.isAny)(oldBusinessObject, ['bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:Activity']) && (0, _ModelingUtil.isAny)(newBusinessObject, ['bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:Activity'])) {
+ newBusinessObject.default = oldBusinessObject.default;
+ }
+
+ if ('fill' in oldBusinessObject.di || 'stroke' in oldBusinessObject.di) {
+ (0, _minDash.assign)(newElement, { colors: (0, _minDash.pick)(oldBusinessObject.di, ['fill', 'stroke']) });
+ }
+
+ newElement = replace.replaceElement(element, newElement, hints);
+
+ if (hints.select !== false) {
+ selection.select(newElement);
+ }
+
+ return newElement;
+ }
+
+ this.replaceElement = replaceElement;
+}
+
+BpmnReplace.$inject = ['bpmnFactory', 'replace', 'selection', 'modeling', 'eventBus'];
+
+function isSubProcess(bo) {
+ return (0, _ModelUtil.is)(bo, 'bpmn:SubProcess');
+}
+
+function hasEventDefinition(element, type) {
+
+ var bo = (0, _ModelUtil.getBusinessObject)(element);
+
+ return type && bo.get('eventDefinitions').some(function (definition) {
+ return (0, _ModelUtil.is)(definition, type);
+ });
+}
+
+/**
+ * Compute intersection between two arrays.
+ */
+function intersection(a1, a2) {
+ return a1.filter(function (el) {
+ return a2.indexOf(el) !== -1;
+ });
+}
+
+},{"../../util/DiUtil":214,"../../util/ModelUtil":216,"../../util/model/ModelCloneHelper":218,"../../util/model/ModelCloneUtils":219,"../modeling/util/ModelingUtil":189,"min-dash":505}],200:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+var START_EVENT = exports.START_EVENT = [{
+ label: 'Start Event',
+ actionName: 'replace-with-none-start',
+ className: 'bpmn-icon-start-event-none',
+ target: {
+ type: 'bpmn:StartEvent'
+ }
+}, {
+ label: 'Intermediate Throw Event',
+ actionName: 'replace-with-none-intermediate-throwing',
+ className: 'bpmn-icon-intermediate-event-none',
+ target: {
+ type: 'bpmn:IntermediateThrowEvent'
+ }
+}, {
+ label: 'End Event',
+ actionName: 'replace-with-none-end',
+ className: 'bpmn-icon-end-event-none',
+ target: {
+ type: 'bpmn:EndEvent'
+ }
+}, {
+ label: 'Message Start Event',
+ actionName: 'replace-with-message-start',
+ className: 'bpmn-icon-start-event-message',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:MessageEventDefinition'
+ }
+}, {
+ label: 'Timer Start Event',
+ actionName: 'replace-with-timer-start',
+ className: 'bpmn-icon-start-event-timer',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:TimerEventDefinition'
+ }
+}, {
+ label: 'Conditional Start Event',
+ actionName: 'replace-with-conditional-start',
+ className: 'bpmn-icon-start-event-condition',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:ConditionalEventDefinition'
+ }
+}, {
+ label: 'Signal Start Event',
+ actionName: 'replace-with-signal-start',
+ className: 'bpmn-icon-start-event-signal',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:SignalEventDefinition'
+ }
+}];
+
+var INTERMEDIATE_EVENT = exports.INTERMEDIATE_EVENT = [{
+ label: 'Start Event',
+ actionName: 'replace-with-none-start',
+ className: 'bpmn-icon-start-event-none',
+ target: {
+ type: 'bpmn:StartEvent'
+ }
+}, {
+ label: 'Intermediate Throw Event',
+ actionName: 'replace-with-none-intermediate-throw',
+ className: 'bpmn-icon-intermediate-event-none',
+ target: {
+ type: 'bpmn:IntermediateThrowEvent'
+ }
+}, {
+ label: 'End Event',
+ actionName: 'replace-with-none-end',
+ className: 'bpmn-icon-end-event-none',
+ target: {
+ type: 'bpmn:EndEvent'
+ }
+}, {
+ label: 'Message Intermediate Catch Event',
+ actionName: 'replace-with-message-intermediate-catch',
+ className: 'bpmn-icon-intermediate-event-catch-message',
+ target: {
+ type: 'bpmn:IntermediateCatchEvent',
+ eventDefinitionType: 'bpmn:MessageEventDefinition'
+ }
+}, {
+ label: 'Message Intermediate Throw Event',
+ actionName: 'replace-with-message-intermediate-throw',
+ className: 'bpmn-icon-intermediate-event-throw-message',
+ target: {
+ type: 'bpmn:IntermediateThrowEvent',
+ eventDefinitionType: 'bpmn:MessageEventDefinition'
+ }
+}, {
+ label: 'Timer Intermediate Catch Event',
+ actionName: 'replace-with-timer-intermediate-catch',
+ className: 'bpmn-icon-intermediate-event-catch-timer',
+ target: {
+ type: 'bpmn:IntermediateCatchEvent',
+ eventDefinitionType: 'bpmn:TimerEventDefinition'
+ }
+}, {
+ label: 'Escalation Intermediate Throw Event',
+ actionName: 'replace-with-escalation-intermediate-throw',
+ className: 'bpmn-icon-intermediate-event-throw-escalation',
+ target: {
+ type: 'bpmn:IntermediateThrowEvent',
+ eventDefinitionType: 'bpmn:EscalationEventDefinition'
+ }
+}, {
+ label: 'Conditional Intermediate Catch Event',
+ actionName: 'replace-with-conditional-intermediate-catch',
+ className: 'bpmn-icon-intermediate-event-catch-condition',
+ target: {
+ type: 'bpmn:IntermediateCatchEvent',
+ eventDefinitionType: 'bpmn:ConditionalEventDefinition'
+ }
+}, {
+ label: 'Link Intermediate Catch Event',
+ actionName: 'replace-with-link-intermediate-catch',
+ className: 'bpmn-icon-intermediate-event-catch-link',
+ target: {
+ type: 'bpmn:IntermediateCatchEvent',
+ eventDefinitionType: 'bpmn:LinkEventDefinition'
+ }
+}, {
+ label: 'Link Intermediate Throw Event',
+ actionName: 'replace-with-link-intermediate-throw',
+ className: 'bpmn-icon-intermediate-event-throw-link',
+ target: {
+ type: 'bpmn:IntermediateThrowEvent',
+ eventDefinitionType: 'bpmn:LinkEventDefinition'
+ }
+}, {
+ label: 'Compensation Intermediate Throw Event',
+ actionName: 'replace-with-compensation-intermediate-throw',
+ className: 'bpmn-icon-intermediate-event-throw-compensation',
+ target: {
+ type: 'bpmn:IntermediateThrowEvent',
+ eventDefinitionType: 'bpmn:CompensateEventDefinition'
+ }
+}, {
+ label: 'Signal Intermediate Catch Event',
+ actionName: 'replace-with-signal-intermediate-catch',
+ className: 'bpmn-icon-intermediate-event-catch-signal',
+ target: {
+ type: 'bpmn:IntermediateCatchEvent',
+ eventDefinitionType: 'bpmn:SignalEventDefinition'
+ }
+}, {
+ label: 'Signal Intermediate Throw Event',
+ actionName: 'replace-with-signal-intermediate-throw',
+ className: 'bpmn-icon-intermediate-event-throw-signal',
+ target: {
+ type: 'bpmn:IntermediateThrowEvent',
+ eventDefinitionType: 'bpmn:SignalEventDefinition'
+ }
+}];
+
+var END_EVENT = exports.END_EVENT = [{
+ label: 'Start Event',
+ actionName: 'replace-with-none-start',
+ className: 'bpmn-icon-start-event-none',
+ target: {
+ type: 'bpmn:StartEvent'
+ }
+}, {
+ label: 'Intermediate Throw Event',
+ actionName: 'replace-with-none-intermediate-throw',
+ className: 'bpmn-icon-intermediate-event-none',
+ target: {
+ type: 'bpmn:IntermediateThrowEvent'
+ }
+}, {
+ label: 'End Event',
+ actionName: 'replace-with-none-end',
+ className: 'bpmn-icon-end-event-none',
+ target: {
+ type: 'bpmn:EndEvent'
+ }
+}, {
+ label: 'Message End Event',
+ actionName: 'replace-with-message-end',
+ className: 'bpmn-icon-end-event-message',
+ target: {
+ type: 'bpmn:EndEvent',
+ eventDefinitionType: 'bpmn:MessageEventDefinition'
+ }
+}, {
+ label: 'Escalation End Event',
+ actionName: 'replace-with-escalation-end',
+ className: 'bpmn-icon-end-event-escalation',
+ target: {
+ type: 'bpmn:EndEvent',
+ eventDefinitionType: 'bpmn:EscalationEventDefinition'
+ }
+}, {
+ label: 'Error End Event',
+ actionName: 'replace-with-error-end',
+ className: 'bpmn-icon-end-event-error',
+ target: {
+ type: 'bpmn:EndEvent',
+ eventDefinitionType: 'bpmn:ErrorEventDefinition'
+ }
+}, {
+ label: 'Cancel End Event',
+ actionName: 'replace-with-cancel-end',
+ className: 'bpmn-icon-end-event-cancel',
+ target: {
+ type: 'bpmn:EndEvent',
+ eventDefinitionType: 'bpmn:CancelEventDefinition'
+ }
+}, {
+ label: 'Compensation End Event',
+ actionName: 'replace-with-compensation-end',
+ className: 'bpmn-icon-end-event-compensation',
+ target: {
+ type: 'bpmn:EndEvent',
+ eventDefinitionType: 'bpmn:CompensateEventDefinition'
+ }
+}, {
+ label: 'Signal End Event',
+ actionName: 'replace-with-signal-end',
+ className: 'bpmn-icon-end-event-signal',
+ target: {
+ type: 'bpmn:EndEvent',
+ eventDefinitionType: 'bpmn:SignalEventDefinition'
+ }
+}, {
+ label: 'Terminate End Event',
+ actionName: 'replace-with-terminate-end',
+ className: 'bpmn-icon-end-event-terminate',
+ target: {
+ type: 'bpmn:EndEvent',
+ eventDefinitionType: 'bpmn:TerminateEventDefinition'
+ }
+}];
+
+var GATEWAY = exports.GATEWAY = [{
+ label: 'Exclusive Gateway',
+ actionName: 'replace-with-exclusive-gateway',
+ className: 'bpmn-icon-gateway-xor',
+ target: {
+ type: 'bpmn:ExclusiveGateway'
+ }
+}, {
+ label: 'Parallel Gateway',
+ actionName: 'replace-with-parallel-gateway',
+ className: 'bpmn-icon-gateway-parallel',
+ target: {
+ type: 'bpmn:ParallelGateway'
+ }
+}, {
+ label: 'Inclusive Gateway',
+ actionName: 'replace-with-inclusive-gateway',
+ className: 'bpmn-icon-gateway-or',
+ target: {
+ type: 'bpmn:InclusiveGateway'
+ }
+}, {
+ label: 'Complex Gateway',
+ actionName: 'replace-with-complex-gateway',
+ className: 'bpmn-icon-gateway-complex',
+ target: {
+ type: 'bpmn:ComplexGateway'
+ }
+}, {
+ label: 'Event based Gateway',
+ actionName: 'replace-with-event-based-gateway',
+ className: 'bpmn-icon-gateway-eventbased',
+ target: {
+ type: 'bpmn:EventBasedGateway',
+ instantiate: false,
+ eventGatewayType: 'Exclusive'
+ }
+ // Gateways deactivated until https://github.com/bpmn-io/bpmn-js/issues/194
+ // {
+ // label: 'Event based instantiating Gateway',
+ // actionName: 'replace-with-exclusive-event-based-gateway',
+ // className: 'bpmn-icon-exclusive-event-based',
+ // target: {
+ // type: 'bpmn:EventBasedGateway'
+ // },
+ // options: {
+ // businessObject: { instantiate: true, eventGatewayType: 'Exclusive' }
+ // }
+ // },
+ // {
+ // label: 'Parallel Event based instantiating Gateway',
+ // actionName: 'replace-with-parallel-event-based-instantiate-gateway',
+ // className: 'bpmn-icon-parallel-event-based-instantiate-gateway',
+ // target: {
+ // type: 'bpmn:EventBasedGateway'
+ // },
+ // options: {
+ // businessObject: { instantiate: true, eventGatewayType: 'Parallel' }
+ // }
+ // }
+}];
+
+var SUBPROCESS_EXPANDED = exports.SUBPROCESS_EXPANDED = [{
+ label: 'Transaction',
+ actionName: 'replace-with-transaction',
+ className: 'bpmn-icon-transaction',
+ target: {
+ type: 'bpmn:Transaction',
+ isExpanded: true
+ }
+}, {
+ label: 'Event Sub Process',
+ actionName: 'replace-with-event-subprocess',
+ className: 'bpmn-icon-event-subprocess-expanded',
+ target: {
+ type: 'bpmn:SubProcess',
+ triggeredByEvent: true,
+ isExpanded: true
+ }
+}, {
+ label: 'Sub Process (collapsed)',
+ actionName: 'replace-with-collapsed-subprocess',
+ className: 'bpmn-icon-subprocess-collapsed',
+ target: {
+ type: 'bpmn:SubProcess',
+ isExpanded: false
+ }
+}];
+
+var TRANSACTION = exports.TRANSACTION = [{
+ label: 'Sub Process',
+ actionName: 'replace-with-subprocess',
+ className: 'bpmn-icon-subprocess-expanded',
+ target: {
+ type: 'bpmn:SubProcess',
+ isExpanded: true
+ }
+}, {
+ label: 'Event Sub Process',
+ actionName: 'replace-with-event-subprocess',
+ className: 'bpmn-icon-event-subprocess-expanded',
+ target: {
+ type: 'bpmn:SubProcess',
+ triggeredByEvent: true,
+ isExpanded: true
+ }
+}];
+
+var EVENT_SUB_PROCESS = exports.EVENT_SUB_PROCESS = [{
+ label: 'Sub Process',
+ actionName: 'replace-with-subprocess',
+ className: 'bpmn-icon-subprocess-expanded',
+ target: {
+ type: 'bpmn:SubProcess',
+ isExpanded: true
+ }
+}, {
+ label: 'Transaction',
+ actionName: 'replace-with-transaction',
+ className: 'bpmn-icon-transaction',
+ target: {
+ type: 'bpmn:Transaction',
+ isExpanded: true
+ }
+}];
+
+var TASK = exports.TASK = [{
+ label: 'Task',
+ actionName: 'replace-with-task',
+ className: 'bpmn-icon-task',
+ target: {
+ type: 'bpmn:Task'
+ }
+}, {
+ label: 'Send Task',
+ actionName: 'replace-with-send-task',
+ className: 'bpmn-icon-send',
+ target: {
+ type: 'bpmn:SendTask'
+ }
+}, {
+ label: 'Receive Task',
+ actionName: 'replace-with-receive-task',
+ className: 'bpmn-icon-receive',
+ target: {
+ type: 'bpmn:ReceiveTask'
+ }
+}, {
+ label: 'User Task',
+ actionName: 'replace-with-user-task',
+ className: 'bpmn-icon-user',
+ target: {
+ type: 'bpmn:UserTask'
+ }
+}, {
+ label: 'Manual Task',
+ actionName: 'replace-with-manual-task',
+ className: 'bpmn-icon-manual',
+ target: {
+ type: 'bpmn:ManualTask'
+ }
+}, {
+ label: 'Business Rule Task',
+ actionName: 'replace-with-rule-task',
+ className: 'bpmn-icon-business-rule',
+ target: {
+ type: 'bpmn:BusinessRuleTask'
+ }
+}, {
+ label: 'Service Task',
+ actionName: 'replace-with-service-task',
+ className: 'bpmn-icon-service',
+ target: {
+ type: 'bpmn:ServiceTask'
+ }
+}, {
+ label: 'Script Task',
+ actionName: 'replace-with-script-task',
+ className: 'bpmn-icon-script',
+ target: {
+ type: 'bpmn:ScriptTask'
+ }
+}, {
+ label: 'Call Activity',
+ actionName: 'replace-with-call-activity',
+ className: 'bpmn-icon-call-activity',
+ target: {
+ type: 'bpmn:CallActivity'
+ }
+}, {
+ label: 'Sub Process (collapsed)',
+ actionName: 'replace-with-collapsed-subprocess',
+ className: 'bpmn-icon-subprocess-collapsed',
+ target: {
+ type: 'bpmn:SubProcess',
+ isExpanded: false
+ }
+}, {
+ label: 'Sub Process (expanded)',
+ actionName: 'replace-with-expanded-subprocess',
+ className: 'bpmn-icon-subprocess-expanded',
+ target: {
+ type: 'bpmn:SubProcess',
+ isExpanded: true
+ }
+}];
+
+var BOUNDARY_EVENT = exports.BOUNDARY_EVENT = [{
+ label: 'Message Boundary Event',
+ actionName: 'replace-with-message-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-message',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:MessageEventDefinition'
+ }
+}, {
+ label: 'Timer Boundary Event',
+ actionName: 'replace-with-timer-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-timer',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:TimerEventDefinition'
+ }
+}, {
+ label: 'Escalation Boundary Event',
+ actionName: 'replace-with-escalation-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-escalation',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:EscalationEventDefinition'
+ }
+}, {
+ label: 'Conditional Boundary Event',
+ actionName: 'replace-with-conditional-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-condition',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:ConditionalEventDefinition'
+ }
+}, {
+ label: 'Error Boundary Event',
+ actionName: 'replace-with-error-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-error',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:ErrorEventDefinition'
+ }
+}, {
+ label: 'Cancel Boundary Event',
+ actionName: 'replace-with-cancel-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-cancel',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:CancelEventDefinition'
+ }
+}, {
+ label: 'Signal Boundary Event',
+ actionName: 'replace-with-signal-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-signal',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:SignalEventDefinition'
+ }
+}, {
+ label: 'Compensation Boundary Event',
+ actionName: 'replace-with-compensation-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-compensation',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:CompensateEventDefinition'
+ }
+}, {
+ label: 'Message Boundary Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-message-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-non-interrupting-message',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:MessageEventDefinition',
+ cancelActivity: false
+ }
+}, {
+ label: 'Timer Boundary Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-timer-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-non-interrupting-timer',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:TimerEventDefinition',
+ cancelActivity: false
+ }
+}, {
+ label: 'Escalation Boundary Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-escalation-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-non-interrupting-escalation',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:EscalationEventDefinition',
+ cancelActivity: false
+ }
+}, {
+ label: 'Conditional Boundary Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-conditional-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-non-interrupting-condition',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:ConditionalEventDefinition',
+ cancelActivity: false
+ }
+}, {
+ label: 'Signal Boundary Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-signal-boundary',
+ className: 'bpmn-icon-intermediate-event-catch-non-interrupting-signal',
+ target: {
+ type: 'bpmn:BoundaryEvent',
+ eventDefinitionType: 'bpmn:SignalEventDefinition',
+ cancelActivity: false
+ }
+}];
+
+var EVENT_SUB_PROCESS_START_EVENT = exports.EVENT_SUB_PROCESS_START_EVENT = [{
+ label: 'Message Start Event',
+ actionName: 'replace-with-message-start',
+ className: 'bpmn-icon-start-event-message',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:MessageEventDefinition'
+ }
+}, {
+ label: 'Timer Start Event',
+ actionName: 'replace-with-timer-start',
+ className: 'bpmn-icon-start-event-timer',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:TimerEventDefinition'
+ }
+}, {
+ label: 'Conditional Start Event',
+ actionName: 'replace-with-conditional-start',
+ className: 'bpmn-icon-start-event-condition',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:ConditionalEventDefinition'
+ }
+}, {
+ label: 'Signal Start Event',
+ actionName: 'replace-with-signal-start',
+ className: 'bpmn-icon-start-event-signal',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:SignalEventDefinition'
+ }
+}, {
+ label: 'Error Start Event',
+ actionName: 'replace-with-error-start',
+ className: 'bpmn-icon-start-event-error',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:ErrorEventDefinition'
+ }
+}, {
+ label: 'Escalation Start Event',
+ actionName: 'replace-with-escalation-start',
+ className: 'bpmn-icon-start-event-escalation',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:EscalationEventDefinition'
+ }
+}, {
+ label: 'Compensation Start Event',
+ actionName: 'replace-with-compensation-start',
+ className: 'bpmn-icon-start-event-compensation',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:CompensateEventDefinition'
+ }
+}, {
+ label: 'Message Start Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-message-start',
+ className: 'bpmn-icon-start-event-non-interrupting-message',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:MessageEventDefinition',
+ isInterrupting: false
+ }
+}, {
+ label: 'Timer Start Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-timer-start',
+ className: 'bpmn-icon-start-event-non-interrupting-timer',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:TimerEventDefinition',
+ isInterrupting: false
+ }
+}, {
+ label: 'Conditional Start Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-conditional-start',
+ className: 'bpmn-icon-start-event-non-interrupting-condition',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:ConditionalEventDefinition',
+ isInterrupting: false
+ }
+}, {
+ label: 'Signal Start Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-signal-start',
+ className: 'bpmn-icon-start-event-non-interrupting-signal',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:SignalEventDefinition',
+ isInterrupting: false
+ }
+}, {
+ label: 'Escalation Start Event (non-interrupting)',
+ actionName: 'replace-with-non-interrupting-escalation-start',
+ className: 'bpmn-icon-start-event-non-interrupting-escalation',
+ target: {
+ type: 'bpmn:StartEvent',
+ eventDefinitionType: 'bpmn:EscalationEventDefinition',
+ isInterrupting: false
+ }
+}];
+
+var SEQUENCE_FLOW = exports.SEQUENCE_FLOW = [{
+ label: 'Sequence Flow',
+ actionName: 'replace-with-sequence-flow',
+ className: 'bpmn-icon-connection'
+}, {
+ label: 'Default Flow',
+ actionName: 'replace-with-default-flow',
+ className: 'bpmn-icon-default-flow'
+}, {
+ label: 'Conditional Flow',
+ actionName: 'replace-with-conditional-flow',
+ className: 'bpmn-icon-conditional-flow'
+}];
+
+var PARTICIPANT = exports.PARTICIPANT = [{
+ label: 'Expanded Pool',
+ actionName: 'replace-with-expanded-pool',
+ className: 'bpmn-icon-participant',
+ target: {
+ type: 'bpmn:Participant',
+ isExpanded: true
+ }
+}, {
+ label: 'Collapsed Pool',
+ actionName: 'replace-with-collapsed-pool',
+ // TODO(@janstuemmel): maybe design new icon
+ className: 'bpmn-icon-lane',
+ target: {
+ type: 'bpmn:Participant',
+ isExpanded: false
+ }
+}];
+
+},{}],201:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _selection = require('diagram-js/lib/features/selection');
+
+var _selection2 = _interopRequireDefault(_selection);
+
+var _replace = require('diagram-js/lib/features/replace');
+
+var _replace2 = _interopRequireDefault(_replace);
+
+var _BpmnReplace = require('./BpmnReplace');
+
+var _BpmnReplace2 = _interopRequireDefault(_BpmnReplace);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_selection2.default, _replace2.default],
+ bpmnReplace: ['type', _BpmnReplace2.default]
+};
+
+},{"./BpmnReplace":199,"diagram-js/lib/features/replace":347,"diagram-js/lib/features/selection":361}],202:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnRules;
+
+var _minDash = require('min-dash');
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _ModelingUtil = require('../modeling/util/ModelingUtil');
+
+var _LabelUtil = require('../../util/LabelUtil');
+
+var _DiUtil = require('../../util/DiUtil');
+
+var _RuleProvider = require('diagram-js/lib/features/rules/RuleProvider');
+
+var _RuleProvider2 = _interopRequireDefault(_RuleProvider);
+
+var _BpmnSnappingUtil = require('../snapping/BpmnSnappingUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * BPMN specific modeling rule
+ */
+function BpmnRules(eventBus) {
+ _RuleProvider2.default.call(this, eventBus);
+}
+
+(0, _inherits2.default)(BpmnRules, _RuleProvider2.default);
+
+BpmnRules.$inject = ['eventBus'];
+
+BpmnRules.prototype.init = function () {
+
+ this.addRule('connection.start', function (context) {
+ var source = context.source;
+
+ return canStartConnection(source);
+ });
+
+ this.addRule('connection.create', function (context) {
+ var source = context.source,
+ target = context.target,
+ hints = context.hints || {},
+ targetParent = hints.targetParent,
+ targetAttach = hints.targetAttach;
+
+ // don't allow incoming connections on
+ // newly created boundary events
+ // to boundary events
+ if (targetAttach) {
+ return false;
+ }
+
+ // temporarily set target parent for scoping
+ // checks to work
+ if (targetParent) {
+ target.parent = targetParent;
+ }
+
+ try {
+ return canConnect(source, target);
+ } finally {
+ // unset temporary target parent
+ if (targetParent) {
+ target.parent = null;
+ }
+ }
+ });
+
+ this.addRule('connection.reconnectStart', function (context) {
+
+ var connection = context.connection,
+ source = context.hover || context.source,
+ target = connection.target;
+
+ return canConnect(source, target, connection);
+ });
+
+ this.addRule('connection.reconnectEnd', function (context) {
+
+ var connection = context.connection,
+ source = connection.source,
+ target = context.hover || context.target;
+
+ return canConnect(source, target, connection);
+ });
+
+ this.addRule('connection.updateWaypoints', function (context) {
+ // OK! but visually ignore
+ return null;
+ });
+
+ this.addRule('shape.resize', function (context) {
+
+ var shape = context.shape,
+ newBounds = context.newBounds;
+
+ return canResize(shape, newBounds);
+ });
+
+ this.addRule('elements.move', function (context) {
+
+ var target = context.target,
+ shapes = context.shapes,
+ position = context.position;
+
+ return canAttach(shapes, target, null, position) || canReplace(shapes, target, position) || canMove(shapes, target, position) || canInsert(shapes, target, position);
+ });
+
+ this.addRule('shape.create', function (context) {
+ return canCreate(context.shape, context.target, context.source, context.position);
+ });
+
+ this.addRule('shape.attach', function (context) {
+
+ return canAttach(context.shape, context.target, null, context.position);
+ });
+
+ this.addRule('element.copy', function (context) {
+ var collection = context.collection,
+ element = context.element;
+
+ return canCopy(collection, element);
+ });
+
+ this.addRule('element.paste', function (context) {
+ var parent = context.parent,
+ element = context.element,
+ position = context.position,
+ source = context.source,
+ target = context.target;
+
+ if (source || target) {
+ return canConnect(source, target);
+ }
+
+ return canAttach([element], parent, null, position) || canCreate(element, parent, null, position);
+ });
+
+ this.addRule('elements.paste', function (context) {
+ var tree = context.tree,
+ target = context.target;
+
+ return canPaste(tree, target);
+ });
+};
+
+BpmnRules.prototype.canConnectMessageFlow = canConnectMessageFlow;
+
+BpmnRules.prototype.canConnectSequenceFlow = canConnectSequenceFlow;
+
+BpmnRules.prototype.canConnectDataAssociation = canConnectDataAssociation;
+
+BpmnRules.prototype.canConnectAssociation = canConnectAssociation;
+
+BpmnRules.prototype.canMove = canMove;
+
+BpmnRules.prototype.canAttach = canAttach;
+
+BpmnRules.prototype.canReplace = canReplace;
+
+BpmnRules.prototype.canDrop = canDrop;
+
+BpmnRules.prototype.canInsert = canInsert;
+
+BpmnRules.prototype.canCreate = canCreate;
+
+BpmnRules.prototype.canConnect = canConnect;
+
+BpmnRules.prototype.canResize = canResize;
+
+BpmnRules.prototype.canCopy = canCopy;
+
+/**
+ * Utility functions for rule checking
+ */
+
+/**
+ * Checks if given element can be used for starting connection.
+ *
+ * @param {Element} source
+ * @return {Boolean}
+ */
+function canStartConnection(element) {
+ if (nonExistingOrLabel(element)) {
+ return null;
+ }
+
+ return (0, _ModelingUtil.isAny)(element, ['bpmn:FlowNode', 'bpmn:InteractionNode', 'bpmn:DataObjectReference', 'bpmn:DataStoreReference']);
+}
+
+function nonExistingOrLabel(element) {
+ return !element || (0, _LabelUtil.isLabel)(element);
+}
+
+function isSame(a, b) {
+ return a === b;
+}
+
+function getOrganizationalParent(element) {
+
+ do {
+ if ((0, _ModelUtil.is)(element, 'bpmn:Process')) {
+ return (0, _ModelUtil.getBusinessObject)(element);
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) {
+ return (0, _ModelUtil.getBusinessObject)(element).processRef || (0, _ModelUtil.getBusinessObject)(element);
+ }
+ } while (element = element.parent);
+}
+
+function isTextAnnotation(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:TextAnnotation');
+}
+
+function isCompensationBoundary(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && hasEventDefinition(element, 'bpmn:CompensateEventDefinition');
+}
+
+function isForCompensation(e) {
+ return (0, _ModelUtil.getBusinessObject)(e).isForCompensation;
+}
+
+function isSameOrganization(a, b) {
+ var parentA = getOrganizationalParent(a),
+ parentB = getOrganizationalParent(b);
+
+ return parentA === parentB;
+}
+
+function isMessageFlowSource(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:InteractionNode') && (!(0, _ModelUtil.is)(element, 'bpmn:Event') || (0, _ModelUtil.is)(element, 'bpmn:ThrowEvent') && hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition'));
+}
+
+function isMessageFlowTarget(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:InteractionNode') && !isForCompensation(element) && (!(0, _ModelUtil.is)(element, 'bpmn:Event') || (0, _ModelUtil.is)(element, 'bpmn:CatchEvent') && hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition'));
+}
+
+function getScopeParent(element) {
+
+ var parent = element;
+
+ while (parent = parent.parent) {
+
+ if ((0, _ModelUtil.is)(parent, 'bpmn:FlowElementsContainer')) {
+ return (0, _ModelUtil.getBusinessObject)(parent);
+ }
+
+ if ((0, _ModelUtil.is)(parent, 'bpmn:Participant')) {
+ return (0, _ModelUtil.getBusinessObject)(parent).processRef;
+ }
+ }
+
+ return null;
+}
+
+function isSameScope(a, b) {
+ var scopeParentA = getScopeParent(a),
+ scopeParentB = getScopeParent(b);
+
+ return scopeParentA && scopeParentA === scopeParentB;
+}
+
+function hasEventDefinition(element, eventDefinition) {
+ var bo = (0, _ModelUtil.getBusinessObject)(element);
+
+ return !!(0, _minDash.find)(bo.eventDefinitions || [], function (definition) {
+ return (0, _ModelUtil.is)(definition, eventDefinition);
+ });
+}
+
+function hasEventDefinitionOrNone(element, eventDefinition) {
+ var bo = (0, _ModelUtil.getBusinessObject)(element);
+
+ return (bo.eventDefinitions || []).every(function (definition) {
+ return (0, _ModelUtil.is)(definition, eventDefinition);
+ });
+}
+
+function isSequenceFlowSource(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(element, 'bpmn:EndEvent') && !(0, _DiUtil.isEventSubProcess)(element) && !((0, _ModelUtil.is)(element, 'bpmn:IntermediateThrowEvent') && hasEventDefinition(element, 'bpmn:LinkEventDefinition')) && !isCompensationBoundary(element) && !isForCompensation(element);
+}
+
+function isSequenceFlowTarget(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(element, 'bpmn:StartEvent') && !(0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !(0, _DiUtil.isEventSubProcess)(element) && !((0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && hasEventDefinition(element, 'bpmn:LinkEventDefinition')) && !isForCompensation(element);
+}
+
+function isEventBasedTarget(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:ReceiveTask') || (0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && (hasEventDefinition(element, 'bpmn:MessageEventDefinition') || hasEventDefinition(element, 'bpmn:TimerEventDefinition') || hasEventDefinition(element, 'bpmn:ConditionalEventDefinition') || hasEventDefinition(element, 'bpmn:SignalEventDefinition'));
+}
+
+function isConnection(element) {
+ return element.waypoints;
+}
+
+function getParents(element) {
+
+ var parents = [];
+
+ while (element) {
+ element = element.parent;
+
+ if (element) {
+ parents.push(element);
+ }
+ }
+
+ return parents;
+}
+
+function isParent(possibleParent, element) {
+ var allParents = getParents(element);
+ return allParents.indexOf(possibleParent) !== -1;
+}
+
+function canConnect(source, target, connection) {
+
+ if (nonExistingOrLabel(source) || nonExistingOrLabel(target)) {
+ return null;
+ }
+
+ if (!(0, _ModelUtil.is)(connection, 'bpmn:DataAssociation')) {
+
+ if (canConnectMessageFlow(source, target)) {
+ return { type: 'bpmn:MessageFlow' };
+ }
+
+ if (canConnectSequenceFlow(source, target)) {
+ return { type: 'bpmn:SequenceFlow' };
+ }
+ }
+
+ var connectDataAssociation = canConnectDataAssociation(source, target);
+
+ if (connectDataAssociation) {
+ return connectDataAssociation;
+ }
+
+ if (isCompensationBoundary(source) && isForCompensation(target)) {
+ return {
+ type: 'bpmn:Association',
+ associationDirection: 'One'
+ };
+ }
+
+ if (canConnectAssociation(source, target)) {
+
+ return {
+ type: 'bpmn:Association'
+ };
+ }
+
+ return false;
+}
+
+/**
+ * Can an element be dropped into the target element
+ *
+ * @return {Boolean}
+ */
+function canDrop(element, target, position) {
+
+ // can move labels everywhere
+ if ((0, _LabelUtil.isLabel)(element)) {
+ return true;
+ }
+
+ // disallow to create elements on collapsed pools
+ if ((0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(target)) {
+ return false;
+ }
+
+ // allow to create new participants on
+ // on existing collaboration and process diagrams
+ if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) {
+ return (0, _ModelUtil.is)(target, 'bpmn:Process') || (0, _ModelUtil.is)(target, 'bpmn:Collaboration');
+ }
+
+ // allow creating lanes on participants and other lanes only
+ if ((0, _ModelUtil.is)(element, 'bpmn:Lane')) {
+ return (0, _ModelUtil.is)(target, 'bpmn:Participant') || (0, _ModelUtil.is)(target, 'bpmn:Lane');
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent')) {
+ return false;
+ }
+
+ // drop flow elements onto flow element containers
+ // and participants
+ if ((0, _ModelUtil.is)(element, 'bpmn:FlowElement') && !(0, _ModelUtil.is)(element, 'bpmn:DataStoreReference')) {
+ if ((0, _ModelUtil.is)(target, 'bpmn:FlowElementsContainer')) {
+ return (0, _DiUtil.isExpanded)(target);
+ }
+
+ return (0, _ModelingUtil.isAny)(target, ['bpmn:Participant', 'bpmn:Lane']);
+ }
+
+ // account for the fact that data associations are always
+ // rendered and moved to top (Process or Collaboration level)
+ //
+ // artifacts may be placed wherever, too
+ if ((0, _ModelingUtil.isAny)(element, ['bpmn:Artifact', 'bpmn:DataAssociation', 'bpmn:DataStoreReference'])) {
+ return (0, _ModelingUtil.isAny)(target, ['bpmn:Collaboration', 'bpmn:Lane', 'bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess']);
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:MessageFlow')) {
+ return (0, _ModelUtil.is)(target, 'bpmn:Collaboration') || element.source.parent == target || element.target.parent == target;
+ }
+
+ return false;
+}
+
+function canPaste(tree, target) {
+ var topLevel = tree[0],
+ participants;
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration')) {
+ return (0, _minDash.every)(topLevel, function (e) {
+ return e.type === 'bpmn:Participant';
+ });
+ }
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:Process')) {
+ participants = (0, _minDash.some)(topLevel, function (e) {
+ return e.type === 'bpmn:Participant';
+ });
+
+ return !(participants && target.children.length > 0);
+ }
+
+ // disallow to create elements on collapsed pools
+ if ((0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(target)) {
+ return false;
+ }
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:FlowElementsContainer')) {
+ return (0, _DiUtil.isExpanded)(target);
+ }
+
+ return (0, _ModelingUtil.isAny)(target, ['bpmn:Collaboration', 'bpmn:Lane', 'bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess']);
+}
+
+function isBoundaryEvent(element) {
+ return !(0, _LabelUtil.isLabel)(element) && (0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent');
+}
+
+function isLane(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:Lane');
+}
+
+/**
+ * We treat IntermediateThrowEvents as boundary events during create,
+ * this must be reflected in the rules.
+ */
+function isBoundaryCandidate(element) {
+ return isBoundaryEvent(element) || (0, _ModelUtil.is)(element, 'bpmn:IntermediateThrowEvent') && !element.parent;
+}
+
+function isReceiveTaskAfterEventBasedGateway(element) {
+ return (0, _ModelUtil.is)(element, 'bpmn:ReceiveTask') && (0, _minDash.find)(element.incoming, function (incoming) {
+ return (0, _ModelUtil.is)(incoming.source, 'bpmn:EventBasedGateway');
+ });
+}
+
+function canAttach(elements, target, source, position) {
+
+ if (!Array.isArray(elements)) {
+ elements = [elements];
+ }
+
+ // disallow appending as boundary event
+ if (source) {
+ return false;
+ }
+
+ // only (re-)attach one element at a time
+ if (elements.length !== 1) {
+ return false;
+ }
+
+ var element = elements[0];
+
+ // do not attach labels
+ if ((0, _LabelUtil.isLabel)(element)) {
+ return false;
+ }
+
+ // only handle boundary events
+ if (!isBoundaryCandidate(element)) {
+ return false;
+ }
+
+ // allow default move operation
+ if (!target) {
+ return true;
+ }
+
+ // disallow drop on event sub processes
+ if ((0, _DiUtil.isEventSubProcess)(target)) {
+ return false;
+ }
+
+ // only allow drop on non compensation activities
+ if (!(0, _ModelUtil.is)(target, 'bpmn:Activity') || isForCompensation(target)) {
+ return false;
+ }
+
+ // only attach to subprocess border
+ if (position && !(0, _BpmnSnappingUtil.getBoundaryAttachment)(position, target)) {
+ return false;
+ }
+
+ // do not attach on receive tasks after event based gateways
+ if (isReceiveTaskAfterEventBasedGateway(target)) {
+ return false;
+ }
+
+ return 'attach';
+}
+
+/**
+ * Defines how to replace elements for a given target.
+ *
+ * Returns an array containing all elements which will be replaced.
+ *
+ * @example
+ *
+ * [{ id: 'IntermediateEvent_2',
+ * type: 'bpmn:StartEvent'
+ * },
+ * { id: 'IntermediateEvent_5',
+ * type: 'bpmn:EndEvent'
+ * }]
+ *
+ * @param {Array} elements
+ * @param {Object} target
+ *
+ * @return {Object} an object containing all elements which have to be replaced
+ */
+function canReplace(elements, target, position) {
+
+ if (!target) {
+ return false;
+ }
+
+ var canExecute = {
+ replacements: []
+ };
+
+ (0, _minDash.forEach)(elements, function (element) {
+
+ if (!(0, _DiUtil.isEventSubProcess)(target)) {
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:StartEvent') && element.type !== 'label' && canDrop(element, target)) {
+
+ // replace a non-interrupting start event by a blank interrupting start event
+ // when the target is not an event sub process
+ if (!(0, _DiUtil.isInterrupting)(element)) {
+ canExecute.replacements.push({
+ oldElementId: element.id,
+ newElementType: 'bpmn:StartEvent'
+ });
+ }
+
+ // replace an error/escalation/compansate start event by a blank interrupting start event
+ // when the target is not an event sub process
+ if ((0, _DiUtil.hasErrorEventDefinition)(element) || (0, _DiUtil.hasEscalationEventDefinition)(element) || (0, _DiUtil.hasCompensateEventDefinition)(element)) {
+ canExecute.replacements.push({
+ oldElementId: element.id,
+ newElementType: 'bpmn:StartEvent'
+ });
+ }
+ }
+ }
+
+ if (!(0, _ModelUtil.is)(target, 'bpmn:Transaction')) {
+ if (hasEventDefinition(element, 'bpmn:CancelEventDefinition') && element.type !== 'label') {
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:EndEvent') && canDrop(element, target)) {
+ canExecute.replacements.push({
+ oldElementId: element.id,
+ newElementType: 'bpmn:EndEvent'
+ });
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && canAttach(element, target, null, position)) {
+ canExecute.replacements.push({
+ oldElementId: element.id,
+ newElementType: 'bpmn:BoundaryEvent'
+ });
+ }
+ }
+ }
+ });
+
+ return canExecute.replacements.length ? canExecute : false;
+}
+
+function canMove(elements, target) {
+
+ // do not move selection containing boundary events
+ if ((0, _minDash.some)(elements, isBoundaryEvent)) {
+ return false;
+ }
+
+ // do not move selection containing lanes
+ if ((0, _minDash.some)(elements, isLane)) {
+ return false;
+ }
+
+ // allow default move check to start move operation
+ if (!target) {
+ return true;
+ }
+
+ return elements.every(function (element) {
+ return canDrop(element, target);
+ });
+}
+
+function canCreate(shape, target, source, position) {
+
+ if (!target) {
+ return false;
+ }
+
+ if ((0, _LabelUtil.isLabel)(target)) {
+ return null;
+ }
+
+ if (isSame(source, target)) {
+ return false;
+ }
+
+ // ensure we do not drop the element
+ // into source
+ if (source && isParent(source, target)) {
+ return false;
+ }
+
+ return canDrop(shape, target, position) || canInsert(shape, target, position);
+}
+
+function canResize(shape, newBounds) {
+ if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess')) {
+ return (0, _DiUtil.isExpanded)(shape) && (!newBounds || newBounds.width >= 100 && newBounds.height >= 80);
+ }
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) {
+ return !newBounds || newBounds.width >= 130 && newBounds.height >= 60;
+ }
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
+ return !newBounds || newBounds.width >= 250 && newBounds.height >= 50;
+ }
+
+ if (isTextAnnotation(shape)) {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Check, whether one side of the relationship
+ * is a text annotation.
+ */
+function isOneTextAnnotation(source, target) {
+
+ var sourceTextAnnotation = isTextAnnotation(source),
+ targetTextAnnotation = isTextAnnotation(target);
+
+ return (sourceTextAnnotation || targetTextAnnotation) && sourceTextAnnotation !== targetTextAnnotation;
+}
+
+function canConnectAssociation(source, target) {
+
+ // do not connect connections
+ if (isConnection(source) || isConnection(target)) {
+ return false;
+ }
+
+ // compensation boundary events are exception
+ if (isCompensationBoundary(source) && isForCompensation(target)) {
+ return true;
+ }
+
+ // don't connect parent <-> child
+ if (isParent(target, source) || isParent(source, target)) {
+ return false;
+ }
+
+ // allow connection of associations between and
+ return isOneTextAnnotation(source, target);
+}
+
+function canConnectMessageFlow(source, target) {
+
+ return isMessageFlowSource(source) && isMessageFlowTarget(target) && !isSameOrganization(source, target);
+}
+
+function canConnectSequenceFlow(source, target) {
+
+ return isSequenceFlowSource(source) && isSequenceFlowTarget(target) && isSameScope(source, target) && !((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && !isEventBasedTarget(target));
+}
+
+function canConnectDataAssociation(source, target) {
+
+ if ((0, _ModelingUtil.isAny)(source, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference']) && (0, _ModelingUtil.isAny)(target, ['bpmn:Activity', 'bpmn:ThrowEvent'])) {
+ return { type: 'bpmn:DataInputAssociation' };
+ }
+
+ if ((0, _ModelingUtil.isAny)(target, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference']) && (0, _ModelingUtil.isAny)(source, ['bpmn:Activity', 'bpmn:CatchEvent'])) {
+ return { type: 'bpmn:DataOutputAssociation' };
+ }
+
+ return false;
+}
+
+function canInsert(shape, flow, position) {
+
+ if (!flow) {
+ return false;
+ }
+
+ if (Array.isArray(shape)) {
+ if (shape.length !== 1) {
+ return false;
+ }
+
+ shape = shape[0];
+ }
+
+ if (flow.source === shape || flow.target === shape) {
+ return false;
+ }
+
+ // return true if we can drop on the
+ // underlying flow parent
+ //
+ // at this point we are not really able to talk
+ // about connection rules (yet)
+
+ return (0, _ModelingUtil.isAny)(flow, ['bpmn:SequenceFlow', 'bpmn:MessageFlow']) && !(0, _LabelUtil.isLabel)(flow) && (0, _ModelUtil.is)(shape, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(shape, 'bpmn:BoundaryEvent') && canDrop(shape, flow.parent, position);
+}
+
+function contains(collection, element) {
+ return collection && element && collection.indexOf(element) !== -1;
+}
+
+function canCopy(collection, element) {
+ if ((0, _ModelUtil.is)(element, 'bpmn:Lane') && !contains(collection, element.parent)) {
+ return false;
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !contains(collection, element.host)) {
+ return false;
+ }
+
+ return true;
+}
+
+},{"../../util/DiUtil":214,"../../util/LabelUtil":215,"../../util/ModelUtil":216,"../modeling/util/ModelingUtil":189,"../snapping/BpmnSnappingUtil":207,"diagram-js/lib/features/rules/RuleProvider":353,"inherits":415,"min-dash":505}],203:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _rules = require('diagram-js/lib/features/rules');
+
+var _rules2 = _interopRequireDefault(_rules);
+
+var _BpmnRules = require('./BpmnRules');
+
+var _BpmnRules2 = _interopRequireDefault(_BpmnRules);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_rules2.default],
+ __init__: ['bpmnRules'],
+ bpmnRules: ['type', _BpmnRules2.default]
+};
+
+},{"./BpmnRules":202,"diagram-js/lib/features/rules":355}],204:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnSearchProvider;
+
+var _minDash = require('min-dash');
+
+var _LabelUtil = require('../label-editing/LabelUtil');
+
+/**
+ * Provides ability to search through BPMN elements
+ */
+function BpmnSearchProvider(elementRegistry, searchPad, canvas) {
+
+ this._elementRegistry = elementRegistry;
+ this._canvas = canvas;
+
+ searchPad.registerProvider(this);
+}
+
+BpmnSearchProvider.$inject = ['elementRegistry', 'searchPad', 'canvas'];
+
+/**
+ * Finds all elements that match given pattern
+ *
+ * :
+ * {
+ * primaryTokens: >,
+ * secondaryTokens: >,
+ * element:
+ * }
+ *
+ * :
+ * {
+ * normal|matched:
+ * }
+ *
+ * @param {String} pattern
+ * @return {Array}
+ */
+BpmnSearchProvider.prototype.find = function (pattern) {
+ var rootElement = this._canvas.getRootElement();
+
+ var elements = this._elementRegistry.filter(function (element) {
+ if (element.labelTarget) {
+ return false;
+ }
+ return true;
+ });
+
+ // do not include root element
+ elements = (0, _minDash.filter)(elements, function (element) {
+ return element !== rootElement;
+ });
+
+ elements = (0, _minDash.map)(elements, function (element) {
+ return {
+ primaryTokens: matchAndSplit((0, _LabelUtil.getLabel)(element), pattern),
+ secondaryTokens: matchAndSplit(element.id, pattern),
+ element: element
+ };
+ });
+
+ // exclude non-matched elements
+ elements = (0, _minDash.filter)(elements, function (element) {
+ return hasMatched(element.primaryTokens) || hasMatched(element.secondaryTokens);
+ });
+
+ elements = (0, _minDash.sortBy)(elements, function (element) {
+ return (0, _LabelUtil.getLabel)(element.element) + element.element.id;
+ });
+
+ return elements;
+};
+
+function hasMatched(tokens) {
+ var matched = (0, _minDash.filter)(tokens, function (t) {
+ return !!t.matched;
+ });
+
+ return matched.length > 0;
+}
+
+function matchAndSplit(text, pattern) {
+ var tokens = [],
+ originalText = text;
+
+ if (!text) {
+ return tokens;
+ }
+
+ text = text.toLowerCase();
+ pattern = pattern.toLowerCase();
+
+ var i = text.indexOf(pattern);
+
+ if (i > -1) {
+ if (i !== 0) {
+ tokens.push({
+ normal: originalText.substr(0, i)
+ });
+ }
+
+ tokens.push({
+ matched: originalText.substr(i, pattern.length)
+ });
+
+ if (pattern.length + i < text.length) {
+ tokens.push({
+ normal: originalText.substr(pattern.length + i, text.length)
+ });
+ }
+ } else {
+ tokens.push({
+ normal: originalText
+ });
+ }
+
+ return tokens;
+}
+
+},{"../label-editing/LabelUtil":142,"min-dash":505}],205:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _searchPad = require('diagram-js/lib/features/search-pad');
+
+var _searchPad2 = _interopRequireDefault(_searchPad);
+
+var _BpmnSearchProvider = require('./BpmnSearchProvider');
+
+var _BpmnSearchProvider2 = _interopRequireDefault(_BpmnSearchProvider);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_searchPad2.default],
+ __init__: ['bpmnSearch'],
+ bpmnSearch: ['type', _BpmnSearchProvider2.default]
+};
+
+},{"./BpmnSearchProvider":204,"diagram-js/lib/features/search-pad":357}],206:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnSnapping;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _minDash = require('min-dash');
+
+var _Elements = require('diagram-js/lib/util/Elements');
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _ModelingUtil = require('../modeling/util/ModelingUtil');
+
+var _DiUtil = require('../../util/DiUtil');
+
+var _Snapping = require('diagram-js/lib/features/snapping/Snapping');
+
+var _Snapping2 = _interopRequireDefault(_Snapping);
+
+var _SnapUtil = require('diagram-js/lib/features/snapping/SnapUtil');
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _BpmnSnappingUtil = require('./BpmnSnappingUtil');
+
+var _LaneUtil = require('../modeling/util/LaneUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var round = Math.round;
+
+var HIGH_PRIORITY = 1500;
+
+/**
+ * BPMN specific snapping functionality
+ *
+ * * snap on process elements if a pool is created inside a
+ * process diagram
+ *
+ * @param {EventBus} eventBus
+ * @param {Canvas} canvas
+ */
+function BpmnSnapping(eventBus, canvas, bpmnRules, elementRegistry) {
+
+ // instantiate super
+ _Snapping2.default.call(this, eventBus, canvas);
+
+ /**
+ * Drop participant on process <> process elements snapping
+ */
+ eventBus.on('create.start', function (event) {
+
+ var context = event.context,
+ shape = context.shape,
+ rootElement = canvas.getRootElement();
+
+ // snap participant around existing elements (if any)
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(rootElement, 'bpmn:Process')) {
+ initParticipantSnapping(context, shape, rootElement.children);
+ }
+ });
+
+ eventBus.on(['create.move', 'create.end'], HIGH_PRIORITY, function (event) {
+
+ var context = event.context,
+ shape = context.shape,
+ participantSnapBox = context.participantSnapBox;
+
+ if (!(0, _SnapUtil.isSnapped)(event) && participantSnapBox) {
+ snapParticipant(participantSnapBox, shape, event);
+ }
+ });
+
+ eventBus.on('shape.move.start', function (event) {
+
+ var context = event.context,
+ shape = context.shape,
+ rootElement = canvas.getRootElement();
+
+ // snap participant around existing elements (if any)
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(rootElement, 'bpmn:Process')) {
+ initParticipantSnapping(context, shape, rootElement.children);
+ }
+ });
+
+ function canAttach(shape, target, position) {
+ return bpmnRules.canAttach([shape], target, null, position) === 'attach';
+ }
+
+ function canConnect(source, target) {
+ return bpmnRules.canConnect(source, target);
+ }
+
+ /**
+ * Snap boundary events to elements border
+ */
+ eventBus.on(['create.move', 'create.end', 'shape.move.move', 'shape.move.end'], HIGH_PRIORITY, function (event) {
+
+ var context = event.context,
+ target = context.target,
+ shape = context.shape;
+
+ if (target && !(0, _SnapUtil.isSnapped)(event) && canAttach(shape, target, event)) {
+ snapBoundaryEvent(event, shape, target);
+ }
+ });
+
+ /**
+ * Adjust parent for flowElements to the target participant
+ * when droping onto lanes.
+ */
+ eventBus.on(['shape.move.hover', 'shape.move.move', 'shape.move.end', 'create.hover', 'create.move', 'create.end'], HIGH_PRIORITY, function (event) {
+ var context = event.context,
+ shape = context.shape,
+ hover = event.hover;
+
+ if ((0, _ModelUtil.is)(hover, 'bpmn:Lane') && !(0, _ModelingUtil.isAny)(shape, ['bpmn:Lane', 'bpmn:Participant'])) {
+ event.hover = (0, _LaneUtil.getLanesRoot)(hover);
+ event.hoverGfx = elementRegistry.getGraphics(event.hover);
+ }
+ });
+
+ /**
+ * Snap sequence flows.
+ */
+ eventBus.on(['connect.move', 'connect.hover', 'connect.end'], HIGH_PRIORITY, function (event) {
+ var context = event.context,
+ source = context.source,
+ target = context.target;
+
+ var connection = canConnect(source, target) || {};
+
+ if (!context.initialSourcePosition) {
+ context.initialSourcePosition = context.sourcePosition;
+ }
+
+ if (target && (connection.type === 'bpmn:Association' || connection.type === 'bpmn:DataOutputAssociation' || connection.type === 'bpmn:DataInputAssociation' || connection.type === 'bpmn:SequenceFlow')) {
+ // snap source
+ context.sourcePosition = (0, _SnapUtil.mid)(source);
+
+ // snap target
+ snapToPosition(event, (0, _SnapUtil.mid)(target));
+ } else if (connection.type === 'bpmn:MessageFlow') {
+
+ if ((0, _ModelUtil.is)(source, 'bpmn:Event')) {
+ // snap source
+ context.sourcePosition = (0, _SnapUtil.mid)(source);
+ }
+
+ if ((0, _ModelUtil.is)(target, 'bpmn:Event')) {
+ // snap target
+ snapToPosition(event, (0, _SnapUtil.mid)(target));
+ }
+ } else {
+ // otherwise reset source snap
+ context.sourcePosition = context.initialSourcePosition;
+ }
+ });
+
+ eventBus.on('resize.start', HIGH_PRIORITY, function (event) {
+ var context = event.context,
+ shape = context.shape;
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(shape)) {
+ context.minDimensions = { width: 140, height: 120 };
+ }
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
+ context.minDimensions = { width: 300, height: 150 };
+ }
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
+ context.resizeConstraints = (0, _BpmnSnappingUtil.getParticipantSizeConstraints)(shape, context.direction, context.balanced);
+ }
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) {
+ context.minDimensions = { width: 50, height: 30 };
+ }
+ });
+}
+
+(0, _inherits2.default)(BpmnSnapping, _Snapping2.default);
+
+BpmnSnapping.$inject = ['eventBus', 'canvas', 'bpmnRules', 'elementRegistry'];
+
+BpmnSnapping.prototype.initSnap = function (event) {
+
+ var context = event.context,
+ shape = event.shape,
+ shapeMid,
+ shapeBounds,
+ shapeTopLeft,
+ shapeBottomRight,
+ snapContext;
+
+ snapContext = _Snapping2.default.prototype.initSnap.call(this, event);
+
+ if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
+ // assign higher priority for outer snaps on participants
+ snapContext.setSnapLocations(['top-left', 'bottom-right', 'mid']);
+ }
+
+ if (shape) {
+
+ shapeMid = (0, _SnapUtil.mid)(shape, event);
+
+ shapeBounds = {
+ width: shape.width,
+ height: shape.height,
+ x: isNaN(shape.x) ? round(shapeMid.x - shape.width / 2) : shape.x,
+ y: isNaN(shape.y) ? round(shapeMid.y - shape.height / 2) : shape.y
+ };
+
+ shapeTopLeft = (0, _SnapUtil.topLeft)(shapeBounds);
+ shapeBottomRight = (0, _SnapUtil.bottomRight)(shapeBounds);
+
+ snapContext.setSnapOrigin('top-left', {
+ x: shapeTopLeft.x - event.x,
+ y: shapeTopLeft.y - event.y
+ });
+
+ snapContext.setSnapOrigin('bottom-right', {
+ x: shapeBottomRight.x - event.x,
+ y: shapeBottomRight.y - event.y
+ });
+
+ (0, _minDash.forEach)(shape.outgoing, function (c) {
+ var docking = c.waypoints[0];
+
+ docking = docking.original || docking;
+
+ snapContext.setSnapOrigin(c.id + '-docking', {
+ x: docking.x - event.x,
+ y: docking.y - event.y
+ });
+ });
+
+ (0, _minDash.forEach)(shape.incoming, function (c) {
+ var docking = c.waypoints[c.waypoints.length - 1];
+
+ docking = docking.original || docking;
+
+ snapContext.setSnapOrigin(c.id + '-docking', {
+ x: docking.x - event.x,
+ y: docking.y - event.y
+ });
+ });
+ }
+
+ var source = context.source;
+
+ if (source) {
+ snapContext.addDefaultSnap('mid', (0, _SnapUtil.mid)(source));
+ }
+};
+
+BpmnSnapping.prototype.addTargetSnaps = function (snapPoints, shape, target) {
+
+ // use target parent as snap target
+ if ((0, _ModelUtil.is)(shape, 'bpmn:BoundaryEvent') && shape.type !== 'label') {
+ target = target.parent;
+ }
+
+ // add sequence flow parents as snap targets
+ if ((0, _ModelUtil.is)(target, 'bpmn:SequenceFlow')) {
+ this.addTargetSnaps(snapPoints, shape, target.parent);
+ }
+
+ var siblings = this.getSiblings(shape, target) || [];
+
+ (0, _minDash.forEach)(siblings, function (sibling) {
+
+ // do not snap to lanes
+ if ((0, _ModelUtil.is)(sibling, 'bpmn:Lane')) {
+ return;
+ }
+
+ if (sibling.waypoints) {
+
+ (0, _minDash.forEach)(sibling.waypoints.slice(1, -1), function (waypoint, i) {
+ var nextWaypoint = sibling.waypoints[i + 2],
+ previousWaypoint = sibling.waypoints[i];
+
+ if (!nextWaypoint || !previousWaypoint) {
+ throw new Error('waypoints must exist');
+ }
+
+ if (nextWaypoint.x === waypoint.x || nextWaypoint.y === waypoint.y || previousWaypoint.x === waypoint.x || previousWaypoint.y === waypoint.y) {
+ snapPoints.add('mid', waypoint);
+ }
+ });
+
+ return;
+ }
+
+ snapPoints.add('mid', (0, _SnapUtil.mid)(sibling));
+
+ if ((0, _ModelUtil.is)(sibling, 'bpmn:Participant')) {
+ snapPoints.add('top-left', (0, _SnapUtil.topLeft)(sibling));
+ snapPoints.add('bottom-right', (0, _SnapUtil.bottomRight)(sibling));
+ }
+ });
+
+ (0, _minDash.forEach)(shape.incoming, function (c) {
+
+ if (siblings.indexOf(c.source) === -1) {
+ snapPoints.add('mid', (0, _SnapUtil.mid)(c.source));
+ }
+
+ var docking = c.waypoints[0];
+ snapPoints.add(c.id + '-docking', docking.original || docking);
+ });
+
+ (0, _minDash.forEach)(shape.outgoing, function (c) {
+
+ if (siblings.indexOf(c.target) === -1) {
+ snapPoints.add('mid', (0, _SnapUtil.mid)(c.target));
+ }
+
+ var docking = c.waypoints[c.waypoints.length - 1];
+ snapPoints.add(c.id + '-docking', docking.original || docking);
+ });
+};
+
+// participant snapping //////////////////////
+
+function initParticipantSnapping(context, shape, elements) {
+
+ if (!elements.length) {
+ return;
+ }
+
+ var snapBox = (0, _Elements.getBBox)(elements.filter(function (e) {
+ return !e.labelTarget && !e.waypoints;
+ }));
+
+ snapBox.x -= 50;
+ snapBox.y -= 20;
+ snapBox.width += 70;
+ snapBox.height += 40;
+
+ // adjust shape height to include bounding box
+ shape.width = Math.max(shape.width, snapBox.width);
+ shape.height = Math.max(shape.height, snapBox.height);
+
+ context.participantSnapBox = snapBox;
+}
+
+function snapParticipant(snapBox, shape, event, offset) {
+ offset = offset || 0;
+
+ var shapeHalfWidth = shape.width / 2 - offset,
+ shapeHalfHeight = shape.height / 2;
+
+ var currentTopLeft = {
+ x: event.x - shapeHalfWidth - offset,
+ y: event.y - shapeHalfHeight
+ };
+
+ var currentBottomRight = {
+ x: event.x + shapeHalfWidth + offset,
+ y: event.y + shapeHalfHeight
+ };
+
+ var snapTopLeft = snapBox,
+ snapBottomRight = (0, _SnapUtil.bottomRight)(snapBox);
+
+ if (currentTopLeft.x >= snapTopLeft.x) {
+ (0, _SnapUtil.setSnapped)(event, 'x', snapTopLeft.x + offset + shapeHalfWidth);
+ } else if (currentBottomRight.x <= snapBottomRight.x) {
+ (0, _SnapUtil.setSnapped)(event, 'x', snapBottomRight.x - offset - shapeHalfWidth);
+ }
+
+ if (currentTopLeft.y >= snapTopLeft.y) {
+ (0, _SnapUtil.setSnapped)(event, 'y', snapTopLeft.y + shapeHalfHeight);
+ } else if (currentBottomRight.y <= snapBottomRight.y) {
+ (0, _SnapUtil.setSnapped)(event, 'y', snapBottomRight.y - shapeHalfHeight);
+ }
+}
+
+// boundary event snapping //////////////////////
+
+function snapBoundaryEvent(event, shape, target) {
+ var targetTRBL = (0, _LayoutUtil.asTRBL)(target);
+
+ var direction = (0, _BpmnSnappingUtil.getBoundaryAttachment)(event, target);
+
+ if (/top/.test(direction)) {
+ (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.top);
+ } else if (/bottom/.test(direction)) {
+ (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.bottom);
+ }
+
+ if (/left/.test(direction)) {
+ (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.left);
+ } else if (/right/.test(direction)) {
+ (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.right);
+ }
+}
+
+function snapToPosition(event, position) {
+ (0, _SnapUtil.setSnapped)(event, 'x', position.x);
+ (0, _SnapUtil.setSnapped)(event, 'y', position.y);
+}
+
+},{"../../util/DiUtil":214,"../../util/ModelUtil":216,"../modeling/util/LaneUtil":188,"../modeling/util/ModelingUtil":189,"./BpmnSnappingUtil":207,"diagram-js/lib/features/snapping/SnapUtil":363,"diagram-js/lib/features/snapping/Snapping":364,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Elements":396,"inherits":415,"min-dash":505}],207:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.getBoundaryAttachment = getBoundaryAttachment;
+exports.getParticipantSizeConstraints = getParticipantSizeConstraints;
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _ModelUtil = require('../../util/ModelUtil');
+
+var _LaneUtil = require('../modeling/util/LaneUtil');
+
+function getBoundaryAttachment(position, targetBounds) {
+
+ var orientation = (0, _LayoutUtil.getOrientation)(position, targetBounds, -15);
+
+ if (orientation !== 'intersect') {
+ return orientation;
+ } else {
+ return null;
+ }
+}
+
+// participant snapping box implementation //////////////////////
+
+var abs = Math.abs,
+ min = Math.min,
+ max = Math.max;
+
+function addToTrbl(trbl, attr, value, choice) {
+
+ var current = trbl[attr];
+
+ // make sure to set the value if it does not exist
+ // or apply the correct value by comparing against
+ // choice(value, currentValue)
+ trbl[attr] = current === undefined ? value : choice(value, current);
+}
+
+function addMin(trbl, attr, value) {
+ return addToTrbl(trbl, attr, value, min);
+}
+
+function addMax(trbl, attr, value) {
+ return addToTrbl(trbl, attr, value, max);
+}
+
+var LANE_MIN_HEIGHT = 60,
+ LANE_MIN_WIDTH = 300,
+ LANE_RIGHT_PADDING = 20,
+ LANE_LEFT_PADDING = 50,
+ LANE_TOP_PADDING = 20,
+ LANE_BOTTOM_PADDING = 20;
+
+function getParticipantSizeConstraints(laneShape, resizeDirection, balanced) {
+
+ var lanesRoot = (0, _LaneUtil.getLanesRoot)(laneShape);
+
+ var isFirst = true,
+ isLast = true;
+
+ // max top/bottom size for lanes
+
+ var allLanes = (0, _LaneUtil.collectLanes)(lanesRoot, [lanesRoot]);
+
+ var laneTrbl = (0, _LayoutUtil.asTRBL)(laneShape);
+
+ var maxTrbl = {},
+ minTrbl = {};
+
+ if (/e/.test(resizeDirection)) {
+ minTrbl.right = laneTrbl.left + LANE_MIN_WIDTH;
+ } else if (/w/.test(resizeDirection)) {
+ minTrbl.left = laneTrbl.right - LANE_MIN_WIDTH;
+ }
+
+ allLanes.forEach(function (other) {
+
+ var otherTrbl = (0, _LayoutUtil.asTRBL)(other);
+
+ if (/n/.test(resizeDirection)) {
+
+ if (otherTrbl.top < laneTrbl.top - 10) {
+ isFirst = false;
+ }
+
+ // max top size (based on next element)
+ if (balanced && abs(laneTrbl.top - otherTrbl.bottom) < 10) {
+ addMax(maxTrbl, 'top', otherTrbl.top + LANE_MIN_HEIGHT);
+ }
+
+ // min top size (based on self or nested element)
+ if (abs(laneTrbl.top - otherTrbl.top) < 5) {
+ addMin(minTrbl, 'top', otherTrbl.bottom - LANE_MIN_HEIGHT);
+ }
+ }
+
+ if (/s/.test(resizeDirection)) {
+
+ if (otherTrbl.bottom > laneTrbl.bottom + 10) {
+ isLast = false;
+ }
+
+ // max bottom size (based on previous element)
+ if (balanced && abs(laneTrbl.bottom - otherTrbl.top) < 10) {
+ addMin(maxTrbl, 'bottom', otherTrbl.bottom - LANE_MIN_HEIGHT);
+ }
+
+ // min bottom size (based on self or nested element)
+ if (abs(laneTrbl.bottom - otherTrbl.bottom) < 5) {
+ addMax(minTrbl, 'bottom', otherTrbl.top + LANE_MIN_HEIGHT);
+ }
+ }
+ });
+
+ // max top/bottom/left/right size based on flow nodes
+
+ var flowElements = lanesRoot.children.filter(function (s) {
+ return !s.hidden && !s.waypoints && ((0, _ModelUtil.is)(s, 'bpmn:FlowElement') || (0, _ModelUtil.is)(s, 'bpmn:Artifact'));
+ });
+
+ flowElements.forEach(function (flowElement) {
+
+ var flowElementTrbl = (0, _LayoutUtil.asTRBL)(flowElement);
+
+ if (isFirst && /n/.test(resizeDirection)) {
+ addMin(minTrbl, 'top', flowElementTrbl.top - LANE_TOP_PADDING);
+ }
+
+ if (/e/.test(resizeDirection)) {
+ addMax(minTrbl, 'right', flowElementTrbl.right + LANE_RIGHT_PADDING);
+ }
+
+ if (isLast && /s/.test(resizeDirection)) {
+ addMax(minTrbl, 'bottom', flowElementTrbl.bottom + LANE_BOTTOM_PADDING);
+ }
+
+ if (/w/.test(resizeDirection)) {
+ addMin(minTrbl, 'left', flowElementTrbl.left - LANE_LEFT_PADDING);
+ }
+ });
+
+ return {
+ min: minTrbl,
+ max: maxTrbl
+ };
+}
+
+},{"../../util/ModelUtil":216,"../modeling/util/LaneUtil":188,"diagram-js/lib/layout/LayoutUtil":380}],208:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _BpmnSnapping = require('./BpmnSnapping');
+
+var _BpmnSnapping2 = _interopRequireDefault(_BpmnSnapping);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['snapping'],
+ snapping: ['type', _BpmnSnapping2.default]
+};
+
+},{"./BpmnSnapping":206}],209:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnImporter;
+
+var _minDash = require('min-dash');
+
+var _ModelUtil = require('../util/ModelUtil');
+
+var _LabelUtil = require('../util/LabelUtil');
+
+var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil');
+
+var _DiUtil = require('../util/DiUtil');
+
+var _Util = require('./Util');
+
+function elementData(semantic, attrs) {
+ return (0, _minDash.assign)({
+ id: semantic.id,
+ type: semantic.$type,
+ businessObject: semantic
+ }, attrs);
+}
+
+function collectWaypoints(waypoints) {
+ return (0, _minDash.map)(waypoints, function (p) {
+ return { x: p.x, y: p.y };
+ });
+}
+
+function notYetDrawn(translate, semantic, refSemantic, property) {
+ return new Error(translate('element {element} referenced by {referenced}#{property} not yet drawn', {
+ element: (0, _Util.elementToString)(refSemantic),
+ referenced: (0, _Util.elementToString)(semantic),
+ property: property
+ }));
+}
+
+/**
+ * An importer that adds bpmn elements to the canvas
+ *
+ * @param {EventBus} eventBus
+ * @param {Canvas} canvas
+ * @param {ElementFactory} elementFactory
+ * @param {ElementRegistry} elementRegistry
+ * @param {Function} translate
+ * @param {TextRenderer} textRenderer
+ */
+function BpmnImporter(eventBus, canvas, elementFactory, elementRegistry, translate, textRenderer) {
+
+ this._eventBus = eventBus;
+ this._canvas = canvas;
+ this._elementFactory = elementFactory;
+ this._elementRegistry = elementRegistry;
+ this._translate = translate;
+ this._textRenderer = textRenderer;
+}
+
+BpmnImporter.$inject = ['eventBus', 'canvas', 'elementFactory', 'elementRegistry', 'translate', 'textRenderer'];
+
+/**
+ * Add bpmn element (semantic) to the canvas onto the
+ * specified parent shape.
+ */
+BpmnImporter.prototype.add = function (semantic, parentElement) {
+
+ var di = semantic.di,
+ element,
+ translate = this._translate,
+ hidden;
+
+ var parentIndex;
+
+ // ROOT ELEMENT
+ // handle the special case that we deal with a
+ // invisible root element (process or collaboration)
+ if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNPlane')) {
+
+ // add a virtual element (not being drawn)
+ element = this._elementFactory.createRoot(elementData(semantic));
+
+ this._canvas.setRootElement(element);
+ }
+
+ // SHAPE
+ else if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNShape')) {
+
+ var collapsed = !(0, _DiUtil.isExpanded)(semantic);
+ hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
+
+ var bounds = semantic.di.bounds;
+
+ element = this._elementFactory.createShape(elementData(semantic, {
+ collapsed: collapsed,
+ hidden: hidden,
+ x: Math.round(bounds.x),
+ y: Math.round(bounds.y),
+ width: Math.round(bounds.width),
+ height: Math.round(bounds.height)
+ }));
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:BoundaryEvent')) {
+ this._attachBoundary(semantic, element);
+ }
+
+ // insert lanes behind other flow nodes (cf. #727)
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:Lane')) {
+ parentIndex = 0;
+ }
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference')) {
+
+ // check wether data store is inside our outside of its semantic parent
+ if (!isPointInsideBBox(parentElement, (0, _LayoutUtil.getMid)(bounds))) {
+ parentElement = this._canvas.getRootElement();
+ }
+ }
+
+ this._canvas.addShape(element, parentElement, parentIndex);
+ }
+
+ // CONNECTION
+ else if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNEdge')) {
+
+ var source = this._getSource(semantic),
+ target = this._getTarget(semantic);
+
+ hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
+
+ element = this._elementFactory.createConnection(elementData(semantic, {
+ hidden: hidden,
+ source: source,
+ target: target,
+ waypoints: collectWaypoints(semantic.di.waypoint)
+ }));
+
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:DataAssociation')) {
+
+ // render always on top; this ensures DataAssociations
+ // are rendered correctly across different "hacks" people
+ // love to model such as cross participant / sub process
+ // associations
+ parentElement = null;
+ }
+
+ // insert sequence flows behind other flow nodes (cf. #727)
+ if ((0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow')) {
+ parentIndex = 0;
+ }
+
+ this._canvas.addConnection(element, parentElement, parentIndex);
+ } else {
+ throw new Error(translate('unknown di {di} for element {semantic}', {
+ di: (0, _Util.elementToString)(di),
+ semantic: (0, _Util.elementToString)(semantic)
+ }));
+ }
+ // (optional) LABEL
+ if ((0, _LabelUtil.isLabelExternal)(semantic) && semantic.name) {
+ this.addLabel(semantic, element);
+ }
+
+ this._eventBus.fire('bpmnElement.added', { element: element });
+
+ return element;
+};
+
+/**
+ * Attach the boundary element to the given host
+ *
+ * @param {ModdleElement} boundarySemantic
+ * @param {djs.model.Base} boundaryElement
+ */
+BpmnImporter.prototype._attachBoundary = function (boundarySemantic, boundaryElement) {
+ var translate = this._translate;
+ var hostSemantic = boundarySemantic.attachedToRef;
+
+ if (!hostSemantic) {
+ throw new Error(translate('missing {semantic}#attachedToRef', {
+ semantic: (0, _Util.elementToString)(boundarySemantic)
+ }));
+ }
+
+ var host = this._elementRegistry.get(hostSemantic.id),
+ attachers = host && host.attachers;
+
+ if (!host) {
+ throw notYetDrawn(translate, boundarySemantic, hostSemantic, 'attachedToRef');
+ }
+
+ // wire element.host <> host.attachers
+ boundaryElement.host = host;
+
+ if (!attachers) {
+ host.attachers = attachers = [];
+ }
+
+ if (attachers.indexOf(boundaryElement) === -1) {
+ attachers.push(boundaryElement);
+ }
+};
+
+/**
+ * add label for an element
+ */
+BpmnImporter.prototype.addLabel = function (semantic, element) {
+ var bounds, text, label;
+
+ bounds = (0, _LabelUtil.getExternalLabelBounds)(semantic, element);
+
+ text = semantic.name;
+
+ if (text) {
+ // get corrected bounds from actual layouted text
+ bounds = this._textRenderer.getExternalLabelBounds(bounds, text);
+ }
+
+ label = this._elementFactory.createLabel(elementData(semantic, {
+ id: semantic.id + '_label',
+ labelTarget: element,
+ type: 'label',
+ hidden: element.hidden || !semantic.name,
+ x: Math.round(bounds.x),
+ y: Math.round(bounds.y),
+ width: Math.round(bounds.width),
+ height: Math.round(bounds.height)
+ }));
+
+ return this._canvas.addShape(label, element.parent);
+};
+
+/**
+ * Return the drawn connection end based on the given side.
+ *
+ * @throws {Error} if the end is not yet drawn
+ */
+BpmnImporter.prototype._getEnd = function (semantic, side) {
+
+ var element,
+ refSemantic,
+ type = semantic.$type,
+ translate = this._translate;
+
+ refSemantic = semantic[side + 'Ref'];
+
+ // handle mysterious isMany DataAssociation#sourceRef
+ if (side === 'source' && type === 'bpmn:DataInputAssociation') {
+ refSemantic = refSemantic && refSemantic[0];
+ }
+
+ // fix source / target for DataInputAssociation / DataOutputAssociation
+ if (side === 'source' && type === 'bpmn:DataOutputAssociation' || side === 'target' && type === 'bpmn:DataInputAssociation') {
+
+ refSemantic = semantic.$parent;
+ }
+
+ element = refSemantic && this._getElement(refSemantic);
+
+ if (element) {
+ return element;
+ }
+
+ if (refSemantic) {
+ throw notYetDrawn(translate, semantic, refSemantic, side + 'Ref');
+ } else {
+ throw new Error(translate('{semantic}#{side} Ref not specified', {
+ semantic: (0, _Util.elementToString)(semantic),
+ side: side
+ }));
+ }
+};
+
+BpmnImporter.prototype._getSource = function (semantic) {
+ return this._getEnd(semantic, 'source');
+};
+
+BpmnImporter.prototype._getTarget = function (semantic) {
+ return this._getEnd(semantic, 'target');
+};
+
+BpmnImporter.prototype._getElement = function (semantic) {
+ return this._elementRegistry.get(semantic.id);
+};
+
+// helpers ////////////////////
+
+function isPointInsideBBox(bbox, point) {
+ var x = point.x,
+ y = point.y;
+
+ return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height;
+}
+
+},{"../util/DiUtil":214,"../util/LabelUtil":215,"../util/ModelUtil":216,"./Util":212,"diagram-js/lib/layout/LayoutUtil":380,"min-dash":505}],210:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnTreeWalker;
+
+var _minDash = require('min-dash');
+
+var _objectRefs = require('object-refs');
+
+var _objectRefs2 = _interopRequireDefault(_objectRefs);
+
+var _Util = require('./Util');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var diRefs = new _objectRefs2.default({ name: 'bpmnElement', enumerable: true }, { name: 'di', configurable: true });
+
+/**
+ * Returns true if an element has the given meta-model type
+ *
+ * @param {ModdleElement} element
+ * @param {String} type
+ *
+ * @return {Boolean}
+ */
+function is(element, type) {
+ return element.$instanceOf(type);
+}
+
+/**
+ * Find a suitable display candidate for definitions where the DI does not
+ * correctly specify one.
+ */
+function findDisplayCandidate(definitions) {
+ return (0, _minDash.find)(definitions.rootElements, function (e) {
+ return is(e, 'bpmn:Process') || is(e, 'bpmn:Collaboration');
+ });
+}
+
+function BpmnTreeWalker(handler, translate) {
+
+ // list of containers already walked
+ var handledElements = {};
+
+ // list of elements to handle deferred to ensure
+ // prerequisites are drawn
+ var deferred = [];
+
+ // Helpers //////////////////////
+
+ function contextual(fn, ctx) {
+ return function (e) {
+ fn(e, ctx);
+ };
+ }
+
+ function handled(element) {
+ handledElements[element.id] = element;
+ }
+
+ function isHandled(element) {
+ return handledElements[element.id];
+ }
+
+ function visit(element, ctx) {
+
+ var gfx = element.gfx;
+
+ // avoid multiple rendering of elements
+ if (gfx) {
+ throw new Error(translate('already rendered {element}', { element: (0, _Util.elementToString)(element) }));
+ }
+
+ // call handler
+ return handler.element(element, ctx);
+ }
+
+ function visitRoot(element, diagram) {
+ return handler.root(element, diagram);
+ }
+
+ function visitIfDi(element, ctx) {
+
+ try {
+ var gfx = element.di && visit(element, ctx);
+
+ handled(element);
+
+ return gfx;
+ } catch (e) {
+ logError(e.message, { element: element, error: e });
+
+ console.error(translate('failed to import {element}', { element: (0, _Util.elementToString)(element) }));
+ console.error(e);
+ }
+ }
+
+ function logError(message, context) {
+ handler.error(message, context);
+ }
+
+ // DI handling //////////////////////
+
+ function registerDi(di) {
+ var bpmnElement = di.bpmnElement;
+
+ if (bpmnElement) {
+ if (bpmnElement.di) {
+ logError(translate('multiple DI elements defined for {element}', {
+ element: (0, _Util.elementToString)(bpmnElement)
+ }), { element: bpmnElement });
+ } else {
+ diRefs.bind(bpmnElement, 'di');
+ bpmnElement.di = di;
+ }
+ } else {
+ logError(translate('no bpmnElement referenced in {element}', {
+ element: (0, _Util.elementToString)(di)
+ }), { element: di });
+ }
+ }
+
+ function handleDiagram(diagram) {
+ handlePlane(diagram.plane);
+ }
+
+ function handlePlane(plane) {
+ registerDi(plane);
+
+ (0, _minDash.forEach)(plane.planeElement, handlePlaneElement);
+ }
+
+ function handlePlaneElement(planeElement) {
+ registerDi(planeElement);
+ }
+
+ // Semantic handling //////////////////////
+
+ /**
+ * Handle definitions and return the rendered diagram (if any)
+ *
+ * @param {ModdleElement} definitions to walk and import
+ * @param {ModdleElement} [diagram] specific diagram to import and display
+ *
+ * @throws {Error} if no diagram to display could be found
+ */
+ function handleDefinitions(definitions, diagram) {
+ // make sure we walk the correct bpmnElement
+
+ var diagrams = definitions.diagrams;
+
+ if (diagram && diagrams.indexOf(diagram) === -1) {
+ throw new Error(translate('diagram not part of bpmn:Definitions'));
+ }
+
+ if (!diagram && diagrams && diagrams.length) {
+ diagram = diagrams[0];
+ }
+
+ // no diagram -> nothing to import
+ if (!diagram) {
+ throw new Error(translate('no diagram to display'));
+ }
+
+ // load DI from selected diagram only
+ handleDiagram(diagram);
+
+ var plane = diagram.plane;
+
+ if (!plane) {
+ throw new Error(translate('no plane for {element}', { element: (0, _Util.elementToString)(diagram) }));
+ }
+
+ var rootElement = plane.bpmnElement;
+
+ // ensure we default to a suitable display candidate (process or collaboration),
+ // even if non is specified in DI
+ if (!rootElement) {
+ rootElement = findDisplayCandidate(definitions);
+
+ if (!rootElement) {
+ throw new Error(translate('no process or collaboration to display'));
+ } else {
+
+ logError(translate('correcting missing bpmnElement on {plane} to {rootElement}', {
+ plane: (0, _Util.elementToString)(plane),
+ rootElement: (0, _Util.elementToString)(rootElement)
+ }));
+
+ // correct DI on the fly
+ plane.bpmnElement = rootElement;
+ registerDi(plane);
+ }
+ }
+
+ var ctx = visitRoot(rootElement, plane);
+
+ if (is(rootElement, 'bpmn:Process')) {
+ handleProcess(rootElement, ctx);
+ } else if (is(rootElement, 'bpmn:Collaboration')) {
+ handleCollaboration(rootElement, ctx);
+
+ // force drawing of everything not yet drawn that is part of the target DI
+ handleUnhandledProcesses(definitions.rootElements, ctx);
+ } else {
+ throw new Error(translate('unsupported bpmnElement for {plane}: {rootElement}', {
+ plane: (0, _Util.elementToString)(plane),
+ rootElement: (0, _Util.elementToString)(rootElement)
+ }));
+ }
+
+ // handle all deferred elements
+ handleDeferred(deferred);
+ }
+
+ function handleDeferred() {
+
+ var fn;
+
+ // drain deferred until empty
+ while (deferred.length) {
+ fn = deferred.shift();
+
+ fn();
+ }
+ }
+
+ function handleProcess(process, context) {
+ handleFlowElementsContainer(process, context);
+ handleIoSpecification(process.ioSpecification, context);
+
+ handleArtifacts(process.artifacts, context);
+
+ // log process handled
+ handled(process);
+ }
+
+ function handleUnhandledProcesses(rootElements) {
+
+ // walk through all processes that have not yet been drawn and draw them
+ // if they contain lanes with DI information.
+ // we do this to pass the free-floating lane test cases in the MIWG test suite
+ var processes = (0, _minDash.filter)(rootElements, function (e) {
+ return !isHandled(e) && is(e, 'bpmn:Process') && e.laneSets;
+ });
+
+ processes.forEach(contextual(handleProcess));
+ }
+
+ function handleMessageFlow(messageFlow, context) {
+ visitIfDi(messageFlow, context);
+ }
+
+ function handleMessageFlows(messageFlows, context) {
+ (0, _minDash.forEach)(messageFlows, contextual(handleMessageFlow, context));
+ }
+
+ function handleDataAssociation(association, context) {
+ visitIfDi(association, context);
+ }
+
+ function handleDataInput(dataInput, context) {
+ visitIfDi(dataInput, context);
+ }
+
+ function handleDataOutput(dataOutput, context) {
+ visitIfDi(dataOutput, context);
+ }
+
+ function handleArtifact(artifact, context) {
+
+ // bpmn:TextAnnotation
+ // bpmn:Group
+ // bpmn:Association
+
+ visitIfDi(artifact, context);
+ }
+
+ function handleArtifacts(artifacts, context) {
+
+ (0, _minDash.forEach)(artifacts, function (e) {
+ if (is(e, 'bpmn:Association')) {
+ deferred.push(function () {
+ handleArtifact(e, context);
+ });
+ } else {
+ handleArtifact(e, context);
+ }
+ });
+ }
+
+ function handleIoSpecification(ioSpecification, context) {
+
+ if (!ioSpecification) {
+ return;
+ }
+
+ (0, _minDash.forEach)(ioSpecification.dataInputs, contextual(handleDataInput, context));
+ (0, _minDash.forEach)(ioSpecification.dataOutputs, contextual(handleDataOutput, context));
+ }
+
+ function handleSubProcess(subProcess, context) {
+ handleFlowElementsContainer(subProcess, context);
+ handleArtifacts(subProcess.artifacts, context);
+ }
+
+ function handleFlowNode(flowNode, context) {
+ var childCtx = visitIfDi(flowNode, context);
+
+ if (is(flowNode, 'bpmn:SubProcess')) {
+ handleSubProcess(flowNode, childCtx || context);
+ }
+
+ if (is(flowNode, 'bpmn:Activity')) {
+ handleIoSpecification(flowNode.ioSpecification, context);
+ }
+
+ // defer handling of associations
+ // affected types:
+ //
+ // * bpmn:Activity
+ // * bpmn:ThrowEvent
+ // * bpmn:CatchEvent
+ //
+ deferred.push(function () {
+ (0, _minDash.forEach)(flowNode.dataInputAssociations, contextual(handleDataAssociation, context));
+ (0, _minDash.forEach)(flowNode.dataOutputAssociations, contextual(handleDataAssociation, context));
+ });
+ }
+
+ function handleSequenceFlow(sequenceFlow, context) {
+ visitIfDi(sequenceFlow, context);
+ }
+
+ function handleDataElement(dataObject, context) {
+ visitIfDi(dataObject, context);
+ }
+
+ function handleBoundaryEvent(dataObject, context) {
+ visitIfDi(dataObject, context);
+ }
+
+ function handleLane(lane, context) {
+
+ deferred.push(function () {
+
+ var newContext = visitIfDi(lane, context);
+
+ if (lane.childLaneSet) {
+ handleLaneSet(lane.childLaneSet, newContext || context);
+ }
+
+ wireFlowNodeRefs(lane);
+ });
+ }
+
+ function handleLaneSet(laneSet, context) {
+ (0, _minDash.forEach)(laneSet.lanes, contextual(handleLane, context));
+ }
+
+ function handleLaneSets(laneSets, context) {
+ (0, _minDash.forEach)(laneSets, contextual(handleLaneSet, context));
+ }
+
+ function handleFlowElementsContainer(container, context) {
+ handleFlowElements(container.flowElements, context);
+
+ if (container.laneSets) {
+ handleLaneSets(container.laneSets, context);
+ }
+ }
+
+ function handleFlowElements(flowElements, context) {
+ (0, _minDash.forEach)(flowElements, function (e) {
+ if (is(e, 'bpmn:SequenceFlow')) {
+ deferred.push(function () {
+ handleSequenceFlow(e, context);
+ });
+ } else if (is(e, 'bpmn:BoundaryEvent')) {
+ deferred.unshift(function () {
+ handleBoundaryEvent(e, context);
+ });
+ } else if (is(e, 'bpmn:FlowNode')) {
+ handleFlowNode(e, context);
+ } else if (is(e, 'bpmn:DataObject')) {
+ // SKIP (assume correct referencing via DataObjectReference)
+ } else if (is(e, 'bpmn:DataStoreReference')) {
+ handleDataElement(e, context);
+ } else if (is(e, 'bpmn:DataObjectReference')) {
+ handleDataElement(e, context);
+ } else {
+ logError(translate('unrecognized flowElement {element} in context {context}', {
+ element: (0, _Util.elementToString)(e),
+ context: context ? (0, _Util.elementToString)(context.businessObject) : 'null'
+ }), { element: e, context: context });
+ }
+ });
+ }
+
+ function handleParticipant(participant, context) {
+ var newCtx = visitIfDi(participant, context);
+
+ var process = participant.processRef;
+ if (process) {
+ handleProcess(process, newCtx || context);
+ }
+ }
+
+ function handleCollaboration(collaboration) {
+
+ (0, _minDash.forEach)(collaboration.participants, contextual(handleParticipant));
+
+ handleArtifacts(collaboration.artifacts);
+
+ // handle message flows latest in the process
+ deferred.push(function () {
+ handleMessageFlows(collaboration.messageFlows);
+ });
+ }
+
+ function wireFlowNodeRefs(lane) {
+ // wire the virtual flowNodeRefs <-> relationship
+ (0, _minDash.forEach)(lane.flowNodeRef, function (flowNode) {
+ var lanes = flowNode.get('lanes');
+
+ if (lanes) {
+ lanes.push(lane);
+ }
+ });
+ }
+
+ // API //////////////////////
+
+ return {
+ handleDeferred: handleDeferred,
+ handleDefinitions: handleDefinitions,
+ handleSubProcess: handleSubProcess,
+ registerDi: registerDi
+ };
+}
+
+},{"./Util":212,"min-dash":505,"object-refs":520}],211:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.importBpmnDiagram = importBpmnDiagram;
+
+var _BpmnTreeWalker = require('./BpmnTreeWalker');
+
+var _BpmnTreeWalker2 = _interopRequireDefault(_BpmnTreeWalker);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Import the definitions into a diagram.
+ *
+ * Errors and warnings are reported through the specified callback.
+ *
+ * @param {Diagram} diagram
+ * @param {ModdleElement} definitions
+ * @param {Function} done the callback, invoked with (err, [ warning ]) once the import is done
+ */
+function importBpmnDiagram(diagram, definitions, done) {
+
+ var importer, eventBus, translate;
+
+ var error,
+ warnings = [];
+
+ /**
+ * Walk the diagram semantically, importing (=drawing)
+ * all elements you encounter.
+ *
+ * @param {ModdleElement} definitions
+ */
+ function render(definitions) {
+
+ var visitor = {
+
+ root: function root(element) {
+ return importer.add(element);
+ },
+
+ element: function element(_element, parentShape) {
+ return importer.add(_element, parentShape);
+ },
+
+ error: function error(message, context) {
+ warnings.push({ message: message, context: context });
+ }
+ };
+
+ var walker = new _BpmnTreeWalker2.default(visitor, translate);
+
+ // traverse BPMN 2.0 document model,
+ // starting at definitions
+ walker.handleDefinitions(definitions);
+ }
+
+ try {
+ importer = diagram.get('bpmnImporter');
+ eventBus = diagram.get('eventBus');
+ translate = diagram.get('translate');
+
+ eventBus.fire('import.render.start', { definitions: definitions });
+
+ render(definitions);
+
+ eventBus.fire('import.render.complete', {
+ error: error,
+ warnings: warnings
+ });
+ } catch (e) {
+ error = e;
+ }
+
+ done(error, warnings);
+}
+
+},{"./BpmnTreeWalker":210}],212:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.elementToString = elementToString;
+function elementToString(e) {
+ if (!e) {
+ return '';
+ }
+
+ return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />';
+}
+
+},{}],213:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _translate = require('diagram-js/lib/i18n/translate');
+
+var _translate2 = _interopRequireDefault(_translate);
+
+var _BpmnImporter = require('./BpmnImporter');
+
+var _BpmnImporter2 = _interopRequireDefault(_BpmnImporter);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_translate2.default],
+ bpmnImporter: ['type', _BpmnImporter2.default]
+};
+
+},{"./BpmnImporter":209,"diagram-js/lib/i18n/translate":376}],214:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.isExpanded = isExpanded;
+exports.isInterrupting = isInterrupting;
+exports.isEventSubProcess = isEventSubProcess;
+exports.hasEventDefinition = hasEventDefinition;
+exports.hasErrorEventDefinition = hasErrorEventDefinition;
+exports.hasEscalationEventDefinition = hasEscalationEventDefinition;
+exports.hasCompensateEventDefinition = hasCompensateEventDefinition;
+
+var _ModelUtil = require('./ModelUtil');
+
+var _minDash = require('min-dash');
+
+function isExpanded(element) {
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:CallActivity')) {
+ return false;
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess')) {
+ return !!(0, _ModelUtil.getBusinessObject)(element).di.isExpanded;
+ }
+
+ if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) {
+ return !!(0, _ModelUtil.getBusinessObject)(element).processRef;
+ }
+
+ return true;
+}
+
+function isInterrupting(element) {
+ return element && (0, _ModelUtil.getBusinessObject)(element).isInterrupting !== false;
+}
+
+function isEventSubProcess(element) {
+ return element && !!(0, _ModelUtil.getBusinessObject)(element).triggeredByEvent;
+}
+
+function hasEventDefinition(element, eventType) {
+ var bo = (0, _ModelUtil.getBusinessObject)(element),
+ hasEventDefinition = false;
+
+ if (bo.eventDefinitions) {
+ (0, _minDash.forEach)(bo.eventDefinitions, function (event) {
+ if ((0, _ModelUtil.is)(event, eventType)) {
+ hasEventDefinition = true;
+ }
+ });
+ }
+
+ return hasEventDefinition;
+}
+
+function hasErrorEventDefinition(element) {
+ return hasEventDefinition(element, 'bpmn:ErrorEventDefinition');
+}
+
+function hasEscalationEventDefinition(element) {
+ return hasEventDefinition(element, 'bpmn:EscalationEventDefinition');
+}
+
+function hasCompensateEventDefinition(element) {
+ return hasEventDefinition(element, 'bpmn:CompensateEventDefinition');
+}
+
+},{"./ModelUtil":216,"min-dash":505}],215:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.FLOW_LABEL_INDENT = exports.DEFAULT_LABEL_SIZE = undefined;
+exports.isLabelExternal = isLabelExternal;
+exports.hasExternalLabel = hasExternalLabel;
+exports.getFlowLabelPosition = getFlowLabelPosition;
+exports.getWaypointsMid = getWaypointsMid;
+exports.getExternalLabelMid = getExternalLabelMid;
+exports.getExternalLabelBounds = getExternalLabelBounds;
+exports.isLabel = isLabel;
+
+var _minDash = require('min-dash');
+
+var _ModelUtil = require('./ModelUtil');
+
+var DEFAULT_LABEL_SIZE = exports.DEFAULT_LABEL_SIZE = {
+ width: 90,
+ height: 20
+};
+
+var FLOW_LABEL_INDENT = exports.FLOW_LABEL_INDENT = 15;
+
+/**
+ * Returns true if the given semantic has an external label
+ *
+ * @param {BpmnElement} semantic
+ * @return {Boolean} true if has label
+ */
+function isLabelExternal(semantic) {
+ return (0, _ModelUtil.is)(semantic, 'bpmn:Event') || (0, _ModelUtil.is)(semantic, 'bpmn:Gateway') || (0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference') || (0, _ModelUtil.is)(semantic, 'bpmn:DataObjectReference') || (0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:MessageFlow');
+}
+
+/**
+ * Returns true if the given element has an external label
+ *
+ * @param {djs.model.shape} element
+ * @return {Boolean} true if has label
+ */
+function hasExternalLabel(element) {
+ return isLabel(element.label);
+}
+
+/**
+ * Get the position for sequence flow labels
+ *
+ * @param {Array} waypoints
+ * @return {Point} the label position
+ */
+function getFlowLabelPosition(waypoints) {
+
+ // get the waypoints mid
+ var mid = waypoints.length / 2 - 1;
+
+ var first = waypoints[Math.floor(mid)];
+ var second = waypoints[Math.ceil(mid + 0.01)];
+
+ // get position
+ var position = getWaypointsMid(waypoints);
+
+ // calculate angle
+ var angle = Math.atan((second.y - first.y) / (second.x - first.x));
+
+ var x = position.x,
+ y = position.y;
+
+ if (Math.abs(angle) < Math.PI / 2) {
+ y -= FLOW_LABEL_INDENT;
+ } else {
+ x += FLOW_LABEL_INDENT;
+ }
+
+ return { x: x, y: y };
+}
+
+/**
+ * Get the middle of a number of waypoints
+ *
+ * @param {Array} waypoints
+ * @return {Point} the mid point
+ */
+function getWaypointsMid(waypoints) {
+
+ var mid = waypoints.length / 2 - 1;
+
+ var first = waypoints[Math.floor(mid)];
+ var second = waypoints[Math.ceil(mid + 0.01)];
+
+ return {
+ x: first.x + (second.x - first.x) / 2,
+ y: first.y + (second.y - first.y) / 2
+ };
+}
+
+function getExternalLabelMid(element) {
+
+ if (element.waypoints) {
+ return getFlowLabelPosition(element.waypoints);
+ } else {
+ return {
+ x: element.x + element.width / 2,
+ y: element.y + element.height + DEFAULT_LABEL_SIZE.height / 2
+ };
+ }
+}
+
+/**
+ * Returns the bounds of an elements label, parsed from the elements DI or
+ * generated from its bounds.
+ *
+ * @param {BpmnElement} semantic
+ * @param {djs.model.Base} element
+ */
+function getExternalLabelBounds(semantic, element) {
+
+ var mid,
+ size,
+ bounds,
+ di = semantic.di,
+ label = di.label;
+
+ if (label && label.bounds) {
+ bounds = label.bounds;
+
+ size = {
+ width: Math.max(DEFAULT_LABEL_SIZE.width, bounds.width),
+ height: bounds.height
+ };
+
+ mid = {
+ x: bounds.x + bounds.width / 2,
+ y: bounds.y + bounds.height / 2
+ };
+ } else {
+
+ mid = getExternalLabelMid(element);
+
+ size = DEFAULT_LABEL_SIZE;
+ }
+
+ return (0, _minDash.assign)({
+ x: mid.x - size.width / 2,
+ y: mid.y - size.height / 2
+ }, size);
+}
+
+function isLabel(element) {
+ return element && element.labelTarget;
+}
+
+},{"./ModelUtil":216,"min-dash":505}],216:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.is = is;
+exports.getBusinessObject = getBusinessObject;
+/**
+ * Is an element of the given BPMN type?
+ *
+ * @param {djs.model.Base|ModdleElement} element
+ * @param {String} type
+ *
+ * @return {Boolean}
+ */
+function is(element, type) {
+ var bo = getBusinessObject(element);
+
+ return bo && typeof bo.$instanceOf === 'function' && bo.$instanceOf(type);
+}
+
+/**
+ * Return the business object for a given element.
+ *
+ * @param {djs.model.Base|ModdleElement} element
+ *
+ * @return {ModdleElement}
+ */
+function getBusinessObject(element) {
+ return element && element.businessObject || element;
+}
+
+},{}],217:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.BPMNIO_IMG = undefined;
+exports.open = open;
+
+var _minDom = require('min-dom');
+
+// inlined ../../resources/logo.svg
+var BPMNIO_LOGO_SVG = ' '; /**
+ * This file must not be changed or exchanged.
+ *
+ * @see http://bpmn.io/license for more information.
+ */
+
+var BPMNIO_LOGO_URL = 'data:image/svg+xml,' + encodeURIComponent(BPMNIO_LOGO_SVG);
+
+var BPMNIO_IMG = exports.BPMNIO_IMG = ' ';
+
+function css(attrs) {
+ return attrs.join(';');
+}
+
+var LIGHTBOX_STYLES = css(['z-index: 1001', 'position: fixed', 'top: 0', 'left: 0', 'right: 0', 'bottom: 0']);
+
+var BACKDROP_STYLES = css(['width: 100%', 'height: 100%', 'background: rgba(0,0,0,0.2)']);
+
+var NOTICE_STYLES = css(['position: absolute', 'left: 50%', 'top: 40%', 'margin: 0 -130px', 'width: 260px', 'padding: 10px', 'background: white', 'border: solid 1px #AAA', 'border-radius: 3px', 'font-family: Helvetica, Arial, sans-serif', 'font-size: 14px', 'line-height: 1.2em']);
+
+var LIGHTBOX_MARKUP = '';
+
+var lightbox;
+
+function open() {
+
+ if (!lightbox) {
+ lightbox = (0, _minDom.domify)(LIGHTBOX_MARKUP);
+
+ _minDom.delegate.bind(lightbox, '.backdrop', 'click', function (event) {
+ document.body.removeChild(lightbox);
+ });
+ }
+
+ document.body.appendChild(lightbox);
+}
+
+},{"min-dom":506}],218:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+exports.default = ModelCloneHelper;
+
+var _minDash = require('min-dash');
+
+var _ModelCloneUtils = require('./ModelCloneUtils');
+
+function isAllowedIn(extProp, type) {
+ var allowedIn = extProp.meta.allowedIn;
+
+ // '*' is a wildcard, which means any element is allowed to use this property
+ if (allowedIn.length === 1 && allowedIn[0] === '*') {
+ return true;
+ }
+
+ return allowedIn.indexOf(type) !== -1;
+}
+
+function isType(element, types) {
+ return (0, _minDash.some)(types, function (type) {
+ return (typeof element === 'undefined' ? 'undefined' : _typeof(element)) === type;
+ });
+}
+
+/**
+ * A bpmn properties cloning interface
+ *
+ */
+function ModelCloneHelper(eventBus, bpmnFactory) {
+ this._eventBus = eventBus;
+ this._bpmnFactory = bpmnFactory;
+}
+
+ModelCloneHelper.prototype.clone = function (refElement, newElement, properties) {
+
+ var self = this;
+
+ // hasNestedProperty: property allows us to avoid ending up with empty (xml) tags
+ // f.ex: if extensionElements.values is empty, don't set it
+ var context = {
+ newElement: newElement,
+ hasNestedProperty: false
+ };
+
+ // we want the extensionElements to be cloned last
+ // so that they can check certain properties
+ properties = (0, _minDash.sortBy)(properties, function (prop) {
+ return prop === 'bpmn:extensionElements';
+ });
+
+ (0, _minDash.forEach)(properties, function (propName) {
+ var refElementProp = refElement.get(propName),
+ newElementProp = newElement.get(propName),
+ propDescriptor = newElement.$model.getPropertyDescriptor(newElement, propName),
+ newProperty,
+ name;
+
+ // we're not interested in cloning:
+ // - same values from simple types
+ // - cloning id's
+ // - cloning reference elements
+ if (newElementProp === refElementProp) {
+ return;
+ }
+
+ if (propDescriptor && (propDescriptor.isId || propDescriptor.isReference)) {
+ return;
+ }
+
+ // if the property is of type 'boolean', 'string', 'number' or 'null', just set it
+ if (isType(refElementProp, ['boolean', 'string', 'number']) || refElementProp === null) {
+ newElement.set(propName, refElementProp);
+
+ return;
+ }
+
+ if ((0, _minDash.isArray)(refElementProp)) {
+
+ (0, _minDash.forEach)(refElementProp, function (extElement) {
+ var newProp;
+
+ context.refTopLevelProperty = extElement;
+
+ newProp = self._deepClone(extElement, context);
+
+ if (context.hasNestedProperty) {
+ newProp.$parent = newElement;
+
+ newElementProp.push(newProp);
+ }
+
+ context.hasNestedProperty = false;
+ });
+ } else {
+ name = propName.replace(/bpmn:/, '');
+
+ context.refTopLevelProperty = refElementProp;
+
+ newProperty = self._deepClone(refElementProp, context);
+
+ if (context.hasNestedProperty) {
+ newProperty.$parent = newElement;
+
+ newElement.set(name, newProperty);
+ }
+
+ context.hasNestedProperty = false;
+ }
+ });
+
+ return newElement;
+};
+
+ModelCloneHelper.prototype._deepClone = function _deepClone(propertyElement, context) {
+ var self = this;
+
+ var eventBus = this._eventBus;
+ var bpmnFactory = this._bpmnFactory;
+
+ var newProp = bpmnFactory.create(propertyElement.$type);
+
+ var properties = (0, _minDash.filter)(Object.keys(propertyElement), function (prop) {
+ var descriptor = newProp.$model.getPropertyDescriptor(newProp, prop);
+
+ if (descriptor && (descriptor.isId || descriptor.isReference)) {
+ return false;
+ }
+
+ // we need to make sure we don't clone certain properties
+ // which we cannot easily know if they hold references or not
+ if (_ModelCloneUtils.IGNORED_PROPERTIES.indexOf(prop) !== -1) {
+ return false;
+ }
+
+ // make sure we don't copy the type
+ return prop !== '$type';
+ });
+
+ if (!properties.length) {
+ context.hasNestedProperty = true;
+ }
+
+ (0, _minDash.forEach)(properties, function (propName) {
+ // check if the propertyElement has this property defined
+ if (propertyElement[propName] !== undefined && (propertyElement[propName].$type || (0, _minDash.isArray)(propertyElement[propName]))) {
+
+ if ((0, _minDash.isArray)(propertyElement[propName])) {
+ newProp[propName] = [];
+
+ (0, _minDash.forEach)(propertyElement[propName], function (property) {
+ var extProp = propertyElement.$model.getTypeDescriptor(property.$type),
+ newDeepProp;
+
+ // we're not going to copy undefined types
+ if (!extProp) {
+ return;
+ }
+
+ var canClone = eventBus.fire('property.clone', {
+ newElement: context.newElement,
+ refTopLevelProperty: context.refTopLevelProperty,
+ propertyDescriptor: extProp
+ });
+
+ if (!canClone) {
+ // if can clone is 'undefined' or 'false'
+ // check for the meta information if it is allowed
+ if (propertyElement.$type === 'bpmn:ExtensionElements' && extProp.meta && extProp.meta.allowedIn && !isAllowedIn(extProp, context.newElement.$type)) {
+ return false;
+ }
+ }
+
+ newDeepProp = self._deepClone(property, context);
+
+ newDeepProp.$parent = newProp;
+
+ if (!newProp[propName]) {
+ newProp[propName] = [];
+ }
+
+ context.hasNestedProperty = true;
+
+ newProp[propName].push(newDeepProp);
+ });
+ } else if (propertyElement[propName].$type) {
+ newProp[propName] = self._deepClone(propertyElement[propName], context);
+
+ if (newProp[propName]) {
+ context.hasNestedProperty = true;
+
+ newProp[propName].$parent = newProp;
+ }
+ }
+ } else {
+ context.hasNestedProperty = true;
+
+ // just assign directly if it's a value
+ newProp[propName] = propertyElement[propName];
+ }
+ });
+
+ return newProp;
+};
+
+},{"./ModelCloneUtils":219,"min-dash":505}],219:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.IGNORED_PROPERTIES = undefined;
+exports.getProperties = getProperties;
+
+var _minDash = require('min-dash');
+
+/**
+ * These are the properties that should be ignored when cloning elements.
+ *
+ * @type {Array}
+ */
+var IGNORED_PROPERTIES = exports.IGNORED_PROPERTIES = ['lanes', 'incoming', 'outgoing', 'artifacts', 'default', 'flowElements', 'dataInputAssociations', 'dataOutputAssociations'];
+
+function getProperties(descriptor, keepDefault) {
+ var properties = [];
+
+ (0, _minDash.forEach)(descriptor.properties, function (property) {
+
+ if (keepDefault && property.default) {
+ return;
+ }
+
+ properties.push(property.ns.name);
+ });
+
+ return properties;
+}
+
+},{"min-dash":505}],220:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _simple = require('./lib/simple');
+
+Object.defineProperty(exports, 'default', {
+ enumerable: true,
+ get: function get() {
+ return _interopRequireDefault(_simple).default;
+ }
+});
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+},{"./lib/simple":222}],221:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BpmnModdle;
+
+var _minDash = require('min-dash');
+
+var _moddle = require('moddle');
+
+var _moddle2 = _interopRequireDefault(_moddle);
+
+var _moddleXml = require('moddle-xml');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A sub class of {@link Moddle} with support for import and export of BPMN 2.0 xml files.
+ *
+ * @class BpmnModdle
+ * @extends Moddle
+ *
+ * @param {Object|Array} packages to use for instantiating the model
+ * @param {Object} [options] additional options to pass over
+ */
+function BpmnModdle(packages, options) {
+ _moddle2.default.call(this, packages, options);
+}
+
+BpmnModdle.prototype = Object.create(_moddle2.default.prototype);
+
+/**
+ * Instantiates a BPMN model tree from a given xml string.
+ *
+ * @param {String} xmlStr
+ * @param {String} [typeName='bpmn:Definitions'] name of the root element
+ * @param {Object} [options] options to pass to the underlying reader
+ * @param {Function} done callback that is invoked with (err, result, parseContext)
+ * once the import completes
+ */
+BpmnModdle.prototype.fromXML = function (xmlStr, typeName, options, done) {
+
+ if (!(0, _minDash.isString)(typeName)) {
+ done = options;
+ options = typeName;
+ typeName = 'bpmn:Definitions';
+ }
+
+ if ((0, _minDash.isFunction)(options)) {
+ done = options;
+ options = {};
+ }
+
+ var reader = new _moddleXml.Reader((0, _minDash.assign)({ model: this, lax: true }, options));
+ var rootHandler = reader.handler(typeName);
+
+ reader.fromXML(xmlStr, rootHandler, done);
+};
+
+/**
+ * Serializes a BPMN 2.0 object tree to XML.
+ *
+ * @param {String} element the root element, typically an instance of `bpmn:Definitions`
+ * @param {Object} [options] to pass to the underlying writer
+ * @param {Function} done callback invoked with (err, xmlStr) once the import completes
+ */
+BpmnModdle.prototype.toXML = function (element, options, done) {
+
+ if ((0, _minDash.isFunction)(options)) {
+ done = options;
+ options = {};
+ }
+
+ var writer = new _moddleXml.Writer(options);
+
+ var result;
+ var err;
+
+ try {
+ result = writer.toXML(element);
+ } catch (e) {
+ err = e;
+ }
+
+ return done(err, result);
+};
+
+},{"min-dash":505,"moddle":511,"moddle-xml":507}],222:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+exports.default = function (additionalPackages, options) {
+ var pks = (0, _minDash.assign)({}, packages, additionalPackages);
+
+ return new _bpmnModdle2.default(pks, options);
+};
+
+var _minDash = require('min-dash');
+
+var _bpmnModdle = require('./bpmn-moddle');
+
+var _bpmnModdle2 = _interopRequireDefault(_bpmnModdle);
+
+var _bpmn = require('../resources/bpmn/json/bpmn.json');
+
+var _bpmn2 = _interopRequireDefault(_bpmn);
+
+var _bpmndi = require('../resources/bpmn/json/bpmndi.json');
+
+var _bpmndi2 = _interopRequireDefault(_bpmndi);
+
+var _dc = require('../resources/bpmn/json/dc.json');
+
+var _dc2 = _interopRequireDefault(_dc);
+
+var _di = require('../resources/bpmn/json/di.json');
+
+var _di2 = _interopRequireDefault(_di);
+
+var _bioc = require('../resources/bpmn-io/json/bioc.json');
+
+var _bioc2 = _interopRequireDefault(_bioc);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var packages = {
+ bpmn: _bpmn2.default,
+ bpmndi: _bpmndi2.default,
+ dc: _dc2.default,
+ di: _di2.default,
+ bioc: _bioc2.default
+};
+
+},{"../resources/bpmn-io/json/bioc.json":223,"../resources/bpmn/json/bpmn.json":224,"../resources/bpmn/json/bpmndi.json":225,"../resources/bpmn/json/dc.json":226,"../resources/bpmn/json/di.json":227,"./bpmn-moddle":221,"min-dash":505}],223:[function(require,module,exports){
+module.exports={
+ "name": "bpmn.io colors for BPMN",
+ "uri": "http://bpmn.io/schema/bpmn/biocolor/1.0",
+ "prefix": "bioc",
+ "types": [
+ {
+ "name": "ColoredShape",
+ "extends": [ "bpmndi:BPMNShape" ],
+ "properties": [
+ {
+ "name": "stroke",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "fill",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ColoredEdge",
+ "extends": [ "bpmndi:BPMNEdge" ],
+ "properties": [
+ {
+ "name": "stroke",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "fill",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ }
+ ],
+ "enumerations": [],
+ "associations": []
+}
+
+},{}],224:[function(require,module,exports){
+module.exports={
+ "name": "BPMN20",
+ "uri": "http://www.omg.org/spec/BPMN/20100524/MODEL",
+ "associations": [],
+ "types": [
+ {
+ "name": "Interface",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "operations",
+ "type": "Operation",
+ "isMany": true
+ },
+ {
+ "name": "implementationRef",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "Operation",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "inMessageRef",
+ "type": "Message",
+ "isReference": true
+ },
+ {
+ "name": "outMessageRef",
+ "type": "Message",
+ "isReference": true
+ },
+ {
+ "name": "errorRef",
+ "type": "Error",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "implementationRef",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "EndPoint",
+ "superClass": [
+ "RootElement"
+ ]
+ },
+ {
+ "name": "Auditing",
+ "superClass": [
+ "BaseElement"
+ ]
+ },
+ {
+ "name": "GlobalTask",
+ "superClass": [
+ "CallableElement"
+ ],
+ "properties": [
+ {
+ "name": "resources",
+ "type": "ResourceRole",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Monitoring",
+ "superClass": [
+ "BaseElement"
+ ]
+ },
+ {
+ "name": "Performer",
+ "superClass": [
+ "ResourceRole"
+ ]
+ },
+ {
+ "name": "Process",
+ "superClass": [
+ "FlowElementsContainer",
+ "CallableElement"
+ ],
+ "properties": [
+ {
+ "name": "processType",
+ "type": "ProcessType",
+ "isAttr": true
+ },
+ {
+ "name": "isClosed",
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "auditing",
+ "type": "Auditing"
+ },
+ {
+ "name": "monitoring",
+ "type": "Monitoring"
+ },
+ {
+ "name": "properties",
+ "type": "Property",
+ "isMany": true
+ },
+ {
+ "name": "laneSets",
+ "type": "LaneSet",
+ "isMany": true,
+ "replaces": "FlowElementsContainer#laneSets"
+ },
+ {
+ "name": "flowElements",
+ "type": "FlowElement",
+ "isMany": true,
+ "replaces": "FlowElementsContainer#flowElements"
+ },
+ {
+ "name": "artifacts",
+ "type": "Artifact",
+ "isMany": true
+ },
+ {
+ "name": "resources",
+ "type": "ResourceRole",
+ "isMany": true
+ },
+ {
+ "name": "correlationSubscriptions",
+ "type": "CorrelationSubscription",
+ "isMany": true
+ },
+ {
+ "name": "supports",
+ "type": "Process",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "definitionalCollaborationRef",
+ "type": "Collaboration",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "isExecutable",
+ "isAttr": true,
+ "type": "Boolean"
+ }
+ ]
+ },
+ {
+ "name": "LaneSet",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "lanes",
+ "type": "Lane",
+ "isMany": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Lane",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "partitionElementRef",
+ "type": "BaseElement",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "partitionElement",
+ "type": "BaseElement"
+ },
+ {
+ "name": "flowNodeRef",
+ "type": "FlowNode",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "childLaneSet",
+ "type": "LaneSet",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ }
+ ]
+ },
+ {
+ "name": "GlobalManualTask",
+ "superClass": [
+ "GlobalTask"
+ ]
+ },
+ {
+ "name": "ManualTask",
+ "superClass": [
+ "Task"
+ ]
+ },
+ {
+ "name": "UserTask",
+ "superClass": [
+ "Task"
+ ],
+ "properties": [
+ {
+ "name": "renderings",
+ "type": "Rendering",
+ "isMany": true
+ },
+ {
+ "name": "implementation",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Rendering",
+ "superClass": [
+ "BaseElement"
+ ]
+ },
+ {
+ "name": "HumanPerformer",
+ "superClass": [
+ "Performer"
+ ]
+ },
+ {
+ "name": "PotentialOwner",
+ "superClass": [
+ "HumanPerformer"
+ ]
+ },
+ {
+ "name": "GlobalUserTask",
+ "superClass": [
+ "GlobalTask"
+ ],
+ "properties": [
+ {
+ "name": "implementation",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "renderings",
+ "type": "Rendering",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Gateway",
+ "isAbstract": true,
+ "superClass": [
+ "FlowNode"
+ ],
+ "properties": [
+ {
+ "name": "gatewayDirection",
+ "type": "GatewayDirection",
+ "default": "Unspecified",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "EventBasedGateway",
+ "superClass": [
+ "Gateway"
+ ],
+ "properties": [
+ {
+ "name": "instantiate",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "eventGatewayType",
+ "type": "EventBasedGatewayType",
+ "isAttr": true,
+ "default": "Exclusive"
+ }
+ ]
+ },
+ {
+ "name": "ComplexGateway",
+ "superClass": [
+ "Gateway"
+ ],
+ "properties": [
+ {
+ "name": "activationCondition",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "default",
+ "type": "SequenceFlow",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ExclusiveGateway",
+ "superClass": [
+ "Gateway"
+ ],
+ "properties": [
+ {
+ "name": "default",
+ "type": "SequenceFlow",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "InclusiveGateway",
+ "superClass": [
+ "Gateway"
+ ],
+ "properties": [
+ {
+ "name": "default",
+ "type": "SequenceFlow",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ParallelGateway",
+ "superClass": [
+ "Gateway"
+ ]
+ },
+ {
+ "name": "RootElement",
+ "isAbstract": true,
+ "superClass": [
+ "BaseElement"
+ ]
+ },
+ {
+ "name": "Relationship",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "type",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "direction",
+ "type": "RelationshipDirection",
+ "isAttr": true
+ },
+ {
+ "name": "source",
+ "isMany": true,
+ "isReference": true,
+ "type": "Element"
+ },
+ {
+ "name": "target",
+ "isMany": true,
+ "isReference": true,
+ "type": "Element"
+ }
+ ]
+ },
+ {
+ "name": "BaseElement",
+ "isAbstract": true,
+ "properties": [
+ {
+ "name": "id",
+ "isAttr": true,
+ "type": "String",
+ "isId": true
+ },
+ {
+ "name": "documentation",
+ "type": "Documentation",
+ "isMany": true
+ },
+ {
+ "name": "extensionDefinitions",
+ "type": "ExtensionDefinition",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "extensionElements",
+ "type": "ExtensionElements"
+ }
+ ]
+ },
+ {
+ "name": "Extension",
+ "properties": [
+ {
+ "name": "mustUnderstand",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "definition",
+ "type": "ExtensionDefinition",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ExtensionDefinition",
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "extensionAttributeDefinitions",
+ "type": "ExtensionAttributeDefinition",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "ExtensionAttributeDefinition",
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "type",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "isReference",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "extensionDefinition",
+ "type": "ExtensionDefinition",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ExtensionElements",
+ "properties": [
+ {
+ "name": "valueRef",
+ "isAttr": true,
+ "isReference": true,
+ "type": "Element"
+ },
+ {
+ "name": "values",
+ "type": "Element",
+ "isMany": true
+ },
+ {
+ "name": "extensionAttributeDefinition",
+ "type": "ExtensionAttributeDefinition",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Documentation",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "text",
+ "type": "String",
+ "isBody": true
+ },
+ {
+ "name": "textFormat",
+ "default": "text/plain",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Event",
+ "isAbstract": true,
+ "superClass": [
+ "FlowNode",
+ "InteractionNode"
+ ],
+ "properties": [
+ {
+ "name": "properties",
+ "type": "Property",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "IntermediateCatchEvent",
+ "superClass": [
+ "CatchEvent"
+ ]
+ },
+ {
+ "name": "IntermediateThrowEvent",
+ "superClass": [
+ "ThrowEvent"
+ ]
+ },
+ {
+ "name": "EndEvent",
+ "superClass": [
+ "ThrowEvent"
+ ]
+ },
+ {
+ "name": "StartEvent",
+ "superClass": [
+ "CatchEvent"
+ ],
+ "properties": [
+ {
+ "name": "isInterrupting",
+ "default": true,
+ "isAttr": true,
+ "type": "Boolean"
+ }
+ ]
+ },
+ {
+ "name": "ThrowEvent",
+ "isAbstract": true,
+ "superClass": [
+ "Event"
+ ],
+ "properties": [
+ {
+ "name": "dataInputs",
+ "type": "DataInput",
+ "isMany": true
+ },
+ {
+ "name": "dataInputAssociations",
+ "type": "DataInputAssociation",
+ "isMany": true
+ },
+ {
+ "name": "inputSet",
+ "type": "InputSet"
+ },
+ {
+ "name": "eventDefinitions",
+ "type": "EventDefinition",
+ "isMany": true
+ },
+ {
+ "name": "eventDefinitionRef",
+ "type": "EventDefinition",
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "CatchEvent",
+ "isAbstract": true,
+ "superClass": [
+ "Event"
+ ],
+ "properties": [
+ {
+ "name": "parallelMultiple",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ },
+ {
+ "name": "dataOutputs",
+ "type": "DataOutput",
+ "isMany": true
+ },
+ {
+ "name": "dataOutputAssociations",
+ "type": "DataOutputAssociation",
+ "isMany": true
+ },
+ {
+ "name": "outputSet",
+ "type": "OutputSet"
+ },
+ {
+ "name": "eventDefinitions",
+ "type": "EventDefinition",
+ "isMany": true
+ },
+ {
+ "name": "eventDefinitionRef",
+ "type": "EventDefinition",
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "BoundaryEvent",
+ "superClass": [
+ "CatchEvent"
+ ],
+ "properties": [
+ {
+ "name": "cancelActivity",
+ "default": true,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "attachedToRef",
+ "type": "Activity",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "EventDefinition",
+ "isAbstract": true,
+ "superClass": [
+ "RootElement"
+ ]
+ },
+ {
+ "name": "CancelEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ]
+ },
+ {
+ "name": "ErrorEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "errorRef",
+ "type": "Error",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "TerminateEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ]
+ },
+ {
+ "name": "EscalationEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "escalationRef",
+ "type": "Escalation",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Escalation",
+ "properties": [
+ {
+ "name": "structureRef",
+ "type": "ItemDefinition",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "escalationCode",
+ "isAttr": true,
+ "type": "String"
+ }
+ ],
+ "superClass": [
+ "RootElement"
+ ]
+ },
+ {
+ "name": "CompensateEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "waitForCompletion",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": true
+ },
+ {
+ "name": "activityRef",
+ "type": "Activity",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "TimerEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "timeDate",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "timeCycle",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "timeDuration",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ }
+ ]
+ },
+ {
+ "name": "LinkEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "target",
+ "type": "LinkEventDefinition",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "source",
+ "type": "LinkEventDefinition",
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "MessageEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "messageRef",
+ "type": "Message",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "operationRef",
+ "type": "Operation",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ConditionalEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "condition",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ }
+ ]
+ },
+ {
+ "name": "SignalEventDefinition",
+ "superClass": [
+ "EventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "signalRef",
+ "type": "Signal",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Signal",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "structureRef",
+ "type": "ItemDefinition",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ImplicitThrowEvent",
+ "superClass": [
+ "ThrowEvent"
+ ]
+ },
+ {
+ "name": "DataState",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ItemAwareElement",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "itemSubjectRef",
+ "type": "ItemDefinition",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "dataState",
+ "type": "DataState"
+ }
+ ]
+ },
+ {
+ "name": "DataAssociation",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "assignment",
+ "type": "Assignment",
+ "isMany": true
+ },
+ {
+ "name": "sourceRef",
+ "type": "ItemAwareElement",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "targetRef",
+ "type": "ItemAwareElement",
+ "isReference": true
+ },
+ {
+ "name": "transformation",
+ "type": "FormalExpression",
+ "xml": {
+ "serialize": "property"
+ }
+ }
+ ]
+ },
+ {
+ "name": "DataInput",
+ "superClass": [
+ "ItemAwareElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "isCollection",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "inputSetRef",
+ "type": "InputSet",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "inputSetWithOptional",
+ "type": "InputSet",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "inputSetWithWhileExecuting",
+ "type": "InputSet",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "DataOutput",
+ "superClass": [
+ "ItemAwareElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "isCollection",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "outputSetRef",
+ "type": "OutputSet",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "outputSetWithOptional",
+ "type": "OutputSet",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "outputSetWithWhileExecuting",
+ "type": "OutputSet",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "InputSet",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "dataInputRefs",
+ "type": "DataInput",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "optionalInputRefs",
+ "type": "DataInput",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "whileExecutingInputRefs",
+ "type": "DataInput",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "outputSetRefs",
+ "type": "OutputSet",
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "OutputSet",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "dataOutputRefs",
+ "type": "DataOutput",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "inputSetRefs",
+ "type": "InputSet",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "optionalOutputRefs",
+ "type": "DataOutput",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "whileExecutingOutputRefs",
+ "type": "DataOutput",
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Property",
+ "superClass": [
+ "ItemAwareElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "DataInputAssociation",
+ "superClass": [
+ "DataAssociation"
+ ]
+ },
+ {
+ "name": "DataOutputAssociation",
+ "superClass": [
+ "DataAssociation"
+ ]
+ },
+ {
+ "name": "InputOutputSpecification",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "dataInputs",
+ "type": "DataInput",
+ "isMany": true
+ },
+ {
+ "name": "dataOutputs",
+ "type": "DataOutput",
+ "isMany": true
+ },
+ {
+ "name": "inputSets",
+ "type": "InputSet",
+ "isMany": true
+ },
+ {
+ "name": "outputSets",
+ "type": "OutputSet",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "DataObject",
+ "superClass": [
+ "FlowElement",
+ "ItemAwareElement"
+ ],
+ "properties": [
+ {
+ "name": "isCollection",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ }
+ ]
+ },
+ {
+ "name": "InputOutputBinding",
+ "properties": [
+ {
+ "name": "inputDataRef",
+ "type": "InputSet",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "outputDataRef",
+ "type": "OutputSet",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "operationRef",
+ "type": "Operation",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Assignment",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "from",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "to",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ }
+ ]
+ },
+ {
+ "name": "DataStore",
+ "superClass": [
+ "RootElement",
+ "ItemAwareElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "capacity",
+ "isAttr": true,
+ "type": "Integer"
+ },
+ {
+ "name": "isUnlimited",
+ "default": true,
+ "isAttr": true,
+ "type": "Boolean"
+ }
+ ]
+ },
+ {
+ "name": "DataStoreReference",
+ "superClass": [
+ "ItemAwareElement",
+ "FlowElement"
+ ],
+ "properties": [
+ {
+ "name": "dataStoreRef",
+ "type": "DataStore",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "DataObjectReference",
+ "superClass": [
+ "ItemAwareElement",
+ "FlowElement"
+ ],
+ "properties": [
+ {
+ "name": "dataObjectRef",
+ "type": "DataObject",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ConversationLink",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "sourceRef",
+ "type": "InteractionNode",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "targetRef",
+ "type": "InteractionNode",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ConversationAssociation",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "innerConversationNodeRef",
+ "type": "ConversationNode",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "outerConversationNodeRef",
+ "type": "ConversationNode",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "CallConversation",
+ "superClass": [
+ "ConversationNode"
+ ],
+ "properties": [
+ {
+ "name": "calledCollaborationRef",
+ "type": "Collaboration",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "participantAssociations",
+ "type": "ParticipantAssociation",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Conversation",
+ "superClass": [
+ "ConversationNode"
+ ]
+ },
+ {
+ "name": "SubConversation",
+ "superClass": [
+ "ConversationNode"
+ ],
+ "properties": [
+ {
+ "name": "conversationNodes",
+ "type": "ConversationNode",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "ConversationNode",
+ "isAbstract": true,
+ "superClass": [
+ "InteractionNode",
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "participantRef",
+ "type": "Participant",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "messageFlowRefs",
+ "type": "MessageFlow",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "correlationKeys",
+ "type": "CorrelationKey",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "GlobalConversation",
+ "superClass": [
+ "Collaboration"
+ ]
+ },
+ {
+ "name": "PartnerEntity",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "participantRef",
+ "type": "Participant",
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "PartnerRole",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "participantRef",
+ "type": "Participant",
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "CorrelationProperty",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "correlationPropertyRetrievalExpression",
+ "type": "CorrelationPropertyRetrievalExpression",
+ "isMany": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "type",
+ "type": "ItemDefinition",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Error",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "structureRef",
+ "type": "ItemDefinition",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "errorCode",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "CorrelationKey",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "correlationPropertyRef",
+ "type": "CorrelationProperty",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Expression",
+ "superClass": [
+ "BaseElement"
+ ],
+ "isAbstract": false,
+ "properties": [
+ {
+ "name": "body",
+ "type": "String",
+ "isBody": true
+ }
+ ]
+ },
+ {
+ "name": "FormalExpression",
+ "superClass": [
+ "Expression"
+ ],
+ "properties": [
+ {
+ "name": "language",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "evaluatesToTypeRef",
+ "type": "ItemDefinition",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Message",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "itemRef",
+ "type": "ItemDefinition",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ItemDefinition",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "itemKind",
+ "type": "ItemKind",
+ "isAttr": true
+ },
+ {
+ "name": "structureRef",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "isCollection",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "import",
+ "type": "Import",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "FlowElement",
+ "isAbstract": true,
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "auditing",
+ "type": "Auditing"
+ },
+ {
+ "name": "monitoring",
+ "type": "Monitoring"
+ },
+ {
+ "name": "categoryValueRef",
+ "type": "CategoryValue",
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "SequenceFlow",
+ "superClass": [
+ "FlowElement"
+ ],
+ "properties": [
+ {
+ "name": "isImmediate",
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "conditionExpression",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "sourceRef",
+ "type": "FlowNode",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "targetRef",
+ "type": "FlowNode",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "FlowElementsContainer",
+ "isAbstract": true,
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "laneSets",
+ "type": "LaneSet",
+ "isMany": true
+ },
+ {
+ "name": "flowElements",
+ "type": "FlowElement",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "CallableElement",
+ "isAbstract": true,
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "ioSpecification",
+ "type": "InputOutputSpecification",
+ "xml": {
+ "serialize": "property"
+ }
+ },
+ {
+ "name": "supportedInterfaceRef",
+ "type": "Interface",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "ioBinding",
+ "type": "InputOutputBinding",
+ "isMany": true,
+ "xml": {
+ "serialize": "property"
+ }
+ }
+ ]
+ },
+ {
+ "name": "FlowNode",
+ "isAbstract": true,
+ "superClass": [
+ "FlowElement"
+ ],
+ "properties": [
+ {
+ "name": "incoming",
+ "type": "SequenceFlow",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "outgoing",
+ "type": "SequenceFlow",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "lanes",
+ "type": "Lane",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "CorrelationPropertyRetrievalExpression",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "messagePath",
+ "type": "FormalExpression"
+ },
+ {
+ "name": "messageRef",
+ "type": "Message",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "CorrelationPropertyBinding",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "dataPath",
+ "type": "FormalExpression"
+ },
+ {
+ "name": "correlationPropertyRef",
+ "type": "CorrelationProperty",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Resource",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "resourceParameters",
+ "type": "ResourceParameter",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "ResourceParameter",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "isRequired",
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "type",
+ "type": "ItemDefinition",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "CorrelationSubscription",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "correlationKeyRef",
+ "type": "CorrelationKey",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "correlationPropertyBinding",
+ "type": "CorrelationPropertyBinding",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "MessageFlow",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "sourceRef",
+ "type": "InteractionNode",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "targetRef",
+ "type": "InteractionNode",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "messageRef",
+ "type": "Message",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "MessageFlowAssociation",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "innerMessageFlowRef",
+ "type": "MessageFlow",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "outerMessageFlowRef",
+ "type": "MessageFlow",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "InteractionNode",
+ "isAbstract": true,
+ "properties": [
+ {
+ "name": "incomingConversationLinks",
+ "type": "ConversationLink",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "outgoingConversationLinks",
+ "type": "ConversationLink",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Participant",
+ "superClass": [
+ "InteractionNode",
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "interfaceRef",
+ "type": "Interface",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "participantMultiplicity",
+ "type": "ParticipantMultiplicity"
+ },
+ {
+ "name": "endPointRefs",
+ "type": "EndPoint",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "processRef",
+ "type": "Process",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ParticipantAssociation",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "innerParticipantRef",
+ "type": "Participant",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "outerParticipantRef",
+ "type": "Participant",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ParticipantMultiplicity",
+ "properties": [
+ {
+ "name": "minimum",
+ "default": 0,
+ "isAttr": true,
+ "type": "Integer"
+ },
+ {
+ "name": "maximum",
+ "default": 1,
+ "isAttr": true,
+ "type": "Integer"
+ }
+ ],
+ "superClass": [
+ "BaseElement"
+ ]
+ },
+ {
+ "name": "Collaboration",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "isClosed",
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "participants",
+ "type": "Participant",
+ "isMany": true
+ },
+ {
+ "name": "messageFlows",
+ "type": "MessageFlow",
+ "isMany": true
+ },
+ {
+ "name": "artifacts",
+ "type": "Artifact",
+ "isMany": true
+ },
+ {
+ "name": "conversations",
+ "type": "ConversationNode",
+ "isMany": true
+ },
+ {
+ "name": "conversationAssociations",
+ "type": "ConversationAssociation"
+ },
+ {
+ "name": "participantAssociations",
+ "type": "ParticipantAssociation",
+ "isMany": true
+ },
+ {
+ "name": "messageFlowAssociations",
+ "type": "MessageFlowAssociation",
+ "isMany": true
+ },
+ {
+ "name": "correlationKeys",
+ "type": "CorrelationKey",
+ "isMany": true
+ },
+ {
+ "name": "choreographyRef",
+ "type": "Choreography",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "conversationLinks",
+ "type": "ConversationLink",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "ChoreographyActivity",
+ "isAbstract": true,
+ "superClass": [
+ "FlowNode"
+ ],
+ "properties": [
+ {
+ "name": "participantRef",
+ "type": "Participant",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "initiatingParticipantRef",
+ "type": "Participant",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "correlationKeys",
+ "type": "CorrelationKey",
+ "isMany": true
+ },
+ {
+ "name": "loopType",
+ "type": "ChoreographyLoopType",
+ "default": "None",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "CallChoreography",
+ "superClass": [
+ "ChoreographyActivity"
+ ],
+ "properties": [
+ {
+ "name": "calledChoreographyRef",
+ "type": "Choreography",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "participantAssociations",
+ "type": "ParticipantAssociation",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "SubChoreography",
+ "superClass": [
+ "ChoreographyActivity",
+ "FlowElementsContainer"
+ ],
+ "properties": [
+ {
+ "name": "artifacts",
+ "type": "Artifact",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "ChoreographyTask",
+ "superClass": [
+ "ChoreographyActivity"
+ ],
+ "properties": [
+ {
+ "name": "messageFlowRef",
+ "type": "MessageFlow",
+ "isMany": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Choreography",
+ "superClass": [
+ "Collaboration",
+ "FlowElementsContainer"
+ ]
+ },
+ {
+ "name": "GlobalChoreographyTask",
+ "superClass": [
+ "Choreography"
+ ],
+ "properties": [
+ {
+ "name": "initiatingParticipantRef",
+ "type": "Participant",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "TextAnnotation",
+ "superClass": [
+ "Artifact"
+ ],
+ "properties": [
+ {
+ "name": "text",
+ "type": "String"
+ },
+ {
+ "name": "textFormat",
+ "default": "text/plain",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Group",
+ "superClass": [
+ "Artifact"
+ ],
+ "properties": [
+ {
+ "name": "categoryValueRef",
+ "type": "CategoryValue",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Association",
+ "superClass": [
+ "Artifact"
+ ],
+ "properties": [
+ {
+ "name": "associationDirection",
+ "type": "AssociationDirection",
+ "isAttr": true
+ },
+ {
+ "name": "sourceRef",
+ "type": "BaseElement",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "targetRef",
+ "type": "BaseElement",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "Category",
+ "superClass": [
+ "RootElement"
+ ],
+ "properties": [
+ {
+ "name": "categoryValue",
+ "type": "CategoryValue",
+ "isMany": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Artifact",
+ "isAbstract": true,
+ "superClass": [
+ "BaseElement"
+ ]
+ },
+ {
+ "name": "CategoryValue",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "categorizedFlowElements",
+ "type": "FlowElement",
+ "isVirtual": true,
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "value",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Activity",
+ "isAbstract": true,
+ "superClass": [
+ "FlowNode"
+ ],
+ "properties": [
+ {
+ "name": "isForCompensation",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "default",
+ "type": "SequenceFlow",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "ioSpecification",
+ "type": "InputOutputSpecification",
+ "xml": {
+ "serialize": "property"
+ }
+ },
+ {
+ "name": "boundaryEventRefs",
+ "type": "BoundaryEvent",
+ "isMany": true,
+ "isReference": true
+ },
+ {
+ "name": "properties",
+ "type": "Property",
+ "isMany": true
+ },
+ {
+ "name": "dataInputAssociations",
+ "type": "DataInputAssociation",
+ "isMany": true
+ },
+ {
+ "name": "dataOutputAssociations",
+ "type": "DataOutputAssociation",
+ "isMany": true
+ },
+ {
+ "name": "startQuantity",
+ "default": 1,
+ "isAttr": true,
+ "type": "Integer"
+ },
+ {
+ "name": "resources",
+ "type": "ResourceRole",
+ "isMany": true
+ },
+ {
+ "name": "completionQuantity",
+ "default": 1,
+ "isAttr": true,
+ "type": "Integer"
+ },
+ {
+ "name": "loopCharacteristics",
+ "type": "LoopCharacteristics"
+ }
+ ]
+ },
+ {
+ "name": "ServiceTask",
+ "superClass": [
+ "Task"
+ ],
+ "properties": [
+ {
+ "name": "implementation",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "operationRef",
+ "type": "Operation",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "SubProcess",
+ "superClass": [
+ "Activity",
+ "FlowElementsContainer",
+ "InteractionNode"
+ ],
+ "properties": [
+ {
+ "name": "triggeredByEvent",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "artifacts",
+ "type": "Artifact",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "LoopCharacteristics",
+ "isAbstract": true,
+ "superClass": [
+ "BaseElement"
+ ]
+ },
+ {
+ "name": "MultiInstanceLoopCharacteristics",
+ "superClass": [
+ "LoopCharacteristics"
+ ],
+ "properties": [
+ {
+ "name": "isSequential",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "behavior",
+ "type": "MultiInstanceBehavior",
+ "default": "All",
+ "isAttr": true
+ },
+ {
+ "name": "loopCardinality",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "loopDataInputRef",
+ "type": "ItemAwareElement",
+ "isReference": true
+ },
+ {
+ "name": "loopDataOutputRef",
+ "type": "ItemAwareElement",
+ "isReference": true
+ },
+ {
+ "name": "inputDataItem",
+ "type": "DataInput",
+ "xml": {
+ "serialize": "property"
+ }
+ },
+ {
+ "name": "outputDataItem",
+ "type": "DataOutput",
+ "xml": {
+ "serialize": "property"
+ }
+ },
+ {
+ "name": "complexBehaviorDefinition",
+ "type": "ComplexBehaviorDefinition",
+ "isMany": true
+ },
+ {
+ "name": "completionCondition",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "oneBehaviorEventRef",
+ "type": "EventDefinition",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "noneBehaviorEventRef",
+ "type": "EventDefinition",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "StandardLoopCharacteristics",
+ "superClass": [
+ "LoopCharacteristics"
+ ],
+ "properties": [
+ {
+ "name": "testBefore",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "loopCondition",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "loopMaximum",
+ "type": "Integer",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "CallActivity",
+ "superClass": [
+ "Activity"
+ ],
+ "properties": [
+ {
+ "name": "calledElement",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "Task",
+ "superClass": [
+ "Activity",
+ "InteractionNode"
+ ]
+ },
+ {
+ "name": "SendTask",
+ "superClass": [
+ "Task"
+ ],
+ "properties": [
+ {
+ "name": "implementation",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "operationRef",
+ "type": "Operation",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "messageRef",
+ "type": "Message",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ReceiveTask",
+ "superClass": [
+ "Task"
+ ],
+ "properties": [
+ {
+ "name": "implementation",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "instantiate",
+ "default": false,
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "operationRef",
+ "type": "Operation",
+ "isAttr": true,
+ "isReference": true
+ },
+ {
+ "name": "messageRef",
+ "type": "Message",
+ "isAttr": true,
+ "isReference": true
+ }
+ ]
+ },
+ {
+ "name": "ScriptTask",
+ "superClass": [
+ "Task"
+ ],
+ "properties": [
+ {
+ "name": "scriptFormat",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "script",
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "BusinessRuleTask",
+ "superClass": [
+ "Task"
+ ],
+ "properties": [
+ {
+ "name": "implementation",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "AdHocSubProcess",
+ "superClass": [
+ "SubProcess"
+ ],
+ "properties": [
+ {
+ "name": "completionCondition",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "ordering",
+ "type": "AdHocOrdering",
+ "isAttr": true
+ },
+ {
+ "name": "cancelRemainingInstances",
+ "default": true,
+ "isAttr": true,
+ "type": "Boolean"
+ }
+ ]
+ },
+ {
+ "name": "Transaction",
+ "superClass": [
+ "SubProcess"
+ ],
+ "properties": [
+ {
+ "name": "protocol",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "method",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "GlobalScriptTask",
+ "superClass": [
+ "GlobalTask"
+ ],
+ "properties": [
+ {
+ "name": "scriptLanguage",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "script",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "GlobalBusinessRuleTask",
+ "superClass": [
+ "GlobalTask"
+ ],
+ "properties": [
+ {
+ "name": "implementation",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ComplexBehaviorDefinition",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "condition",
+ "type": "FormalExpression"
+ },
+ {
+ "name": "event",
+ "type": "ImplicitThrowEvent"
+ }
+ ]
+ },
+ {
+ "name": "ResourceRole",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "resourceRef",
+ "type": "Resource",
+ "isReference": true
+ },
+ {
+ "name": "resourceParameterBindings",
+ "type": "ResourceParameterBinding",
+ "isMany": true
+ },
+ {
+ "name": "resourceAssignmentExpression",
+ "type": "ResourceAssignmentExpression"
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ResourceParameterBinding",
+ "properties": [
+ {
+ "name": "expression",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ },
+ {
+ "name": "parameterRef",
+ "type": "ResourceParameter",
+ "isAttr": true,
+ "isReference": true
+ }
+ ],
+ "superClass": [
+ "BaseElement"
+ ]
+ },
+ {
+ "name": "ResourceAssignmentExpression",
+ "properties": [
+ {
+ "name": "expression",
+ "type": "Expression",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ }
+ ],
+ "superClass": [
+ "BaseElement"
+ ]
+ },
+ {
+ "name": "Import",
+ "properties": [
+ {
+ "name": "importType",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "location",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "namespace",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Definitions",
+ "superClass": [
+ "BaseElement"
+ ],
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "targetNamespace",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "expressionLanguage",
+ "default": "http://www.w3.org/1999/XPath",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "typeLanguage",
+ "default": "http://www.w3.org/2001/XMLSchema",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "imports",
+ "type": "Import",
+ "isMany": true
+ },
+ {
+ "name": "extensions",
+ "type": "Extension",
+ "isMany": true
+ },
+ {
+ "name": "rootElements",
+ "type": "RootElement",
+ "isMany": true
+ },
+ {
+ "name": "diagrams",
+ "isMany": true,
+ "type": "bpmndi:BPMNDiagram"
+ },
+ {
+ "name": "exporter",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "relationships",
+ "type": "Relationship",
+ "isMany": true
+ },
+ {
+ "name": "exporterVersion",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ }
+ ],
+ "enumerations": [
+ {
+ "name": "ProcessType",
+ "literalValues": [
+ {
+ "name": "None"
+ },
+ {
+ "name": "Public"
+ },
+ {
+ "name": "Private"
+ }
+ ]
+ },
+ {
+ "name": "GatewayDirection",
+ "literalValues": [
+ {
+ "name": "Unspecified"
+ },
+ {
+ "name": "Converging"
+ },
+ {
+ "name": "Diverging"
+ },
+ {
+ "name": "Mixed"
+ }
+ ]
+ },
+ {
+ "name": "EventBasedGatewayType",
+ "literalValues": [
+ {
+ "name": "Parallel"
+ },
+ {
+ "name": "Exclusive"
+ }
+ ]
+ },
+ {
+ "name": "RelationshipDirection",
+ "literalValues": [
+ {
+ "name": "None"
+ },
+ {
+ "name": "Forward"
+ },
+ {
+ "name": "Backward"
+ },
+ {
+ "name": "Both"
+ }
+ ]
+ },
+ {
+ "name": "ItemKind",
+ "literalValues": [
+ {
+ "name": "Physical"
+ },
+ {
+ "name": "Information"
+ }
+ ]
+ },
+ {
+ "name": "ChoreographyLoopType",
+ "literalValues": [
+ {
+ "name": "None"
+ },
+ {
+ "name": "Standard"
+ },
+ {
+ "name": "MultiInstanceSequential"
+ },
+ {
+ "name": "MultiInstanceParallel"
+ }
+ ]
+ },
+ {
+ "name": "AssociationDirection",
+ "literalValues": [
+ {
+ "name": "None"
+ },
+ {
+ "name": "One"
+ },
+ {
+ "name": "Both"
+ }
+ ]
+ },
+ {
+ "name": "MultiInstanceBehavior",
+ "literalValues": [
+ {
+ "name": "None"
+ },
+ {
+ "name": "One"
+ },
+ {
+ "name": "All"
+ },
+ {
+ "name": "Complex"
+ }
+ ]
+ },
+ {
+ "name": "AdHocOrdering",
+ "literalValues": [
+ {
+ "name": "Parallel"
+ },
+ {
+ "name": "Sequential"
+ }
+ ]
+ }
+ ],
+ "prefix": "bpmn",
+ "xml": {
+ "tagAlias": "lowerCase",
+ "typePrefix": "t"
+ }
+}
+},{}],225:[function(require,module,exports){
+module.exports={
+ "name": "BPMNDI",
+ "uri": "http://www.omg.org/spec/BPMN/20100524/DI",
+ "types": [
+ {
+ "name": "BPMNDiagram",
+ "properties": [
+ {
+ "name": "plane",
+ "type": "BPMNPlane",
+ "redefines": "di:Diagram#rootElement"
+ },
+ {
+ "name": "labelStyle",
+ "type": "BPMNLabelStyle",
+ "isMany": true
+ }
+ ],
+ "superClass": [
+ "di:Diagram"
+ ]
+ },
+ {
+ "name": "BPMNPlane",
+ "properties": [
+ {
+ "name": "bpmnElement",
+ "isAttr": true,
+ "isReference": true,
+ "type": "bpmn:BaseElement",
+ "redefines": "di:DiagramElement#modelElement"
+ }
+ ],
+ "superClass": [
+ "di:Plane"
+ ]
+ },
+ {
+ "name": "BPMNShape",
+ "properties": [
+ {
+ "name": "bpmnElement",
+ "isAttr": true,
+ "isReference": true,
+ "type": "bpmn:BaseElement",
+ "redefines": "di:DiagramElement#modelElement"
+ },
+ {
+ "name": "isHorizontal",
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "isExpanded",
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "isMarkerVisible",
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "label",
+ "type": "BPMNLabel"
+ },
+ {
+ "name": "isMessageVisible",
+ "isAttr": true,
+ "type": "Boolean"
+ },
+ {
+ "name": "participantBandKind",
+ "type": "ParticipantBandKind",
+ "isAttr": true
+ },
+ {
+ "name": "choreographyActivityShape",
+ "type": "BPMNShape",
+ "isAttr": true,
+ "isReference": true
+ }
+ ],
+ "superClass": [
+ "di:LabeledShape"
+ ]
+ },
+ {
+ "name": "BPMNEdge",
+ "properties": [
+ {
+ "name": "label",
+ "type": "BPMNLabel"
+ },
+ {
+ "name": "bpmnElement",
+ "isAttr": true,
+ "isReference": true,
+ "type": "bpmn:BaseElement",
+ "redefines": "di:DiagramElement#modelElement"
+ },
+ {
+ "name": "sourceElement",
+ "isAttr": true,
+ "isReference": true,
+ "type": "di:DiagramElement",
+ "redefines": "di:Edge#source"
+ },
+ {
+ "name": "targetElement",
+ "isAttr": true,
+ "isReference": true,
+ "type": "di:DiagramElement",
+ "redefines": "di:Edge#target"
+ },
+ {
+ "name": "messageVisibleKind",
+ "type": "MessageVisibleKind",
+ "isAttr": true,
+ "default": "initiating"
+ }
+ ],
+ "superClass": [
+ "di:LabeledEdge"
+ ]
+ },
+ {
+ "name": "BPMNLabel",
+ "properties": [
+ {
+ "name": "labelStyle",
+ "type": "BPMNLabelStyle",
+ "isAttr": true,
+ "isReference": true,
+ "redefines": "di:DiagramElement#style"
+ }
+ ],
+ "superClass": [
+ "di:Label"
+ ]
+ },
+ {
+ "name": "BPMNLabelStyle",
+ "properties": [
+ {
+ "name": "font",
+ "type": "dc:Font"
+ }
+ ],
+ "superClass": [
+ "di:Style"
+ ]
+ }
+ ],
+ "enumerations": [
+ {
+ "name": "ParticipantBandKind",
+ "literalValues": [
+ {
+ "name": "top_initiating"
+ },
+ {
+ "name": "middle_initiating"
+ },
+ {
+ "name": "bottom_initiating"
+ },
+ {
+ "name": "top_non_initiating"
+ },
+ {
+ "name": "middle_non_initiating"
+ },
+ {
+ "name": "bottom_non_initiating"
+ }
+ ]
+ },
+ {
+ "name": "MessageVisibleKind",
+ "literalValues": [
+ {
+ "name": "initiating"
+ },
+ {
+ "name": "non_initiating"
+ }
+ ]
+ }
+ ],
+ "associations": [],
+ "prefix": "bpmndi"
+}
+},{}],226:[function(require,module,exports){
+module.exports={
+ "name": "DC",
+ "uri": "http://www.omg.org/spec/DD/20100524/DC",
+ "types": [
+ {
+ "name": "Boolean"
+ },
+ {
+ "name": "Integer"
+ },
+ {
+ "name": "Real"
+ },
+ {
+ "name": "String"
+ },
+ {
+ "name": "Font",
+ "properties": [
+ {
+ "name": "name",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "size",
+ "type": "Real",
+ "isAttr": true
+ },
+ {
+ "name": "isBold",
+ "type": "Boolean",
+ "isAttr": true
+ },
+ {
+ "name": "isItalic",
+ "type": "Boolean",
+ "isAttr": true
+ },
+ {
+ "name": "isUnderline",
+ "type": "Boolean",
+ "isAttr": true
+ },
+ {
+ "name": "isStrikeThrough",
+ "type": "Boolean",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "Point",
+ "properties": [
+ {
+ "name": "x",
+ "type": "Real",
+ "default": "0",
+ "isAttr": true
+ },
+ {
+ "name": "y",
+ "type": "Real",
+ "default": "0",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "Bounds",
+ "properties": [
+ {
+ "name": "x",
+ "type": "Real",
+ "default": "0",
+ "isAttr": true
+ },
+ {
+ "name": "y",
+ "type": "Real",
+ "default": "0",
+ "isAttr": true
+ },
+ {
+ "name": "width",
+ "type": "Real",
+ "isAttr": true
+ },
+ {
+ "name": "height",
+ "type": "Real",
+ "isAttr": true
+ }
+ ]
+ }
+ ],
+ "prefix": "dc",
+ "associations": []
+}
+},{}],227:[function(require,module,exports){
+module.exports={
+ "name": "DI",
+ "uri": "http://www.omg.org/spec/DD/20100524/DI",
+ "types": [
+ {
+ "name": "DiagramElement",
+ "isAbstract": true,
+ "properties": [
+ {
+ "name": "id",
+ "type": "String",
+ "isAttr": true,
+ "isId": true
+ },
+ {
+ "name": "extension",
+ "type": "Extension"
+ },
+ {
+ "name": "owningDiagram",
+ "type": "Diagram",
+ "isReadOnly": true,
+ "isVirtual": true,
+ "isReference": true
+ },
+ {
+ "name": "owningElement",
+ "type": "DiagramElement",
+ "isReadOnly": true,
+ "isVirtual": true,
+ "isReference": true
+ },
+ {
+ "name": "modelElement",
+ "isReadOnly": true,
+ "isVirtual": true,
+ "isReference": true,
+ "type": "Element"
+ },
+ {
+ "name": "style",
+ "type": "Style",
+ "isReadOnly": true,
+ "isVirtual": true,
+ "isReference": true
+ },
+ {
+ "name": "ownedElement",
+ "type": "DiagramElement",
+ "isReadOnly": true,
+ "isVirtual": true,
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Node",
+ "isAbstract": true,
+ "superClass": [
+ "DiagramElement"
+ ]
+ },
+ {
+ "name": "Edge",
+ "isAbstract": true,
+ "superClass": [
+ "DiagramElement"
+ ],
+ "properties": [
+ {
+ "name": "source",
+ "type": "DiagramElement",
+ "isReadOnly": true,
+ "isVirtual": true,
+ "isReference": true
+ },
+ {
+ "name": "target",
+ "type": "DiagramElement",
+ "isReadOnly": true,
+ "isVirtual": true,
+ "isReference": true
+ },
+ {
+ "name": "waypoint",
+ "isUnique": false,
+ "isMany": true,
+ "type": "dc:Point",
+ "xml": {
+ "serialize": "xsi:type"
+ }
+ }
+ ]
+ },
+ {
+ "name": "Diagram",
+ "isAbstract": true,
+ "properties": [
+ {
+ "name": "id",
+ "type": "String",
+ "isAttr": true,
+ "isId": true
+ },
+ {
+ "name": "rootElement",
+ "type": "DiagramElement",
+ "isReadOnly": true,
+ "isVirtual": true
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "documentation",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "resolution",
+ "isAttr": true,
+ "type": "Real"
+ },
+ {
+ "name": "ownedStyle",
+ "type": "Style",
+ "isReadOnly": true,
+ "isVirtual": true,
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Shape",
+ "isAbstract": true,
+ "superClass": [
+ "Node"
+ ],
+ "properties": [
+ {
+ "name": "bounds",
+ "type": "dc:Bounds"
+ }
+ ]
+ },
+ {
+ "name": "Plane",
+ "isAbstract": true,
+ "superClass": [
+ "Node"
+ ],
+ "properties": [
+ {
+ "name": "planeElement",
+ "type": "DiagramElement",
+ "subsettedProperty": "DiagramElement-ownedElement",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "LabeledEdge",
+ "isAbstract": true,
+ "superClass": [
+ "Edge"
+ ],
+ "properties": [
+ {
+ "name": "ownedLabel",
+ "type": "Label",
+ "isReadOnly": true,
+ "subsettedProperty": "DiagramElement-ownedElement",
+ "isVirtual": true,
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "LabeledShape",
+ "isAbstract": true,
+ "superClass": [
+ "Shape"
+ ],
+ "properties": [
+ {
+ "name": "ownedLabel",
+ "type": "Label",
+ "isReadOnly": true,
+ "subsettedProperty": "DiagramElement-ownedElement",
+ "isVirtual": true,
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Label",
+ "isAbstract": true,
+ "superClass": [
+ "Node"
+ ],
+ "properties": [
+ {
+ "name": "bounds",
+ "type": "dc:Bounds"
+ }
+ ]
+ },
+ {
+ "name": "Style",
+ "isAbstract": true,
+ "properties": [
+ {
+ "name": "id",
+ "type": "String",
+ "isAttr": true,
+ "isId": true
+ }
+ ]
+ },
+ {
+ "name": "Extension",
+ "properties": [
+ {
+ "name": "values",
+ "type": "Element",
+ "isMany": true
+ }
+ ]
+ }
+ ],
+ "associations": [],
+ "prefix": "di",
+ "xml": {
+ "tagAlias": "lowerCase"
+ }
+}
+},{}],228:[function(require,module,exports){
+'use strict';
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var objectCreate = Object.create || objectCreatePolyfill;
+var objectKeys = Object.keys || objectKeysPolyfill;
+var bind = Function.prototype.bind || functionBindPolyfill;
+
+function EventEmitter() {
+ if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ }
+
+ this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+var defaultMaxListeners = 10;
+
+var hasDefineProperty;
+try {
+ var o = {};
+ if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
+ hasDefineProperty = o.x === 0;
+} catch (err) {
+ hasDefineProperty = false;
+}
+if (hasDefineProperty) {
+ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
+ enumerable: true,
+ get: function get() {
+ return defaultMaxListeners;
+ },
+ set: function set(arg) {
+ // check whether the input is a positive number (whose value is zero or
+ // greater and not a NaN).
+ if (typeof arg !== 'number' || arg < 0 || arg !== arg) throw new TypeError('"defaultMaxListeners" must be a positive number');
+ defaultMaxListeners = arg;
+ }
+ });
+} else {
+ EventEmitter.defaultMaxListeners = defaultMaxListeners;
+}
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
+ if (typeof n !== 'number' || n < 0 || isNaN(n)) throw new TypeError('"n" argument must be a positive number');
+ this._maxListeners = n;
+ return this;
+};
+
+function $getMaxListeners(that) {
+ if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners;
+ return that._maxListeners;
+}
+
+EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
+ return $getMaxListeners(this);
+};
+
+// These standalone emit* functions are used to optimize calling of event
+// handlers for fast cases because emit() itself often has a variable number of
+// arguments and can be deoptimized because of that. These functions always have
+// the same number of arguments and thus do not get deoptimized, so the code
+// inside them can execute faster.
+function emitNone(handler, isFn, self) {
+ if (isFn) handler.call(self);else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i) {
+ listeners[i].call(self);
+ }
+ }
+}
+function emitOne(handler, isFn, self, arg1) {
+ if (isFn) handler.call(self, arg1);else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i) {
+ listeners[i].call(self, arg1);
+ }
+ }
+}
+function emitTwo(handler, isFn, self, arg1, arg2) {
+ if (isFn) handler.call(self, arg1, arg2);else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i) {
+ listeners[i].call(self, arg1, arg2);
+ }
+ }
+}
+function emitThree(handler, isFn, self, arg1, arg2, arg3) {
+ if (isFn) handler.call(self, arg1, arg2, arg3);else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i) {
+ listeners[i].call(self, arg1, arg2, arg3);
+ }
+ }
+}
+
+function emitMany(handler, isFn, self, args) {
+ if (isFn) handler.apply(self, args);else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i) {
+ listeners[i].apply(self, args);
+ }
+ }
+}
+
+EventEmitter.prototype.emit = function emit(type) {
+ var er, handler, len, args, i, events;
+ var doError = type === 'error';
+
+ events = this._events;
+ if (events) doError = doError && events.error == null;else if (!doError) return false;
+
+ // If there is no 'error' event listener then throw.
+ if (doError) {
+ if (arguments.length > 1) er = arguments[1];
+ if (er instanceof Error) {
+ throw er; // Unhandled 'error' event
+ } else {
+ // At least give some kind of context to the user
+ var err = new Error('Unhandled "error" event. (' + er + ')');
+ err.context = er;
+ throw err;
+ }
+ return false;
+ }
+
+ handler = events[type];
+
+ if (!handler) return false;
+
+ var isFn = typeof handler === 'function';
+ len = arguments.length;
+ switch (len) {
+ // fast cases
+ case 1:
+ emitNone(handler, isFn, this);
+ break;
+ case 2:
+ emitOne(handler, isFn, this, arguments[1]);
+ break;
+ case 3:
+ emitTwo(handler, isFn, this, arguments[1], arguments[2]);
+ break;
+ case 4:
+ emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
+ break;
+ // slower
+ default:
+ args = new Array(len - 1);
+ for (i = 1; i < len; i++) {
+ args[i - 1] = arguments[i];
+ }emitMany(handler, isFn, this, args);
+ }
+
+ return true;
+};
+
+function _addListener(target, type, listener, prepend) {
+ var m;
+ var events;
+ var existing;
+
+ if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function');
+
+ events = target._events;
+ if (!events) {
+ events = target._events = objectCreate(null);
+ target._eventsCount = 0;
+ } else {
+ // To avoid recursion in the case that type === "newListener"! Before
+ // adding it to the listeners, first emit "newListener".
+ if (events.newListener) {
+ target.emit('newListener', type, listener.listener ? listener.listener : listener);
+
+ // Re-assign `events` because a newListener handler could have caused the
+ // this._events to be assigned to a new object
+ events = target._events;
+ }
+ existing = events[type];
+ }
+
+ if (!existing) {
+ // Optimize the case of one listener. Don't need the extra array object.
+ existing = events[type] = listener;
+ ++target._eventsCount;
+ } else {
+ if (typeof existing === 'function') {
+ // Adding the second element, need to change to array.
+ existing = events[type] = prepend ? [listener, existing] : [existing, listener];
+ } else {
+ // If we've already got an array, just append.
+ if (prepend) {
+ existing.unshift(listener);
+ } else {
+ existing.push(listener);
+ }
+ }
+
+ // Check for listener leak
+ if (!existing.warned) {
+ m = $getMaxListeners(target);
+ if (m && m > 0 && existing.length > m) {
+ existing.warned = true;
+ var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' "' + String(type) + '" listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit.');
+ w.name = 'MaxListenersExceededWarning';
+ w.emitter = target;
+ w.type = type;
+ w.count = existing.length;
+ if ((typeof console === 'undefined' ? 'undefined' : _typeof(console)) === 'object' && console.warn) {
+ console.warn('%s: %s', w.name, w.message);
+ }
+ }
+ }
+ }
+
+ return target;
+}
+
+EventEmitter.prototype.addListener = function addListener(type, listener) {
+ return _addListener(this, type, listener, false);
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.prependListener = function prependListener(type, listener) {
+ return _addListener(this, type, listener, true);
+};
+
+function onceWrapper() {
+ if (!this.fired) {
+ this.target.removeListener(this.type, this.wrapFn);
+ this.fired = true;
+ switch (arguments.length) {
+ case 0:
+ return this.listener.call(this.target);
+ case 1:
+ return this.listener.call(this.target, arguments[0]);
+ case 2:
+ return this.listener.call(this.target, arguments[0], arguments[1]);
+ case 3:
+ return this.listener.call(this.target, arguments[0], arguments[1], arguments[2]);
+ default:
+ var args = new Array(arguments.length);
+ for (var i = 0; i < args.length; ++i) {
+ args[i] = arguments[i];
+ }this.listener.apply(this.target, args);
+ }
+ }
+}
+
+function _onceWrap(target, type, listener) {
+ var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
+ var wrapped = bind.call(onceWrapper, state);
+ wrapped.listener = listener;
+ state.wrapFn = wrapped;
+ return wrapped;
+}
+
+EventEmitter.prototype.once = function once(type, listener) {
+ if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function');
+ this.on(type, _onceWrap(this, type, listener));
+ return this;
+};
+
+EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
+ if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function');
+ this.prependListener(type, _onceWrap(this, type, listener));
+ return this;
+};
+
+// Emits a 'removeListener' event if and only if the listener was removed.
+EventEmitter.prototype.removeListener = function removeListener(type, listener) {
+ var list, events, position, i, originalListener;
+
+ if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function');
+
+ events = this._events;
+ if (!events) return this;
+
+ list = events[type];
+ if (!list) return this;
+
+ if (list === listener || list.listener === listener) {
+ if (--this._eventsCount === 0) this._events = objectCreate(null);else {
+ delete events[type];
+ if (events.removeListener) this.emit('removeListener', type, list.listener || listener);
+ }
+ } else if (typeof list !== 'function') {
+ position = -1;
+
+ for (i = list.length - 1; i >= 0; i--) {
+ if (list[i] === listener || list[i].listener === listener) {
+ originalListener = list[i].listener;
+ position = i;
+ break;
+ }
+ }
+
+ if (position < 0) return this;
+
+ if (position === 0) list.shift();else spliceOne(list, position);
+
+ if (list.length === 1) events[type] = list[0];
+
+ if (events.removeListener) this.emit('removeListener', type, originalListener || listener);
+ }
+
+ return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
+ var listeners, events, i;
+
+ events = this._events;
+ if (!events) return this;
+
+ // not listening for removeListener, no need to emit
+ if (!events.removeListener) {
+ if (arguments.length === 0) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ } else if (events[type]) {
+ if (--this._eventsCount === 0) this._events = objectCreate(null);else delete events[type];
+ }
+ return this;
+ }
+
+ // emit removeListener for all listeners on all events
+ if (arguments.length === 0) {
+ var keys = objectKeys(events);
+ var key;
+ for (i = 0; i < keys.length; ++i) {
+ key = keys[i];
+ if (key === 'removeListener') continue;
+ this.removeAllListeners(key);
+ }
+ this.removeAllListeners('removeListener');
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ return this;
+ }
+
+ listeners = events[type];
+
+ if (typeof listeners === 'function') {
+ this.removeListener(type, listeners);
+ } else if (listeners) {
+ // LIFO order
+ for (i = listeners.length - 1; i >= 0; i--) {
+ this.removeListener(type, listeners[i]);
+ }
+ }
+
+ return this;
+};
+
+function _listeners(target, type, unwrap) {
+ var events = target._events;
+
+ if (!events) return [];
+
+ var evlistener = events[type];
+ if (!evlistener) return [];
+
+ if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener];
+
+ return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
+}
+
+EventEmitter.prototype.listeners = function listeners(type) {
+ return _listeners(this, type, true);
+};
+
+EventEmitter.prototype.rawListeners = function rawListeners(type) {
+ return _listeners(this, type, false);
+};
+
+EventEmitter.listenerCount = function (emitter, type) {
+ if (typeof emitter.listenerCount === 'function') {
+ return emitter.listenerCount(type);
+ } else {
+ return listenerCount.call(emitter, type);
+ }
+};
+
+EventEmitter.prototype.listenerCount = listenerCount;
+function listenerCount(type) {
+ var events = this._events;
+
+ if (events) {
+ var evlistener = events[type];
+
+ if (typeof evlistener === 'function') {
+ return 1;
+ } else if (evlistener) {
+ return evlistener.length;
+ }
+ }
+
+ return 0;
+}
+
+EventEmitter.prototype.eventNames = function eventNames() {
+ return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
+};
+
+// About 1.5x faster than the two-arg version of Array#splice().
+function spliceOne(list, index) {
+ for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) {
+ list[i] = list[k];
+ }list.pop();
+}
+
+function arrayClone(arr, n) {
+ var copy = new Array(n);
+ for (var i = 0; i < n; ++i) {
+ copy[i] = arr[i];
+ }return copy;
+}
+
+function unwrapListeners(arr) {
+ var ret = new Array(arr.length);
+ for (var i = 0; i < ret.length; ++i) {
+ ret[i] = arr[i].listener || arr[i];
+ }
+ return ret;
+}
+
+function objectCreatePolyfill(proto) {
+ var F = function F() {};
+ F.prototype = proto;
+ return new F();
+}
+function objectKeysPolyfill(obj) {
+ var keys = [];
+ for (var k in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, k)) {
+ keys.push(k);
+ }
+ }return k;
+}
+function functionBindPolyfill(context) {
+ var fn = this;
+ return function () {
+ return fn.apply(context, arguments);
+ };
+}
+
+},{}],229:[function(require,module,exports){
+module.exports={
+ "name": "Camunda",
+ "uri": "http://camunda.org/schema/1.0/bpmn",
+ "prefix": "camunda",
+ "xml": {
+ "tagAlias": "lowerCase"
+ },
+ "associations": [],
+ "types": [
+ {
+ "name": "InOutBinding",
+ "superClass": [
+ "Element"
+ ],
+ "isAbstract": true,
+ "properties": [
+ {
+ "name": "source",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "sourceExpression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "target",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "businessKey",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "local",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ },
+ {
+ "name": "variables",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "In",
+ "superClass": [
+ "InOutBinding"
+ ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:CallActivity"
+ ]
+ }
+ },
+ {
+ "name": "Out",
+ "superClass": [
+ "InOutBinding"
+ ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:CallActivity"
+ ]
+ }
+ },
+ {
+ "name": "AsyncCapable",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:Activity",
+ "bpmn:Gateway",
+ "bpmn:Event"
+ ],
+ "properties": [
+ {
+ "name": "async",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ },
+ {
+ "name": "asyncBefore",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ },
+ {
+ "name": "asyncAfter",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ },
+ {
+ "name": "exclusive",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": true
+ }
+ ]
+ },
+ {
+ "name": "JobPriorized",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:Process",
+ "camunda:AsyncCapable"
+ ],
+ "properties": [
+ {
+ "name": "jobPriority",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "SignalEventDefinition",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:SignalEventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "async",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ }
+ ]
+ },
+ {
+ "name": "ErrorEventDefinition",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:ErrorEventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "errorCodeVariable",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "errorMessageVariable",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "PotentialStarter",
+ "superClass": [
+ "Element"
+ ],
+ "properties": [
+ {
+ "name": "resourceAssignmentExpression",
+ "type": "bpmn:ResourceAssignmentExpression"
+ }
+ ]
+ },
+ {
+ "name": "FormSupported",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:StartEvent",
+ "bpmn:UserTask"
+ ],
+ "properties": [
+ {
+ "name": "formHandlerClass",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "formKey",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "TemplateSupported",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:Process",
+ "bpmn:FlowElement"
+ ],
+ "properties": [
+ {
+ "name": "modelerTemplate",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Initiator",
+ "isAbstract": true,
+ "extends": [ "bpmn:StartEvent" ],
+ "properties": [
+ {
+ "name": "initiator",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ScriptTask",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:ScriptTask"
+ ],
+ "properties": [
+ {
+ "name": "resultVariable",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "resource",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Process",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:Process"
+ ],
+ "properties": [
+ {
+ "name": "candidateStarterGroups",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "candidateStarterUsers",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "versionTag",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "historyTimeToLive",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "isStartableInTasklist",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": true
+ }
+ ]
+ },
+ {
+ "name": "EscalationEventDefinition",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:EscalationEventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "escalationCodeVariable",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "FormalExpression",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:FormalExpression"
+ ],
+ "properties": [
+ {
+ "name": "resource",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Assignable",
+ "extends": [ "bpmn:UserTask" ],
+ "properties": [
+ {
+ "name": "assignee",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "candidateUsers",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "candidateGroups",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "dueDate",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "followUpDate",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "priority",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "CallActivity",
+ "extends": [ "bpmn:CallActivity" ],
+ "properties": [
+ {
+ "name": "calledElementBinding",
+ "isAttr": true,
+ "type": "String",
+ "default": "latest"
+ },
+ {
+ "name": "calledElementVersion",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "calledElementVersionTag",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "calledElementTenantId",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "caseRef",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "caseBinding",
+ "isAttr": true,
+ "type": "String",
+ "default": "latest"
+ },
+ {
+ "name": "caseVersion",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "caseTenantId",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "variableMappingClass",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "variableMappingDelegateExpression",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ServiceTaskLike",
+ "extends": [
+ "bpmn:ServiceTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:SendTask",
+ "bpmn:MessageEventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "expression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "class",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "delegateExpression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "resultVariable",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "DmnCapable",
+ "extends": [
+ "bpmn:BusinessRuleTask"
+ ],
+ "properties": [
+ {
+ "name": "decisionRef",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "decisionRefBinding",
+ "isAttr": true,
+ "type": "String",
+ "default": "latest"
+ },
+ {
+ "name": "decisionRefVersion",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "mapDecisionResult",
+ "isAttr": true,
+ "type": "String",
+ "default": "resultList"
+ },
+ {
+ "name": "decisionRefTenantId",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ExternalCapable",
+ "extends": [
+ "camunda:ServiceTaskLike"
+ ],
+ "properties": [
+ {
+ "name": "type",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "topic",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "TaskPriorized",
+ "extends": [
+ "bpmn:Process",
+ "camunda:ExternalCapable"
+ ],
+ "properties": [
+ {
+ "name": "taskPriority",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Properties",
+ "superClass": [
+ "Element"
+ ],
+ "meta": {
+ "allowedIn": [ "*" ]
+ },
+ "properties": [
+ {
+ "name": "values",
+ "type": "Property",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Property",
+ "superClass": [
+ "Element"
+ ],
+ "properties": [
+ {
+ "name": "id",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "name",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "value",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "Connector",
+ "superClass": [
+ "Element"
+ ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:ServiceTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:SendTask"
+ ]
+ },
+ "properties": [
+ {
+ "name": "inputOutput",
+ "type": "InputOutput"
+ },
+ {
+ "name": "connectorId",
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "InputOutput",
+ "superClass": [
+ "Element"
+ ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:Task",
+ "bpmn:UserTask",
+ "bpmn:ServiceTask",
+ "bpmn:SendTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:ReceiveTask",
+ "bpmn:ScriptTask",
+ "bpmn:ManualTask",
+ "bpmn:GlobalUserTask",
+ "bpmn:GlobalScriptTask",
+ "bpmn:GlobalBusinessRuleTask",
+ "bpmn:GlobalTask",
+ "bpmn:GlobalManualTask",
+ "bpmn:SubProcess",
+ "bpmn:Transaction",
+ "bpmn:IntermediateCatchEvent",
+ "bpmn:IntermediateThrowEvent",
+ "bpmn:EndEvent",
+ "bpmn:ThrowEvent",
+ "bpmn:CatchEvent",
+ "bpmn:ImplicitThrowEvent",
+ "bpmn:CallActivity"
+ ]
+ },
+ "properties": [
+ {
+ "name": "inputOutput",
+ "type": "InputOutput"
+ },
+ {
+ "name": "connectorId",
+ "type": "String"
+ },
+ {
+ "name": "inputParameters",
+ "isMany": true,
+ "type": "InputParameter"
+ },
+ {
+ "name": "outputParameters",
+ "isMany": true,
+ "type": "OutputParameter"
+ }
+ ]
+ },
+ {
+ "name": "InputOutputParameter",
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "value",
+ "isBody": true,
+ "type": "String"
+ },
+ {
+ "name": "definition",
+ "type": "InputOutputParameterDefinition"
+ }
+ ]
+ },
+ {
+ "name": "InputOutputParameterDefinition",
+ "isAbstract": true
+ },
+ {
+ "name": "List",
+ "superClass": [ "InputOutputParameterDefinition" ],
+ "properties": [
+ {
+ "name": "items",
+ "isMany": true,
+ "type": "InputOutputParameterDefinition"
+ }
+ ]
+ },
+ {
+ "name": "Map",
+ "superClass": [ "InputOutputParameterDefinition" ],
+ "properties": [
+ {
+ "name": "entries",
+ "isMany": true,
+ "type": "Entry"
+ }
+ ]
+ },
+ {
+ "name": "Entry",
+ "properties": [
+ {
+ "name": "key",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "value",
+ "isBody": true,
+ "type": "String"
+ },
+ {
+ "name": "definition",
+ "type": "InputOutputParameterDefinition"
+ }
+ ]
+ },
+ {
+ "name": "Value",
+ "superClass": [
+ "InputOutputParameterDefinition"
+ ],
+ "properties": [
+ {
+ "name": "id",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "value",
+ "isBody": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Script",
+ "superClass": [ "InputOutputParameterDefinition" ],
+ "properties": [
+ {
+ "name": "scriptFormat",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "resource",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "value",
+ "isBody": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Field",
+ "superClass": [ "Element" ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:ServiceTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:SendTask"
+ ]
+ },
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "expression",
+ "type": "String"
+ },
+ {
+ "name": "stringValue",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "string",
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "InputParameter",
+ "superClass": [ "InputOutputParameter" ]
+ },
+ {
+ "name": "OutputParameter",
+ "superClass": [ "InputOutputParameter" ]
+ },
+ {
+ "name": "Collectable",
+ "isAbstract": true,
+ "extends": [ "bpmn:MultiInstanceLoopCharacteristics" ],
+ "superClass": [ "camunda:AsyncCapable" ],
+ "properties": [
+ {
+ "name": "collection",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "elementVariable",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "FailedJobRetryTimeCycle",
+ "superClass": [ "Element" ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:Task",
+ "bpmn:ServiceTask",
+ "bpmn:SendTask",
+ "bpmn:UserTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:ScriptTask",
+ "bpmn:ReceiveTask",
+ "bpmn:CallActivity",
+ "bpmn:TimerEventDefinition",
+ "bpmn:SignalEventDefinition",
+ "bpmn:MultiInstanceLoopCharacteristics"
+ ]
+ },
+ "properties": [
+ {
+ "name": "body",
+ "isBody": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ExecutionListener",
+ "superClass": [ "Element" ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:Task",
+ "bpmn:ServiceTask",
+ "bpmn:UserTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:ScriptTask",
+ "bpmn:ReceiveTask",
+ "bpmn:ManualTask",
+ "bpmn:ExclusiveGateway",
+ "bpmn:SequenceFlow",
+ "bpmn:ParallelGateway",
+ "bpmn:InclusiveGateway",
+ "bpmn:EventBasedGateway",
+ "bpmn:StartEvent",
+ "bpmn:IntermediateCatchEvent",
+ "bpmn:IntermediateThrowEvent",
+ "bpmn:EndEvent",
+ "bpmn:BoundaryEvent",
+ "bpmn:CallActivity",
+ "bpmn:SubProcess"
+ ]
+ },
+ "properties": [
+ {
+ "name": "expression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "class",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "delegateExpression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "event",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "script",
+ "type": "Script"
+ },
+ {
+ "name": "fields",
+ "type": "Field",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "TaskListener",
+ "superClass": [ "Element" ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:UserTask"
+ ]
+ },
+ "properties": [
+ {
+ "name": "expression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "class",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "delegateExpression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "event",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "script",
+ "type": "Script"
+ },
+ {
+ "name": "fields",
+ "type": "Field",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "FormProperty",
+ "superClass": [ "Element" ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:StartEvent",
+ "bpmn:UserTask"
+ ]
+ },
+ "properties": [
+ {
+ "name": "id",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "name",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "type",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "required",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "readable",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "writable",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "variable",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "expression",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "datePattern",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "default",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "values",
+ "type": "Value",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "FormData",
+ "superClass": [ "Element" ],
+ "meta": {
+ "allowedIn": [
+ "bpmn:StartEvent",
+ "bpmn:UserTask"
+ ]
+ },
+ "properties": [
+ {
+ "name": "fields",
+ "type": "FormField",
+ "isMany": true
+ },
+ {
+ "name": "businessKey",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "FormField",
+ "superClass": [ "Element" ],
+ "properties": [
+ {
+ "name": "id",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "label",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "type",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "datePattern",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "defaultValue",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "properties",
+ "type": "Properties"
+ },
+ {
+ "name": "validation",
+ "type": "Validation"
+ },
+ {
+ "name": "values",
+ "type": "Value",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Validation",
+ "superClass": [ "Element" ],
+ "properties": [
+ {
+ "name": "constraints",
+ "type": "Constraint",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Constraint",
+ "superClass": [ "Element" ],
+ "properties": [
+ {
+ "name": "name",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "config",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "ConditionalEventDefinition",
+ "isAbstract": true,
+ "extends": [
+ "bpmn:ConditionalEventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "variableName",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "variableEvent",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ }
+ ],
+ "emumerations": [ ]
+}
+
+},{}],230:[function(require,module,exports){
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+
+try {
+ var index = require('indexof');
+} catch (err) {
+ var index = require('component-indexof');
+}
+
+/**
+ * Whitespace regexp.
+ */
+
+var re = /\s+/;
+
+/**
+ * toString reference.
+ */
+
+var toString = Object.prototype.toString;
+
+/**
+ * Wrap `el` in a `ClassList`.
+ *
+ * @param {Element} el
+ * @return {ClassList}
+ * @api public
+ */
+
+module.exports = function (el) {
+ return new ClassList(el);
+};
+
+/**
+ * Initialize a new ClassList for `el`.
+ *
+ * @param {Element} el
+ * @api private
+ */
+
+function ClassList(el) {
+ if (!el || !el.nodeType) {
+ throw new Error('A DOM element reference is required');
+ }
+ this.el = el;
+ this.list = el.classList;
+}
+
+/**
+ * Add class `name` if not already present.
+ *
+ * @param {String} name
+ * @return {ClassList}
+ * @api public
+ */
+
+ClassList.prototype.add = function (name) {
+ // classList
+ if (this.list) {
+ this.list.add(name);
+ return this;
+ }
+
+ // fallback
+ var arr = this.array();
+ var i = index(arr, name);
+ if (!~i) arr.push(name);
+ this.el.className = arr.join(' ');
+ return this;
+};
+
+/**
+ * Remove class `name` when present, or
+ * pass a regular expression to remove
+ * any which match.
+ *
+ * @param {String|RegExp} name
+ * @return {ClassList}
+ * @api public
+ */
+
+ClassList.prototype.remove = function (name) {
+ if ('[object RegExp]' == toString.call(name)) {
+ return this.removeMatching(name);
+ }
+
+ // classList
+ if (this.list) {
+ this.list.remove(name);
+ return this;
+ }
+
+ // fallback
+ var arr = this.array();
+ var i = index(arr, name);
+ if (~i) arr.splice(i, 1);
+ this.el.className = arr.join(' ');
+ return this;
+};
+
+/**
+ * Remove all classes matching `re`.
+ *
+ * @param {RegExp} re
+ * @return {ClassList}
+ * @api private
+ */
+
+ClassList.prototype.removeMatching = function (re) {
+ var arr = this.array();
+ for (var i = 0; i < arr.length; i++) {
+ if (re.test(arr[i])) {
+ this.remove(arr[i]);
+ }
+ }
+ return this;
+};
+
+/**
+ * Toggle class `name`, can force state via `force`.
+ *
+ * For browsers that support classList, but do not support `force` yet,
+ * the mistake will be detected and corrected.
+ *
+ * @param {String} name
+ * @param {Boolean} force
+ * @return {ClassList}
+ * @api public
+ */
+
+ClassList.prototype.toggle = function (name, force) {
+ // classList
+ if (this.list) {
+ if ("undefined" !== typeof force) {
+ if (force !== this.list.toggle(name, force)) {
+ this.list.toggle(name); // toggle again to correct
+ }
+ } else {
+ this.list.toggle(name);
+ }
+ return this;
+ }
+
+ // fallback
+ if ("undefined" !== typeof force) {
+ if (!force) {
+ this.remove(name);
+ } else {
+ this.add(name);
+ }
+ } else {
+ if (this.has(name)) {
+ this.remove(name);
+ } else {
+ this.add(name);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Return an array of classes.
+ *
+ * @return {Array}
+ * @api public
+ */
+
+ClassList.prototype.array = function () {
+ var className = this.el.getAttribute('class') || '';
+ var str = className.replace(/^\s+|\s+$/g, '');
+ var arr = str.split(re);
+ if ('' === arr[0]) arr.shift();
+ return arr;
+};
+
+/**
+ * Check if class `name` is present.
+ *
+ * @param {String} name
+ * @return {ClassList}
+ * @api public
+ */
+
+ClassList.prototype.has = ClassList.prototype.contains = function (name) {
+ return this.list ? this.list.contains(name) : !!~index(this.array(), name);
+};
+
+},{"component-indexof":234,"indexof":234}],231:[function(require,module,exports){
+'use strict';
+
+var matches = require('matches-selector');
+
+module.exports = function (element, selector, checkYoSelf, root) {
+ element = checkYoSelf ? { parentNode: element } : element;
+
+ root = root || document;
+
+ // Make sure `element !== document` and `element != null`
+ // otherwise we get an illegal invocation
+ while ((element = element.parentNode) && element !== document) {
+ if (matches(element, selector)) return element;
+ // After `matches` on the edge case that
+ // the selector matches the root
+ // (when the root is not the document)
+ if (element === root) return;
+ }
+};
+
+},{"matches-selector":235}],232:[function(require,module,exports){
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+
+try {
+ var closest = require('closest');
+} catch (err) {
+ var closest = require('component-closest');
+}
+
+try {
+ var event = require('event');
+} catch (err) {
+ var event = require('component-event');
+}
+
+/**
+ * Delegate event `type` to `selector`
+ * and invoke `fn(e)`. A callback function
+ * is returned which may be passed to `.unbind()`.
+ *
+ * @param {Element} el
+ * @param {String} selector
+ * @param {String} type
+ * @param {Function} fn
+ * @param {Boolean} capture
+ * @return {Function}
+ * @api public
+ */
+
+exports.bind = function (el, selector, type, fn, capture) {
+ return event.bind(el, type, function (e) {
+ var target = e.target || e.srcElement;
+ e.delegateTarget = closest(target, selector, true, el);
+ if (e.delegateTarget) fn.call(el, e);
+ }, capture);
+};
+
+/**
+ * Unbind event `type`'s callback `fn`.
+ *
+ * @param {Element} el
+ * @param {String} type
+ * @param {Function} fn
+ * @param {Boolean} capture
+ * @api public
+ */
+
+exports.unbind = function (el, type, fn, capture) {
+ event.unbind(el, type, fn, capture);
+};
+
+},{"closest":231,"component-closest":231,"component-event":233,"event":233}],233:[function(require,module,exports){
+'use strict';
+
+var bind = window.addEventListener ? 'addEventListener' : 'attachEvent',
+ unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent',
+ prefix = bind !== 'addEventListener' ? 'on' : '';
+
+/**
+ * Bind `el` event `type` to `fn`.
+ *
+ * @param {Element} el
+ * @param {String} type
+ * @param {Function} fn
+ * @param {Boolean} capture
+ * @return {Function}
+ * @api public
+ */
+
+exports.bind = function (el, type, fn, capture) {
+ el[bind](prefix + type, fn, capture || false);
+ return fn;
+};
+
+/**
+ * Unbind `el` event `type`'s callback `fn`.
+ *
+ * @param {Element} el
+ * @param {String} type
+ * @param {Function} fn
+ * @param {Boolean} capture
+ * @return {Function}
+ * @api public
+ */
+
+exports.unbind = function (el, type, fn, capture) {
+ el[unbind](prefix + type, fn, capture || false);
+ return fn;
+};
+
+},{}],234:[function(require,module,exports){
+"use strict";
+
+module.exports = function (arr, obj) {
+ if (arr.indexOf) return arr.indexOf(obj);
+ for (var i = 0; i < arr.length; ++i) {
+ if (arr[i] === obj) return i;
+ }
+ return -1;
+};
+
+},{}],235:[function(require,module,exports){
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+
+try {
+ var query = require('query');
+} catch (err) {
+ var query = require('component-query');
+}
+
+/**
+ * Element prototype.
+ */
+
+var proto = Element.prototype;
+
+/**
+ * Vendor function.
+ */
+
+var vendor = proto.matches || proto.webkitMatchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector;
+
+/**
+ * Expose `match()`.
+ */
+
+module.exports = match;
+
+/**
+ * Match `el` to `selector`.
+ *
+ * @param {Element} el
+ * @param {String} selector
+ * @return {Boolean}
+ * @api public
+ */
+
+function match(el, selector) {
+ if (!el || el.nodeType !== 1) return false;
+ if (vendor) return vendor.call(el, selector);
+ var nodes = query.all(selector, el.parentNode);
+ for (var i = 0; i < nodes.length; ++i) {
+ if (nodes[i] == el) return true;
+ }
+ return false;
+}
+
+},{"component-query":236,"query":236}],236:[function(require,module,exports){
+'use strict';
+
+function one(selector, el) {
+ return el.querySelector(selector);
+}
+
+exports = module.exports = function (selector, el) {
+ el = el || document;
+ return one(selector, el);
+};
+
+exports.all = function (selector, el) {
+ el = el || document;
+ return el.querySelectorAll(selector);
+};
+
+exports.engine = function (obj) {
+ if (!obj.one) throw new Error('.one callback required');
+ if (!obj.all) throw new Error('.all callback required');
+ one = obj.one;
+ exports.all = obj.all;
+ return exports;
+};
+
+},{}],237:[function(require,module,exports){
+(function (global){
+'use strict';
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+/*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */
+;(function (root, factory) {
+ // https://github.com/umdjs/umd/blob/master/returnExports.js
+ if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) == 'object') {
+ // For Node.js.
+ module.exports = factory(root);
+ } else if (typeof define == 'function' && define.amd) {
+ // For AMD. Register as an anonymous module.
+ define([], factory.bind(root, root));
+ } else {
+ // For browser globals (not exposing the function separately).
+ factory(root);
+ }
+})(typeof global != 'undefined' ? global : undefined, function (root) {
+
+ if (root.CSS && root.CSS.escape) {
+ return root.CSS.escape;
+ }
+
+ // https://drafts.csswg.org/cssom/#serialize-an-identifier
+ var cssEscape = function cssEscape(value) {
+ if (arguments.length == 0) {
+ throw new TypeError('`CSS.escape` requires an argument.');
+ }
+ var string = String(value);
+ var length = string.length;
+ var index = -1;
+ var codeUnit;
+ var result = '';
+ var firstCodeUnit = string.charCodeAt(0);
+ while (++index < length) {
+ codeUnit = string.charCodeAt(index);
+ // Note: there’s no need to special-case astral symbols, surrogate
+ // pairs, or lone surrogates.
+
+ // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
+ // (U+FFFD).
+ if (codeUnit == 0x0000) {
+ result += '\uFFFD';
+ continue;
+ }
+
+ if (
+ // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
+ // U+007F, […]
+ codeUnit >= 0x0001 && codeUnit <= 0x001F || codeUnit == 0x007F ||
+ // If the character is the first character and is in the range [0-9]
+ // (U+0030 to U+0039), […]
+ index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
+ // If the character is the second character and is in the range [0-9]
+ // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
+ index == 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && firstCodeUnit == 0x002D) {
+ // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
+ result += '\\' + codeUnit.toString(16) + ' ';
+ continue;
+ }
+
+ if (
+ // If the character is the first character and is a `-` (U+002D), and
+ // there is no second character, […]
+ index == 0 && length == 1 && codeUnit == 0x002D) {
+ result += '\\' + string.charAt(index);
+ continue;
+ }
+
+ // If the character is not handled by one of the above rules and is
+ // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
+ // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
+ // U+005A), or [a-z] (U+0061 to U+007A), […]
+ if (codeUnit >= 0x0080 || codeUnit == 0x002D || codeUnit == 0x005F || codeUnit >= 0x0030 && codeUnit <= 0x0039 || codeUnit >= 0x0041 && codeUnit <= 0x005A || codeUnit >= 0x0061 && codeUnit <= 0x007A) {
+ // the character itself
+ result += string.charAt(index);
+ continue;
+ }
+
+ // Otherwise, the escaped character.
+ // https://drafts.csswg.org/cssom/#escape-a-character
+ result += '\\' + string.charAt(index);
+ }
+ return result;
+ };
+
+ if (!root.CSS) {
+ root.CSS = {};
+ }
+
+ root.CSS.escape = cssEscape;
+ return cssEscape;
+});
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{}],238:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _interactionEvents = require('diagram-js/lib/features/interaction-events');
+
+var _interactionEvents2 = _interopRequireDefault(_interactionEvents);
+
+var _DirectEditing = require('./lib/DirectEditing');
+
+var _DirectEditing2 = _interopRequireDefault(_DirectEditing);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_interactionEvents2.default],
+ __init__: ['directEditing'],
+ directEditing: ['type', _DirectEditing2.default]
+};
+
+},{"./lib/DirectEditing":239,"diagram-js/lib/features/interaction-events":294}],239:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DirectEditing;
+
+var _minDash = require('min-dash');
+
+var _TextBox = require('./TextBox');
+
+var _TextBox2 = _interopRequireDefault(_TextBox);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A direct editing component that allows users
+ * to edit an elements text directly in the diagram
+ *
+ * @param {EventBus} eventBus the event bus
+ */
+function DirectEditing(eventBus, canvas) {
+
+ this._eventBus = eventBus;
+
+ this._providers = [];
+ this._textbox = new _TextBox2.default({
+ container: canvas.getContainer(),
+ keyHandler: (0, _minDash.bind)(this._handleKey, this),
+ resizeHandler: (0, _minDash.bind)(this._handleResize, this)
+ });
+}
+
+DirectEditing.$inject = ['eventBus', 'canvas'];
+
+/**
+ * Register a direct editing provider
+
+ * @param {Object} provider the provider, must expose an #activate(element) method that returns
+ * an activation context ({ bounds: {x, y, width, height }, text }) if
+ * direct editing is available for the given element.
+ * Additionally the provider must expose a #update(element, value) method
+ * to receive direct editing updates.
+ */
+DirectEditing.prototype.registerProvider = function (provider) {
+ this._providers.push(provider);
+};
+
+/**
+ * Returns true if direct editing is currently active
+ *
+ * @return {Boolean}
+ */
+DirectEditing.prototype.isActive = function () {
+ return !!this._active;
+};
+
+/**
+ * Cancel direct editing, if it is currently active
+ */
+DirectEditing.prototype.cancel = function () {
+ if (!this._active) {
+ return;
+ }
+
+ this._fire('cancel');
+ this.close();
+};
+
+DirectEditing.prototype._fire = function (event, context) {
+ this._eventBus.fire('directEditing.' + event, context || { active: this._active });
+};
+
+DirectEditing.prototype.close = function () {
+ this._textbox.destroy();
+
+ this._fire('deactivate');
+
+ this._active = null;
+
+ this.resizable = undefined;
+};
+
+DirectEditing.prototype.complete = function () {
+
+ var active = this._active;
+
+ if (!active) {
+ return;
+ }
+
+ var text = this.getValue();
+
+ var bounds = this.$textbox.getBoundingClientRect();
+
+ if (text !== active.context.text || this.resizable) {
+ active.provider.update(active.element, text, active.context.text, {
+ x: bounds.top,
+ y: bounds.left,
+ width: bounds.width,
+ height: bounds.height
+ });
+ }
+
+ this._fire('complete');
+
+ this.close();
+};
+
+DirectEditing.prototype.getValue = function () {
+ return this._textbox.getValue();
+};
+
+DirectEditing.prototype._handleKey = function (e) {
+
+ // stop bubble
+ e.stopPropagation();
+
+ var key = e.keyCode || e.charCode;
+
+ // ESC
+ if (key === 27) {
+ e.preventDefault();
+ return this.cancel();
+ }
+
+ // Enter
+ if (key === 13 && !e.shiftKey) {
+ e.preventDefault();
+ return this.complete();
+ }
+};
+
+DirectEditing.prototype._handleResize = function (event) {
+ this._fire('resize', event);
+};
+
+/**
+ * Activate direct editing on the given element
+ *
+ * @param {Object} ElementDescriptor the descriptor for a shape or connection
+ * @return {Boolean} true if the activation was possible
+ */
+DirectEditing.prototype.activate = function (element) {
+ if (this.isActive()) {
+ this.cancel();
+ }
+
+ // the direct editing context
+ var context;
+
+ var provider = (0, _minDash.find)(this._providers, function (p) {
+ return (context = p.activate(element)) ? p : null;
+ });
+
+ // check if activation took place
+ if (context) {
+ this.$textbox = this._textbox.create(context.bounds, context.style, context.text, context.options);
+
+ this._active = {
+ element: element,
+ context: context,
+ provider: provider
+ };
+
+ if (context.options && context.options.resizable) {
+ this.resizable = true;
+ }
+
+ this._fire('activate');
+ }
+
+ return !!context;
+};
+
+},{"./TextBox":240,"min-dash":505}],240:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = TextBox;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var min = Math.min,
+ max = Math.max;
+
+function preventDefault(e) {
+ e.preventDefault();
+}
+
+function stopPropagation(e) {
+ e.stopPropagation();
+}
+
+function isTextNode(node) {
+ return node.nodeType === Node.TEXT_NODE;
+}
+
+function toArray(nodeList) {
+ return [].slice.call(nodeList);
+}
+
+/**
+ * Initializes a container for a content editable div.
+ *
+ * Structure:
+ *
+ * container
+ * parent
+ * content
+ * resize-handle
+ *
+ * @param {object} options
+ * @param {DOMElement} options.container The DOM element to append the contentContainer to
+ * @param {Function} options.keyHandler Handler for key events
+ * @param {Function} options.resizeHandler Handler for resize events
+ */
+function TextBox(options) {
+ this.container = options.container;
+
+ this.parent = (0, _minDom.domify)('');
+
+ this.content = (0, _minDom.query)('[contenteditable]', this.parent);
+
+ this.keyHandler = options.keyHandler || function () {};
+ this.resizeHandler = options.resizeHandler || function () {};
+
+ this.autoResize = (0, _minDash.bind)(this.autoResize, this);
+ this.handlePaste = (0, _minDash.bind)(this.handlePaste, this);
+}
+
+/**
+ * Create a text box with the given position, size, style and text content
+ *
+ * @param {Object} bounds
+ * @param {Number} bounds.x absolute x position
+ * @param {Number} bounds.y absolute y position
+ * @param {Number} [bounds.width] fixed width value
+ * @param {Number} [bounds.height] fixed height value
+ * @param {Number} [bounds.maxWidth] maximum width value
+ * @param {Number} [bounds.maxHeight] maximum height value
+ * @param {Number} [bounds.minWidth] minimum width value
+ * @param {Number} [bounds.minHeight] minimum height value
+ * @param {Object} [style]
+ * @param {String} value text content
+ *
+ * @return {DOMElement} The created content DOM element
+ */
+TextBox.prototype.create = function (bounds, style, value, options) {
+ var self = this;
+
+ var parent = this.parent,
+ content = this.content,
+ container = this.container;
+
+ options = this.options = options || {};
+
+ style = this.style = style || {};
+
+ var parentStyle = (0, _minDash.pick)(style, ['width', 'height', 'maxWidth', 'maxHeight', 'minWidth', 'minHeight', 'left', 'top', 'backgroundColor', 'position', 'overflow', 'border', 'wordWrap', 'textAlign', 'outline', 'transform']);
+
+ (0, _minDash.assign)(parent.style, {
+ width: bounds.width + 'px',
+ height: bounds.height + 'px',
+ maxWidth: bounds.maxWidth + 'px',
+ maxHeight: bounds.maxHeight + 'px',
+ minWidth: bounds.minWidth + 'px',
+ minHeight: bounds.minHeight + 'px',
+ left: bounds.x + 'px',
+ top: bounds.y + 'px',
+ backgroundColor: '#ffffff',
+ position: 'absolute',
+ overflow: 'visible',
+ border: '1px solid #ccc',
+ boxSizing: 'border-box',
+ wordWrap: 'normal',
+ textAlign: 'center',
+ outline: 'none'
+ }, parentStyle);
+
+ var contentStyle = (0, _minDash.pick)(style, ['fontFamily', 'fontSize', 'fontWeight', 'lineHeight', 'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft']);
+
+ (0, _minDash.assign)(content.style, {
+ boxSizing: 'border-box',
+ width: '100%',
+ outline: 'none',
+ wordWrap: 'break-word'
+ }, contentStyle);
+
+ if (options.centerVertically) {
+ (0, _minDash.assign)(content.style, {
+ position: 'absolute',
+ top: '50%',
+ transform: 'translate(0, -50%)'
+ }, contentStyle);
+ }
+
+ content.innerText = value;
+
+ _minDom.event.bind(content, 'keydown', this.keyHandler);
+ _minDom.event.bind(content, 'mousedown', stopPropagation);
+ _minDom.event.bind(content, 'paste', self.handlePaste);
+
+ if (options.autoResize) {
+ _minDom.event.bind(content, 'input', this.autoResize);
+ }
+
+ if (options.resizable) {
+ this.resizable(style);
+ }
+
+ container.appendChild(parent);
+
+ // set selection to end of text
+ this.setSelection(content.lastChild, content.lastChild && content.lastChild.length);
+
+ return parent;
+};
+
+/**
+ * Intercept paste events to remove formatting from pasted text.
+ */
+TextBox.prototype.handlePaste = function (e) {
+ var self = this;
+
+ var options = this.options,
+ style = this.style;
+
+ e.preventDefault();
+
+ var text;
+
+ if (e.clipboardData) {
+
+ // Chrome, Firefox, Safari
+ text = e.clipboardData.getData('text/plain');
+ } else {
+
+ // Internet Explorer
+ text = window.clipboardData.getData('Text');
+ }
+
+ // insertHTML command not supported by Internet Explorer
+ var success = document.execCommand('insertHTML', false, text);
+
+ if (!success) {
+
+ // Internet Explorer
+ var range = this.getSelection(),
+ startContainer = range.startContainer,
+ endContainer = range.endContainer,
+ startOffset = range.startOffset,
+ endOffset = range.endOffset,
+ commonAncestorContainer = range.commonAncestorContainer;
+
+ var childNodesArray = toArray(commonAncestorContainer.childNodes);
+
+ var container, offset;
+
+ if (isTextNode(commonAncestorContainer)) {
+ var containerTextContent = startContainer.textContent;
+
+ startContainer.textContent = containerTextContent.substring(0, startOffset) + text + containerTextContent.substring(endOffset);
+
+ container = startContainer;
+ offset = startOffset + text.length;
+ } else if (startContainer === this.content && endContainer === this.content) {
+ var textNode = document.createTextNode(text);
+
+ this.content.insertBefore(textNode, childNodesArray[startOffset]);
+
+ container = textNode;
+ offset = textNode.textContent.length;
+ } else {
+ var startContainerChildIndex = childNodesArray.indexOf(startContainer),
+ endContainerChildIndex = childNodesArray.indexOf(endContainer);
+
+ childNodesArray.forEach(function (childNode, index) {
+
+ if (index === startContainerChildIndex) {
+ childNode.textContent = startContainer.textContent.substring(0, startOffset) + text + endContainer.textContent.substring(endOffset);
+ } else if (index > startContainerChildIndex && index <= endContainerChildIndex) {
+ (0, _minDom.remove)(childNode);
+ }
+ });
+
+ container = startContainer;
+ offset = startOffset + text.length;
+ }
+
+ if (container && offset !== undefined) {
+
+ // is necessary in Internet Explorer
+ setTimeout(function () {
+ self.setSelection(container, offset);
+ });
+ }
+ }
+
+ if (options.autoResize) {
+ var hasResized = this.autoResize(style);
+
+ if (hasResized) {
+ this.resizeHandler(hasResized);
+ }
+ }
+};
+
+/**
+ * Automatically resize element vertically to fit its content.
+ */
+TextBox.prototype.autoResize = function () {
+ var parent = this.parent,
+ content = this.content;
+
+ var fontSize = parseInt(this.style.fontSize) || 12;
+
+ if (content.scrollHeight > parent.offsetHeight || content.scrollHeight < parent.offsetHeight - fontSize) {
+ var bounds = parent.getBoundingClientRect();
+
+ var height = content.scrollHeight;
+ parent.style.height = height + 'px';
+
+ this.resizeHandler({
+ width: bounds.width,
+ height: bounds.height,
+ dx: 0,
+ dy: height - bounds.height
+ });
+ }
+};
+
+/**
+ * Make an element resizable by adding a resize handle.
+ */
+TextBox.prototype.resizable = function () {
+ var self = this;
+
+ var parent = this.parent,
+ resizeHandle = this.resizeHandle;
+
+ var minWidth = parseInt(this.style.minWidth) || 0,
+ minHeight = parseInt(this.style.minHeight) || 0,
+ maxWidth = parseInt(this.style.maxWidth) || Infinity,
+ maxHeight = parseInt(this.style.maxHeight) || Infinity;
+
+ if (!resizeHandle) {
+ resizeHandle = this.resizeHandle = (0, _minDom.domify)('
');
+
+ var startX, startY, startWidth, startHeight;
+
+ var onMouseDown = function onMouseDown(e) {
+ preventDefault(e);
+ stopPropagation(e);
+
+ startX = e.clientX;
+ startY = e.clientY;
+
+ var bounds = parent.getBoundingClientRect();
+
+ startWidth = bounds.width;
+ startHeight = bounds.height;
+
+ _minDom.event.bind(document, 'mousemove', onMouseMove);
+ _minDom.event.bind(document, 'mouseup', onMouseUp);
+ };
+
+ var onMouseMove = function onMouseMove(e) {
+ preventDefault(e);
+ stopPropagation(e);
+
+ var newWidth = min(max(startWidth + e.clientX - startX, minWidth), maxWidth);
+ var newHeight = min(max(startHeight + e.clientY - startY, minHeight), maxHeight);
+
+ parent.style.width = newWidth + 'px';
+ parent.style.height = newHeight + 'px';
+
+ self.resizeHandler({
+ width: startWidth,
+ height: startHeight,
+ dx: e.clientX - startX,
+ dy: e.clientY - startY
+ });
+ };
+
+ var onMouseUp = function onMouseUp(e) {
+ preventDefault(e);
+ stopPropagation(e);
+
+ _minDom.event.unbind(document, 'mousemove', onMouseMove, false);
+ _minDom.event.unbind(document, 'mouseup', onMouseUp, false);
+ };
+
+ _minDom.event.bind(resizeHandle, 'mousedown', onMouseDown);
+ }
+
+ (0, _minDash.assign)(resizeHandle.style, {
+ position: 'absolute',
+ bottom: '0px',
+ right: '0px',
+ cursor: 'nwse-resize',
+ width: '0',
+ height: '0',
+ borderTop: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid transparent',
+ borderRight: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid #ccc',
+ borderBottom: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid #ccc',
+ borderLeft: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid transparent'
+ });
+
+ parent.appendChild(resizeHandle);
+};
+
+/**
+ * Clear content and style of the textbox, unbind listeners and
+ * reset CSS style.
+ */
+TextBox.prototype.destroy = function () {
+ var parent = this.parent,
+ content = this.content,
+ resizeHandle = this.resizeHandle;
+
+ // clear content
+ content.innerText = '';
+
+ // clear styles
+ parent.removeAttribute('style');
+ content.removeAttribute('style');
+
+ _minDom.event.unbind(content, 'keydown', this.keyHandler);
+ _minDom.event.unbind(content, 'mousedown', stopPropagation);
+ _minDom.event.unbind(content, 'input', this.autoResize);
+ _minDom.event.unbind(content, 'paste', this.handlePaste);
+
+ if (resizeHandle) {
+ resizeHandle.removeAttribute('style');
+
+ (0, _minDom.remove)(resizeHandle);
+ }
+
+ (0, _minDom.remove)(parent);
+};
+
+TextBox.prototype.getValue = function () {
+ return this.content.innerText;
+};
+
+TextBox.prototype.getSelection = function () {
+ var selection = window.getSelection(),
+ range = selection.getRangeAt(0);
+
+ return range;
+};
+
+TextBox.prototype.setSelection = function (container, offset) {
+ var range = document.createRange();
+
+ if (container === null) {
+ range.selectNodeContents(this.content);
+ } else {
+ range.setStart(container, offset);
+ range.setEnd(container, offset);
+ }
+
+ var selection = window.getSelection();
+
+ selection.removeAllRanges();
+ selection.addRange(range);
+};
+
+},{"min-dash":505,"min-dom":506}],241:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _Diagram = require('./lib/Diagram');
+
+Object.defineProperty(exports, 'default', {
+ enumerable: true,
+ get: function get() {
+ return _interopRequireDefault(_Diagram).default;
+ }
+});
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+},{"./lib/Diagram":242}],242:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Diagram;
+
+var _didi = require('didi');
+
+var _core = require('./core');
+
+var _core2 = _interopRequireDefault(_core);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Bootstrap an injector from a list of modules, instantiating a number of default components
+ *
+ * @ignore
+ * @param {Array} bootstrapModules
+ *
+ * @return {didi.Injector} a injector to use to access the components
+ */
+function bootstrap(bootstrapModules) {
+
+ var modules = [],
+ components = [];
+
+ function hasModule(m) {
+ return modules.indexOf(m) >= 0;
+ }
+
+ function addModule(m) {
+ modules.push(m);
+ }
+
+ function visit(m) {
+ if (hasModule(m)) {
+ return;
+ }
+
+ (m.__depends__ || []).forEach(visit);
+
+ if (hasModule(m)) {
+ return;
+ }
+
+ addModule(m);
+
+ (m.__init__ || []).forEach(function (c) {
+ components.push(c);
+ });
+ }
+
+ bootstrapModules.forEach(visit);
+
+ var injector = new _didi.Injector(modules);
+
+ components.forEach(function (c) {
+
+ try {
+ // eagerly resolve component (fn or string)
+ injector[typeof c === 'string' ? 'get' : 'invoke'](c);
+ } catch (e) {
+ console.error('Failed to instantiate component');
+ console.error(e.stack);
+
+ throw e;
+ }
+ });
+
+ return injector;
+}
+
+/**
+ * Creates an injector from passed options.
+ *
+ * @ignore
+ * @param {Object} options
+ * @return {didi.Injector}
+ */
+function createInjector(options) {
+
+ options = options || {};
+
+ var configModule = {
+ 'config': ['value', options]
+ };
+
+ var modules = [configModule, _core2.default].concat(options.modules || []);
+
+ return bootstrap(modules);
+}
+
+/**
+ * The main diagram-js entry point that bootstraps the diagram with the given
+ * configuration.
+ *
+ * To register extensions with the diagram, pass them as Array to the constructor.
+ *
+ * @class djs.Diagram
+ * @memberOf djs
+ * @constructor
+ *
+ * @example
+ *
+ * Creating a plug-in that logs whenever a shape is added to the canvas.
+ *
+ * // plug-in implemenentation
+ * function MyLoggingPlugin(eventBus) {
+ * eventBus.on('shape.added', function(event) {
+ * console.log('shape ', event.shape, ' was added to the diagram');
+ * });
+ * }
+ *
+ * // export as module
+ * export default {
+ * __init__: [ 'myLoggingPlugin' ],
+ * myLoggingPlugin: [ 'type', MyLoggingPlugin ]
+ * };
+ *
+ *
+ * // instantiate the diagram with the new plug-in
+ *
+ * import MyLoggingModule from 'path-to-my-logging-plugin';
+ *
+ * var diagram = new Diagram({
+ * modules: [
+ * MyLoggingModule
+ * ]
+ * });
+ *
+ * diagram.invoke([ 'canvas', function(canvas) {
+ * // add shape to drawing canvas
+ * canvas.addShape({ x: 10, y: 10 });
+ * });
+ *
+ * // 'shape ... was added to the diagram' logged to console
+ *
+ * @param {Object} options
+ * @param {Array} [options.modules] external modules to instantiate with the diagram
+ * @param {didi.Injector} [injector] an (optional) injector to bootstrap the diagram with
+ */
+function Diagram(options, injector) {
+
+ // create injector unless explicitly specified
+ this.injector = injector = injector || createInjector(options);
+
+ // API
+
+ /**
+ * Resolves a diagram service
+ *
+ * @method Diagram#get
+ *
+ * @param {String} name the name of the diagram service to be retrieved
+ * @param {Boolean} [strict=true] if false, resolve missing services to null
+ */
+ this.get = injector.get;
+
+ /**
+ * Executes a function into which diagram services are injected
+ *
+ * @method Diagram#invoke
+ *
+ * @param {Function|Object[]} fn the function to resolve
+ * @param {Object} locals a number of locals to use to resolve certain dependencies
+ */
+ this.invoke = injector.invoke;
+
+ // init
+
+ // indicate via event
+
+
+ /**
+ * An event indicating that all plug-ins are loaded.
+ *
+ * Use this event to fire other events to interested plug-ins
+ *
+ * @memberOf Diagram
+ *
+ * @event diagram.init
+ *
+ * @example
+ *
+ * eventBus.on('diagram.init', function() {
+ * eventBus.fire('my-custom-event', { foo: 'BAR' });
+ * });
+ *
+ * @type {Object}
+ */
+ this.get('eventBus').fire('diagram.init');
+}
+
+/**
+ * Destroys the diagram
+ *
+ * @method Diagram#destroy
+ */
+Diagram.prototype.destroy = function () {
+ this.get('eventBus').fire('diagram.destroy');
+};
+
+/**
+ * Clear the diagram, removing all contents.
+ */
+Diagram.prototype.clear = function () {
+ this.get('eventBus').fire('diagram.clear');
+};
+
+},{"./core":251,"didi":410}],243:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CommandInterceptor;
+
+var _minDash = require('min-dash');
+
+var DEFAULT_PRIORITY = 1000;
+
+/**
+ * A utility that can be used to plug-in into the command execution for
+ * extension and/or validation.
+ *
+ * @param {EventBus} eventBus
+ *
+ * @example
+ *
+ * import inherits from 'inherits';
+ *
+ * import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
+ *
+ * function CommandLogger(eventBus) {
+ * CommandInterceptor.call(this, eventBus);
+ *
+ * this.preExecute(function(event) {
+ * console.log('command pre-execute', event);
+ * });
+ * }
+ *
+ * inherits(CommandLogger, CommandInterceptor);
+ *
+ */
+function CommandInterceptor(eventBus) {
+ this._eventBus = eventBus;
+}
+
+CommandInterceptor.$inject = ['eventBus'];
+
+function unwrapEvent(fn, that) {
+ return function (event) {
+ return fn.call(that || null, event.context, event.command, event);
+ };
+}
+
+/**
+ * Register an interceptor for a command execution
+ *
+ * @param {String|Array} [events] list of commands to register on
+ * @param {String} [hook] command hook, i.e. preExecute, executed to listen on
+ * @param {Number} [priority] the priority on which to hook into the execution
+ * @param {Function} handlerFn interceptor to be invoked with (event)
+ * @param {Boolean} unwrap if true, unwrap the event and pass (context, command, event) to the
+ * listener instead
+ * @param {Object} [that] Pass context (`this`) to the handler function
+ */
+CommandInterceptor.prototype.on = function (events, hook, priority, handlerFn, unwrap, that) {
+
+ if ((0, _minDash.isFunction)(hook) || (0, _minDash.isNumber)(hook)) {
+ that = unwrap;
+ unwrap = handlerFn;
+ handlerFn = priority;
+ priority = hook;
+ hook = null;
+ }
+
+ if ((0, _minDash.isFunction)(priority)) {
+ that = unwrap;
+ unwrap = handlerFn;
+ handlerFn = priority;
+ priority = DEFAULT_PRIORITY;
+ }
+
+ if ((0, _minDash.isObject)(unwrap)) {
+ that = unwrap;
+ unwrap = false;
+ }
+
+ if (!(0, _minDash.isFunction)(handlerFn)) {
+ throw new Error('handlerFn must be a function');
+ }
+
+ if (!(0, _minDash.isArray)(events)) {
+ events = [events];
+ }
+
+ var eventBus = this._eventBus;
+
+ (0, _minDash.forEach)(events, function (event) {
+ // concat commandStack(.event)?(.hook)?
+ var fullEvent = ['commandStack', event, hook].filter(function (e) {
+ return e;
+ }).join('.');
+
+ eventBus.on(fullEvent, priority, unwrap ? unwrapEvent(handlerFn, that) : handlerFn, that);
+ });
+};
+
+var hooks = ['canExecute', 'preExecute', 'preExecuted', 'execute', 'executed', 'postExecute', 'postExecuted', 'revert', 'reverted'];
+
+/*
+ * Install hook shortcuts
+ *
+ * This will generate the CommandInterceptor#(preExecute|...|reverted) methods
+ * which will in term forward to CommandInterceptor#on.
+ */
+(0, _minDash.forEach)(hooks, function (hook) {
+
+ /**
+ * {canExecute|preExecute|preExecuted|execute|executed|postExecute|postExecuted|revert|reverted}
+ *
+ * A named hook for plugging into the command execution
+ *
+ * @param {String|Array} [events] list of commands to register on
+ * @param {Number} [priority] the priority on which to hook into the execution
+ * @param {Function} handlerFn interceptor to be invoked with (event)
+ * @param {Boolean} [unwrap=false] if true, unwrap the event and pass (context, command, event) to the
+ * listener instead
+ * @param {Object} [that] Pass context (`this`) to the handler function
+ */
+ CommandInterceptor.prototype[hook] = function (events, priority, handlerFn, unwrap, that) {
+
+ if ((0, _minDash.isFunction)(events) || (0, _minDash.isNumber)(events)) {
+ that = unwrap;
+ unwrap = handlerFn;
+ handlerFn = priority;
+ priority = events;
+ events = null;
+ }
+
+ this.on(events, hook, priority, handlerFn, unwrap, that);
+ };
+});
+
+},{"min-dash":505}],244:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CommandStack;
+
+var _minDash = require('min-dash');
+
+/**
+ * A service that offers un- and redoable execution of commands.
+ *
+ * The command stack is responsible for executing modeling actions
+ * in a un- and redoable manner. To do this it delegates the actual
+ * command execution to {@link CommandHandler}s.
+ *
+ * Command handlers provide {@link CommandHandler#execute(ctx)} and
+ * {@link CommandHandler#revert(ctx)} methods to un- and redo a command
+ * identified by a command context.
+ *
+ *
+ * ## Life-Cycle events
+ *
+ * In the process the command stack fires a number of life-cycle events
+ * that other components to participate in the command execution.
+ *
+ * * preExecute
+ * * preExecuted
+ * * execute
+ * * executed
+ * * postExecute
+ * * postExecuted
+ * * revert
+ * * reverted
+ *
+ * A special event is used for validating, whether a command can be
+ * performed prior to its execution.
+ *
+ * * canExecute
+ *
+ * Each of the events is fired as `commandStack.{eventName}` and
+ * `commandStack.{commandName}.{eventName}`, respectively. This gives
+ * components fine grained control on where to hook into.
+ *
+ * The event object fired transports `command`, the name of the
+ * command and `context`, the command context.
+ *
+ *
+ * ## Creating Command Handlers
+ *
+ * Command handlers should provide the {@link CommandHandler#execute(ctx)}
+ * and {@link CommandHandler#revert(ctx)} methods to implement
+ * redoing and undoing of a command.
+ *
+ * A command handler _must_ ensure undo is performed properly in order
+ * not to break the undo chain. It must also return the shapes that
+ * got changed during the `execute` and `revert` operations.
+ *
+ * Command handlers may execute other modeling operations (and thus
+ * commands) in their `preExecute` and `postExecute` phases. The command
+ * stack will properly group all commands together into a logical unit
+ * that may be re- and undone atomically.
+ *
+ * Command handlers must not execute other commands from within their
+ * core implementation (`execute`, `revert`).
+ *
+ *
+ * ## Change Tracking
+ *
+ * During the execution of the CommandStack it will keep track of all
+ * elements that have been touched during the command's execution.
+ *
+ * At the end of the CommandStack execution it will notify interested
+ * components via an 'elements.changed' event with all the dirty
+ * elements.
+ *
+ * The event can be picked up by components that are interested in the fact
+ * that elements have been changed. One use case for this is updating
+ * their graphical representation after moving / resizing or deletion.
+ *
+ * @see CommandHandler
+ *
+ * @param {EventBus} eventBus
+ * @param {Injector} injector
+ */
+function CommandStack(eventBus, injector) {
+
+ /**
+ * A map of all registered command handlers.
+ *
+ * @type {Object}
+ */
+ this._handlerMap = {};
+
+ /**
+ * A stack containing all re/undoable actions on the diagram
+ *
+ * @type {Array}
+ */
+ this._stack = [];
+
+ /**
+ * The current index on the stack
+ *
+ * @type {Number}
+ */
+ this._stackIdx = -1;
+
+ /**
+ * Current active commandStack execution
+ *
+ * @type {Object}
+ */
+ this._currentExecution = {
+ actions: [],
+ dirty: []
+ };
+
+ this._injector = injector;
+ this._eventBus = eventBus;
+
+ this._uid = 1;
+
+ eventBus.on(['diagram.destroy', 'diagram.clear'], function () {
+ this.clear(false);
+ }, this);
+}
+
+CommandStack.$inject = ['eventBus', 'injector'];
+
+/**
+ * Execute a command
+ *
+ * @param {String} command the command to execute
+ * @param {Object} context the environment to execute the command in
+ */
+CommandStack.prototype.execute = function (command, context) {
+ if (!command) {
+ throw new Error('command required');
+ }
+
+ var action = { command: command, context: context };
+
+ this._pushAction(action);
+ this._internalExecute(action);
+ this._popAction(action);
+};
+
+/**
+ * Ask whether a given command can be executed.
+ *
+ * Implementors may hook into the mechanism on two ways:
+ *
+ * * in event listeners:
+ *
+ * Users may prevent the execution via an event listener.
+ * It must prevent the default action for `commandStack.(.)canExecute` events.
+ *
+ * * in command handlers:
+ *
+ * If the method {@link CommandHandler#canExecute} is implemented in a handler
+ * it will be called to figure out whether the execution is allowed.
+ *
+ * @param {String} command the command to execute
+ * @param {Object} context the environment to execute the command in
+ *
+ * @return {Boolean} true if the command can be executed
+ */
+CommandStack.prototype.canExecute = function (command, context) {
+
+ var action = { command: command, context: context };
+
+ var handler = this._getHandler(command);
+
+ var result = this._fire(command, 'canExecute', action);
+
+ // handler#canExecute will only be called if no listener
+ // decided on a result already
+ if (result === undefined) {
+ if (!handler) {
+ return false;
+ }
+
+ if (handler.canExecute) {
+ result = handler.canExecute(context);
+ }
+ }
+
+ return result;
+};
+
+/**
+ * Clear the command stack, erasing all undo / redo history
+ */
+CommandStack.prototype.clear = function (emit) {
+ this._stack.length = 0;
+ this._stackIdx = -1;
+
+ if (emit !== false) {
+ this._fire('changed');
+ }
+};
+
+/**
+ * Undo last command(s)
+ */
+CommandStack.prototype.undo = function () {
+ var action = this._getUndoAction(),
+ next;
+
+ if (action) {
+ this._pushAction(action);
+
+ while (action) {
+ this._internalUndo(action);
+ next = this._getUndoAction();
+
+ if (!next || next.id !== action.id) {
+ break;
+ }
+
+ action = next;
+ }
+
+ this._popAction();
+ }
+};
+
+/**
+ * Redo last command(s)
+ */
+CommandStack.prototype.redo = function () {
+ var action = this._getRedoAction(),
+ next;
+
+ if (action) {
+ this._pushAction(action);
+
+ while (action) {
+ this._internalExecute(action, true);
+ next = this._getRedoAction();
+
+ if (!next || next.id !== action.id) {
+ break;
+ }
+
+ action = next;
+ }
+
+ this._popAction();
+ }
+};
+
+/**
+ * Register a handler instance with the command stack
+ *
+ * @param {String} command
+ * @param {CommandHandler} handler
+ */
+CommandStack.prototype.register = function (command, handler) {
+ this._setHandler(command, handler);
+};
+
+/**
+ * Register a handler type with the command stack
+ * by instantiating it and injecting its dependencies.
+ *
+ * @param {String} command
+ * @param {Function} a constructor for a {@link CommandHandler}
+ */
+CommandStack.prototype.registerHandler = function (command, handlerCls) {
+
+ if (!command || !handlerCls) {
+ throw new Error('command and handlerCls must be defined');
+ }
+
+ var handler = this._injector.instantiate(handlerCls);
+ this.register(command, handler);
+};
+
+CommandStack.prototype.canUndo = function () {
+ return !!this._getUndoAction();
+};
+
+CommandStack.prototype.canRedo = function () {
+ return !!this._getRedoAction();
+};
+
+// stack access //////////////////////
+
+CommandStack.prototype._getRedoAction = function () {
+ return this._stack[this._stackIdx + 1];
+};
+
+CommandStack.prototype._getUndoAction = function () {
+ return this._stack[this._stackIdx];
+};
+
+// internal functionality //////////////////////
+
+CommandStack.prototype._internalUndo = function (action) {
+ var self = this;
+
+ var command = action.command,
+ context = action.context;
+
+ var handler = this._getHandler(command);
+
+ // guard against illegal nested command stack invocations
+ this._atomicDo(function () {
+ self._fire(command, 'revert', action);
+
+ if (handler.revert) {
+ self._markDirty(handler.revert(context));
+ }
+
+ self._revertedAction(action);
+
+ self._fire(command, 'reverted', action);
+ });
+};
+
+CommandStack.prototype._fire = function (command, qualifier, event) {
+ if (arguments.length < 3) {
+ event = qualifier;
+ qualifier = null;
+ }
+
+ var names = qualifier ? [command + '.' + qualifier, qualifier] : [command],
+ i,
+ name,
+ result;
+
+ event = this._eventBus.createEvent(event);
+
+ for (i = 0; name = names[i]; i++) {
+ result = this._eventBus.fire('commandStack.' + name, event);
+
+ if (event.cancelBubble) {
+ break;
+ }
+ }
+
+ return result;
+};
+
+CommandStack.prototype._createId = function () {
+ return this._uid++;
+};
+
+CommandStack.prototype._atomicDo = function (fn) {
+
+ var execution = this._currentExecution;
+
+ execution.atomic = true;
+
+ try {
+ fn();
+ } finally {
+ execution.atomic = false;
+ }
+};
+
+CommandStack.prototype._internalExecute = function (action, redo) {
+ var self = this;
+
+ var command = action.command,
+ context = action.context;
+
+ var handler = this._getHandler(command);
+
+ if (!handler) {
+ throw new Error('no command handler registered for <' + command + '>');
+ }
+
+ this._pushAction(action);
+
+ if (!redo) {
+ this._fire(command, 'preExecute', action);
+
+ if (handler.preExecute) {
+ handler.preExecute(context);
+ }
+
+ this._fire(command, 'preExecuted', action);
+ }
+
+ // guard against illegal nested command stack invocations
+ this._atomicDo(function () {
+
+ self._fire(command, 'execute', action);
+
+ if (handler.execute) {
+ // actual execute + mark return results as dirty
+ self._markDirty(handler.execute(context));
+ }
+
+ // log to stack
+ self._executedAction(action, redo);
+
+ self._fire(command, 'executed', action);
+ });
+
+ if (!redo) {
+ this._fire(command, 'postExecute', action);
+
+ if (handler.postExecute) {
+ handler.postExecute(context);
+ }
+
+ this._fire(command, 'postExecuted', action);
+ }
+
+ this._popAction(action);
+};
+
+CommandStack.prototype._pushAction = function (action) {
+
+ var execution = this._currentExecution,
+ actions = execution.actions;
+
+ var baseAction = actions[0];
+
+ if (execution.atomic) {
+ throw new Error('illegal invocation in or phase (action: ' + action.command + ')');
+ }
+
+ if (!action.id) {
+ action.id = baseAction && baseAction.id || this._createId();
+ }
+
+ actions.push(action);
+};
+
+CommandStack.prototype._popAction = function () {
+ var execution = this._currentExecution,
+ actions = execution.actions,
+ dirty = execution.dirty;
+
+ actions.pop();
+
+ if (!actions.length) {
+ this._eventBus.fire('elements.changed', { elements: (0, _minDash.uniqueBy)('id', dirty) });
+
+ dirty.length = 0;
+
+ this._fire('changed');
+ }
+};
+
+CommandStack.prototype._markDirty = function (elements) {
+ var execution = this._currentExecution;
+
+ if (!elements) {
+ return;
+ }
+
+ elements = (0, _minDash.isArray)(elements) ? elements : [elements];
+
+ execution.dirty = execution.dirty.concat(elements);
+};
+
+CommandStack.prototype._executedAction = function (action, redo) {
+ var stackIdx = ++this._stackIdx;
+
+ if (!redo) {
+ this._stack.splice(stackIdx, this._stack.length, action);
+ }
+};
+
+CommandStack.prototype._revertedAction = function (action) {
+ this._stackIdx--;
+};
+
+CommandStack.prototype._getHandler = function (command) {
+ return this._handlerMap[command];
+};
+
+CommandStack.prototype._setHandler = function (command, handler) {
+ if (!command || !handler) {
+ throw new Error('command and handler required');
+ }
+
+ if (this._handlerMap[command]) {
+ throw new Error('overriding handler for command <' + command + '>');
+ }
+
+ this._handlerMap[command] = handler;
+};
+
+},{"min-dash":505}],245:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _CommandStack = require('./CommandStack');
+
+var _CommandStack2 = _interopRequireDefault(_CommandStack);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ commandStack: ['type', _CommandStack2.default]
+};
+
+},{"./CommandStack":244}],246:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+exports.default = Canvas;
+
+var _minDash = require('min-dash');
+
+var _Collections = require('../util/Collections');
+
+var _Elements = require('../util/Elements');
+
+var _tinySvg = require('tiny-svg');
+
+function round(number, resolution) {
+ return Math.round(number * resolution) / resolution;
+}
+
+function ensurePx(number) {
+ return (0, _minDash.isNumber)(number) ? number + 'px' : number;
+}
+
+/**
+ * Creates a HTML container element for a SVG element with
+ * the given configuration
+ *
+ * @param {Object} options
+ * @return {HTMLElement} the container element
+ */
+function createContainer(options) {
+
+ options = (0, _minDash.assign)({}, { width: '100%', height: '100%' }, options);
+
+ var container = options.container || document.body;
+
+ // create a around the svg element with the respective size
+ // this way we can always get the correct container size
+ // (this is impossible for
elements at the moment)
+ var parent = document.createElement('div');
+ parent.setAttribute('class', 'djs-container');
+
+ (0, _minDash.assign)(parent.style, {
+ position: 'relative',
+ overflow: 'hidden',
+ width: ensurePx(options.width),
+ height: ensurePx(options.height)
+ });
+
+ container.appendChild(parent);
+
+ return parent;
+}
+
+function createGroup(parent, cls, childIndex) {
+ var group = (0, _tinySvg.create)('g');
+ (0, _tinySvg.classes)(group).add(cls);
+
+ var index = childIndex !== undefined ? childIndex : parent.childNodes.length - 1;
+
+ // must ensure second argument is node or _null_
+ // cf. https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore
+ parent.insertBefore(group, parent.childNodes[index] || null);
+
+ return group;
+}
+
+var BASE_LAYER = 'base';
+
+var REQUIRED_MODEL_ATTRS = {
+ shape: ['x', 'y', 'width', 'height'],
+ connection: ['waypoints']
+};
+
+/**
+ * The main drawing canvas.
+ *
+ * @class
+ * @constructor
+ *
+ * @emits Canvas#canvas.init
+ *
+ * @param {Object} config
+ * @param {EventBus} eventBus
+ * @param {GraphicsFactory} graphicsFactory
+ * @param {ElementRegistry} elementRegistry
+ */
+function Canvas(config, eventBus, graphicsFactory, elementRegistry) {
+
+ this._eventBus = eventBus;
+ this._elementRegistry = elementRegistry;
+ this._graphicsFactory = graphicsFactory;
+
+ this._init(config || {});
+}
+
+Canvas.$inject = ['config.canvas', 'eventBus', 'graphicsFactory', 'elementRegistry'];
+
+Canvas.prototype._init = function (config) {
+
+ var eventBus = this._eventBus;
+
+ // Creates a element that is wrapped into a .
+ // This way we are always able to correctly figure out the size of the svg element
+ // by querying the parent node.
+ //
+ // (It is not possible to get the size of a svg element cross browser @ 2014-04-01)
+ //
+ //
+ //
+ // ...
+ //
+ //
+
+ // html container
+ var container = this._container = createContainer(config);
+
+ var svg = this._svg = (0, _tinySvg.create)('svg');
+ (0, _tinySvg.attr)(svg, { width: '100%', height: '100%' });
+
+ (0, _tinySvg.append)(container, svg);
+
+ var viewport = this._viewport = createGroup(svg, 'viewport');
+
+ this._layers = {};
+
+ // debounce canvas.viewbox.changed events
+ // for smoother diagram interaction
+ if (config.deferUpdate !== false) {
+ this._viewboxChanged = (0, _minDash.debounce)((0, _minDash.bind)(this._viewboxChanged, this), 300);
+ }
+
+ eventBus.on('diagram.init', function () {
+
+ /**
+ * An event indicating that the canvas is ready to be drawn on.
+ *
+ * @memberOf Canvas
+ *
+ * @event canvas.init
+ *
+ * @type {Object}
+ * @property {SVGElement} svg the created svg element
+ * @property {SVGElement} viewport the direct parent of diagram elements and shapes
+ */
+ eventBus.fire('canvas.init', {
+ svg: svg,
+ viewport: viewport
+ });
+ }, this);
+
+ // reset viewbox on shape changes to
+ // recompute the viewbox
+ eventBus.on(['shape.added', 'connection.added', 'shape.removed', 'connection.removed', 'elements.changed'], function () {
+ delete this._cachedViewbox;
+ }, this);
+
+ eventBus.on('diagram.destroy', 500, this._destroy, this);
+ eventBus.on('diagram.clear', 500, this._clear, this);
+};
+
+Canvas.prototype._destroy = function (emit) {
+ this._eventBus.fire('canvas.destroy', {
+ svg: this._svg,
+ viewport: this._viewport
+ });
+
+ var parent = this._container.parentNode;
+
+ if (parent) {
+ parent.removeChild(this._container);
+ }
+
+ delete this._svg;
+ delete this._container;
+ delete this._layers;
+ delete this._rootElement;
+ delete this._viewport;
+};
+
+Canvas.prototype._clear = function () {
+
+ var self = this;
+
+ var allElements = this._elementRegistry.getAll();
+
+ // remove all elements
+ allElements.forEach(function (element) {
+ var type = (0, _Elements.getType)(element);
+
+ if (type === 'root') {
+ self.setRootElement(null, true);
+ } else {
+ self._removeElement(element, type);
+ }
+ });
+
+ // force recomputation of view box
+ delete this._cachedViewbox;
+};
+
+/**
+ * Returns the default layer on which
+ * all elements are drawn.
+ *
+ * @returns {SVGElement}
+ */
+Canvas.prototype.getDefaultLayer = function () {
+ return this.getLayer(BASE_LAYER, 0);
+};
+
+/**
+ * Returns a layer that is used to draw elements
+ * or annotations on it.
+ *
+ * Non-existing layers retrieved through this method
+ * will be created. During creation, the optional index
+ * may be used to create layers below or above existing layers.
+ * A layer with a certain index is always created above all
+ * existing layers with the same index.
+ *
+ * @param {String} name
+ * @param {Number} index
+ *
+ * @returns {SVGElement}
+ */
+Canvas.prototype.getLayer = function (name, index) {
+
+ if (!name) {
+ throw new Error('must specify a name');
+ }
+
+ var layer = this._layers[name];
+
+ if (!layer) {
+ layer = this._layers[name] = this._createLayer(name, index);
+ }
+
+ // throw an error if layer creation / retrival is
+ // requested on different index
+ if (typeof index !== 'undefined' && layer.index !== index) {
+ throw new Error('layer <' + name + '> already created at index <' + index + '>');
+ }
+
+ return layer.group;
+};
+
+/**
+ * Creates a given layer and returns it.
+ *
+ * @param {String} name
+ * @param {Number} [index=0]
+ *
+ * @return {Object} layer descriptor with { index, group: SVGGroup }
+ */
+Canvas.prototype._createLayer = function (name, index) {
+
+ if (!index) {
+ index = 0;
+ }
+
+ var childIndex = (0, _minDash.reduce)(this._layers, function (childIndex, layer) {
+ if (index >= layer.index) {
+ childIndex++;
+ }
+
+ return childIndex;
+ }, 0);
+
+ return {
+ group: createGroup(this._viewport, 'layer-' + name, childIndex),
+ index: index
+ };
+};
+
+/**
+ * Returns the html element that encloses the
+ * drawing canvas.
+ *
+ * @return {DOMNode}
+ */
+Canvas.prototype.getContainer = function () {
+ return this._container;
+};
+
+// markers //////////////////////
+
+Canvas.prototype._updateMarker = function (element, marker, add) {
+ var container;
+
+ if (!element.id) {
+ element = this._elementRegistry.get(element);
+ }
+
+ // we need to access all
+ container = this._elementRegistry._elements[element.id];
+
+ if (!container) {
+ return;
+ }
+
+ (0, _minDash.forEach)([container.gfx, container.secondaryGfx], function (gfx) {
+ if (gfx) {
+ // invoke either addClass or removeClass based on mode
+ if (add) {
+ (0, _tinySvg.classes)(gfx).add(marker);
+ } else {
+ (0, _tinySvg.classes)(gfx).remove(marker);
+ }
+ }
+ });
+
+ /**
+ * An event indicating that a marker has been updated for an element
+ *
+ * @event element.marker.update
+ * @type {Object}
+ * @property {djs.model.Element} element the shape
+ * @property {Object} gfx the graphical representation of the shape
+ * @property {String} marker
+ * @property {Boolean} add true if the marker was added, false if it got removed
+ */
+ this._eventBus.fire('element.marker.update', { element: element, gfx: container.gfx, marker: marker, add: !!add });
+};
+
+/**
+ * Adds a marker to an element (basically a css class).
+ *
+ * Fires the element.marker.update event, making it possible to
+ * integrate extension into the marker life-cycle, too.
+ *
+ * @example
+ * canvas.addMarker('foo', 'some-marker');
+ *
+ * var fooGfx = canvas.getGraphics('foo');
+ *
+ * fooGfx; //
...
+ *
+ * @param {String|djs.model.Base} element
+ * @param {String} marker
+ */
+Canvas.prototype.addMarker = function (element, marker) {
+ this._updateMarker(element, marker, true);
+};
+
+/**
+ * Remove a marker from an element.
+ *
+ * Fires the element.marker.update event, making it possible to
+ * integrate extension into the marker life-cycle, too.
+ *
+ * @param {String|djs.model.Base} element
+ * @param {String} marker
+ */
+Canvas.prototype.removeMarker = function (element, marker) {
+ this._updateMarker(element, marker, false);
+};
+
+/**
+ * Check the existence of a marker on element.
+ *
+ * @param {String|djs.model.Base} element
+ * @param {String} marker
+ */
+Canvas.prototype.hasMarker = function (element, marker) {
+ if (!element.id) {
+ element = this._elementRegistry.get(element);
+ }
+
+ var gfx = this.getGraphics(element);
+
+ return (0, _tinySvg.classes)(gfx).has(marker);
+};
+
+/**
+ * Toggles a marker on an element.
+ *
+ * Fires the element.marker.update event, making it possible to
+ * integrate extension into the marker life-cycle, too.
+ *
+ * @param {String|djs.model.Base} element
+ * @param {String} marker
+ */
+Canvas.prototype.toggleMarker = function (element, marker) {
+ if (this.hasMarker(element, marker)) {
+ this.removeMarker(element, marker);
+ } else {
+ this.addMarker(element, marker);
+ }
+};
+
+Canvas.prototype.getRootElement = function () {
+ if (!this._rootElement) {
+ this.setRootElement({ id: '__implicitroot', children: [] });
+ }
+
+ return this._rootElement;
+};
+
+// root element handling //////////////////////
+
+/**
+ * Sets a given element as the new root element for the canvas
+ * and returns the new root element.
+ *
+ * @param {Object|djs.model.Root} element
+ * @param {Boolean} [override] whether to override the current root element, if any
+ *
+ * @return {Object|djs.model.Root} new root element
+ */
+Canvas.prototype.setRootElement = function (element, override) {
+
+ if (element) {
+ this._ensureValid('root', element);
+ }
+
+ var currentRoot = this._rootElement,
+ elementRegistry = this._elementRegistry,
+ eventBus = this._eventBus;
+
+ if (currentRoot) {
+ if (!override) {
+ throw new Error('rootElement already set, need to specify override');
+ }
+
+ // simulate element remove event sequence
+ eventBus.fire('root.remove', { element: currentRoot });
+ eventBus.fire('root.removed', { element: currentRoot });
+
+ elementRegistry.remove(currentRoot);
+ }
+
+ if (element) {
+ var gfx = this.getDefaultLayer();
+
+ // resemble element add event sequence
+ eventBus.fire('root.add', { element: element });
+
+ elementRegistry.add(element, gfx, this._svg);
+
+ eventBus.fire('root.added', { element: element, gfx: gfx });
+ }
+
+ this._rootElement = element;
+
+ return element;
+};
+
+// add functionality //////////////////////
+
+Canvas.prototype._ensureValid = function (type, element) {
+ if (!element.id) {
+ throw new Error('element must have an id');
+ }
+
+ if (this._elementRegistry.get(element.id)) {
+ throw new Error('element with id ' + element.id + ' already exists');
+ }
+
+ var requiredAttrs = REQUIRED_MODEL_ATTRS[type];
+
+ var valid = (0, _minDash.every)(requiredAttrs, function (attr) {
+ return typeof element[attr] !== 'undefined';
+ });
+
+ if (!valid) {
+ throw new Error('must supply { ' + requiredAttrs.join(', ') + ' } with ' + type);
+ }
+};
+
+Canvas.prototype._setParent = function (element, parent, parentIndex) {
+ (0, _Collections.add)(parent.children, element, parentIndex);
+ element.parent = parent;
+};
+
+/**
+ * Adds an element to the canvas.
+ *
+ * This wires the parent <-> child relationship between the element and
+ * a explicitly specified parent or an implicit root element.
+ *
+ * During add it emits the events
+ *
+ * * <{type}.add> (element, parent)
+ * * <{type}.added> (element, gfx)
+ *
+ * Extensions may hook into these events to perform their magic.
+ *
+ * @param {String} type
+ * @param {Object|djs.model.Base} element
+ * @param {Object|djs.model.Base} [parent]
+ * @param {Number} [parentIndex]
+ *
+ * @return {Object|djs.model.Base} the added element
+ */
+Canvas.prototype._addElement = function (type, element, parent, parentIndex) {
+
+ parent = parent || this.getRootElement();
+
+ var eventBus = this._eventBus,
+ graphicsFactory = this._graphicsFactory;
+
+ this._ensureValid(type, element);
+
+ eventBus.fire(type + '.add', { element: element, parent: parent });
+
+ this._setParent(element, parent, parentIndex);
+
+ // create graphics
+ var gfx = graphicsFactory.create(type, element, parentIndex);
+
+ this._elementRegistry.add(element, gfx);
+
+ // update its visual
+ graphicsFactory.update(type, element, gfx);
+
+ eventBus.fire(type + '.added', { element: element, gfx: gfx });
+
+ return element;
+};
+
+/**
+ * Adds a shape to the canvas
+ *
+ * @param {Object|djs.model.Shape} shape to add to the diagram
+ * @param {djs.model.Base} [parent]
+ * @param {Number} [parentIndex]
+ *
+ * @return {djs.model.Shape} the added shape
+ */
+Canvas.prototype.addShape = function (shape, parent, parentIndex) {
+ return this._addElement('shape', shape, parent, parentIndex);
+};
+
+/**
+ * Adds a connection to the canvas
+ *
+ * @param {Object|djs.model.Connection} connection to add to the diagram
+ * @param {djs.model.Base} [parent]
+ * @param {Number} [parentIndex]
+ *
+ * @return {djs.model.Connection} the added connection
+ */
+Canvas.prototype.addConnection = function (connection, parent, parentIndex) {
+ return this._addElement('connection', connection, parent, parentIndex);
+};
+
+/**
+ * Internal remove element
+ */
+Canvas.prototype._removeElement = function (element, type) {
+
+ var elementRegistry = this._elementRegistry,
+ graphicsFactory = this._graphicsFactory,
+ eventBus = this._eventBus;
+
+ element = elementRegistry.get(element.id || element);
+
+ if (!element) {
+ // element was removed already
+ return;
+ }
+
+ eventBus.fire(type + '.remove', { element: element });
+
+ graphicsFactory.remove(element);
+
+ // unset parent <-> child relationship
+ (0, _Collections.remove)(element.parent && element.parent.children, element);
+ element.parent = null;
+
+ eventBus.fire(type + '.removed', { element: element });
+
+ elementRegistry.remove(element);
+
+ return element;
+};
+
+/**
+ * Removes a shape from the canvas
+ *
+ * @param {String|djs.model.Shape} shape or shape id to be removed
+ *
+ * @return {djs.model.Shape} the removed shape
+ */
+Canvas.prototype.removeShape = function (shape) {
+
+ /**
+ * An event indicating that a shape is about to be removed from the canvas.
+ *
+ * @memberOf Canvas
+ *
+ * @event shape.remove
+ * @type {Object}
+ * @property {djs.model.Shape} element the shape descriptor
+ * @property {Object} gfx the graphical representation of the shape
+ */
+
+ /**
+ * An event indicating that a shape has been removed from the canvas.
+ *
+ * @memberOf Canvas
+ *
+ * @event shape.removed
+ * @type {Object}
+ * @property {djs.model.Shape} element the shape descriptor
+ * @property {Object} gfx the graphical representation of the shape
+ */
+ return this._removeElement(shape, 'shape');
+};
+
+/**
+ * Removes a connection from the canvas
+ *
+ * @param {String|djs.model.Connection} connection or connection id to be removed
+ *
+ * @return {djs.model.Connection} the removed connection
+ */
+Canvas.prototype.removeConnection = function (connection) {
+
+ /**
+ * An event indicating that a connection is about to be removed from the canvas.
+ *
+ * @memberOf Canvas
+ *
+ * @event connection.remove
+ * @type {Object}
+ * @property {djs.model.Connection} element the connection descriptor
+ * @property {Object} gfx the graphical representation of the connection
+ */
+
+ /**
+ * An event indicating that a connection has been removed from the canvas.
+ *
+ * @memberOf Canvas
+ *
+ * @event connection.removed
+ * @type {Object}
+ * @property {djs.model.Connection} element the connection descriptor
+ * @property {Object} gfx the graphical representation of the connection
+ */
+ return this._removeElement(connection, 'connection');
+};
+
+/**
+ * Return the graphical object underlaying a certain diagram element
+ *
+ * @param {String|djs.model.Base} element descriptor of the element
+ * @param {Boolean} [secondary=false] whether to return the secondary connected element
+ *
+ * @return {SVGElement}
+ */
+Canvas.prototype.getGraphics = function (element, secondary) {
+ return this._elementRegistry.getGraphics(element, secondary);
+};
+
+/**
+ * Perform a viewbox update via a given change function.
+ *
+ * @param {Function} changeFn
+ */
+Canvas.prototype._changeViewbox = function (changeFn) {
+
+ // notify others of the upcoming viewbox change
+ this._eventBus.fire('canvas.viewbox.changing');
+
+ // perform actual change
+ changeFn.apply(this);
+
+ // reset the cached viewbox so that
+ // a new get operation on viewbox or zoom
+ // triggers a viewbox re-computation
+ this._cachedViewbox = null;
+
+ // notify others of the change; this step
+ // may or may not be debounced
+ this._viewboxChanged();
+};
+
+Canvas.prototype._viewboxChanged = function () {
+ this._eventBus.fire('canvas.viewbox.changed', { viewbox: this.viewbox() });
+};
+
+/**
+ * Gets or sets the view box of the canvas, i.e. the
+ * area that is currently displayed.
+ *
+ * The getter may return a cached viewbox (if it is currently
+ * changing). To force a recomputation, pass `false` as the first argument.
+ *
+ * @example
+ *
+ * canvas.viewbox({ x: 100, y: 100, width: 500, height: 500 })
+ *
+ * // sets the visible area of the diagram to (100|100) -> (600|100)
+ * // and and scales it according to the diagram width
+ *
+ * var viewbox = canvas.viewbox(); // pass `false` to force recomputing the box.
+ *
+ * console.log(viewbox);
+ * // {
+ * // inner: Dimensions,
+ * // outer: Dimensions,
+ * // scale,
+ * // x, y,
+ * // width, height
+ * // }
+ *
+ * // if the current diagram is zoomed and scrolled, you may reset it to the
+ * // default zoom via this method, too:
+ *
+ * var zoomedAndScrolledViewbox = canvas.viewbox();
+ *
+ * canvas.viewbox({
+ * x: 0,
+ * y: 0,
+ * width: zoomedAndScrolledViewbox.outer.width,
+ * height: zoomedAndScrolledViewbox.outer.height
+ * });
+ *
+ * @param {Object} [box] the new view box to set
+ * @param {Number} box.x the top left X coordinate of the canvas visible in view box
+ * @param {Number} box.y the top left Y coordinate of the canvas visible in view box
+ * @param {Number} box.width the visible width
+ * @param {Number} box.height
+ *
+ * @return {Object} the current view box
+ */
+Canvas.prototype.viewbox = function (box) {
+
+ if (box === undefined && this._cachedViewbox) {
+ return this._cachedViewbox;
+ }
+
+ var viewport = this._viewport,
+ innerBox,
+ outerBox = this.getSize(),
+ matrix,
+ transform,
+ scale,
+ x,
+ y;
+
+ if (!box) {
+ // compute the inner box based on the
+ // diagrams default layer. This allows us to exclude
+ // external components, such as overlays
+ innerBox = this.getDefaultLayer().getBBox();
+
+ transform = (0, _tinySvg.transform)(viewport);
+ matrix = transform ? transform.matrix : (0, _tinySvg.createMatrix)();
+ scale = round(matrix.a, 1000);
+
+ x = round(-matrix.e || 0, 1000);
+ y = round(-matrix.f || 0, 1000);
+
+ box = this._cachedViewbox = {
+ x: x ? x / scale : 0,
+ y: y ? y / scale : 0,
+ width: outerBox.width / scale,
+ height: outerBox.height / scale,
+ scale: scale,
+ inner: {
+ width: innerBox.width,
+ height: innerBox.height,
+ x: innerBox.x,
+ y: innerBox.y
+ },
+ outer: outerBox
+ };
+
+ return box;
+ } else {
+
+ this._changeViewbox(function () {
+ scale = Math.min(outerBox.width / box.width, outerBox.height / box.height);
+
+ var matrix = this._svg.createSVGMatrix().scale(scale).translate(-box.x, -box.y);
+
+ (0, _tinySvg.transform)(viewport, matrix);
+ });
+ }
+
+ return box;
+};
+
+/**
+ * Gets or sets the scroll of the canvas.
+ *
+ * @param {Object} [delta] the new scroll to apply.
+ *
+ * @param {Number} [delta.dx]
+ * @param {Number} [delta.dy]
+ */
+Canvas.prototype.scroll = function (delta) {
+
+ var node = this._viewport;
+ var matrix = node.getCTM();
+
+ if (delta) {
+ this._changeViewbox(function () {
+ delta = (0, _minDash.assign)({ dx: 0, dy: 0 }, delta || {});
+
+ matrix = this._svg.createSVGMatrix().translate(delta.dx, delta.dy).multiply(matrix);
+
+ setCTM(node, matrix);
+ });
+ }
+
+ return { x: matrix.e, y: matrix.f };
+};
+
+/**
+ * Gets or sets the current zoom of the canvas, optionally zooming
+ * to the specified position.
+ *
+ * The getter may return a cached zoom level. Call it with `false` as
+ * the first argument to force recomputation of the current level.
+ *
+ * @param {String|Number} [newScale] the new zoom level, either a number, i.e. 0.9,
+ * or `fit-viewport` to adjust the size to fit the current viewport
+ * @param {String|Point} [center] the reference point { x: .., y: ..} to zoom to, 'auto' to zoom into mid or null
+ *
+ * @return {Number} the current scale
+ */
+Canvas.prototype.zoom = function (newScale, center) {
+
+ if (!newScale) {
+ return this.viewbox(newScale).scale;
+ }
+
+ if (newScale === 'fit-viewport') {
+ return this._fitViewport(center);
+ }
+
+ var outer, matrix;
+
+ this._changeViewbox(function () {
+
+ if ((typeof center === 'undefined' ? 'undefined' : _typeof(center)) !== 'object') {
+ outer = this.viewbox().outer;
+
+ center = {
+ x: outer.width / 2,
+ y: outer.height / 2
+ };
+ }
+
+ matrix = this._setZoom(newScale, center);
+ });
+
+ return round(matrix.a, 1000);
+};
+
+function setCTM(node, m) {
+ var mstr = 'matrix(' + m.a + ',' + m.b + ',' + m.c + ',' + m.d + ',' + m.e + ',' + m.f + ')';
+ node.setAttribute('transform', mstr);
+}
+
+Canvas.prototype._fitViewport = function (center) {
+
+ var vbox = this.viewbox(),
+ outer = vbox.outer,
+ inner = vbox.inner,
+ newScale,
+ newViewbox;
+
+ // display the complete diagram without zooming in.
+ // instead of relying on internal zoom, we perform a
+ // hard reset on the canvas viewbox to realize this
+ //
+ // if diagram does not need to be zoomed in, we focus it around
+ // the diagram origin instead
+
+ if (inner.x >= 0 && inner.y >= 0 && inner.x + inner.width <= outer.width && inner.y + inner.height <= outer.height && !center) {
+
+ newViewbox = {
+ x: 0,
+ y: 0,
+ width: Math.max(inner.width + inner.x, outer.width),
+ height: Math.max(inner.height + inner.y, outer.height)
+ };
+ } else {
+
+ newScale = Math.min(1, outer.width / inner.width, outer.height / inner.height);
+ newViewbox = {
+ x: inner.x + (center ? inner.width / 2 - outer.width / newScale / 2 : 0),
+ y: inner.y + (center ? inner.height / 2 - outer.height / newScale / 2 : 0),
+ width: outer.width / newScale,
+ height: outer.height / newScale
+ };
+ }
+
+ this.viewbox(newViewbox);
+
+ return this.viewbox(false).scale;
+};
+
+Canvas.prototype._setZoom = function (scale, center) {
+
+ var svg = this._svg,
+ viewport = this._viewport;
+
+ var matrix = svg.createSVGMatrix();
+ var point = svg.createSVGPoint();
+
+ var centerPoint, originalPoint, currentMatrix, scaleMatrix, newMatrix;
+
+ currentMatrix = viewport.getCTM();
+
+ var currentScale = currentMatrix.a;
+
+ if (center) {
+ centerPoint = (0, _minDash.assign)(point, center);
+
+ // revert applied viewport transformations
+ originalPoint = centerPoint.matrixTransform(currentMatrix.inverse());
+
+ // create scale matrix
+ scaleMatrix = matrix.translate(originalPoint.x, originalPoint.y).scale(1 / currentScale * scale).translate(-originalPoint.x, -originalPoint.y);
+
+ newMatrix = currentMatrix.multiply(scaleMatrix);
+ } else {
+ newMatrix = matrix.scale(scale);
+ }
+
+ setCTM(this._viewport, newMatrix);
+
+ return newMatrix;
+};
+
+/**
+ * Returns the size of the canvas
+ *
+ * @return {Dimensions}
+ */
+Canvas.prototype.getSize = function () {
+ return {
+ width: this._container.clientWidth,
+ height: this._container.clientHeight
+ };
+};
+
+/**
+ * Return the absolute bounding box for the given element
+ *
+ * The absolute bounding box may be used to display overlays in the
+ * callers (browser) coordinate system rather than the zoomed in/out
+ * canvas coordinates.
+ *
+ * @param {ElementDescriptor} element
+ * @return {Bounds} the absolute bounding box
+ */
+Canvas.prototype.getAbsoluteBBox = function (element) {
+ var vbox = this.viewbox();
+ var bbox;
+
+ // connection
+ // use svg bbox
+ if (element.waypoints) {
+ var gfx = this.getGraphics(element);
+
+ bbox = gfx.getBBox();
+ }
+ // shapes
+ // use data
+ else {
+ bbox = element;
+ }
+
+ var x = bbox.x * vbox.scale - vbox.x * vbox.scale;
+ var y = bbox.y * vbox.scale - vbox.y * vbox.scale;
+
+ var width = bbox.width * vbox.scale;
+ var height = bbox.height * vbox.scale;
+
+ return {
+ x: x,
+ y: y,
+ width: width,
+ height: height
+ };
+};
+
+/**
+ * Fires an event in order other modules can react to the
+ * canvas resizing
+ */
+Canvas.prototype.resized = function () {
+
+ // force recomputation of view box
+ delete this._cachedViewbox;
+
+ this._eventBus.fire('canvas.resized');
+};
+
+},{"../util/Collections":393,"../util/Elements":396,"min-dash":505,"tiny-svg":535}],247:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ElementFactory;
+
+var _model = require('../model');
+
+var _minDash = require('min-dash');
+
+/**
+ * A factory for diagram-js shapes
+ */
+function ElementFactory() {
+ this._uid = 12;
+}
+
+ElementFactory.prototype.createRoot = function (attrs) {
+ return this.create('root', attrs);
+};
+
+ElementFactory.prototype.createLabel = function (attrs) {
+ return this.create('label', attrs);
+};
+
+ElementFactory.prototype.createShape = function (attrs) {
+ return this.create('shape', attrs);
+};
+
+ElementFactory.prototype.createConnection = function (attrs) {
+ return this.create('connection', attrs);
+};
+
+/**
+ * Create a model element with the given type and
+ * a number of pre-set attributes.
+ *
+ * @param {String} type
+ * @param {Object} attrs
+ * @return {djs.model.Base} the newly created model instance
+ */
+ElementFactory.prototype.create = function (type, attrs) {
+
+ attrs = (0, _minDash.assign)({}, attrs || {});
+
+ if (!attrs.id) {
+ attrs.id = type + '_' + this._uid++;
+ }
+
+ return (0, _model.create)(type, attrs);
+};
+
+},{"../model":382,"min-dash":505}],248:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ElementRegistry;
+
+var _tinySvg = require('tiny-svg');
+
+var ELEMENT_ID = 'data-element-id';
+
+/**
+ * @class
+ *
+ * A registry that keeps track of all shapes in the diagram.
+ */
+function ElementRegistry(eventBus) {
+ this._elements = {};
+
+ this._eventBus = eventBus;
+}
+
+ElementRegistry.$inject = ['eventBus'];
+
+/**
+ * Register a pair of (element, gfx, (secondaryGfx)).
+ *
+ * @param {djs.model.Base} element
+ * @param {SVGElement} gfx
+ * @param {SVGElement} [secondaryGfx] optional other element to register, too
+ */
+ElementRegistry.prototype.add = function (element, gfx, secondaryGfx) {
+
+ var id = element.id;
+
+ this._validateId(id);
+
+ // associate dom node with element
+ (0, _tinySvg.attr)(gfx, ELEMENT_ID, id);
+
+ if (secondaryGfx) {
+ (0, _tinySvg.attr)(secondaryGfx, ELEMENT_ID, id);
+ }
+
+ this._elements[id] = { element: element, gfx: gfx, secondaryGfx: secondaryGfx };
+};
+
+/**
+ * Removes an element from the registry.
+ *
+ * @param {djs.model.Base} element
+ */
+ElementRegistry.prototype.remove = function (element) {
+ var elements = this._elements,
+ id = element.id || element,
+ container = id && elements[id];
+
+ if (container) {
+
+ // unset element id on gfx
+ (0, _tinySvg.attr)(container.gfx, ELEMENT_ID, '');
+
+ if (container.secondaryGfx) {
+ (0, _tinySvg.attr)(container.secondaryGfx, ELEMENT_ID, '');
+ }
+
+ delete elements[id];
+ }
+};
+
+/**
+ * Update the id of an element
+ *
+ * @param {djs.model.Base} element
+ * @param {String} newId
+ */
+ElementRegistry.prototype.updateId = function (element, newId) {
+
+ this._validateId(newId);
+
+ if (typeof element === 'string') {
+ element = this.get(element);
+ }
+
+ this._eventBus.fire('element.updateId', {
+ element: element,
+ newId: newId
+ });
+
+ var gfx = this.getGraphics(element),
+ secondaryGfx = this.getGraphics(element, true);
+
+ this.remove(element);
+
+ element.id = newId;
+
+ this.add(element, gfx, secondaryGfx);
+};
+
+/**
+ * Return the model element for a given id or graphics.
+ *
+ * @example
+ *
+ * elementRegistry.get('SomeElementId_1');
+ * elementRegistry.get(gfx);
+ *
+ *
+ * @param {String|SVGElement} filter for selecting the element
+ *
+ * @return {djs.model.Base}
+ */
+ElementRegistry.prototype.get = function (filter) {
+ var id;
+
+ if (typeof filter === 'string') {
+ id = filter;
+ } else {
+ id = filter && (0, _tinySvg.attr)(filter, ELEMENT_ID);
+ }
+
+ var container = this._elements[id];
+ return container && container.element;
+};
+
+/**
+ * Return all elements that match a given filter function.
+ *
+ * @param {Function} fn
+ *
+ * @return {Array
}
+ */
+ElementRegistry.prototype.filter = function (fn) {
+
+ var filtered = [];
+
+ this.forEach(function (element, gfx) {
+ if (fn(element, gfx)) {
+ filtered.push(element);
+ }
+ });
+
+ return filtered;
+};
+
+/**
+ * Return all rendered model elements.
+ *
+ * @return {Array}
+ */
+ElementRegistry.prototype.getAll = function () {
+ return this.filter(function (e) {
+ return e;
+ });
+};
+
+/**
+ * Iterate over all diagram elements.
+ *
+ * @param {Function} fn
+ */
+ElementRegistry.prototype.forEach = function (fn) {
+
+ var map = this._elements;
+
+ Object.keys(map).forEach(function (id) {
+ var container = map[id],
+ element = container.element,
+ gfx = container.gfx;
+
+ return fn(element, gfx);
+ });
+};
+
+/**
+ * Return the graphical representation of an element or its id.
+ *
+ * @example
+ * elementRegistry.getGraphics('SomeElementId_1');
+ * elementRegistry.getGraphics(rootElement); //
+ *
+ * elementRegistry.getGraphics(rootElement, true); //
+ *
+ *
+ * @param {String|djs.model.Base} filter
+ * @param {Boolean} [secondary=false] whether to return the secondary connected element
+ *
+ * @return {SVGElement}
+ */
+ElementRegistry.prototype.getGraphics = function (filter, secondary) {
+ var id = filter.id || filter;
+
+ var container = this._elements[id];
+ return container && (secondary ? container.secondaryGfx : container.gfx);
+};
+
+/**
+ * Validate the suitability of the given id and signals a problem
+ * with an exception.
+ *
+ * @param {String} id
+ *
+ * @throws {Error} if id is empty or already assigned
+ */
+ElementRegistry.prototype._validateId = function (id) {
+ if (!id) {
+ throw new Error('element must have an id');
+ }
+
+ if (this._elements[id]) {
+ throw new Error('element with id ' + id + ' already added');
+ }
+};
+
+},{"tiny-svg":535}],249:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+exports.default = EventBus;
+
+var _minDash = require('min-dash');
+
+var FN_REF = '__fn';
+
+var DEFAULT_PRIORITY = 1000;
+
+var slice = Array.prototype.slice;
+
+/**
+ * A general purpose event bus.
+ *
+ * This component is used to communicate across a diagram instance.
+ * Other parts of a diagram can use it to listen to and broadcast events.
+ *
+ *
+ * ## Registering for Events
+ *
+ * The event bus provides the {@link EventBus#on} and {@link EventBus#once}
+ * methods to register for events. {@link EventBus#off} can be used to
+ * remove event registrations. Listeners receive an instance of {@link Event}
+ * as the first argument. It allows them to hook into the event execution.
+ *
+ * ```javascript
+ *
+ * // listen for event
+ * eventBus.on('foo', function(event) {
+ *
+ * // access event type
+ * event.type; // 'foo'
+ *
+ * // stop propagation to other listeners
+ * event.stopPropagation();
+ *
+ * // prevent event default
+ * event.preventDefault();
+ * });
+ *
+ * // listen for event with custom payload
+ * eventBus.on('bar', function(event, payload) {
+ * console.log(payload);
+ * });
+ *
+ * // listen for event returning value
+ * eventBus.on('foobar', function(event) {
+ *
+ * // stop event propagation + prevent default
+ * return false;
+ *
+ * // stop event propagation + return custom result
+ * return {
+ * complex: 'listening result'
+ * };
+ * });
+ *
+ *
+ * // listen with custom priority (default=1000, higher is better)
+ * eventBus.on('priorityfoo', 1500, function(event) {
+ * console.log('invoked first!');
+ * });
+ *
+ *
+ * // listen for event and pass the context (`this`)
+ * eventBus.on('foobar', function(event) {
+ * this.foo();
+ * }, this);
+ * ```
+ *
+ *
+ * ## Emitting Events
+ *
+ * Events can be emitted via the event bus using {@link EventBus#fire}.
+ *
+ * ```javascript
+ *
+ * // false indicates that the default action
+ * // was prevented by listeners
+ * if (eventBus.fire('foo') === false) {
+ * console.log('default has been prevented!');
+ * };
+ *
+ *
+ * // custom args + return value listener
+ * eventBus.on('sum', function(event, a, b) {
+ * return a + b;
+ * });
+ *
+ * // you can pass custom arguments + retrieve result values.
+ * var sum = eventBus.fire('sum', 1, 2);
+ * console.log(sum); // 3
+ * ```
+ */
+function EventBus() {
+ this._listeners = {};
+
+ // cleanup on destroy on lowest priority to allow
+ // message passing until the bitter end
+ this.on('diagram.destroy', 1, this._destroy, this);
+}
+
+/**
+ * Register an event listener for events with the given name.
+ *
+ * The callback will be invoked with `event, ...additionalArguments`
+ * that have been passed to {@link EventBus#fire}.
+ *
+ * Returning false from a listener will prevent the events default action
+ * (if any is specified). To stop an event from being processed further in
+ * other listeners execute {@link Event#stopPropagation}.
+ *
+ * Returning anything but `undefined` from a listener will stop the listener propagation.
+ *
+ * @param {String|Array} events
+ * @param {Number} [priority=1000] the priority in which this listener is called, larger is higher
+ * @param {Function} callback
+ * @param {Object} [that] Pass context (`this`) to the callback
+ */
+EventBus.prototype.on = function (events, priority, callback, that) {
+
+ events = (0, _minDash.isArray)(events) ? events : [events];
+
+ if ((0, _minDash.isFunction)(priority)) {
+ that = callback;
+ callback = priority;
+ priority = DEFAULT_PRIORITY;
+ }
+
+ if (!(0, _minDash.isNumber)(priority)) {
+ throw new Error('priority must be a number');
+ }
+
+ var actualCallback = callback;
+
+ if (that) {
+ actualCallback = (0, _minDash.bind)(callback, that);
+
+ // make sure we remember and are able to remove
+ // bound callbacks via {@link #off} using the original
+ // callback
+ actualCallback[FN_REF] = callback[FN_REF] || callback;
+ }
+
+ var self = this;
+
+ events.forEach(function (e) {
+ self._addListener(e, {
+ priority: priority,
+ callback: actualCallback,
+ next: null
+ });
+ });
+};
+
+/**
+ * Register an event listener that is executed only once.
+ *
+ * @param {String} event the event name to register for
+ * @param {Function} callback the callback to execute
+ * @param {Object} [that] Pass context (`this`) to the callback
+ */
+EventBus.prototype.once = function (event, priority, callback, that) {
+ var self = this;
+
+ if ((0, _minDash.isFunction)(priority)) {
+ that = callback;
+ callback = priority;
+ priority = DEFAULT_PRIORITY;
+ }
+
+ if (!(0, _minDash.isNumber)(priority)) {
+ throw new Error('priority must be a number');
+ }
+
+ function wrappedCallback() {
+ var result = callback.apply(that, arguments);
+
+ self.off(event, wrappedCallback);
+
+ return result;
+ }
+
+ // make sure we remember and are able to remove
+ // bound callbacks via {@link #off} using the original
+ // callback
+ wrappedCallback[FN_REF] = callback;
+
+ this.on(event, priority, wrappedCallback);
+};
+
+/**
+ * Removes event listeners by event and callback.
+ *
+ * If no callback is given, all listeners for a given event name are being removed.
+ *
+ * @param {String|Array} events
+ * @param {Function} [callback]
+ */
+EventBus.prototype.off = function (events, callback) {
+
+ events = (0, _minDash.isArray)(events) ? events : [events];
+
+ var self = this;
+
+ events.forEach(function (event) {
+ self._removeListener(event, callback);
+ });
+};
+
+/**
+ * Create an EventBus event.
+ *
+ * @param {Object} data
+ *
+ * @return {Object} event, recognized by the eventBus
+ */
+EventBus.prototype.createEvent = function (data) {
+ var event = new InternalEvent();
+
+ event.init(data);
+
+ return event;
+};
+
+/**
+ * Fires a named event.
+ *
+ * @example
+ *
+ * // fire event by name
+ * events.fire('foo');
+ *
+ * // fire event object with nested type
+ * var event = { type: 'foo' };
+ * events.fire(event);
+ *
+ * // fire event with explicit type
+ * var event = { x: 10, y: 20 };
+ * events.fire('element.moved', event);
+ *
+ * // pass additional arguments to the event
+ * events.on('foo', function(event, bar) {
+ * alert(bar);
+ * });
+ *
+ * events.fire({ type: 'foo' }, 'I am bar!');
+ *
+ * @param {String} [name] the optional event name
+ * @param {Object} [event] the event object
+ * @param {...Object} additional arguments to be passed to the callback functions
+ *
+ * @return {Boolean} the events return value, if specified or false if the
+ * default action was prevented by listeners
+ */
+EventBus.prototype.fire = function (type, data) {
+
+ var event, firstListener, returnValue, args;
+
+ args = slice.call(arguments);
+
+ if ((typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object') {
+ event = type;
+ type = event.type;
+ }
+
+ if (!type) {
+ throw new Error('no event type specified');
+ }
+
+ firstListener = this._listeners[type];
+
+ if (!firstListener) {
+ return;
+ }
+
+ // we make sure we fire instances of our home made
+ // events here. We wrap them only once, though
+ if (data instanceof InternalEvent) {
+ // we are fine, we alread have an event
+ event = data;
+ } else {
+ event = this.createEvent(data);
+ }
+
+ // ensure we pass the event as the first parameter
+ args[0] = event;
+
+ // original event type (in case we delegate)
+ var originalType = event.type;
+
+ // update event type before delegation
+ if (type !== originalType) {
+ event.type = type;
+ }
+
+ try {
+ returnValue = this._invokeListeners(event, args, firstListener);
+ } finally {
+ // reset event type after delegation
+ if (type !== originalType) {
+ event.type = originalType;
+ }
+ }
+
+ // set the return value to false if the event default
+ // got prevented and no other return value exists
+ if (returnValue === undefined && event.defaultPrevented) {
+ returnValue = false;
+ }
+
+ return returnValue;
+};
+
+EventBus.prototype.handleError = function (error) {
+ return this.fire('error', { error: error }) === false;
+};
+
+EventBus.prototype._destroy = function () {
+ this._listeners = {};
+};
+
+EventBus.prototype._invokeListeners = function (event, args, listener) {
+
+ var returnValue;
+
+ while (listener) {
+
+ // handle stopped propagation
+ if (event.cancelBubble) {
+ break;
+ }
+
+ returnValue = this._invokeListener(event, args, listener);
+
+ listener = listener.next;
+ }
+
+ return returnValue;
+};
+
+EventBus.prototype._invokeListener = function (event, args, listener) {
+
+ var returnValue;
+
+ try {
+ // returning false prevents the default action
+ returnValue = invokeFunction(listener.callback, args);
+
+ // stop propagation on return value
+ if (returnValue !== undefined) {
+ event.returnValue = returnValue;
+ event.stopPropagation();
+ }
+
+ // prevent default on return false
+ if (returnValue === false) {
+ event.preventDefault();
+ }
+ } catch (e) {
+ if (!this.handleError(e)) {
+ console.error('unhandled error in event listener');
+ console.error(e.stack);
+
+ throw e;
+ }
+ }
+
+ return returnValue;
+};
+
+/*
+ * Add new listener with a certain priority to the list
+ * of listeners (for the given event).
+ *
+ * The semantics of listener registration / listener execution are
+ * first register, first serve: New listeners will always be inserted
+ * after existing listeners with the same priority.
+ *
+ * Example: Inserting two listeners with priority 1000 and 1300
+ *
+ * * before: [ 1500, 1500, 1000, 1000 ]
+ * * after: [ 1500, 1500, (new=1300), 1000, 1000, (new=1000) ]
+ *
+ * @param {String} event
+ * @param {Object} listener { priority, callback }
+ */
+EventBus.prototype._addListener = function (event, newListener) {
+
+ var listener = this._getListeners(event),
+ previousListener;
+
+ // no prior listeners
+ if (!listener) {
+ this._setListeners(event, newListener);
+
+ return;
+ }
+
+ // ensure we order listeners by priority from
+ // 0 (high) to n > 0 (low)
+ while (listener) {
+
+ if (listener.priority < newListener.priority) {
+
+ newListener.next = listener;
+
+ if (previousListener) {
+ previousListener.next = newListener;
+ } else {
+ this._setListeners(event, newListener);
+ }
+
+ return;
+ }
+
+ previousListener = listener;
+ listener = listener.next;
+ }
+
+ // add new listener to back
+ previousListener.next = newListener;
+};
+
+EventBus.prototype._getListeners = function (name) {
+ return this._listeners[name];
+};
+
+EventBus.prototype._setListeners = function (name, listener) {
+ this._listeners[name] = listener;
+};
+
+EventBus.prototype._removeListener = function (event, callback) {
+
+ var listener = this._getListeners(event),
+ nextListener,
+ previousListener,
+ listenerCallback;
+
+ if (!callback) {
+ // clear listeners
+ this._setListeners(event, null);
+
+ return;
+ }
+
+ while (listener) {
+
+ nextListener = listener.next;
+
+ listenerCallback = listener.callback;
+
+ if (listenerCallback === callback || listenerCallback[FN_REF] === callback) {
+ if (previousListener) {
+ previousListener.next = nextListener;
+ } else {
+ // new first listener
+ this._setListeners(event, nextListener);
+ }
+ }
+
+ previousListener = listener;
+ listener = nextListener;
+ }
+};
+
+/**
+ * A event that is emitted via the event bus.
+ */
+function InternalEvent() {}
+
+InternalEvent.prototype.stopPropagation = function () {
+ this.cancelBubble = true;
+};
+
+InternalEvent.prototype.preventDefault = function () {
+ this.defaultPrevented = true;
+};
+
+InternalEvent.prototype.init = function (data) {
+ (0, _minDash.assign)(this, data || {});
+};
+
+/**
+ * Invoke function. Be fast...
+ *
+ * @param {Function} fn
+ * @param {Array} args
+ *
+ * @return {Any}
+ */
+function invokeFunction(fn, args) {
+ return fn.apply(null, args);
+}
+
+},{"min-dash":505}],250:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = GraphicsFactory;
+
+var _minDash = require('min-dash');
+
+var _GraphicsUtil = require('../util/GraphicsUtil');
+
+var _SvgTransformUtil = require('../util/SvgTransformUtil');
+
+var _minDom = require('min-dom');
+
+var _tinySvg = require('tiny-svg');
+
+/**
+ * A factory that creates graphical elements
+ *
+ * @param {EventBus} eventBus
+ * @param {ElementRegistry} elementRegistry
+ */
+function GraphicsFactory(eventBus, elementRegistry) {
+ this._eventBus = eventBus;
+ this._elementRegistry = elementRegistry;
+}
+
+GraphicsFactory.$inject = ['eventBus', 'elementRegistry'];
+
+GraphicsFactory.prototype._getChildren = function (element) {
+
+ var gfx = this._elementRegistry.getGraphics(element);
+
+ var childrenGfx;
+
+ // root element
+ if (!element.parent) {
+ childrenGfx = gfx;
+ } else {
+ childrenGfx = (0, _GraphicsUtil.getChildren)(gfx);
+ if (!childrenGfx) {
+ childrenGfx = (0, _tinySvg.create)('g');
+ (0, _tinySvg.classes)(childrenGfx).add('djs-children');
+
+ (0, _tinySvg.append)(gfx.parentNode, childrenGfx);
+ }
+ }
+
+ return childrenGfx;
+};
+
+/**
+ * Clears the graphical representation of the element and returns the
+ * cleared visual (the element).
+ */
+GraphicsFactory.prototype._clear = function (gfx) {
+ var visual = (0, _GraphicsUtil.getVisual)(gfx);
+
+ (0, _minDom.clear)(visual);
+
+ return visual;
+};
+
+/**
+ * Creates a gfx container for shapes and connections
+ *
+ * The layout is as follows:
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * @param {Object} parent
+ * @param {String} type the type of the element, i.e. shape | connection
+ * @param {Number} [parentIndex] position to create container in parent
+ */
+GraphicsFactory.prototype._createContainer = function (type, childrenGfx, parentIndex) {
+ var outerGfx = (0, _tinySvg.create)('g');
+ (0, _tinySvg.classes)(outerGfx).add('djs-group');
+
+ // insert node at position
+ if (typeof parentIndex !== 'undefined') {
+ prependTo(outerGfx, childrenGfx, childrenGfx.childNodes[parentIndex]);
+ } else {
+ (0, _tinySvg.append)(childrenGfx, outerGfx);
+ }
+
+ var gfx = (0, _tinySvg.create)('g');
+ (0, _tinySvg.classes)(gfx).add('djs-element');
+ (0, _tinySvg.classes)(gfx).add('djs-' + type);
+
+ (0, _tinySvg.append)(outerGfx, gfx);
+
+ // create visual
+ var visual = (0, _tinySvg.create)('g');
+ (0, _tinySvg.classes)(visual).add('djs-visual');
+
+ (0, _tinySvg.append)(gfx, visual);
+
+ return gfx;
+};
+
+GraphicsFactory.prototype.create = function (type, element, parentIndex) {
+ var childrenGfx = this._getChildren(element.parent);
+ return this._createContainer(type, childrenGfx, parentIndex);
+};
+
+GraphicsFactory.prototype.updateContainments = function (elements) {
+
+ var self = this,
+ elementRegistry = this._elementRegistry,
+ parents;
+
+ parents = (0, _minDash.reduce)(elements, function (map, e) {
+
+ if (e.parent) {
+ map[e.parent.id] = e.parent;
+ }
+
+ return map;
+ }, {});
+
+ // update all parents of changed and reorganized their children
+ // in the correct order (as indicated in our model)
+ (0, _minDash.forEach)(parents, function (parent) {
+
+ var children = parent.children;
+
+ if (!children) {
+ return;
+ }
+
+ var childGfx = self._getChildren(parent);
+
+ (0, _minDash.forEach)(children.slice().reverse(), function (c) {
+ var gfx = elementRegistry.getGraphics(c);
+
+ prependTo(gfx.parentNode, childGfx);
+ });
+ });
+};
+
+GraphicsFactory.prototype.drawShape = function (visual, element) {
+ var eventBus = this._eventBus;
+
+ return eventBus.fire('render.shape', { gfx: visual, element: element });
+};
+
+GraphicsFactory.prototype.getShapePath = function (element) {
+ var eventBus = this._eventBus;
+
+ return eventBus.fire('render.getShapePath', element);
+};
+
+GraphicsFactory.prototype.drawConnection = function (visual, element) {
+ var eventBus = this._eventBus;
+
+ return eventBus.fire('render.connection', { gfx: visual, element: element });
+};
+
+GraphicsFactory.prototype.getConnectionPath = function (waypoints) {
+ var eventBus = this._eventBus;
+
+ return eventBus.fire('render.getConnectionPath', waypoints);
+};
+
+GraphicsFactory.prototype.update = function (type, element, gfx) {
+ // Do not update root element
+ if (!element.parent) {
+ return;
+ }
+
+ var visual = this._clear(gfx);
+
+ // redraw
+ if (type === 'shape') {
+ this.drawShape(visual, element);
+
+ // update positioning
+ (0, _SvgTransformUtil.translate)(gfx, element.x, element.y);
+ } else if (type === 'connection') {
+ this.drawConnection(visual, element);
+ } else {
+ throw new Error('unknown type: ' + type);
+ }
+
+ if (element.hidden) {
+ (0, _tinySvg.attr)(gfx, 'display', 'none');
+ } else {
+ (0, _tinySvg.attr)(gfx, 'display', 'block');
+ }
+};
+
+GraphicsFactory.prototype.remove = function (element) {
+ var gfx = this._elementRegistry.getGraphics(element);
+
+ // remove
+ (0, _tinySvg.remove)(gfx.parentNode);
+};
+
+// helpers //////////////////////
+
+function prependTo(newNode, parentNode, siblingNode) {
+ parentNode.insertBefore(newNode, siblingNode || parentNode.firstChild);
+}
+
+},{"../util/GraphicsUtil":399,"../util/SvgTransformUtil":408,"min-dash":505,"min-dom":506,"tiny-svg":535}],251:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _draw = require('../draw');
+
+var _draw2 = _interopRequireDefault(_draw);
+
+var _Canvas = require('./Canvas');
+
+var _Canvas2 = _interopRequireDefault(_Canvas);
+
+var _ElementRegistry = require('./ElementRegistry');
+
+var _ElementRegistry2 = _interopRequireDefault(_ElementRegistry);
+
+var _ElementFactory = require('./ElementFactory');
+
+var _ElementFactory2 = _interopRequireDefault(_ElementFactory);
+
+var _EventBus = require('./EventBus');
+
+var _EventBus2 = _interopRequireDefault(_EventBus);
+
+var _GraphicsFactory = require('./GraphicsFactory');
+
+var _GraphicsFactory2 = _interopRequireDefault(_GraphicsFactory);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_draw2.default],
+ __init__: ['canvas'],
+ canvas: ['type', _Canvas2.default],
+ elementRegistry: ['type', _ElementRegistry2.default],
+ elementFactory: ['type', _ElementFactory2.default],
+ eventBus: ['type', _EventBus2.default],
+ graphicsFactory: ['type', _GraphicsFactory2.default]
+};
+
+},{"../draw":255,"./Canvas":246,"./ElementFactory":247,"./ElementRegistry":248,"./EventBus":249,"./GraphicsFactory":250}],252:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BaseRenderer;
+var DEFAULT_RENDER_PRIORITY = 1000;
+
+/**
+ * The base implementation of shape and connection renderers.
+ *
+ * @param {EventBus} eventBus
+ * @param {Number} [renderPriority=1000]
+ */
+function BaseRenderer(eventBus, renderPriority) {
+ var self = this;
+
+ renderPriority = renderPriority || DEFAULT_RENDER_PRIORITY;
+
+ eventBus.on(['render.shape', 'render.connection'], renderPriority, function (evt, context) {
+ var type = evt.type,
+ element = context.element,
+ visuals = context.gfx;
+
+ if (self.canRender(element)) {
+ if (type === 'render.shape') {
+ return self.drawShape(visuals, element);
+ } else {
+ return self.drawConnection(visuals, element);
+ }
+ }
+ });
+
+ eventBus.on(['render.getShapePath', 'render.getConnectionPath'], renderPriority, function (evt, element) {
+ if (self.canRender(element)) {
+ if (evt.type === 'render.getShapePath') {
+ return self.getShapePath(element);
+ } else {
+ return self.getConnectionPath(element);
+ }
+ }
+ });
+}
+
+/**
+ * Should check whether *this* renderer can render
+ * the element/connection.
+ *
+ * @param {element} element
+ *
+ * @returns {Boolean}
+ */
+BaseRenderer.prototype.canRender = function () {};
+
+/**
+ * Provides the shape's snap svg element to be drawn on the `canvas`.
+ *
+ * @param {djs.Graphics} visuals
+ * @param {Shape} shape
+ *
+ * @returns {Snap.svg} [returns a Snap.svg paper element ]
+ */
+BaseRenderer.prototype.drawShape = function () {};
+
+/**
+ * Provides the shape's snap svg element to be drawn on the `canvas`.
+ *
+ * @param {djs.Graphics} visuals
+ * @param {Connection} connection
+ *
+ * @returns {Snap.svg} [returns a Snap.svg paper element ]
+ */
+BaseRenderer.prototype.drawConnection = function () {};
+
+/**
+ * Gets the SVG path of a shape that represents it's visual bounds.
+ *
+ * @param {Shape} shape
+ *
+ * @return {string} svg path
+ */
+BaseRenderer.prototype.getShapePath = function () {};
+
+/**
+ * Gets the SVG path of a connection that represents it's visual bounds.
+ *
+ * @param {Connection} connection
+ *
+ * @return {string} svg path
+ */
+BaseRenderer.prototype.getConnectionPath = function () {};
+
+},{}],253:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DefaultRenderer;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _BaseRenderer = require('./BaseRenderer');
+
+var _BaseRenderer2 = _interopRequireDefault(_BaseRenderer);
+
+var _RenderUtil = require('../util/RenderUtil');
+
+var _tinySvg = require('tiny-svg');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// apply default renderer with lowest possible priority
+// so that it only kicks in if noone else could render
+var DEFAULT_RENDER_PRIORITY = 1;
+
+/**
+ * The default renderer used for shapes and connections.
+ *
+ * @param {EventBus} eventBus
+ * @param {Styles} styles
+ */
+function DefaultRenderer(eventBus, styles) {
+ //
+ _BaseRenderer2.default.call(this, eventBus, DEFAULT_RENDER_PRIORITY);
+
+ this.CONNECTION_STYLE = styles.style(['no-fill'], { strokeWidth: 5, stroke: 'fuchsia' });
+ this.SHAPE_STYLE = styles.style({ fill: 'white', stroke: 'fuchsia', strokeWidth: 2 });
+}
+
+(0, _inherits2.default)(DefaultRenderer, _BaseRenderer2.default);
+
+DefaultRenderer.prototype.canRender = function () {
+ return true;
+};
+
+DefaultRenderer.prototype.drawShape = function drawShape(visuals, element) {
+
+ var rect = (0, _tinySvg.create)('rect');
+ (0, _tinySvg.attr)(rect, {
+ x: 0,
+ y: 0,
+ width: element.width || 0,
+ height: element.height || 0
+ });
+ (0, _tinySvg.attr)(rect, this.SHAPE_STYLE);
+
+ (0, _tinySvg.append)(visuals, rect);
+
+ return rect;
+};
+
+DefaultRenderer.prototype.drawConnection = function drawConnection(visuals, connection) {
+
+ var line = (0, _RenderUtil.createLine)(connection.waypoints, this.CONNECTION_STYLE);
+ (0, _tinySvg.append)(visuals, line);
+
+ return line;
+};
+
+DefaultRenderer.prototype.getShapePath = function getShapePath(shape) {
+
+ var x = shape.x,
+ y = shape.y,
+ width = shape.width,
+ height = shape.height;
+
+ var shapePath = [['M', x, y], ['l', width, 0], ['l', 0, height], ['l', -width, 0], ['z']];
+
+ return (0, _RenderUtil.componentsToPath)(shapePath);
+};
+
+DefaultRenderer.prototype.getConnectionPath = function getConnectionPath(connection) {
+ var waypoints = connection.waypoints;
+
+ var idx,
+ point,
+ connectionPath = [];
+
+ for (idx = 0; point = waypoints[idx]; idx++) {
+
+ // take invisible docking into account
+ // when creating the path
+ point = point.original || point;
+
+ connectionPath.push([idx === 0 ? 'M' : 'L', point.x, point.y]);
+ }
+
+ return (0, _RenderUtil.componentsToPath)(connectionPath);
+};
+
+DefaultRenderer.$inject = ['eventBus', 'styles'];
+
+},{"../util/RenderUtil":407,"./BaseRenderer":252,"inherits":415,"tiny-svg":535}],254:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Styles;
+
+var _minDash = require('min-dash');
+
+/**
+ * A component that manages shape styles
+ */
+function Styles() {
+
+ var defaultTraits = {
+
+ 'no-fill': {
+ fill: 'none'
+ },
+ 'no-border': {
+ strokeOpacity: 0.0
+ },
+ 'no-events': {
+ pointerEvents: 'none'
+ }
+ };
+
+ var self = this;
+
+ /**
+ * Builds a style definition from a className, a list of traits and an object of additional attributes.
+ *
+ * @param {String} className
+ * @param {Array} traits
+ * @param {Object} additionalAttrs
+ *
+ * @return {Object} the style defintion
+ */
+ this.cls = function (className, traits, additionalAttrs) {
+ var attrs = this.style(traits, additionalAttrs);
+
+ return (0, _minDash.assign)(attrs, { 'class': className });
+ };
+
+ /**
+ * Builds a style definition from a list of traits and an object of additional attributes.
+ *
+ * @param {Array} traits
+ * @param {Object} additionalAttrs
+ *
+ * @return {Object} the style defintion
+ */
+ this.style = function (traits, additionalAttrs) {
+
+ if (!(0, _minDash.isArray)(traits) && !additionalAttrs) {
+ additionalAttrs = traits;
+ traits = [];
+ }
+
+ var attrs = (0, _minDash.reduce)(traits, function (attrs, t) {
+ return (0, _minDash.assign)(attrs, defaultTraits[t] || {});
+ }, {});
+
+ return additionalAttrs ? (0, _minDash.assign)(attrs, additionalAttrs) : attrs;
+ };
+
+ this.computeStyle = function (custom, traits, defaultStyles) {
+ if (!(0, _minDash.isArray)(traits)) {
+ defaultStyles = traits;
+ traits = [];
+ }
+
+ return self.style(traits || [], (0, _minDash.assign)({}, defaultStyles, custom || {}));
+ };
+}
+
+},{"min-dash":505}],255:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _DefaultRenderer = require('./DefaultRenderer');
+
+var _DefaultRenderer2 = _interopRequireDefault(_DefaultRenderer);
+
+var _Styles = require('./Styles');
+
+var _Styles2 = _interopRequireDefault(_Styles);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['defaultRenderer'],
+ defaultRenderer: ['type', _DefaultRenderer2.default],
+ styles: ['type', _Styles2.default]
+};
+
+},{"./DefaultRenderer":253,"./Styles":254}],256:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AlignElements;
+
+var _minDash = require('min-dash');
+
+function last(arr) {
+ return arr && arr[arr.length - 1];
+}
+
+function sortTopOrMiddle(element) {
+ return element.y;
+}
+
+function sortLeftOrCenter(element) {
+ return element.x;
+}
+
+/**
+ * Sorting functions for different types of alignment
+ *
+ * @type {Object}
+ *
+ * @return {Function}
+ */
+var ALIGNMENT_SORTING = {
+ left: sortLeftOrCenter,
+ center: sortLeftOrCenter,
+ right: function right(element) {
+ return element.x + element.width;
+ },
+ top: sortTopOrMiddle,
+ middle: sortTopOrMiddle,
+ bottom: function bottom(element) {
+ return element.y + element.height;
+ }
+};
+
+function AlignElements(modeling) {
+ this._modeling = modeling;
+}
+
+AlignElements.$inject = ['modeling'];
+
+/**
+ * Get the relevant "axis" and "dimension" related to the current type of alignment
+ *
+ * @param {String} type left|right|center|top|bottom|middle
+ *
+ * @return {Object} { axis, dimension }
+ */
+AlignElements.prototype._getOrientationDetails = function (type) {
+ var vertical = ['top', 'bottom', 'middle'],
+ axis = 'x',
+ dimension = 'width';
+
+ if (vertical.indexOf(type) !== -1) {
+ axis = 'y';
+ dimension = 'height';
+ }
+
+ return {
+ axis: axis,
+ dimension: dimension
+ };
+};
+
+AlignElements.prototype._isType = function (type, types) {
+ return types.indexOf(type) !== -1;
+};
+
+/**
+ * Get a point on the relevant axis where elements should align to
+ *
+ * @param {String} type left|right|center|top|bottom|middle
+ * @param {Array} sortedElements
+ *
+ * @return {Object}
+ */
+AlignElements.prototype._alignmentPosition = function (type, sortedElements) {
+ var orientation = this._getOrientationDetails(type),
+ axis = orientation.axis,
+ dimension = orientation.dimension,
+ alignment = {},
+ centers = {},
+ hasSharedCenters = false,
+ centeredElements,
+ firstElement,
+ lastElement;
+
+ function getMiddleOrTop(first, last) {
+ return Math.round((first[axis] + last[axis] + last[dimension]) / 2);
+ }
+
+ if (this._isType(type, ['left', 'top'])) {
+ alignment[type] = sortedElements[0][axis];
+ } else if (this._isType(type, ['right', 'bottom'])) {
+ lastElement = last(sortedElements);
+
+ alignment[type] = lastElement[axis] + lastElement[dimension];
+ } else if (this._isType(type, ['center', 'middle'])) {
+
+ // check if there is a center shared by more than one shape
+ // if not, just take the middle of the range
+ (0, _minDash.forEach)(sortedElements, function (element) {
+ var center = element[axis] + Math.round(element[dimension] / 2);
+
+ if (centers[center]) {
+ centers[center].elements.push(element);
+ } else {
+ centers[center] = {
+ elements: [element],
+ center: center
+ };
+ }
+ });
+
+ centeredElements = (0, _minDash.sortBy)(centers, function (center) {
+ if (center.elements.length > 1) {
+ hasSharedCenters = true;
+ }
+
+ return center.elements.length;
+ });
+
+ if (hasSharedCenters) {
+ alignment[type] = last(centeredElements).center;
+
+ return alignment;
+ }
+
+ firstElement = sortedElements[0];
+
+ sortedElements = (0, _minDash.sortBy)(sortedElements, function (element) {
+ return element[axis] + element[dimension];
+ });
+
+ lastElement = last(sortedElements);
+
+ alignment[type] = getMiddleOrTop(firstElement, lastElement);
+ }
+
+ return alignment;
+};
+
+/**
+ * Executes the alignment of a selection of elements
+ *
+ * @param {Array} elements [description]
+ * @param {String} type left|right|center|top|bottom|middle
+ */
+AlignElements.prototype.trigger = function (elements, type) {
+ var modeling = this._modeling;
+
+ var filteredElements = (0, _minDash.filter)(elements, function (element) {
+ return !(element.waypoints || element.host || element.labelTarget);
+ });
+
+ var sortFn = ALIGNMENT_SORTING[type];
+
+ var sortedElements = (0, _minDash.sortBy)(filteredElements, sortFn);
+
+ var alignment = this._alignmentPosition(type, sortedElements);
+
+ modeling.alignElements(sortedElements, alignment);
+};
+
+},{"min-dash":505}],257:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _AlignElements = require('./AlignElements');
+
+var _AlignElements2 = _interopRequireDefault(_AlignElements);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['alignElements'],
+ alignElements: ['type', _AlignElements2.default]
+};
+
+},{"./AlignElements":256}],258:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AttachSupport;
+
+var _minDash = require('min-dash');
+
+var _Removal = require('../../util/Removal');
+
+var _Collections = require('../../util/Collections');
+
+var _AttachUtil = require('../../util/AttachUtil');
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('../../command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var LOW_PRIORITY = 251,
+ HIGH_PRIORITY = 1401;
+
+/**
+ * Adds the notion of attached elements to the modeler.
+ *
+ * Optionally depends on `diagram-js/lib/features/move` to render
+ * the attached elements during move preview.
+ *
+ * Optionally depends on `diagram-js/lib/features/label-support`
+ * to render attached labels during move preview.
+ *
+ * @param {didi.Injector} injector
+ * @param {EventBus} eventBus
+ * @param {Rules} rules
+ * @param {Modeling} modeling
+ */
+function AttachSupport(injector, eventBus, rules, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ var movePreview = injector.get('movePreview', false);
+
+ // remove all the attached elements from the shapes to be validated
+ // add all the attached shapes to the overall list of moved shapes
+ eventBus.on('shape.move.start', HIGH_PRIORITY, function (e) {
+
+ var context = e.context,
+ shapes = context.shapes,
+ validatedShapes = context.validatedShapes;
+
+ context.shapes = addAttached(shapes);
+
+ context.validatedShapes = removeAttached(validatedShapes);
+ });
+
+ // add attachers to the visual's group
+ movePreview && eventBus.on('shape.move.start', LOW_PRIORITY, function (e) {
+
+ var context = e.context,
+ shapes = context.shapes,
+ attachers = getAttachers(shapes);
+
+ (0, _minDash.forEach)(attachers, function (attacher) {
+ movePreview.makeDraggable(context, attacher, true);
+
+ (0, _minDash.forEach)(attacher.labels, function (label) {
+ movePreview.makeDraggable(context, label, true);
+ });
+ });
+ });
+
+ // add all attachers to move closure
+ this.preExecuted('elements.move', HIGH_PRIORITY, function (e) {
+ var context = e.context,
+ closure = context.closure,
+ shapes = context.shapes,
+ attachers = getAttachers(shapes);
+
+ (0, _minDash.forEach)(attachers, function (attacher) {
+ closure.add(attacher, closure.topLevel[attacher.host.id]);
+ });
+ });
+
+ // perform the attaching after shapes are done moving
+ this.postExecuted('elements.move', function (e) {
+
+ var context = e.context,
+ shapes = context.shapes,
+ newHost = context.newHost,
+ attachers;
+
+ // we only support attachment / detachment of one element
+ if (shapes.length > 1) {
+ return;
+ }
+
+ if (newHost) {
+
+ attachers = shapes;
+ } else {
+
+ attachers = (0, _minDash.filter)(shapes, function (s) {
+ return !!s.host;
+ });
+ }
+
+ (0, _minDash.forEach)(attachers, function (attacher) {
+ modeling.updateAttachment(attacher, newHost);
+ });
+ });
+
+ // ensure invalid attachment connections are removed
+ this.postExecuted('elements.move', function (e) {
+
+ var shapes = e.context.shapes;
+
+ (0, _minDash.forEach)(shapes, function (shape) {
+
+ (0, _minDash.forEach)(shape.attachers, function (attacher) {
+
+ // remove invalid outgoing connections
+ (0, _minDash.forEach)(attacher.outgoing.slice(), function (connection) {
+ var allowed = rules.allowed('connection.reconnectStart', {
+ connection: connection,
+ source: connection.source,
+ target: connection.target
+ });
+
+ if (!allowed) {
+ modeling.removeConnection(connection);
+ }
+ });
+
+ // remove invalid incoming connections
+ (0, _minDash.forEach)(attacher.incoming.slice(), function (connection) {
+ var allowed = rules.allowed('connection.reconnectEnd', {
+ connection: connection,
+ source: connection.source,
+ target: connection.target
+ });
+
+ if (!allowed) {
+ modeling.removeConnection(connection);
+ }
+ });
+ });
+ });
+ });
+
+ this.postExecute('shape.create', function (e) {
+ var context = e.context,
+ shape = context.shape,
+ host = context.host;
+
+ if (host) {
+ modeling.updateAttachment(shape, host);
+ }
+ });
+
+ // update attachments if the host is replaced
+ this.postExecute('shape.replace', function (e) {
+
+ var context = e.context,
+ oldShape = context.oldShape,
+ newShape = context.newShape;
+
+ // move the attachers to the new host
+ (0, _Removal.saveClear)(oldShape.attachers, function (attacher) {
+ var allowed = rules.allowed('elements.move', {
+ target: newShape,
+ shapes: [attacher]
+ });
+
+ if (allowed === 'attach') {
+ modeling.updateAttachment(attacher, newShape);
+ } else {
+ modeling.removeShape(attacher);
+ }
+ });
+
+ // move attachers if new host has different size
+ if (newShape.attachers.length) {
+
+ (0, _minDash.forEach)(newShape.attachers, function (attacher) {
+ var delta = (0, _AttachUtil.getNewAttachShapeDelta)(attacher, oldShape, newShape);
+ modeling.moveShape(attacher, delta, attacher.parent);
+ });
+ }
+ });
+
+ // move shape on host resize
+ this.postExecute('shape.resize', function (event) {
+ var context = event.context,
+ shape = context.shape,
+ oldBounds = context.oldBounds,
+ newBounds = context.newBounds,
+ attachers = shape.attachers;
+
+ (0, _minDash.forEach)(attachers, function (attacher) {
+ var delta = (0, _AttachUtil.getNewAttachShapeDelta)(attacher, oldBounds, newBounds);
+
+ modeling.moveShape(attacher, delta, attacher.parent);
+
+ (0, _minDash.forEach)(attacher.labels, function (label) {
+ modeling.moveShape(label, delta, label.parent);
+ });
+ });
+ });
+
+ // remove attachments
+ this.preExecute('shape.delete', function (event) {
+
+ var shape = event.context.shape;
+
+ (0, _Removal.saveClear)(shape.attachers, function (attacher) {
+ modeling.removeShape(attacher);
+ });
+
+ if (shape.host) {
+ modeling.updateAttachment(shape, null);
+ }
+ });
+
+ // Prevent attachers and their labels from moving, when the space tool is performed.
+ // Otherwise the attachers and their labels would be moved twice.
+ eventBus.on('spaceTool.move', function (event) {
+
+ var context = event.context,
+ initialized = context.initialized,
+ attachSupportInitialized = context.attachSupportInitialized;
+
+ if (!initialized || attachSupportInitialized) {
+ return;
+ }
+
+ var movingShapes = context.movingShapes;
+
+ // collect attachers whose host is not being moved using the space tool
+ var staticAttachers = (0, _minDash.filter)(movingShapes, function (shape) {
+ var host = shape.host;
+
+ return host && movingShapes.indexOf(host) === -1;
+ });
+
+ // remove attachers that are not going to be moved from moving shapes
+ (0, _minDash.forEach)(staticAttachers, function (shape) {
+ (0, _Collections.remove)(movingShapes, shape);
+
+ (0, _minDash.forEach)(shape.labels, function (label) {
+ (0, _Collections.remove)(movingShapes, shape.label);
+ });
+ });
+
+ context.attachSupportInitialized = true;
+ });
+}
+
+(0, _inherits2.default)(AttachSupport, _CommandInterceptor2.default);
+
+AttachSupport.$inject = ['injector', 'eventBus', 'rules', 'modeling'];
+
+/**
+ * Return attachers of the given shapes
+ *
+ * @param {Array} shapes
+ * @return {Array}
+ */
+function getAttachers(shapes) {
+ return (0, _minDash.flatten)((0, _minDash.map)(shapes, function (s) {
+ return s.attachers || [];
+ }));
+}
+
+/**
+ * Return a combined list of elements and
+ * attachers.
+ *
+ * @param {Array} elements
+ * @return {Array} filtered
+ */
+function addAttached(elements) {
+ var attachers = getAttachers(elements);
+
+ return (0, _minDash.unionBy)('id', elements, attachers);
+}
+
+/**
+ * Return a filtered list of elements that do not
+ * contain attached elements with hosts being part
+ * of the selection.
+ *
+ * @param {Array} elements
+ *
+ * @return {Array} filtered
+ */
+function removeAttached(elements) {
+
+ var ids = (0, _minDash.groupBy)(elements, 'id');
+
+ return (0, _minDash.filter)(elements, function (element) {
+ while (element) {
+
+ // host in selection
+ if (element.host && ids[element.host.id]) {
+ return false;
+ }
+
+ element = element.parent;
+ }
+
+ return true;
+ });
+}
+
+},{"../../command/CommandInterceptor":243,"../../util/AttachUtil":391,"../../util/Collections":393,"../../util/Removal":406,"inherits":415,"min-dash":505}],259:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _rules = require('../rules');
+
+var _rules2 = _interopRequireDefault(_rules);
+
+var _AttachSupport = require('./AttachSupport');
+
+var _AttachSupport2 = _interopRequireDefault(_AttachSupport);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_rules2.default],
+ __init__: ['attachSupport'],
+ attachSupport: ['type', _AttachSupport2.default]
+};
+
+},{"../rules":355,"./AttachSupport":258}],260:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AutoResize;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _Elements = require('../../util/Elements');
+
+var _LayoutUtil = require('../../layout/LayoutUtil');
+
+var _minDash = require('min-dash');
+
+var _CommandInterceptor = require('../../command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * An auto resize component that takes care of expanding a parent element
+ * if child elements are created or moved close the parents edge.
+ *
+ * @param {EventBus} eventBus
+ * @param {ElementRegistry} elementRegistry
+ * @param {Modeling} modeling
+ * @param {Rules} rules
+ */
+function AutoResize(eventBus, elementRegistry, modeling, rules) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ this._elementRegistry = elementRegistry;
+ this._modeling = modeling;
+ this._rules = rules;
+
+ var self = this;
+
+ this.postExecuted(['shape.create'], function (event) {
+ var context = event.context,
+ hints = context.hints,
+ shape = context.shape,
+ parent = context.parent || context.newParent;
+
+ if (hints && (hints.root === false || hints.autoResize === false)) {
+ return;
+ }
+
+ self._expand([shape], parent);
+ });
+
+ this.postExecuted(['elements.move'], function (event) {
+ var context = event.context,
+ elements = (0, _minDash.flatten)((0, _minDash.values)(context.closure.topLevel)),
+ hints = context.hints;
+
+ var autoResize = hints ? hints.autoResize : true;
+
+ if (autoResize === false) {
+ return;
+ }
+
+ var expandings = (0, _minDash.groupBy)(elements, function (element) {
+ return element.parent.id;
+ });
+
+ (0, _minDash.forEach)(expandings, function (elements, parentId) {
+
+ // optionally filter elements to be considered when resizing
+ if ((0, _minDash.isArray)(autoResize)) {
+ elements = elements.filter(function (element) {
+ return autoResize.indexOf(element) !== -1;
+ });
+ }
+
+ self._expand(elements, parentId);
+ });
+ });
+
+ this.postExecuted(['shape.toggleCollapse'], function (event) {
+ var context = event.context,
+ hints = context.hints,
+ shape = context.shape;
+
+ if (hints && (hints.root === false || hints.autoResize === false)) {
+ return;
+ }
+
+ if (shape.collapsed) {
+ return;
+ }
+
+ self._expand(shape.children || [], shape);
+ });
+
+ this.postExecuted(['shape.resize'], function (event) {
+ var context = event.context,
+ hints = context.hints,
+ shape = context.shape,
+ parent = shape.parent;
+
+ if (hints && (hints.root === false || hints.autoResize === false)) {
+ return;
+ }
+
+ if (parent) {
+ self._expand([shape], parent);
+ }
+ });
+}
+
+AutoResize.$inject = ['eventBus', 'elementRegistry', 'modeling', 'rules'];
+
+(0, _inherits2.default)(AutoResize, _CommandInterceptor2.default);
+
+/**
+ * Calculate the new bounds of the target shape, given
+ * a number of elements have been moved or added into the parent.
+ *
+ * This method considers the current size, the added elements as well as
+ * the provided padding for the new bounds.
+ *
+ * @param {Array} elements
+ * @param {djs.model.Shape} target
+ */
+AutoResize.prototype._getOptimalBounds = function (elements, target) {
+
+ var offset = this.getOffset(target),
+ padding = this.getPadding(target);
+
+ var elementsTrbl = (0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(elements)),
+ targetTrbl = (0, _LayoutUtil.asTRBL)(target);
+
+ var newTrbl = {};
+
+ if (elementsTrbl.top - targetTrbl.top < padding.top) {
+ newTrbl.top = elementsTrbl.top - offset.top;
+ }
+
+ if (elementsTrbl.left - targetTrbl.left < padding.left) {
+ newTrbl.left = elementsTrbl.left - offset.left;
+ }
+
+ if (targetTrbl.right - elementsTrbl.right < padding.right) {
+ newTrbl.right = elementsTrbl.right + offset.right;
+ }
+
+ if (targetTrbl.bottom - elementsTrbl.bottom < padding.bottom) {
+ newTrbl.bottom = elementsTrbl.bottom + offset.bottom;
+ }
+
+ return (0, _LayoutUtil.asBounds)((0, _minDash.assign)({}, targetTrbl, newTrbl));
+};
+
+/**
+ * Expand the target shape respecting rules, offset and padding
+ *
+ * @param {Array} elements
+ * @param {djs.model.Shape|String} target|targetId
+ */
+AutoResize.prototype._expand = function (elements, target) {
+
+ if (typeof target === 'string') {
+ target = this._elementRegistry.get(target);
+ }
+
+ var allowed = this._rules.allowed('element.autoResize', {
+ elements: elements,
+ target: target
+ });
+
+ if (!allowed) {
+ return;
+ }
+
+ // calculate the new bounds
+ var newBounds = this._getOptimalBounds(elements, target);
+
+ if (!boundsChanged(newBounds, target)) {
+ return;
+ }
+
+ // resize the parent shape
+ this.resize(target, newBounds);
+
+ var parent = target.parent;
+
+ // recursively expand parent elements
+ if (parent) {
+ this._expand([target], parent);
+ }
+};
+
+/**
+ * Get the amount to expand the given shape in each direction.
+ *
+ * @param {djs.model.Shape} shape
+ *
+ * @return {Object} {top, bottom, left, right}
+ */
+AutoResize.prototype.getOffset = function (shape) {
+ return { top: 60, bottom: 60, left: 100, right: 100 };
+};
+
+/**
+ * Get the activation threshold for each side for which
+ * resize triggers.
+ *
+ * @param {djs.model.Shape} shape
+ *
+ * @return {Object} {top, bottom, left, right}
+ */
+AutoResize.prototype.getPadding = function (shape) {
+ return { top: 2, bottom: 2, left: 15, right: 15 };
+};
+
+/**
+ * Perform the actual resize operation.
+ *
+ * @param {djs.model.Shape} target
+ * @param {Object} newBounds
+ */
+AutoResize.prototype.resize = function (target, newBounds) {
+ this._modeling.resizeShape(target, newBounds);
+};
+
+function boundsChanged(newBounds, oldBounds) {
+ return newBounds.x !== oldBounds.x || newBounds.y !== oldBounds.y || newBounds.width !== oldBounds.width || newBounds.height !== oldBounds.height;
+}
+
+},{"../../command/CommandInterceptor":243,"../../layout/LayoutUtil":380,"../../util/Elements":396,"inherits":415,"min-dash":505}],261:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AutoResizeProvider;
+
+var _RuleProvider = require('../rules/RuleProvider');
+
+var _RuleProvider2 = _interopRequireDefault(_RuleProvider);
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * This is a base rule provider for the element.autoResize rule.
+ */
+function AutoResizeProvider(eventBus) {
+
+ _RuleProvider2.default.call(this, eventBus);
+
+ var self = this;
+
+ this.addRule('element.autoResize', function (context) {
+ return self.canResize(context.elements, context.target);
+ });
+}
+
+AutoResizeProvider.$inject = ['eventBus'];
+
+(0, _inherits2.default)(AutoResizeProvider, _RuleProvider2.default);
+
+/**
+ * Needs to be implemented by sub classes to allow actual auto resize
+ *
+ * @param {Array} elements
+ * @param {djs.model.Shape} target
+ *
+ * @return {Boolean}
+ */
+AutoResizeProvider.prototype.canResize = function (elements, target) {
+ return false;
+};
+
+},{"../rules/RuleProvider":353,"inherits":415}],262:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AutoScroll;
+
+var _minDash = require('min-dash');
+
+var _Event = require('../../util/Event');
+
+/**
+ * Initiates canvas scrolling if current cursor point is close to a border.
+ * Cancelled when current point moves back inside the scrolling borders
+ * or cancelled manually.
+ *
+ * Default options :
+ * scrollThresholdIn: [ 20, 20, 20, 20 ],
+ * scrollThresholdOut: [ 0, 0, 0, 0 ],
+ * scrollRepeatTimeout: 15,
+ * scrollStep: 10
+ *
+ * Threshold order:
+ * [ left, top, right, bottom ]
+ */
+function AutoScroll(config, eventBus, canvas, mouseTracking) {
+
+ this._canvas = canvas;
+ this._mouseTracking = mouseTracking;
+
+ this._opts = (0, _minDash.assign)({
+ scrollThresholdIn: [20, 20, 20, 20],
+ scrollThresholdOut: [0, 0, 0, 0],
+ scrollRepeatTimeout: 15,
+ scrollStep: 10
+ }, config);
+
+ var self = this;
+
+ eventBus.on('drag.move', function (e) {
+ var point = self._toBorderPoint(e);
+
+ self.startScroll(point);
+ });
+
+ eventBus.on(['drag.cleanup'], function () {
+ self.stopScroll();
+ });
+}
+
+AutoScroll.$inject = ['config.autoScroll', 'eventBus', 'canvas', 'mouseTracking'];
+
+/**
+ * Starts scrolling loop.
+ * Point is given in global scale in canvas container box plane.
+ *
+ * @param {Object} point { x: X, y: Y }
+ */
+AutoScroll.prototype.startScroll = function (point) {
+
+ var canvas = this._canvas;
+ var opts = this._opts;
+ var self = this;
+
+ var clientRect = canvas.getContainer().getBoundingClientRect();
+
+ var diff = [point.x, point.y, clientRect.width - point.x, clientRect.height - point.y];
+
+ this.stopScroll();
+
+ var dx = 0,
+ dy = 0;
+
+ for (var i = 0; i < 4; i++) {
+ if (between(diff[i], opts.scrollThresholdOut[i], opts.scrollThresholdIn[i])) {
+ if (i === 0) {
+ dx = opts.scrollStep;
+ } else if (i == 1) {
+ dy = opts.scrollStep;
+ } else if (i == 2) {
+ dx = -opts.scrollStep;
+ } else if (i == 3) {
+ dy = -opts.scrollStep;
+ }
+ }
+ }
+
+ if (dx !== 0 || dy !== 0) {
+ canvas.scroll({ dx: dx, dy: dy });
+
+ this._scrolling = setTimeout(function () {
+ self.startScroll(point);
+ }, opts.scrollRepeatTimeout);
+ }
+};
+
+function between(val, start, end) {
+ if (start < val && val < end) {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Stops scrolling loop.
+ */
+AutoScroll.prototype.stopScroll = function () {
+ clearTimeout(this._scrolling);
+};
+
+/**
+ * Overrides defaults options.
+ *
+ * @param {Object} options
+ */
+AutoScroll.prototype.setOptions = function (options) {
+ this._opts = (0, _minDash.assign)({}, this._opts, options);
+};
+
+/**
+ * Converts event to a point in canvas container plane in global scale.
+ *
+ * @param {Event} event
+ * @return {Point}
+ */
+AutoScroll.prototype._toBorderPoint = function (event) {
+ var clientRect = this._canvas._container.getBoundingClientRect();
+
+ var globalPosition = (0, _Event.toPoint)(event.originalEvent);
+
+ return {
+ x: globalPosition.x - clientRect.left,
+ y: globalPosition.y - clientRect.top
+ };
+};
+
+},{"../../util/Event":397,"min-dash":505}],263:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _dragging = require('../dragging');
+
+var _dragging2 = _interopRequireDefault(_dragging);
+
+var _mouseTracking = require('../mouse-tracking');
+
+var _mouseTracking2 = _interopRequireDefault(_mouseTracking);
+
+var _AutoScroll = require('./AutoScroll');
+
+var _AutoScroll2 = _interopRequireDefault(_AutoScroll);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_dragging2.default, _mouseTracking2.default],
+ __init__: ['autoScroll'],
+ autoScroll: ['type', _AutoScroll2.default]
+};
+
+},{"../dragging":286,"../mouse-tracking":331,"./AutoScroll":262}],264:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BendpointMove;
+
+var _Geometry = require('../../util/Geometry');
+
+var _BendpointUtil = require('./BendpointUtil');
+
+var _tinySvg = require('tiny-svg');
+
+var _SvgTransformUtil = require('../../util/SvgTransformUtil');
+
+var MARKER_OK = 'connect-ok',
+ MARKER_NOT_OK = 'connect-not-ok',
+ MARKER_CONNECT_HOVER = 'connect-hover',
+ MARKER_CONNECT_UPDATING = 'djs-updating';
+
+var COMMAND_BENDPOINT_UPDATE = 'connection.updateWaypoints',
+ COMMAND_RECONNECT_START = 'connection.reconnectStart',
+ COMMAND_RECONNECT_END = 'connection.reconnectEnd';
+
+var round = Math.round;
+
+/**
+ * A component that implements moving of bendpoints
+ */
+function BendpointMove(injector, eventBus, canvas, dragging, graphicsFactory, rules, modeling) {
+
+ // optional connection docking integration
+ var connectionDocking = injector.get('connectionDocking', false);
+
+ // API
+
+ this.start = function (event, connection, bendpointIndex, insert) {
+
+ var type,
+ context,
+ waypoints = connection.waypoints,
+ gfx = canvas.getGraphics(connection);
+
+ if (!insert && bendpointIndex === 0) {
+ type = COMMAND_RECONNECT_START;
+ } else if (!insert && bendpointIndex === waypoints.length - 1) {
+ type = COMMAND_RECONNECT_END;
+ } else {
+ type = COMMAND_BENDPOINT_UPDATE;
+ }
+
+ context = {
+ connection: connection,
+ bendpointIndex: bendpointIndex,
+ insert: insert,
+ type: type
+ };
+
+ dragging.init(event, 'bendpoint.move', {
+ data: {
+ connection: connection,
+ connectionGfx: gfx,
+ context: context
+ }
+ });
+ };
+
+ // DRAGGING IMPLEMENTATION
+
+
+ function redrawConnection(data) {
+ graphicsFactory.update('connection', data.connection, data.connectionGfx);
+ }
+
+ function filterRedundantWaypoints(waypoints) {
+
+ // alter copy of waypoints, not original
+ waypoints = waypoints.slice();
+
+ var idx = 0,
+ point,
+ previousPoint,
+ nextPoint;
+
+ while (waypoints[idx]) {
+ point = waypoints[idx];
+ previousPoint = waypoints[idx - 1];
+ nextPoint = waypoints[idx + 1];
+
+ if ((0, _Geometry.pointDistance)(point, nextPoint) === 0 || (0, _Geometry.pointsOnLine)(previousPoint, nextPoint, point)) {
+
+ // remove point, if overlapping with {nextPoint}
+ // or on line with {previousPoint} -> {point} -> {nextPoint}
+ waypoints.splice(idx, 1);
+ } else {
+ idx++;
+ }
+ }
+
+ return waypoints;
+ }
+
+ eventBus.on('bendpoint.move.start', function (e) {
+
+ var context = e.context,
+ connection = context.connection,
+ originalWaypoints = connection.waypoints,
+ waypoints = originalWaypoints.slice(),
+ insert = context.insert,
+ idx = context.bendpointIndex;
+
+ context.originalWaypoints = originalWaypoints;
+
+ if (insert) {
+ // insert placeholder for bendpoint to-be-added
+ waypoints.splice(idx, 0, null);
+ }
+
+ connection.waypoints = waypoints;
+
+ // add dragger gfx
+ context.draggerGfx = (0, _BendpointUtil.addBendpoint)(canvas.getLayer('overlays'));
+ (0, _tinySvg.classes)(context.draggerGfx).add('djs-dragging');
+
+ canvas.addMarker(connection, MARKER_CONNECT_UPDATING);
+ });
+
+ eventBus.on('bendpoint.move.hover', function (e) {
+ var context = e.context;
+
+ context.hover = e.hover;
+
+ if (e.hover) {
+ canvas.addMarker(e.hover, MARKER_CONNECT_HOVER);
+
+ // asks whether reconnect / bendpoint move / bendpoint add
+ // is allowed at the given position
+ var allowed = context.allowed = rules.allowed(context.type, context);
+
+ if (allowed) {
+ canvas.removeMarker(context.hover, MARKER_NOT_OK);
+ canvas.addMarker(context.hover, MARKER_OK);
+
+ context.target = context.hover;
+ } else if (allowed === false) {
+ canvas.removeMarker(context.hover, MARKER_OK);
+ canvas.addMarker(context.hover, MARKER_NOT_OK);
+
+ context.target = null;
+ }
+ }
+ });
+
+ eventBus.on(['bendpoint.move.out', 'bendpoint.move.cleanup'], function (e) {
+
+ // remove connect marker
+ // if it was added
+ var hover = e.context.hover;
+
+ if (hover) {
+ canvas.removeMarker(hover, MARKER_CONNECT_HOVER);
+ canvas.removeMarker(hover, e.context.target ? MARKER_OK : MARKER_NOT_OK);
+ }
+ });
+
+ eventBus.on('bendpoint.move.move', function (e) {
+
+ var context = e.context,
+ moveType = context.type,
+ connection = e.connection,
+ source,
+ target;
+
+ connection.waypoints[context.bendpointIndex] = { x: e.x, y: e.y };
+
+ if (connectionDocking) {
+
+ if (context.hover) {
+ if (moveType === COMMAND_RECONNECT_START) {
+ source = context.hover;
+ }
+
+ if (moveType === COMMAND_RECONNECT_END) {
+ target = context.hover;
+ }
+ }
+
+ connection.waypoints = connectionDocking.getCroppedWaypoints(connection, source, target);
+ }
+
+ // add dragger gfx
+ (0, _SvgTransformUtil.translate)(context.draggerGfx, e.x, e.y);
+
+ redrawConnection(e);
+ });
+
+ eventBus.on(['bendpoint.move.end', 'bendpoint.move.cancel'], function (e) {
+
+ var context = e.context,
+ hover = context.hover,
+ connection = context.connection;
+
+ // remove dragger gfx
+ (0, _tinySvg.remove)(context.draggerGfx);
+ context.newWaypoints = connection.waypoints.slice();
+ connection.waypoints = context.originalWaypoints;
+ canvas.removeMarker(connection, MARKER_CONNECT_UPDATING);
+
+ if (hover) {
+ canvas.removeMarker(hover, MARKER_OK);
+ canvas.removeMarker(hover, MARKER_NOT_OK);
+ }
+ });
+
+ eventBus.on('bendpoint.move.end', function (e) {
+
+ var context = e.context,
+ waypoints = context.newWaypoints,
+ bendpointIndex = context.bendpointIndex,
+ bendpoint = waypoints[bendpointIndex],
+ allowed = context.allowed,
+ hints;
+
+ // ensure we have actual pixel values bendpoint
+ // coordinates (important when zoom level was > 1 during move)
+ bendpoint.x = round(bendpoint.x);
+ bendpoint.y = round(bendpoint.y);
+
+ if (allowed && context.type === COMMAND_RECONNECT_START) {
+ modeling.reconnectStart(context.connection, context.target, bendpoint);
+ } else if (allowed && context.type === COMMAND_RECONNECT_END) {
+ modeling.reconnectEnd(context.connection, context.target, bendpoint);
+ } else if (allowed !== false && context.type === COMMAND_BENDPOINT_UPDATE) {
+
+ // pass hints on the actual moved bendpoint
+ // this is useful for connection and label layouting
+ hints = {
+ bendpointMove: {
+ insert: e.context.insert,
+ bendpointIndex: bendpointIndex
+ }
+ };
+
+ modeling.updateWaypoints(context.connection, filterRedundantWaypoints(waypoints), hints);
+ } else {
+ redrawConnection(e);
+
+ return false;
+ }
+ });
+
+ eventBus.on('bendpoint.move.cancel', function (e) {
+ redrawConnection(e);
+ });
+}
+
+BendpointMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'graphicsFactory', 'rules', 'modeling'];
+
+},{"../../util/Geometry":398,"../../util/SvgTransformUtil":408,"./BendpointUtil":266,"tiny-svg":535}],265:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = BendpointSnapping;
+
+var _minDash = require('min-dash');
+
+var abs = Math.abs,
+ round = Math.round;
+
+var TOLERANCE = 10;
+
+function BendpointSnapping(eventBus) {
+
+ function snapTo(values, value) {
+
+ if ((0, _minDash.isArray)(values)) {
+ var i = values.length;
+
+ while (i--) {
+ if (abs(values[i] - value) <= TOLERANCE) {
+ return values[i];
+ }
+ }
+ } else {
+ values = +values;
+ var rem = value % values;
+
+ if (rem < TOLERANCE) {
+ return value - rem;
+ }
+
+ if (rem > values - TOLERANCE) {
+ return value - rem + values;
+ }
+ }
+
+ return value;
+ }
+
+ function mid(element) {
+ if (element.width) {
+ return {
+ x: round(element.width / 2 + element.x),
+ y: round(element.height / 2 + element.y)
+ };
+ }
+ }
+
+ // connection segment snapping //////////////////////
+
+ function getConnectionSegmentSnaps(context) {
+
+ var snapPoints = context.snapPoints,
+ connection = context.connection,
+ waypoints = connection.waypoints,
+ segmentStart = context.segmentStart,
+ segmentStartIndex = context.segmentStartIndex,
+ segmentEnd = context.segmentEnd,
+ segmentEndIndex = context.segmentEndIndex,
+ axis = context.axis;
+
+ if (snapPoints) {
+ return snapPoints;
+ }
+
+ var referenceWaypoints = [waypoints[segmentStartIndex - 1], segmentStart, segmentEnd, waypoints[segmentEndIndex + 1]];
+
+ if (segmentStartIndex < 2) {
+ referenceWaypoints.unshift(mid(connection.source));
+ }
+
+ if (segmentEndIndex > waypoints.length - 3) {
+ referenceWaypoints.unshift(mid(connection.target));
+ }
+
+ context.snapPoints = snapPoints = { horizontal: [], vertical: [] };
+
+ (0, _minDash.forEach)(referenceWaypoints, function (p) {
+ // we snap on existing bendpoints only,
+ // not placeholders that are inserted during add
+ if (p) {
+ p = p.original || p;
+
+ if (axis === 'y') {
+ snapPoints.horizontal.push(p.y);
+ }
+
+ if (axis === 'x') {
+ snapPoints.vertical.push(p.x);
+ }
+ }
+ });
+
+ return snapPoints;
+ }
+
+ eventBus.on('connectionSegment.move.move', 1500, function (event) {
+ var context = event.context,
+ snapPoints = getConnectionSegmentSnaps(context),
+ x = event.x,
+ y = event.y,
+ sx,
+ sy;
+
+ if (!snapPoints) {
+ return;
+ }
+
+ // snap
+ sx = snapTo(snapPoints.vertical, x);
+ sy = snapTo(snapPoints.horizontal, y);
+
+ // correction x/y
+ var cx = x - sx,
+ cy = y - sy;
+
+ // update delta
+ (0, _minDash.assign)(event, {
+ dx: event.dx - cx,
+ dy: event.dy - cy,
+ x: sx,
+ y: sy
+ });
+ });
+
+ // bendpoint snapping //////////////////////
+
+ function getBendpointSnaps(context) {
+
+ var snapPoints = context.snapPoints,
+ waypoints = context.connection.waypoints,
+ bendpointIndex = context.bendpointIndex;
+
+ if (snapPoints) {
+ return snapPoints;
+ }
+
+ var referenceWaypoints = [waypoints[bendpointIndex - 1], waypoints[bendpointIndex + 1]];
+
+ context.snapPoints = snapPoints = { horizontal: [], vertical: [] };
+
+ (0, _minDash.forEach)(referenceWaypoints, function (p) {
+ // we snap on existing bendpoints only,
+ // not placeholders that are inserted during add
+ if (p) {
+ p = p.original || p;
+
+ snapPoints.horizontal.push(p.y);
+ snapPoints.vertical.push(p.x);
+ }
+ });
+
+ return snapPoints;
+ }
+
+ eventBus.on('bendpoint.move.move', 1500, function (event) {
+
+ var context = event.context,
+ snapPoints = getBendpointSnaps(context),
+ target = context.target,
+ targetMid = target && mid(target),
+ x = event.x,
+ y = event.y,
+ sx,
+ sy;
+
+ if (!snapPoints) {
+ return;
+ }
+
+ // snap
+ sx = snapTo(targetMid ? snapPoints.vertical.concat([targetMid.x]) : snapPoints.vertical, x);
+ sy = snapTo(targetMid ? snapPoints.horizontal.concat([targetMid.y]) : snapPoints.horizontal, y);
+
+ // correction x/y
+ var cx = x - sx,
+ cy = y - sy;
+
+ // update delta
+ (0, _minDash.assign)(event, {
+ dx: event.dx - cx,
+ dy: event.dy - cy,
+ x: event.x - cx,
+ y: event.y - cy
+ });
+ });
+}
+
+BendpointSnapping.$inject = ['eventBus'];
+
+},{"min-dash":505}],266:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.SEGMENT_DRAGGER_CLS = exports.BENDPOINT_CLS = undefined;
+exports.toCanvasCoordinates = toCanvasCoordinates;
+exports.addBendpoint = addBendpoint;
+exports.addSegmentDragger = addSegmentDragger;
+
+var _Event = require('../../util/Event');
+
+var _Geometry = require('../../util/Geometry');
+
+var _tinySvg = require('tiny-svg');
+
+var _SvgTransformUtil = require('../../util/SvgTransformUtil');
+
+var BENDPOINT_CLS = exports.BENDPOINT_CLS = 'djs-bendpoint';
+var SEGMENT_DRAGGER_CLS = exports.SEGMENT_DRAGGER_CLS = 'djs-segment-dragger';
+
+function toCanvasCoordinates(canvas, event) {
+
+ var position = (0, _Event.toPoint)(event),
+ clientRect = canvas._container.getBoundingClientRect(),
+ offset;
+
+ // canvas relative position
+
+ offset = {
+ x: clientRect.left,
+ y: clientRect.top
+ };
+
+ // update actual event payload with canvas relative measures
+
+ var viewbox = canvas.viewbox();
+
+ return {
+ x: viewbox.x + (position.x - offset.x) / viewbox.scale,
+ y: viewbox.y + (position.y - offset.y) / viewbox.scale
+ };
+}
+
+function addBendpoint(parentGfx, cls) {
+ var groupGfx = (0, _tinySvg.create)('g');
+ (0, _tinySvg.classes)(groupGfx).add(BENDPOINT_CLS);
+
+ (0, _tinySvg.append)(parentGfx, groupGfx);
+
+ var visual = (0, _tinySvg.create)('circle');
+ (0, _tinySvg.attr)(visual, {
+ cx: 0,
+ cy: 0,
+ r: 4
+ });
+ (0, _tinySvg.classes)(visual).add('djs-visual');
+
+ (0, _tinySvg.append)(groupGfx, visual);
+
+ var hit = (0, _tinySvg.create)('circle');
+ (0, _tinySvg.attr)(hit, {
+ cx: 0,
+ cy: 0,
+ r: 10
+ });
+ (0, _tinySvg.classes)(hit).add('djs-hit');
+
+ (0, _tinySvg.append)(groupGfx, hit);
+
+ if (cls) {
+ (0, _tinySvg.classes)(groupGfx).add(cls);
+ }
+
+ return groupGfx;
+}
+
+function createParallelDragger(parentGfx, position, alignment) {
+ var draggerGfx = (0, _tinySvg.create)('g');
+
+ (0, _tinySvg.append)(parentGfx, draggerGfx);
+
+ var width = 14,
+ height = 3,
+ padding = 6,
+ hitWidth = width + padding,
+ hitHeight = height + padding;
+
+ var visual = (0, _tinySvg.create)('rect');
+ (0, _tinySvg.attr)(visual, {
+ x: -width / 2,
+ y: -height / 2,
+ width: width,
+ height: height
+ });
+ (0, _tinySvg.classes)(visual).add('djs-visual');
+
+ (0, _tinySvg.append)(draggerGfx, visual);
+
+ var hit = (0, _tinySvg.create)('rect');
+ (0, _tinySvg.attr)(hit, {
+ x: -hitWidth / 2,
+ y: -hitHeight / 2,
+ width: hitWidth,
+ height: hitHeight
+ });
+ (0, _tinySvg.classes)(hit).add('djs-hit');
+
+ (0, _tinySvg.append)(draggerGfx, hit);
+
+ (0, _SvgTransformUtil.rotate)(draggerGfx, alignment === 'h' ? 90 : 0, 0, 0);
+
+ return draggerGfx;
+}
+
+function addSegmentDragger(parentGfx, segmentStart, segmentEnd) {
+
+ var groupGfx = (0, _tinySvg.create)('g'),
+ mid = (0, _Geometry.getMidPoint)(segmentStart, segmentEnd),
+ alignment = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd);
+
+ (0, _tinySvg.append)(parentGfx, groupGfx);
+
+ createParallelDragger(groupGfx, mid, alignment);
+
+ (0, _tinySvg.classes)(groupGfx).add(SEGMENT_DRAGGER_CLS);
+ (0, _tinySvg.classes)(groupGfx).add(alignment === 'h' ? 'vertical' : 'horizontal');
+
+ (0, _SvgTransformUtil.translate)(groupGfx, mid.x, mid.y);
+
+ return groupGfx;
+}
+
+},{"../../util/Event":397,"../../util/Geometry":398,"../../util/SvgTransformUtil":408,"tiny-svg":535}],267:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Bendpoints;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var _BendpointUtil = require('./BendpointUtil');
+
+var _css = require('css.escape');
+
+var _css2 = _interopRequireDefault(_css);
+
+var _Geometry = require('../../util/Geometry');
+
+var _LineIntersection = require('../../util/LineIntersection');
+
+var _tinySvg = require('tiny-svg');
+
+var _SvgTransformUtil = require('../../util/SvgTransformUtil');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A service that adds editable bendpoints to connections.
+ */
+function Bendpoints(eventBus, canvas, interactionEvents, bendpointMove, connectionSegmentMove) {
+
+ function getConnectionIntersection(waypoints, event) {
+ var localPosition = (0, _BendpointUtil.toCanvasCoordinates)(canvas, event),
+ intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, localPosition);
+
+ return intersection;
+ }
+
+ function isIntersectionMiddle(intersection, waypoints, treshold) {
+ var idx = intersection.index,
+ p = intersection.point,
+ p0,
+ p1,
+ mid,
+ aligned,
+ xDelta,
+ yDelta;
+
+ if (idx <= 0 || intersection.bendpoint) {
+ return false;
+ }
+
+ p0 = waypoints[idx - 1];
+ p1 = waypoints[idx];
+ mid = (0, _Geometry.getMidPoint)(p0, p1), aligned = (0, _Geometry.pointsAligned)(p0, p1);
+ xDelta = Math.abs(p.x - mid.x);
+ yDelta = Math.abs(p.y - mid.y);
+
+ return aligned && xDelta <= treshold && yDelta <= treshold;
+ }
+
+ function activateBendpointMove(event, connection) {
+ var waypoints = connection.waypoints,
+ intersection = getConnectionIntersection(waypoints, event);
+
+ if (!intersection) {
+ return;
+ }
+
+ if (isIntersectionMiddle(intersection, waypoints, 10)) {
+ connectionSegmentMove.start(event, connection, intersection.index);
+ } else {
+ bendpointMove.start(event, connection, intersection.index, !intersection.bendpoint);
+ }
+
+ // we've handled the event
+ return true;
+ }
+
+ function bindInteractionEvents(node, eventName, element) {
+
+ _minDom.event.bind(node, eventName, function (event) {
+ interactionEvents.triggerMouseEvent(eventName, event, element);
+ event.stopPropagation();
+ });
+ }
+
+ function getBendpointsContainer(element, create) {
+
+ var layer = canvas.getLayer('overlays'),
+ gfx = (0, _minDom.query)('.djs-bendpoints[data-element-id="' + (0, _css2.default)(element.id) + '"]', layer);
+
+ if (!gfx && create) {
+ gfx = (0, _tinySvg.create)('g');
+ (0, _tinySvg.attr)(gfx, { 'data-element-id': element.id });
+ (0, _tinySvg.classes)(gfx).add('djs-bendpoints');
+
+ (0, _tinySvg.append)(layer, gfx);
+
+ bindInteractionEvents(gfx, 'mousedown', element);
+ bindInteractionEvents(gfx, 'click', element);
+ bindInteractionEvents(gfx, 'dblclick', element);
+ }
+
+ return gfx;
+ }
+
+ function createBendpoints(gfx, connection) {
+ connection.waypoints.forEach(function (p, idx) {
+ var bendpoint = (0, _BendpointUtil.addBendpoint)(gfx);
+
+ (0, _tinySvg.append)(gfx, bendpoint);
+
+ (0, _SvgTransformUtil.translate)(bendpoint, p.x, p.y);
+ });
+
+ // add floating bendpoint
+ (0, _BendpointUtil.addBendpoint)(gfx, 'floating');
+ }
+
+ function createSegmentDraggers(gfx, connection) {
+
+ var waypoints = connection.waypoints;
+
+ var segmentStart, segmentEnd;
+
+ for (var i = 1; i < waypoints.length; i++) {
+
+ segmentStart = waypoints[i - 1];
+ segmentEnd = waypoints[i];
+
+ if ((0, _Geometry.pointsAligned)(segmentStart, segmentEnd)) {
+ (0, _BendpointUtil.addSegmentDragger)(gfx, segmentStart, segmentEnd);
+ }
+ }
+ }
+
+ function clearBendpoints(gfx) {
+ (0, _minDash.forEach)((0, _minDom.queryAll)('.' + _BendpointUtil.BENDPOINT_CLS, gfx), function (node) {
+ (0, _tinySvg.remove)(node);
+ });
+ }
+
+ function clearSegmentDraggers(gfx) {
+ (0, _minDash.forEach)((0, _minDom.queryAll)('.' + _BendpointUtil.SEGMENT_DRAGGER_CLS, gfx), function (node) {
+ (0, _tinySvg.remove)(node);
+ });
+ }
+
+ function addHandles(connection) {
+
+ var gfx = getBendpointsContainer(connection);
+
+ if (!gfx) {
+ gfx = getBendpointsContainer(connection, true);
+
+ createBendpoints(gfx, connection);
+ createSegmentDraggers(gfx, connection);
+ }
+
+ return gfx;
+ }
+
+ function updateHandles(connection) {
+
+ var gfx = getBendpointsContainer(connection);
+
+ if (gfx) {
+ clearSegmentDraggers(gfx);
+ clearBendpoints(gfx);
+ createSegmentDraggers(gfx, connection);
+ createBendpoints(gfx, connection);
+ }
+ }
+
+ eventBus.on('connection.changed', function (event) {
+ updateHandles(event.element);
+ });
+
+ eventBus.on('connection.remove', function (event) {
+ var gfx = getBendpointsContainer(event.element);
+
+ if (gfx) {
+ (0, _tinySvg.remove)(gfx);
+ }
+ });
+
+ eventBus.on('element.marker.update', function (event) {
+
+ var element = event.element,
+ bendpointsGfx;
+
+ if (!element.waypoints) {
+ return;
+ }
+
+ bendpointsGfx = addHandles(element);
+
+ if (event.add) {
+ (0, _tinySvg.classes)(bendpointsGfx).add(event.marker);
+ } else {
+ (0, _tinySvg.classes)(bendpointsGfx).remove(event.marker);
+ }
+ });
+
+ eventBus.on('element.mousemove', function (event) {
+
+ var element = event.element,
+ waypoints = element.waypoints,
+ bendpointsGfx,
+ floating,
+ intersection;
+
+ if (waypoints) {
+ bendpointsGfx = getBendpointsContainer(element, true);
+ floating = (0, _minDom.query)('.floating', bendpointsGfx);
+
+ if (!floating) {
+ return;
+ }
+
+ intersection = getConnectionIntersection(waypoints, event.originalEvent);
+
+ if (intersection) {
+ (0, _SvgTransformUtil.translate)(floating, intersection.point.x, intersection.point.y);
+ }
+ }
+ });
+
+ eventBus.on('element.mousedown', function (event) {
+
+ var originalEvent = event.originalEvent,
+ element = event.element,
+ waypoints = element.waypoints;
+
+ if (!waypoints) {
+ return;
+ }
+
+ return activateBendpointMove(originalEvent, element, waypoints);
+ });
+
+ eventBus.on('selection.changed', function (event) {
+ var newSelection = event.newSelection,
+ primary = newSelection[0];
+
+ if (primary && primary.waypoints) {
+ addHandles(primary);
+ }
+ });
+
+ eventBus.on('element.hover', function (event) {
+ var element = event.element;
+
+ if (element.waypoints) {
+ addHandles(element);
+ interactionEvents.registerEvent(event.gfx, 'mousemove', 'element.mousemove');
+ }
+ });
+
+ eventBus.on('element.out', function (event) {
+ interactionEvents.unregisterEvent(event.gfx, 'mousemove', 'element.mousemove');
+ });
+
+ // update bendpoint container data attribute on element ID change
+ eventBus.on('element.updateId', function (context) {
+ var element = context.element,
+ newId = context.newId;
+
+ if (element.waypoints) {
+ var bendpointContainer = getBendpointsContainer(element);
+
+ if (bendpointContainer) {
+ (0, _tinySvg.attr)(bendpointContainer, { 'data-element-id': newId });
+ }
+ }
+ });
+
+ // API
+
+ this.addHandles = addHandles;
+ this.updateHandles = updateHandles;
+ this.getBendpointsContainer = getBendpointsContainer;
+}
+
+Bendpoints.$inject = ['eventBus', 'canvas', 'interactionEvents', 'bendpointMove', 'connectionSegmentMove'];
+
+},{"../../util/Geometry":398,"../../util/LineIntersection":401,"../../util/SvgTransformUtil":408,"./BendpointUtil":266,"css.escape":237,"min-dash":505,"min-dom":506,"tiny-svg":535}],268:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ConnectionSegmentMove;
+
+var _Geometry = require('../../util/Geometry');
+
+var _BendpointUtil = require('./BendpointUtil');
+
+var _LayoutUtil = require('../../layout/LayoutUtil');
+
+var _tinySvg = require('tiny-svg');
+
+var _SvgTransformUtil = require('../../util/SvgTransformUtil');
+
+var MARKER_CONNECT_HOVER = 'connect-hover',
+ MARKER_CONNECT_UPDATING = 'djs-updating';
+
+function axisAdd(point, axis, delta) {
+ return axisSet(point, axis, point[axis] + delta);
+}
+
+function axisSet(point, axis, value) {
+ return {
+ x: axis === 'x' ? value : point.x,
+ y: axis === 'y' ? value : point.y
+ };
+}
+
+function axisFenced(position, segmentStart, segmentEnd, axis) {
+
+ var maxValue = Math.max(segmentStart[axis], segmentEnd[axis]),
+ minValue = Math.min(segmentStart[axis], segmentEnd[axis]);
+
+ var padding = 20;
+
+ var fencedValue = Math.min(Math.max(minValue + padding, position[axis]), maxValue - padding);
+
+ return axisSet(segmentStart, axis, fencedValue);
+}
+
+function flipAxis(axis) {
+ return axis === 'x' ? 'y' : 'x';
+}
+
+/**
+ * Get the docking point on the given element.
+ *
+ * Compute a reasonable docking, if non exists.
+ *
+ * @param {Point} point
+ * @param {djs.model.Shape} referenceElement
+ * @param {String} moveAxis (x|y)
+ *
+ * @return {Point}
+ */
+function getDocking(point, referenceElement, moveAxis) {
+
+ var referenceMid, inverseAxis;
+
+ if (point.original) {
+ return point.original;
+ } else {
+ referenceMid = (0, _LayoutUtil.getMid)(referenceElement);
+ inverseAxis = flipAxis(moveAxis);
+
+ return axisSet(point, inverseAxis, referenceMid[inverseAxis]);
+ }
+}
+
+/**
+ * A component that implements moving of bendpoints
+ */
+function ConnectionSegmentMove(injector, eventBus, canvas, dragging, graphicsFactory, rules, modeling) {
+
+ // optional connection docking integration
+ var connectionDocking = injector.get('connectionDocking', false);
+
+ // API
+
+ this.start = function (event, connection, idx) {
+
+ var context,
+ gfx = canvas.getGraphics(connection),
+ segmentStartIndex = idx - 1,
+ segmentEndIndex = idx,
+ waypoints = connection.waypoints,
+ segmentStart = waypoints[segmentStartIndex],
+ segmentEnd = waypoints[segmentEndIndex],
+ direction,
+ axis;
+
+ direction = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd);
+
+ // do not move diagonal connection
+ if (!direction) {
+ return;
+ }
+
+ // the axis where we are going to move things
+ axis = direction === 'v' ? 'y' : 'x';
+
+ if (segmentStartIndex === 0) {
+ segmentStart = getDocking(segmentStart, connection.source, axis);
+ }
+
+ if (segmentEndIndex === waypoints.length - 1) {
+ segmentEnd = getDocking(segmentEnd, connection.target, axis);
+ }
+
+ context = {
+ connection: connection,
+ segmentStartIndex: segmentStartIndex,
+ segmentEndIndex: segmentEndIndex,
+ segmentStart: segmentStart,
+ segmentEnd: segmentEnd,
+ axis: axis
+ };
+
+ dragging.init(event, {
+ x: (segmentStart.x + segmentEnd.x) / 2,
+ y: (segmentStart.y + segmentEnd.y) / 2
+ }, 'connectionSegment.move', {
+ cursor: axis === 'x' ? 'resize-ew' : 'resize-ns',
+ data: {
+ connection: connection,
+ connectionGfx: gfx,
+ context: context
+ }
+ });
+ };
+
+ /**
+ * Crop connection if connection cropping is provided.
+ *
+ * @param {Connection} connection
+ * @param {Array} newWaypoints
+ *
+ * @return {Array} cropped connection waypoints
+ */
+ function cropConnection(connection, newWaypoints) {
+
+ // crop connection, if docking service is provided only
+ if (!connectionDocking) {
+ return newWaypoints;
+ }
+
+ var oldWaypoints = connection.waypoints,
+ croppedWaypoints;
+
+ // temporary set new waypoints
+ connection.waypoints = newWaypoints;
+
+ croppedWaypoints = connectionDocking.getCroppedWaypoints(connection);
+
+ // restore old waypoints
+ connection.waypoints = oldWaypoints;
+
+ return croppedWaypoints;
+ }
+
+ // DRAGGING IMPLEMENTATION
+
+ function redrawConnection(data) {
+ graphicsFactory.update('connection', data.connection, data.connectionGfx);
+ }
+
+ function updateDragger(context, segmentOffset, event) {
+
+ var newWaypoints = context.newWaypoints,
+ segmentStartIndex = context.segmentStartIndex + segmentOffset,
+ segmentStart = newWaypoints[segmentStartIndex],
+ segmentEndIndex = context.segmentEndIndex + segmentOffset,
+ segmentEnd = newWaypoints[segmentEndIndex],
+ axis = flipAxis(context.axis);
+
+ // make sure the dragger does not move
+ // outside the connection
+ var draggerPosition = axisFenced(event, segmentStart, segmentEnd, axis);
+
+ // update dragger
+ (0, _SvgTransformUtil.translate)(context.draggerGfx, draggerPosition.x, draggerPosition.y);
+ }
+
+ /**
+ * Filter waypoints for redundant ones (i.e. on the same axis).
+ * Returns the filtered waypoints and the offset related to the segment move.
+ *
+ * @param {Array} waypoints
+ * @param {Integer} segmentStartIndex of moved segment start
+ *
+ * @return {Object} { filteredWaypoints, segmentOffset }
+ */
+ function filterRedundantWaypoints(waypoints, segmentStartIndex) {
+
+ var segmentOffset = 0;
+
+ var filteredWaypoints = waypoints.filter(function (r, idx) {
+ if ((0, _Geometry.pointsOnLine)(waypoints[idx - 1], waypoints[idx + 1], r)) {
+
+ // remove point and increment offset
+ segmentOffset = idx <= segmentStartIndex ? segmentOffset - 1 : segmentOffset;
+ return false;
+ }
+
+ // dont remove point
+ return true;
+ });
+
+ return {
+ waypoints: filteredWaypoints,
+ segmentOffset: segmentOffset
+ };
+ }
+
+ eventBus.on('connectionSegment.move.start', function (e) {
+
+ var context = e.context,
+ connection = e.connection,
+ layer = canvas.getLayer('overlays');
+
+ context.originalWaypoints = connection.waypoints.slice();
+
+ // add dragger gfx
+ context.draggerGfx = (0, _BendpointUtil.addSegmentDragger)(layer, context.segmentStart, context.segmentEnd);
+ (0, _tinySvg.classes)(context.draggerGfx).add('djs-dragging');
+
+ canvas.addMarker(connection, MARKER_CONNECT_UPDATING);
+ });
+
+ eventBus.on('connectionSegment.move.move', function (e) {
+
+ var context = e.context,
+ connection = context.connection,
+ segmentStartIndex = context.segmentStartIndex,
+ segmentEndIndex = context.segmentEndIndex,
+ segmentStart = context.segmentStart,
+ segmentEnd = context.segmentEnd,
+ axis = context.axis;
+
+ var newWaypoints = context.originalWaypoints.slice(),
+ newSegmentStart = axisAdd(segmentStart, axis, e['d' + axis]),
+ newSegmentEnd = axisAdd(segmentEnd, axis, e['d' + axis]);
+
+ // original waypoint count and added / removed
+ // from start waypoint delta. We use the later
+ // to retrieve the updated segmentStartIndex / segmentEndIndex
+ var waypointCount = newWaypoints.length,
+ segmentOffset = 0;
+
+ // move segment start / end by axis delta
+ newWaypoints[segmentStartIndex] = newSegmentStart;
+ newWaypoints[segmentEndIndex] = newSegmentEnd;
+
+ var sourceToSegmentOrientation, targetToSegmentOrientation;
+
+ // handle first segment
+ if (segmentStartIndex < 2) {
+ sourceToSegmentOrientation = (0, _LayoutUtil.getOrientation)(connection.source, newSegmentStart);
+
+ // first bendpoint, remove first segment if intersecting
+ if (segmentStartIndex === 1) {
+
+ if (sourceToSegmentOrientation === 'intersect') {
+ newWaypoints.shift();
+ newWaypoints[0] = newSegmentStart;
+ segmentOffset--;
+ }
+ }
+
+ // docking point, add segment if not intersecting anymore
+ else {
+ if (sourceToSegmentOrientation !== 'intersect') {
+ newWaypoints.unshift(segmentStart);
+ segmentOffset++;
+ }
+ }
+ }
+
+ // handle last segment
+ if (segmentEndIndex > waypointCount - 3) {
+ targetToSegmentOrientation = (0, _LayoutUtil.getOrientation)(connection.target, newSegmentEnd);
+
+ // last bendpoint, remove last segment if intersecting
+ if (segmentEndIndex === waypointCount - 2) {
+
+ if (targetToSegmentOrientation === 'intersect') {
+ newWaypoints.pop();
+ newWaypoints[newWaypoints.length - 1] = newSegmentEnd;
+ }
+ }
+
+ // last bendpoint, remove last segment if intersecting
+ else {
+ if (targetToSegmentOrientation !== 'intersect') {
+ newWaypoints.push(segmentEnd);
+ }
+ }
+ }
+
+ // update connection waypoints
+ context.newWaypoints = connection.waypoints = cropConnection(connection, newWaypoints);
+
+ // update dragger position
+ updateDragger(context, segmentOffset, e);
+
+ // save segmentOffset in context
+ context.newSegmentStartIndex = segmentStartIndex + segmentOffset;
+
+ // redraw connection
+ redrawConnection(e);
+ });
+
+ eventBus.on('connectionSegment.move.hover', function (e) {
+
+ e.context.hover = e.hover;
+ canvas.addMarker(e.hover, MARKER_CONNECT_HOVER);
+ });
+
+ eventBus.on(['connectionSegment.move.out', 'connectionSegment.move.cleanup'], function (e) {
+
+ // remove connect marker
+ // if it was added
+ var hover = e.context.hover;
+
+ if (hover) {
+ canvas.removeMarker(hover, MARKER_CONNECT_HOVER);
+ }
+ });
+
+ eventBus.on('connectionSegment.move.cleanup', function (e) {
+
+ var context = e.context,
+ connection = context.connection;
+
+ // remove dragger gfx
+ if (context.draggerGfx) {
+ (0, _tinySvg.remove)(context.draggerGfx);
+ }
+
+ canvas.removeMarker(connection, MARKER_CONNECT_UPDATING);
+ });
+
+ eventBus.on(['connectionSegment.move.cancel', 'connectionSegment.move.end'], function (e) {
+ var context = e.context,
+ connection = context.connection;
+
+ connection.waypoints = context.originalWaypoints;
+
+ redrawConnection(e);
+ });
+
+ eventBus.on('connectionSegment.move.end', function (e) {
+
+ var context = e.context,
+ connection = context.connection,
+ newWaypoints = context.newWaypoints,
+ newSegmentStartIndex = context.newSegmentStartIndex;
+
+ // ensure we have actual pixel values bendpoint
+ // coordinates (important when zoom level was > 1 during move)
+ newWaypoints = newWaypoints.map(function (p) {
+ return {
+ original: p.original,
+ x: Math.round(p.x),
+ y: Math.round(p.y)
+ };
+ });
+
+ // apply filter redunant waypoints
+ var filtered = filterRedundantWaypoints(newWaypoints, newSegmentStartIndex);
+
+ // get filtered waypoints
+ var filteredWaypoints = filtered.waypoints,
+ croppedWaypoints = cropConnection(connection, filteredWaypoints),
+ segmentOffset = filtered.segmentOffset;
+
+ var hints = {
+ segmentMove: {
+ segmentStartIndex: context.segmentStartIndex,
+ newSegmentStartIndex: newSegmentStartIndex + segmentOffset
+ }
+ };
+
+ modeling.updateWaypoints(connection, croppedWaypoints, hints);
+ });
+}
+
+ConnectionSegmentMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'graphicsFactory', 'rules', 'modeling'];
+
+},{"../../layout/LayoutUtil":380,"../../util/Geometry":398,"../../util/SvgTransformUtil":408,"./BendpointUtil":266,"tiny-svg":535}],269:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _dragging = require('../dragging');
+
+var _dragging2 = _interopRequireDefault(_dragging);
+
+var _rules = require('../rules');
+
+var _rules2 = _interopRequireDefault(_rules);
+
+var _Bendpoints = require('./Bendpoints');
+
+var _Bendpoints2 = _interopRequireDefault(_Bendpoints);
+
+var _BendpointMove = require('./BendpointMove');
+
+var _BendpointMove2 = _interopRequireDefault(_BendpointMove);
+
+var _ConnectionSegmentMove = require('./ConnectionSegmentMove');
+
+var _ConnectionSegmentMove2 = _interopRequireDefault(_ConnectionSegmentMove);
+
+var _BendpointSnapping = require('./BendpointSnapping');
+
+var _BendpointSnapping2 = _interopRequireDefault(_BendpointSnapping);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_dragging2.default, _rules2.default],
+ __init__: ['bendpoints', 'bendpointSnapping'],
+ bendpoints: ['type', _Bendpoints2.default],
+ bendpointMove: ['type', _BendpointMove2.default],
+ connectionSegmentMove: ['type', _ConnectionSegmentMove2.default],
+ bendpointSnapping: ['type', _BendpointSnapping2.default]
+};
+
+},{"../dragging":286,"../rules":355,"./BendpointMove":264,"./BendpointSnapping":265,"./Bendpoints":267,"./ConnectionSegmentMove":268}],270:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ChangeSupport;
+
+var _Elements = require('../../util/Elements');
+
+/**
+ * Adds change support to the diagram, including
+ *
+ *
+ * redrawing shapes and connections on change
+ *
+ *
+ * @param {EventBus} eventBus
+ * @param {Canvas} canvas
+ * @param {ElementRegistry} elementRegistry
+ * @param {GraphicsFactory} graphicsFactory
+ */
+function ChangeSupport(eventBus, canvas, elementRegistry, graphicsFactory) {
+
+ // redraw shapes / connections on change
+
+ eventBus.on('element.changed', function (event) {
+
+ var element = event.element;
+
+ // element might have been deleted and replaced by new element with same ID
+ // thus check for parent of element except for root element
+ if (element.parent || element === canvas.getRootElement()) {
+ event.gfx = elementRegistry.getGraphics(element);
+ }
+
+ // shape + gfx may have been deleted
+ if (!event.gfx) {
+ return;
+ }
+
+ eventBus.fire((0, _Elements.getType)(element) + '.changed', event);
+ });
+
+ eventBus.on('elements.changed', function (event) {
+
+ var elements = event.elements;
+
+ elements.forEach(function (e) {
+ eventBus.fire('element.changed', { element: e });
+ });
+
+ graphicsFactory.updateContainments(elements);
+ });
+
+ eventBus.on('shape.changed', function (event) {
+ graphicsFactory.update('shape', event.element, event.gfx);
+ });
+
+ eventBus.on('connection.changed', function (event) {
+ graphicsFactory.update('connection', event.element, event.gfx);
+ });
+}
+
+ChangeSupport.$inject = ['eventBus', 'canvas', 'elementRegistry', 'graphicsFactory'];
+
+},{"../../util/Elements":396}],271:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _ChangeSupport = require('./ChangeSupport');
+
+var _ChangeSupport2 = _interopRequireDefault(_ChangeSupport);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['changeSupport'],
+ changeSupport: ['type', _ChangeSupport2.default]
+};
+
+},{"./ChangeSupport":270}],272:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Clipboard;
+/**
+ * A clip board stub
+ */
+function Clipboard() {}
+
+Clipboard.prototype.get = function () {
+ return this._data;
+};
+
+Clipboard.prototype.set = function (data) {
+ this._data = data;
+};
+
+Clipboard.prototype.clear = function () {
+ var data = this._data;
+
+ delete this._data;
+
+ return data;
+};
+
+Clipboard.prototype.isEmpty = function () {
+ return !this._data;
+};
+
+},{}],273:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _Clipboard = require('./Clipboard');
+
+var _Clipboard2 = _interopRequireDefault(_Clipboard);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ clipboard: ['type', _Clipboard2.default]
+};
+
+},{"./Clipboard":272}],274:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+exports.default = Connect;
+
+var _LayoutUtil = require('../../layout/LayoutUtil');
+
+var _tinySvg = require('tiny-svg');
+
+var MARKER_OK = 'connect-ok',
+ MARKER_NOT_OK = 'connect-not-ok';
+
+function Connect(eventBus, dragging, modeling, rules, canvas, graphicsFactory) {
+
+ // TODO(nre): separate UI and events
+
+ // rules
+
+ function canConnect(source, target) {
+ return rules.allowed('connection.create', {
+ source: source,
+ target: target
+ });
+ }
+
+ // layouting
+
+ function crop(start, end, source, target) {
+
+ var sourcePath = graphicsFactory.getShapePath(source),
+ targetPath = target && graphicsFactory.getShapePath(target),
+ connectionPath = graphicsFactory.getConnectionPath({ waypoints: [start, end] });
+
+ start = (0, _LayoutUtil.getElementLineIntersection)(sourcePath, connectionPath, true) || start;
+ end = target && (0, _LayoutUtil.getElementLineIntersection)(targetPath, connectionPath, false) || end;
+
+ return [start, end];
+ }
+
+ // event handlers
+
+ eventBus.on('connect.move', function (event) {
+
+ var context = event.context,
+ source = context.source,
+ target = context.target,
+ visual = context.visual,
+ sourcePosition = context.sourcePosition,
+ endPosition,
+ waypoints;
+
+ // update connection visuals during drag
+
+ endPosition = {
+ x: event.x,
+ y: event.y
+ };
+
+ waypoints = crop(sourcePosition, endPosition, source, target);
+
+ (0, _tinySvg.attr)(visual, { 'points': [waypoints[0].x, waypoints[0].y, waypoints[1].x, waypoints[1].y] });
+ });
+
+ eventBus.on('connect.hover', function (event) {
+ var context = event.context,
+ source = context.source,
+ hover = event.hover,
+ canExecute;
+
+ canExecute = context.canExecute = canConnect(source, hover);
+
+ // simply ignore hover
+ if (canExecute === null) {
+ return;
+ }
+
+ context.target = hover;
+
+ canvas.addMarker(hover, canExecute ? MARKER_OK : MARKER_NOT_OK);
+ });
+
+ eventBus.on(['connect.out', 'connect.cleanup'], function (event) {
+ var context = event.context;
+
+ if (context.target) {
+ canvas.removeMarker(context.target, context.canExecute ? MARKER_OK : MARKER_NOT_OK);
+ }
+
+ context.target = null;
+ context.canExecute = false;
+ });
+
+ eventBus.on('connect.cleanup', function (event) {
+ var context = event.context;
+
+ if (context.visual) {
+ (0, _tinySvg.remove)(context.visual);
+ }
+ });
+
+ eventBus.on('connect.start', function (event) {
+ var context = event.context,
+ visual;
+
+ visual = (0, _tinySvg.create)('polyline');
+ (0, _tinySvg.attr)(visual, {
+ 'stroke': '#333',
+ 'strokeDasharray': [1],
+ 'strokeWidth': 2,
+ 'pointer-events': 'none'
+ });
+
+ (0, _tinySvg.append)(canvas.getDefaultLayer(), visual);
+
+ context.visual = visual;
+ });
+
+ eventBus.on('connect.end', function (event) {
+
+ var context = event.context,
+ source = context.source,
+ sourcePosition = context.sourcePosition,
+ target = context.target,
+ targetPosition = {
+ x: event.x,
+ y: event.y
+ },
+ canExecute = context.canExecute || canConnect(source, target);
+
+ if (!canExecute) {
+ return false;
+ }
+
+ var attrs = null,
+ hints = {
+ connectionStart: sourcePosition,
+ connectionEnd: targetPosition
+ };
+
+ if ((typeof canExecute === 'undefined' ? 'undefined' : _typeof(canExecute)) === 'object') {
+ attrs = canExecute;
+ }
+
+ modeling.connect(source, target, attrs, hints);
+ });
+
+ // API
+
+ /**
+ * Start connect operation.
+ *
+ * @param {DOMEvent} event
+ * @param {djs.model.Base} source
+ * @param {Point} [sourcePosition]
+ * @param {Boolean} [autoActivate=false]
+ */
+ this.start = function (event, source, sourcePosition, autoActivate) {
+
+ if ((typeof sourcePosition === 'undefined' ? 'undefined' : _typeof(sourcePosition)) !== 'object') {
+ autoActivate = sourcePosition;
+ sourcePosition = (0, _LayoutUtil.getMid)(source);
+ }
+
+ dragging.init(event, 'connect', {
+ autoActivate: autoActivate,
+ data: {
+ shape: source,
+ context: {
+ source: source,
+ sourcePosition: sourcePosition
+ }
+ }
+ });
+ };
+}
+
+Connect.$inject = ['eventBus', 'dragging', 'modeling', 'rules', 'canvas', 'graphicsFactory'];
+
+},{"../../layout/LayoutUtil":380,"tiny-svg":535}],275:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _selection = require('../selection');
+
+var _selection2 = _interopRequireDefault(_selection);
+
+var _rules = require('../rules');
+
+var _rules2 = _interopRequireDefault(_rules);
+
+var _dragging = require('../dragging');
+
+var _dragging2 = _interopRequireDefault(_dragging);
+
+var _Connect = require('./Connect');
+
+var _Connect2 = _interopRequireDefault(_Connect);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_selection2.default, _rules2.default, _dragging2.default],
+ connect: ['type', _Connect2.default]
+};
+
+},{"../dragging":286,"../rules":355,"../selection":361,"./Connect":274}],276:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ContextPad;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var entrySelector = '.entry';
+
+/**
+ * A context pad that displays element specific, contextual actions next
+ * to a diagram element.
+ *
+ * @param {Object} config
+ * @param {Boolean|Object} [config.scale={ min: 1.0, max: 1.5 }]
+ * @param {Number} [config.scale.min]
+ * @param {Number} [config.scale.max]
+ * @param {EventBus} eventBus
+ * @param {Overlays} overlays
+ */
+function ContextPad(config, eventBus, overlays) {
+
+ this._providers = [];
+
+ this._eventBus = eventBus;
+ this._overlays = overlays;
+
+ var scale = (0, _minDash.isDefined)(config && config.scale) ? config.scale : {
+ min: 1,
+ max: 1.5
+ };
+
+ this._overlaysConfig = {
+ position: {
+ right: -9,
+ top: -6
+ },
+ scale: scale
+ };
+
+ this._current = null;
+
+ this._init();
+}
+
+ContextPad.$inject = ['config.contextPad', 'eventBus', 'overlays'];
+
+/**
+ * Registers events needed for interaction with other components
+ */
+ContextPad.prototype._init = function () {
+
+ var eventBus = this._eventBus;
+
+ var self = this;
+
+ eventBus.on('selection.changed', function (e) {
+
+ var selection = e.newSelection;
+
+ if (selection.length === 1) {
+ self.open(selection[0]);
+ } else {
+ self.close();
+ }
+ });
+
+ eventBus.on('elements.delete', function (event) {
+ var elements = event.elements;
+
+ (0, _minDash.forEach)(elements, function (e) {
+ if (self.isOpen(e)) {
+ self.close();
+ }
+ });
+ });
+
+ eventBus.on('element.changed', function (event) {
+ var element = event.element,
+ current = self._current;
+
+ // force reopen if element for which we are currently opened changed
+ if (current && current.element === element) {
+ self.open(element, true);
+ }
+ });
+};
+
+/**
+ * Register a provider with the context pad
+ *
+ * @param {ContextPadProvider} provider
+ */
+ContextPad.prototype.registerProvider = function (provider) {
+ this._providers.push(provider);
+};
+
+/**
+ * Returns the context pad entries for a given element
+ *
+ * @param {djs.element.Base} element
+ *
+ * @return {Array} list of entries
+ */
+ContextPad.prototype.getEntries = function (element) {
+ var entries = {};
+
+ // loop through all providers and their entries.
+ // group entries by id so that overriding an entry is possible
+ (0, _minDash.forEach)(this._providers, function (provider) {
+ var e = provider.getContextPadEntries(element);
+
+ (0, _minDash.forEach)(e, function (entry, id) {
+ entries[id] = entry;
+ });
+ });
+
+ return entries;
+};
+
+/**
+ * Trigger an action available on the opened context pad
+ *
+ * @param {String} action
+ * @param {Event} event
+ * @param {Boolean} [autoActivate=false]
+ */
+ContextPad.prototype.trigger = function (action, event, autoActivate) {
+
+ var element = this._current.element,
+ entries = this._current.entries,
+ entry,
+ handler,
+ originalEvent,
+ button = event.delegateTarget || event.target;
+
+ if (!button) {
+ return event.preventDefault();
+ }
+
+ entry = entries[(0, _minDom.attr)(button, 'data-action')];
+ handler = entry.action;
+
+ originalEvent = event.originalEvent || event;
+
+ // simple action (via callback function)
+ if ((0, _minDash.isFunction)(handler)) {
+ if (action === 'click') {
+ return handler(originalEvent, element, autoActivate);
+ }
+ } else {
+ if (handler[action]) {
+ return handler[action](originalEvent, element, autoActivate);
+ }
+ }
+
+ // silence other actions
+ event.preventDefault();
+};
+
+/**
+ * Open the context pad for the given element
+ *
+ * @param {djs.model.Base} element
+ * @param {Boolean} force if true, force reopening the context pad
+ */
+ContextPad.prototype.open = function (element, force) {
+ if (!force && this.isOpen(element)) {
+ return;
+ }
+
+ this.close();
+ this._updateAndOpen(element);
+};
+
+ContextPad.prototype._updateAndOpen = function (element) {
+
+ var entries = this.getEntries(element),
+ pad = this.getPad(element),
+ html = pad.html;
+
+ (0, _minDash.forEach)(entries, function (entry, id) {
+ var grouping = entry.group || 'default',
+ control = (0, _minDom.domify)(entry.html || '
'),
+ container;
+
+ (0, _minDom.attr)(control, 'data-action', id);
+
+ container = (0, _minDom.query)('[data-group=' + grouping + ']', html);
+ if (!container) {
+ container = (0, _minDom.domify)('
');
+ html.appendChild(container);
+ }
+
+ container.appendChild(control);
+
+ if (entry.className) {
+ addClasses(control, entry.className);
+ }
+
+ if (entry.title) {
+ (0, _minDom.attr)(control, 'title', entry.title);
+ }
+
+ if (entry.imageUrl) {
+ control.appendChild((0, _minDom.domify)(' '));
+ }
+ });
+
+ (0, _minDom.classes)(html).add('open');
+
+ this._current = {
+ element: element,
+ pad: pad,
+ entries: entries
+ };
+
+ this._eventBus.fire('contextPad.open', { current: this._current });
+};
+
+ContextPad.prototype.getPad = function (element) {
+ if (this.isOpen()) {
+ return this._current.pad;
+ }
+
+ var self = this;
+
+ var overlays = this._overlays;
+
+ var html = (0, _minDom.domify)('
');
+
+ var overlaysConfig = (0, _minDash.assign)({
+ html: html
+ }, this._overlaysConfig);
+
+ _minDom.delegate.bind(html, entrySelector, 'click', function (event) {
+ self.trigger('click', event);
+ });
+
+ _minDom.delegate.bind(html, entrySelector, 'dragstart', function (event) {
+ self.trigger('dragstart', event);
+ });
+
+ // stop propagation of mouse events
+ _minDom.event.bind(html, 'mousedown', function (event) {
+ event.stopPropagation();
+ });
+
+ this._overlayId = overlays.add(element, 'context-pad', overlaysConfig);
+
+ var pad = overlays.get(this._overlayId);
+
+ this._eventBus.fire('contextPad.create', { element: element, pad: pad });
+
+ return pad;
+};
+
+/**
+ * Close the context pad
+ */
+ContextPad.prototype.close = function () {
+ if (!this.isOpen()) {
+ return;
+ }
+
+ this._overlays.remove(this._overlayId);
+
+ this._overlayId = null;
+
+ this._eventBus.fire('contextPad.close', { current: this._current });
+
+ this._current = null;
+};
+
+/**
+ * Check if pad is open. If element is given, will check
+ * if pad is opened with given element.
+ *
+ * @param {Element} element
+ * @return {Boolean}
+ */
+ContextPad.prototype.isOpen = function (element) {
+ return !!this._current && (!element ? true : this._current.element === element);
+};
+
+// helpers //////////////////////
+
+function addClasses(element, classNames) {
+
+ var classes = (0, _minDom.classes)(element);
+
+ var actualClassNames = (0, _minDash.isArray)(classNames) ? classNames : classNames.split(/\s+/g);
+ actualClassNames.forEach(function (cls) {
+ classes.add(cls);
+ });
+}
+
+},{"min-dash":505,"min-dom":506}],277:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _interactionEvents = require('../interaction-events');
+
+var _interactionEvents2 = _interopRequireDefault(_interactionEvents);
+
+var _overlays = require('../overlays');
+
+var _overlays2 = _interopRequireDefault(_overlays);
+
+var _ContextPad = require('./ContextPad');
+
+var _ContextPad2 = _interopRequireDefault(_ContextPad);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_interactionEvents2.default, _overlays2.default],
+ contextPad: ['type', _ContextPad2.default]
+};
+
+},{"../interaction-events":294,"../overlays":339,"./ContextPad":276}],278:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CopyPaste;
+
+var _minDash = require('min-dash');
+
+var _Elements = require('../../util/Elements');
+
+var _PositionUtil = require('../../util/PositionUtil');
+
+var _CopyPasteUtil = require('../../util/CopyPasteUtil');
+
+function CopyPaste(eventBus, modeling, elementFactory, rules, clipboard, canvas) {
+
+ this._eventBus = eventBus;
+ this._modeling = modeling;
+ this._elementFactory = elementFactory;
+ this._rules = rules;
+ this._canvas = canvas;
+
+ this._clipboard = clipboard;
+
+ this._descriptors = [];
+
+ // Element creation priorities:
+ // - 1: Independent shapes
+ // - 2: Attached shapes
+ // - 3: Connections
+ // - 4: labels
+ this.registerDescriptor(function (element, descriptor) {
+ // Base priority
+ descriptor.priority = 1;
+
+ descriptor.id = element.id;
+
+ if (element.parent) {
+ descriptor.parent = element.parent.id;
+ }
+
+ if (element.labelTarget) {
+ // Labels priority
+ descriptor.priority = 4;
+ descriptor.labelTarget = element.labelTarget.id;
+ }
+
+ if (element.host) {
+ // Attached shapes priority
+ descriptor.priority = 2;
+ descriptor.host = element.host.id;
+ }
+
+ if (typeof element.x === 'number') {
+ descriptor.x = element.x;
+ descriptor.y = element.y;
+ }
+
+ if (element.width) {
+ descriptor.width = element.width;
+ descriptor.height = element.height;
+ }
+
+ if (element.waypoints) {
+ // Connections priority
+ descriptor.priority = 3;
+ descriptor.waypoints = [];
+
+ (0, _minDash.forEach)(element.waypoints, function (waypoint) {
+ var wp = {
+ x: waypoint.x,
+ y: waypoint.y
+ };
+
+ if (waypoint.original) {
+ wp.original = {
+ x: waypoint.original.x,
+ y: waypoint.original.y
+ };
+ }
+
+ descriptor.waypoints.push(wp);
+ });
+ }
+
+ if (element.source && element.target) {
+ descriptor.source = element.source.id;
+ descriptor.target = element.target.id;
+ }
+
+ return descriptor;
+ });
+}
+
+CopyPaste.$inject = ['eventBus', 'modeling', 'elementFactory', 'rules', 'clipboard', 'canvas'];
+
+/**
+ * Copy a number of elements.
+ *
+ * @param {djs.model.Base} selectedElements
+ *
+ * @return {Object} the copied tree
+ */
+CopyPaste.prototype.copy = function (selectedElements) {
+ var clipboard = this._clipboard,
+ tree,
+ bbox;
+
+ if (!(0, _minDash.isArray)(selectedElements)) {
+ selectedElements = selectedElements ? [selectedElements] : [];
+ }
+
+ if (!selectedElements.length) {
+ return;
+ }
+
+ tree = this.createTree(selectedElements);
+
+ bbox = this._bbox = (0, _PositionUtil.center)((0, _Elements.getBBox)(tree.allShapes));
+
+ // not needed after computing the center position of the copied elements
+ delete tree.allShapes;
+
+ (0, _minDash.forEach)(tree, function (elements) {
+
+ (0, _minDash.forEach)(elements, function (element) {
+ var delta, labelTarget;
+
+ // set label's relative position to their label target
+ if (element.labelTarget) {
+ labelTarget = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.labelTarget }));
+
+ // just grab the delta from the first waypoint
+ if (labelTarget.waypoints) {
+ delta = (0, _PositionUtil.delta)(element, labelTarget.waypoints[0]);
+ } else {
+ delta = (0, _PositionUtil.delta)(element, labelTarget);
+ }
+ } else if (element.priority === 3) {
+ // connections have priority 3
+ delta = [];
+
+ (0, _minDash.forEach)(element.waypoints, function (waypoint) {
+ var waypointDelta = (0, _PositionUtil.delta)(waypoint, bbox);
+
+ delta.push(waypointDelta);
+ });
+ } else {
+ delta = (0, _PositionUtil.delta)(element, bbox);
+ }
+
+ element.delta = delta;
+ });
+ });
+
+ this._eventBus.fire('elements.copy', { context: { tree: tree } });
+
+ // if tree is empty, means that nothing can be or is allowed to be copied
+ if (Object.keys(tree).length === 0) {
+ clipboard.clear();
+ } else {
+ clipboard.set(tree);
+ }
+
+ this._eventBus.fire('elements.copied', { context: { tree: tree } });
+
+ return tree;
+};
+
+// Allow pasting under the cursor
+CopyPaste.prototype.paste = function (context) {
+ var clipboard = this._clipboard,
+ modeling = this._modeling,
+ eventBus = this._eventBus,
+ rules = this._rules;
+
+ var tree = clipboard.get(),
+ topParent = context.element,
+ position = context.point,
+ newTree,
+ canPaste;
+
+ if (clipboard.isEmpty()) {
+ return;
+ }
+
+ newTree = (0, _minDash.reduce)(tree, function (pasteTree, elements, depthStr) {
+ var depth = parseInt(depthStr, 10);
+
+ if (isNaN(depth)) {
+ return pasteTree;
+ }
+
+ pasteTree[depth] = elements;
+
+ return pasteTree;
+ }, {});
+
+ canPaste = rules.allowed('elements.paste', {
+ tree: newTree,
+ target: topParent
+ });
+
+ if (!canPaste) {
+ eventBus.fire('elements.paste.rejected', {
+ context: {
+ tree: newTree,
+ position: position,
+ target: topParent
+ }
+ });
+
+ return;
+ }
+
+ modeling.pasteElements(newTree, topParent, position);
+};
+
+CopyPaste.prototype._computeDelta = function (elements, element) {
+ var bbox = this._bbox,
+ delta = {};
+
+ // set label's relative position to their label target
+ if (element.labelTarget) {
+ return (0, _PositionUtil.delta)(element, element.labelTarget);
+ }
+
+ // connections have prority 3
+ if (element.priority === 3) {
+ delta = [];
+
+ (0, _minDash.forEach)(element.waypoints, function (waypoint) {
+ var waypointDelta = (0, _PositionUtil.delta)(waypoint, bbox);
+
+ delta.push(waypointDelta);
+ });
+ } else {
+ delta = (0, _PositionUtil.delta)(element, bbox);
+ }
+
+ return delta;
+};
+
+/**
+ * Checks if the element in question has a relations to other elements.
+ * Possible dependants: connections, labels, attachers
+ *
+ * @param {Array} elements
+ * @param {Object} element
+ *
+ * @return {Boolean}
+ */
+CopyPaste.prototype.hasRelations = function (elements, element) {
+ var source, target, labelTarget;
+
+ if (element.waypoints) {
+ source = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.source.id }));
+ target = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.target.id }));
+
+ if (!source || !target) {
+ return false;
+ }
+ }
+
+ if (element.labelTarget) {
+ labelTarget = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.labelTarget.id }));
+
+ if (!labelTarget) {
+ return false;
+ }
+ }
+
+ return true;
+};
+
+CopyPaste.prototype.registerDescriptor = function (descriptor) {
+ if (typeof descriptor !== 'function') {
+ throw new Error('the descriptor must be a function');
+ }
+
+ if (this._descriptors.indexOf(descriptor) !== -1) {
+ throw new Error('this descriptor is already registered');
+ }
+
+ this._descriptors.push(descriptor);
+};
+
+CopyPaste.prototype._executeDescriptors = function (data) {
+ if (!data.descriptor) {
+ data.descriptor = {};
+ }
+
+ (0, _minDash.forEach)(this._descriptors, function (descriptor) {
+ data.descriptor = descriptor(data.element, data.descriptor);
+ });
+
+ return data;
+};
+
+/**
+ * Creates a tree like structure from an arbitrary collection of elements
+ *
+ * @example
+ * tree: {
+ * 0: [
+ * { id: 'shape_12da', priority: 1, ... },
+ * { id: 'shape_01bj', priority: 1, ... },
+ * { id: 'connection_79fa', source: 'shape_12da', target: 'shape_01bj', priority: 3, ... },
+ * ],
+ * 1: [ ... ]
+ * };
+ *
+ * @param {Array} elements
+ * @return {Object}
+ */
+CopyPaste.prototype.createTree = function (elements) {
+ var rules = this._rules,
+ self = this;
+
+ var tree = {},
+ includedElements = [],
+ _elements;
+
+ var topLevel = (0, _CopyPasteUtil.getTopLevel)(elements);
+
+ tree.allShapes = [];
+
+ function canCopy(collection, element) {
+ return rules.allowed('element.copy', {
+ collection: collection,
+ element: element
+ });
+ }
+
+ function includeElement(data) {
+ var idx = (0, _minDash.findIndex)(includedElements, (0, _minDash.matchPattern)({ element: data.element })),
+ element;
+
+ if (idx !== -1) {
+ element = includedElements[idx];
+ } else {
+ return includedElements.push(data);
+ }
+
+ // makes sure that it has the correct depth
+ if (element.depth < data.depth) {
+ includedElements.splice(idx, 1);
+
+ includedElements.push(data);
+ }
+ }
+
+ (0, _Elements.eachElement)(topLevel, function (element, i, depth) {
+ var nestedChildren = element.children;
+
+ // don't add labels directly
+ if (element.labelTarget) {
+ return;
+ }
+
+ function getNested(lists) {
+ (0, _minDash.forEach)(lists, function (list) {
+ if (list && list.length) {
+
+ (0, _minDash.forEach)(list, function (elem) {
+
+ (0, _minDash.forEach)(elem.labels, function (label) {
+ includeElement({
+ element: label,
+ depth: depth
+ });
+ });
+
+ includeElement({
+ element: elem,
+ depth: depth
+ });
+ });
+ }
+ });
+ }
+
+ // fetch element's labels
+ (0, _minDash.forEach)(element.labels, function (label) {
+
+ includeElement({
+ element: label,
+ depth: depth
+ });
+ });
+
+ getNested([element.attachers, element.incoming, element.outgoing]);
+
+ includeElement({
+ element: element,
+ depth: depth
+ });
+
+ if (nestedChildren) {
+ return nestedChildren;
+ }
+ });
+
+ includedElements = (0, _minDash.map)(includedElements, function (data) {
+ // this is where other registered descriptors hook in
+ return self._executeDescriptors(data);
+ });
+
+ // order the elements to check if the ones dependant on others (by relationship)
+ // can be copied. f.ex: label needs it's label target
+ includedElements = (0, _minDash.sortBy)(includedElements, function (data) {
+ return data.descriptor.priority;
+ });
+
+ _elements = (0, _minDash.map)(includedElements, function (data) {
+ return data.element;
+ });
+
+ (0, _minDash.forEach)(includedElements, function (data) {
+ var depth = data.depth;
+
+ if (!self.hasRelations(tree.allShapes, data.element)) {
+ return;
+ }
+
+ if (!canCopy(_elements, data.element)) {
+ return;
+ }
+
+ tree.allShapes.push(data.element);
+
+ // create depth branches
+ if (!tree[depth]) {
+ tree[depth] = [];
+ }
+
+ tree[depth].push(data.descriptor);
+ });
+
+ return tree;
+};
+
+},{"../../util/CopyPasteUtil":394,"../../util/Elements":396,"../../util/PositionUtil":405,"min-dash":505}],279:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _clipboard = require('../clipboard');
+
+var _clipboard2 = _interopRequireDefault(_clipboard);
+
+var _rules = require('../rules');
+
+var _rules2 = _interopRequireDefault(_rules);
+
+var _mouseTracking = require('../mouse-tracking');
+
+var _mouseTracking2 = _interopRequireDefault(_mouseTracking);
+
+var _CopyPaste = require('./CopyPaste');
+
+var _CopyPaste2 = _interopRequireDefault(_CopyPaste);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_clipboard2.default, _rules2.default, _mouseTracking2.default],
+ __init__: ['copyPaste'],
+ copyPaste: ['type', _CopyPaste2.default]
+};
+
+},{"../clipboard":273,"../mouse-tracking":331,"../rules":355,"./CopyPaste":278}],280:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Create;
+
+var _tinySvg = require('tiny-svg');
+
+var _SvgTransformUtil = require('../../util/SvgTransformUtil');
+
+var LOW_PRIORITY = 750;
+
+var MARKER_OK = 'drop-ok',
+ MARKER_NOT_OK = 'drop-not-ok',
+ MARKER_ATTACH = 'attach-ok',
+ MARKER_NEW_PARENT = 'new-parent';
+
+/**
+ * Adds the ability to create new shapes via drag and drop.
+ *
+ * Create must be activated via {@link Create#start}. From that
+ * point on, create will invoke `shape.create` and `shape.attach`
+ * rules to query whether or not creation or attachment on a certain
+ * position is allowed.
+ *
+ * If create or attach is allowed and a source is given, Create it
+ * will invoke `connection.create` rules to query whether a connection
+ * can be drawn between source and new shape. During rule evaluation
+ * the target is not attached yet, however
+ *
+ * hints = { targetParent, targetAttach }
+ *
+ * are passed to the evaluating rules.
+ *
+ *
+ * ## Rule Return Values
+ *
+ * Return values interpreted from `shape.create`:
+ *
+ * * `true`: create is allowed
+ * * `false`: create is disallowed
+ * * `null`: create is not allowed but should be ignored visually
+ *
+ * Return values interpreted from `shape.attach`:
+ *
+ * * `true`: attach is allowed
+ * * `Any`: attach is allowed with the constraints
+ * * `false`: attach is disallowed
+ *
+ * Return values interpreted from `connection.create`:
+ *
+ * * `true`: connection can be created
+ * * `Any`: connection with the given attributes can be created
+ * * `false`: connection can't be created
+ *
+ *
+ * @param {EventBus} eventBus
+ * @param {Dragging} dragging
+ * @param {Rules} rules
+ * @param {Modeling} modeling
+ * @param {Canvas} canvas
+ * @param {Styles} styles
+ * @param {GraphicsFactory} graphicsFactory
+ */
+function Create(eventBus, dragging, rules, modeling, canvas, styles, graphicsFactory) {
+
+ // rules
+
+ function canCreate(shape, target, source, position) {
+
+ if (!target) {
+ return false;
+ }
+
+ var ctx = {
+ source: source,
+ shape: shape,
+ target: target,
+ position: position
+ };
+
+ var create, attach, connect;
+
+ attach = rules.allowed('shape.attach', ctx);
+
+ if (!attach) {
+ create = rules.allowed('shape.create', ctx);
+ }
+
+ if (create || attach) {
+
+ connect = source && rules.allowed('connection.create', {
+ source: source,
+ target: shape,
+ hints: {
+ targetParent: target,
+ targetAttach: attach
+ }
+ });
+ }
+
+ if (create || attach) {
+ return {
+ attach: attach,
+ connect: connect
+ };
+ }
+
+ return false;
+ }
+
+ /** set drop marker on an element */
+ function setMarker(element, marker) {
+
+ [MARKER_ATTACH, MARKER_OK, MARKER_NOT_OK, MARKER_NEW_PARENT].forEach(function (m) {
+
+ if (m === marker) {
+ canvas.addMarker(element, m);
+ } else {
+ canvas.removeMarker(element, m);
+ }
+ });
+ }
+
+ // visual helpers
+
+ function createVisual(shape) {
+ var group, preview, visual;
+
+ group = (0, _tinySvg.create)('g');
+ (0, _tinySvg.attr)(group, styles.cls('djs-drag-group', ['no-events']));
+
+ (0, _tinySvg.append)(canvas.getDefaultLayer(), group);
+
+ preview = (0, _tinySvg.create)('g');
+ (0, _tinySvg.classes)(preview).add('djs-dragger');
+
+ (0, _tinySvg.append)(group, preview);
+
+ (0, _SvgTransformUtil.translate)(preview, shape.width / -2, shape.height / -2);
+
+ var visualGroup = (0, _tinySvg.create)('g');
+ (0, _tinySvg.classes)(visualGroup).add('djs-visual');
+
+ (0, _tinySvg.append)(preview, visualGroup);
+
+ visual = visualGroup;
+
+ // hijack renderer to draw preview
+ graphicsFactory.drawShape(visual, shape);
+
+ return group;
+ }
+
+ // event handlers
+
+ eventBus.on('create.move', function (event) {
+
+ var context = event.context,
+ hover = event.hover,
+ shape = context.shape,
+ source = context.source,
+ canExecute;
+
+ var position = {
+ x: event.x,
+ y: event.y
+ };
+
+ canExecute = context.canExecute = hover && canCreate(shape, hover, source, position);
+
+ // ignore hover visually if canExecute is null
+ if (hover && canExecute !== null) {
+ context.target = hover;
+
+ if (canExecute && canExecute.attach) {
+ setMarker(hover, MARKER_ATTACH);
+ } else {
+ setMarker(hover, canExecute ? MARKER_NEW_PARENT : MARKER_NOT_OK);
+ }
+ }
+ });
+
+ eventBus.on('create.move', LOW_PRIORITY, function (event) {
+
+ var context = event.context,
+ shape = context.shape,
+ visual = context.visual;
+
+ // lazy init drag visual once we received the first real
+ // drag move event (this allows us to get the proper canvas local coordinates)
+ if (!visual) {
+ visual = context.visual = createVisual(shape);
+ }
+
+ (0, _SvgTransformUtil.translate)(visual, event.x, event.y);
+ });
+
+ eventBus.on(['create.end', 'create.out', 'create.cleanup'], function (event) {
+ var context = event.context,
+ target = context.target;
+
+ if (target) {
+ setMarker(target, null);
+ }
+ });
+
+ eventBus.on('create.end', function (event) {
+ var context = event.context,
+ source = context.source,
+ shape = context.shape,
+ target = context.target,
+ canExecute = context.canExecute,
+ attach = canExecute && canExecute.attach,
+ connect = canExecute && canExecute.connect,
+ position = {
+ x: event.x,
+ y: event.y
+ };
+
+ if (!canExecute) {
+ return false;
+ }
+
+ if (connect) {
+ // invoke append if connect is set via rules
+ shape = modeling.appendShape(source, shape, position, target, {
+ attach: attach,
+ connection: connect === true ? {} : connect
+ });
+ } else {
+ // invoke create, if connect is not set
+ shape = modeling.createShape(shape, position, target, {
+ attach: attach
+ });
+ }
+
+ // make sure we provide the actual attached
+ // shape with the context so that selection and
+ // other components can use it right after the create
+ // operation ends
+ context.shape = shape;
+ });
+
+ eventBus.on('create.cleanup', function (event) {
+ var context = event.context;
+
+ if (context.visual) {
+ (0, _tinySvg.remove)(context.visual);
+ }
+ });
+
+ // API
+
+ this.start = function (event, shape, source) {
+
+ dragging.init(event, 'create', {
+ cursor: 'grabbing',
+ autoActivate: true,
+ data: {
+ shape: shape,
+ context: {
+ shape: shape,
+ source: source
+ }
+ }
+ });
+ };
+}
+
+Create.$inject = ['eventBus', 'dragging', 'rules', 'modeling', 'canvas', 'styles', 'graphicsFactory'];
+
+},{"../../util/SvgTransformUtil":408,"tiny-svg":535}],281:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _dragging = require('../dragging');
+
+var _dragging2 = _interopRequireDefault(_dragging);
+
+var _selection = require('../selection');
+
+var _selection2 = _interopRequireDefault(_selection);
+
+var _rules = require('../rules');
+
+var _rules2 = _interopRequireDefault(_rules);
+
+var _Create = require('./Create');
+
+var _Create2 = _interopRequireDefault(_Create);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_dragging2.default, _selection2.default, _rules2.default],
+ create: ['type', _Create2.default]
+};
+
+},{"../dragging":286,"../rules":355,"../selection":361,"./Create":280}],282:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DistributeElements;
+
+var _minDash = require('min-dash');
+
+var AXIS_DIMENSIONS = {
+ horizontal: ['x', 'width'],
+ vertical: ['y', 'height']
+};
+
+var THRESHOLD = 5;
+
+/**
+ * Groups and filters elements and then trigger even distribution.
+ */
+function DistributeElements(modeling) {
+ this._modeling = modeling;
+
+ this._filters = [];
+
+ // register filter for filtering big elements
+ this.registerFilter(function (elements, axis, dimension) {
+ var elementsSize = 0,
+ numOfShapes = 0,
+ avgDimension;
+
+ (0, _minDash.forEach)(elements, function (element) {
+ if (element.waypoints || element.labelTarget) {
+ return;
+ }
+
+ elementsSize += element[dimension];
+
+ numOfShapes += 1;
+ });
+
+ avgDimension = Math.round(elementsSize / numOfShapes);
+
+ return (0, _minDash.filter)(elements, function (element) {
+ return element[dimension] < avgDimension + 50;
+ });
+ });
+}
+
+DistributeElements.$inject = ['modeling'];
+
+/**
+ * Registers filter functions that allow external parties to filter
+ * out certain elements.
+ *
+ * @param {Function} filterFn
+ */
+DistributeElements.prototype.registerFilter = function (filterFn) {
+ if (typeof filterFn !== 'function') {
+ throw new Error('the filter has to be a function');
+ }
+
+ this._filters.push(filterFn);
+};
+
+/**
+ * Distributes the elements with a given orientation
+ *
+ * @param {Array} elements [description]
+ * @param {String} orientation [description]
+ */
+DistributeElements.prototype.trigger = function (elements, orientation) {
+ var modeling = this._modeling;
+
+ var groups, distributableElements;
+
+ if (elements.length < 3) {
+ return;
+ }
+
+ this._setOrientation(orientation);
+
+ distributableElements = this._filterElements(elements);
+
+ groups = this._createGroups(distributableElements);
+
+ // nothing to distribute
+ if (groups.length <= 2) {
+ return;
+ }
+
+ modeling.distributeElements(groups, this._axis, this._dimension);
+
+ return groups;
+};
+
+/**
+ * Filters the elements with provided filters by external parties
+ *
+ * @param {Array[Elements]} elements
+ *
+ * @return {Array[Elements]}
+ */
+DistributeElements.prototype._filterElements = function (elements) {
+ var filters = this._filters,
+ axis = this._axis,
+ dimension = this._dimension,
+ distributableElements = [].concat(elements);
+
+ if (!filters.length) {
+ return elements;
+ }
+
+ (0, _minDash.forEach)(filters, function (filterFn) {
+ distributableElements = filterFn(distributableElements, axis, dimension);
+ });
+
+ return distributableElements;
+};
+
+/**
+ * Create range (min, max) groups. Also tries to group elements
+ * together that share the same range.
+ *
+ * @example
+ * var distributableElements = [
+ * {
+ * range: {
+ * min: 100,
+ * max: 200
+ * },
+ * elements: [ { id: 'shape1', .. }]
+ * }
+ * ]
+ *
+ * @param {Array} elements
+ *
+ * @return {Array[Objects]}
+ */
+DistributeElements.prototype._createGroups = function (elements) {
+ var rangeGroups = [],
+ self = this,
+ axis = this._axis,
+ dimension = this._dimension;
+
+ if (!axis) {
+ throw new Error('must have a defined "axis" and "dimension"');
+ }
+
+ // sort by 'left->right' or 'top->bottom'
+ var sortedElements = (0, _minDash.sortBy)(elements, axis);
+
+ (0, _minDash.forEach)(sortedElements, function (element, idx) {
+ var elementRange = self._findRange(element, axis, dimension),
+ range;
+
+ var previous = rangeGroups[rangeGroups.length - 1];
+
+ if (previous && self._hasIntersection(previous.range, elementRange)) {
+ rangeGroups[rangeGroups.length - 1].elements.push(element);
+ } else {
+ range = { range: elementRange, elements: [element] };
+
+ rangeGroups.push(range);
+ }
+ });
+
+ return rangeGroups;
+};
+
+/**
+ * Maps a direction to the according axis and dimension
+ *
+ * @param {String} direction 'horizontal' or 'vertical'
+ */
+DistributeElements.prototype._setOrientation = function (direction) {
+ var orientation = AXIS_DIMENSIONS[direction];
+
+ this._axis = orientation[0];
+ this._dimension = orientation[1];
+};
+
+/**
+ * Checks if the two ranges intercept each other
+ *
+ * @param {Object} rangeA {min, max}
+ * @param {Object} rangeB {min, max}
+ *
+ * @return {Boolean}
+ */
+DistributeElements.prototype._hasIntersection = function (rangeA, rangeB) {
+ return Math.max(rangeA.min, rangeA.max) >= Math.min(rangeB.min, rangeB.max) && Math.min(rangeA.min, rangeA.max) <= Math.max(rangeB.min, rangeB.max);
+};
+
+/**
+ * Returns the min and max values for an element
+ *
+ * @param {[type]} element [description]
+ * @param {[type]} axis [description]
+ * @param {[type]} dimension [description]
+ *
+ * @return {[type]} [description]
+ */
+DistributeElements.prototype._findRange = function (element) {
+ var axis = element[this._axis],
+ dimension = element[this._dimension];
+
+ return {
+ min: axis + THRESHOLD,
+ max: axis + dimension - THRESHOLD
+ };
+};
+
+},{"min-dash":505}],283:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _DistributeElements = require('./DistributeElements');
+
+var _DistributeElements2 = _interopRequireDefault(_DistributeElements);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['distributeElements'],
+ distributeElements: ['type', _DistributeElements2.default]
+};
+
+},{"./DistributeElements":282}],284:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Dragging;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var _Event = require('../../util/Event');
+
+var _Cursor = require('../../util/Cursor');
+
+var _ClickTrap = require('../../util/ClickTrap');
+
+var _PositionUtil = require('../../util/PositionUtil');
+
+/* global TouchEvent */
+
+var round = Math.round;
+
+var DRAG_ACTIVE_CLS = 'djs-drag-active';
+
+function preventDefault(event) {
+ event.preventDefault();
+}
+
+function isTouchEvent(event) {
+ // check for TouchEvent being available first
+ // (i.e. not available on desktop Firefox)
+ return typeof TouchEvent !== 'undefined' && event instanceof TouchEvent;
+}
+
+function getLength(point) {
+ return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));
+}
+
+/**
+ * A helper that fires canvas localized drag events and realizes
+ * the general "drag-and-drop" look and feel.
+ *
+ * Calling {@link Dragging#activate} activates dragging on a canvas.
+ *
+ * It provides the following:
+ *
+ * * emits life cycle events, namespaced with a prefix assigned
+ * during dragging activation
+ * * sets and restores the cursor
+ * * sets and restores the selection
+ * * ensures there can be only one drag operation active at a time
+ *
+ * Dragging may be canceled manually by calling {@link Dragging#cancel}
+ * or by pressing ESC.
+ *
+ *
+ * ## Life-cycle events
+ *
+ * Dragging can be in three different states, off, initialized
+ * and active.
+ *
+ * (1) off: no dragging operation is in progress
+ * (2) initialized: a new drag operation got initialized but not yet
+ * started (i.e. because of no initial move)
+ * (3) started: dragging is in progress
+ *
+ * Eventually dragging will be off again after a drag operation has
+ * been ended or canceled via user click or ESC key press.
+ *
+ * To indicate transitions between these states dragging emits generic
+ * life-cycle events with the `drag.` prefix _and_ events namespaced
+ * to a prefix choosen by a user during drag initialization.
+ *
+ * The following events are emitted (appropriately prefixed) via
+ * the {@link EventBus}.
+ *
+ * * `init`
+ * * `start`
+ * * `move`
+ * * `end`
+ * * `ended` (dragging already in off state)
+ * * `cancel` (only if previously started)
+ * * `canceled` (dragging already in off state, only if previously started)
+ * * `cleanup`
+ *
+ *
+ * @example
+ *
+ * function MyDragComponent(eventBus, dragging) {
+ *
+ * eventBus.on('mydrag.start', function(event) {
+ * console.log('yes, we start dragging');
+ * });
+ *
+ * eventBus.on('mydrag.move', function(event) {
+ * console.log('canvas local coordinates', event.x, event.y, event.dx, event.dy);
+ *
+ * // local drag data is passed with the event
+ * event.context.foo; // "BAR"
+ *
+ * // the original mouse event, too
+ * event.originalEvent; // MouseEvent(...)
+ * });
+ *
+ * eventBus.on('element.click', function(event) {
+ * dragging.init(event, 'mydrag', {
+ * cursor: 'grabbing',
+ * data: {
+ * context: {
+ * foo: "BAR"
+ * }
+ * }
+ * });
+ * });
+ * }
+ */
+function Dragging(eventBus, canvas, selection) {
+
+ var defaultOptions = {
+ threshold: 5,
+ trapClick: true
+ };
+
+ // the currently active drag operation
+ // dragging is active as soon as this context exists.
+ //
+ // it is visually _active_ only when a context.active flag is set to true.
+ var context;
+
+ /* convert a global event into local coordinates */
+ function toLocalPoint(globalPosition) {
+
+ var viewbox = canvas.viewbox();
+
+ var clientRect = canvas._container.getBoundingClientRect();
+
+ return {
+ x: viewbox.x + (globalPosition.x - clientRect.left) / viewbox.scale,
+ y: viewbox.y + (globalPosition.y - clientRect.top) / viewbox.scale
+ };
+ }
+
+ // helpers
+
+ function fire(type, dragContext) {
+ dragContext = dragContext || context;
+
+ var event = eventBus.createEvent((0, _minDash.assign)({}, dragContext.payload, dragContext.data, { isTouch: dragContext.isTouch }));
+
+ // default integration
+ if (eventBus.fire('drag.' + type, event) === false) {
+ return false;
+ }
+
+ return eventBus.fire(dragContext.prefix + '.' + type, event);
+ }
+
+ // event listeners
+
+ function move(event, activate) {
+ var payload = context.payload,
+ displacement = context.displacement;
+
+ var globalStart = context.globalStart,
+ globalCurrent = (0, _Event.toPoint)(event),
+ globalDelta = (0, _PositionUtil.delta)(globalCurrent, globalStart);
+
+ var localStart = context.localStart,
+ localCurrent = toLocalPoint(globalCurrent),
+ localDelta = (0, _PositionUtil.delta)(localCurrent, localStart);
+
+ // activate context explicitly or once threshold is reached
+ if (!context.active && (activate || getLength(globalDelta) > context.threshold)) {
+
+ // fire start event with original
+ // starting coordinates
+
+ (0, _minDash.assign)(payload, {
+ x: round(localStart.x + displacement.x),
+ y: round(localStart.y + displacement.y),
+ dx: 0,
+ dy: 0
+ }, { originalEvent: event });
+
+ if (false === fire('start')) {
+ return cancel();
+ }
+
+ context.active = true;
+
+ // unset selection and remember old selection
+ // the previous (old) selection will always passed
+ // with the event via the event.previousSelection property
+ if (!context.keepSelection) {
+ payload.previousSelection = selection.get();
+ selection.select(null);
+ }
+
+ // allow custom cursor
+ if (context.cursor) {
+ (0, _Cursor.set)(context.cursor);
+ }
+
+ // indicate dragging via marker on root element
+ canvas.addMarker(canvas.getRootElement(), DRAG_ACTIVE_CLS);
+ }
+
+ (0, _Event.stopPropagation)(event);
+
+ if (context.active) {
+
+ // update payload with actual coordinates
+ (0, _minDash.assign)(payload, {
+ x: round(localCurrent.x + displacement.x),
+ y: round(localCurrent.y + displacement.y),
+ dx: round(localDelta.x),
+ dy: round(localDelta.y)
+ }, { originalEvent: event });
+
+ // emit move event
+ fire('move');
+ }
+ }
+
+ function end(event) {
+ var previousContext,
+ returnValue = true;
+
+ if (context.active) {
+
+ if (event) {
+ context.payload.originalEvent = event;
+
+ // suppress original event (click, ...)
+ // because we just ended a drag operation
+ (0, _Event.stopPropagation)(event);
+ }
+
+ // implementations may stop restoring the
+ // original state (selections, ...) by preventing the
+ // end events default action
+ returnValue = fire('end');
+ }
+
+ if (returnValue === false) {
+ fire('rejected');
+ }
+
+ previousContext = cleanup(returnValue !== true);
+
+ // last event to be fired when all drag operations are done
+ // at this point in time no drag operation is in progress anymore
+ fire('ended', previousContext);
+ }
+
+ // cancel active drag operation if the user presses
+ // the ESC key on the keyboard
+
+ function checkCancel(event) {
+
+ if (event.which === 27) {
+ preventDefault(event);
+
+ cancel();
+ }
+ }
+
+ // prevent ghost click that might occur after a finished
+ // drag and drop session
+
+ function trapClickAndEnd(event) {
+
+ var untrap;
+
+ // trap the click in case we are part of an active
+ // drag operation. This will effectively prevent
+ // the ghost click that cannot be canceled otherwise.
+ if (context.active) {
+
+ untrap = (0, _ClickTrap.install)(eventBus);
+
+ // remove trap after minimal delay
+ setTimeout(untrap, 400);
+
+ // prevent default action (click)
+ preventDefault(event);
+ }
+
+ end(event);
+ }
+
+ function trapTouch(event) {
+ move(event);
+ }
+
+ // update the drag events hover (djs.model.Base) and hoverGfx (Snap)
+ // properties during hover and out and fire {prefix}.hover and {prefix}.out properties
+ // respectively
+
+ function hover(event) {
+ var payload = context.payload;
+
+ payload.hoverGfx = event.gfx;
+ payload.hover = event.element;
+
+ fire('hover');
+ }
+
+ function out(event) {
+ fire('out');
+
+ var payload = context.payload;
+
+ payload.hoverGfx = null;
+ payload.hover = null;
+ }
+
+ // life-cycle methods
+
+ function cancel(restore) {
+ var previousContext;
+
+ if (!context) {
+ return;
+ }
+
+ var wasActive = context.active;
+
+ if (wasActive) {
+ fire('cancel');
+ }
+
+ previousContext = cleanup(restore);
+
+ if (wasActive) {
+ // last event to be fired when all drag operations are done
+ // at this point in time no drag operation is in progress anymore
+ fire('canceled', previousContext);
+ }
+ }
+
+ function cleanup(restore) {
+ var previousContext, endDrag;
+
+ fire('cleanup');
+
+ // reset cursor
+ (0, _Cursor.unset)();
+
+ if (context.trapClick) {
+ endDrag = trapClickAndEnd;
+ } else {
+ endDrag = end;
+ }
+
+ // reset dom listeners
+ _minDom.event.unbind(document, 'mousemove', move);
+
+ _minDom.event.unbind(document, 'dragstart', preventDefault);
+ _minDom.event.unbind(document, 'selectstart', preventDefault);
+
+ _minDom.event.unbind(document, 'mousedown', endDrag, true);
+ _minDom.event.unbind(document, 'mouseup', endDrag, true);
+
+ _minDom.event.unbind(document, 'keyup', checkCancel);
+
+ _minDom.event.unbind(document, 'touchstart', trapTouch, true);
+ _minDom.event.unbind(document, 'touchcancel', cancel, true);
+ _minDom.event.unbind(document, 'touchmove', move, true);
+ _minDom.event.unbind(document, 'touchend', end, true);
+
+ eventBus.off('element.hover', hover);
+ eventBus.off('element.out', out);
+
+ // remove drag marker on root element
+ canvas.removeMarker(canvas.getRootElement(), DRAG_ACTIVE_CLS);
+
+ // restore selection, unless it has changed
+ var previousSelection = context.payload.previousSelection;
+
+ if (restore !== false && previousSelection && !selection.get().length) {
+ selection.select(previousSelection);
+ }
+
+ previousContext = context;
+
+ context = null;
+
+ return previousContext;
+ }
+
+ /**
+ * Initialize a drag operation.
+ *
+ * If `localPosition` is given, drag events will be emitted
+ * relative to it.
+ *
+ * @param {MouseEvent|TouchEvent} [event]
+ * @param {Point} [localPosition] actual diagram local position this drag operation should start at
+ * @param {String} prefix
+ * @param {Object} [options]
+ */
+ function init(event, relativeTo, prefix, options) {
+
+ // only one drag operation may be active, at a time
+ if (context) {
+ cancel(false);
+ }
+
+ if (typeof relativeTo === 'string') {
+ options = prefix;
+ prefix = relativeTo;
+ relativeTo = null;
+ }
+
+ options = (0, _minDash.assign)({}, defaultOptions, options || {});
+
+ var data = options.data || {},
+ originalEvent,
+ globalStart,
+ localStart,
+ endDrag,
+ isTouch;
+
+ if (options.trapClick) {
+ endDrag = trapClickAndEnd;
+ } else {
+ endDrag = end;
+ }
+
+ if (event) {
+ originalEvent = (0, _Event.getOriginal)(event) || event;
+ globalStart = (0, _Event.toPoint)(event);
+
+ (0, _Event.stopPropagation)(event);
+
+ // prevent default browser dragging behavior
+ if (originalEvent.type === 'dragstart') {
+ preventDefault(originalEvent);
+ }
+ } else {
+ originalEvent = null;
+ globalStart = { x: 0, y: 0 };
+ }
+
+ localStart = toLocalPoint(globalStart);
+
+ if (!relativeTo) {
+ relativeTo = localStart;
+ }
+
+ isTouch = isTouchEvent(originalEvent);
+
+ context = (0, _minDash.assign)({
+ prefix: prefix,
+ data: data,
+ payload: {},
+ globalStart: globalStart,
+ displacement: (0, _PositionUtil.delta)(relativeTo, localStart),
+ localStart: localStart,
+ isTouch: isTouch
+ }, options);
+
+ // skip dom registration if trigger
+ // is set to manual (during testing)
+ if (!options.manual) {
+
+ // add dom listeners
+
+ if (isTouch) {
+ _minDom.event.bind(document, 'touchstart', trapTouch, true);
+ _minDom.event.bind(document, 'touchcancel', cancel, true);
+ _minDom.event.bind(document, 'touchmove', move, true);
+ _minDom.event.bind(document, 'touchend', end, true);
+ } else {
+ // assume we use the mouse to interact per default
+ _minDom.event.bind(document, 'mousemove', move);
+
+ // prevent default browser drag and text selection behavior
+ _minDom.event.bind(document, 'dragstart', preventDefault);
+ _minDom.event.bind(document, 'selectstart', preventDefault);
+
+ _minDom.event.bind(document, 'mousedown', endDrag, true);
+ _minDom.event.bind(document, 'mouseup', endDrag, true);
+ }
+
+ _minDom.event.bind(document, 'keyup', checkCancel);
+
+ eventBus.on('element.hover', hover);
+ eventBus.on('element.out', out);
+ }
+
+ fire('init');
+
+ if (options.autoActivate) {
+ move(event, true);
+ }
+ }
+
+ // cancel on diagram destruction
+ eventBus.on('diagram.destroy', cancel);
+
+ // API
+
+ this.init = init;
+ this.move = move;
+ this.hover = hover;
+ this.out = out;
+ this.end = end;
+
+ this.cancel = cancel;
+
+ // for introspection
+
+ this.context = function () {
+ return context;
+ };
+
+ this.setOptions = function (options) {
+ (0, _minDash.assign)(defaultOptions, options);
+ };
+}
+
+Dragging.$inject = ['eventBus', 'canvas', 'selection'];
+
+},{"../../util/ClickTrap":392,"../../util/Cursor":395,"../../util/Event":397,"../../util/PositionUtil":405,"min-dash":505,"min-dom":506}],285:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = HoverFix;
+
+var _minDom = require('min-dom');
+
+var _Event = require('../../util/Event');
+
+function getGfx(target) {
+ var node = (0, _minDom.closest)(target, 'svg, .djs-element', true);
+ return node;
+}
+
+/**
+ * Browsers may swallow the hover event if users are to
+ * fast with the mouse.
+ *
+ * @see http://stackoverflow.com/questions/7448468/why-cant-i-reliably-capture-a-mouseout-event
+ *
+ * The fix implemented in this component ensure that we
+ * have a hover state after a successive drag.move event.
+ *
+ * @param {EventBus} eventBus
+ * @param {Dragging} dragging
+ * @param {ElementRegistry} elementRegistry
+ */
+function HoverFix(eventBus, dragging, elementRegistry) {
+
+ var self = this;
+
+ // we wait for a specific sequence of events before
+ // emitting a fake drag.hover event.
+ //
+ // Event Sequence:
+ //
+ // drag.start
+ // drag.move
+ // drag.move >> ensure we are hovering
+ //
+ eventBus.on('drag.start', function (event) {
+
+ eventBus.once('drag.move', function () {
+
+ eventBus.once('drag.move', function (event) {
+
+ self.ensureHover(event);
+ });
+ });
+ });
+
+ /**
+ * Make sure we are god damn hovering!
+ *
+ * @param {Event} dragging event
+ */
+ this.ensureHover = function (event) {
+
+ if (event.hover) {
+ return;
+ }
+
+ var originalEvent = event.originalEvent,
+ position,
+ target,
+ element,
+ gfx;
+
+ if (!(originalEvent instanceof MouseEvent)) {
+ return;
+ }
+
+ position = (0, _Event.toPoint)(originalEvent);
+
+ // damn expensive operation, ouch!
+ target = document.elementFromPoint(position.x, position.y);
+
+ gfx = getGfx(target);
+
+ if (gfx) {
+ element = elementRegistry.get(gfx);
+
+ dragging.hover({ element: element, gfx: gfx });
+ }
+ };
+}
+
+HoverFix.$inject = ['eventBus', 'dragging', 'elementRegistry'];
+
+},{"../../util/Event":397,"min-dom":506}],286:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _selection = require('../selection');
+
+var _selection2 = _interopRequireDefault(_selection);
+
+var _Dragging = require('./Dragging');
+
+var _Dragging2 = _interopRequireDefault(_Dragging);
+
+var _HoverFix = require('./HoverFix');
+
+var _HoverFix2 = _interopRequireDefault(_HoverFix);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['hoverFix'],
+ __depends__: [_selection2.default],
+ dragging: ['type', _Dragging2.default],
+ hoverFix: ['type', _HoverFix2.default]
+};
+
+},{"../selection":361,"./Dragging":284,"./HoverFix":285}],287:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = EditorActions;
+
+var _minDash = require('min-dash');
+
+var NOT_REGISTERED_ERROR = 'is not a registered action',
+ IS_REGISTERED_ERROR = 'is already registered';
+
+/**
+ * An interface that provides access to modeling actions by decoupling
+ * the one who requests the action to be triggered and the trigger itself.
+ *
+ * It's possible to add new actions by registering them with ´registerAction´
+ * and likewise unregister existing ones with ´unregisterAction´.
+ *
+ *
+ * ## Life-Cycle and configuration
+ *
+ * The editor actions will wait for diagram initialization before
+ * registering default actions _and_ firing an `editorActions.init` event.
+ *
+ * Interested parties may listen to the `editorActions.init` event with
+ * low priority to check, which actions got registered. Other components
+ * may use the event to register their own actions via `registerAction`.
+ *
+ * @param {EventBus} eventBus
+ * @param {Injector} injector
+ */
+function EditorActions(eventBus, injector) {
+
+ // initialize actions
+ this._actions = {};
+
+ var self = this;
+
+ eventBus.on('diagram.init', function () {
+
+ // all diagram modules got loaded; check which ones
+ // are available and register the respective default actions
+ self._registerDefaultActions(injector);
+
+ // ask interested parties to register available editor
+ // actions on diagram initialization
+ eventBus.fire('editorActions.init', {
+ editorActions: self
+ });
+ });
+}
+
+EditorActions.$inject = ['eventBus', 'injector'];
+
+/**
+ * Register default actions.
+ *
+ * @param {Injector} injector
+ */
+EditorActions.prototype._registerDefaultActions = function (injector) {
+
+ // (1) retrieve optional components to integrate with
+
+ var commandStack = injector.get('commandStack', false);
+ var modeling = injector.get('modeling', false);
+ var selection = injector.get('selection', false);
+ var zoomScroll = injector.get('zoomScroll', false);
+ var copyPaste = injector.get('copyPaste', false);
+ var canvas = injector.get('canvas', false);
+ var rules = injector.get('rules', false);
+ var mouseTracking = injector.get('mouseTracking', false);
+ var keyboardMove = injector.get('keyboardMove', false);
+ var keyboardMoveSelection = injector.get('keyboardMoveSelection', false);
+
+ // (2) check components and register actions
+
+ if (commandStack) {
+ this.register('undo', function () {
+ commandStack.undo();
+ });
+
+ this.register('redo', function () {
+ commandStack.redo();
+ });
+ }
+
+ if (copyPaste && selection) {
+ this.register('copy', function () {
+ var selectedElements = selection.get();
+
+ copyPaste.copy(selectedElements);
+ });
+ }
+
+ if (mouseTracking && copyPaste) {
+ this.register('paste', function () {
+ var context = mouseTracking.getHoverContext();
+
+ copyPaste.paste(context);
+ });
+ }
+
+ if (zoomScroll) {
+ this.register('stepZoom', function (opts) {
+ zoomScroll.stepZoom(opts.value);
+ });
+ }
+
+ if (canvas) {
+ this.register('zoom', function (opts) {
+ canvas.zoom(opts.value);
+ });
+ }
+
+ if (modeling && selection && rules) {
+ this.register('removeSelection', function () {
+
+ var selectedElements = selection.get();
+
+ if (!selectedElements.length) {
+ return;
+ }
+
+ var allowed = rules.allowed('elements.delete', { elements: selectedElements }),
+ removableElements;
+
+ if (allowed === false) {
+ return;
+ } else if ((0, _minDash.isArray)(allowed)) {
+ removableElements = allowed;
+ } else {
+ removableElements = selectedElements;
+ }
+
+ if (removableElements.length) {
+ modeling.removeElements(removableElements.slice());
+ }
+ });
+ }
+
+ if (keyboardMove) {
+ this.register('moveCanvas', function (opts) {
+ keyboardMove.moveCanvas(opts);
+ });
+ }
+
+ if (keyboardMoveSelection) {
+ this.register('moveSelection', function (opts) {
+ keyboardMoveSelection.moveSelection(opts.direction, opts.accelerated);
+ });
+ }
+};
+
+/**
+ * Triggers a registered action
+ *
+ * @param {String} action
+ * @param {Object} opts
+ *
+ * @return {Unknown} Returns what the registered listener returns
+ */
+EditorActions.prototype.trigger = function (action, opts) {
+ if (!this._actions[action]) {
+ throw error(action, NOT_REGISTERED_ERROR);
+ }
+
+ return this._actions[action](opts);
+};
+
+/**
+ * Registers a collections of actions.
+ * The key of the object will be the name of the action.
+ *
+ * @example
+ * ´´´
+ * var actions = {
+ * spaceTool: function() {
+ * spaceTool.activateSelection();
+ * },
+ * lassoTool: function() {
+ * lassoTool.activateSelection();
+ * }
+ * ];
+ *
+ * editorActions.register(actions);
+ *
+ * editorActions.isRegistered('spaceTool'); // true
+ * ´´´
+ *
+ * @param {Object} actions
+ */
+EditorActions.prototype.register = function (actions, listener) {
+ var self = this;
+
+ if (typeof actions === 'string') {
+ return this._registerAction(actions, listener);
+ }
+
+ (0, _minDash.forEach)(actions, function (listener, action) {
+ self._registerAction(action, listener);
+ });
+};
+
+/**
+ * Registers a listener to an action key
+ *
+ * @param {String} action
+ * @param {Function} listener
+ */
+EditorActions.prototype._registerAction = function (action, listener) {
+ if (this.isRegistered(action)) {
+ throw error(action, IS_REGISTERED_ERROR);
+ }
+
+ this._actions[action] = listener;
+};
+
+/**
+ * Unregister an existing action
+ *
+ * @param {String} action
+ */
+EditorActions.prototype.unregister = function (action) {
+ if (!this.isRegistered(action)) {
+ throw error(action, NOT_REGISTERED_ERROR);
+ }
+
+ this._actions[action] = undefined;
+};
+
+/**
+ * Returns the number of actions that are currently registered
+ *
+ * @return {Number}
+ */
+EditorActions.prototype.getActions = function () {
+ return Object.keys(this._actions);
+};
+
+/**
+ * Checks wether the given action is registered
+ *
+ * @param {String} action
+ *
+ * @return {Boolean}
+ */
+EditorActions.prototype.isRegistered = function (action) {
+ return !!this._actions[action];
+};
+
+function error(action, message) {
+ return new Error(action + ' ' + message);
+}
+
+},{"min-dash":505}],288:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _EditorActions = require('./EditorActions');
+
+var _EditorActions2 = _interopRequireDefault(_EditorActions);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['editorActions'],
+ editorActions: ['type', _EditorActions2.default]
+};
+
+},{"./EditorActions":287}],289:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = GlobalConnect;
+var MARKER_OK = 'connect-ok',
+ MARKER_NOT_OK = 'connect-not-ok';
+
+/**
+ * @class
+ * @constructor
+ *
+ * @param {EventBus} eventBus
+ * @param {Dragging} dragging
+ * @param {Connect} connect
+ * @param {Canvas} canvas
+ * @param {ToolManager} toolManager
+ * @param {Rules} rules
+ */
+function GlobalConnect(eventBus, dragging, connect, canvas, toolManager, rules) {
+
+ var self = this;
+
+ this._dragging = dragging;
+ this._rules = rules;
+
+ toolManager.registerTool('global-connect', {
+ tool: 'global-connect',
+ dragging: 'global-connect.drag'
+ });
+
+ eventBus.on('global-connect.hover', function (event) {
+ var context = event.context,
+ startTarget = event.hover;
+
+ var canStartConnect = context.canStartConnect = self.canStartConnect(startTarget);
+
+ // simply ignore hover
+ if (canStartConnect === null) {
+ return;
+ }
+
+ context.startTarget = startTarget;
+
+ canvas.addMarker(startTarget, canStartConnect ? MARKER_OK : MARKER_NOT_OK);
+ });
+
+ eventBus.on(['global-connect.out', 'global-connect.cleanup'], function (event) {
+ var startTarget = event.context.startTarget,
+ canStartConnect = event.context.canStartConnect;
+
+ if (startTarget) {
+ canvas.removeMarker(startTarget, canStartConnect ? MARKER_OK : MARKER_NOT_OK);
+ }
+ });
+
+ eventBus.on(['global-connect.ended'], function (event) {
+ var context = event.context,
+ startTarget = context.startTarget,
+ startPosition = {
+ x: event.x,
+ y: event.y
+ };
+
+ var canStartConnect = self.canStartConnect(startTarget);
+
+ if (!canStartConnect) {
+ return;
+ }
+
+ eventBus.once('element.out', function () {
+ eventBus.once(['connect.ended', 'connect.canceled'], function () {
+ eventBus.fire('global-connect.drag.ended');
+ });
+
+ connect.start(null, startTarget, startPosition);
+ });
+
+ return false;
+ });
+}
+
+GlobalConnect.$inject = ['eventBus', 'dragging', 'connect', 'canvas', 'toolManager', 'rules'];
+
+/**
+ * Initiates tool activity.
+ */
+GlobalConnect.prototype.start = function (event) {
+ this._dragging.init(event, 'global-connect', {
+ trapClick: false,
+ data: {
+ context: {}
+ }
+ });
+};
+
+GlobalConnect.prototype.toggle = function () {
+ if (this.isActive()) {
+ this._dragging.cancel();
+ } else {
+ this.start();
+ }
+};
+
+GlobalConnect.prototype.isActive = function () {
+ var context = this._dragging.context();
+
+ return context && /^global-connect/.test(context.prefix);
+};
+
+/**
+ * Check if source shape can initiate connection.
+ *
+ * @param {Shape} startTarget
+ * @return {Boolean}
+ */
+GlobalConnect.prototype.canStartConnect = function (startTarget) {
+ return this._rules.allowed('connection.start', { source: startTarget });
+};
+
+},{}],290:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _connect = require('../connect');
+
+var _connect2 = _interopRequireDefault(_connect);
+
+var _rules = require('../rules');
+
+var _rules2 = _interopRequireDefault(_rules);
+
+var _dragging = require('../dragging');
+
+var _dragging2 = _interopRequireDefault(_dragging);
+
+var _toolManager = require('../tool-manager');
+
+var _toolManager2 = _interopRequireDefault(_toolManager);
+
+var _GlobalConnect = require('./GlobalConnect');
+
+var _GlobalConnect2 = _interopRequireDefault(_GlobalConnect);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_connect2.default, _rules2.default, _dragging2.default, _toolManager2.default],
+ globalConnect: ['type', _GlobalConnect2.default]
+};
+
+},{"../connect":275,"../dragging":286,"../rules":355,"../tool-manager":370,"./GlobalConnect":289}],291:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+exports.default = HandTool;
+
+var _Mouse = require('../../util/Mouse');
+
+var HIGH_PRIORITY = 1500;
+var HAND_CURSOR = 'grab';
+
+function HandTool(eventBus, canvas, dragging, toolManager) {
+ this._dragging = dragging;
+
+ toolManager.registerTool('hand', {
+ tool: 'hand',
+ dragging: 'hand.move'
+ });
+
+ eventBus.on('element.mousedown', HIGH_PRIORITY, function (event) {
+ if ((0, _Mouse.hasPrimaryModifier)(event)) {
+ this.activateMove(event.originalEvent);
+
+ return false;
+ }
+ }, this);
+
+ eventBus.on('hand.end', function (event) {
+ var target = event.originalEvent.target;
+
+ // only reactive on diagram click
+ // on some occasions, event.hover is not set and we have to check if the target is an svg
+ if (!event.hover && !(target instanceof SVGElement)) {
+ return false;
+ }
+
+ eventBus.once('hand.ended', function () {
+ this.activateMove(event.originalEvent, { reactivate: true });
+ }, this);
+ }, this);
+
+ eventBus.on('hand.move.move', function (event) {
+ var scale = canvas.viewbox().scale;
+
+ canvas.scroll({
+ dx: event.dx * scale,
+ dy: event.dy * scale
+ });
+ });
+
+ eventBus.on('hand.move.end', function (event) {
+ var context = event.context,
+ reactivate = context.reactivate;
+
+ // Don't reactivate if the user is using the keyboard keybinding
+ if (!(0, _Mouse.hasPrimaryModifier)(event) && reactivate) {
+
+ eventBus.once('hand.move.ended', function (event) {
+ this.activateHand(event.originalEvent, true, true);
+ }, this);
+ }
+
+ return false;
+ }, this);
+}
+
+HandTool.$inject = ['eventBus', 'canvas', 'dragging', 'toolManager'];
+
+HandTool.prototype.activateMove = function (event, autoActivate, context) {
+ if ((typeof autoActivate === 'undefined' ? 'undefined' : _typeof(autoActivate)) === 'object') {
+ context = autoActivate;
+ autoActivate = false;
+ }
+
+ this._dragging.init(event, 'hand.move', {
+ autoActivate: autoActivate,
+ cursor: HAND_CURSOR,
+ data: {
+ context: context || {}
+ }
+ });
+};
+
+HandTool.prototype.activateHand = function (event, autoActivate, reactivate) {
+ this._dragging.init(event, 'hand', {
+ trapClick: false,
+ autoActivate: autoActivate,
+ cursor: HAND_CURSOR,
+ data: {
+ context: {
+ reactivate: reactivate
+ }
+ }
+ });
+};
+
+HandTool.prototype.toggle = function () {
+ if (this.isActive()) {
+ this._dragging.cancel();
+ } else {
+ this.activateHand();
+ }
+};
+
+HandTool.prototype.isActive = function () {
+ var context = this._dragging.context();
+
+ return context && /^hand/.test(context.prefix);
+};
+
+},{"../../util/Mouse":403}],292:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _toolManager = require('../tool-manager');
+
+var _toolManager2 = _interopRequireDefault(_toolManager);
+
+var _HandTool = require('./HandTool');
+
+var _HandTool2 = _interopRequireDefault(_HandTool);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_toolManager2.default],
+ __init__: ['handTool'],
+ handTool: ['type', _HandTool2.default]
+};
+
+},{"../tool-manager":370,"./HandTool":291}],293:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = InteractionEvents;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var _Mouse = require('../../util/Mouse');
+
+var _tinySvg = require('tiny-svg');
+
+var _RenderUtil = require('../../util/RenderUtil');
+
+function allowAll(e) {
+ return true;
+}
+
+var LOW_PRIORITY = 500;
+
+/**
+ * A plugin that provides interaction events for diagram elements.
+ *
+ * It emits the following events:
+ *
+ * * element.hover
+ * * element.out
+ * * element.click
+ * * element.dblclick
+ * * element.mousedown
+ * * element.contextmenu
+ *
+ * Each event is a tuple { element, gfx, originalEvent }.
+ *
+ * Canceling the event via Event#preventDefault()
+ * prevents the original DOM operation.
+ *
+ * @param {EventBus} eventBus
+ */
+function InteractionEvents(eventBus, elementRegistry, styles) {
+
+ var HIT_STYLE = styles.cls('djs-hit', ['no-fill', 'no-border'], {
+ stroke: 'white',
+ strokeWidth: 15
+ });
+
+ /**
+ * Fire an interaction event.
+ *
+ * @param {String} type local event name, e.g. element.click.
+ * @param {DOMEvent} event native event
+ * @param {djs.model.Base} [element] the diagram element to emit the event on;
+ * defaults to the event target
+ */
+ function fire(type, event, element) {
+
+ if (isIgnored(type, event)) {
+ return;
+ }
+
+ var target, gfx, returnValue;
+
+ if (!element) {
+ target = event.delegateTarget || event.target;
+
+ if (target) {
+ gfx = target;
+ element = elementRegistry.get(gfx);
+ }
+ } else {
+ gfx = elementRegistry.getGraphics(element);
+ }
+
+ if (!gfx || !element) {
+ return;
+ }
+
+ returnValue = eventBus.fire(type, {
+ element: element,
+ gfx: gfx,
+ originalEvent: event
+ });
+
+ if (returnValue === false) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
+ }
+
+ // TODO(nikku): document this
+ var handlers = {};
+
+ function mouseHandler(localEventName) {
+ return handlers[localEventName];
+ }
+
+ function isIgnored(localEventName, event) {
+
+ var filter = ignoredFilters[localEventName] || _Mouse.isPrimaryButton;
+
+ // only react on left mouse button interactions
+ // except for interaction events that are enabled
+ // for secundary mouse button
+ return !filter(event);
+ }
+
+ var bindings = {
+ mouseover: 'element.hover',
+ mouseout: 'element.out',
+ click: 'element.click',
+ dblclick: 'element.dblclick',
+ mousedown: 'element.mousedown',
+ mouseup: 'element.mouseup',
+ contextmenu: 'element.contextmenu'
+ };
+
+ var ignoredFilters = {
+ 'element.contextmenu': allowAll
+ };
+
+ // manual event trigger
+
+ /**
+ * Trigger an interaction event (based on a native dom event)
+ * on the target shape or connection.
+ *
+ * @param {String} eventName the name of the triggered DOM event
+ * @param {MouseEvent} event
+ * @param {djs.model.Base} targetElement
+ */
+ function triggerMouseEvent(eventName, event, targetElement) {
+
+ // i.e. element.mousedown...
+ var localEventName = bindings[eventName];
+
+ if (!localEventName) {
+ throw new Error('unmapped DOM event name <' + eventName + '>');
+ }
+
+ return fire(localEventName, event, targetElement);
+ }
+
+ var elementSelector = 'svg, .djs-element';
+
+ // event registration
+
+ function registerEvent(node, event, localEvent, ignoredFilter) {
+
+ var handler = handlers[localEvent] = function (event) {
+ fire(localEvent, event);
+ };
+
+ if (ignoredFilter) {
+ ignoredFilters[localEvent] = ignoredFilter;
+ }
+
+ handler.$delegate = _minDom.delegate.bind(node, elementSelector, event, handler);
+ }
+
+ function unregisterEvent(node, event, localEvent) {
+
+ var handler = mouseHandler(localEvent);
+
+ if (!handler) {
+ return;
+ }
+
+ _minDom.delegate.unbind(node, event, handler.$delegate);
+ }
+
+ function registerEvents(svg) {
+ (0, _minDash.forEach)(bindings, function (val, key) {
+ registerEvent(svg, key, val);
+ });
+ }
+
+ function unregisterEvents(svg) {
+ (0, _minDash.forEach)(bindings, function (val, key) {
+ unregisterEvent(svg, key, val);
+ });
+ }
+
+ eventBus.on('canvas.destroy', function (event) {
+ unregisterEvents(event.svg);
+ });
+
+ eventBus.on('canvas.init', function (event) {
+ registerEvents(event.svg);
+ });
+
+ eventBus.on(['shape.added', 'connection.added'], function (event) {
+ var element = event.element,
+ gfx = event.gfx,
+ hit;
+
+ if (element.waypoints) {
+ hit = (0, _RenderUtil.createLine)(element.waypoints);
+ } else {
+ hit = (0, _tinySvg.create)('rect');
+ (0, _tinySvg.attr)(hit, {
+ x: 0,
+ y: 0,
+ width: element.width,
+ height: element.height
+ });
+ }
+
+ (0, _tinySvg.attr)(hit, HIT_STYLE);
+
+ (0, _tinySvg.append)(gfx, hit);
+ });
+
+ // Update djs-hit on change.
+ // A low priortity is necessary, because djs-hit of labels has to be updated
+ // after the label bounds have been updated in the renderer.
+ eventBus.on('shape.changed', LOW_PRIORITY, function (event) {
+
+ var element = event.element,
+ gfx = event.gfx,
+ hit = (0, _minDom.query)('.djs-hit', gfx);
+
+ (0, _tinySvg.attr)(hit, {
+ width: element.width,
+ height: element.height
+ });
+ });
+
+ eventBus.on('connection.changed', function (event) {
+
+ var element = event.element,
+ gfx = event.gfx,
+ hit = (0, _minDom.query)('.djs-hit', gfx);
+
+ (0, _RenderUtil.updateLine)(hit, element.waypoints);
+ });
+
+ // API
+
+ this.fire = fire;
+
+ this.triggerMouseEvent = triggerMouseEvent;
+
+ this.mouseHandler = mouseHandler;
+
+ this.registerEvent = registerEvent;
+ this.unregisterEvent = unregisterEvent;
+}
+
+InteractionEvents.$inject = ['eventBus', 'elementRegistry', 'styles'];
+
+/**
+ * An event indicating that the mouse hovered over an element
+ *
+ * @event element.hover
+ *
+ * @type {Object}
+ * @property {djs.model.Base} element
+ * @property {SVGElement} gfx
+ * @property {Event} originalEvent
+ */
+
+/**
+ * An event indicating that the mouse has left an element
+ *
+ * @event element.out
+ *
+ * @type {Object}
+ * @property {djs.model.Base} element
+ * @property {SVGElement} gfx
+ * @property {Event} originalEvent
+ */
+
+/**
+ * An event indicating that the mouse has clicked an element
+ *
+ * @event element.click
+ *
+ * @type {Object}
+ * @property {djs.model.Base} element
+ * @property {SVGElement} gfx
+ * @property {Event} originalEvent
+ */
+
+/**
+ * An event indicating that the mouse has double clicked an element
+ *
+ * @event element.dblclick
+ *
+ * @type {Object}
+ * @property {djs.model.Base} element
+ * @property {SVGElement} gfx
+ * @property {Event} originalEvent
+ */
+
+/**
+ * An event indicating that the mouse has gone down on an element.
+ *
+ * @event element.mousedown
+ *
+ * @type {Object}
+ * @property {djs.model.Base} element
+ * @property {SVGElement} gfx
+ * @property {Event} originalEvent
+ */
+
+/**
+ * An event indicating that the mouse has gone up on an element.
+ *
+ * @event element.mouseup
+ *
+ * @type {Object}
+ * @property {djs.model.Base} element
+ * @property {SVGElement} gfx
+ * @property {Event} originalEvent
+ */
+
+/**
+ * An event indicating that the context menu action is triggered
+ * via mouse or touch controls.
+ *
+ * @event element.contextmenu
+ *
+ * @type {Object}
+ * @property {djs.model.Base} element
+ * @property {SVGElement} gfx
+ * @property {Event} originalEvent
+ */
+
+},{"../../util/Mouse":403,"../../util/RenderUtil":407,"min-dash":505,"min-dom":506,"tiny-svg":535}],294:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _InteractionEvents = require('./InteractionEvents');
+
+var _InteractionEvents2 = _interopRequireDefault(_InteractionEvents);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['interactionEvents'],
+ interactionEvents: ['type', _InteractionEvents2.default]
+};
+
+},{"./InteractionEvents":293}],295:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = KeyboardMoveSelection;
+
+var _minDash = require('min-dash');
+
+var DEFAULT_CONFIG = {
+ moveSpeed: 1,
+ moveSpeedAccelerated: 10
+};
+
+var HIGHER_PRIORITY = 1500;
+
+var LEFT = 'left';
+var UP = 'up';
+var RIGHT = 'right';
+var DOWN = 'down';
+
+var KEY_TO_DIRECTION = {
+ ArrowLeft: LEFT,
+ Left: LEFT,
+ ArrowUp: UP,
+ Up: UP,
+ ArrowRight: RIGHT,
+ Right: RIGHT,
+ ArrowDown: DOWN,
+ Down: DOWN
+};
+
+var DIRECTIONS_DELTA = {
+ left: function left(speed) {
+ return {
+ x: -speed,
+ y: 0
+ };
+ },
+ up: function up(speed) {
+ return {
+ x: 0,
+ y: -speed
+ };
+ },
+ right: function right(speed) {
+ return {
+ x: speed,
+ y: 0
+ };
+ },
+ down: function down(speed) {
+ return {
+ x: 0,
+ y: speed
+ };
+ }
+};
+
+/**
+ * Enables to move selection with keyboard arrows.
+ * Use with Shift for modified speed (default=1, with Shift=10).
+ * Pressed Cmd/Ctrl turns the feature off.
+ *
+ * @param {Object} config
+ * @param {Number} [config.moveSpeed=1]
+ * @param {Number} [config.moveSpeedAccelerated=10]
+ * @param {Keyboard} keyboard
+ * @param {Modeling} modeling
+ * @param {Selection} selection
+ */
+function KeyboardMoveSelection(config, keyboard, modeling, selection) {
+
+ var self = this;
+
+ this._config = (0, _minDash.assign)({}, DEFAULT_CONFIG, config || {});
+
+ keyboard.addListener(HIGHER_PRIORITY, function (event) {
+
+ var keyEvent = event.keyEvent;
+
+ var direction = KEY_TO_DIRECTION[keyEvent.key];
+
+ if (!direction) {
+ return;
+ }
+
+ if (keyboard.isCmd(keyEvent)) {
+ return;
+ }
+
+ var accelerated = keyboard.isShift(keyEvent);
+
+ self.moveSelection(direction, accelerated);
+
+ return true;
+ });
+
+ /**
+ * Move selected elements in the given direction,
+ * optionally specifying accelerated movement.
+ *
+ * @param {String} direction
+ * @param {Boolean} [accelerated=false]
+ */
+ this.moveSelection = function (direction, accelerated) {
+
+ var selectedElements = selection.get();
+
+ if (!selectedElements.length) {
+ return;
+ }
+
+ var speed = this._config[accelerated ? 'moveSpeedAccelerated' : 'moveSpeed'];
+
+ var delta = DIRECTIONS_DELTA[direction](speed);
+
+ modeling.moveElements(selectedElements, delta);
+ };
+}
+
+KeyboardMoveSelection.$inject = ['config.keyboardMoveSelection', 'keyboard', 'modeling', 'selection'];
+
+},{"min-dash":505}],296:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _keyboard = require('../keyboard');
+
+var _keyboard2 = _interopRequireDefault(_keyboard);
+
+var _selection = require('../selection');
+
+var _selection2 = _interopRequireDefault(_selection);
+
+var _KeyboardMoveSelection = require('./KeyboardMoveSelection');
+
+var _KeyboardMoveSelection2 = _interopRequireDefault(_KeyboardMoveSelection);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_keyboard2.default, _selection2.default],
+ __init__: ['keyboardMoveSelection'],
+ keyboardMoveSelection: ['type', _KeyboardMoveSelection2.default]
+};
+
+},{"../keyboard":300,"../selection":361,"./KeyboardMoveSelection":295}],297:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Keyboard;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var _KeyboardUtil = require('./KeyboardUtil');
+
+var KEYDOWN_EVENT = 'keyboard.keydown';
+
+var DEFAULT_PRIORITY = 1000;
+
+/**
+ * A keyboard abstraction that may be activated and
+ * deactivated by users at will, consuming key events
+ * and triggering diagram actions.
+ *
+ * For keys pressed down, keyboard fires `keyboard.keydown` event.
+ * The event context contains one field which is `KeyboardEvent` event.
+ *
+ * The implementation fires the following key events that allow
+ * other components to hook into key handling:
+ *
+ * - keyboard.bind
+ * - keyboard.unbind
+ * - keyboard.init
+ * - keyboard.destroy
+ *
+ * All events contain one field which is node.
+ *
+ * A default binding for the keyboard may be specified via the
+ * `keyboard.bindTo` configuration option.
+ *
+ * @param {Config} config
+ * @param {EventBus} eventBus
+ */
+function Keyboard(config, eventBus) {
+ var self = this;
+
+ this._config = config || {};
+ this._eventBus = eventBus;
+
+ this._keyHandler = this._keyHandler.bind(this);
+
+ // properly clean dom registrations
+ eventBus.on('diagram.destroy', function () {
+ self._fire('destroy');
+
+ self.unbind();
+ });
+
+ eventBus.on('diagram.init', function () {
+ self._fire('init');
+ });
+
+ eventBus.on('attach', function () {
+ if (config && config.bindTo) {
+ self.bind(config.bindTo);
+ }
+ });
+
+ eventBus.on('detach', function () {
+ self.unbind();
+ });
+}
+
+Keyboard.$inject = ['config.keyboard', 'eventBus'];
+
+Keyboard.prototype._keyHandler = function (event) {
+
+ var target = event.target,
+ eventBusResult;
+
+ if (isInput(target)) {
+ return;
+ }
+
+ var context = {
+ keyEvent: event
+ };
+
+ eventBusResult = this._eventBus.fire(KEYDOWN_EVENT, context);
+
+ if (eventBusResult) {
+ event.preventDefault();
+ }
+};
+
+Keyboard.prototype.bind = function (node) {
+
+ // make sure that the keyboard is only bound once to the DOM
+ this.unbind();
+
+ this._node = node;
+
+ // bind key events
+ _minDom.event.bind(node, 'keydown', this._keyHandler, true);
+
+ this._fire('bind');
+};
+
+Keyboard.prototype.getBinding = function () {
+ return this._node;
+};
+
+Keyboard.prototype.unbind = function () {
+ var node = this._node;
+
+ if (node) {
+ this._fire('unbind');
+
+ // unbind key events
+ _minDom.event.unbind(node, 'keydown', this._keyHandler, true);
+ }
+
+ this._node = null;
+};
+
+Keyboard.prototype._fire = function (event) {
+ this._eventBus.fire('keyboard.' + event, { node: this._node });
+};
+
+/**
+ * Add a listener function that is notified with `KeyboardEvent` whenever
+ * the keyboard is bound and the user presses a key. If no priority is
+ * provided, the default value of 1000 is used.
+ *
+ * @param {Number} priority
+ * @param {Function} listener
+ */
+Keyboard.prototype.addListener = function (priority, listener) {
+ if ((0, _minDash.isFunction)(priority)) {
+ listener = priority;
+ priority = DEFAULT_PRIORITY;
+ }
+
+ this._eventBus.on(KEYDOWN_EVENT, priority, listener);
+};
+
+Keyboard.prototype.hasModifier = _KeyboardUtil.hasModifier;
+Keyboard.prototype.isCmd = _KeyboardUtil.isCmd;
+Keyboard.prototype.isShift = _KeyboardUtil.isShift;
+Keyboard.prototype.isKey = _KeyboardUtil.isKey;
+
+// helpers ///////
+
+function isInput(target) {
+ return target && ((0, _minDom.matches)(target, 'input, textarea') || target.contentEditable === 'true');
+}
+
+},{"./KeyboardUtil":299,"min-dash":505,"min-dom":506}],298:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = KeyboardBindings;
+
+var _KeyboardUtil = require('./KeyboardUtil');
+
+var LOW_PRIORITY = 500;
+
+/**
+ * Adds default keyboard bindings.
+ *
+ * This does not pull in any features will bind only actions that
+ * have previously been registered against the editorActions component.
+ *
+ * @param {EventBus} eventBus
+ * @param {Keyboard} keyboard
+ */
+function KeyboardBindings(eventBus, keyboard) {
+
+ var self = this;
+
+ eventBus.on('editorActions.init', LOW_PRIORITY, function (event) {
+
+ var editorActions = event.editorActions;
+
+ self.registerBindings(keyboard, editorActions);
+ });
+}
+
+KeyboardBindings.$inject = ['eventBus', 'keyboard'];
+
+/**
+ * Register available keyboard bindings.
+ *
+ * @param {Keyboard} keyboard
+ * @param {EditorActions} editorActions
+ */
+KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) {
+
+ /**
+ * Add keyboard binding if respective editor action
+ * is registered.
+ *
+ * @param {String} action name
+ * @param {Function} fn that implements the key binding
+ */
+ function addListener(action, fn) {
+
+ if (editorActions.isRegistered(action)) {
+ keyboard.addListener(fn);
+ }
+ }
+
+ // undo
+ // (CTRL|CMD) + Z
+ addListener('undo', function (context) {
+
+ var event = context.keyEvent;
+
+ if ((0, _KeyboardUtil.isCmd)(event) && !(0, _KeyboardUtil.isShift)(event) && (0, _KeyboardUtil.isKey)(['z', 'Z'], event)) {
+ editorActions.trigger('undo');
+
+ return true;
+ }
+ });
+
+ // redo
+ // CTRL + Y
+ // CMD + SHIFT + Z
+ addListener('redo', function (context) {
+
+ var event = context.keyEvent;
+
+ if ((0, _KeyboardUtil.isCmd)(event) && ((0, _KeyboardUtil.isKey)(['y', 'Y'], event) || (0, _KeyboardUtil.isKey)(['z', 'Z'], event) && (0, _KeyboardUtil.isShift)(event))) {
+ editorActions.trigger('redo');
+
+ return true;
+ }
+ });
+
+ // copy
+ // CTRL/CMD + C
+ addListener('copy', function (context) {
+
+ var event = context.keyEvent;
+
+ if ((0, _KeyboardUtil.isCmd)(event) && (0, _KeyboardUtil.isKey)(['c', 'C'], event)) {
+ editorActions.trigger('copy');
+
+ return true;
+ }
+ });
+
+ // paste
+ // CTRL/CMD + V
+ addListener('paste', function (context) {
+
+ var event = context.keyEvent;
+
+ if ((0, _KeyboardUtil.isCmd)(event) && (0, _KeyboardUtil.isKey)(['v', 'V'], event)) {
+ editorActions.trigger('paste');
+
+ return true;
+ }
+ });
+
+ // zoom in one step
+ // CTRL/CMD + +
+ addListener('stepZoom', function (context) {
+
+ var event = context.keyEvent;
+
+ if ((0, _KeyboardUtil.isKey)(['+', 'Add'], event) && (0, _KeyboardUtil.isCmd)(event)) {
+ editorActions.trigger('stepZoom', { value: 1 });
+
+ return true;
+ }
+ });
+
+ // zoom out one step
+ // CTRL + -
+ addListener('stepZoom', function (context) {
+
+ var event = context.keyEvent;
+
+ if ((0, _KeyboardUtil.isKey)(['-', 'Subtract'], event) && (0, _KeyboardUtil.isCmd)(event)) {
+ editorActions.trigger('stepZoom', { value: -1 });
+
+ return true;
+ }
+ });
+
+ // zoom to the default level
+ // CTRL + 0
+ addListener('zoom', function (context) {
+
+ var event = context.keyEvent;
+
+ if ((0, _KeyboardUtil.isKey)('0', event) && (0, _KeyboardUtil.isCmd)(event)) {
+ editorActions.trigger('zoom', { value: 1 });
+
+ return true;
+ }
+ });
+
+ // delete selected element
+ // DEL
+ addListener('removeSelection', function (context) {
+
+ var event = context.keyEvent;
+
+ if ((0, _KeyboardUtil.isKey)(['Delete', 'Del'], event)) {
+ editorActions.trigger('removeSelection');
+
+ return true;
+ }
+ });
+};
+
+},{"./KeyboardUtil":299}],299:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.hasModifier = hasModifier;
+exports.isCmd = isCmd;
+exports.isKey = isKey;
+exports.isShift = isShift;
+
+var _minDash = require('min-dash');
+
+/**
+ * Returns true if event was triggered with any modifier
+ * @param {KeyboardEvent} event
+ */
+function hasModifier(event) {
+ return event.ctrlKey || event.metaKey || event.shiftKey || event.altKey;
+}
+
+/**
+ * @param {KeyboardEvent} event
+ */
+function isCmd(event) {
+
+ // ensure we don't react to AltGr
+ // (mapped to CTRL + ALT)
+ if (event.altKey) {
+ return false;
+ }
+
+ return event.ctrlKey || event.metaKey;
+}
+
+/**
+ * Checks if key pressed is one of provided keys.
+ *
+ * @param {String|String[]} keys
+ * @param {KeyboardEvent} event
+ */
+function isKey(keys, event) {
+ keys = (0, _minDash.isArray)(keys) ? keys : [keys];
+
+ return keys.indexOf(event.key) > -1;
+}
+
+/**
+ * @param {KeyboardEvent} event
+ */
+function isShift(event) {
+ return event.shiftKey;
+}
+
+},{"min-dash":505}],300:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _Keyboard = require('./Keyboard');
+
+var _Keyboard2 = _interopRequireDefault(_Keyboard);
+
+var _KeyboardBindings = require('./KeyboardBindings');
+
+var _KeyboardBindings2 = _interopRequireDefault(_KeyboardBindings);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['keyboard', 'keyboardBindings'],
+ keyboard: ['type', _Keyboard2.default],
+ keyboardBindings: ['type', _KeyboardBindings2.default]
+};
+
+},{"./Keyboard":297,"./KeyboardBindings":298}],301:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = LabelSupport;
+
+var _minDash = require('min-dash');
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _Collections = require('../../util/Collections');
+
+var _Removal = require('../../util/Removal');
+
+var _CommandInterceptor = require('../../command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var LOW_PRIORITY = 250,
+ HIGH_PRIORITY = 1400;
+
+/**
+ * A handler that makes sure labels are properly moved with
+ * their label targets.
+ *
+ * @param {didi.Injector} injector
+ * @param {EventBus} eventBus
+ * @param {Modeling} modeling
+ */
+function LabelSupport(injector, eventBus, modeling) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ var movePreview = injector.get('movePreview', false);
+
+ // remove labels from the collection that are being
+ // moved with other elements anyway
+ eventBus.on('shape.move.start', HIGH_PRIORITY, function (e) {
+
+ var context = e.context,
+ shapes = context.shapes,
+ validatedShapes = context.validatedShapes;
+
+ context.shapes = removeLabels(shapes);
+ context.validatedShapes = removeLabels(validatedShapes);
+ });
+
+ // add labels to visual's group
+ movePreview && eventBus.on('shape.move.start', LOW_PRIORITY, function (e) {
+
+ var context = e.context,
+ shapes = context.shapes;
+
+ var labels = [];
+
+ (0, _minDash.forEach)(shapes, function (element) {
+
+ (0, _minDash.forEach)(element.labels, function (label) {
+
+ if (!label.hidden && context.shapes.indexOf(label) === -1) {
+ labels.push(label);
+ }
+
+ if (element.labelTarget) {
+ labels.push(element);
+ }
+ });
+ });
+
+ (0, _minDash.forEach)(labels, function (label) {
+ movePreview.makeDraggable(context, label, true);
+ });
+ });
+
+ // add all labels to move closure
+ this.preExecuted('elements.move', HIGH_PRIORITY, function (e) {
+ var context = e.context,
+ closure = context.closure,
+ enclosedElements = closure.enclosedElements;
+
+ var enclosedLabels = [];
+
+ // find labels that are not part of
+ // move closure yet and add them
+ (0, _minDash.forEach)(enclosedElements, function (element) {
+ (0, _minDash.forEach)(element.labels, function (label) {
+
+ if (!enclosedElements[label.id]) {
+ enclosedLabels.push(label);
+ }
+ });
+ });
+
+ closure.addAll(enclosedLabels);
+ });
+
+ this.preExecute(['connection.delete', 'shape.delete'], function (e) {
+
+ var context = e.context,
+ element = context.connection || context.shape;
+
+ (0, _Removal.saveClear)(element.labels, function (label) {
+ modeling.removeShape(label, { nested: true });
+ });
+ });
+
+ this.execute('shape.delete', function (e) {
+
+ var context = e.context,
+ shape = context.shape,
+ labelTarget = shape.labelTarget;
+
+ // unset labelTarget
+ if (labelTarget) {
+ context.labelTargetIndex = (0, _Collections.indexOf)(labelTarget.labels, shape);
+ context.labelTarget = labelTarget;
+
+ shape.labelTarget = null;
+ }
+ });
+
+ this.revert('shape.delete', function (e) {
+
+ var context = e.context,
+ shape = context.shape,
+ labelTarget = context.labelTarget,
+ labelTargetIndex = context.labelTargetIndex;
+
+ // restore labelTarget
+ if (labelTarget) {
+ (0, _Collections.add)(labelTarget.labels, shape, labelTargetIndex);
+
+ shape.labelTarget = labelTarget;
+ }
+ });
+}
+
+(0, _inherits2.default)(LabelSupport, _CommandInterceptor2.default);
+
+LabelSupport.$inject = ['injector', 'eventBus', 'modeling'];
+
+/**
+ * Return a filtered list of elements that do not
+ * contain attached elements with hosts being part
+ * of the selection.
+ *
+ * @param {Array} elements
+ *
+ * @return {Array} filtered
+ */
+function removeLabels(elements) {
+
+ return (0, _minDash.filter)(elements, function (element) {
+
+ // filter out labels that are move together
+ // with their label targets
+ return elements.indexOf(element.labelTarget) === -1;
+ });
+}
+
+},{"../../command/CommandInterceptor":243,"../../util/Collections":393,"../../util/Removal":406,"inherits":415,"min-dash":505}],302:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _LabelSupport = require('./LabelSupport');
+
+var _LabelSupport2 = _interopRequireDefault(_LabelSupport);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['labelSupport'],
+ labelSupport: ['type', _LabelSupport2.default]
+};
+
+},{"./LabelSupport":301}],303:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = LassoTool;
+
+var _minDash = require('min-dash');
+
+var _Elements = require('../../util/Elements');
+
+var _Mouse = require('../../util/Mouse');
+
+var _tinySvg = require('tiny-svg');
+
+var LASSO_TOOL_CURSOR = 'crosshair';
+
+function LassoTool(eventBus, canvas, dragging, elementRegistry, selection, toolManager) {
+
+ this._selection = selection;
+ this._dragging = dragging;
+
+ var self = this;
+
+ // lasso visuals implementation
+
+ /**
+ * A helper that realizes the selection box visual
+ */
+ var visuals = {
+
+ create: function create(context) {
+ var container = canvas.getDefaultLayer(),
+ frame;
+
+ frame = context.frame = (0, _tinySvg.create)('rect');
+ (0, _tinySvg.attr)(frame, {
+ class: 'djs-lasso-overlay',
+ width: 1,
+ height: 1,
+ x: 0,
+ y: 0
+ });
+
+ (0, _tinySvg.append)(container, frame);
+ },
+
+ update: function update(context) {
+ var frame = context.frame,
+ bbox = context.bbox;
+
+ (0, _tinySvg.attr)(frame, {
+ x: bbox.x,
+ y: bbox.y,
+ width: bbox.width,
+ height: bbox.height
+ });
+ },
+
+ remove: function remove(context) {
+
+ if (context.frame) {
+ (0, _tinySvg.remove)(context.frame);
+ }
+ }
+ };
+
+ toolManager.registerTool('lasso', {
+ tool: 'lasso.selection',
+ dragging: 'lasso'
+ });
+
+ eventBus.on('lasso.selection.end', function (event) {
+ var target = event.originalEvent.target;
+
+ // only reactive on diagram click
+ // on some occasions, event.hover is not set and we have to check if the target is an svg
+ if (!event.hover && !(target instanceof SVGElement)) {
+ return;
+ }
+
+ eventBus.once('lasso.selection.ended', function () {
+ self.activateLasso(event.originalEvent, true);
+ });
+ });
+
+ // lasso interaction implementation
+
+ eventBus.on('lasso.end', function (event) {
+
+ var bbox = toBBox(event);
+
+ var elements = elementRegistry.filter(function (element) {
+ return element;
+ });
+
+ self.select(elements, bbox);
+ });
+
+ eventBus.on('lasso.start', function (event) {
+
+ var context = event.context;
+
+ context.bbox = toBBox(event);
+ visuals.create(context);
+ });
+
+ eventBus.on('lasso.move', function (event) {
+
+ var context = event.context;
+
+ context.bbox = toBBox(event);
+ visuals.update(context);
+ });
+
+ eventBus.on('lasso.cleanup', function (event) {
+
+ var context = event.context;
+
+ visuals.remove(context);
+ });
+
+ // event integration
+
+ eventBus.on('element.mousedown', 1500, function (event) {
+
+ if ((0, _Mouse.hasSecondaryModifier)(event)) {
+ self.activateLasso(event.originalEvent);
+
+ // we've handled the event
+ return true;
+ }
+ });
+}
+
+LassoTool.$inject = ['eventBus', 'canvas', 'dragging', 'elementRegistry', 'selection', 'toolManager'];
+
+LassoTool.prototype.activateLasso = function (event, autoActivate) {
+
+ this._dragging.init(event, 'lasso', {
+ autoActivate: autoActivate,
+ cursor: LASSO_TOOL_CURSOR,
+ data: {
+ context: {}
+ }
+ });
+};
+
+LassoTool.prototype.activateSelection = function (event) {
+
+ this._dragging.init(event, 'lasso.selection', {
+ trapClick: false,
+ cursor: LASSO_TOOL_CURSOR,
+ data: {
+ context: {}
+ }
+ });
+};
+
+LassoTool.prototype.select = function (elements, bbox) {
+ var selectedElements = (0, _Elements.getEnclosedElements)(elements, bbox);
+
+ this._selection.select((0, _minDash.values)(selectedElements));
+};
+
+LassoTool.prototype.toggle = function () {
+ if (this.isActive()) {
+ this._dragging.cancel();
+ } else {
+ this.activateSelection();
+ }
+};
+
+LassoTool.prototype.isActive = function () {
+ var context = this._dragging.context();
+
+ return context && /^lasso/.test(context.prefix);
+};
+
+function toBBox(event) {
+
+ var start = {
+
+ x: event.x - event.dx,
+ y: event.y - event.dy
+ };
+
+ var end = {
+ x: event.x,
+ y: event.y
+ };
+
+ var bbox;
+
+ if (start.x <= end.x && start.y < end.y || start.x < end.x && start.y <= end.y) {
+
+ bbox = {
+ x: start.x,
+ y: start.y,
+ width: end.x - start.x,
+ height: end.y - start.y
+ };
+ } else if (start.x >= end.x && start.y < end.y || start.x > end.x && start.y <= end.y) {
+
+ bbox = {
+ x: end.x,
+ y: start.y,
+ width: start.x - end.x,
+ height: end.y - start.y
+ };
+ } else if (start.x <= end.x && start.y > end.y || start.x < end.x && start.y >= end.y) {
+
+ bbox = {
+ x: start.x,
+ y: end.y,
+ width: end.x - start.x,
+ height: start.y - end.y
+ };
+ } else if (start.x >= end.x && start.y > end.y || start.x > end.x && start.y >= end.y) {
+
+ bbox = {
+ x: end.x,
+ y: end.y,
+ width: start.x - end.x,
+ height: start.y - end.y
+ };
+ } else {
+
+ bbox = {
+ x: end.x,
+ y: end.y,
+ width: 0,
+ height: 0
+ };
+ }
+ return bbox;
+}
+
+},{"../../util/Elements":396,"../../util/Mouse":403,"min-dash":505,"tiny-svg":535}],304:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _toolManager = require('../tool-manager');
+
+var _toolManager2 = _interopRequireDefault(_toolManager);
+
+var _LassoTool = require('./LassoTool');
+
+var _LassoTool2 = _interopRequireDefault(_LassoTool);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_toolManager2.default],
+ __init__: ['lassoTool'],
+ lassoTool: ['type', _LassoTool2.default]
+};
+
+},{"../tool-manager":370,"./LassoTool":303}],305:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+exports.default = Modeling;
+
+var _minDash = require('min-dash');
+
+var _model = require('../../model');
+
+var _AppendShapeHandler = require('./cmd/AppendShapeHandler');
+
+var _AppendShapeHandler2 = _interopRequireDefault(_AppendShapeHandler);
+
+var _CreateShapeHandler = require('./cmd/CreateShapeHandler');
+
+var _CreateShapeHandler2 = _interopRequireDefault(_CreateShapeHandler);
+
+var _DeleteShapeHandler = require('./cmd/DeleteShapeHandler');
+
+var _DeleteShapeHandler2 = _interopRequireDefault(_DeleteShapeHandler);
+
+var _MoveShapeHandler = require('./cmd/MoveShapeHandler');
+
+var _MoveShapeHandler2 = _interopRequireDefault(_MoveShapeHandler);
+
+var _ResizeShapeHandler = require('./cmd/ResizeShapeHandler');
+
+var _ResizeShapeHandler2 = _interopRequireDefault(_ResizeShapeHandler);
+
+var _ReplaceShapeHandler = require('./cmd/ReplaceShapeHandler');
+
+var _ReplaceShapeHandler2 = _interopRequireDefault(_ReplaceShapeHandler);
+
+var _ToggleShapeCollapseHandler = require('./cmd/ToggleShapeCollapseHandler');
+
+var _ToggleShapeCollapseHandler2 = _interopRequireDefault(_ToggleShapeCollapseHandler);
+
+var _SpaceToolHandler = require('./cmd/SpaceToolHandler');
+
+var _SpaceToolHandler2 = _interopRequireDefault(_SpaceToolHandler);
+
+var _CreateLabelHandler = require('./cmd/CreateLabelHandler');
+
+var _CreateLabelHandler2 = _interopRequireDefault(_CreateLabelHandler);
+
+var _CreateConnectionHandler = require('./cmd/CreateConnectionHandler');
+
+var _CreateConnectionHandler2 = _interopRequireDefault(_CreateConnectionHandler);
+
+var _DeleteConnectionHandler = require('./cmd/DeleteConnectionHandler');
+
+var _DeleteConnectionHandler2 = _interopRequireDefault(_DeleteConnectionHandler);
+
+var _MoveConnectionHandler = require('./cmd/MoveConnectionHandler');
+
+var _MoveConnectionHandler2 = _interopRequireDefault(_MoveConnectionHandler);
+
+var _LayoutConnectionHandler = require('./cmd/LayoutConnectionHandler');
+
+var _LayoutConnectionHandler2 = _interopRequireDefault(_LayoutConnectionHandler);
+
+var _UpdateWaypointsHandler = require('./cmd/UpdateWaypointsHandler');
+
+var _UpdateWaypointsHandler2 = _interopRequireDefault(_UpdateWaypointsHandler);
+
+var _ReconnectConnectionHandler = require('./cmd/ReconnectConnectionHandler');
+
+var _ReconnectConnectionHandler2 = _interopRequireDefault(_ReconnectConnectionHandler);
+
+var _MoveElementsHandler = require('./cmd/MoveElementsHandler');
+
+var _MoveElementsHandler2 = _interopRequireDefault(_MoveElementsHandler);
+
+var _DeleteElementsHandler = require('./cmd/DeleteElementsHandler');
+
+var _DeleteElementsHandler2 = _interopRequireDefault(_DeleteElementsHandler);
+
+var _DistributeElementsHandler = require('./cmd/DistributeElementsHandler');
+
+var _DistributeElementsHandler2 = _interopRequireDefault(_DistributeElementsHandler);
+
+var _AlignElementsHandler = require('./cmd/AlignElementsHandler');
+
+var _AlignElementsHandler2 = _interopRequireDefault(_AlignElementsHandler);
+
+var _UpdateAttachmentHandler = require('./cmd/UpdateAttachmentHandler');
+
+var _UpdateAttachmentHandler2 = _interopRequireDefault(_UpdateAttachmentHandler);
+
+var _PasteHandler = require('./cmd/PasteHandler');
+
+var _PasteHandler2 = _interopRequireDefault(_PasteHandler);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * The basic modeling entry point.
+ *
+ * @param {EventBus} eventBus
+ * @param {ElementFactory} elementFactory
+ * @param {CommandStack} commandStack
+ */
+function Modeling(eventBus, elementFactory, commandStack) {
+ this._eventBus = eventBus;
+ this._elementFactory = elementFactory;
+ this._commandStack = commandStack;
+
+ var self = this;
+
+ eventBus.on('diagram.init', function () {
+ // register modeling handlers
+ self.registerHandlers(commandStack);
+ });
+}
+
+Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack'];
+
+Modeling.prototype.getHandlers = function () {
+ return {
+ 'shape.append': _AppendShapeHandler2.default,
+ 'shape.create': _CreateShapeHandler2.default,
+ 'shape.delete': _DeleteShapeHandler2.default,
+ 'shape.move': _MoveShapeHandler2.default,
+ 'shape.resize': _ResizeShapeHandler2.default,
+ 'shape.replace': _ReplaceShapeHandler2.default,
+ 'shape.toggleCollapse': _ToggleShapeCollapseHandler2.default,
+
+ 'spaceTool': _SpaceToolHandler2.default,
+
+ 'label.create': _CreateLabelHandler2.default,
+
+ 'connection.create': _CreateConnectionHandler2.default,
+ 'connection.delete': _DeleteConnectionHandler2.default,
+ 'connection.move': _MoveConnectionHandler2.default,
+ 'connection.layout': _LayoutConnectionHandler2.default,
+
+ 'connection.updateWaypoints': _UpdateWaypointsHandler2.default,
+
+ 'connection.reconnectStart': _ReconnectConnectionHandler2.default,
+ 'connection.reconnectEnd': _ReconnectConnectionHandler2.default,
+
+ 'elements.move': _MoveElementsHandler2.default,
+ 'elements.delete': _DeleteElementsHandler2.default,
+
+ 'elements.distribute': _DistributeElementsHandler2.default,
+ 'elements.align': _AlignElementsHandler2.default,
+
+ 'element.updateAttachment': _UpdateAttachmentHandler2.default,
+
+ 'elements.paste': _PasteHandler2.default
+ };
+};
+
+/**
+ * Register handlers with the command stack
+ *
+ * @param {CommandStack} commandStack
+ */
+Modeling.prototype.registerHandlers = function (commandStack) {
+ (0, _minDash.forEach)(this.getHandlers(), function (handler, id) {
+ commandStack.registerHandler(id, handler);
+ });
+};
+
+// modeling helpers //////////////////////
+
+Modeling.prototype.moveShape = function (shape, delta, newParent, newParentIndex, hints) {
+
+ if ((typeof newParentIndex === 'undefined' ? 'undefined' : _typeof(newParentIndex)) === 'object') {
+ hints = newParentIndex;
+ newParentIndex = null;
+ }
+
+ var context = {
+ shape: shape,
+ delta: delta,
+ newParent: newParent,
+ newParentIndex: newParentIndex,
+ hints: hints || {}
+ };
+
+ this._commandStack.execute('shape.move', context);
+};
+
+/**
+ * Update the attachment of the given shape.
+ *
+ * @param {djs.mode.Base} shape
+ * @param {djs.model.Base} [newHost]
+ */
+Modeling.prototype.updateAttachment = function (shape, newHost) {
+ var context = {
+ shape: shape,
+ newHost: newHost
+ };
+
+ this._commandStack.execute('element.updateAttachment', context);
+};
+
+/**
+ * Move a number of shapes to a new target, either setting it as
+ * the new parent or attaching it.
+ *
+ * @param {Array} shapes
+ * @param {Point} delta
+ * @param {djs.model.Base} [target]
+ * @param {Object} [hints]
+ * @param {Boolean} [hints.attach=false]
+ */
+Modeling.prototype.moveElements = function (shapes, delta, target, hints) {
+
+ hints = hints || {};
+
+ var attach = hints.attach;
+
+ var newParent = target,
+ newHost;
+
+ if (attach === true) {
+ newHost = target;
+ newParent = target.parent;
+ } else if (attach === false) {
+ newHost = null;
+ }
+
+ var context = {
+ shapes: shapes,
+ delta: delta,
+ newParent: newParent,
+ newHost: newHost,
+ hints: hints
+ };
+
+ this._commandStack.execute('elements.move', context);
+};
+
+Modeling.prototype.moveConnection = function (connection, delta, newParent, newParentIndex, hints) {
+
+ if ((typeof newParentIndex === 'undefined' ? 'undefined' : _typeof(newParentIndex)) === 'object') {
+ hints = newParentIndex;
+ newParentIndex = undefined;
+ }
+
+ var context = {
+ connection: connection,
+ delta: delta,
+ newParent: newParent,
+ newParentIndex: newParentIndex,
+ hints: hints || {}
+ };
+
+ this._commandStack.execute('connection.move', context);
+};
+
+Modeling.prototype.layoutConnection = function (connection, hints) {
+ var context = {
+ connection: connection,
+ hints: hints || {}
+ };
+
+ this._commandStack.execute('connection.layout', context);
+};
+
+/**
+ * Create connection.
+ *
+ * @param {djs.model.Base} source
+ * @param {djs.model.Base} target
+ * @param {Number} [targetIndex]
+ * @param {Object|djs.model.Connection} connection
+ * @param {djs.model.Base} parent
+ * @param {Object} hints
+ *
+ * @return {djs.model.Connection} the created connection.
+ */
+Modeling.prototype.createConnection = function (source, target, parentIndex, connection, parent, hints) {
+
+ if ((typeof parentIndex === 'undefined' ? 'undefined' : _typeof(parentIndex)) === 'object') {
+ hints = parent;
+ parent = connection;
+ connection = parentIndex;
+ parentIndex = undefined;
+ }
+
+ connection = this._create('connection', connection);
+
+ var context = {
+ source: source,
+ target: target,
+ parent: parent,
+ parentIndex: parentIndex,
+ connection: connection,
+ hints: hints
+ };
+
+ this._commandStack.execute('connection.create', context);
+
+ return context.connection;
+};
+
+/**
+ * Create a shape at the specified position.
+ *
+ * @param {djs.model.Shape|Object} shape
+ * @param {Point} position
+ * @param {djs.model.Shape|djs.model.Root} target
+ * @param {Number} [parentIndex] position in parents children list
+ * @param {Object} [hints]
+ * @param {Boolean} [hints.attach] whether to attach to target or become a child
+ *
+ * @return {djs.model.Shape} the created shape
+ */
+Modeling.prototype.createShape = function (shape, position, target, parentIndex, hints) {
+
+ if (typeof parentIndex !== 'number') {
+ hints = parentIndex;
+ parentIndex = undefined;
+ }
+
+ hints = hints || {};
+
+ var attach = hints.attach,
+ parent,
+ host;
+
+ shape = this._create('shape', shape);
+
+ if (attach) {
+ parent = target.parent;
+ host = target;
+ } else {
+ parent = target;
+ }
+
+ var context = {
+ position: position,
+ shape: shape,
+ parent: parent,
+ parentIndex: parentIndex,
+ host: host,
+ hints: hints
+ };
+
+ this._commandStack.execute('shape.create', context);
+
+ return context.shape;
+};
+
+Modeling.prototype.createLabel = function (labelTarget, position, label, parent) {
+
+ label = this._create('label', label);
+
+ var context = {
+ labelTarget: labelTarget,
+ position: position,
+ parent: parent || labelTarget.parent,
+ shape: label
+ };
+
+ this._commandStack.execute('label.create', context);
+
+ return context.shape;
+};
+
+/**
+ * Append shape to given source, drawing a connection
+ * between source and the newly created shape.
+ *
+ * @param {djs.model.Shape} source
+ * @param {djs.model.Shape|Object} shape
+ * @param {Point} position
+ * @param {djs.model.Shape} target
+ * @param {Object} [hints]
+ * @param {Boolean} [hints.attach]
+ * @param {djs.model.Connection|Object} [hints.connection]
+ * @param {djs.model.Base} [hints.connectionParent]
+ *
+ * @return {djs.model.Shape} the newly created shape
+ */
+Modeling.prototype.appendShape = function (source, shape, position, target, hints) {
+
+ hints = hints || {};
+
+ shape = this._create('shape', shape);
+
+ var context = {
+ source: source,
+ position: position,
+ target: target,
+ shape: shape,
+ connection: hints.connection,
+ connectionParent: hints.connectionParent,
+ attach: hints.attach
+ };
+
+ this._commandStack.execute('shape.append', context);
+
+ return context.shape;
+};
+
+Modeling.prototype.removeElements = function (elements) {
+ var context = {
+ elements: elements
+ };
+
+ this._commandStack.execute('elements.delete', context);
+};
+
+Modeling.prototype.distributeElements = function (groups, axis, dimension) {
+ var context = {
+ groups: groups,
+ axis: axis,
+ dimension: dimension
+ };
+
+ this._commandStack.execute('elements.distribute', context);
+};
+
+Modeling.prototype.removeShape = function (shape, hints) {
+ var context = {
+ shape: shape,
+ hints: hints || {}
+ };
+
+ this._commandStack.execute('shape.delete', context);
+};
+
+Modeling.prototype.removeConnection = function (connection, hints) {
+ var context = {
+ connection: connection,
+ hints: hints || {}
+ };
+
+ this._commandStack.execute('connection.delete', context);
+};
+
+Modeling.prototype.replaceShape = function (oldShape, newShape, hints) {
+ var context = {
+ oldShape: oldShape,
+ newData: newShape,
+ hints: hints || {}
+ };
+
+ this._commandStack.execute('shape.replace', context);
+
+ return context.newShape;
+};
+
+Modeling.prototype.pasteElements = function (tree, topParent, position) {
+ var context = {
+ tree: tree,
+ topParent: topParent,
+ position: position
+ };
+
+ this._commandStack.execute('elements.paste', context);
+};
+
+Modeling.prototype.alignElements = function (elements, alignment) {
+ var context = {
+ elements: elements,
+ alignment: alignment
+ };
+
+ this._commandStack.execute('elements.align', context);
+};
+
+Modeling.prototype.resizeShape = function (shape, newBounds, minBounds) {
+ var context = {
+ shape: shape,
+ newBounds: newBounds,
+ minBounds: minBounds
+ };
+
+ this._commandStack.execute('shape.resize', context);
+};
+
+Modeling.prototype.createSpace = function (movingShapes, resizingShapes, delta, direction) {
+ var context = {
+ movingShapes: movingShapes,
+ resizingShapes: resizingShapes,
+ delta: delta,
+ direction: direction
+ };
+
+ this._commandStack.execute('spaceTool', context);
+};
+
+Modeling.prototype.updateWaypoints = function (connection, newWaypoints, hints) {
+ var context = {
+ connection: connection,
+ newWaypoints: newWaypoints,
+ hints: hints || {}
+ };
+
+ this._commandStack.execute('connection.updateWaypoints', context);
+};
+
+Modeling.prototype.reconnectStart = function (connection, newSource, dockingOrPoints) {
+ var context = {
+ connection: connection,
+ newSource: newSource,
+ dockingOrPoints: dockingOrPoints
+ };
+
+ this._commandStack.execute('connection.reconnectStart', context);
+};
+
+Modeling.prototype.reconnectEnd = function (connection, newTarget, dockingOrPoints) {
+ var context = {
+ connection: connection,
+ newTarget: newTarget,
+ dockingOrPoints: dockingOrPoints
+ };
+
+ this._commandStack.execute('connection.reconnectEnd', context);
+};
+
+Modeling.prototype.connect = function (source, target, attrs, hints) {
+ return this.createConnection(source, target, attrs || {}, source.parent, hints);
+};
+
+Modeling.prototype._create = function (type, attrs) {
+ if (attrs instanceof _model.Base) {
+ return attrs;
+ } else {
+ return this._elementFactory.create(type, attrs);
+ }
+};
+
+Modeling.prototype.toggleCollapse = function (shape, hints) {
+ var context = {
+ shape: shape,
+ hints: hints || {}
+ };
+
+ this._commandStack.execute('shape.toggleCollapse', context);
+};
+
+},{"../../model":382,"./cmd/AlignElementsHandler":306,"./cmd/AppendShapeHandler":307,"./cmd/CreateConnectionHandler":308,"./cmd/CreateLabelHandler":309,"./cmd/CreateShapeHandler":310,"./cmd/DeleteConnectionHandler":311,"./cmd/DeleteElementsHandler":312,"./cmd/DeleteShapeHandler":313,"./cmd/DistributeElementsHandler":314,"./cmd/LayoutConnectionHandler":315,"./cmd/MoveConnectionHandler":316,"./cmd/MoveElementsHandler":317,"./cmd/MoveShapeHandler":318,"./cmd/PasteHandler":319,"./cmd/ReconnectConnectionHandler":320,"./cmd/ReplaceShapeHandler":321,"./cmd/ResizeShapeHandler":322,"./cmd/SpaceToolHandler":323,"./cmd/ToggleShapeCollapseHandler":324,"./cmd/UpdateAttachmentHandler":325,"./cmd/UpdateWaypointsHandler":326,"min-dash":505}],306:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AlignElements;
+
+var _minDash = require('min-dash');
+
+/**
+ * A handler that align elements in a certain way.
+ *
+ */
+function AlignElements(modeling, canvas) {
+ this._modeling = modeling;
+ this._canvas = canvas;
+}
+
+AlignElements.$inject = ['modeling', 'canvas'];
+
+AlignElements.prototype.preExecute = function (context) {
+ var modeling = this._modeling;
+
+ var elements = context.elements,
+ alignment = context.alignment;
+
+ (0, _minDash.forEach)(elements, function (element) {
+ var delta = {
+ x: 0,
+ y: 0
+ };
+
+ if (alignment.left) {
+ delta.x = alignment.left - element.x;
+ } else if (alignment.right) {
+ delta.x = alignment.right - element.width - element.x;
+ } else if (alignment.center) {
+ delta.x = alignment.center - Math.round(element.width / 2) - element.x;
+ } else if (alignment.top) {
+ delta.y = alignment.top - element.y;
+ } else if (alignment.bottom) {
+ delta.y = alignment.bottom - element.height - element.y;
+ } else if (alignment.middle) {
+ delta.y = alignment.middle - Math.round(element.height / 2) - element.y;
+ }
+
+ modeling.moveElements([element], delta, element.parent);
+ });
+};
+
+AlignElements.prototype.postExecute = function (context) {};
+
+},{"min-dash":505}],307:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = AppendShapeHandler;
+
+var _minDash = require('min-dash');
+
+/**
+ * A handler that implements reversible appending of shapes
+ * to a source shape.
+ *
+ * @param {canvas} Canvas
+ * @param {elementFactory} ElementFactory
+ * @param {modeling} Modeling
+ */
+function AppendShapeHandler(modeling) {
+ this._modeling = modeling;
+}
+
+AppendShapeHandler.$inject = ['modeling'];
+
+// api //////////////////////
+
+
+/**
+ * Creates a new shape
+ *
+ * @param {Object} context
+ * @param {ElementDescriptor} context.shape the new shape
+ * @param {ElementDescriptor} context.source the source object
+ * @param {ElementDescriptor} context.parent the parent object
+ * @param {Point} context.position position of the new element
+ */
+AppendShapeHandler.prototype.preExecute = function (context) {
+
+ var source = context.source;
+
+ if (!source) {
+ throw new Error('source required');
+ }
+
+ var target = context.target || source.parent,
+ shape = context.shape;
+
+ shape = context.shape = this._modeling.createShape(shape, context.position, target, { attach: context.attach });
+
+ context.shape = shape;
+};
+
+AppendShapeHandler.prototype.postExecute = function (context) {
+ var parent = context.connectionParent || context.shape.parent;
+
+ if (!existsConnection(context.source, context.shape)) {
+
+ // create connection
+ this._modeling.connect(context.source, context.shape, context.connection, parent);
+ }
+};
+
+function existsConnection(source, target) {
+ return (0, _minDash.some)(source.outgoing, function (c) {
+ return c.target === target;
+ });
+}
+
+},{"min-dash":505}],308:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CreateConnectionHandler;
+function CreateConnectionHandler(canvas, layouter) {
+ this._canvas = canvas;
+ this._layouter = layouter;
+}
+
+CreateConnectionHandler.$inject = ['canvas', 'layouter'];
+
+// api //////////////////////
+
+
+/**
+ * Appends a shape to a target shape
+ *
+ * @param {Object} context
+ * @param {djs.element.Base} context.source the source object
+ * @param {djs.element.Base} context.target the parent object
+ * @param {Point} context.position position of the new element
+ */
+CreateConnectionHandler.prototype.execute = function (context) {
+
+ var connection = context.connection,
+ source = context.source,
+ target = context.target,
+ parent = context.parent,
+ parentIndex = context.parentIndex,
+ hints = context.hints;
+
+ if (!source || !target) {
+ throw new Error('source and target required');
+ }
+
+ if (!parent) {
+ throw new Error('parent required');
+ }
+
+ connection.source = source;
+ connection.target = target;
+
+ if (!connection.waypoints) {
+ connection.waypoints = this._layouter.layoutConnection(connection, hints);
+ }
+
+ // add connection
+ this._canvas.addConnection(connection, parent, parentIndex);
+
+ return connection;
+};
+
+CreateConnectionHandler.prototype.revert = function (context) {
+ var connection = context.connection;
+
+ this._canvas.removeConnection(connection);
+
+ connection.source = null;
+ connection.target = null;
+};
+
+},{}],309:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CreateLabelHandler;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CreateShapeHandler = require('./CreateShapeHandler');
+
+var _CreateShapeHandler2 = _interopRequireDefault(_CreateShapeHandler);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A handler that attaches a label to a given target shape.
+ *
+ * @param {Canvas} canvas
+ */
+function CreateLabelHandler(canvas) {
+ _CreateShapeHandler2.default.call(this, canvas);
+}
+
+(0, _inherits2.default)(CreateLabelHandler, _CreateShapeHandler2.default);
+
+CreateLabelHandler.$inject = ['canvas'];
+
+// api //////////////////////
+
+
+var originalExecute = _CreateShapeHandler2.default.prototype.execute;
+
+/**
+ * Appends a label to a target shape.
+ *
+ * @method CreateLabelHandler#execute
+ *
+ * @param {Object} context
+ * @param {ElementDescriptor} context.target the element the label is attached to
+ * @param {ElementDescriptor} context.parent the parent object
+ * @param {Point} context.position position of the new element
+ */
+CreateLabelHandler.prototype.execute = function (context) {
+
+ var label = context.shape;
+
+ ensureValidDimensions(label);
+
+ label.labelTarget = context.labelTarget;
+
+ return originalExecute.call(this, context);
+};
+
+var originalRevert = _CreateShapeHandler2.default.prototype.revert;
+
+/**
+ * Undo append by removing the shape
+ */
+CreateLabelHandler.prototype.revert = function (context) {
+ context.shape.labelTarget = null;
+
+ return originalRevert.call(this, context);
+};
+
+// helpers //////////////////////
+
+function ensureValidDimensions(label) {
+ // make sure a label has valid { width, height } dimensions
+ ['width', 'height'].forEach(function (prop) {
+ if (typeof label[prop] === 'undefined') {
+ label[prop] = 0;
+ }
+ });
+}
+
+},{"./CreateShapeHandler":310,"inherits":415}],310:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = CreateShapeHandler;
+
+var _minDash = require('min-dash');
+
+var round = Math.round;
+
+/**
+ * A handler that implements reversible addition of shapes.
+ *
+ * @param {canvas} Canvas
+ */
+function CreateShapeHandler(canvas) {
+ this._canvas = canvas;
+}
+
+CreateShapeHandler.$inject = ['canvas'];
+
+// api //////////////////////
+
+
+/**
+ * Appends a shape to a target shape
+ *
+ * @param {Object} context
+ * @param {djs.model.Base} context.parent the parent object
+ * @param {Point} context.position position of the new element
+ */
+CreateShapeHandler.prototype.execute = function (context) {
+
+ var shape = context.shape,
+ positionOrBounds = context.position,
+ parent = context.parent,
+ parentIndex = context.parentIndex;
+
+ if (!parent) {
+ throw new Error('parent required');
+ }
+
+ if (!positionOrBounds) {
+ throw new Error('position required');
+ }
+
+ // (1) add at event center position _or_ at given bounds
+ if (positionOrBounds.width !== undefined) {
+ (0, _minDash.assign)(shape, positionOrBounds);
+ } else {
+ (0, _minDash.assign)(shape, {
+ x: positionOrBounds.x - round(shape.width / 2),
+ y: positionOrBounds.y - round(shape.height / 2)
+ });
+ }
+
+ // (2) add to canvas
+ this._canvas.addShape(shape, parent, parentIndex);
+
+ return shape;
+};
+
+/**
+ * Undo append by removing the shape
+ */
+CreateShapeHandler.prototype.revert = function (context) {
+
+ // (3) remove form canvas
+ this._canvas.removeShape(context.shape);
+};
+
+},{"min-dash":505}],311:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DeleteConnectionHandler;
+
+var _Collections = require('../../../util/Collections');
+
+/**
+ * A handler that implements reversible deletion of Connections.
+ */
+function DeleteConnectionHandler(canvas, modeling) {
+ this._canvas = canvas;
+ this._modeling = modeling;
+}
+
+DeleteConnectionHandler.$inject = ['canvas', 'modeling'];
+
+DeleteConnectionHandler.prototype.execute = function (context) {
+
+ var connection = context.connection,
+ parent = connection.parent;
+
+ context.parent = parent;
+
+ // remember containment
+ context.parentIndex = (0, _Collections.indexOf)(parent.children, connection);
+
+ context.source = connection.source;
+ context.target = connection.target;
+
+ this._canvas.removeConnection(connection);
+
+ connection.source = null;
+ connection.target = null;
+
+ return connection;
+};
+
+/**
+ * Command revert implementation.
+ */
+DeleteConnectionHandler.prototype.revert = function (context) {
+
+ var connection = context.connection,
+ parent = context.parent,
+ parentIndex = context.parentIndex;
+
+ connection.source = context.source;
+ connection.target = context.target;
+
+ // restore containment
+ (0, _Collections.add)(parent.children, connection, parentIndex);
+
+ this._canvas.addConnection(connection, parent);
+
+ return connection;
+};
+
+},{"../../../util/Collections":393}],312:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DeleteElementsHandler;
+
+var _minDash = require('min-dash');
+
+function DeleteElementsHandler(modeling, elementRegistry) {
+ this._modeling = modeling;
+ this._elementRegistry = elementRegistry;
+}
+
+DeleteElementsHandler.$inject = ['modeling', 'elementRegistry'];
+
+DeleteElementsHandler.prototype.postExecute = function (context) {
+
+ var modeling = this._modeling,
+ elementRegistry = this._elementRegistry,
+ elements = context.elements;
+
+ (0, _minDash.forEach)(elements, function (element) {
+
+ // element may have been removed with previous
+ // remove operations already (e.g. in case of nesting)
+ if (!elementRegistry.get(element.id)) {
+ return;
+ }
+
+ if (element.waypoints) {
+ modeling.removeConnection(element);
+ } else {
+ modeling.removeShape(element);
+ }
+ });
+};
+
+},{"min-dash":505}],313:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DeleteShapeHandler;
+
+var _Collections = require('../../../util/Collections');
+
+var _Removal = require('../../../util/Removal');
+
+/**
+ * A handler that implements reversible deletion of shapes.
+ *
+ */
+function DeleteShapeHandler(canvas, modeling) {
+ this._canvas = canvas;
+ this._modeling = modeling;
+}
+
+DeleteShapeHandler.$inject = ['canvas', 'modeling'];
+
+/**
+ * - Remove connections
+ * - Remove all direct children
+ */
+DeleteShapeHandler.prototype.preExecute = function (context) {
+
+ var modeling = this._modeling;
+
+ var shape = context.shape;
+
+ // remove connections
+ (0, _Removal.saveClear)(shape.incoming, function (connection) {
+ // To make sure that the connection isn't removed twice
+ // For example if a container is removed
+ modeling.removeConnection(connection, { nested: true });
+ });
+
+ (0, _Removal.saveClear)(shape.outgoing, function (connection) {
+ modeling.removeConnection(connection, { nested: true });
+ });
+
+ // remove child shapes and connections
+ (0, _Removal.saveClear)(shape.children, function (child) {
+ if (isConnection(child)) {
+ modeling.removeConnection(child, { nested: true });
+ } else {
+ modeling.removeShape(child, { nested: true });
+ }
+ });
+};
+
+/**
+ * Remove shape and remember the parent
+ */
+DeleteShapeHandler.prototype.execute = function (context) {
+ var canvas = this._canvas;
+
+ var shape = context.shape,
+ oldParent = shape.parent;
+
+ context.oldParent = oldParent;
+
+ // remove containment
+ context.oldParentIndex = (0, _Collections.indexOf)(oldParent.children, shape);
+
+ // remove shape
+ canvas.removeShape(shape);
+
+ return shape;
+};
+
+/**
+ * Command revert implementation
+ */
+DeleteShapeHandler.prototype.revert = function (context) {
+
+ var canvas = this._canvas;
+
+ var shape = context.shape,
+ oldParent = context.oldParent,
+ oldParentIndex = context.oldParentIndex;
+
+ // restore containment
+ (0, _Collections.add)(oldParent.children, shape, oldParentIndex);
+
+ canvas.addShape(shape, oldParent);
+
+ return shape;
+};
+
+function isConnection(element) {
+ return element.waypoints;
+}
+
+},{"../../../util/Collections":393,"../../../util/Removal":406}],314:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = DistributeElements;
+
+var _minDash = require('min-dash');
+
+/**
+ * A handler that distributes elements evenly.
+ */
+function DistributeElements(modeling) {
+ this._modeling = modeling;
+}
+
+DistributeElements.$inject = ['modeling'];
+
+var OFF_AXIS = {
+ x: 'y',
+ y: 'x'
+};
+
+DistributeElements.prototype.preExecute = function (context) {
+ var modeling = this._modeling;
+
+ var groups = context.groups,
+ axis = context.axis,
+ dimension = context.dimension;
+
+ function updateRange(group, element) {
+ group.range.min = Math.min(element[axis], group.range.min);
+ group.range.max = Math.max(element[axis] + element[dimension], group.range.max);
+ }
+
+ function center(element) {
+ return element[axis] + element[dimension] / 2;
+ }
+
+ function lastIdx(arr) {
+ return arr.length - 1;
+ }
+
+ function rangeDiff(range) {
+ return range.max - range.min;
+ }
+
+ function centerElement(refCenter, element) {
+ var delta = { y: 0 };
+
+ delta[axis] = refCenter - center(element);
+
+ if (delta[axis]) {
+
+ delta[OFF_AXIS[axis]] = 0;
+
+ modeling.moveElements([element], delta, element.parent);
+ }
+ }
+
+ var firstGroup = groups[0],
+ lastGroupIdx = lastIdx(groups),
+ lastGroup = groups[lastGroupIdx];
+
+ var margin,
+ spaceInBetween,
+ groupsSize = 0; // the size of each range
+
+ (0, _minDash.forEach)(groups, function (group, idx) {
+ var sortedElements, refElem, refCenter;
+
+ if (group.elements.length < 2) {
+ if (idx && idx !== groups.length - 1) {
+ updateRange(group, group.elements[0]);
+
+ groupsSize += rangeDiff(group.range);
+ }
+ return;
+ }
+
+ sortedElements = (0, _minDash.sortBy)(group.elements, axis);
+
+ refElem = sortedElements[0];
+
+ if (idx === lastGroupIdx) {
+ refElem = sortedElements[lastIdx(sortedElements)];
+ }
+
+ refCenter = center(refElem);
+
+ // wanna update the ranges after the shapes have been centered
+ group.range = null;
+
+ (0, _minDash.forEach)(sortedElements, function (element) {
+
+ centerElement(refCenter, element);
+
+ if (group.range === null) {
+ group.range = {
+ min: element[axis],
+ max: element[axis] + element[dimension]
+ };
+
+ return;
+ }
+
+ // update group's range after centering the range elements
+ updateRange(group, element);
+ });
+
+ if (idx && idx !== groups.length - 1) {
+ groupsSize += rangeDiff(group.range);
+ }
+ });
+
+ spaceInBetween = Math.abs(lastGroup.range.min - firstGroup.range.max);
+
+ margin = Math.round((spaceInBetween - groupsSize) / (groups.length - 1));
+
+ if (margin < groups.length - 1) {
+ return;
+ }
+
+ (0, _minDash.forEach)(groups, function (group, groupIdx) {
+ var delta = {},
+ prevGroup;
+
+ if (group === firstGroup || group === lastGroup) {
+ return;
+ }
+
+ prevGroup = groups[groupIdx - 1];
+
+ group.range.max = 0;
+
+ (0, _minDash.forEach)(group.elements, function (element, idx) {
+ delta[OFF_AXIS[axis]] = 0;
+ delta[axis] = prevGroup.range.max - element[axis] + margin;
+
+ if (group.range.min !== element[axis]) {
+ delta[axis] += element[axis] - group.range.min;
+ }
+
+ if (delta[axis]) {
+ modeling.moveElements([element], delta, element.parent);
+ }
+
+ group.range.max = Math.max(element[axis] + element[dimension], idx ? group.range.max : 0);
+ });
+ });
+};
+
+DistributeElements.prototype.postExecute = function (context) {};
+
+},{"min-dash":505}],315:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = LayoutConnectionHandler;
+
+var _minDash = require('min-dash');
+
+/**
+ * A handler that implements reversible moving of shapes.
+ */
+function LayoutConnectionHandler(layouter, canvas) {
+ this._layouter = layouter;
+ this._canvas = canvas;
+}
+
+LayoutConnectionHandler.$inject = ['layouter', 'canvas'];
+
+LayoutConnectionHandler.prototype.execute = function (context) {
+
+ var connection = context.connection;
+
+ var oldWaypoints = connection.waypoints;
+
+ (0, _minDash.assign)(context, {
+ oldWaypoints: oldWaypoints
+ });
+
+ connection.waypoints = this._layouter.layoutConnection(connection, context.hints);
+
+ return connection;
+};
+
+LayoutConnectionHandler.prototype.revert = function (context) {
+
+ var connection = context.connection;
+
+ connection.waypoints = context.oldWaypoints;
+
+ return connection;
+};
+
+},{"min-dash":505}],316:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = MoveConnectionHandler;
+
+var _minDash = require('min-dash');
+
+var _Collections = require('../../../util/Collections');
+
+/**
+ * A handler that implements reversible moving of connections.
+ *
+ * The handler differs from the layout connection handler in a sense
+ * that it preserves the connection layout.
+ */
+function MoveConnectionHandler() {}
+
+MoveConnectionHandler.prototype.execute = function (context) {
+
+ var connection = context.connection,
+ delta = context.delta;
+
+ var newParent = context.newParent || connection.parent,
+ newParentIndex = context.newParentIndex,
+ oldParent = connection.parent;
+
+ // save old parent in context
+ context.oldParent = oldParent;
+ context.oldParentIndex = (0, _Collections.remove)(oldParent.children, connection);
+
+ // add to new parent at position
+ (0, _Collections.add)(newParent.children, connection, newParentIndex);
+
+ // update parent
+ connection.parent = newParent;
+
+ // update waypoint positions
+ (0, _minDash.forEach)(connection.waypoints, function (p) {
+ p.x += delta.x;
+ p.y += delta.y;
+
+ if (p.original) {
+ p.original.x += delta.x;
+ p.original.y += delta.y;
+ }
+ });
+
+ return connection;
+};
+
+MoveConnectionHandler.prototype.revert = function (context) {
+
+ var connection = context.connection,
+ newParent = connection.parent,
+ oldParent = context.oldParent,
+ oldParentIndex = context.oldParentIndex,
+ delta = context.delta;
+
+ // remove from newParent
+ (0, _Collections.remove)(newParent.children, connection);
+
+ // restore previous location in old parent
+ (0, _Collections.add)(oldParent.children, connection, oldParentIndex);
+
+ // restore parent
+ connection.parent = oldParent;
+
+ // revert to old waypoint positions
+ (0, _minDash.forEach)(connection.waypoints, function (p) {
+ p.x -= delta.x;
+ p.y -= delta.y;
+
+ if (p.original) {
+ p.original.x -= delta.x;
+ p.original.y -= delta.y;
+ }
+ });
+
+ return connection;
+};
+
+},{"../../../util/Collections":393,"min-dash":505}],317:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = MoveElementsHandler;
+
+var _MoveHelper = require('./helper/MoveHelper');
+
+var _MoveHelper2 = _interopRequireDefault(_MoveHelper);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A handler that implements reversible moving of shapes.
+ */
+function MoveElementsHandler(modeling) {
+ this._helper = new _MoveHelper2.default(modeling);
+}
+
+MoveElementsHandler.$inject = ['modeling'];
+
+MoveElementsHandler.prototype.preExecute = function (context) {
+ context.closure = this._helper.getClosure(context.shapes);
+};
+
+MoveElementsHandler.prototype.postExecute = function (context) {
+
+ var hints = context.hints,
+ primaryShape;
+
+ if (hints && hints.primaryShape) {
+ primaryShape = hints.primaryShape;
+ hints.oldParent = primaryShape.parent;
+ }
+
+ this._helper.moveClosure(context.closure, context.delta, context.newParent, context.newHost, primaryShape);
+};
+
+},{"./helper/MoveHelper":329}],318:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = MoveShapeHandler;
+
+var _minDash = require('min-dash');
+
+var _MoveHelper = require('./helper/MoveHelper');
+
+var _MoveHelper2 = _interopRequireDefault(_MoveHelper);
+
+var _Collections = require('../../../util/Collections');
+
+var _AnchorsHelper = require('./helper/AnchorsHelper');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A handler that implements reversible moving of shapes.
+ */
+function MoveShapeHandler(modeling) {
+ this._modeling = modeling;
+
+ this._helper = new _MoveHelper2.default(modeling);
+}
+
+MoveShapeHandler.$inject = ['modeling'];
+
+MoveShapeHandler.prototype.execute = function (context) {
+
+ var shape = context.shape,
+ delta = context.delta,
+ newParent = context.newParent || shape.parent,
+ newParentIndex = context.newParentIndex,
+ oldParent = shape.parent;
+
+ context.oldBounds = (0, _minDash.pick)(shape, ['x', 'y', 'width', 'height']);
+
+ // save old parent in context
+ context.oldParent = oldParent;
+ context.oldParentIndex = (0, _Collections.remove)(oldParent.children, shape);
+
+ // add to new parent at position
+ (0, _Collections.add)(newParent.children, shape, newParentIndex);
+
+ // update shape parent + position
+ (0, _minDash.assign)(shape, {
+ parent: newParent,
+ x: shape.x + delta.x,
+ y: shape.y + delta.y
+ });
+
+ return shape;
+};
+
+MoveShapeHandler.prototype.postExecute = function (context) {
+
+ var shape = context.shape,
+ delta = context.delta,
+ hints = context.hints;
+
+ var modeling = this._modeling;
+
+ if (hints.layout !== false) {
+
+ (0, _minDash.forEach)(shape.incoming, function (c) {
+ modeling.layoutConnection(c, {
+ connectionEnd: (0, _AnchorsHelper.getMovedTargetAnchor)(c, shape, delta)
+ });
+ });
+
+ (0, _minDash.forEach)(shape.outgoing, function (c) {
+ modeling.layoutConnection(c, {
+ connectionStart: (0, _AnchorsHelper.getMovedSourceAnchor)(c, shape, delta)
+ });
+ });
+ }
+
+ if (hints.recurse !== false) {
+ this.moveChildren(context);
+ }
+};
+
+MoveShapeHandler.prototype.revert = function (context) {
+
+ var shape = context.shape,
+ oldParent = context.oldParent,
+ oldParentIndex = context.oldParentIndex,
+ delta = context.delta;
+
+ // restore previous location in old parent
+ (0, _Collections.add)(oldParent.children, shape, oldParentIndex);
+
+ // revert to old position and parent
+ (0, _minDash.assign)(shape, {
+ parent: oldParent,
+ x: shape.x - delta.x,
+ y: shape.y - delta.y
+ });
+
+ return shape;
+};
+
+MoveShapeHandler.prototype.moveChildren = function (context) {
+
+ var delta = context.delta,
+ shape = context.shape;
+
+ this._helper.moveRecursive(shape.children, delta, null);
+};
+
+MoveShapeHandler.prototype.getNewParent = function (context) {
+ return context.newParent || context.shape.parent;
+};
+
+},{"../../../util/Collections":393,"./helper/AnchorsHelper":327,"./helper/MoveHelper":329,"min-dash":505}],319:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = PasteHandler;
+
+var _minDash = require('min-dash');
+
+function removeProperties(element, properties) {
+ (0, _minDash.forEach)(properties, function (prop) {
+ if (element[prop]) {
+ delete element[prop];
+ }
+ });
+}
+
+/**
+ * A handler that implements pasting of elements onto the diagram.
+ *
+ * @param {eventBus} EventBus
+ * @param {canvas} Canvas
+ * @param {selection} Selection
+ * @param {elementFactory} ElementFactory
+ * @param {modeling} Modeling
+ * @param {rules} Rules
+ */
+function PasteHandler(eventBus, canvas, selection, elementFactory, modeling, rules) {
+
+ this._eventBus = eventBus;
+ this._canvas = canvas;
+ this._selection = selection;
+ this._elementFactory = elementFactory;
+ this._modeling = modeling;
+ this._rules = rules;
+}
+
+PasteHandler.$inject = ['eventBus', 'canvas', 'selection', 'elementFactory', 'modeling', 'rules'];
+
+// api //////////////////////
+
+/**
+ * Creates a new shape
+ *
+ * @param {Object} context
+ * @param {Object} context.tree the new shape
+ * @param {Element} context.topParent the paste target
+ */
+PasteHandler.prototype.preExecute = function (context) {
+ var eventBus = this._eventBus,
+ self = this;
+
+ var tree = context.tree,
+ topParent = context.topParent,
+ position = context.position;
+
+ tree.createdElements = {};
+
+ tree.labels = [];
+
+ (0, _minDash.forEach)(tree, function (elements, depthStr) {
+ var depth = parseInt(depthStr, 10);
+
+ if (isNaN(depth)) {
+ return;
+ }
+
+ // set the parent on the top level elements
+ if (!depth) {
+ elements = (0, _minDash.map)(elements, function (descriptor) {
+ descriptor.parent = topParent;
+
+ return descriptor;
+ });
+ }
+
+ // Order by priority for element creation
+ elements = (0, _minDash.sortBy)(elements, 'priority');
+
+ (0, _minDash.forEach)(elements, function (descriptor) {
+ var id = descriptor.id,
+ parent = descriptor.parent,
+ hints = {},
+ newPosition;
+
+ var element = (0, _minDash.assign)({}, descriptor);
+
+ if (depth) {
+ element.parent = self._getCreatedElement(parent, tree);
+ }
+
+ // this happens when shapes have not been created due to rules
+ if (!parent) {
+ return;
+ }
+
+ eventBus.fire('element.paste', {
+ createdElements: tree.createdElements,
+ descriptor: element
+ });
+
+ // in case the parent changed during 'element.paste'
+ parent = element.parent;
+
+ if (element.waypoints) {
+ element = self._createConnection(element, parent, position, tree);
+
+ if (element) {
+ tree.createdElements[id] = {
+ element: element,
+ descriptor: descriptor
+ };
+ }
+
+ return;
+ }
+
+ // supply not-root information as hint
+ if (element.parent !== topParent) {
+ hints.root = false;
+ }
+
+ // set host
+ if (element.host) {
+ hints.attach = true;
+
+ parent = self._getCreatedElement(element.host, tree);
+ }
+
+ // handle labels
+ if (element.labelTarget) {
+ return tree.labels.push(element);
+ }
+
+ newPosition = {
+ x: Math.round(position.x + element.delta.x + element.width / 2),
+ y: Math.round(position.y + element.delta.y + element.height / 2)
+ };
+
+ removeProperties(element, ['id', 'parent', 'delta', 'host', 'priority']);
+
+ element = self._createShape(element, parent, newPosition, hints);
+
+ if (element) {
+ tree.createdElements[id] = {
+ element: element,
+ descriptor: descriptor
+ };
+ }
+ });
+ });
+};
+
+// move label's to their relative position
+PasteHandler.prototype.postExecute = function (context) {
+ var modeling = this._modeling,
+ selection = this._selection,
+ self = this;
+
+ var tree = context.tree,
+ labels = tree.labels,
+ topLevelElements = [];
+
+ (0, _minDash.forEach)(labels, function (labelDescriptor) {
+ var labelTarget = self._getCreatedElement(labelDescriptor.labelTarget, tree),
+ labels,
+ labelTargetPos,
+ newPosition;
+
+ if (!labelTarget) {
+ return;
+ }
+
+ labels = labelTarget.labels;
+
+ if (!labels || !labels.length) {
+ return;
+ }
+
+ labelTargetPos = {
+ x: labelTarget.x,
+ y: labelTarget.y
+ };
+
+ if (labelTarget.waypoints) {
+ labelTargetPos = labelTarget.waypoints[0];
+ }
+
+ (0, _minDash.forEach)(labels, function (label) {
+ newPosition = {
+ x: Math.round(labelTargetPos.x - label.x + labelDescriptor.delta.x),
+ y: Math.round(labelTargetPos.y - label.y + labelDescriptor.delta.y)
+ };
+
+ modeling.moveShape(label, newPosition, labelTarget.parent);
+ });
+ });
+
+ (0, _minDash.forEach)(tree[0], function (descriptor) {
+ var id = descriptor.id,
+ toplevel = tree.createdElements[id];
+
+ if (toplevel) {
+ topLevelElements.push(toplevel.element);
+ }
+ });
+
+ selection.select(topLevelElements);
+};
+
+PasteHandler.prototype._createConnection = function (element, parent, parentCenter, tree) {
+ var modeling = this._modeling,
+ rules = this._rules;
+
+ var connection, source, target, canPaste;
+
+ element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint, idx) {
+ return {
+ x: Math.round(parentCenter.x + element.delta[idx].x),
+ y: Math.round(parentCenter.y + element.delta[idx].y)
+ };
+ });
+
+ source = this._getCreatedElement(element.source, tree);
+ target = this._getCreatedElement(element.target, tree);
+
+ if (!source || !target) {
+ return null;
+ }
+
+ canPaste = rules.allowed('element.paste', {
+ source: source,
+ target: target
+ });
+
+ if (!canPaste) {
+ return null;
+ }
+
+ removeProperties(element, ['id', 'parent', 'delta', 'source', 'target', 'width', 'height', 'priority']);
+
+ connection = modeling.createConnection(source, target, element, parent);
+
+ return connection;
+};
+
+PasteHandler.prototype._createShape = function (element, parent, position, isAttach, hints) {
+ var modeling = this._modeling,
+ elementFactory = this._elementFactory,
+ rules = this._rules;
+
+ var canPaste = rules.allowed('element.paste', {
+ element: element,
+ position: position,
+ parent: parent
+ });
+
+ if (!canPaste) {
+ return null;
+ }
+
+ var shape = elementFactory.createShape(element);
+
+ modeling.createShape(shape, position, parent, isAttach, hints);
+
+ return shape;
+};
+
+PasteHandler.prototype._getCreatedElement = function (id, tree) {
+ return tree.createdElements[id] && tree.createdElements[id].element;
+};
+
+},{"min-dash":505}],320:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ReconnectConnectionHandler;
+
+var _minDash = require('min-dash');
+
+/**
+ * Reconnect connection handler
+ */
+function ReconnectConnectionHandler() {}
+
+ReconnectConnectionHandler.$inject = [];
+
+ReconnectConnectionHandler.prototype.execute = function (context) {
+
+ var newSource = context.newSource,
+ newTarget = context.newTarget,
+ connection = context.connection,
+ dockingOrPoints = context.dockingOrPoints,
+ oldWaypoints = connection.waypoints,
+ newWaypoints;
+
+ if (!newSource && !newTarget) {
+ throw new Error('newSource or newTarget are required');
+ }
+
+ if (newSource && newTarget) {
+ throw new Error('must specify either newSource or newTarget');
+ }
+
+ context.oldWaypoints = oldWaypoints;
+
+ if ((0, _minDash.isArray)(dockingOrPoints)) {
+ newWaypoints = dockingOrPoints;
+ } else {
+ newWaypoints = oldWaypoints.slice();
+
+ newWaypoints.splice(newSource ? 0 : -1, 1, dockingOrPoints);
+ }
+
+ if (newSource) {
+ context.oldSource = connection.source;
+ connection.source = newSource;
+ }
+
+ if (newTarget) {
+ context.oldTarget = connection.target;
+ connection.target = newTarget;
+ }
+
+ connection.waypoints = newWaypoints;
+
+ return connection;
+};
+
+ReconnectConnectionHandler.prototype.revert = function (context) {
+
+ var newSource = context.newSource,
+ newTarget = context.newTarget,
+ connection = context.connection;
+
+ if (newSource) {
+ connection.source = context.oldSource;
+ }
+
+ if (newTarget) {
+ connection.target = context.oldTarget;
+ }
+
+ connection.waypoints = context.oldWaypoints;
+
+ return connection;
+};
+
+},{"min-dash":505}],321:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ReplaceShapeHandler;
+
+var _minDash = require('min-dash');
+
+/**
+ * A handler that implements reversible replacing of shapes.
+ * Internally the old shape will be removed and the new shape will be added.
+ *
+ *
+ * @class
+ * @constructor
+ *
+ * @param {canvas} Canvas
+ */
+function ReplaceShapeHandler(modeling, rules) {
+ this._modeling = modeling;
+ this._rules = rules;
+}
+
+ReplaceShapeHandler.$inject = ['modeling', 'rules'];
+
+// api //////////////////////
+
+
+/**
+ * Replaces a shape with an replacement Element.
+ *
+ * The newData object should contain type, x, y.
+ *
+ * If possible also the incoming/outgoing connection
+ * will be restored.
+ *
+ * @param {Object} context
+ */
+ReplaceShapeHandler.prototype.preExecute = function (context) {
+
+ var self = this,
+ modeling = this._modeling,
+ rules = this._rules;
+
+ var oldShape = context.oldShape,
+ newData = context.newData,
+ hints = context.hints,
+ newShape;
+
+ function canReconnect(type, source, target, connection) {
+ return rules.allowed(type, {
+ source: source,
+ target: target,
+ connection: connection
+ });
+ }
+
+ // (1) place a new shape at the given position
+
+ var position = {
+ x: newData.x,
+ y: newData.y
+ };
+
+ newShape = context.newShape = context.newShape || self.createShape(newData, position, oldShape.parent, hints);
+
+ // (2) update the host
+
+ if (oldShape.host) {
+ modeling.updateAttachment(newShape, oldShape.host);
+ }
+
+ // (3) adopt all children from the old shape
+
+ var children;
+
+ if (hints.moveChildren !== false) {
+ children = oldShape.children.slice();
+
+ modeling.moveElements(children, { x: 0, y: 0 }, newShape);
+ }
+
+ // (4) reconnect connections to the new shape (where allowed)
+
+ var incoming = oldShape.incoming.slice(),
+ outgoing = oldShape.outgoing.slice();
+
+ (0, _minDash.forEach)(incoming, function (connection) {
+ var waypoints = connection.waypoints,
+ docking = waypoints[waypoints.length - 1],
+ source = connection.source,
+ allowed = canReconnect('connection.reconnectEnd', source, newShape, connection);
+
+ if (allowed) {
+ self.reconnectEnd(connection, newShape, docking);
+ }
+ });
+
+ (0, _minDash.forEach)(outgoing, function (connection) {
+ var waypoints = connection.waypoints,
+ docking = waypoints[0],
+ target = connection.target,
+ allowed = canReconnect('connection.reconnectStart', newShape, target, connection);
+
+ if (allowed) {
+ self.reconnectStart(connection, newShape, docking);
+ }
+ });
+};
+
+ReplaceShapeHandler.prototype.postExecute = function (context) {
+ var modeling = this._modeling;
+
+ var oldShape = context.oldShape,
+ newShape = context.newShape;
+
+ // if an element gets resized on replace, layout the connection again
+ (0, _minDash.forEach)(newShape.incoming, function (c) {
+ modeling.layoutConnection(c, { endChanged: true });
+ });
+
+ (0, _minDash.forEach)(newShape.outgoing, function (c) {
+ modeling.layoutConnection(c, { startChanged: true });
+ });
+
+ modeling.removeShape(oldShape);
+};
+
+ReplaceShapeHandler.prototype.execute = function (context) {};
+
+ReplaceShapeHandler.prototype.revert = function (context) {};
+
+ReplaceShapeHandler.prototype.createShape = function (shape, position, target, hints) {
+ var modeling = this._modeling;
+ return modeling.createShape(shape, position, target, hints);
+};
+
+ReplaceShapeHandler.prototype.reconnectStart = function (connection, newSource, dockingPoint) {
+ var modeling = this._modeling;
+ modeling.reconnectStart(connection, newSource, dockingPoint);
+};
+
+ReplaceShapeHandler.prototype.reconnectEnd = function (connection, newTarget, dockingPoint) {
+ var modeling = this._modeling;
+ modeling.reconnectEnd(connection, newTarget, dockingPoint);
+};
+
+},{"min-dash":505}],322:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ResizeShapeHandler;
+
+var _minDash = require('min-dash');
+
+var _AnchorsHelper = require('./helper/AnchorsHelper');
+
+/**
+ * A handler that implements reversible resizing of shapes.
+ *
+ * @param {Modeling} modeling
+ */
+function ResizeShapeHandler(modeling) {
+ this._modeling = modeling;
+}
+
+ResizeShapeHandler.$inject = ['modeling'];
+
+/**
+ * {
+ * shape: {....}
+ * newBounds: {
+ * width: 20,
+ * height: 40,
+ * x: 5,
+ * y: 10
+ * }
+ *
+ * }
+ */
+ResizeShapeHandler.prototype.execute = function (context) {
+ var shape = context.shape,
+ newBounds = context.newBounds,
+ minBounds = context.minBounds;
+
+ if (newBounds.x === undefined || newBounds.y === undefined || newBounds.width === undefined || newBounds.height === undefined) {
+ throw new Error('newBounds must have {x, y, width, height} properties');
+ }
+
+ if (minBounds && (newBounds.width < minBounds.width || newBounds.height < minBounds.height)) {
+ throw new Error('width and height cannot be less than minimum height and width');
+ } else if (!minBounds && newBounds.width < 10 || newBounds.height < 10) {
+ throw new Error('width and height cannot be less than 10px');
+ }
+
+ // save old bbox in context
+ context.oldBounds = {
+ width: shape.width,
+ height: shape.height,
+ x: shape.x,
+ y: shape.y
+ };
+
+ // update shape
+ (0, _minDash.assign)(shape, {
+ width: newBounds.width,
+ height: newBounds.height,
+ x: newBounds.x,
+ y: newBounds.y
+ });
+
+ return shape;
+};
+
+ResizeShapeHandler.prototype.postExecute = function (context) {
+
+ var shape = context.shape,
+ oldBounds = context.oldBounds;
+
+ var modeling = this._modeling;
+
+ (0, _minDash.forEach)(shape.incoming, function (c) {
+ modeling.layoutConnection(c, {
+ connectionEnd: (0, _AnchorsHelper.getResizedTargetAnchor)(c, shape, oldBounds)
+ });
+ });
+
+ (0, _minDash.forEach)(shape.outgoing, function (c) {
+ modeling.layoutConnection(c, {
+ connectionStart: (0, _AnchorsHelper.getResizedSourceAnchor)(c, shape, oldBounds)
+ });
+ });
+};
+
+ResizeShapeHandler.prototype.revert = function (context) {
+
+ var shape = context.shape,
+ oldBounds = context.oldBounds;
+
+ // restore previous bbox
+ (0, _minDash.assign)(shape, {
+ width: oldBounds.width,
+ height: oldBounds.height,
+ x: oldBounds.x,
+ y: oldBounds.y
+ });
+
+ return shape;
+};
+
+},{"./helper/AnchorsHelper":327,"min-dash":505}],323:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = SpaceToolHandler;
+
+var _minDash = require('min-dash');
+
+var _SpaceUtil = require('../../space-tool/SpaceUtil');
+
+/**
+ * A handler that implements reversible creating and removing of space.
+ *
+ * It executes in two phases:
+ *
+ * (1) resize all affected resizeShapes
+ * (2) move all affected moveElements
+ */
+function SpaceToolHandler(modeling) {
+ this._modeling = modeling;
+}
+
+SpaceToolHandler.$inject = ['modeling'];
+
+SpaceToolHandler.prototype.preExecute = function (context) {
+
+ // resize
+ var modeling = this._modeling,
+ resizingShapes = context.resizingShapes,
+ delta = context.delta,
+ direction = context.direction;
+
+ (0, _minDash.forEach)(resizingShapes, function (shape) {
+ var newBounds = (0, _SpaceUtil.resizeBounds)(shape, direction, delta);
+
+ modeling.resizeShape(shape, newBounds);
+ });
+};
+
+SpaceToolHandler.prototype.postExecute = function (context) {
+ // move
+ var modeling = this._modeling,
+ movingShapes = context.movingShapes,
+ delta = context.delta;
+
+ modeling.moveElements(movingShapes, delta, undefined, { autoResize: false, attach: false });
+};
+
+SpaceToolHandler.prototype.execute = function (context) {};
+SpaceToolHandler.prototype.revert = function (context) {};
+
+},{"../../space-tool/SpaceUtil":367,"min-dash":505}],324:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = ToggleShapeCollapseHandler;
+/**
+ * A handler that toggles the collapsed state of an element
+ * and the visibility of all its children.
+ *
+ * @param {Modeling} modeling
+ */
+function ToggleShapeCollapseHandler(modeling) {
+ this._modeling = modeling;
+}
+
+ToggleShapeCollapseHandler.$inject = ['modeling'];
+
+ToggleShapeCollapseHandler.prototype.execute = function (context) {
+
+ var shape = context.shape,
+ children = shape.children;
+
+ // remember previous visibility of children
+ context.oldChildrenVisibility = getElementsVisibility(children);
+
+ // toggle state
+ shape.collapsed = !shape.collapsed;
+
+ // hide/show children
+ setHidden(children, shape.collapsed);
+
+ return [shape].concat(children);
+};
+
+ToggleShapeCollapseHandler.prototype.revert = function (context) {
+
+ var shape = context.shape,
+ oldChildrenVisibility = context.oldChildrenVisibility;
+
+ var children = shape.children;
+
+ // set old visability of children
+ restoreVisibility(children, oldChildrenVisibility);
+
+ // retoggle state
+ shape.collapsed = !shape.collapsed;
+
+ return [shape].concat(children);
+};
+
+// helpers //////////////////////
+
+/**
+ * Return a map { elementId -> hiddenState}.
+ *
+ * @param {Array} elements
+ *
+ * @return {Object}
+ */
+function getElementsVisibility(elements) {
+
+ var result = {};
+
+ elements.forEach(function (e) {
+ result[e.id] = e.hidden;
+ });
+
+ return result;
+}
+
+function setHidden(elements, newHidden) {
+ elements.forEach(function (element) {
+ element.hidden = newHidden;
+ });
+}
+
+function restoreVisibility(elements, lastState) {
+ elements.forEach(function (e) {
+ e.hidden = lastState[e.id];
+ });
+}
+
+},{}],325:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = UpdateAttachmentHandler;
+
+var _Collections = require('../../../util/Collections');
+
+/**
+ * A handler that implements reversible attaching/detaching of shapes.
+ */
+function UpdateAttachmentHandler(modeling) {
+ this._modeling = modeling;
+}
+
+UpdateAttachmentHandler.$inject = ['modeling'];
+
+UpdateAttachmentHandler.prototype.execute = function (context) {
+ var shape = context.shape,
+ newHost = context.newHost,
+ oldHost = shape.host;
+
+ // (0) detach from old host
+ context.oldHost = oldHost;
+ context.attacherIdx = removeAttacher(oldHost, shape);
+
+ // (1) attach to new host
+ addAttacher(newHost, shape);
+
+ // (2) update host
+ shape.host = newHost;
+
+ return shape;
+};
+
+UpdateAttachmentHandler.prototype.revert = function (context) {
+ var shape = context.shape,
+ newHost = context.newHost,
+ oldHost = context.oldHost,
+ attacherIdx = context.attacherIdx;
+
+ // (2) update host
+ shape.host = oldHost;
+
+ // (1) attach to new host
+ removeAttacher(newHost, shape);
+
+ // (0) detach from old host
+ addAttacher(oldHost, shape, attacherIdx);
+
+ return shape;
+};
+
+function removeAttacher(host, attacher) {
+ // remove attacher from host
+ return (0, _Collections.remove)(host && host.attachers, attacher);
+}
+
+function addAttacher(host, attacher, idx) {
+
+ if (!host) {
+ return;
+ }
+
+ var attachers = host.attachers;
+
+ if (!attachers) {
+ host.attachers = attachers = [];
+ }
+
+ (0, _Collections.add)(attachers, attacher, idx);
+}
+
+},{"../../../util/Collections":393}],326:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = UpdateWaypointsHandler;
+function UpdateWaypointsHandler() {}
+
+UpdateWaypointsHandler.prototype.execute = function (context) {
+
+ var connection = context.connection,
+ newWaypoints = context.newWaypoints;
+
+ context.oldWaypoints = connection.waypoints;
+
+ connection.waypoints = newWaypoints;
+
+ return connection;
+};
+
+UpdateWaypointsHandler.prototype.revert = function (context) {
+
+ var connection = context.connection,
+ oldWaypoints = context.oldWaypoints;
+
+ connection.waypoints = oldWaypoints;
+
+ return connection;
+};
+
+},{}],327:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.getResizedSourceAnchor = getResizedSourceAnchor;
+exports.getResizedTargetAnchor = getResizedTargetAnchor;
+exports.getMovedSourceAnchor = getMovedSourceAnchor;
+exports.getMovedTargetAnchor = getMovedTargetAnchor;
+
+var _AttachUtil = require('../../../../util/AttachUtil');
+
+function getResizedSourceAnchor(connection, shape, oldBounds) {
+
+ var waypoints = safeGetWaypoints(connection),
+ oldAnchor = waypoints[0];
+
+ return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape);
+}
+
+function getResizedTargetAnchor(connection, shape, oldBounds) {
+
+ var waypoints = safeGetWaypoints(connection),
+ oldAnchor = waypoints[waypoints.length - 1];
+
+ return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape);
+}
+
+function getMovedSourceAnchor(connection, source, moveDelta) {
+ return getResizedSourceAnchor(connection, source, substractPosition(source, moveDelta));
+}
+
+function getMovedTargetAnchor(connection, target, moveDelta) {
+ return getResizedTargetAnchor(connection, target, substractPosition(target, moveDelta));
+}
+
+// helpers //////////////////////
+
+function substractPosition(bounds, delta) {
+ return {
+ x: bounds.x - delta.x,
+ y: bounds.y - delta.y,
+ width: bounds.width,
+ height: bounds.height
+ };
+}
+
+/**
+ * Return waypoints of given connection; throw if non exists (should not happen!!).
+ *
+ * @param {Connection} connection
+ *
+ * @return {Array}
+ */
+function safeGetWaypoints(connection) {
+
+ var waypoints = connection.waypoints;
+
+ if (!waypoints.length) {
+ throw new Error('connection#' + connection.id + ': no waypoints');
+ }
+
+ return waypoints;
+}
+
+},{"../../../../util/AttachUtil":391}],328:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = MoveClosure;
+
+var _minDash = require('min-dash');
+
+var _Elements = require('../../../../util/Elements');
+
+function MoveClosure() {
+
+ this.allShapes = {};
+ this.allConnections = {};
+
+ this.enclosedElements = {};
+ this.enclosedConnections = {};
+
+ this.topLevel = {};
+}
+
+MoveClosure.prototype.add = function (element, isTopLevel) {
+ return this.addAll([element], isTopLevel);
+};
+
+MoveClosure.prototype.addAll = function (elements, isTopLevel) {
+
+ var newClosure = (0, _Elements.getClosure)(elements, !!isTopLevel, this);
+
+ (0, _minDash.assign)(this, newClosure);
+
+ return this;
+};
+
+},{"../../../../util/Elements":396,"min-dash":505}],329:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = MoveHelper;
+
+var _minDash = require('min-dash');
+
+var _AnchorsHelper = require('./AnchorsHelper');
+
+var _MoveClosure = require('./MoveClosure');
+
+var _MoveClosure2 = _interopRequireDefault(_MoveClosure);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * A helper that is able to carry out serialized move
+ * operations on multiple elements.
+ *
+ * @param {Modeling} modeling
+ */
+function MoveHelper(modeling) {
+ this._modeling = modeling;
+}
+
+/**
+ * Move the specified elements and all children by the given delta.
+ *
+ * This moves all enclosed connections, too and layouts all affected
+ * external connections.
+ *
+ * @param {Array} elements
+ * @param {Point} delta
+ * @param {djs.model.Base} newParent applied to the first level of shapes
+ *
+ * @return {Array} list of touched elements
+ */
+MoveHelper.prototype.moveRecursive = function (elements, delta, newParent) {
+ if (!elements) {
+ return [];
+ } else {
+ return this.moveClosure(this.getClosure(elements), delta, newParent);
+ }
+};
+
+/**
+ * Move the given closure of elmements.
+ *
+ * @param {Object} closure
+ * @param {Point} delta
+ * @param {djs.model.Base} [newParent]
+ * @param {djs.model.Base} [newHost]
+ */
+MoveHelper.prototype.moveClosure = function (closure, delta, newParent, newHost, primaryShape) {
+ var modeling = this._modeling;
+
+ var allShapes = closure.allShapes,
+ allConnections = closure.allConnections,
+ enclosedConnections = closure.enclosedConnections,
+ topLevel = closure.topLevel,
+ keepParent = false;
+
+ if (primaryShape && primaryShape.parent === newParent) {
+ keepParent = true;
+ }
+
+ // move all shapes
+ (0, _minDash.forEach)(allShapes, function (shape) {
+
+ // move the element according to the given delta
+ modeling.moveShape(shape, delta, topLevel[shape.id] && !keepParent && newParent, {
+ recurse: false,
+ layout: false
+ });
+ });
+
+ // move all child connections / layout external connections
+ (0, _minDash.forEach)(allConnections, function (c) {
+
+ var sourceMoved = !!allShapes[c.source.id],
+ targetMoved = !!allShapes[c.target.id];
+
+ if (enclosedConnections[c.id] && sourceMoved && targetMoved) {
+ modeling.moveConnection(c, delta, topLevel[c.id] && !keepParent && newParent);
+ } else {
+ modeling.layoutConnection(c, {
+ connectionStart: sourceMoved && (0, _AnchorsHelper.getMovedSourceAnchor)(c, c.source, delta),
+ connectionEnd: targetMoved && (0, _AnchorsHelper.getMovedTargetAnchor)(c, c.target, delta)
+ });
+ }
+ });
+};
+
+/**
+ * Returns the closure for the selected elements
+ *
+ * @param {Array} elements
+ * @return {MoveClosure} closure
+ */
+MoveHelper.prototype.getClosure = function (elements) {
+ return new _MoveClosure2.default().addAll(elements, true);
+};
+
+},{"./AnchorsHelper":327,"./MoveClosure":328,"min-dash":505}],330:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = MouseTracking;
+
+var _minDash = require('min-dash');
+
+function MouseTracking(eventBus, canvas) {
+ this._eventBus = eventBus;
+ this._canvas = canvas;
+
+ this._init();
+}
+
+MouseTracking.$inject = ['eventBus', 'canvas'];
+
+MouseTracking.prototype.getHoverContext = function () {
+ var viewbox = this._canvas.viewbox();
+
+ return {
+ element: this._hoverElement,
+ point: {
+ x: viewbox.x + Math.round(this._mouseX / viewbox.scale),
+ y: viewbox.y + Math.round(this._mouseY / viewbox.scale)
+ }
+ };
+};
+
+MouseTracking.prototype._init = function () {
+ var eventBus = this._eventBus,
+ canvas = this._canvas;
+
+ var container = canvas.getContainer();
+
+ this._setMousePosition = (0, _minDash.bind)(this._setMousePosition, this);
+
+ container.addEventListener('mousemove', this._setMousePosition);
+
+ eventBus.on('diagram.destroy', function () {
+ container.removeEventListener('mousemove', this._setMousePosition);
+ }, this);
+
+ eventBus.on('element.hover', this._setHoverElement, this);
+};
+
+MouseTracking.prototype._setHoverElement = function (event) {
+ this._hoverElement = event.element;
+};
+
+MouseTracking.prototype._setMousePosition = function (event) {
+ this._mouseX = event.layerX;
+ this._mouseY = event.layerY;
+};
+
+},{"min-dash":505}],331:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _MouseTracking = require('./MouseTracking');
+
+var _MouseTracking2 = _interopRequireDefault(_MouseTracking);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['mouseTracking'],
+ mouseTracking: ['type', _MouseTracking2.default]
+};
+
+},{"./MouseTracking":330}],332:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = MoveEvents;
+
+var _minDash = require('min-dash');
+
+var _Event = require('../../util/Event');
+
+var LOW_PRIORITY = 500,
+ MEDIUM_PRIORITY = 1250,
+ HIGH_PRIORITY = 1500;
+
+var round = Math.round;
+
+function mid(element) {
+ return {
+ x: element.x + round(element.width / 2),
+ y: element.y + round(element.height / 2)
+ };
+}
+
+/**
+ * A plugin that makes shapes draggable / droppable.
+ *
+ * @param {EventBus} eventBus
+ * @param {Dragging} dragging
+ * @param {Modeling} modeling
+ * @param {Selection} selection
+ * @param {Rules} rules
+ */
+function MoveEvents(eventBus, dragging, modeling, selection, rules) {
+
+ // rules
+
+ function canMove(shapes, delta, position, target) {
+
+ return rules.allowed('elements.move', {
+ shapes: shapes,
+ delta: delta,
+ position: position,
+ target: target
+ });
+ }
+
+ // move events
+
+ // assign a high priority to this handler to setup the environment
+ // others may hook up later, e.g. at default priority and modify
+ // the move environment.
+ //
+ // This sets up the context with
+ //
+ // * shape: the primary shape being moved
+ // * shapes: a list of shapes to be moved
+ // * validatedShapes: a list of shapes that are being checked
+ // against the rules before and during move
+ //
+ eventBus.on('shape.move.start', HIGH_PRIORITY, function (event) {
+
+ var context = event.context,
+ shape = event.shape,
+ shapes = selection.get().slice();
+
+ // move only single shape if the dragged element
+ // is not part of the current selection
+ if (shapes.indexOf(shape) === -1) {
+ shapes = [shape];
+ }
+
+ // ensure we remove nested elements in the collection
+ // and add attachers for a proper dragger
+ shapes = removeNested(shapes);
+
+ // attach shapes to drag context
+ (0, _minDash.assign)(context, {
+ shapes: shapes,
+ validatedShapes: shapes,
+ shape: shape
+ });
+ });
+
+ // assign a high priority to this handler to setup the environment
+ // others may hook up later, e.g. at default priority and modify
+ // the move environment
+ //
+ eventBus.on('shape.move.start', MEDIUM_PRIORITY, function (event) {
+
+ var context = event.context,
+ validatedShapes = context.validatedShapes,
+ canExecute;
+
+ canExecute = context.canExecute = canMove(validatedShapes);
+
+ // check if we can move the elements
+ if (!canExecute) {
+ return false;
+ }
+ });
+
+ // assign a low priority to this handler
+ // to let others modify the move event before we update
+ // the context
+ //
+ eventBus.on('shape.move.move', LOW_PRIORITY, function (event) {
+
+ var context = event.context,
+ validatedShapes = context.validatedShapes,
+ hover = event.hover,
+ delta = { x: event.dx, y: event.dy },
+ position = { x: event.x, y: event.y },
+ canExecute;
+
+ // check if we can move the elements
+ canExecute = canMove(validatedShapes, delta, position, hover);
+
+ context.delta = delta;
+ context.canExecute = canExecute;
+
+ // simply ignore move over
+ if (canExecute === null) {
+ context.target = null;
+
+ return;
+ }
+
+ context.target = hover;
+ });
+
+ eventBus.on('shape.move.end', function (event) {
+
+ var context = event.context;
+
+ var delta = context.delta,
+ canExecute = context.canExecute,
+ isAttach = canExecute === 'attach',
+ shapes = context.shapes;
+
+ if (!canExecute) {
+ return false;
+ }
+
+ // ensure we have actual pixel values deltas
+ // (important when zoom level was > 1 during move)
+ delta.x = round(delta.x);
+ delta.y = round(delta.y);
+
+ modeling.moveElements(shapes, delta, context.target, {
+ primaryShape: context.shape,
+ attach: isAttach
+ });
+ });
+
+ // move activation
+
+ eventBus.on('element.mousedown', function (event) {
+
+ var originalEvent = (0, _Event.getOriginal)(event);
+
+ if (!originalEvent) {
+ throw new Error('must supply DOM mousedown event');
+ }
+
+ return start(originalEvent, event.element);
+ });
+
+ function start(event, element, activate) {
+
+ // do not move connections or the root element
+ if (element.waypoints || !element.parent) {
+ return;
+ }
+
+ var referencePoint = mid(element);
+
+ dragging.init(event, referencePoint, 'shape.move', {
+ cursor: 'grabbing',
+ autoActivate: activate,
+ data: {
+ shape: element,
+ context: {}
+ }
+ });
+
+ // we've handled the event
+ return true;
+ }
+
+ // API
+
+ this.start = start;
+}
+
+MoveEvents.$inject = ['eventBus', 'dragging', 'modeling', 'selection', 'rules'];
+
+/**
+ * Return a filtered list of elements that do not contain
+ * those nested into others.
+ *
+ * @param {Array} elements
+ *
+ * @return {Array} filtered
+ */
+function removeNested(elements) {
+
+ var ids = (0, _minDash.groupBy)(elements, 'id');
+
+ return (0, _minDash.filter)(elements, function (element) {
+ while (element = element.parent) {
+
+ // parent in selection
+ if (ids[element.id]) {
+ return false;
+ }
+ }
+
+ return true;
+ });
+}
+
+},{"../../util/Event":397,"min-dash":505}],333:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = MovePreview;
+
+var _minDash = require('min-dash');
+
+var _Elements = require('../../util/Elements');
+
+var _tinySvg = require('tiny-svg');
+
+var _SvgTransformUtil = require('../../util/SvgTransformUtil');
+
+var LOW_PRIORITY = 499;
+
+var MARKER_DRAGGING = 'djs-dragging',
+ MARKER_OK = 'drop-ok',
+ MARKER_NOT_OK = 'drop-not-ok',
+ MARKER_NEW_PARENT = 'new-parent',
+ MARKER_ATTACH = 'attach-ok';
+
+/**
+ * Provides previews for moving shapes when moving.
+ *
+ * @param {EventBus} eventBus
+ * @param {ElementRegistry} elementRegistry
+ * @param {Canvas} canvas
+ * @param {Styles} styles
+ */
+function MovePreview(eventBus, elementRegistry, canvas, styles, previewSupport) {
+
+ function getVisualDragShapes(shapes) {
+ var elements = getAllDraggedElements(shapes);
+
+ var filteredElements = removeEdges(elements);
+
+ return filteredElements;
+ }
+
+ function getAllDraggedElements(shapes) {
+ var allShapes = (0, _Elements.selfAndAllChildren)(shapes, true);
+
+ var allConnections = (0, _minDash.map)(allShapes, function (shape) {
+ return (shape.incoming || []).concat(shape.outgoing || []);
+ });
+
+ return (0, _minDash.flatten)(allShapes.concat(allConnections));
+ }
+
+ /**
+ * Sets drop marker on an element.
+ */
+ function setMarker(element, marker) {
+
+ [MARKER_ATTACH, MARKER_OK, MARKER_NOT_OK, MARKER_NEW_PARENT].forEach(function (m) {
+
+ if (m === marker) {
+ canvas.addMarker(element, m);
+ } else {
+ canvas.removeMarker(element, m);
+ }
+ });
+ }
+
+ /**
+ * Make an element draggable.
+ *
+ * @param {Object} context
+ * @param {djs.model.Base} element
+ * @param {Boolean} addMarker
+ */
+ function makeDraggable(context, element, addMarker) {
+
+ previewSupport.addDragger(element, context.dragGroup);
+
+ if (addMarker) {
+ canvas.addMarker(element, MARKER_DRAGGING);
+ }
+
+ if (context.allDraggedElements) {
+ context.allDraggedElements.push(element);
+ } else {
+ context.allDraggedElements = [element];
+ }
+ }
+
+ // assign a low priority to this handler
+ // to let others modify the move context before
+ // we draw things
+ eventBus.on('shape.move.start', LOW_PRIORITY, function (event) {
+
+ var context = event.context,
+ dragShapes = context.shapes,
+ allDraggedElements = context.allDraggedElements;
+
+ var visuallyDraggedShapes = getVisualDragShapes(dragShapes);
+
+ if (!context.dragGroup) {
+ var dragGroup = (0, _tinySvg.create)('g');
+ (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events']));
+
+ var defaultLayer = canvas.getDefaultLayer();
+
+ (0, _tinySvg.append)(defaultLayer, dragGroup);
+
+ context.dragGroup = dragGroup;
+ }
+
+ // add previews
+ visuallyDraggedShapes.forEach(function (shape) {
+ previewSupport.addDragger(shape, context.dragGroup);
+ });
+
+ // cache all dragged elements / gfx
+ // so that we can quickly undo their state changes later
+ if (!allDraggedElements) {
+ allDraggedElements = getAllDraggedElements(dragShapes);
+ } else {
+ allDraggedElements = (0, _minDash.flatten)([allDraggedElements, getAllDraggedElements(dragShapes)]);
+ }
+
+ // add dragging marker
+ (0, _minDash.forEach)(allDraggedElements, function (e) {
+ canvas.addMarker(e, MARKER_DRAGGING);
+ });
+
+ context.allDraggedElements = allDraggedElements;
+
+ // determine, if any of the dragged elements have different parents
+ context.differentParents = haveDifferentParents(dragShapes);
+ });
+
+ // update previews
+ eventBus.on('shape.move.move', LOW_PRIORITY, function (event) {
+
+ var context = event.context,
+ dragGroup = context.dragGroup,
+ target = context.target,
+ parent = context.shape.parent,
+ canExecute = context.canExecute;
+
+ if (target) {
+ if (canExecute === 'attach') {
+ setMarker(target, MARKER_ATTACH);
+ } else if (context.canExecute && target && target.id !== parent.id) {
+ setMarker(target, MARKER_NEW_PARENT);
+ } else {
+ setMarker(target, context.canExecute ? MARKER_OK : MARKER_NOT_OK);
+ }
+ }
+
+ (0, _SvgTransformUtil.translate)(dragGroup, event.dx, event.dy);
+ });
+
+ eventBus.on(['shape.move.out', 'shape.move.cleanup'], function (event) {
+ var context = event.context,
+ target = context.target;
+
+ if (target) {
+ setMarker(target, null);
+ }
+ });
+
+ // remove previews
+ eventBus.on('shape.move.cleanup', function (event) {
+
+ var context = event.context,
+ allDraggedElements = context.allDraggedElements,
+ dragGroup = context.dragGroup;
+
+ // remove dragging marker
+ (0, _minDash.forEach)(allDraggedElements, function (e) {
+ canvas.removeMarker(e, MARKER_DRAGGING);
+ });
+
+ if (dragGroup) {
+ (0, _tinySvg.clear)(dragGroup);
+ }
+ });
+
+ // API //////////////////////
+
+ /**
+ * Make an element draggable.
+ *
+ * @param {Object} context
+ * @param {djs.model.Base} element
+ * @param {Boolean} addMarker
+ */
+ this.makeDraggable = makeDraggable;
+}
+
+MovePreview.$inject = ['eventBus', 'elementRegistry', 'canvas', 'styles', 'previewSupport'];
+
+// helpers //////////////////////
+
+/**
+ * returns elements minus all connections
+ * where source or target is not elements
+ */
+function removeEdges(elements) {
+
+ var filteredElements = (0, _minDash.filter)(elements, function (element) {
+
+ if (!isConnection(element)) {
+ return true;
+ } else {
+
+ return (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.source.id })) && (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.target.id }));
+ }
+ });
+
+ return filteredElements;
+}
+
+function haveDifferentParents(elements) {
+ return (0, _minDash.size)((0, _minDash.groupBy)(elements, function (e) {
+ return e.parent && e.parent.id;
+ })) !== 1;
+}
+
+/**
+ * Checks if an element is a connection.
+ */
+function isConnection(element) {
+ return element.waypoints;
+}
+
+},{"../../util/Elements":396,"../../util/SvgTransformUtil":408,"min-dash":505,"tiny-svg":535}],334:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _interactionEvents = require('../interaction-events');
+
+var _interactionEvents2 = _interopRequireDefault(_interactionEvents);
+
+var _selection = require('../selection');
+
+var _selection2 = _interopRequireDefault(_selection);
+
+var _outline = require('../outline');
+
+var _outline2 = _interopRequireDefault(_outline);
+
+var _rules = require('../rules');
+
+var _rules2 = _interopRequireDefault(_rules);
+
+var _dragging = require('../dragging');
+
+var _dragging2 = _interopRequireDefault(_dragging);
+
+var _previewSupport = require('../preview-support');
+
+var _previewSupport2 = _interopRequireDefault(_previewSupport);
+
+var _Move = require('./Move');
+
+var _Move2 = _interopRequireDefault(_Move);
+
+var _MovePreview = require('./MovePreview');
+
+var _MovePreview2 = _interopRequireDefault(_MovePreview);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __depends__: [_interactionEvents2.default, _selection2.default, _outline2.default, _rules2.default, _dragging2.default, _previewSupport2.default],
+ __init__: ['move', 'movePreview'],
+ move: ['type', _Move2.default],
+ movePreview: ['type', _MovePreview2.default]
+};
+
+},{"../dragging":286,"../interaction-events":294,"../outline":337,"../preview-support":345,"../rules":355,"../selection":361,"./Move":332,"./MovePreview":333}],335:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = OrderingProvider;
+
+var _inherits = require('inherits');
+
+var _inherits2 = _interopRequireDefault(_inherits);
+
+var _CommandInterceptor = require('../../command/CommandInterceptor');
+
+var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * An abstract provider that allows modelers to implement a custom
+ * ordering of diagram elements on the canvas.
+ *
+ * It makes sure that the order is always preserved during element
+ * creation and move operations.
+ *
+ * In order to use this behavior, inherit from it and override
+ * the method {@link OrderingProvider#getOrdering}.
+ *
+ * @example
+ *
+ * ```javascript
+ * function CustomOrderingProvider(eventBus) {
+ * OrderingProvider.call(this, eventBus);
+ *
+ * this.getOrdering = function(element, newParent) {
+ * // always insert elements at the front
+ * // when moving
+ * return {
+ * index: 0,
+ * parent: newParent
+ * };
+ * };
+ * }
+ * ```
+ *
+ * @param {EventBus} eventBus
+ */
+function OrderingProvider(eventBus) {
+
+ _CommandInterceptor2.default.call(this, eventBus);
+
+ var self = this;
+
+ this.preExecute(['shape.create', 'connection.create'], function (event) {
+
+ var context = event.context,
+ element = context.shape || context.connection,
+ parent = context.parent;
+
+ var ordering = self.getOrdering(element, parent);
+
+ if (ordering) {
+
+ if (ordering.parent !== undefined) {
+ context.parent = ordering.parent;
+ }
+
+ context.parentIndex = ordering.index;
+ }
+ });
+
+ this.preExecute(['shape.move', 'connection.move'], function (event) {
+
+ var context = event.context,
+ element = context.shape || context.connection,
+ parent = context.newParent || element.parent;
+
+ var ordering = self.getOrdering(element, parent);
+
+ if (ordering) {
+
+ if (ordering.parent !== undefined) {
+ context.newParent = ordering.parent;
+ }
+
+ context.newParentIndex = ordering.index;
+ }
+ });
+}
+
+/**
+ * Return a custom ordering of the element, both in terms
+ * of parent element and index in the new parent.
+ *
+ * Implementors of this method must return an object with
+ * `parent` _and_ `index` in it.
+ *
+ * @param {djs.model.Base} element
+ * @param {djs.model.Shape} newParent
+ *
+ * @return {Object} ordering descriptor
+ */
+OrderingProvider.prototype.getOrdering = function (element, newParent) {
+ return null;
+};
+
+(0, _inherits2.default)(OrderingProvider, _CommandInterceptor2.default);
+
+},{"../../command/CommandInterceptor":243,"inherits":415}],336:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Outline;
+
+var _Elements = require('../../util/Elements');
+
+var _tinySvg = require('tiny-svg');
+
+var _minDom = require('min-dom');
+
+var _minDash = require('min-dash');
+
+var LOW_PRIORITY = 500;
+
+/**
+ * @class
+ *
+ * A plugin that adds an outline to shapes and connections that may be activated and styled
+ * via CSS classes.
+ *
+ * @param {EventBus} eventBus
+ * @param {Styles} styles
+ * @param {ElementRegistry} elementRegistry
+ */
+function Outline(eventBus, styles, elementRegistry) {
+
+ this.offset = 6;
+
+ var OUTLINE_STYLE = styles.cls('djs-outline', ['no-fill']);
+
+ var self = this;
+
+ function createOutline(gfx, bounds) {
+ var outline = (0, _tinySvg.create)('rect');
+
+ (0, _tinySvg.attr)(outline, (0, _minDash.assign)({
+ x: 10,
+ y: 10,
+ width: 100,
+ height: 100
+ }, OUTLINE_STYLE));
+
+ (0, _tinySvg.append)(gfx, outline);
+
+ return outline;
+ }
+
+ // A low priortity is necessary, because outlines of labels have to be updated
+ // after the label bounds have been updated in the renderer.
+ eventBus.on(['shape.added', 'shape.changed'], LOW_PRIORITY, function (event) {
+ var element = event.element,
+ gfx = event.gfx;
+
+ var outline = (0, _minDom.query)('.djs-outline', gfx);
+
+ if (!outline) {
+ outline = createOutline(gfx, element);
+ }
+
+ self.updateShapeOutline(outline, element);
+ });
+
+ eventBus.on(['connection.added', 'connection.changed'], function (event) {
+ var element = event.element,
+ gfx = event.gfx;
+
+ var outline = (0, _minDom.query)('.djs-outline', gfx);
+
+ if (!outline) {
+ outline = createOutline(gfx, element);
+ }
+
+ self.updateConnectionOutline(outline, element);
+ });
+}
+
+/**
+ * Updates the outline of a shape respecting the dimension of the
+ * element and an outline offset.
+ *
+ * @param {SVGElement} outline
+ * @param {djs.model.Base} element
+ */
+Outline.prototype.updateShapeOutline = function (outline, element) {
+
+ (0, _tinySvg.attr)(outline, {
+ x: -this.offset,
+ y: -this.offset,
+ width: element.width + this.offset * 2,
+ height: element.height + this.offset * 2
+ });
+};
+
+/**
+ * Updates the outline of a connection respecting the bounding box of
+ * the connection and an outline offset.
+ *
+ * @param {SVGElement} outline
+ * @param {djs.model.Base} element
+ */
+Outline.prototype.updateConnectionOutline = function (outline, connection) {
+
+ var bbox = (0, _Elements.getBBox)(connection);
+
+ (0, _tinySvg.attr)(outline, {
+ x: bbox.x - this.offset,
+ y: bbox.y - this.offset,
+ width: bbox.width + this.offset * 2,
+ height: bbox.height + this.offset * 2
+ });
+};
+
+Outline.$inject = ['eventBus', 'styles', 'elementRegistry'];
+
+},{"../../util/Elements":396,"min-dash":505,"min-dom":506,"tiny-svg":535}],337:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _Outline = require('./Outline');
+
+var _Outline2 = _interopRequireDefault(_Outline);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['outline'],
+ outline: ['type', _Outline2.default]
+};
+
+},{"./Outline":336}],338:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Overlays;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var _Elements = require('../../util/Elements');
+
+var _IdGenerator = require('../../util/IdGenerator');
+
+var _IdGenerator2 = _interopRequireDefault(_IdGenerator);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// document wide unique overlay ids
+var ids = new _IdGenerator2.default('ov');
+
+var LOW_PRIORITY = 500;
+
+/**
+ * A service that allows users to attach overlays to diagram elements.
+ *
+ * The overlay service will take care of overlay positioning during updates.
+ *
+ * @example
+ *
+ * // add a pink badge on the top left of the shape
+ * overlays.add(someShape, {
+ * position: {
+ * top: -5,
+ * left: -5
+ * },
+ * html: '0
'
+ * });
+ *
+ * // or add via shape id
+ *
+ * overlays.add('some-element-id', {
+ * position: {
+ * top: -5,
+ * left: -5
+ * }
+ * html: '0
'
+ * });
+ *
+ * // or add with optional type
+ *
+ * overlays.add(someShape, 'badge', {
+ * position: {
+ * top: -5,
+ * left: -5
+ * }
+ * html: '0
'
+ * });
+ *
+ *
+ * // remove an overlay
+ *
+ * var id = overlays.add(...);
+ * overlays.remove(id);
+ *
+ *
+ * You may configure overlay defaults during tool by providing a `config` module
+ * with `overlays.defaults` as an entry:
+ *
+ * {
+ * overlays: {
+ * defaults: {
+ * show: {
+ * minZoom: 0.7,
+ * maxZoom: 5.0
+ * },
+ * scale: {
+ * min: 1
+ * }
+ * }
+ * }
+ *
+ * @param {Object} config
+ * @param {EventBus} eventBus
+ * @param {Canvas} canvas
+ * @param {ElementRegistry} elementRegistry
+ */
+function Overlays(config, eventBus, canvas, elementRegistry) {
+
+ this._eventBus = eventBus;
+ this._canvas = canvas;
+ this._elementRegistry = elementRegistry;
+
+ this._ids = ids;
+
+ this._overlayDefaults = (0, _minDash.assign)({
+ // no show constraints
+ show: null,
+
+ // always scale
+ scale: true
+ }, config && config.defaults);
+
+ /**
+ * Mapping overlayId -> overlay
+ */
+ this._overlays = {};
+
+ /**
+ * Mapping elementId -> overlay container
+ */
+ this._overlayContainers = [];
+
+ // root html element for all overlays
+ this._overlayRoot = createRoot(canvas.getContainer());
+
+ this._init();
+}
+
+Overlays.$inject = ['config.overlays', 'eventBus', 'canvas', 'elementRegistry'];
+
+/**
+ * Returns the overlay with the specified id or a list of overlays
+ * for an element with a given type.
+ *
+ * @example
+ *
+ * // return the single overlay with the given id
+ * overlays.get('some-id');
+ *
+ * // return all overlays for the shape
+ * overlays.get({ element: someShape });
+ *
+ * // return all overlays on shape with type 'badge'
+ * overlays.get({ element: someShape, type: 'badge' });
+ *
+ * // shape can also be specified as id
+ * overlays.get({ element: 'element-id', type: 'badge' });
+ *
+ *
+ * @param {Object} search
+ * @param {String} [search.id]
+ * @param {String|djs.model.Base} [search.element]
+ * @param {String} [search.type]
+ *
+ * @return {Object|Array} the overlay(s)
+ */
+Overlays.prototype.get = function (search) {
+
+ if ((0, _minDash.isString)(search)) {
+ search = { id: search };
+ }
+
+ if ((0, _minDash.isString)(search.element)) {
+ search.element = this._elementRegistry.get(search.element);
+ }
+
+ if (search.element) {
+ var container = this._getOverlayContainer(search.element, true);
+
+ // return a list of overlays when searching by element (+type)
+ if (container) {
+ return search.type ? (0, _minDash.filter)(container.overlays, (0, _minDash.matchPattern)({ type: search.type })) : container.overlays.slice();
+ } else {
+ return [];
+ }
+ } else if (search.type) {
+ return (0, _minDash.filter)(this._overlays, (0, _minDash.matchPattern)({ type: search.type }));
+ } else {
+ // return single element when searching by id
+ return search.id ? this._overlays[search.id] : null;
+ }
+};
+
+/**
+ * Adds a HTML overlay to an element.
+ *
+ * @param {String|djs.model.Base} element attach overlay to this shape
+ * @param {String} [type] optional type to assign to the overlay
+ * @param {Object} overlay the overlay configuration
+ *
+ * @param {String|DOMElement} overlay.html html element to use as an overlay
+ * @param {Object} [overlay.show] show configuration
+ * @param {Number} [overlay.show.minZoom] minimal zoom level to show the overlay
+ * @param {Number} [overlay.show.maxZoom] maximum zoom level to show the overlay
+ * @param {Object} overlay.position where to attach the overlay
+ * @param {Number} [overlay.position.left] relative to element bbox left attachment
+ * @param {Number} [overlay.position.top] relative to element bbox top attachment
+ * @param {Number} [overlay.position.bottom] relative to element bbox bottom attachment
+ * @param {Number} [overlay.position.right] relative to element bbox right attachment
+ * @param {Boolean|Object} [overlay.scale=true] false to preserve the same size regardless of
+ * diagram zoom
+ * @param {Number} [overlay.scale.min]
+ * @param {Number} [overlay.scale.max]
+ *
+ * @return {String} id that may be used to reference the overlay for update or removal
+ */
+Overlays.prototype.add = function (element, type, overlay) {
+
+ if ((0, _minDash.isObject)(type)) {
+ overlay = type;
+ type = null;
+ }
+
+ if (!element.id) {
+ element = this._elementRegistry.get(element);
+ }
+
+ if (!overlay.position) {
+ throw new Error('must specifiy overlay position');
+ }
+
+ if (!overlay.html) {
+ throw new Error('must specifiy overlay html');
+ }
+
+ if (!element) {
+ throw new Error('invalid element specified');
+ }
+
+ var id = this._ids.next();
+
+ overlay = (0, _minDash.assign)({}, this._overlayDefaults, overlay, {
+ id: id,
+ type: type,
+ element: element,
+ html: overlay.html
+ });
+
+ this._addOverlay(overlay);
+
+ return id;
+};
+
+/**
+ * Remove an overlay with the given id or all overlays matching the given filter.
+ *
+ * @see Overlays#get for filter options.
+ *
+ * @param {String} [id]
+ * @param {Object} [filter]
+ */
+Overlays.prototype.remove = function (filter) {
+
+ var overlays = this.get(filter) || [];
+
+ if (!(0, _minDash.isArray)(overlays)) {
+ overlays = [overlays];
+ }
+
+ var self = this;
+
+ (0, _minDash.forEach)(overlays, function (overlay) {
+
+ var container = self._getOverlayContainer(overlay.element, true);
+
+ if (overlay) {
+ (0, _minDom.remove)(overlay.html);
+ (0, _minDom.remove)(overlay.htmlContainer);
+
+ delete overlay.htmlContainer;
+ delete overlay.element;
+
+ delete self._overlays[overlay.id];
+ }
+
+ if (container) {
+ var idx = container.overlays.indexOf(overlay);
+ if (idx !== -1) {
+ container.overlays.splice(idx, 1);
+ }
+ }
+ });
+};
+
+Overlays.prototype.show = function () {
+ setVisible(this._overlayRoot);
+};
+
+Overlays.prototype.hide = function () {
+ setVisible(this._overlayRoot, false);
+};
+
+Overlays.prototype.clear = function () {
+ this._overlays = {};
+
+ this._overlayContainers = [];
+
+ (0, _minDom.clear)(this._overlayRoot);
+};
+
+Overlays.prototype._updateOverlayContainer = function (container) {
+ var element = container.element,
+ html = container.html;
+
+ // update container left,top according to the elements x,y coordinates
+ // this ensures we can attach child elements relative to this container
+
+ var x = element.x,
+ y = element.y;
+
+ if (element.waypoints) {
+ var bbox = (0, _Elements.getBBox)(element);
+ x = bbox.x;
+ y = bbox.y;
+ }
+
+ setPosition(html, x, y);
+
+ (0, _minDom.attr)(container.html, 'data-container-id', element.id);
+};
+
+Overlays.prototype._updateOverlay = function (overlay) {
+
+ var position = overlay.position,
+ htmlContainer = overlay.htmlContainer,
+ element = overlay.element;
+
+ // update overlay html relative to shape because
+ // it is already positioned on the element
+
+ // update relative
+ var left = position.left,
+ top = position.top;
+
+ if (position.right !== undefined) {
+
+ var width;
+
+ if (element.waypoints) {
+ width = (0, _Elements.getBBox)(element).width;
+ } else {
+ width = element.width;
+ }
+
+ left = position.right * -1 + width;
+ }
+
+ if (position.bottom !== undefined) {
+
+ var height;
+
+ if (element.waypoints) {
+ height = (0, _Elements.getBBox)(element).height;
+ } else {
+ height = element.height;
+ }
+
+ top = position.bottom * -1 + height;
+ }
+
+ setPosition(htmlContainer, left || 0, top || 0);
+};
+
+Overlays.prototype._createOverlayContainer = function (element) {
+ var html = (0, _minDom.domify)('
');
+
+ this._overlayRoot.appendChild(html);
+
+ var container = {
+ html: html,
+ element: element,
+ overlays: []
+ };
+
+ this._updateOverlayContainer(container);
+
+ this._overlayContainers.push(container);
+
+ return container;
+};
+
+Overlays.prototype._updateRoot = function (viewbox) {
+ var scale = viewbox.scale || 1;
+
+ var matrix = 'matrix(' + [scale, 0, 0, scale, -1 * viewbox.x * scale, -1 * viewbox.y * scale].join(',') + ')';
+
+ setTransform(this._overlayRoot, matrix);
+};
+
+Overlays.prototype._getOverlayContainer = function (element, raw) {
+ var container = (0, _minDash.find)(this._overlayContainers, function (c) {
+ return c.element === element;
+ });
+
+ if (!container && !raw) {
+ return this._createOverlayContainer(element);
+ }
+
+ return container;
+};
+
+Overlays.prototype._addOverlay = function (overlay) {
+
+ var id = overlay.id,
+ element = overlay.element,
+ html = overlay.html,
+ htmlContainer,
+ overlayContainer;
+
+ // unwrap jquery (for those who need it)
+ if (html.get && html.constructor.prototype.jquery) {
+ html = html.get(0);
+ }
+
+ // create proper html elements from
+ // overlay HTML strings
+ if ((0, _minDash.isString)(html)) {
+ html = (0, _minDom.domify)(html);
+ }
+
+ overlayContainer = this._getOverlayContainer(element);
+
+ htmlContainer = (0, _minDom.domify)('');
+
+ htmlContainer.appendChild(html);
+
+ if (overlay.type) {
+ (0, _minDom.classes)(htmlContainer).add('djs-overlay-' + overlay.type);
+ }
+
+ overlay.htmlContainer = htmlContainer;
+
+ overlayContainer.overlays.push(overlay);
+ overlayContainer.html.appendChild(htmlContainer);
+
+ this._overlays[id] = overlay;
+
+ this._updateOverlay(overlay);
+ this._updateOverlayVisibilty(overlay, this._canvas.viewbox());
+};
+
+Overlays.prototype._updateOverlayVisibilty = function (overlay, viewbox) {
+ var show = overlay.show,
+ minZoom = show && show.minZoom,
+ maxZoom = show && show.maxZoom,
+ htmlContainer = overlay.htmlContainer,
+ visible = true;
+
+ if (show) {
+ if ((0, _minDash.isDefined)(minZoom) && minZoom > viewbox.scale || (0, _minDash.isDefined)(maxZoom) && maxZoom < viewbox.scale) {
+ visible = false;
+ }
+
+ setVisible(htmlContainer, visible);
+ }
+
+ this._updateOverlayScale(overlay, viewbox);
+};
+
+Overlays.prototype._updateOverlayScale = function (overlay, viewbox) {
+ var shouldScale = overlay.scale,
+ minScale,
+ maxScale,
+ htmlContainer = overlay.htmlContainer;
+
+ var scale,
+ transform = '';
+
+ if (shouldScale !== true) {
+
+ if (shouldScale === false) {
+ minScale = 1;
+ maxScale = 1;
+ } else {
+ minScale = shouldScale.min;
+ maxScale = shouldScale.max;
+ }
+
+ if ((0, _minDash.isDefined)(minScale) && viewbox.scale < minScale) {
+ scale = (1 / viewbox.scale || 1) * minScale;
+ }
+
+ if ((0, _minDash.isDefined)(maxScale) && viewbox.scale > maxScale) {
+ scale = (1 / viewbox.scale || 1) * maxScale;
+ }
+ }
+
+ if ((0, _minDash.isDefined)(scale)) {
+ transform = 'scale(' + scale + ',' + scale + ')';
+ }
+
+ setTransform(htmlContainer, transform);
+};
+
+Overlays.prototype._updateOverlaysVisibilty = function (viewbox) {
+
+ var self = this;
+
+ (0, _minDash.forEach)(this._overlays, function (overlay) {
+ self._updateOverlayVisibilty(overlay, viewbox);
+ });
+};
+
+Overlays.prototype._init = function () {
+
+ var eventBus = this._eventBus;
+
+ var self = this;
+
+ // scroll/zoom integration
+
+ function updateViewbox(viewbox) {
+ self._updateRoot(viewbox);
+ self._updateOverlaysVisibilty(viewbox);
+
+ self.show();
+ }
+
+ eventBus.on('canvas.viewbox.changing', function (event) {
+ self.hide();
+ });
+
+ eventBus.on('canvas.viewbox.changed', function (event) {
+ updateViewbox(event.viewbox);
+ });
+
+ // remove integration
+
+ eventBus.on(['shape.remove', 'connection.remove'], function (e) {
+ var element = e.element;
+ var overlays = self.get({ element: element });
+
+ (0, _minDash.forEach)(overlays, function (o) {
+ self.remove(o.id);
+ });
+
+ var container = self._getOverlayContainer(element);
+
+ if (container) {
+ (0, _minDom.remove)(container.html);
+ var i = self._overlayContainers.indexOf(container);
+ if (i !== -1) {
+ self._overlayContainers.splice(i, 1);
+ }
+ }
+ });
+
+ // move integration
+
+ eventBus.on('element.changed', LOW_PRIORITY, function (e) {
+ var element = e.element;
+
+ var container = self._getOverlayContainer(element, true);
+
+ if (container) {
+ (0, _minDash.forEach)(container.overlays, function (overlay) {
+ self._updateOverlay(overlay);
+ });
+
+ self._updateOverlayContainer(container);
+ }
+ });
+
+ // marker integration, simply add them on the overlays as classes, too.
+
+ eventBus.on('element.marker.update', function (e) {
+ var container = self._getOverlayContainer(e.element, true);
+ if (container) {
+ (0, _minDom.classes)(container.html)[e.add ? 'add' : 'remove'](e.marker);
+ }
+ });
+
+ // clear overlays with diagram
+
+ eventBus.on('diagram.clear', this.clear, this);
+};
+
+// helpers /////////////////////////////
+
+function createRoot(parentNode) {
+ var root = (0, _minDom.domify)('
');
+
+ parentNode.insertBefore(root, parentNode.firstChild);
+
+ return root;
+}
+
+function setPosition(el, x, y) {
+ (0, _minDash.assign)(el.style, { left: x + 'px', top: y + 'px' });
+}
+
+function setVisible(el, visible) {
+ el.style.display = visible === false ? 'none' : '';
+}
+
+function setTransform(el, transform) {
+
+ el.style['transform-origin'] = 'top left';
+
+ ['', '-ms-', '-webkit-'].forEach(function (prefix) {
+ el.style[prefix + 'transform'] = transform;
+ });
+}
+
+},{"../../util/Elements":396,"../../util/IdGenerator":400,"min-dash":505,"min-dom":506}],339:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _Overlays = require('./Overlays');
+
+var _Overlays2 = _interopRequireDefault(_Overlays);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['overlays'],
+ overlays: ['type', _Overlays2.default]
+};
+
+},{"./Overlays":338}],340:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = Palette;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var TOGGLE_SELECTOR = '.djs-palette-toggle',
+ ENTRY_SELECTOR = '.entry',
+ ELEMENT_SELECTOR = TOGGLE_SELECTOR + ', ' + ENTRY_SELECTOR;
+
+var PALETTE_OPEN_CLS = 'open',
+ PALETTE_TWO_COLUMN_CLS = 'two-column';
+
+/**
+ * A palette containing modeling elements.
+ */
+function Palette(eventBus, canvas) {
+
+ this._eventBus = eventBus;
+ this._canvas = canvas;
+
+ this._providers = [];
+
+ var self = this;
+
+ eventBus.on('tool-manager.update', function (event) {
+ var tool = event.tool;
+
+ self.updateToolHighlight(tool);
+ });
+
+ eventBus.on('i18n.changed', function () {
+ self._update();
+ });
+
+ eventBus.on('diagram.init', function () {
+
+ self._diagramInitialized = true;
+
+ // initialize + update once diagram is ready
+ if (self._providers.length) {
+ self._init();
+
+ self._update();
+ }
+ });
+}
+
+Palette.$inject = ['eventBus', 'canvas'];
+
+/**
+ * Register a provider with the palette
+ *
+ * @param {PaletteProvider} provider
+ */
+Palette.prototype.registerProvider = function (provider) {
+ this._providers.push(provider);
+
+ // postpone init / update until diagram is initialized
+ if (!this._diagramInitialized) {
+ return;
+ }
+
+ if (!this._container) {
+ this._init();
+ }
+
+ this._update();
+};
+
+/**
+ * Returns the palette entries for a given element
+ *
+ * @return {Array
} list of entries
+ */
+Palette.prototype.getEntries = function () {
+
+ var entries = {};
+
+ // loop through all providers and their entries.
+ // group entries by id so that overriding an entry is possible
+ (0, _minDash.forEach)(this._providers, function (provider) {
+ var e = provider.getPaletteEntries();
+
+ (0, _minDash.forEach)(e, function (entry, id) {
+ entries[id] = entry;
+ });
+ });
+
+ return entries;
+};
+
+/**
+ * Initialize
+ */
+Palette.prototype._init = function () {
+ var canvas = this._canvas,
+ eventBus = this._eventBus;
+
+ var parent = canvas.getContainer(),
+ container = this._container = (0, _minDom.domify)(Palette.HTML_MARKUP),
+ self = this;
+
+ parent.appendChild(container);
+
+ _minDom.delegate.bind(container, ELEMENT_SELECTOR, 'click', function (event) {
+
+ var target = event.delegateTarget;
+
+ if ((0, _minDom.matches)(target, TOGGLE_SELECTOR)) {
+ return self.toggle();
+ }
+
+ self.trigger('click', event);
+ });
+
+ // prevent drag propagation
+ _minDom.event.bind(container, 'mousedown', function (event) {
+ event.stopPropagation();
+ });
+
+ // prevent drag propagation
+ _minDom.delegate.bind(container, ENTRY_SELECTOR, 'dragstart', function (event) {
+ self.trigger('dragstart', event);
+ });
+
+ eventBus.on('canvas.resized', this._layoutChanged, this);
+
+ eventBus.fire('palette.create', {
+ container: container
+ });
+};
+
+/**
+ * Update palette state.
+ *
+ * @param {Object} [state] { open, twoColumn }
+ */
+Palette.prototype._toggleState = function (state) {
+
+ state = state || {};
+
+ var parent = this._getParentContainer(),
+ container = this._container;
+
+ var eventBus = this._eventBus;
+
+ var twoColumn;
+
+ var cls = (0, _minDom.classes)(container);
+
+ if ('twoColumn' in state) {
+ twoColumn = state.twoColumn;
+ } else {
+ twoColumn = this._needsCollapse(parent.clientHeight, this._entries || {});
+ }
+
+ // always update two column
+ cls.toggle(PALETTE_TWO_COLUMN_CLS, twoColumn);
+
+ if ('open' in state) {
+ cls.toggle(PALETTE_OPEN_CLS, state.open);
+ }
+
+ eventBus.fire('palette.changed', {
+ twoColumn: twoColumn,
+ open: this.isOpen()
+ });
+};
+
+Palette.prototype._update = function () {
+
+ var entriesContainer = (0, _minDom.query)('.djs-palette-entries', this._container),
+ entries = this._entries = this.getEntries();
+
+ (0, _minDom.clear)(entriesContainer);
+
+ (0, _minDash.forEach)(entries, function (entry, id) {
+
+ var grouping = entry.group || 'default';
+
+ var container = (0, _minDom.query)('[data-group=' + grouping + ']', entriesContainer);
+ if (!container) {
+ container = (0, _minDom.domify)('
');
+ entriesContainer.appendChild(container);
+ }
+
+ var html = entry.html || (entry.separator ? ' ' : '
');
+
+ var control = (0, _minDom.domify)(html);
+ container.appendChild(control);
+
+ if (!entry.separator) {
+ (0, _minDom.attr)(control, 'data-action', id);
+
+ if (entry.title) {
+ (0, _minDom.attr)(control, 'title', entry.title);
+ }
+
+ if (entry.className) {
+ addClasses(control, entry.className);
+ }
+
+ if (entry.imageUrl) {
+ control.appendChild((0, _minDom.domify)(' '));
+ }
+ }
+ });
+
+ // open after update
+ this.open();
+};
+
+/**
+ * Trigger an action available on the palette
+ *
+ * @param {String} action
+ * @param {Event} event
+ */
+Palette.prototype.trigger = function (action, event, autoActivate) {
+ var entries = this._entries,
+ entry,
+ handler,
+ originalEvent,
+ button = event.delegateTarget || event.target;
+
+ if (!button) {
+ return event.preventDefault();
+ }
+
+ entry = entries[(0, _minDom.attr)(button, 'data-action')];
+
+ // when user clicks on the palette and not on an action
+ if (!entry) {
+ return;
+ }
+
+ handler = entry.action;
+
+ originalEvent = event.originalEvent || event;
+
+ // simple action (via callback function)
+ if ((0, _minDash.isFunction)(handler)) {
+ if (action === 'click') {
+ handler(originalEvent, autoActivate);
+ }
+ } else {
+ if (handler[action]) {
+ handler[action](originalEvent, autoActivate);
+ }
+ }
+
+ // silence other actions
+ event.preventDefault();
+};
+
+Palette.prototype._layoutChanged = function () {
+ this._toggleState({});
+};
+
+/**
+ * Do we need to collapse to two columns?
+ *
+ * @param {Number} availableHeight
+ * @param {Object} entries
+ *
+ * @return {Boolean}
+ */
+Palette.prototype._needsCollapse = function (availableHeight, entries) {
+
+ // top margin + bottom toggle + bottom margin
+ // implementors must override this method if they
+ // change the palette styles
+ var margin = 20 + 10 + 20;
+
+ var entriesHeight = Object.keys(entries).length * 46;
+
+ return availableHeight < entriesHeight + margin;
+};
+
+/**
+ * Close the palette
+ */
+Palette.prototype.close = function () {
+
+ this._toggleState({
+ open: false,
+ twoColumn: false
+ });
+};
+
+/**
+ * Open the palette
+ */
+Palette.prototype.open = function () {
+ this._toggleState({ open: true });
+};
+
+Palette.prototype.toggle = function (open) {
+ if (this.isOpen()) {
+ this.close();
+ } else {
+ this.open();
+ }
+};
+
+Palette.prototype.isActiveTool = function (tool) {
+ return tool && this._activeTool === tool;
+};
+
+Palette.prototype.updateToolHighlight = function (name) {
+ var entriesContainer, toolsContainer;
+
+ if (!this._toolsContainer) {
+ entriesContainer = (0, _minDom.query)('.djs-palette-entries', this._container);
+
+ this._toolsContainer = (0, _minDom.query)('[data-group=tools]', entriesContainer);
+ }
+
+ toolsContainer = this._toolsContainer;
+
+ (0, _minDash.forEach)(toolsContainer.children, function (tool) {
+ var actionName = tool.getAttribute('data-action');
+
+ if (!actionName) {
+ return;
+ }
+
+ var toolClasses = (0, _minDom.classes)(tool);
+
+ actionName = actionName.replace('-tool', '');
+
+ if (toolClasses.contains('entry') && actionName === name) {
+ toolClasses.add('highlighted-entry');
+ } else {
+ toolClasses.remove('highlighted-entry');
+ }
+ });
+};
+
+/**
+ * Return true if the palette is opened.
+ *
+ * @example
+ *
+ * palette.open();
+ *
+ * if (palette.isOpen()) {
+ * // yes, we are open
+ * }
+ *
+ * @return {boolean} true if palette is opened
+ */
+Palette.prototype.isOpen = function () {
+ return (0, _minDom.classes)(this._container).has(PALETTE_OPEN_CLS);
+};
+
+/**
+ * Get container the palette lives in.
+ *
+ * @return {Element}
+ */
+Palette.prototype._getParentContainer = function () {
+ return this._canvas.getContainer();
+};
+
+/* markup definition */
+
+Palette.HTML_MARKUP = '';
+
+// helpers //////////////////////
+
+function addClasses(element, classNames) {
+
+ var classes = (0, _minDom.classes)(element);
+
+ var actualClassNames = (0, _minDash.isArray)(classNames) ? classNames : classNames.split(/\s+/g);
+ actualClassNames.forEach(function (cls) {
+ classes.add(cls);
+ });
+}
+
+},{"min-dash":505,"min-dom":506}],341:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _Palette = require('./Palette');
+
+var _Palette2 = _interopRequireDefault(_Palette);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ __init__: ['palette'],
+ palette: ['type', _Palette2.default]
+};
+
+},{"./Palette":340}],342:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = PopupMenu;
+
+var _minDash = require('min-dash');
+
+var _minDom = require('min-dom');
+
+var DATA_REF = 'data-id';
+
+/**
+ * A popup menu that can be used to display a list of actions anywhere in the canvas.
+ *
+ * @param {Object} config
+ * @param {Boolean|Object} [config.scale={ min: 1.0, max: 1.5 }]
+ * @param {Number} [config.scale.min]
+ * @param {Number} [config.scale.max]
+ * @param {EventBus} eventBus
+ * @param {Canvas} canvas
+ *
+ * @class
+ * @constructor
+ */
+function PopupMenu(config, eventBus, canvas) {
+
+ var scale = (0, _minDash.isDefined)(config && config.scale) ? config.scale : {
+ min: 1,
+ max: 1.5
+ };
+
+ this._config = {
+ scale: scale
+ };
+
+ this._eventBus = eventBus;
+ this._canvas = canvas;
+ this._providers = {};
+ this._current = {};
+}
+
+PopupMenu.$inject = ['config.popupMenu', 'eventBus', 'canvas'];
+
+/**
+ * Registers a popup menu provider
+ *
+ * @param {String} id
+ * @param {Object} provider
+ *
+ * @example
+ *
+ * popupMenu.registerProvider('myMenuID', {
+ * getEntries: function(element) {
+ * return [
+ * {
+ * id: 'entry-1',
+ * label: 'My Entry',
+ * action: 'alert("I have been clicked!")'
+ * }
+ * ];
+ * }
+ * });
+ */
+PopupMenu.prototype.registerProvider = function (id, provider) {
+ this._providers[id] = provider;
+};
+
+/**
+ * Determine if the popup menu has entries.
+ *
+ * @return {Boolean} true if empty
+ */
+PopupMenu.prototype.isEmpty = function (element, providerId) {
+ if (!element) {
+ throw new Error('element parameter is missing');
+ }
+
+ if (!providerId) {
+ throw new Error('providerId parameter is missing');
+ }
+
+ var provider = this._providers[providerId];
+
+ var entries = provider.getEntries(element),
+ headerEntries = provider.getHeaderEntries && provider.getHeaderEntries(element);
+
+ var hasEntries = entries.length > 0,
+ hasHeaderEntries = headerEntries && headerEntries.length > 0;
+
+ return !hasEntries && !hasHeaderEntries;
+};
+
+/**
+ * Create entries and open popup menu at given position
+ *
+ * @param {Object} element
+ * @param {String} id provider id
+ * @param {Object} position
+ *
+ * @return {Object} popup menu instance
+ */
+PopupMenu.prototype.open = function (element, id, position) {
+
+ var provider = this._providers[id];
+
+ if (!element) {
+ throw new Error('Element is missing');
+ }
+
+ if (!provider) {
+ throw new Error('Provider is not registered: ' + id);
+ }
+
+ if (!position) {
+ throw new Error('the position argument is missing');
+ }
+
+ if (this.isOpen()) {
+ this.close();
+ }
+
+ this._emit('open');
+
+ var current = this._current = {
+ provider: provider,
+ className: id,
+ element: element,
+ position: position
+ };
+
+ if (provider.getHeaderEntries) {
+ current.headerEntries = provider.getHeaderEntries(element);
+ }
+
+ current.entries = provider.getEntries(element);
+
+ current.container = this._createContainer();
+
+ var headerEntries = current.headerEntries || [],
+ entries = current.entries || [];
+
+ if (headerEntries.length) {
+ current.container.appendChild(this._createEntries(current.headerEntries, 'djs-popup-header'));
+ }
+
+ if (entries.length) {
+ current.container.appendChild(this._createEntries(current.entries, 'djs-popup-body'));
+ }
+
+ var canvas = this._canvas,
+ parent = canvas.getContainer();
+
+ this._attachContainer(current.container, parent, position.cursor);
+};
+
+/**
+ * Removes the popup menu and unbinds the event handlers.
+ */
+PopupMenu.prototype.close = function () {
+
+ if (!this.isOpen()) {
+ return;
+ }
+
+ this._emit('close');
+
+ this._unbindHandlers();
+ (0, _minDom.remove)(this._current.container);
+ this._current.container = null;
+};
+
+/**
+ * Determine if an open popup menu exist.
+ *
+ * @return {Boolean} true if open
+ */
+PopupMenu.prototype.isOpen = function () {
+ return !!this._current.container;
+};
+
+/**
+ * Trigger an action associated with an entry.
+ *
+ * @param {Object} event
+ *
+ * @return the result of the action callback, if any
+ */
+PopupMenu.prototype.trigger = function (event) {
+
+ // silence other actions
+ event.preventDefault();
+
+ var element = event.delegateTarget || event.target,
+ entryId = (0, _minDom.attr)(element, DATA_REF);
+
+ var entry = this._getEntry(entryId);
+
+ if (entry.action) {
+ return entry.action.call(null, event, entry);
+ }
+};
+
+/**
+ * Gets an entry instance (either entry or headerEntry) by id.
+ *
+ * @param {String} entryId
+ *
+ * @return {Object} entry instance
+ */
+PopupMenu.prototype._getEntry = function (entryId) {
+
+ var search = (0, _minDash.matchPattern)({ id: entryId });
+
+ var entry = (0, _minDash.find)(this._current.entries, search) || (0, _minDash.find)(this._current.headerEntries, search);
+
+ if (!entry) {
+ throw new Error('entry not found');
+ }
+
+ return entry;
+};
+
+PopupMenu.prototype._emit = function (eventName) {
+ this._eventBus.fire('popupMenu.' + eventName);
+};
+
+/**
+ * Creates the popup menu container.
+ *
+ * @return {Object} a DOM container
+ */
+PopupMenu.prototype._createContainer = function () {
+ var container = (0, _minDom.domify)('