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 @@ + + + + + + + + + + + + + + + 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,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"); + src: url("data:;base64,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") format('embedded-opentype'), url("data:application/font-woff;base64,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") format('woff'), url("data:application/x-font-ttf;base64,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IDxZIyAuRrACJUZQWCA8WS6xKwEUKy2wPiywNSsjIC5GsAIlRlJYIDxZLrErARQrLbA/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(''); + + 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(''); + 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 = '' + ''; + + // 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 ''; +}; + +/** + * @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 = '' + ''; + + // 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 = ''; + +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 += ''; + }); + 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 ? '
' + '' + '' + '
' : '') + '
' + '
' + 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 = '' + '
' + '
' + '
'; + + // 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 = '' + '
' + '' + '' + '
'; + + // 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: '
' + '' + '
' + '' + '' + '
' + '
', + + 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(''); + + // 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: '
' + '' + '
' + '' + '
' + '
' + + + // expression + '
' + '' + '
' + '' + '' + '
' + '
' + 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 ''; + }; + + var initSelectionSize = function initSelectionSize(selectBox, optionsLength) { + if (resizable) { + selectBox.size = optionsLength > defaultSize ? optionsLength : defaultSize; + } + }; + + return { + id: id, + html: '
' + '' + '
' + '' + (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: '
' + '' + '
' + '' + '' + '
' + '
' + '
' + '' + '
' + '' + '
' + '
' + '
' + '' + '
' + '' + '' + '
' + '
' + '
' + '' + '
' + '' + '
' + '
', + + 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 = '
' + '
' + '
' + '' + BPMNIO_IMG + '' + 'Web-based tooling for BPMN, DMN and CMMN diagrams ' + 'powered by bpmn.io.' + '
' + '
'; + +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)('
'), + position = this._current.position, + className = this._current.className; + + (0, _minDash.assign)(container.style, { + position: 'absolute', + left: position.x + 'px', + top: position.y + 'px', + visibility: 'hidden' + }); + + (0, _minDom.classes)(container).add(className); + + return container; +}; + +/** + * Attaches the container to the DOM and binds the event handlers. + * + * @param {Object} container + * @param {Object} parent + */ +PopupMenu.prototype._attachContainer = function (container, parent, cursor) { + var self = this; + + // Event handler + _minDom.delegate.bind(container, '.entry', 'click', function (event) { + self.trigger(event); + }); + + this._updateScale(container); + + // Attach to DOM + parent.appendChild(container); + + if (cursor) { + this._assureIsInbounds(container, cursor); + } + + // Add Handler + this._bindHandlers(); +}; + +/** + * Updates popup style.transform with respect to the config and zoom level. + * + * @method _updateScale + * + * @param {Object} container + */ +PopupMenu.prototype._updateScale = function (container) { + var zoom = this._canvas.zoom(); + + var scaleConfig = this._config.scale, + minScale, + maxScale, + scale = zoom; + + if (scaleConfig !== true) { + + if (scaleConfig === false) { + minScale = 1; + maxScale = 1; + } else { + minScale = scaleConfig.min; + maxScale = scaleConfig.max; + } + + if ((0, _minDash.isDefined)(minScale) && zoom < minScale) { + scale = minScale; + } + + if ((0, _minDash.isDefined)(maxScale) && zoom > maxScale) { + scale = maxScale; + } + } + + setTransform(container, 'scale(' + scale + ')'); +}; + +/** + * Make sure that the menu is always fully shown + * + * @method function + * + * @param {Object} container + * @param {Position} cursor {x, y} + */ +PopupMenu.prototype._assureIsInbounds = function (container, cursor) { + var canvas = this._canvas, + clientRect = canvas._container.getBoundingClientRect(); + + var containerX = container.offsetLeft, + containerY = container.offsetTop, + containerWidth = container.scrollWidth, + containerHeight = container.scrollHeight, + overAxis = {}, + left, + top; + + var cursorPosition = { + x: cursor.x - clientRect.left, + y: cursor.y - clientRect.top + }; + + if (containerX + containerWidth > clientRect.width) { + overAxis.x = true; + } + + if (containerY + containerHeight > clientRect.height) { + overAxis.y = true; + } + + if (overAxis.x && overAxis.y) { + left = cursorPosition.x - containerWidth + 'px'; + top = cursorPosition.y - containerHeight + 'px'; + } else if (overAxis.x) { + left = cursorPosition.x - containerWidth + 'px'; + top = cursorPosition.y + 'px'; + } else if (overAxis.y && cursorPosition.y < containerHeight) { + left = cursorPosition.x + 'px'; + top = 10 + 'px'; + } else if (overAxis.y) { + left = cursorPosition.x + 'px'; + top = cursorPosition.y - containerHeight + 'px'; + } + + (0, _minDash.assign)(container.style, { left: left, top: top }, { visibility: 'visible', 'z-index': 1000 }); +}; + +/** + * Creates a list of entries and returns them as a DOM container. + * + * @param {Array} entries an array of entry objects + * @param {String} className the class name of the entry container + * + * @return {Object} a DOM container + */ +PopupMenu.prototype._createEntries = function (entries, className) { + + var entriesContainer = (0, _minDom.domify)('
'), + self = this; + + (0, _minDom.classes)(entriesContainer).add(className); + + (0, _minDash.forEach)(entries, function (entry) { + var entryContainer = self._createEntry(entry, entriesContainer); + entriesContainer.appendChild(entryContainer); + }); + + return entriesContainer; +}; + +/** + * Creates a single entry and returns it as a DOM container. + * + * @param {Object} entry + * + * @return {Object} a DOM container + */ +PopupMenu.prototype._createEntry = function (entry) { + + if (!entry.id) { + throw new Error('every entry must have the id property set'); + } + + var entryContainer = (0, _minDom.domify)('
'), + entryClasses = (0, _minDom.classes)(entryContainer); + + entryClasses.add('entry'); + + if (entry.className) { + entry.className.split(' ').forEach(function (className) { + entryClasses.add(className); + }); + } + + (0, _minDom.attr)(entryContainer, DATA_REF, entry.id); + + if (entry.label) { + var label = (0, _minDom.domify)(''); + label.textContent = entry.label; + entryContainer.appendChild(label); + } + + if (entry.imageUrl) { + entryContainer.appendChild((0, _minDom.domify)('')); + } + + if (entry.active === true) { + entryClasses.add('active'); + } + + if (entry.disabled === true) { + entryClasses.add('disabled'); + } + + if (entry.title) { + entryContainer.title = entry.title; + } + + return entryContainer; +}; + +/** + * Binds the `close` method to 'contextPad.close' & 'canvas.viewbox.changed'. + */ +PopupMenu.prototype._bindHandlers = function () { + + var eventBus = this._eventBus, + self = this; + + function close() { + self.close(); + } + + eventBus.once('contextPad.close', close); + eventBus.once('canvas.viewbox.changing', close); + eventBus.once('commandStack.changed', close); +}; + +/** + * Unbinds the `close` method to 'contextPad.close' & 'canvas.viewbox.changing'. + */ +PopupMenu.prototype._unbindHandlers = function () { + + var eventBus = this._eventBus, + self = this; + + function close() { + self.close(); + } + + eventBus.off('contextPad.close', close); + eventBus.off('canvas.viewbox.changed', close); + eventBus.off('commandStack.changed', close); +}; + +// helpers ///////////////////////////// + +function setTransform(element, transform) { + element.style['transform-origin'] = 'top left'; + + ['', '-ms-', '-webkit-'].forEach(function (prefix) { + element.style[prefix + 'transform'] = transform; + }); +} + +},{"min-dash":505,"min-dom":506}],343:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _PopupMenu = require('./PopupMenu'); + +var _PopupMenu2 = _interopRequireDefault(_PopupMenu); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __init__: ['popupMenu'], + popupMenu: ['type', _PopupMenu2.default] +}; + +},{"./PopupMenu":342}],344:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = PreviewSupport; + +var _minDash = require('min-dash'); + +var _tinySvg = require('tiny-svg'); + +/** + * Adds support for previews of moving/resizing elements. + */ +function PreviewSupport(elementRegistry, canvas, styles) { + this._elementRegistry = elementRegistry; + this._canvas = canvas; + this._styles = styles; +} + +PreviewSupport.$inject = ['elementRegistry', 'canvas', 'styles']; + +/** + * Returns graphics of an element. + * + * @param {djs.model.Base} element + * + * @return {SVGElement} + */ +PreviewSupport.prototype.getGfx = function (element) { + return this._elementRegistry.getGraphics(element); +}; + +/** + * Adds a move preview of a given shape to a given svg group. + * + * @param {djs.model.Base} element + * @param {SVGElement} group + * + * @return {SVGElement} dragger + */ +PreviewSupport.prototype.addDragger = function (shape, group) { + var gfx = this.getGfx(shape); + + // clone is not included in tsvg for some reason + var dragger = (0, _tinySvg.clone)(gfx); + var bbox = gfx.getBoundingClientRect(); + + // remove markers from connections + if (isConnection(shape)) { + removeMarkers(dragger); + } + + (0, _tinySvg.attr)(dragger, this._styles.cls('djs-dragger', [], { + x: bbox.top, + y: bbox.left + })); + + (0, _tinySvg.append)(group, dragger); + + return dragger; +}; + +/** + * Adds a resize preview of a given shape to a given svg group. + * + * @param {djs.model.Base} element + * @param {SVGElement} group + * + * @return {SVGElement} frame + */ +PreviewSupport.prototype.addFrame = function (shape, group) { + + var frame = (0, _tinySvg.create)('rect', { + class: 'djs-resize-overlay', + width: shape.width, + height: shape.height, + x: shape.x, + y: shape.y + }); + + (0, _tinySvg.append)(group, frame); + + return frame; +}; + +// helpers ////////////////////// + +/** + * Removes all svg marker references from an SVG. + * + * @param {SVGElement} gfx + */ +function removeMarkers(gfx) { + + if (gfx.children) { + + (0, _minDash.forEach)(gfx.children, function (child) { + + // recursion + removeMarkers(child); + }); + } + + gfx.style.markerStart = ''; + gfx.style.markerEnd = ''; +} + +/** + * Checks if an element is a connection. + */ +function isConnection(element) { + return element.waypoints; +} + +},{"min-dash":505,"tiny-svg":535}],345:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _PreviewSupport = require('./PreviewSupport'); + +var _PreviewSupport2 = _interopRequireDefault(_PreviewSupport); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __init__: ['previewSupport'], + previewSupport: ['type', _PreviewSupport2.default] +}; + +},{"./PreviewSupport":344}],346:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = Replace; +var round = Math.round; + +/** + * Service that allow replacing of elements. + */ +function Replace(modeling) { + + this._modeling = modeling; +} + +Replace.$inject = ['modeling']; + +/** + * @param {Element} oldElement - Element to be replaced + * @param {Object} newElementData - Containing information about the new Element, for example height, width, type. + * @param {Object} options - Custom options that will be attached to the context. It can be used to inject data + * that is needed in the command chain. For example it could be used in + * eventbus.on('commandStack.shape.replace.postExecute') to change shape attributes after + * shape creation. + */ +Replace.prototype.replaceElement = function (oldElement, newElementData, options) { + + var modeling = this._modeling; + + var newElement = null; + + if (oldElement.waypoints) { + // TODO + // modeling.replaceConnection + } else { + // set center of element for modeling API + // if no new width / height is given use old elements size + newElementData.x = round(oldElement.x + (newElementData.width || oldElement.width) / 2); + newElementData.y = round(oldElement.y + (newElementData.height || oldElement.height) / 2); + + newElement = modeling.replaceShape(oldElement, newElementData, options); + } + + return newElement; +}; + +},{}],347:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _Replace = require('./Replace'); + +var _Replace2 = _interopRequireDefault(_Replace); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __init__: ['replace'], + replace: ['type', _Replace2.default] +}; + +},{"./Replace":346}],348:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = Resize; + +var _minDash = require('min-dash'); + +var _ResizeUtil = require('./ResizeUtil'); + +var _LayoutUtil = require('../../layout/LayoutUtil'); + +var DEFAULT_MIN_WIDTH = 10; + +/** + * A component that provides resizing of shapes on the canvas. + * + * The following components are part of shape resize: + * + * * adding resize handles, + * * creating a visual during resize + * * checking resize rules + * * committing a change once finished + * + * + * ## Customizing + * + * It's possible to customize the resizing behaviour by intercepting 'resize.start' + * and providing the following parameters through the 'context': + * + * * minDimensions ({ width, height }): minimum shape dimensions + * + * * childrenBoxPadding ({ left, top, bottom, right } || number): + * gap between the minimum bounding box and the container + * + * f.ex: + * + * ```javascript + * eventBus.on('resize.start', 1500, function(event) { + * var context = event.context, + * + * context.minDimensions = { width: 140, height: 120 }; + * + * // Passing general padding + * context.childrenBoxPadding = 30; + * + * // Passing padding to a specific side + * context.childrenBoxPadding.left = 20; + * }); + * ``` + */ +function Resize(eventBus, rules, modeling, dragging) { + + this._dragging = dragging; + this._rules = rules; + + var self = this; + + /** + * Handle resize move by specified delta. + * + * @param {Object} context + * @param {Point delta + */ + function handleMove(context, delta) { + + var shape = context.shape, + direction = context.direction, + resizeConstraints = context.resizeConstraints, + newBounds; + + context.delta = delta; + + newBounds = (0, _ResizeUtil.resizeBounds)(shape, direction, delta); + + // ensure constraints during resize + context.newBounds = (0, _ResizeUtil.ensureConstraints)(newBounds, resizeConstraints); + + // update + cache executable state + context.canExecute = self.canResize(context); + } + + /** + * Handle resize start. + * + * @param {Object} context + */ + function handleStart(context) { + + var resizeConstraints = context.resizeConstraints, + + // evaluate minBounds for backwards compatibility + minBounds = context.minBounds; + + if (resizeConstraints !== undefined) { + return; + } + + if (minBounds === undefined) { + minBounds = self.computeMinResizeBox(context); + } + + context.resizeConstraints = { + min: (0, _LayoutUtil.asTRBL)(minBounds) + }; + } + + /** + * Handle resize end. + * + * @param {Object} context + */ + function handleEnd(context) { + var shape = context.shape, + canExecute = context.canExecute, + newBounds = context.newBounds; + + 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.resizeShape(shape, newBounds); + } + } + + eventBus.on('resize.start', function (event) { + handleStart(event.context); + }); + + eventBus.on('resize.move', function (event) { + var delta = { + x: event.dx, + y: event.dy + }; + + handleMove(event.context, delta); + }); + + eventBus.on('resize.end', function (event) { + handleEnd(event.context); + }); +} + +Resize.prototype.canResize = function (context) { + var rules = this._rules; + + var ctx = (0, _minDash.pick)(context, ['newBounds', 'shape', 'delta', 'direction']); + + return rules.allowed('shape.resize', ctx); +}; + +/** + * Activate a resize operation. + * + * You may specify additional contextual information and must specify a + * resize direction during activation of the resize event. + * + * @param {MouseEvent} event + * @param {djs.model.Shape} shape + * @param {Object|String} contextOrDirection + */ +Resize.prototype.activate = function (event, shape, contextOrDirection) { + var dragging = this._dragging, + context, + direction; + + if (typeof contextOrDirection === 'string') { + contextOrDirection = { + direction: contextOrDirection + }; + } + + context = (0, _minDash.assign)({ shape: shape }, contextOrDirection); + + direction = context.direction; + + if (!direction) { + throw new Error('must provide a direction (nw|se|ne|sw)'); + } + + dragging.init(event, 'resize', { + autoActivate: true, + cursor: 'resize-' + (/nw|se/.test(direction) ? 'nwse' : 'nesw'), + data: { + shape: shape, + context: context + } + }); +}; + +Resize.prototype.computeMinResizeBox = function (context) { + var shape = context.shape, + direction = context.direction, + minDimensions, + childrenBounds; + + minDimensions = context.minDimensions || { + width: DEFAULT_MIN_WIDTH, + height: DEFAULT_MIN_WIDTH + }; + + // get children bounds + childrenBounds = (0, _ResizeUtil.computeChildrenBBox)(shape, context.childrenBoxPadding); + + // get correct minimum bounds from given resize direction + // basically ensures that the minBounds is max(childrenBounds, minDimensions) + return (0, _ResizeUtil.getMinResizeBounds)(direction, shape, minDimensions, childrenBounds); +}; + +Resize.$inject = ['eventBus', 'rules', 'modeling', 'dragging']; + +},{"../../layout/LayoutUtil":380,"./ResizeUtil":351,"min-dash":505}],349:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = ResizeHandles; + +var _minDash = require('min-dash'); + +var _tinySvg = require('tiny-svg'); + +var _minDom = require('min-dom'); + +var _Mouse = require('../../util/Mouse'); + +var _LayoutUtil = require('../../layout/LayoutUtil'); + +var _SvgTransformUtil = require('../../util/SvgTransformUtil'); + +var HANDLE_OFFSET = -2, + HANDLE_SIZE = 5, + HANDLE_HIT_SIZE = 20; + +var CLS_RESIZER = 'djs-resizer'; + +/** + * This component is responsible for adding resize handles. + * + * @param {EventBus} eventBus + * @param {Canvas} canvas + * @param {Selection} selection + * @param {Resize} resize + */ +function ResizeHandles(eventBus, canvas, selection, resize) { + + this._resize = resize; + this._canvas = canvas; + + var self = this; + + eventBus.on('selection.changed', function (e) { + var newSelection = e.newSelection; + + // remove old selection markers + self.removeResizers(); + + // add new selection markers ONLY if single selection + if (newSelection.length === 1) { + (0, _minDash.forEach)(newSelection, (0, _minDash.bind)(self.addResizer, self)); + } + }); + + eventBus.on('shape.changed', function (e) { + var shape = e.element; + + if (selection.isSelected(shape)) { + self.removeResizers(); + + self.addResizer(shape); + } + }); +} + +ResizeHandles.prototype.makeDraggable = function (element, gfx, direction) { + var resize = this._resize; + + function startResize(event) { + // only trigger on left mouse button + if ((0, _Mouse.isPrimaryButton)(event)) { + resize.activate(event, element, direction); + } + } + + _minDom.event.bind(gfx, 'mousedown', startResize); + _minDom.event.bind(gfx, 'touchstart', startResize); +}; + +ResizeHandles.prototype._createResizer = function (element, x, y, rotation, direction) { + var resizersParent = this._getResizersParent(); + + var group = (0, _tinySvg.create)('g'); + (0, _tinySvg.classes)(group).add(CLS_RESIZER); + (0, _tinySvg.classes)(group).add(CLS_RESIZER + '-' + element.id); + (0, _tinySvg.classes)(group).add(CLS_RESIZER + '-' + direction); + + (0, _tinySvg.append)(resizersParent, group); + + var origin = -HANDLE_SIZE + HANDLE_OFFSET; + + // Create four drag indicators on the outline + var visual = (0, _tinySvg.create)('rect'); + (0, _tinySvg.attr)(visual, { + x: origin, + y: origin, + width: HANDLE_SIZE, + height: HANDLE_SIZE + }); + (0, _tinySvg.classes)(visual).add(CLS_RESIZER + '-visual'); + + (0, _tinySvg.append)(group, visual); + + var hit = (0, _tinySvg.create)('rect'); + (0, _tinySvg.attr)(hit, { + x: origin, + y: origin, + width: HANDLE_HIT_SIZE, + height: HANDLE_HIT_SIZE + }); + (0, _tinySvg.classes)(hit).add(CLS_RESIZER + '-hit'); + + (0, _tinySvg.append)(group, hit); + + (0, _SvgTransformUtil.transform)(group, x, y, rotation); + + return group; +}; + +ResizeHandles.prototype.createResizer = function (element, direction) { + var resizer; + + var trbl = (0, _LayoutUtil.asTRBL)(element); + + if (direction === 'nw') { + resizer = this._createResizer(element, trbl.left, trbl.top, 0, direction); + } else if (direction === 'ne') { + resizer = this._createResizer(element, trbl.right, trbl.top, 90, direction); + } else if (direction === 'se') { + resizer = this._createResizer(element, trbl.right, trbl.bottom, 180, direction); + } else { + resizer = this._createResizer(element, trbl.left, trbl.bottom, 270, direction); + } + + this.makeDraggable(element, resizer, direction); +}; + +// resize handles implementation /////////////////////////////// + +/** + * Add resizers for a given element. + * + * @param {djs.model.Shape} shape + */ +ResizeHandles.prototype.addResizer = function (shape) { + var resize = this._resize; + + if (!resize.canResize({ shape: shape })) { + return; + } + + this.createResizer(shape, 'nw'); + this.createResizer(shape, 'ne'); + this.createResizer(shape, 'se'); + this.createResizer(shape, 'sw'); +}; + +/** + * Remove all resizers + */ +ResizeHandles.prototype.removeResizers = function () { + var resizersParent = this._getResizersParent(); + + (0, _tinySvg.clear)(resizersParent); +}; + +ResizeHandles.prototype._getResizersParent = function () { + return this._canvas.getLayer('resizers'); +}; + +ResizeHandles.$inject = ['eventBus', 'canvas', 'selection', 'resize']; + +},{"../../layout/LayoutUtil":380,"../../util/Mouse":403,"../../util/SvgTransformUtil":408,"min-dash":505,"min-dom":506,"tiny-svg":535}],350:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = ResizePreview; + +var _tinySvg = require('tiny-svg'); + +var MARKER_RESIZING = 'djs-resizing', + MARKER_RESIZE_NOT_OK = 'resize-not-ok'; + +var LOW_PRIORITY = 500; + +/** + * Provides previews for resizing shapes when resizing. + * + * @param {EventBus} eventBus + * @param {Canvas} canvas + * @param {PreviewSupport} previewSupport + */ +function ResizePreview(eventBus, canvas, previewSupport) { + + /** + * Update resizer frame. + * + * @param {Object} context + */ + function updateFrame(context) { + + var shape = context.shape, + bounds = context.newBounds, + frame = context.frame; + + if (!frame) { + frame = context.frame = previewSupport.addFrame(shape, canvas.getDefaultLayer()); + + canvas.addMarker(shape, MARKER_RESIZING); + } + + if (bounds.width > 5) { + (0, _tinySvg.attr)(frame, { x: bounds.x, width: bounds.width }); + } + + if (bounds.height > 5) { + (0, _tinySvg.attr)(frame, { y: bounds.y, height: bounds.height }); + } + + if (context.canExecute) { + (0, _tinySvg.classes)(frame).remove(MARKER_RESIZE_NOT_OK); + } else { + (0, _tinySvg.classes)(frame).add(MARKER_RESIZE_NOT_OK); + } + } + + /** + * Remove resizer frame. + * + * @param {Object} context + */ + function removeFrame(context) { + var shape = context.shape, + frame = context.frame; + + if (frame) { + (0, _tinySvg.remove)(context.frame); + } + + canvas.removeMarker(shape, MARKER_RESIZING); + } + + // add and update previews + eventBus.on('resize.move', LOW_PRIORITY, function (event) { + updateFrame(event.context); + }); + + // remove previews + eventBus.on('resize.cleanup', function (event) { + removeFrame(event.context); + }); +} + +ResizePreview.$inject = ['eventBus', 'canvas', 'previewSupport']; + +},{"tiny-svg":535}],351:[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.substractTRBL = substractTRBL; +exports.resizeBounds = resizeBounds; +exports.resizeTRBL = resizeTRBL; +exports.reattachPoint = reattachPoint; +exports.ensureConstraints = ensureConstraints; +exports.getMinResizeBounds = getMinResizeBounds; +exports.addPadding = addPadding; +exports.computeChildrenBBox = computeChildrenBBox; + +var _minDash = require('min-dash'); + +var _Elements = require('../../util/Elements'); + +var _LayoutUtil = require('../../layout/LayoutUtil'); + +var max = Math.max, + min = Math.min; + +var DEFAULT_CHILD_BOX_PADDING = 20; + +/** + * Substract a TRBL from another + * + * @param {TRBL} trblA + * @param {TRBL} trblB + * + * @return {TRBL} + */ +function substractTRBL(trblA, trblB) { + return { + top: trblA.top - trblB.top, + right: trblA.right - trblB.right, + bottom: trblA.bottom - trblB.bottom, + left: trblA.left - trblB.left + }; +} + +/** + * Resize the given bounds by the specified delta from a given anchor point. + * + * @param {Bounds} bounds the bounding box that should be resized + * @param {String} direction in which the element is resized (nw, ne, se, sw) + * @param {Point} delta of the resize operation + * + * @return {Bounds} resized bounding box + */ +function resizeBounds(bounds, direction, delta) { + + var dx = delta.x, + dy = delta.y; + + switch (direction) { + + case 'nw': + return { + x: bounds.x + dx, + y: bounds.y + dy, + width: bounds.width - dx, + height: bounds.height - dy + }; + + case 'sw': + return { + x: bounds.x + dx, + y: bounds.y, + width: bounds.width - dx, + height: bounds.height + dy + }; + + case 'ne': + return { + x: bounds.x, + y: bounds.y + dy, + width: bounds.width + dx, + height: bounds.height - dy + }; + + case 'se': + return { + x: bounds.x, + y: bounds.y, + width: bounds.width + dx, + height: bounds.height + dy + }; + + default: + throw new Error('unrecognized direction: ' + direction); + } +} + +/** + * Resize the given bounds by applying the passed + * { top, right, bottom, left } delta. + * + * @param {Bounds} bounds + * @param {TRBL} trblResize + * + * @return {Bounds} + */ +function resizeTRBL(bounds, resize) { + return { + x: bounds.x + (resize.left || 0), + y: bounds.y + (resize.top || 0), + width: bounds.width - (resize.left || 0) + (resize.right || 0), + height: bounds.height - (resize.top || 0) + (resize.bottom || 0) + }; +} + +function reattachPoint(bounds, newBounds, point) { + + var sx = bounds.width / newBounds.width, + sy = bounds.height / newBounds.height; + + return { + x: Math.round(newBounds.x + newBounds.width / 2) - Math.floor((bounds.x + bounds.width / 2 - point.x) / sx), + y: Math.round(newBounds.y + newBounds.height / 2) - Math.floor((bounds.y + bounds.height / 2 - point.y) / sy) + }; +} + +function applyConstraints(attr, trbl, resizeConstraints) { + + var value = trbl[attr], + minValue = resizeConstraints.min && resizeConstraints.min[attr], + maxValue = resizeConstraints.max && resizeConstraints.max[attr]; + + if ((0, _minDash.isNumber)(minValue)) { + value = (/top|left/.test(attr) ? min : max)(value, minValue); + } + + if ((0, _minDash.isNumber)(maxValue)) { + value = (/top|left/.test(attr) ? max : min)(value, maxValue); + } + + return value; +} + +function ensureConstraints(currentBounds, resizeConstraints) { + + if (!resizeConstraints) { + return currentBounds; + } + + var currentTrbl = (0, _LayoutUtil.asTRBL)(currentBounds); + + return (0, _LayoutUtil.asBounds)({ + top: applyConstraints('top', currentTrbl, resizeConstraints), + right: applyConstraints('right', currentTrbl, resizeConstraints), + bottom: applyConstraints('bottom', currentTrbl, resizeConstraints), + left: applyConstraints('left', currentTrbl, resizeConstraints) + }); +} + +function getMinResizeBounds(direction, currentBounds, minDimensions, childrenBounds) { + + var currentBox = (0, _LayoutUtil.asTRBL)(currentBounds); + + var minBox = { + top: /n/.test(direction) ? currentBox.bottom - minDimensions.height : currentBox.top, + left: /w/.test(direction) ? currentBox.right - minDimensions.width : currentBox.left, + bottom: /s/.test(direction) ? currentBox.top + minDimensions.height : currentBox.bottom, + right: /e/.test(direction) ? currentBox.left + minDimensions.width : currentBox.right + }; + + var childrenBox = childrenBounds ? (0, _LayoutUtil.asTRBL)(childrenBounds) : minBox; + + var combinedBox = { + top: min(minBox.top, childrenBox.top), + left: min(minBox.left, childrenBox.left), + bottom: max(minBox.bottom, childrenBox.bottom), + right: max(minBox.right, childrenBox.right) + }; + + return (0, _LayoutUtil.asBounds)(combinedBox); +} + +function asPadding(mayBePadding, defaultValue) { + if (typeof mayBePadding !== 'undefined') { + return mayBePadding; + } else { + return DEFAULT_CHILD_BOX_PADDING; + } +} + +function addPadding(bbox, padding) { + var left, right, top, bottom; + + if ((typeof padding === 'undefined' ? 'undefined' : _typeof(padding)) === 'object') { + left = asPadding(padding.left); + right = asPadding(padding.right); + top = asPadding(padding.top); + bottom = asPadding(padding.bottom); + } else { + left = right = top = bottom = asPadding(padding); + } + + return { + x: bbox.x - left, + y: bbox.y - top, + width: bbox.width + left + right, + height: bbox.height + top + bottom + }; +} + +/** + * Is the given element part of the resize + * targets min boundary box? + * + * This is the default implementation which excludes + * connections and labels. + * + * @param {djs.model.Base} element + */ +function isBBoxChild(element) { + + // exclude connections + if (element.waypoints) { + return false; + } + + // exclude labels + if (element.type === 'label') { + return false; + } + + return true; +} + +/** + * Return children bounding computed from a shapes children + * or a list of prefiltered children. + * + * @param {djs.model.Shape|Array} shapeOrChildren + * @param {Number|Object} padding + * + * @return {Bounds} + */ +function computeChildrenBBox(shapeOrChildren, padding) { + + var elements; + + // compute based on shape + if (shapeOrChildren.length === undefined) { + // grab all the children that are part of the + // parents children box + elements = (0, _minDash.filter)(shapeOrChildren.children, isBBoxChild); + } else { + elements = shapeOrChildren; + } + + if (elements.length) { + return addPadding((0, _Elements.getBBox)(elements), padding); + } +} + +},{"../../layout/LayoutUtil":380,"../../util/Elements":396,"min-dash":505}],352:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +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 _Resize = require('./Resize'); + +var _Resize2 = _interopRequireDefault(_Resize); + +var _ResizePreview = require('./ResizePreview'); + +var _ResizePreview2 = _interopRequireDefault(_ResizePreview); + +var _ResizeHandles = require('./ResizeHandles'); + +var _ResizeHandles2 = _interopRequireDefault(_ResizeHandles); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __depends__: [_rules2.default, _dragging2.default, _previewSupport2.default], + __init__: ['resize', 'resizePreview', 'resizeHandles'], + resize: ['type', _Resize2.default], + resizePreview: ['type', _ResizePreview2.default], + resizeHandles: ['type', _ResizeHandles2.default] +}; + +},{"../dragging":286,"../preview-support":345,"../rules":355,"./Resize":348,"./ResizeHandles":349,"./ResizePreview":350}],353:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = RuleProvider; + +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 }; } + +/** + * A basic provider that may be extended to implement modeling rules. + * + * Extensions should implement the init method to actually add their custom + * modeling checks. Checks may be added via the #addRule(action, fn) method. + * + * @param {EventBus} eventBus + */ +function RuleProvider(eventBus) { + _CommandInterceptor2.default.call(this, eventBus); + + this.init(); +} + +RuleProvider.$inject = ['eventBus']; + +(0, _inherits2.default)(RuleProvider, _CommandInterceptor2.default); + +/** + * Adds a modeling rule for the given action, implemented through + * a callback function. + * + * The function will receive the modeling specific action context + * to perform its check. It must return `false` to disallow the + * action from happening or `true` to allow the action. + * + * A rule provider may pass over the evaluation to lower priority + * rules by returning return nothing (or undefined). + * + * @example + * + * ResizableRules.prototype.init = function() { + * + * \/** + * * Return `true`, `false` or nothing to denote + * * _allowed_, _not allowed_ and _continue evaluating_. + * *\/ + * this.addRule('shape.resize', function(context) { + * + * var shape = context.shape; + * + * if (!context.newBounds) { + * // check general resizability + * if (!shape.resizable) { + * return false; + * } + * + * // not returning anything (read: undefined) + * // will continue the evaluation of other rules + * // (with lower priority) + * return; + * } else { + * // element must have minimum size of 10*10 points + * return context.newBounds.width > 10 && context.newBounds.height > 10; + * } + * }); + * }; + * + * @param {String|Array} actions the identifier for the modeling action to check + * @param {Number} [priority] the priority at which this rule is being applied + * @param {Function} fn the callback function that performs the actual check + */ +RuleProvider.prototype.addRule = function (actions, priority, fn) { + + var self = this; + + if (typeof actions === 'string') { + actions = [actions]; + } + + actions.forEach(function (action) { + + self.canExecute(action, priority, function (context, action, event) { + return fn(context); + }, true); + }); +}; + +/** + * Implement this method to add new rules during provider initialization. + */ +RuleProvider.prototype.init = function () {}; + +},{"../../command/CommandInterceptor":243,"inherits":415}],354:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = Rules; +/** + * A service that provides rules for certain diagram actions. + * + * The default implementation will hook into the {@link CommandStack} + * to perform the actual rule evaluation. Make sure to provide the + * `commandStack` service with this module if you plan to use it. + * + * Together with this implementation you may use the {@link RuleProvider} + * to implement your own rule checkers. + * + * This module is ment to be easily replaced, thus the tiny foot print. + * + * @param {Injector} injector + */ +function Rules(injector) { + this._commandStack = injector.get('commandStack', false); +} + +Rules.$inject = ['injector']; + +/** + * Returns whether or not a given modeling action can be executed + * in the specified context. + * + * This implementation will respond with allow unless anyone + * objects. + * + * @param {String} action the action to be checked + * @param {Object} [context] the context to check the action in + * + * @return {Boolean} returns true, false or null depending on whether the + * operation is allowed, not allowed or should be ignored. + */ +Rules.prototype.allowed = function (action, context) { + var allowed = true; + + var commandStack = this._commandStack; + + if (commandStack) { + allowed = commandStack.canExecute(action, context); + } + + // map undefined to true, i.e. no rules + return allowed === undefined ? true : allowed; +}; + +},{}],355:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _Rules = require('./Rules'); + +var _Rules2 = _interopRequireDefault(_Rules); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __init__: ['rules'], + rules: ['type', _Rules2.default] +}; + +},{"./Rules":354}],356:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = SearchPad; + +var _minDom = require('min-dom'); + +var _Elements = require('../../util/Elements'); + +/** + * Provides searching infrastructure + */ +function SearchPad(canvas, eventBus, overlays, selection) { + this._open = false; + this._results = []; + this._eventMaps = []; + + this._canvas = canvas; + this._eventBus = eventBus; + this._overlays = overlays; + this._selection = selection; + + // setup elements + this._container = (0, _minDom.domify)(SearchPad.BOX_HTML); + this._searchInput = (0, _minDom.query)(SearchPad.INPUT_SELECTOR, this._container); + this._resultsContainer = (0, _minDom.query)(SearchPad.RESULTS_CONTAINER_SELECTOR, this._container); + + // attach search pad + this._canvas.getContainer().appendChild(this._container); + + // cleanup on destroy + eventBus.on(['canvas.destroy', 'diagram.destroy'], this.close, this); +} + +SearchPad.$inject = ['canvas', 'eventBus', 'overlays', 'selection']; + +/** + * Binds and keeps track of all event listereners + */ +SearchPad.prototype._bindEvents = function () { + var self = this; + + function listen(el, selector, type, fn) { + self._eventMaps.push({ + el: el, + type: type, + listener: _minDom.delegate.bind(el, selector, type, fn) + }); + } + + // close search on clicking anywhere outside + listen(document, 'html', 'click', function (e) { + self.close(); + }, true); + + // stop event from propagating and closing search + // focus on input + listen(this._container, SearchPad.INPUT_SELECTOR, 'click', function (e) { + e.stopPropagation(); + e.delegateTarget.focus(); + }); + + // preselect result on hover + listen(this._container, SearchPad.RESULT_SELECTOR, 'mouseover', function (e) { + e.stopPropagation(); + self._scrollToNode(e.delegateTarget); + self._preselect(e.delegateTarget); + }); + + // selects desired result on mouse click + listen(this._container, SearchPad.RESULT_SELECTOR, 'click', function (e) { + e.stopPropagation(); + self._select(e.delegateTarget); + }); + + // prevent cursor in input from going left and right when using up/down to + // navigate results + listen(this._container, SearchPad.INPUT_SELECTOR, 'keydown', function (e) { + // up + if (e.keyCode === 38) { + e.preventDefault(); + } + + // down + if (e.keyCode === 40) { + e.preventDefault(); + } + }); + + // handle keyboard input + listen(this._container, SearchPad.INPUT_SELECTOR, 'keyup', function (e) { + // escape + if (e.keyCode === 27) { + return self.close(); + } + + // enter + if (e.keyCode === 13) { + var selected = self._getCurrentResult(); + + return selected ? self._select(selected) : self.close(); + } + + // up + if (e.keyCode === 38) { + return self._scrollToDirection(true); + } + + // down + if (e.keyCode === 40) { + return self._scrollToDirection(); + } + + // left && right + // do not search while navigating text input + if (e.keyCode === 37 || e.keyCode === 39) { + return; + } + + // anything else + self._search(e.delegateTarget.value); + }); +}; + +/** + * Unbinds all previously established listeners + */ +SearchPad.prototype._unbindEvents = function () { + this._eventMaps.forEach(function (m) { + _minDom.delegate.unbind(m.el, m.type, m.listener); + }); +}; + +/** + * Performs a search for the given pattern. + * + * @param {String} pattern + */ +SearchPad.prototype._search = function (pattern) { + var self = this; + + this._clearResults(); + + // do not search on empty query + if (!pattern || pattern === '') { + return; + } + + var searchResults = this._searchProvider.find(pattern); + + if (!searchResults.length) { + return; + } + + // append new results + searchResults.forEach(function (result) { + var id = result.element.id; + var node = self._createResultNode(result, id); + self._results[id] = { + element: result.element, + node: node + }; + }); + + // preselect first result + var node = (0, _minDom.query)(SearchPad.RESULT_SELECTOR, this._resultsContainer); + this._scrollToNode(node); + this._preselect(node); +}; + +/** + * Navigate to the previous/next result. Defaults to next result. + * @param {Boolean} previous + */ +SearchPad.prototype._scrollToDirection = function (previous) { + var selected = this._getCurrentResult(); + if (!selected) { + return; + } + + var node = previous ? selected.previousElementSibling : selected.nextElementSibling; + if (node) { + this._scrollToNode(node); + this._preselect(node); + } +}; + +/** + * Scroll to the node if it is not visible. + * + * @param {Element} node + */ +SearchPad.prototype._scrollToNode = function (node) { + if (!node || node === this._getCurrentResult()) { + return; + } + + var nodeOffset = node.offsetTop; + var containerScroll = this._resultsContainer.scrollTop; + + var bottomScroll = nodeOffset - this._resultsContainer.clientHeight + node.clientHeight; + + if (nodeOffset < containerScroll) { + this._resultsContainer.scrollTop = nodeOffset; + } else if (containerScroll < bottomScroll) { + this._resultsContainer.scrollTop = bottomScroll; + } +}; + +/** + * Clears all results data. + */ +SearchPad.prototype._clearResults = function () { + (0, _minDom.clear)(this._resultsContainer); + + this._results = []; + + this._resetOverlay(); + + this._eventBus.fire('searchPad.cleared'); +}; + +/** + * Get currently selected result. + * + * @return {Element} + */ +SearchPad.prototype._getCurrentResult = function () { + return (0, _minDom.query)(SearchPad.RESULT_SELECTED_SELECTOR, this._resultsContainer); +}; + +/** + * Create result DOM element within results container + * that corresponds to a search result. + * + * 'result' : one of the elements returned by SearchProvider + * 'id' : id attribute value to assign to the new DOM node + * return : created DOM element + * + * @param {SearchResult} result + * @param {String} id + * @return {Element} + */ +SearchPad.prototype._createResultNode = function (result, id) { + var node = (0, _minDom.domify)(SearchPad.RESULT_HTML); + + // create only if available + if (result.primaryTokens.length > 0) { + createInnerTextNode(node, result.primaryTokens, SearchPad.RESULT_PRIMARY_HTML); + } + + // secondary tokens (represent element ID) are allways available + createInnerTextNode(node, result.secondaryTokens, SearchPad.RESULT_SECONDARY_HTML); + + (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE, id); + + this._resultsContainer.appendChild(node); + + return node; +}; + +/** + * Register search element provider. + * + * SearchProvider.find - provides search function over own elements + * (pattern) => [{ text: , element: }, ...] + * + * @param {SearchProvider} provider + */ +SearchPad.prototype.registerProvider = function (provider) { + this._searchProvider = provider; +}; + +/** + * Open search pad. + */ +SearchPad.prototype.open = function () { + if (!this._searchProvider) { + throw new Error('no search provider registered'); + } + + if (this.isOpen()) { + return; + } + + this._bindEvents(); + + this._open = true; + + (0, _minDom.classes)(this._container).add('open'); + + this._searchInput.focus(); + + this._eventBus.fire('searchPad.opened'); +}; + +/** + * Close search pad. + */ +SearchPad.prototype.close = function () { + if (!this.isOpen()) { + return; + } + + this._unbindEvents(); + + this._open = false; + + (0, _minDom.classes)(this._container).remove('open'); + + this._clearResults(); + + this._searchInput.value = ''; + this._searchInput.blur(); + + this._resetOverlay(); + + this._eventBus.fire('searchPad.closed'); +}; + +/** + * Toggles search pad on/off. + */ +SearchPad.prototype.toggle = function () { + this.isOpen() ? this.close() : this.open(); +}; + +/** + * Report state of search pad. + */ +SearchPad.prototype.isOpen = function () { + return this._open; +}; + +/** + * Preselect result entry. + * + * @param {Element} element + */ +SearchPad.prototype._preselect = function (node) { + var selectedNode = this._getCurrentResult(); + + // already selected + if (node === selectedNode) { + return; + } + + // removing preselection from current node + if (selectedNode) { + (0, _minDom.classes)(selectedNode).remove(SearchPad.RESULT_SELECTED_CLASS); + } + + var id = (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE); + var element = this._results[id].element; + + (0, _minDom.classes)(node).add(SearchPad.RESULT_SELECTED_CLASS); + + this._resetOverlay(element); + + this._centerViewbox(element); + + this._selection.select(element); + + this._eventBus.fire('searchPad.preselected', element); +}; + +/** + * Select result node. + * + * @param {Element} element + */ +SearchPad.prototype._select = function (node) { + var id = (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE); + var element = this._results[id].element; + + this.close(); + + this._resetOverlay(); + + this._centerViewbox(element); + + this._selection.select(element); + + this._eventBus.fire('searchPad.selected', element); +}; + +/** + * Center viewbox on the element middle point. + * + * @param {Element} element + */ +SearchPad.prototype._centerViewbox = function (element) { + var viewbox = this._canvas.viewbox(); + + var box = (0, _Elements.getBBox)(element); + + var newViewbox = { + x: box.x + box.width / 2 - viewbox.outer.width / 2, + y: box.y + box.height / 2 - viewbox.outer.height / 2, + width: viewbox.outer.width, + height: viewbox.outer.height + }; + + this._canvas.viewbox(newViewbox); + + this._canvas.zoom(viewbox.scale); +}; + +/** + * Reset overlay removes and, optionally, set + * overlay to a new element. + * + * @param {Element} element + */ +SearchPad.prototype._resetOverlay = function (element) { + if (this._overlayId) { + this._overlays.remove(this._overlayId); + } + + if (element) { + var box = (0, _Elements.getBBox)(element); + var overlay = constructOverlay(box); + this._overlayId = this._overlays.add(element, overlay); + } +}; + +/** + * Construct overlay object for the given bounding box. + * + * @param {BoundingBox} box + * @return {Object} + */ +function constructOverlay(box) { + + var offset = 6; + var w = box.width + offset * 2; + var h = box.height + offset * 2; + + var styles = ['width: ' + w + 'px', 'height: ' + h + 'px'].join('; '); + + return { + position: { + bottom: h - offset, + right: w - offset + }, + show: true, + html: '
' + }; +} + +/** + * Creates and appends child node from result tokens and HTML template. + * + * @param {Element} node + * @param {Array} tokens + * @param {String} template + */ +function createInnerTextNode(parentNode, tokens, template) { + var text = createHtmlText(tokens); + var childNode = (0, _minDom.domify)(template); + childNode.innerHTML = text; + parentNode.appendChild(childNode); +} + +/** + * Create internal HTML markup from result tokens. + * Caters for highlighting pattern matched tokens. + * + * @param {Array} tokens + * @return {String} + */ +function createHtmlText(tokens) { + var htmlText = ''; + + tokens.forEach(function (t) { + if (t.matched) { + htmlText += '' + t.matched + ''; + } else { + htmlText += t.normal; + } + }); + + return htmlText !== '' ? htmlText : null; +} + +/** + * CONSTANTS + */ +SearchPad.CONTAINER_SELECTOR = '.djs-search-container'; +SearchPad.INPUT_SELECTOR = '.djs-search-input input'; +SearchPad.RESULTS_CONTAINER_SELECTOR = '.djs-search-results'; +SearchPad.RESULT_SELECTOR = '.djs-search-result'; +SearchPad.RESULT_SELECTED_CLASS = 'djs-search-result-selected'; +SearchPad.RESULT_SELECTED_SELECTOR = '.' + SearchPad.RESULT_SELECTED_CLASS; +SearchPad.RESULT_ID_ATTRIBUTE = 'data-result-id'; +SearchPad.RESULT_HIGHLIGHT_CLASS = 'djs-search-highlight'; +SearchPad.OVERLAY_CLASS = 'djs-search-overlay'; + +SearchPad.BOX_HTML = '
' + '
' + '' + '
' + '
' + '
'; + +SearchPad.RESULT_HTML = '
'; + +SearchPad.RESULT_PRIMARY_HTML = '
'; + +SearchPad.RESULT_SECONDARY_HTML = '

'; + +},{"../../util/Elements":396,"min-dom":506}],357:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _overlays = require('../overlays'); + +var _overlays2 = _interopRequireDefault(_overlays); + +var _selection = require('../selection'); + +var _selection2 = _interopRequireDefault(_selection); + +var _SearchPad = require('./SearchPad'); + +var _SearchPad2 = _interopRequireDefault(_SearchPad); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __depends__: [_overlays2.default, _selection2.default], + searchPad: ['type', _SearchPad2.default] +}; + +},{"../overlays":339,"../selection":361,"./SearchPad":356}],358:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = Selection; + +var _minDash = require('min-dash'); + +/** + * A service that offers the current selection in a diagram. + * Offers the api to control the selection, too. + * + * @class + * + * @param {EventBus} eventBus the event bus + */ +function Selection(eventBus) { + + this._eventBus = eventBus; + + this._selectedElements = []; + + var self = this; + + eventBus.on(['shape.remove', 'connection.remove'], function (e) { + var element = e.element; + self.deselect(element); + }); + + eventBus.on(['diagram.clear'], function (e) { + self.select(null); + }); +} + +Selection.$inject = ['eventBus']; + +Selection.prototype.deselect = function (element) { + var selectedElements = this._selectedElements; + + var idx = selectedElements.indexOf(element); + + if (idx !== -1) { + var oldSelection = selectedElements.slice(); + + selectedElements.splice(idx, 1); + + this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements }); + } +}; + +Selection.prototype.get = function () { + return this._selectedElements; +}; + +Selection.prototype.isSelected = function (element) { + return this._selectedElements.indexOf(element) !== -1; +}; + +/** + * This method selects one or more elements on the diagram. + * + * By passing an additional add parameter you can decide whether or not the element(s) + * should be added to the already existing selection or not. + * + * @method Selection#select + * + * @param {Object|Object[]} elements element or array of elements to be selected + * @param {boolean} [add] whether the element(s) should be appended to the current selection, defaults to false + */ +Selection.prototype.select = function (elements, add) { + var selectedElements = this._selectedElements, + oldSelection = selectedElements.slice(); + + if (!(0, _minDash.isArray)(elements)) { + elements = elements ? [elements] : []; + } + + // selection may be cleared by passing an empty array or null + // to the method + if (add) { + (0, _minDash.forEach)(elements, function (element) { + if (selectedElements.indexOf(element) !== -1) { + // already selected + return; + } else { + selectedElements.push(element); + } + }); + } else { + this._selectedElements = selectedElements = elements.slice(); + } + + this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements }); +}; + +},{"min-dash":505}],359:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = SelectionBehavior; + +var _Mouse = require('../../util/Mouse'); + +var _minDash = require('min-dash'); + +function SelectionBehavior(eventBus, selection, canvas, elementRegistry) { + + eventBus.on('create.end', 500, function (e) { + + // select the created shape after a + // successful create operation + if (e.context.canExecute) { + selection.select(e.context.shape); + } + }); + + eventBus.on('connect.end', 500, function (e) { + + // select the connect end target + // after a connect operation + if (e.context.canExecute && e.context.target) { + selection.select(e.context.target); + } + }); + + eventBus.on('shape.move.end', 500, function (e) { + var previousSelection = e.previousSelection || []; + + var shape = elementRegistry.get(e.context.shape.id); + + // make sure at least the main moved element is being + // selected after a move operation + var inSelection = (0, _minDash.find)(previousSelection, function (selectedShape) { + return shape.id === selectedShape.id; + }); + + if (!inSelection) { + selection.select(shape); + } + }); + + // Shift + click selection + eventBus.on('element.click', function (event) { + + var element = event.element; + + // do not select the root element + // or connections + if (element === canvas.getRootElement()) { + element = null; + } + + var isSelected = selection.isSelected(element), + isMultiSelect = selection.get().length > 1; + + // mouse-event: SELECTION_KEY + var add = (0, _Mouse.hasPrimaryModifier)(event); + + // select OR deselect element in multi selection + if (isSelected && isMultiSelect) { + if (add) { + return selection.deselect(element); + } else { + return selection.select(element); + } + } else if (!isSelected) { + selection.select(element, add); + } else { + selection.deselect(element); + } + }); +} + +SelectionBehavior.$inject = ['eventBus', 'selection', 'canvas', 'elementRegistry']; + +},{"../../util/Mouse":403,"min-dash":505}],360:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = SelectionVisuals; + +var _minDash = require('min-dash'); + +var MARKER_HOVER = 'hover', + MARKER_SELECTED = 'selected'; + +/** + * A plugin that adds a visible selection UI to shapes and connections + * by appending the hover and selected classes to them. + * + * @class + * + * Makes elements selectable, too. + * + * @param {EventBus} events + * @param {SelectionService} selection + * @param {Canvas} canvas + */ +function SelectionVisuals(events, canvas, selection, styles) { + + this._multiSelectionBox = null; + + function addMarker(e, cls) { + canvas.addMarker(e, cls); + } + + function removeMarker(e, cls) { + canvas.removeMarker(e, cls); + } + + events.on('element.hover', function (event) { + addMarker(event.element, MARKER_HOVER); + }); + + events.on('element.out', function (event) { + removeMarker(event.element, MARKER_HOVER); + }); + + events.on('selection.changed', function (event) { + + function deselect(s) { + removeMarker(s, MARKER_SELECTED); + } + + function select(s) { + addMarker(s, MARKER_SELECTED); + } + + var oldSelection = event.oldSelection, + newSelection = event.newSelection; + + (0, _minDash.forEach)(oldSelection, function (e) { + if (newSelection.indexOf(e) === -1) { + deselect(e); + } + }); + + (0, _minDash.forEach)(newSelection, function (e) { + if (oldSelection.indexOf(e) === -1) { + select(e); + } + }); + }); +} + +SelectionVisuals.$inject = ['eventBus', 'canvas', 'selection', 'styles']; + +},{"min-dash":505}],361:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _interactionEvents = require('../interaction-events'); + +var _interactionEvents2 = _interopRequireDefault(_interactionEvents); + +var _outline = require('../outline'); + +var _outline2 = _interopRequireDefault(_outline); + +var _Selection = require('./Selection'); + +var _Selection2 = _interopRequireDefault(_Selection); + +var _SelectionVisuals = require('./SelectionVisuals'); + +var _SelectionVisuals2 = _interopRequireDefault(_SelectionVisuals); + +var _SelectionBehavior = require('./SelectionBehavior'); + +var _SelectionBehavior2 = _interopRequireDefault(_SelectionBehavior); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __init__: ['selectionVisuals', 'selectionBehavior'], + __depends__: [_interactionEvents2.default, _outline2.default], + selection: ['type', _Selection2.default], + selectionVisuals: ['type', _SelectionVisuals2.default], + selectionBehavior: ['type', _SelectionBehavior2.default] +}; + +},{"../interaction-events":294,"../outline":337,"./Selection":358,"./SelectionBehavior":359,"./SelectionVisuals":360}],362:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = SnapContext; + +var _minDash = require('min-dash'); + +var _SnapUtil = require('./SnapUtil'); + +/** + * A snap context, containing the (possibly incomplete) + * mappings of drop targets (to identify the snapping) + * to computed snap points. + */ +function SnapContext() { + + /** + * Map mapping drop targets to + * a list of possible snappings. + * + * @type {Object} + */ + this._targets = {}; + + /** + * Map initial positioning of element + * regarding various snap directions. + * + * @type {Object} + */ + this._snapOrigins = {}; + + /** + * List of snap locations + * + * @type {Array} + */ + this._snapLocations = []; + + /** + * Map> of default snapping locations + * + * @type {Object} + */ + this._defaultSnaps = {}; +} + +SnapContext.prototype.getSnapOrigin = function (snapLocation) { + return this._snapOrigins[snapLocation]; +}; + +SnapContext.prototype.setSnapOrigin = function (snapLocation, initialValue) { + this._snapOrigins[snapLocation] = initialValue; + + if (this._snapLocations.indexOf(snapLocation) === -1) { + this._snapLocations.push(snapLocation); + } +}; + +SnapContext.prototype.addDefaultSnap = function (type, point) { + + var snapValues = this._defaultSnaps[type]; + + if (!snapValues) { + snapValues = this._defaultSnaps[type] = []; + } + + snapValues.push(point); +}; + +/** + * Return a number of initialized snaps, i.e. snap locations such as + * top-left, mid, bottom-right and so forth. + * + * @return {Array} snapLocations + */ +SnapContext.prototype.getSnapLocations = function () { + return this._snapLocations; +}; + +/** + * Set the snap locations for this context. + * + * The order of locations determines precedence. + * + * @param {Array} snapLocations + */ +SnapContext.prototype.setSnapLocations = function (snapLocations) { + this._snapLocations = snapLocations; +}; + +/** + * Get snap points for a given target + * + * @param {Element|String} target + */ +SnapContext.prototype.pointsForTarget = function (target) { + + var targetId = target.id || target; + + var snapPoints = this._targets[targetId]; + + if (!snapPoints) { + snapPoints = this._targets[targetId] = new SnapPoints(); + snapPoints.initDefaults(this._defaultSnaps); + } + + return snapPoints; +}; + +/** + * Creates the snap points and initializes them with the + * given default values. + * + * @param {Object>} [defaultPoints] + */ +function SnapPoints(defaultSnaps) { + + /** + * Map>> mapping snap locations, + * i.e. top-left, bottom-right, center to actual snap values. + * + * @type {Object} + */ + this._snapValues = {}; +} + +SnapPoints.prototype.add = function (snapLocation, point) { + + var snapValues = this._snapValues[snapLocation]; + + if (!snapValues) { + snapValues = this._snapValues[snapLocation] = { x: [], y: [] }; + } + + if (snapValues.x.indexOf(point.x) === -1) { + snapValues.x.push(point.x); + } + + if (snapValues.y.indexOf(point.y) === -1) { + snapValues.y.push(point.y); + } +}; + +SnapPoints.prototype.snap = function (point, snapLocation, axis, tolerance) { + var snappingValues = this._snapValues[snapLocation]; + + return snappingValues && (0, _SnapUtil.snapTo)(point[axis], snappingValues[axis], tolerance); +}; + +/** + * Initialize a number of default snapping points. + * + * @param {Object} defaultSnaps + */ +SnapPoints.prototype.initDefaults = function (defaultSnaps) { + + var self = this; + + (0, _minDash.forEach)(defaultSnaps || {}, function (snapPoints, snapLocation) { + (0, _minDash.forEach)(snapPoints, function (point) { + self.add(snapLocation, point); + }); + }); +}; + +},{"./SnapUtil":363,"min-dash":505}],363:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.snapTo = snapTo; +exports.topLeft = topLeft; +exports.mid = mid; +exports.bottomRight = bottomRight; +exports.isSnapped = isSnapped; +exports.setSnapped = setSnapped; +var abs = Math.abs, + round = Math.round; + +/** + * Snap value to a collection of reference values. + * + * @param {Number} value + * @param {Array} values + * @param {Number} [tolerance=10] + * + * @return {Number} the value we snapped to or null, if none snapped + */ +function snapTo(value, values, tolerance) { + tolerance = tolerance === undefined ? 10 : tolerance; + + var idx, snapValue; + + for (idx = 0; idx < values.length; idx++) { + snapValue = values[idx]; + + if (abs(snapValue - value) <= tolerance) { + return snapValue; + } + } +} + +function topLeft(bounds) { + return { + x: bounds.x, + y: bounds.y + }; +} + +function mid(bounds, defaultValue) { + + if (!bounds || isNaN(bounds.x) || isNaN(bounds.y)) { + return defaultValue; + } + + return { + x: round(bounds.x + bounds.width / 2), + y: round(bounds.y + bounds.height / 2) + }; +} + +function bottomRight(bounds) { + return { + x: bounds.x + bounds.width, + y: bounds.y + bounds.height + }; +} + +/** + * Retrieve the snap state of the given event. + * + * @param {Event} event + * @param {String} axis + * + * @return {Boolean} the snapped state + * + */ +function isSnapped(event, axis) { + var snapped = event.snapped; + + if (!snapped) { + return false; + } + + if (typeof axis === 'string') { + return snapped[axis]; + } + + return snapped.x && snapped.y; +} + +/** + * Set the given event as snapped. + * + * This method may change the x and/or y position of the shape + * from the given event! + * + * @param {Event} event + * @param {String} axis + * @param {Number|Boolean} value + * + * @return {Number} old value + */ +function setSnapped(event, axis, value) { + if (typeof axis !== 'string') { + throw new Error('axis must be in [x, y]'); + } + + if (typeof value !== 'number' && value !== false) { + throw new Error('value must be Number or false'); + } + + var delta, + previousValue = event[axis]; + + var snapped = event.snapped = event.snapped || {}; + + if (value === false) { + snapped[axis] = false; + } else { + snapped[axis] = true; + + delta = value - previousValue; + + event[axis] += delta; + event['d' + axis] += delta; + } + + return previousValue; +} + +},{}],364:[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 = Snapping; + +var _minDash = require('min-dash'); + +var _SnapContext = require('./SnapContext'); + +var _SnapContext2 = _interopRequireDefault(_SnapContext); + +var _SnapUtil = require('./SnapUtil'); + +var _tinySvg = require('tiny-svg'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var HIGHER_PRIORITY = 1250; + +/** + * A general purpose snapping component for diagram elements. + * + * @param {EventBus} eventBus + * @param {Canvas} canvas + */ +function Snapping(eventBus, canvas) { + + this._canvas = canvas; + + var self = this; + + eventBus.on(['shape.move.start', 'create.start'], function (event) { + self.initSnap(event); + }); + + eventBus.on(['shape.move.move', 'shape.move.end', 'create.move', 'create.end'], HIGHER_PRIORITY, function (event) { + + if (event.originalEvent && event.originalEvent.ctrlKey) { + return; + } + + if ((0, _SnapUtil.isSnapped)(event)) { + return; + } + + self.snap(event); + }); + + eventBus.on(['shape.move.cleanup', 'create.cleanup'], function (event) { + self.hide(); + }); + + // delay hide by 1000 seconds since last match + this._asyncHide = (0, _minDash.debounce)((0, _minDash.bind)(this.hide, this), 1000); +} + +Snapping.$inject = ['eventBus', 'canvas']; + +Snapping.prototype.initSnap = function (event) { + + var context = event.context, + shape = context.shape, + snapContext = context.snapContext; + + if (!snapContext) { + snapContext = context.snapContext = new _SnapContext2.default(); + } + + var snapMid = (0, _SnapUtil.mid)(shape, event); + + snapContext.setSnapOrigin('mid', { + x: snapMid.x - event.x, + y: snapMid.y - event.y + }); + + return snapContext; +}; + +Snapping.prototype.snap = function (event) { + + var context = event.context, + snapContext = context.snapContext, + shape = context.shape, + target = context.target, + snapLocations = snapContext.getSnapLocations(); + + if (!target) { + return; + } + + var snapPoints = snapContext.pointsForTarget(target); + + if (!snapPoints.initialized) { + this.addTargetSnaps(snapPoints, shape, target); + + snapPoints.initialized = true; + } + + var snapping = { + x: (0, _SnapUtil.isSnapped)(event, 'x'), + y: (0, _SnapUtil.isSnapped)(event, 'y') + }; + + (0, _minDash.forEach)(snapLocations, function (location) { + + var snapOrigin = snapContext.getSnapOrigin(location); + + var snapCurrent = { + x: event.x + snapOrigin.x, + y: event.y + snapOrigin.y + }; + + // snap on both axis, if not snapped already + (0, _minDash.forEach)(['x', 'y'], function (axis) { + var locationSnapping; + + if (!snapping[axis]) { + locationSnapping = snapPoints.snap(snapCurrent, location, axis, 7); + + if (locationSnapping !== undefined) { + snapping[axis] = { + value: locationSnapping, + originValue: locationSnapping - snapOrigin[axis] + }; + } + } + }); + + // no more need to snap, drop out of interation + if (snapping.x && snapping.y) { + return false; + } + }); + + // show snap visuals + + this.showSnapLine('vertical', snapping.x && snapping.x.value); + this.showSnapLine('horizontal', snapping.y && snapping.y.value); + + // adjust event { x, y, dx, dy } and mark as snapping + (0, _minDash.forEach)(['x', 'y'], function (axis) { + + var axisSnapping = snapping[axis]; + + if ((typeof axisSnapping === 'undefined' ? 'undefined' : _typeof(axisSnapping)) === 'object') { + // set as snapped and adjust the x and/or y position of the event + (0, _SnapUtil.setSnapped)(event, axis, axisSnapping.originValue); + } + }); +}; + +Snapping.prototype._createLine = function (orientation) { + + var root = this._canvas.getLayer('snap'); + + // var line = root.path('M0,0 L0,0').addClass('djs-snap-line'); + + var line = (0, _tinySvg.create)('path'); + (0, _tinySvg.attr)(line, { d: 'M0,0 L0,0' }); + (0, _tinySvg.classes)(line).add('djs-snap-line'); + + (0, _tinySvg.append)(root, line); + + return { + update: function update(position) { + + if (typeof position !== 'number') { + (0, _tinySvg.attr)(line, { display: 'none' }); + } else { + if (orientation === 'horizontal') { + (0, _tinySvg.attr)(line, { + d: 'M-100000,' + position + ' L+100000,' + position, + display: '' + }); + } else { + (0, _tinySvg.attr)(line, { + d: 'M ' + position + ',-100000 L ' + position + ', +100000', + display: '' + }); + } + } + } + }; +}; + +Snapping.prototype._createSnapLines = function () { + + this._snapLines = { + horizontal: this._createLine('horizontal'), + vertical: this._createLine('vertical') + }; +}; + +Snapping.prototype.showSnapLine = function (orientation, position) { + + var line = this.getSnapLine(orientation); + + if (line) { + line.update(position); + } + + this._asyncHide(); +}; + +Snapping.prototype.getSnapLine = function (orientation) { + if (!this._snapLines) { + this._createSnapLines(); + } + + return this._snapLines[orientation]; +}; + +Snapping.prototype.hide = function () { + (0, _minDash.forEach)(this._snapLines, function (l) { + l.update(); + }); +}; + +Snapping.prototype.addTargetSnaps = function (snapPoints, shape, target) { + + var siblings = this.getSiblings(shape, target); + + (0, _minDash.forEach)(siblings, function (s) { + snapPoints.add('mid', (0, _SnapUtil.mid)(s)); + }); +}; + +Snapping.prototype.getSiblings = function (element, target) { + + // snap to all siblings that are not hidden, labels, attached to element or element itself + return target && (0, _minDash.filter)(target.children, function (e) { + return !e.hidden && !e.labelTarget && e.host !== element && e !== element; + }); +}; + +},{"./SnapContext":362,"./SnapUtil":363,"min-dash":505,"tiny-svg":535}],365:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = SpaceTool; + +var _SpaceUtil = require('./SpaceUtil'); + +var _Cursor = require('../../util/Cursor'); + +var _Mouse = require('../../util/Mouse'); + +var _Elements = require('../../util/Elements'); + +var _minDash = require('min-dash'); + +var abs = Math.abs, + round = Math.round; + +var HIGH_PRIORITY = 1500, + SPACE_TOOL_CURSOR = 'crosshair'; + +var AXIS_TO_DIMENSION = { x: 'width', y: 'height' }, + AXIS_INVERTED = { x: 'y', y: 'x' }; + +/** + * A tool that allows users to create and remove space in a diagram. + * + * The tool needs to be activated manually via {@link SpaceTool#activate(MouseEvent)}. + */ +function SpaceTool(eventBus, dragging, canvas, modeling, rules, toolManager) { + + this._canvas = canvas; + this._dragging = dragging; + this._modeling = modeling; + this._rules = rules; + this._toolManager = toolManager; + + var self = this; + + toolManager.registerTool('space', { + tool: 'spaceTool.selection', + dragging: 'spaceTool' + }); + + eventBus.on('spaceTool.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('spaceTool.selection.ended', function () { + self.activateMakeSpace(event.originalEvent); + }); + }); + + eventBus.on('spaceTool.move', HIGH_PRIORITY, function (event) { + + var context = event.context; + + if (!context.initialized) { + context.initialized = self.initializeMakeSpace(event, context); + } + }); + + eventBus.on('spaceTool.end', function (event) { + + var context = event.context, + axis = context.axis, + direction = context.direction, + movingShapes = context.movingShapes, + resizingShapes = context.resizingShapes; + + // skip if create space has not been initialized yet + if (!context.initialized) { + return; + } + + var delta = { x: round(event.dx), y: round(event.dy) }; + delta[AXIS_INVERTED[axis]] = 0; + + var insideBounds = true; + + // check if the space tool cursor is inside of bounds of + // any of the shapes that would be resized. + (0, _minDash.forEach)(resizingShapes, function (shape) { + + if (direction === 'w' && event.x > shape.x + shape.width || direction === 'e' && event.x < shape.x || direction === 'n' && event.y > shape.y + shape.height || direction === 's' && event.y < shape.y) { + + insideBounds = false; + return; + } + }); + + if (insideBounds) { + // make space only if the cursor is inside bounds + self.makeSpace(movingShapes, resizingShapes, delta, direction); + } + + eventBus.once('spaceTool.ended', function (event) { + // reactivate space tool after usage + self.activateSelection(event.originalEvent, true, true); + }); + }); +} + +SpaceTool.$inject = ['eventBus', 'dragging', 'canvas', 'modeling', 'rules', 'toolManager']; + +/** + * Activate space tool selection + * + * @param {MouseEvent} event + * @param {Boolean} autoActivate + */ +SpaceTool.prototype.activateSelection = function (event, autoActivate, reactivate) { + this._dragging.init(event, 'spaceTool.selection', { + trapClick: false, + cursor: SPACE_TOOL_CURSOR, + autoActivate: autoActivate, + data: { + context: { + reactivate: reactivate + } + } + }); +}; + +/** + * Activate make space + * + * @param {MouseEvent} event + */ +SpaceTool.prototype.activateMakeSpace = function (event) { + this._dragging.init(event, 'spaceTool', { + autoActivate: true, + cursor: SPACE_TOOL_CURSOR, + data: { + context: {} + } + }); +}; + +/** + * Actually make space on the diagram + * + * @param {Array} movingShapes + * @param {Array} resizingShapes + * @param {Point} delta + * @param {String} direction + */ +SpaceTool.prototype.makeSpace = function (movingShapes, resizingShapes, delta, direction) { + return this._modeling.createSpace(movingShapes, resizingShapes, delta, direction); +}; + +/** + * Initialize make space and return true if that was successful. + * + * @param {Event} event + * @param {Object} context + * + * @return {Boolean} true, if successful + */ +SpaceTool.prototype.initializeMakeSpace = function (event, context) { + + var axis = abs(event.dx) > abs(event.dy) ? 'x' : 'y', + offset = event['d' + axis], + + // start point of create space operation + spacePos = event[axis] - offset; + + if (abs(offset) < 5) { + return false; + } + + // invert the offset in order to remove space when moving left + if (offset < 0) { + offset *= -1; + } + + // inverts the offset to choose the shapes + // on the opposite side of the resizer if + // a key modifier is pressed + if ((0, _Mouse.hasPrimaryModifier)(event)) { + offset *= -1; + } + + var rootShape = this._canvas.getRootElement(); + + var allShapes = (0, _Elements.selfAndAllChildren)(rootShape, true); + + var adjustments = this.calculateAdjustments(allShapes, axis, offset, spacePos); + + // store data in context + (0, _minDash.assign)(context, adjustments, { + axis: axis, + direction: (0, _SpaceUtil.getDirection)(axis, offset) + }); + + (0, _Cursor.set)('resize-' + (axis === 'x' ? 'ew' : 'ns')); + + return true; +}; + +/** + * Calculate adjustments needed when making space + * + * @param {Array} elements + * @param {String} axis + * @param {Number} offset + * @param {Number} spacePos + * + * @return {Object} + */ +SpaceTool.prototype.calculateAdjustments = function (elements, axis, offset, spacePos) { + + var movingShapes = [], + resizingShapes = []; + + var rules = this._rules; + + // collect all elements that need to be moved _AND_ + // resized given on the initial create space position + elements.forEach(function (shape) { + + var shapeStart = shape[axis], + shapeEnd = shapeStart + shape[AXIS_TO_DIMENSION[axis]]; + + // checking if it's root + if (!shape.parent) { + return; + } + + // checking if it's a shape + if (shape.waypoints) { + return; + } + + // shape after spacePos + if (offset > 0 && shapeStart > spacePos) { + return movingShapes.push(shape); + } + + // shape before spacePos + if (offset < 0 && shapeEnd < spacePos) { + return movingShapes.push(shape); + } + + // shape on top of spacePos, resize only if allowed + if (shapeStart < spacePos && shapeEnd > spacePos && rules.allowed('shape.resize', { shape: shape })) { + + return resizingShapes.push(shape); + } + }); + + return { + movingShapes: movingShapes, + resizingShapes: resizingShapes + }; +}; + +SpaceTool.prototype.toggle = function () { + if (this.isActive()) { + this._dragging.cancel(); + } else { + this.activateSelection(); + } +}; + +SpaceTool.prototype.isActive = function () { + var context = this._dragging.context(); + + return context && /^spaceTool/.test(context.prefix); +}; + +},{"../../util/Cursor":395,"../../util/Elements":396,"../../util/Mouse":403,"./SpaceUtil":367,"min-dash":505}],366:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = SpaceToolPreview; + +var _minDash = require('min-dash'); + +var _tinySvg = require('tiny-svg'); + +var _SvgTransformUtil = require('../../util/SvgTransformUtil'); + +var MARKER_DRAGGING = 'djs-dragging', + MARKER_RESIZING = 'djs-resizing'; + +var LOW_PRIORITY = 250; + +/** + * Provides previews for selecting/moving/resizing shapes when creating/removing space. + * + * @param {EventBus} eventBus + * @param {ElementRegistry} elementRegistry + * @param {Canvas} canvas + * @param {Styles} styles + */ +function SpaceToolPreview(eventBus, elementRegistry, canvas, styles, previewSupport) { + + function addPreviewGfx(collection, dragGroup) { + (0, _minDash.forEach)(collection, function (element) { + previewSupport.addDragger(element, dragGroup); + + canvas.addMarker(element, MARKER_DRAGGING); + }); + } + + // add crosshair + eventBus.on('spaceTool.selection.start', function (event) { + var space = canvas.getLayer('space'), + context = event.context; + + var orientation = { + x: 'M 0,-10000 L 0,10000', + y: 'M -10000,0 L 10000,0' + }; + + var crosshairGroup = (0, _tinySvg.create)('g'); + (0, _tinySvg.attr)(crosshairGroup, styles.cls('djs-crosshair-group', ['no-events'])); + + (0, _tinySvg.append)(space, crosshairGroup); + + // horizontal path + var pathX = (0, _tinySvg.create)('path'); + (0, _tinySvg.attr)(pathX, 'd', orientation.x); + (0, _tinySvg.classes)(pathX).add('djs-crosshair'); + + (0, _tinySvg.append)(crosshairGroup, pathX); + + // vertical path + var pathY = (0, _tinySvg.create)('path'); + (0, _tinySvg.attr)(pathY, 'd', orientation.y); + (0, _tinySvg.classes)(pathY).add('djs-crosshair'); + + (0, _tinySvg.append)(crosshairGroup, pathY); + + context.crosshairGroup = crosshairGroup; + }); + + // update crosshair + eventBus.on('spaceTool.selection.move', function (event) { + var crosshairGroup = event.context.crosshairGroup; + + (0, _SvgTransformUtil.translate)(crosshairGroup, event.x, event.y); + }); + + // remove crosshair + eventBus.on('spaceTool.selection.cleanup', function (event) { + var context = event.context, + crosshairGroup = context.crosshairGroup; + + if (crosshairGroup) { + (0, _tinySvg.remove)(crosshairGroup); + } + }); + + // add and update move/resize previews + eventBus.on('spaceTool.move', LOW_PRIORITY, function (event) { + + var context = event.context, + line = context.line, + axis = context.axis, + movingShapes = context.movingShapes, + resizingShapes = context.resizingShapes; + + if (!context.initialized) { + return; + } + + if (!context.dragGroup) { + var spaceLayer = canvas.getLayer('space'); + + line = (0, _tinySvg.create)('path'); + (0, _tinySvg.attr)(line, 'd', 'M0,0 L0,0'); + (0, _tinySvg.classes)(line).add('djs-crosshair'); + + (0, _tinySvg.append)(spaceLayer, line); + + context.line = line; + + var dragGroup = (0, _tinySvg.create)('g'); + (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events'])); + + (0, _tinySvg.append)(canvas.getDefaultLayer(), dragGroup); + + // shapes + addPreviewGfx(movingShapes, dragGroup); + + // connections + var movingConnections = context.movingConnections = elementRegistry.filter(function (element) { + var sourceIsMoving = false; + + (0, _minDash.forEach)(movingShapes, function (shape) { + (0, _minDash.forEach)(shape.outgoing, function (connection) { + if (element === connection) { + sourceIsMoving = true; + } + }); + }); + + var targetIsMoving = false; + + (0, _minDash.forEach)(movingShapes, function (shape) { + (0, _minDash.forEach)(shape.incoming, function (connection) { + if (element === connection) { + targetIsMoving = true; + } + }); + }); + + var sourceIsResizing = false; + + (0, _minDash.forEach)(resizingShapes, function (shape) { + (0, _minDash.forEach)(shape.outgoing, function (connection) { + if (element === connection) { + sourceIsResizing = true; + } + }); + }); + + var targetIsResizing = false; + + (0, _minDash.forEach)(resizingShapes, function (shape) { + (0, _minDash.forEach)(shape.incoming, function (connection) { + if (element === connection) { + targetIsResizing = true; + } + }); + }); + + return isConnection(element) && (sourceIsMoving || sourceIsResizing) && (targetIsMoving || targetIsResizing); + }); + + addPreviewGfx(movingConnections, dragGroup); + + context.dragGroup = dragGroup; + } + + if (!context.frameGroup) { + var frameGroup = (0, _tinySvg.create)('g'); + (0, _tinySvg.attr)(frameGroup, styles.cls('djs-frame-group', ['no-events'])); + + (0, _tinySvg.append)(canvas.getDefaultLayer(), frameGroup); + + var frames = []; + + (0, _minDash.forEach)(resizingShapes, function (shape) { + var frame = previewSupport.addFrame(shape, frameGroup); + + frames.push({ + element: frame, + initialWidth: frame.getBBox().width, + initialHeight: frame.getBBox().height + }); + + canvas.addMarker(shape, MARKER_RESIZING); + }); + + context.frameGroup = frameGroup; + context.frames = frames; + } + + var orientation = { + x: 'M' + event.x + ', -10000 L' + event.x + ', 10000', + y: 'M -10000, ' + event.y + ' L 10000, ' + event.y + }; + + (0, _tinySvg.attr)(line, { path: orientation[axis], display: '' }); + + var opposite = { x: 'y', y: 'x' }; + var delta = { x: event.dx, y: event.dy }; + delta[opposite[context.axis]] = 0; + + // update move previews + (0, _SvgTransformUtil.translate)(context.dragGroup, delta.x, delta.y); + + // update resize previews + (0, _minDash.forEach)(context.frames, function (frame) { + if (frame.initialWidth + delta.x > 5) { + (0, _tinySvg.attr)(frame.element, { width: frame.initialWidth + delta.x }); + } + + if (frame.initialHeight + delta.y > 5) { + (0, _tinySvg.attr)(frame.element, { height: frame.initialHeight + delta.y }); + } + }); + }); + + // remove move/resize previews + eventBus.on('spaceTool.cleanup', function (event) { + + var context = event.context, + movingShapes = context.movingShapes, + movingConnections = context.movingConnections, + resizingShapes = context.resizingShapes, + line = context.line, + dragGroup = context.dragGroup, + frameGroup = context.frameGroup; + + // moving shapes + (0, _minDash.forEach)(movingShapes, function (shape) { + canvas.removeMarker(shape, MARKER_DRAGGING); + }); + + // moving connections + (0, _minDash.forEach)(movingConnections, function (connection) { + canvas.removeMarker(connection, MARKER_DRAGGING); + }); + + if (dragGroup) { + (0, _tinySvg.remove)(line); + (0, _tinySvg.remove)(dragGroup); + } + + (0, _minDash.forEach)(resizingShapes, function (shape) { + canvas.removeMarker(shape, MARKER_RESIZING); + }); + + if (frameGroup) { + (0, _tinySvg.remove)(frameGroup); + } + }); +} + +SpaceToolPreview.$inject = ['eventBus', 'elementRegistry', 'canvas', 'styles', 'previewSupport']; + +// helpers ////////////////////// + +/** + * Checks if an element is a connection. + */ +function isConnection(element) { + return element.waypoints; +} + +},{"../../util/SvgTransformUtil":408,"min-dash":505,"tiny-svg":535}],367:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDirection = getDirection; +exports.resizeBounds = resizeBounds; +/** + * Get Resize direction given axis + offset + * + * @param {String} axis (x|y) + * @param {Number} offset + * + * @return {String} (e|w|n|s) + */ +function getDirection(axis, offset) { + + if (axis === 'x') { + if (offset > 0) { + return 'e'; + } + + if (offset < 0) { + return 'w'; + } + } + + if (axis === 'y') { + if (offset > 0) { + return 's'; + } + + if (offset < 0) { + return 'n'; + } + } + + return null; +} + +/** + * Resize the given bounds by the specified delta from a given anchor point. + * + * @param {Bounds} bounds the bounding box that should be resized + * @param {String} direction in which the element is resized (n, s, e, w) + * @param {Point} delta of the resize operation + * + * @return {Bounds} resized bounding box + */ +function resizeBounds(bounds, direction, delta) { + + var dx = delta.x, + dy = delta.y; + + switch (direction) { + + case 'n': + return { + x: bounds.x, + y: bounds.y + dy, + width: bounds.width, + height: bounds.height - dy + }; + + case 's': + return { + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: bounds.height + dy + }; + + case 'w': + return { + x: bounds.x + dx, + y: bounds.y, + width: bounds.width - dx, + height: bounds.height + }; + + case 'e': + return { + x: bounds.x, + y: bounds.y, + width: bounds.width + dx, + height: bounds.height + }; + + default: + throw new Error('unrecognized direction: ' + direction); + } +} + +},{}],368:[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 _toolManager = require('../tool-manager'); + +var _toolManager2 = _interopRequireDefault(_toolManager); + +var _previewSupport = require('../preview-support'); + +var _previewSupport2 = _interopRequireDefault(_previewSupport); + +var _SpaceTool = require('./SpaceTool'); + +var _SpaceTool2 = _interopRequireDefault(_SpaceTool); + +var _SpaceToolPreview = require('./SpaceToolPreview'); + +var _SpaceToolPreview2 = _interopRequireDefault(_SpaceToolPreview); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __init__: ['spaceToolPreview'], + __depends__: [_dragging2.default, _rules2.default, _toolManager2.default, _previewSupport2.default], + spaceTool: ['type', _SpaceTool2.default], + spaceToolPreview: ['type', _SpaceToolPreview2.default] +}; + +},{"../dragging":286,"../preview-support":345,"../rules":355,"../tool-manager":370,"./SpaceTool":365,"./SpaceToolPreview":366}],369:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = ToolManager; + +var _minDash = require('min-dash'); + +var _minDom = require('min-dom'); + +var LOW_PRIORITY = 250; + +/** + * The tool manager acts as middle-man between the available tool's and the Palette, + * it takes care of making sure that the correct active state is set. + * + * @param {Object} eventBus + * @param {Object} dragging + */ +function ToolManager(eventBus, dragging) { + this._eventBus = eventBus; + this._dragging = dragging; + + this._tools = []; + this._active = null; +} + +ToolManager.$inject = ['eventBus', 'dragging']; + +ToolManager.prototype.registerTool = function (name, events) { + var tools = this._tools; + + if (!events) { + throw new Error('A tool has to be registered with it\'s "events"'); + } + + tools.push(name); + + this.bindEvents(name, events); +}; + +ToolManager.prototype.isActive = function (tool) { + return tool && this._active === tool; +}; + +ToolManager.prototype.length = function (tool) { + return this._tools.length; +}; + +ToolManager.prototype.setActive = function (tool) { + var eventBus = this._eventBus; + + if (this._active !== tool) { + this._active = tool; + + eventBus.fire('tool-manager.update', { tool: tool }); + } +}; + +ToolManager.prototype.bindEvents = function (name, events) { + var eventBus = this._eventBus, + dragging = this._dragging; + + var eventsToRegister = []; + + eventBus.on(events.tool + '.init', function (event) { + var context = event.context; + + // Active tools that want to reactivate themselves must do this explicitly + if (!context.reactivate && this.isActive(name)) { + this.setActive(null); + + dragging.cancel(); + return; + } + + this.setActive(name); + }, this); + + // Todo[ricardo]: add test cases + (0, _minDash.forEach)(events, function (event) { + eventsToRegister.push(event + '.ended'); + eventsToRegister.push(event + '.canceled'); + }); + + eventBus.on(eventsToRegister, LOW_PRIORITY, function (event) { + var originalEvent = event.originalEvent; + + // We defer the de-activation of the tool to the .activate phase, + // so we're able to check if we want to toggle off the current + // active tool or switch to a new one + if (!this._active) { + return; + } + + if (originalEvent && (0, _minDom.closest)(originalEvent.target, '.group[data-group="tools"]')) { + return; + } + + this.setActive(null); + }, this); +}; + +},{"min-dash":505,"min-dom":506}],370:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _dragging = require('../dragging'); + +var _dragging2 = _interopRequireDefault(_dragging); + +var _ToolManager = require('./ToolManager'); + +var _ToolManager2 = _interopRequireDefault(_ToolManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __depends__: [_dragging2.default], + __init__: ['toolManager'], + toolManager: ['type', _ToolManager2.default] +}; + +},{"../dragging":286,"./ToolManager":369}],371:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = Tooltips; + +var _minDash = require('min-dash'); + +var _minDom = require('min-dom'); + +var _IdGenerator = require('../../util/IdGenerator'); + +var _IdGenerator2 = _interopRequireDefault(_IdGenerator); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// document wide unique tooltip ids +var ids = new _IdGenerator2.default('tt'); + +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' : ''; +} + +var tooltipClass = 'djs-tooltip', + tooltipSelector = '.' + tooltipClass; + +/** + * A service that allows users to render tool tips on the diagram. + * + * The tooltip service will take care of updating the tooltip positioning + * during navigation + zooming. + * + * @example + * + * ```javascript + * + * // add a pink badge on the top left of the shape + * tooltips.add({ + * position: { + * x: 50, + * y: 100 + * }, + * html: '
0
' + * }); + * + * // or with optional life span + * tooltips.add({ + * position: { + * top: -5, + * left: -5 + * }, + * html: '
0
', + * ttl: 2000 + * }); + * + * // remove a tool tip + * var id = tooltips.add(...); + * tooltips.remove(id); + * ``` + * + * @param {EventBus} eventBus + * @param {Canvas} canvas + */ +function Tooltips(eventBus, canvas) { + + this._eventBus = eventBus; + this._canvas = canvas; + + this._ids = ids; + + this._tooltipDefaults = { + show: { + minZoom: 0.7, + maxZoom: 5.0 + } + }; + + /** + * Mapping tooltipId -> tooltip + */ + this._tooltips = {}; + + // root html element for all tooltips + this._tooltipRoot = createRoot(canvas.getContainer()); + + var self = this; + + _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mousedown', function (event) { + event.stopPropagation(); + }); + + _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mouseover', function (event) { + self.trigger('mouseover', event); + }); + + _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mouseout', function (event) { + self.trigger('mouseout', event); + }); + + this._init(); +} + +Tooltips.$inject = ['eventBus', 'canvas']; + +/** + * Adds a HTML tooltip to the diagram + * + * @param {Object} tooltip the tooltip configuration + * + * @param {String|DOMElement} tooltip.html html element to use as an tooltip + * @param {Object} [tooltip.show] show configuration + * @param {Number} [tooltip.show.minZoom] minimal zoom level to show the tooltip + * @param {Number} [tooltip.show.maxZoom] maximum zoom level to show the tooltip + * @param {Object} tooltip.position where to attach the tooltip + * @param {Number} [tooltip.position.left] relative to element bbox left attachment + * @param {Number} [tooltip.position.top] relative to element bbox top attachment + * @param {Number} [tooltip.position.bottom] relative to element bbox bottom attachment + * @param {Number} [tooltip.position.right] relative to element bbox right attachment + * @param {Number} [tooltip.timeout=-1] + * + * @return {String} id that may be used to reference the tooltip for update or removal + */ +Tooltips.prototype.add = function (tooltip) { + + if (!tooltip.position) { + throw new Error('must specifiy tooltip position'); + } + + if (!tooltip.html) { + throw new Error('must specifiy tooltip html'); + } + + var id = this._ids.next(); + + tooltip = (0, _minDash.assign)({}, this._tooltipDefaults, tooltip, { + id: id + }); + + this._addTooltip(tooltip); + + if (tooltip.timeout) { + this.setTimeout(tooltip); + } + + return id; +}; + +Tooltips.prototype.trigger = function (action, event) { + + var node = event.delegateTarget || event.target; + + var tooltip = this.get((0, _minDom.attr)(node, 'data-tooltip-id')); + + if (!tooltip) { + return; + } + + if (action === 'mouseover' && tooltip.timeout) { + this.clearTimeout(tooltip); + } + + if (action === 'mouseout' && tooltip.timeout) { + // cut timeout after mouse out + tooltip.timeout = 1000; + + this.setTimeout(tooltip); + } +}; + +/** + * Get a tooltip with the given id + * + * @param {String} id + */ +Tooltips.prototype.get = function (id) { + + if (typeof id !== 'string') { + id = id.id; + } + + return this._tooltips[id]; +}; + +Tooltips.prototype.clearTimeout = function (tooltip) { + + tooltip = this.get(tooltip); + + if (!tooltip) { + return; + } + + var removeTimer = tooltip.removeTimer; + + if (removeTimer) { + clearTimeout(removeTimer); + tooltip.removeTimer = null; + } +}; + +Tooltips.prototype.setTimeout = function (tooltip) { + + tooltip = this.get(tooltip); + + if (!tooltip) { + return; + } + + this.clearTimeout(tooltip); + + var self = this; + + tooltip.removeTimer = setTimeout(function () { + self.remove(tooltip); + }, tooltip.timeout); +}; + +/** + * Remove an tooltip with the given id + * + * @param {String} id + */ +Tooltips.prototype.remove = function (id) { + + var tooltip = this.get(id); + + if (tooltip) { + (0, _minDom.remove)(tooltip.html); + (0, _minDom.remove)(tooltip.htmlContainer); + + delete tooltip.htmlContainer; + + delete this._tooltips[tooltip.id]; + } +}; + +Tooltips.prototype.show = function () { + setVisible(this._tooltipRoot); +}; + +Tooltips.prototype.hide = function () { + setVisible(this._tooltipRoot, false); +}; + +Tooltips.prototype._updateRoot = function (viewbox) { + var a = viewbox.scale || 1; + var d = viewbox.scale || 1; + + var matrix = 'matrix(' + a + ',0,0,' + d + ',' + -1 * viewbox.x * a + ',' + -1 * viewbox.y * d + ')'; + + this._tooltipRoot.style.transform = matrix; + this._tooltipRoot.style['-ms-transform'] = matrix; +}; + +Tooltips.prototype._addTooltip = function (tooltip) { + + var id = tooltip.id, + html = tooltip.html, + htmlContainer, + tooltipRoot = this._tooltipRoot; + + // unwrap jquery (for those who need it) + if (html.get && html.constructor.prototype.jquery) { + html = html.get(0); + } + + // create proper html elements from + // tooltip HTML strings + if ((0, _minDash.isString)(html)) { + html = (0, _minDom.domify)(html); + } + + htmlContainer = (0, _minDom.domify)('
'); + + htmlContainer.appendChild(html); + + if (tooltip.type) { + (0, _minDom.classes)(htmlContainer).add('djs-tooltip-' + tooltip.type); + } + + if (tooltip.className) { + (0, _minDom.classes)(htmlContainer).add(tooltip.className); + } + + tooltip.htmlContainer = htmlContainer; + + tooltipRoot.appendChild(htmlContainer); + + this._tooltips[id] = tooltip; + + this._updateTooltip(tooltip); +}; + +Tooltips.prototype._updateTooltip = function (tooltip) { + + var position = tooltip.position, + htmlContainer = tooltip.htmlContainer; + + // update overlay html based on tooltip x, y + + setPosition(htmlContainer, position.x, position.y); +}; + +Tooltips.prototype._updateTooltipVisibilty = function (viewbox) { + + (0, _minDash.forEach)(this._tooltips, function (tooltip) { + var show = tooltip.show, + htmlContainer = tooltip.htmlContainer, + visible = true; + + if (show) { + if (show.minZoom > viewbox.scale || show.maxZoom < viewbox.scale) { + visible = false; + } + + setVisible(htmlContainer, visible); + } + }); +}; + +Tooltips.prototype._init = function () { + + var self = this; + + // scroll/zoom integration + + function updateViewbox(viewbox) { + self._updateRoot(viewbox); + self._updateTooltipVisibilty(viewbox); + + self.show(); + } + + this._eventBus.on('canvas.viewbox.changing', function (event) { + self.hide(); + }); + + this._eventBus.on('canvas.viewbox.changed', function (event) { + updateViewbox(event.viewbox); + }); +}; + +},{"../../util/IdGenerator":400,"min-dash":505,"min-dom":506}],372:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _Tooltips = require('./Tooltips'); + +var _Tooltips2 = _interopRequireDefault(_Tooltips); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __init__: ['tooltips'], + tooltips: ['type', _Tooltips2.default] +}; + +},{"./Tooltips":371}],373:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = TouchFix; + +var _tinySvg = require('tiny-svg'); + +function TouchFix(canvas, eventBus) { + + var self = this; + + eventBus.on('canvas.init', function (e) { + self.addBBoxMarker(e.svg); + }); +} + +TouchFix.$inject = ['canvas', 'eventBus']; + +/** + * Safari mobile (iOS 7) does not fire touchstart event in element + * if there is no shape between 0,0 and viewport elements origin. + * + * So touchstart event is only fired when the element was hit. + * Putting an element over and below the 'viewport' fixes that behavior. + */ +TouchFix.prototype.addBBoxMarker = function (svg) { + + var markerStyle = { + fill: 'none', + class: 'outer-bound-marker' + }; + + var rect1 = (0, _tinySvg.create)('rect'); + (0, _tinySvg.attr)(rect1, { + x: -10000, + y: 10000, + width: 10, + height: 10 + }); + (0, _tinySvg.attr)(rect1, markerStyle); + + (0, _tinySvg.append)(svg, rect1); + + var rect2 = (0, _tinySvg.create)('rect'); + (0, _tinySvg.attr)(rect2, { + x: 10000, + y: 10000, + width: 10, + height: 10 + }); + (0, _tinySvg.attr)(rect2, markerStyle); + + (0, _tinySvg.append)(svg, rect2); +}; + +},{"tiny-svg":535}],374:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = TouchInteractionEvents; + +var _minDash = require('min-dash'); + +var _minDom = require('min-dom'); + +var _hammerjs = require('hammerjs'); + +var _hammerjs2 = _interopRequireDefault(_hammerjs); + +var _Event = require('../../util/Event'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var MIN_ZOOM = 0.2, + MAX_ZOOM = 4; + +var mouseEvents = ['mousedown', 'mouseup', 'mouseover', 'mouseout', 'click', 'dblclick']; + +function log() { + // console.log.apply(console, arguments); +} + +function get(service, injector) { + return injector.get(service, false); +} + +function stopEvent(event) { + + event.preventDefault(); + event.stopPropagation(); + + if (typeof event.stopImmediatePropagation === 'function') { + event.stopImmediatePropagation(); + } +} + +function createTouchRecognizer(node) { + + function stopMouse(event) { + + (0, _minDash.forEach)(mouseEvents, function (e) { + _minDom.event.bind(node, e, stopEvent, true); + }); + } + + function allowMouse(event) { + setTimeout(function () { + (0, _minDash.forEach)(mouseEvents, function (e) { + _minDom.event.unbind(node, e, stopEvent, true); + }); + }, 500); + } + + _minDom.event.bind(node, 'touchstart', stopMouse, true); + _minDom.event.bind(node, 'touchend', allowMouse, true); + _minDom.event.bind(node, 'touchcancel', allowMouse, true); + + // A touch event recognizer that handles + // touch events only (we know, we can already handle + // mouse events out of the box) + + var recognizer = new _hammerjs2.default.Manager(node, { + inputClass: _hammerjs2.default.TouchInput, + recognizers: [] + }); + + var tap = new _hammerjs2.default.Tap(); + var pan = new _hammerjs2.default.Pan({ threshold: 10 }); + var press = new _hammerjs2.default.Press(); + var pinch = new _hammerjs2.default.Pinch(); + + var doubleTap = new _hammerjs2.default.Tap({ event: 'doubletap', taps: 2 }); + + pinch.requireFailure(pan); + pinch.requireFailure(press); + + recognizer.add([pan, press, pinch, doubleTap, tap]); + + recognizer.reset = function (force) { + var recognizers = this.recognizers, + session = this.session; + + if (session.stopped) { + return; + } + + log('recognizer', 'stop'); + + recognizer.stop(force); + + setTimeout(function () { + var i, r; + + log('recognizer', 'reset'); + for (i = 0; r = recognizers[i]; i++) { + r.reset(); + r.state = 8; // FAILED STATE + } + + session.curRecognizer = null; + }, 0); + }; + + recognizer.on('hammer.input', function (event) { + if (event.srcEvent.defaultPrevented) { + recognizer.reset(true); + } + }); + + return recognizer; +} + +/** + * A plugin that provides touch events for elements. + * + * @param {EventBus} eventBus + * @param {InteractionEvents} interactionEvents + */ +function TouchInteractionEvents(injector, canvas, eventBus, elementRegistry, interactionEvents) { + + // optional integrations + var dragging = get('dragging', injector), + move = get('move', injector), + contextPad = get('contextPad', injector), + palette = get('palette', injector); + + // the touch recognizer + var recognizer; + + function handler(type) { + + return function (event) { + log('element', type, event); + + interactionEvents.fire(type, event); + }; + } + + function getGfx(target) { + var node = (0, _minDom.closest)(target, 'svg, .djs-element', true); + return node; + } + + function initEvents(svg) { + + // touch recognizer + recognizer = createTouchRecognizer(svg); + + recognizer.on('doubletap', handler('element.dblclick')); + + recognizer.on('tap', handler('element.click')); + + function startGrabCanvas(event) { + + log('canvas', 'grab start'); + + var lx = 0, + ly = 0; + + function update(e) { + + var dx = e.deltaX - lx, + dy = e.deltaY - ly; + + canvas.scroll({ dx: dx, dy: dy }); + + lx = e.deltaX; + ly = e.deltaY; + } + + function end(e) { + recognizer.off('panmove', update); + recognizer.off('panend', end); + recognizer.off('pancancel', end); + + log('canvas', 'grab end'); + } + + recognizer.on('panmove', update); + recognizer.on('panend', end); + recognizer.on('pancancel', end); + } + + function startGrab(event) { + + var gfx = getGfx(event.target), + element = gfx && elementRegistry.get(gfx); + + // recognizer + if (move && canvas.getRootElement() !== element) { + log('element', 'move start', element, event, true); + return move.start(event, element, true); + } else { + startGrabCanvas(event); + } + } + + function startZoom(e) { + + log('canvas', 'zoom start'); + + var zoom = canvas.zoom(), + mid = e.center; + + function update(e) { + + var ratio = 1 - (1 - e.scale) / 1.50, + newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, ratio * zoom)); + + canvas.zoom(newZoom, mid); + + stopEvent(e); + } + + function end(e) { + recognizer.off('pinchmove', update); + recognizer.off('pinchend', end); + recognizer.off('pinchcancel', end); + + recognizer.reset(true); + + log('canvas', 'zoom end'); + } + + recognizer.on('pinchmove', update); + recognizer.on('pinchend', end); + recognizer.on('pinchcancel', end); + } + + recognizer.on('panstart', startGrab); + recognizer.on('press', startGrab); + + recognizer.on('pinchstart', startZoom); + } + + if (dragging) { + + // simulate hover during dragging + eventBus.on('drag.move', function (event) { + + var originalEvent = event.originalEvent; + + if (!originalEvent || originalEvent instanceof MouseEvent) { + return; + } + + var position = (0, _Event.toPoint)(originalEvent); + + // this gets really expensive ... + var node = document.elementFromPoint(position.x, position.y), + gfx = getGfx(node), + element = gfx && elementRegistry.get(gfx); + + if (element !== event.hover) { + if (event.hover) { + dragging.out(event); + } + + if (element) { + dragging.hover({ element: element, gfx: gfx }); + + event.hover = element; + event.hoverGfx = gfx; + } + } + }); + } + + if (contextPad) { + + eventBus.on('contextPad.create', function (event) { + var node = event.pad.html; + + // touch recognizer + var padRecognizer = createTouchRecognizer(node); + + padRecognizer.on('panstart', function (event) { + log('context-pad', 'panstart', event); + contextPad.trigger('dragstart', event, true); + }); + + padRecognizer.on('press', function (event) { + log('context-pad', 'press', event); + contextPad.trigger('dragstart', event, true); + }); + + padRecognizer.on('tap', function (event) { + log('context-pad', 'tap', event); + contextPad.trigger('click', event); + }); + }); + } + + if (palette) { + eventBus.on('palette.create', function (event) { + var node = event.container; + + // touch recognizer + var padRecognizer = createTouchRecognizer(node); + + padRecognizer.on('panstart', function (event) { + log('palette', 'panstart', event); + palette.trigger('dragstart', event, true); + }); + + padRecognizer.on('press', function (event) { + log('palette', 'press', event); + palette.trigger('dragstart', event, true); + }); + + padRecognizer.on('tap', function (event) { + log('palette', 'tap', event); + palette.trigger('click', event); + }); + }); + } + + eventBus.on('canvas.init', function (event) { + initEvents(event.svg); + }); +} + +TouchInteractionEvents.$inject = ['injector', 'canvas', 'eventBus', 'elementRegistry', 'interactionEvents', 'touchFix']; + +},{"../../util/Event":397,"hammerjs":412,"min-dash":505,"min-dom":506}],375:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _interactionEvents = require('../interaction-events'); + +var _interactionEvents2 = _interopRequireDefault(_interactionEvents); + +var _TouchInteractionEvents = require('./TouchInteractionEvents'); + +var _TouchInteractionEvents2 = _interopRequireDefault(_TouchInteractionEvents); + +var _TouchFix = require('./TouchFix'); + +var _TouchFix2 = _interopRequireDefault(_TouchFix); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __depends__: [_interactionEvents2.default], + __init__: ['touchInteractionEvents'], + touchInteractionEvents: ['type', _TouchInteractionEvents2.default], + touchFix: ['type', _TouchFix2.default] +}; + +},{"../interaction-events":294,"./TouchFix":373,"./TouchInteractionEvents":374}],376:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _translate = require('./translate'); + +var _translate2 = _interopRequireDefault(_translate); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + translate: ['value', _translate2.default] +}; + +},{"./translate":377}],377:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = translate; +/** + * A simple translation stub to be used for multi-language support + * in diagrams. Can be easily replaced with a more sophisticated + * solution. + * + * @example + * + * // use it inside any diagram component by injecting `translate`. + * + * function MyService(translate) { + * alert(translate('HELLO {you}', { you: 'You!' })); + * } + * + * @param {String} template to interpolate + * @param {Object} [replacements] a map with substitutes + * + * @return {String} the translated string + */ +function translate(template, replacements) { + + replacements = replacements || {}; + + return template.replace(/{([^}]+)}/g, function (_, key) { + return replacements[key] || '{' + key + '}'; + }); +} + +},{}],378:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = BaseLayouter; + +var _LayoutUtil = require('./LayoutUtil'); + +/** + * A base connection layouter implementation + * that layouts the connection by directly connecting + * mid(source) + mid(target). + */ +function BaseLayouter() {} + +/** + * Return the new layouted waypoints for the given connection. + * + * The connection passed is still unchanged; you may figure out about + * the new connection start / end via the layout hints provided. + * + * @param {djs.model.Connection} connection + * @param {Object} [hints] + * @param {Point} [hints.connectionStart] + * @param {Point} [hints.connectionEnd] + * + * @return {Array} the layouted connection waypoints + */ +BaseLayouter.prototype.layoutConnection = function (connection, hints) { + + hints = hints || {}; + + return [hints.connectionStart || (0, _LayoutUtil.getMid)(connection.source), hints.connectionEnd || (0, _LayoutUtil.getMid)(connection.target)]; +}; + +},{"./LayoutUtil":380}],379:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = CroppingConnectionDocking; + +var _minDash = require('min-dash'); + +var _LayoutUtil = require('./LayoutUtil'); + +function dockingToPoint(docking) { + // use the dockings actual point and + // retain the original docking + return (0, _minDash.assign)({ original: docking.point.original || docking.point }, docking.actual); +} + +/** + * A {@link ConnectionDocking} that crops connection waypoints based on + * the path(s) of the connection source and target. + * + * @param {djs.core.ElementRegistry} elementRegistry + */ +function CroppingConnectionDocking(elementRegistry, graphicsFactory) { + this._elementRegistry = elementRegistry; + this._graphicsFactory = graphicsFactory; +} + +CroppingConnectionDocking.$inject = ['elementRegistry', 'graphicsFactory']; + +/** + * @inheritDoc ConnectionDocking#getCroppedWaypoints + */ +CroppingConnectionDocking.prototype.getCroppedWaypoints = function (connection, source, target) { + + source = source || connection.source; + target = target || connection.target; + + var sourceDocking = this.getDockingPoint(connection, source, true), + targetDocking = this.getDockingPoint(connection, target); + + var croppedWaypoints = connection.waypoints.slice(sourceDocking.idx + 1, targetDocking.idx); + + croppedWaypoints.unshift(dockingToPoint(sourceDocking)); + croppedWaypoints.push(dockingToPoint(targetDocking)); + + return croppedWaypoints; +}; + +/** + * Return the connection docking point on the specified shape + * + * @inheritDoc ConnectionDocking#getDockingPoint + */ +CroppingConnectionDocking.prototype.getDockingPoint = function (connection, shape, dockStart) { + + var waypoints = connection.waypoints, + dockingIdx, + dockingPoint, + croppedPoint; + + dockingIdx = dockStart ? 0 : waypoints.length - 1; + dockingPoint = waypoints[dockingIdx]; + + croppedPoint = this._getIntersection(shape, connection, dockStart); + + return { + point: dockingPoint, + actual: croppedPoint || dockingPoint, + idx: dockingIdx + }; +}; + +// helpers ////////////////////// + +CroppingConnectionDocking.prototype._getIntersection = function (shape, connection, takeFirst) { + + var shapePath = this._getShapePath(shape), + connectionPath = this._getConnectionPath(connection); + + return (0, _LayoutUtil.getElementLineIntersection)(shapePath, connectionPath, takeFirst); +}; + +CroppingConnectionDocking.prototype._getConnectionPath = function (connection) { + return this._graphicsFactory.getConnectionPath(connection); +}; + +CroppingConnectionDocking.prototype._getShapePath = function (shape) { + return this._graphicsFactory.getShapePath(shape); +}; + +CroppingConnectionDocking.prototype._getGfx = function (element) { + return this._elementRegistry.getGraphics(element); +}; + +},{"./LayoutUtil":380,"min-dash":505}],380:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.roundBounds = roundBounds; +exports.roundPoint = roundPoint; +exports.asTRBL = asTRBL; +exports.asBounds = asBounds; +exports.getMid = getMid; +exports.getOrientation = getOrientation; +exports.getElementLineIntersection = getElementLineIntersection; +exports.getIntersections = getIntersections; + +var _minDash = require('min-dash'); + +var _Geometry = require('../util/Geometry'); + +var _pathIntersection = require('path-intersection'); + +var _pathIntersection2 = _interopRequireDefault(_pathIntersection); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function roundBounds(bounds) { + return { + x: Math.round(bounds.x), + y: Math.round(bounds.y), + width: Math.round(bounds.width), + height: Math.round(bounds.height) + }; +} + +function roundPoint(point) { + + return { + x: Math.round(point.x), + y: Math.round(point.y) + }; +} + +/** + * Convert the given bounds to a { top, left, bottom, right } descriptor. + * + * @param {Bounds|Point} bounds + * + * @return {Object} + */ +function asTRBL(bounds) { + return { + top: bounds.y, + right: bounds.x + (bounds.width || 0), + bottom: bounds.y + (bounds.height || 0), + left: bounds.x + }; +} + +/** + * Convert a { top, left, bottom, right } to an objects bounds. + * + * @param {Object} trbl + * + * @return {Bounds} + */ +function asBounds(trbl) { + return { + x: trbl.left, + y: trbl.top, + width: trbl.right - trbl.left, + height: trbl.bottom - trbl.top + }; +} + +/** + * Get the mid of the given bounds or point. + * + * @param {Bounds|Point} bounds + * + * @return {Point} + */ +function getMid(bounds) { + return roundPoint({ + x: bounds.x + (bounds.width || 0) / 2, + y: bounds.y + (bounds.height || 0) / 2 + }); +} + +// orientation utils ////////////////////// + +/** + * Get orientation of the given rectangle with respect to + * the reference rectangle. + * + * A padding (positive or negative) may be passed to influence + * horizontal / vertical orientation and intersection. + * + * @param {Bounds} rect + * @param {Bounds} reference + * @param {Point|Number} padding + * + * @return {String} the orientation; one of top, top-left, left, ..., bottom, right or intersect. + */ +function getOrientation(rect, reference, padding) { + + padding = padding || 0; + + // make sure we can use an object, too + // for individual { x, y } padding + if (!(0, _minDash.isObject)(padding)) { + padding = { x: padding, y: padding }; + } + + var rectOrientation = asTRBL(rect), + referenceOrientation = asTRBL(reference); + + var top = rectOrientation.bottom + padding.y <= referenceOrientation.top, + right = rectOrientation.left - padding.x >= referenceOrientation.right, + bottom = rectOrientation.top - padding.y >= referenceOrientation.bottom, + left = rectOrientation.right + padding.x <= referenceOrientation.left; + + var vertical = top ? 'top' : bottom ? 'bottom' : null, + horizontal = left ? 'left' : right ? 'right' : null; + + if (horizontal && vertical) { + return vertical + '-' + horizontal; + } else { + return horizontal || vertical || 'intersect'; + } +} + +// intersection utils ////////////////////// + +/** + * Get intersection between an element and a line path. + * + * @param {PathDef} elementPath + * @param {PathDef} linePath + * @param {Boolean} cropStart crop from start or end + * + * @return {Point} + */ +function getElementLineIntersection(elementPath, linePath, cropStart) { + + var intersections = getIntersections(elementPath, linePath); + + // recognize intersections + // only one -> choose + // two close together -> choose first + // two or more distinct -> pull out appropriate one + // none -> ok (fallback to point itself) + if (intersections.length === 1) { + return roundPoint(intersections[0]); + } else if (intersections.length === 2 && (0, _Geometry.pointDistance)(intersections[0], intersections[1]) < 1) { + return roundPoint(intersections[0]); + } else if (intersections.length > 1) { + + // sort by intersections based on connection segment + + // distance from start + intersections = (0, _minDash.sortBy)(intersections, function (i) { + var distance = Math.floor(i.t2 * 100) || 1; + + distance = 100 - distance; + + distance = (distance < 10 ? '0' : '') + distance; + + // create a sort string that makes sure we sort + // line segment ASC + line segment position DESC (for cropStart) + // line segment ASC + line segment position ASC (for cropEnd) + return i.segment2 + '#' + distance; + }); + + return roundPoint(intersections[cropStart ? 0 : intersections.length - 1]); + } + + return null; +} + +function getIntersections(a, b) { + return (0, _pathIntersection2.default)(a, b); +} + +},{"../util/Geometry":398,"min-dash":505,"path-intersection":523}],381:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.connectPoints = connectPoints; +exports.connectRectangles = connectRectangles; +exports.repairConnection = repairConnection; +exports.layoutStraight = layoutStraight; +exports._repairConnectionSide = _repairConnectionSide; +exports.withoutRedundantPoints = withoutRedundantPoints; + +var _minDash = require('min-dash'); + +var _LayoutUtil = require('./LayoutUtil'); + +var _Geometry = require('../util/Geometry'); + +var MIN_SEGMENT_LENGTH = 20, + POINT_ORIENTATION_PADDING = 5; + +var round = Math.round; + +var INTERSECTION_THRESHOLD = 20, + ORIENTATION_THRESHOLD = { + 'h:h': 20, + 'v:v': 20, + 'h:v': -10, + 'v:h': -10 +}; + +function needsTurn(orientation, startDirection) { + return !{ + t: /top/, + r: /right/, + b: /bottom/, + l: /left/, + h: /./, + v: /./ + }[startDirection].test(orientation); +} + +function canLayoutStraight(direction, targetOrientation) { + return { + t: /top/, + r: /right/, + b: /bottom/, + l: /left/, + h: /left|right/, + v: /top|bottom/ + }[direction].test(targetOrientation); +} + +function getSegmentBendpoints(a, b, directions) { + var orientation = (0, _LayoutUtil.getOrientation)(b, a, POINT_ORIENTATION_PADDING); + + var startDirection = directions.split(':')[0]; + + var xmid = round((b.x - a.x) / 2 + a.x), + ymid = round((b.y - a.y) / 2 + a.y); + + var segmentEnd, segmentDirections; + + var layoutStraight = canLayoutStraight(startDirection, orientation), + layoutHorizontal = /h|r|l/.test(startDirection), + layoutTurn = false; + + var turnNextDirections = false; + + if (layoutStraight) { + segmentEnd = layoutHorizontal ? { x: xmid, y: a.y } : { x: a.x, y: ymid }; + + segmentDirections = layoutHorizontal ? 'h:h' : 'v:v'; + } else { + layoutTurn = needsTurn(orientation, startDirection); + + segmentDirections = layoutHorizontal ? 'h:v' : 'v:h'; + + if (layoutTurn) { + + if (layoutHorizontal) { + turnNextDirections = ymid === a.y; + + segmentEnd = { + x: a.x + MIN_SEGMENT_LENGTH * (/l/.test(startDirection) ? -1 : 1), + y: turnNextDirections ? ymid + MIN_SEGMENT_LENGTH : ymid + }; + } else { + turnNextDirections = xmid === a.x; + + segmentEnd = { + x: turnNextDirections ? xmid + MIN_SEGMENT_LENGTH : xmid, + y: a.y + MIN_SEGMENT_LENGTH * (/t/.test(startDirection) ? -1 : 1) + }; + } + } else { + segmentEnd = { + x: xmid, + y: ymid + }; + } + } + + return { + waypoints: getBendpoints(a, segmentEnd, segmentDirections).concat(segmentEnd), + directions: segmentDirections, + turnNextDirections: turnNextDirections + }; +} + +function getStartSegment(a, b, directions) { + return getSegmentBendpoints(a, b, directions); +} + +function getEndSegment(a, b, directions) { + var invertedSegment = getSegmentBendpoints(b, a, invertDirections(directions)); + + return { + waypoints: invertedSegment.waypoints.slice().reverse(), + directions: invertDirections(invertedSegment.directions), + turnNextDirections: invertedSegment.turnNextDirections + }; +} + +function getMidSegment(startSegment, endSegment) { + + var startDirection = startSegment.directions.split(':')[1], + endDirection = endSegment.directions.split(':')[0]; + + if (startSegment.turnNextDirections) { + startDirection = startDirection == 'h' ? 'v' : 'h'; + } + + if (endSegment.turnNextDirections) { + endDirection = endDirection == 'h' ? 'v' : 'h'; + } + + var directions = startDirection + ':' + endDirection; + + var bendpoints = getBendpoints(startSegment.waypoints[startSegment.waypoints.length - 1], endSegment.waypoints[0], directions); + + return { + waypoints: bendpoints, + directions: directions + }; +} + +function invertDirections(directions) { + return directions.split(':').reverse().join(':'); +} + +/** + * Handle simple layouts with maximum two bendpoints. + */ +function getSimpleBendpoints(a, b, directions) { + + var xmid = round((b.x - a.x) / 2 + a.x), + ymid = round((b.y - a.y) / 2 + a.y); + + // one point, right or left from a + if (directions === 'h:v') { + return [{ x: b.x, y: a.y }]; + } + + // one point, above or below a + if (directions === 'v:h') { + return [{ x: a.x, y: b.y }]; + } + + // vertical segment between a and b + if (directions === 'h:h') { + return [{ x: xmid, y: a.y }, { x: xmid, y: b.y }]; + } + + // horizontal segment between a and b + if (directions === 'v:v') { + return [{ x: a.x, y: ymid }, { x: b.x, y: ymid }]; + } + + throw new Error('invalid directions: can only handle varians of [hv]:[hv]'); +} + +/** + * Returns the mid points for a manhattan connection between two points. + * + * @example h:h (horizontal:horizontal) + * + * [a]----[x] + * | + * [x]----[b] + * + * @example h:v (horizontal:vertical) + * + * [a]----[x] + * | + * [b] + * + * @example h:r (horizontal:right) + * + * [a]----[x] + * | + * [b]-[x] + * + * @param {Point} a + * @param {Point} b + * @param {String} directions + * + * @return {Array} + */ +function getBendpoints(a, b, directions) { + directions = directions || 'h:h'; + + if (!isValidDirections(directions)) { + throw new Error('unknown directions: <' + directions + '>: ' + 'must be specified as : ' + 'with start/end in { h,v,t,r,b,l }'); + } + + // compute explicit directions, involving trbl dockings + // using a three segmented layouting algorithm + if (isExplicitDirections(directions)) { + var startSegment = getStartSegment(a, b, directions), + endSegment = getEndSegment(a, b, directions), + midSegment = getMidSegment(startSegment, endSegment); + + return [].concat(startSegment.waypoints, midSegment.waypoints, endSegment.waypoints); + } + + // handle simple [hv]:[hv] cases that can be easily computed + return getSimpleBendpoints(a, b, directions); +} + +/** + * Create a connection between the two points according + * to the manhattan layout (only horizontal and vertical) edges. + * + * @param {Point} a + * @param {Point} b + * + * @param {String} [directions='h:h'] specifies manhattan directions for each point as {adirection}:{bdirection}. + A directionfor a point is either `h` (horizontal) or `v` (vertical) + * + * @return {Array} + */ +function connectPoints(a, b, directions) { + + var points = getBendpoints(a, b, directions); + + points.unshift(a); + points.push(b); + + return withoutRedundantPoints(points); +} + +/** + * Connect two rectangles using a manhattan layouted connection. + * + * @param {Bounds} source source rectangle + * @param {Bounds} target target rectangle + * @param {Point} [start] source docking + * @param {Point} [end] target docking + * + * @param {Object} [hints] + * @param {String} [hints.preserveDocking=source] preserve docking on selected side + * @param {Array} [hints.preferredLayouts] + * @param {Point|Boolean} [hints.connectionStart] whether the start changed + * @param {Point|Boolean} [hints.connectionEnd] whether the end changed + * + * @return {Array} connection points + */ +function connectRectangles(source, target, start, end, hints) { + + var preferredLayouts = hints && hints.preferredLayouts || []; + + var preferredLayout = (0, _minDash.without)(preferredLayouts, 'straight')[0] || 'h:h'; + + var threshold = ORIENTATION_THRESHOLD[preferredLayout] || 0; + + var orientation = (0, _LayoutUtil.getOrientation)(source, target, threshold); + + var directions = getDirections(orientation, preferredLayout); + + start = start || (0, _LayoutUtil.getMid)(source); + end = end || (0, _LayoutUtil.getMid)(target); + + var directionSplit = directions.split(':'); + + // compute actual docking points for start / end + // this ensures we properly layout only parts of the + // connection that lies in between the two rectangles + var startDocking = getDockingPoint(start, source, directionSplit[0], invertOrientation(orientation)), + endDocking = getDockingPoint(end, target, directionSplit[1], orientation); + + return connectPoints(startDocking, endDocking, directions); +} + +/** + * Repair the connection between two rectangles, of which one has been updated. + * + * @param {Bounds} source + * @param {Bounds} target + * @param {Point} [start] + * @param {Point} [end] + * @param {Array} waypoints + * @param {Object} [hints] + * @param {Array} [hints.preferredLayouts] list of preferred layouts + * @param {Boolean} [hints.connectionStart] + * @param {Boolean} [hints.connectionEnd] + * + * @return {Array} repaired waypoints + */ +function repairConnection(source, target, start, end, waypoints, hints) { + + if ((0, _minDash.isArray)(start)) { + waypoints = start; + hints = end; + + start = (0, _LayoutUtil.getMid)(source); + end = (0, _LayoutUtil.getMid)(target); + } + + hints = (0, _minDash.assign)({ preferredLayouts: [] }, hints); + waypoints = waypoints || []; + + var preferredLayouts = hints.preferredLayouts, + preferStraight = preferredLayouts.indexOf('straight') !== -1, + repairedWaypoints; + + // just layout non-existing or simple connections + // attempt to render straight lines, if required + + if (preferStraight) { + // attempt to layout a straight line + repairedWaypoints = layoutStraight(source, target, start, end, hints); + } + + if (!repairedWaypoints) { + // check if we layout from start or end + if (hints.connectionEnd) { + repairedWaypoints = _repairConnectionSide(target, source, end, waypoints.slice().reverse()); + repairedWaypoints = repairedWaypoints && repairedWaypoints.reverse(); + } else if (hints.connectionStart) { + repairedWaypoints = _repairConnectionSide(source, target, start, waypoints); + } else + // or whether nothing seems to have changed + if (waypoints && waypoints.length) { + repairedWaypoints = waypoints; + } + } + + // simply reconnect if nothing else worked + if (!repairedWaypoints) { + repairedWaypoints = connectRectangles(source, target, start, end, hints); + } + + return repairedWaypoints; +} + +function inRange(a, start, end) { + return a >= start && a <= end; +} + +function isInRange(axis, a, b) { + var size = { + x: 'width', + y: 'height' + }; + + return inRange(a[axis], b[axis], b[axis] + b[size[axis]]); +} + +/** + * Layout a straight connection + * + * @param {Bounds} source + * @param {Bounds} target + * @param {Point} start + * @param {Point} end + * @param {Object} [hints] + * + * @return {Array} waypoints if straight layout worked + */ +function layoutStraight(source, target, start, end, hints) { + var axis = {}, + primaryAxis, + orientation; + + orientation = (0, _LayoutUtil.getOrientation)(source, target); + + // only layout a straight connection if shapes are + // horizontally or vertically aligned + if (!/^(top|bottom|left|right)$/.test(orientation)) { + return null; + } + + if (/top|bottom/.test(orientation)) { + primaryAxis = 'x'; + } + + if (/left|right/.test(orientation)) { + primaryAxis = 'y'; + } + + if (hints.preserveDocking === 'target') { + + if (!isInRange(primaryAxis, end, source)) { + return null; + } + + axis[primaryAxis] = end[primaryAxis]; + + return [{ + x: axis.x !== undefined ? axis.x : start.x, + y: axis.y !== undefined ? axis.y : start.y, + original: { + x: axis.x !== undefined ? axis.x : start.x, + y: axis.y !== undefined ? axis.y : start.y + } + }, { + x: end.x, + y: end.y + }]; + } else { + + if (!isInRange(primaryAxis, start, target)) { + return null; + } + + axis[primaryAxis] = start[primaryAxis]; + + return [{ + x: start.x, + y: start.y + }, { + x: axis.x !== undefined ? axis.x : end.x, + y: axis.y !== undefined ? axis.y : end.y, + original: { + x: axis.x !== undefined ? axis.x : end.x, + y: axis.y !== undefined ? axis.y : end.y + } + }]; + } +} + +/** + * Repair a connection from one side that moved. + * + * @param {Bounds} moved + * @param {Bounds} other + * @param {Point} newDocking + * @param {Array} points originalPoints from moved to other + * + * @return {Array} the repaired points between the two rectangles + */ +function _repairConnectionSide(moved, other, newDocking, points) { + + function needsRelayout(moved, other, points) { + + if (points.length < 3) { + return true; + } + + if (points.length > 4) { + return false; + } + + // relayout if two points overlap + // this is most likely due to + return !!(0, _minDash.find)(points, function (p, idx) { + var q = points[idx - 1]; + + return q && (0, _Geometry.pointDistance)(p, q) < 3; + }); + } + + function repairBendpoint(candidate, oldPeer, newPeer) { + + var alignment = (0, _Geometry.pointsAligned)(oldPeer, candidate); + + switch (alignment) { + case 'v': + // repair vertical alignment + return { x: candidate.x, y: newPeer.y }; + case 'h': + // repair horizontal alignment + return { x: newPeer.x, y: candidate.y }; + } + + return { x: candidate.x, y: candidate.y }; + } + + function removeOverlapping(points, a, b) { + var i; + + for (i = points.length - 2; i !== 0; i--) { + + // intersects (?) break, remove all bendpoints up to this one and relayout + if ((0, _Geometry.pointInRect)(points[i], a, INTERSECTION_THRESHOLD) || (0, _Geometry.pointInRect)(points[i], b, INTERSECTION_THRESHOLD)) { + + // return sliced old connection + return points.slice(i); + } + } + + return points; + } + + // (0) only repair what has layoutable bendpoints + + // (1) if only one bendpoint and on shape moved onto other shapes axis + // (horizontally / vertically), relayout + + if (needsRelayout(moved, other, points)) { + return null; + } + + var oldDocking = points[0], + newPoints = points.slice(), + slicedPoints; + + // (2) repair only last line segment and only if it was layouted before + + newPoints[0] = newDocking; + newPoints[1] = repairBendpoint(newPoints[1], oldDocking, newDocking); + + // (3) if shape intersects with any bendpoint after repair, + // remove all segments up to this bendpoint and repair from there + + slicedPoints = removeOverlapping(newPoints, moved, other); + + if (slicedPoints !== newPoints) { + return _repairConnectionSide(moved, other, newDocking, slicedPoints); + } + + return newPoints; +} + +/** + * Returns the manhattan directions connecting two rectangles + * with the given orientation. + * + * Will always return the default layout, if it is specific + * regarding sides already (trbl). + * + * @example + * + * getDirections('top'); // -> 'v:v' + * getDirections('intersect'); // -> 't:t' + * + * getDirections('top-right', 'v:h'); // -> 'v:h' + * getDirections('top-right', 'h:h'); // -> 'h:h' + * + * + * @param {String} orientation + * @param {String} defaultLayout + * + * @return {String} + */ +function getDirections(orientation, defaultLayout) { + + // don't override specific trbl directions + if (isExplicitDirections(defaultLayout)) { + return defaultLayout; + } + + switch (orientation) { + case 'intersect': + return 't:t'; + + case 'top': + case 'bottom': + return 'v:v'; + + case 'left': + case 'right': + return 'h:h'; + + // 'top-left' + // 'top-right' + // 'bottom-left' + // 'bottom-right' + default: + return defaultLayout; + } +} + +function isValidDirections(directions) { + return directions && /^h|v|t|r|b|l:h|v|t|r|b|l$/.test(directions); +} + +function isExplicitDirections(directions) { + return directions && /t|r|b|l/.test(directions); +} + +function invertOrientation(orientation) { + return { + 'top': 'bottom', + 'bottom': 'top', + 'left': 'right', + 'right': 'left', + 'top-left': 'bottom-right', + 'bottom-right': 'top-left', + 'top-right': 'bottom-left', + 'bottom-left': 'top-right' + }[orientation]; +} + +function getDockingPoint(point, rectangle, dockingDirection, targetOrientation) { + + // ensure we end up with a specific docking direction + // based on the targetOrientation, if is being passed + + if (dockingDirection === 'h') { + dockingDirection = /left/.test(targetOrientation) ? 'l' : 'r'; + } + + if (dockingDirection === 'v') { + dockingDirection = /top/.test(targetOrientation) ? 't' : 'b'; + } + + if (dockingDirection === 't') { + return { original: point, x: point.x, y: rectangle.y }; + } + + if (dockingDirection === 'r') { + return { original: point, x: rectangle.x + rectangle.width, y: point.y }; + } + + if (dockingDirection === 'b') { + return { original: point, x: point.x, y: rectangle.y + rectangle.height }; + } + + if (dockingDirection === 'l') { + return { original: point, x: rectangle.x, y: point.y }; + } + + throw new Error('unexpected dockingDirection: <' + dockingDirection + '>'); +} + +/** + * Return list of waypoints with redundant ones filtered out. + * + * @example + * + * Original points: + * + * [x] ----- [x] ------ [x] + * | + * [x] ----- [x] - [x] + * + * Filtered: + * + * [x] ---------------- [x] + * | + * [x] ----------- [x] + * + * @param {Array} waypoints + * + * @return {Array} + */ +function withoutRedundantPoints(waypoints) { + return waypoints.reduce(function (points, p, idx) { + + var previous = points[points.length - 1], + next = waypoints[idx + 1]; + + if (!(0, _Geometry.pointsOnLine)(previous, next, p, 0)) { + points.push(p); + } + + return points; + }, []); +} + +},{"../util/Geometry":398,"./LayoutUtil":380,"min-dash":505}],382:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Base = Base; +exports.Shape = Shape; +exports.Root = Root; +exports.Label = Label; +exports.Connection = Connection; +exports.create = create; + +var _minDash = require('min-dash'); + +var _inherits = require('inherits'); + +var _inherits2 = _interopRequireDefault(_inherits); + +var _objectRefs = require('object-refs'); + +var _objectRefs2 = _interopRequireDefault(_objectRefs); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var parentRefs = new _objectRefs2.default({ name: 'children', enumerable: true, collection: true }, { name: 'parent' }), + labelRefs = new _objectRefs2.default({ name: 'labels', enumerable: true, collection: true }, { name: 'labelTarget' }), + attacherRefs = new _objectRefs2.default({ name: 'attachers', collection: true }, { name: 'host' }), + outgoingRefs = new _objectRefs2.default({ name: 'outgoing', collection: true }, { name: 'source' }), + incomingRefs = new _objectRefs2.default({ name: 'incoming', collection: true }, { name: 'target' }); + +/** + * @namespace djs.model + */ + +/** + * @memberOf djs.model + */ + +/** + * The basic graphical representation + * + * @class + * + * @abstract + */ +function Base() { + + /** + * The object that backs up the shape + * + * @name Base#businessObject + * @type Object + */ + Object.defineProperty(this, 'businessObject', { + writable: true + }); + + /** + * Single label support, will mapped to multi label array + * + * @name Base#label + * @type Object + */ + Object.defineProperty(this, 'label', { + get: function get() { + return this.labels[0]; + }, + set: function set(newLabel) { + + var label = this.label, + labels = this.labels; + + if (!newLabel && label) { + labels.remove(label); + } else { + labels.add(newLabel, 0); + } + } + }); + + /** + * The parent shape + * + * @name Base#parent + * @type Shape + */ + parentRefs.bind(this, 'parent'); + + /** + * The list of labels + * + * @name Base#labels + * @type Label + */ + labelRefs.bind(this, 'labels'); + + /** + * The list of outgoing connections + * + * @name Base#outgoing + * @type Array + */ + outgoingRefs.bind(this, 'outgoing'); + + /** + * The list of incoming connections + * + * @name Base#incoming + * @type Array + */ + incomingRefs.bind(this, 'incoming'); +} + +/** + * A graphical object + * + * @class + * @constructor + * + * @extends Base + */ +function Shape() { + Base.call(this); + + /** + * The list of children + * + * @name Shape#children + * @type Array + */ + parentRefs.bind(this, 'children'); + + /** + * @name Shape#host + * @type Shape + */ + attacherRefs.bind(this, 'host'); + + /** + * @name Shape#attachers + * @type Shape + */ + attacherRefs.bind(this, 'attachers'); +} + +(0, _inherits2.default)(Shape, Base); + +/** + * A root graphical object + * + * @class + * @constructor + * + * @extends Shape + */ +function Root() { + Shape.call(this); +} + +(0, _inherits2.default)(Root, Shape); + +/** + * A label for an element + * + * @class + * @constructor + * + * @extends Shape + */ +function Label() { + Shape.call(this); + + /** + * The labeled element + * + * @name Label#labelTarget + * @type Base + */ + labelRefs.bind(this, 'labelTarget'); +} + +(0, _inherits2.default)(Label, Shape); + +/** + * A connection between two elements + * + * @class + * @constructor + * + * @extends Base + */ +function Connection() { + Base.call(this); + + /** + * The element this connection originates from + * + * @name Connection#source + * @type Base + */ + outgoingRefs.bind(this, 'source'); + + /** + * The element this connection points to + * + * @name Connection#target + * @type Base + */ + incomingRefs.bind(this, 'target'); +} + +(0, _inherits2.default)(Connection, Base); + +var types = { + connection: Connection, + shape: Shape, + label: Label, + root: Root +}; + +/** + * Creates a new model element of the specified type + * + * @method create + * + * @example + * + * var shape1 = Model.create('shape', { x: 10, y: 10, width: 100, height: 100 }); + * var shape2 = Model.create('shape', { x: 210, y: 210, width: 100, height: 100 }); + * + * var connection = Model.create('connection', { waypoints: [ { x: 110, y: 55 }, {x: 210, y: 55 } ] }); + * + * @param {String} type lower-cased model name + * @param {Object} attrs attributes to initialize the new model instance with + * + * @return {Base} the new model instance + */ +function create(type, attrs) { + var Type = types[type]; + if (!Type) { + throw new Error('unknown type: <' + type + '>'); + } + return (0, _minDash.assign)(new Type(), attrs); +} + +},{"inherits":415,"min-dash":505,"object-refs":520}],383:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = KeyboardMove; + +var _minDash = require('min-dash'); + +var DEFAULT_CONFIG = { + moveSpeed: 50, + moveSpeedAccelerated: 200 +}; + +/** + * A feature that allows users to move the canvas using the keyboard. + * + * @param {Object} config + * @param {Number} [config.moveSpeed=50] + * @param {Number} [config.moveSpeedAccelerated=200] + * @param {Keyboard} keyboard + * @param {Canvas} canvas + */ +function KeyboardMove(config, keyboard, canvas) { + + var self = this; + + this._config = (0, _minDash.assign)({}, DEFAULT_CONFIG, config || {}); + + keyboard.addListener(arrowsListener); + + function arrowsListener(context) { + + var event = context.keyEvent, + config = self._config; + + if (!keyboard.isCmd(event)) { + return; + } + + if (keyboard.isKey(['ArrowLeft', 'Left', 'ArrowUp', 'Up', 'ArrowDown', 'Down', 'ArrowRight', 'Right'], event)) { + + var speed = keyboard.isShift(event) ? config.moveSpeedAccelerated : config.moveSpeed; + + var direction; + + switch (event.key) { + case 'ArrowLeft': + case 'Left': + direction = 'left'; + break; + case 'ArrowUp': + case 'Up': + direction = 'up'; + break; + case 'ArrowRight': + case 'Right': + direction = 'right'; + break; + case 'ArrowDown': + case 'Down': + direction = 'down'; + break; + } + + self.moveCanvas({ + speed: speed, + direction: direction + }); + + return true; + } + } + + this.moveCanvas = function (opts) { + + var dx = 0, + dy = 0, + speed = opts.speed; + + var actualSpeed = speed / Math.min(Math.sqrt(canvas.viewbox().scale), 1); + + switch (opts.direction) { + case 'left': + // Left + dx = actualSpeed; + break; + case 'up': + // Up + dy = actualSpeed; + break; + case 'right': + // Right + dx = -actualSpeed; + break; + case 'down': + // Down + dy = -actualSpeed; + break; + } + + canvas.scroll({ + dx: dx, + dy: dy + }); + }; +} + +KeyboardMove.$inject = ['config.keyboardMove', 'keyboard', 'canvas']; + +},{"min-dash":505}],384:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _keyboard = require('../../features/keyboard'); + +var _keyboard2 = _interopRequireDefault(_keyboard); + +var _KeyboardMove = require('./KeyboardMove'); + +var _KeyboardMove2 = _interopRequireDefault(_KeyboardMove); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __depends__: [_keyboard2.default], + __init__: ['keyboardMove'], + keyboardMove: ['type', _KeyboardMove2.default] +}; + +},{"../../features/keyboard":300,"./KeyboardMove":383}],385:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = MoveCanvas; + +var _Cursor = require('../../util/Cursor'); + +var _ClickTrap = require('../../util/ClickTrap'); + +var _PositionUtil = require('../../util/PositionUtil'); + +var _minDom = require('min-dom'); + +var _Event = require('../../util/Event'); + +var THRESHOLD = 15; + +/** + * Move the canvas via mouse. + * + * @param {EventBus} eventBus + * @param {Canvas} canvas + */ +function MoveCanvas(eventBus, canvas) { + + var context; + + // listen for move on element mouse down; + // allow others to hook into the event before us though + // (dragging / element moving will do this) + eventBus.on('element.mousedown', 500, function (e) { + return handleStart(e.originalEvent); + }); + + function handleMove(event) { + + var start = context.start, + position = (0, _Event.toPoint)(event), + delta = (0, _PositionUtil.delta)(position, start); + + if (!context.dragging && length(delta) > THRESHOLD) { + context.dragging = true; + + (0, _ClickTrap.install)(eventBus); + + (0, _Cursor.set)('grab'); + } + + if (context.dragging) { + + var lastPosition = context.last || context.start; + + delta = (0, _PositionUtil.delta)(position, lastPosition); + + canvas.scroll({ + dx: delta.x, + dy: delta.y + }); + + context.last = position; + } + + // prevent select + event.preventDefault(); + } + + function handleEnd(event) { + _minDom.event.unbind(document, 'mousemove', handleMove); + _minDom.event.unbind(document, 'mouseup', handleEnd); + + context = null; + + (0, _Cursor.unset)(); + } + + function handleStart(event) { + // event is already handled by '.djs-draggable' + if ((0, _minDom.closest)(event.target, '.djs-draggable')) { + return; + } + + // reject non-left left mouse button or modifier key + if (event.button || event.ctrlKey || event.shiftKey || event.altKey) { + return; + } + + context = { + start: (0, _Event.toPoint)(event) + }; + + _minDom.event.bind(document, 'mousemove', handleMove); + _minDom.event.bind(document, 'mouseup', handleEnd); + + // we've handled the event + return true; + } +} + +MoveCanvas.$inject = ['eventBus', 'canvas']; + +// helpers /////// + +function length(point) { + return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2)); +} + +},{"../../util/ClickTrap":392,"../../util/Cursor":395,"../../util/Event":397,"../../util/PositionUtil":405,"min-dom":506}],386:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _MoveCanvas = require('./MoveCanvas'); + +var _MoveCanvas2 = _interopRequireDefault(_MoveCanvas); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __init__: ['moveCanvas'], + moveCanvas: ['type', _MoveCanvas2.default] +}; + +},{"./MoveCanvas":385}],387:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _touch = require('../../features/touch'); + +var _touch2 = _interopRequireDefault(_touch); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __depends__: [_touch2.default] +}; + +},{"../../features/touch":375}],388:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = ZoomScroll; + +var _minDom = require('min-dom'); + +var _ZoomUtil = require('./ZoomUtil'); + +var _Math = require('../../util/Math'); + +var _minDash = require('min-dash'); + +var sign = Math.sign || function (n) { + return n >= 0 ? 1 : -1; +}; + +var RANGE = { min: 0.2, max: 4 }, + NUM_STEPS = 10; + +var DELTA_THRESHOLD = 0.1; + +var DEFAULT_SCALE = 0.75; + +/** + * An implementation of zooming and scrolling within the + * {@link Canvas} via the mouse wheel. + * + * Mouse wheel zooming / scrolling may be disabled using + * the {@link toggle(enabled)} method. + * + * @param {Object} [config] + * @param {Boolean} [config.enabled=true] default enabled state + * @param {Number} [config.scale=.75] scroll sensivity + * @param {EventBus} eventBus + * @param {Canvas} canvas + */ +function ZoomScroll(config, eventBus, canvas) { + + config = config || {}; + + this._enabled = false; + + this._canvas = canvas; + this._container = canvas._container; + + this._handleWheel = (0, _minDash.bind)(this._handleWheel, this); + + this._totalDelta = 0; + this._scale = config.scale || DEFAULT_SCALE; + + var self = this; + + eventBus.on('canvas.init', function (e) { + self._init(config.enabled !== false); + }); +} + +ZoomScroll.$inject = ['config.zoomScroll', 'eventBus', 'canvas']; + +ZoomScroll.prototype.scroll = function scroll(delta) { + this._canvas.scroll(delta); +}; + +ZoomScroll.prototype.reset = function reset() { + this._canvas.zoom('fit-viewport'); +}; + +/** + * Zoom depending on delta. + * + * @param {number} delta - Zoom delta. + * @param {Object} position - Zoom position. + */ +ZoomScroll.prototype.zoom = function zoom(delta, position) { + + // zoom with half the step size of stepZoom + var stepSize = (0, _ZoomUtil.getStepSize)(RANGE, NUM_STEPS * 2); + + // add until threshold reached + this._totalDelta += delta; + + if (Math.abs(this._totalDelta) > DELTA_THRESHOLD) { + this._zoom(delta, position, stepSize); + + // reset + this._totalDelta = 0; + } +}; + +ZoomScroll.prototype._handleWheel = function handleWheel(event) { + // event is already handled by '.djs-scrollable' + if ((0, _minDom.closest)(event.target, '.djs-scrollable', true)) { + return; + } + + var element = this._container; + + event.preventDefault(); + + // pinch to zoom is mapped to wheel + ctrlKey = true + // in modern browsers (!) + + var isZoom = event.ctrlKey; + + var isHorizontalScroll = event.shiftKey; + + var factor = -1 * this._scale, + delta; + + if (isZoom) { + factor *= event.deltaMode === 0 ? 0.020 : 0.32; + } else { + factor *= event.deltaMode === 0 ? 1.0 : 16.0; + } + + if (isZoom) { + var elementRect = element.getBoundingClientRect(); + + var offset = { + x: event.clientX - elementRect.left, + y: event.clientY - elementRect.top + }; + + delta = Math.sqrt(Math.pow(event.deltaY, 2) + Math.pow(event.deltaX, 2)) * sign(event.deltaY) * factor; + + // zoom in relative to diagram {x,y} coordinates + this.zoom(delta, offset); + } else { + + if (isHorizontalScroll) { + delta = { + dx: factor * event.deltaY, + dy: 0 + }; + } else { + delta = { + dx: factor * event.deltaX, + dy: factor * event.deltaY + }; + } + + this.scroll(delta); + } +}; + +/** + * Zoom with fixed step size. + * + * @param {number} delta - Zoom delta (1 for zooming in, -1 for out). + * @param {Object} position - Zoom position. + */ +ZoomScroll.prototype.stepZoom = function stepZoom(delta, position) { + + var stepSize = (0, _ZoomUtil.getStepSize)(RANGE, NUM_STEPS); + + this._zoom(delta, position, stepSize); +}; + +/** + * Zoom in/out given a step size. + * + * @param {number} delta - Zoom delta. Can be positive or negative. + * @param {Object} position - Zoom position. + * @param {number} stepSize - Step size. + */ +ZoomScroll.prototype._zoom = function (delta, position, stepSize) { + var canvas = this._canvas; + + var direction = delta > 0 ? 1 : -1; + + var currentLinearZoomLevel = (0, _Math.log10)(canvas.zoom()); + + // snap to a proximate zoom step + var newLinearZoomLevel = Math.round(currentLinearZoomLevel / stepSize) * stepSize; + + // increase or decrease one zoom step in the given direction + newLinearZoomLevel += stepSize * direction; + + // calculate the absolute logarithmic zoom level based on the linear zoom level + // (e.g. 2 for an absolute x2 zoom) + var newLogZoomLevel = Math.pow(10, newLinearZoomLevel); + + canvas.zoom((0, _ZoomUtil.cap)(RANGE, newLogZoomLevel), position); +}; + +/** + * Toggle the zoom scroll ability via mouse wheel. + * + * @param {Boolean} [newEnabled] new enabled state + */ +ZoomScroll.prototype.toggle = function toggle(newEnabled) { + + var element = this._container; + var handleWheel = this._handleWheel; + + var oldEnabled = this._enabled; + + if (typeof newEnabled === 'undefined') { + newEnabled = !oldEnabled; + } + + // only react on actual changes + if (oldEnabled !== newEnabled) { + + // add or remove wheel listener based on + // changed enabled state + _minDom.event[newEnabled ? 'bind' : 'unbind'](element, 'wheel', handleWheel, false); + } + + this._enabled = newEnabled; + + return newEnabled; +}; + +ZoomScroll.prototype._init = function (newEnabled) { + this.toggle(newEnabled); +}; + +},{"../../util/Math":402,"./ZoomUtil":389,"min-dash":505,"min-dom":506}],389:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getStepSize = getStepSize; +exports.cap = cap; + +var _Math = require('../../util/Math'); + +/** + * Get step size for given range and number of steps. + * + * @param {Object} range - Range. + * @param {number} range.min - Range minimum. + * @param {number} range.max - Range maximum. + */ +function getStepSize(range, steps) { + + var minLinearRange = (0, _Math.log10)(range.min), + maxLinearRange = (0, _Math.log10)(range.max); + + var absoluteLinearRange = Math.abs(minLinearRange) + Math.abs(maxLinearRange); + + return absoluteLinearRange / steps; +} + +function cap(range, scale) { + return Math.max(range.min, Math.min(range.max, scale)); +} + +},{"../../util/Math":402}],390:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _ZoomScroll = require('./ZoomScroll'); + +var _ZoomScroll2 = _interopRequireDefault(_ZoomScroll); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + __init__: ['zoomScroll'], + zoomScroll: ['type', _ZoomScroll2.default] +}; + +},{"./ZoomScroll":388}],391:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getNewAttachPoint = getNewAttachPoint; +exports.getNewAttachShapeDelta = getNewAttachShapeDelta; + +var _LayoutUtil = require('../layout/LayoutUtil'); + +var _PositionUtil = require('./PositionUtil'); + +/** + * Calculates the absolute point relative to the new element's position + * + * @param {point} point [absolute] + * @param {bounds} oldBounds + * @param {bounds} newBounds + * + * @return {point} point [absolute] + */ +function getNewAttachPoint(point, oldBounds, newBounds) { + var oldCenter = (0, _PositionUtil.center)(oldBounds), + newCenter = (0, _PositionUtil.center)(newBounds), + oldDelta = (0, _PositionUtil.delta)(point, oldCenter); + + var newDelta = { + x: oldDelta.x * (newBounds.width / oldBounds.width), + y: oldDelta.y * (newBounds.height / oldBounds.height) + }; + + return (0, _LayoutUtil.roundPoint)({ + x: newCenter.x + newDelta.x, + y: newCenter.y + newDelta.y + }); +} + +/** + * Calculates the shape's delta relative to a new position + * of a certain element's bounds + * + * @param {djs.model.Shape} point [absolute] + * @param {bounds} oldBounds + * @param {bounds} newBounds + * + * @return {delta} delta + */ +function getNewAttachShapeDelta(shape, oldBounds, newBounds) { + var shapeCenter = (0, _PositionUtil.center)(shape), + oldCenter = (0, _PositionUtil.center)(oldBounds), + newCenter = (0, _PositionUtil.center)(newBounds), + shapeDelta = (0, _PositionUtil.delta)(shape, shapeCenter), + oldCenterDelta = (0, _PositionUtil.delta)(shapeCenter, oldCenter); + + var newCenterDelta = { + x: oldCenterDelta.x * (newBounds.width / oldBounds.width), + y: oldCenterDelta.y * (newBounds.height / oldBounds.height) + }; + + var newShapeCenter = { + x: newCenter.x + newCenterDelta.x, + y: newCenter.y + newCenterDelta.y + }; + + return (0, _LayoutUtil.roundPoint)({ + x: newShapeCenter.x + shapeDelta.x - shape.x, + y: newShapeCenter.y + shapeDelta.y - shape.y + }); +} + +},{"../layout/LayoutUtil":380,"./PositionUtil":405}],392:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.install = install; +var TRAP_PRIORITY = 5000; + +/** + * Installs a click trap that prevents a ghost click following a dragging operation. + * + * @return {Function} a function to immediately remove the installed trap. + */ +function install(eventBus, eventName) { + + eventName = eventName || 'element.click'; + + function trap() { + return false; + } + + eventBus.once(eventName, TRAP_PRIORITY, trap); + + return function () { + eventBus.off(eventName, trap); + }; +} + +},{}],393:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.remove = remove; +exports.add = add; +exports.indexOf = indexOf; +/** + * Failsafe remove an element from a collection + * + * @param {Array} [collection] + * @param {Object} [element] + * + * @return {Number} the previous index of the element + */ +function remove(collection, element) { + + if (!collection || !element) { + return -1; + } + + var idx = collection.indexOf(element); + + if (idx !== -1) { + collection.splice(idx, 1); + } + + return idx; +} + +/** + * Fail save add an element to the given connection, ensuring + * it does not yet exist. + * + * @param {Array} collection + * @param {Object} element + * @param {Number} idx + */ +function add(collection, element, idx) { + + if (!collection || !element) { + return; + } + + if (typeof idx !== 'number') { + idx = -1; + } + + var currentIdx = collection.indexOf(element); + + if (currentIdx !== -1) { + + if (currentIdx === idx) { + // nothing to do, position has not changed + return; + } else { + + if (idx !== -1) { + // remove from current position + collection.splice(currentIdx, 1); + } else { + // already exists in collection + return; + } + } + } + + if (idx !== -1) { + // insert at specified position + collection.splice(idx, 0, element); + } else { + // push to end + collection.push(element); + } +} + +/** + * Fail save get the index of an element in a collection. + * + * @param {Array} collection + * @param {Object} element + * + * @return {Number} the index or -1 if collection or element do + * not exist or the element is not contained. + */ +function indexOf(collection, element) { + + if (!collection || !element) { + return -1; + } + + return collection.indexOf(element); +} + +},{}],394:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getTopLevel = getTopLevel; + +var _minDash = require('min-dash'); + +function getTopLevel(elements) { + var topLevel = {}, + parents = [], + result = [], + clearedParents = []; + + (0, _minDash.forEach)(elements, function (element) { + var parent = element.parent; + + if (!topLevel[parent.id]) { + topLevel[parent.id] = []; + } + + if (parents.indexOf(parent.id) === -1) { + parents.push(parent.id); + } + + topLevel[parent.id].push(element); + }); + + (0, _minDash.forEach)(parents, function (parent) { + (0, _minDash.forEach)(topLevel[parent], function (element) { + if (topLevel[element.id]) { + clearedParents.push(element.id); + } + }); + }); + + (0, _minDash.forEach)(parents, function (parent) { + var idx = clearedParents.indexOf(parent); + + if (idx === -1) { + result = result.concat(topLevel[parent]); + } + }); + + return result; +} + +},{"min-dash":505}],395:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.set = set; +exports.unset = unset; +exports.has = has; + +var _minDom = require('min-dom'); + +var CURSOR_CLS_PATTERN = /^djs-cursor-.*$/; + +function set(mode) { + var classes = (0, _minDom.classes)(document.body); + + classes.removeMatching(CURSOR_CLS_PATTERN); + + if (mode) { + classes.add('djs-cursor-' + mode); + } +} + +function unset() { + set(null); +} + +function has(mode) { + var classes = (0, _minDom.classes)(document.body); + + return classes.has('djs-cursor-' + mode); +} + +},{"min-dom":506}],396:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.add = add; +exports.eachElement = eachElement; +exports.selfAndChildren = selfAndChildren; +exports.selfAndDirectChildren = selfAndDirectChildren; +exports.selfAndAllChildren = selfAndAllChildren; +exports.getClosure = getClosure; +exports.getBBox = getBBox; +exports.getEnclosedElements = getEnclosedElements; +exports.getType = getType; + +var _minDash = require('min-dash'); + +/** + * Adds an element to a collection and returns true if the + * element was added. + * + * @param {Array} elements + * @param {Object} e + * @param {Boolean} unique + */ +function add(elements, e, unique) { + var canAdd = !unique || elements.indexOf(e) === -1; + + if (canAdd) { + elements.push(e); + } + + return canAdd; +} + +/** + * Iterate over each element in a collection, calling the iterator function `fn` + * with (element, index, recursionDepth). + * + * Recurse into all elements that are returned by `fn`. + * + * @param {Object|Array} elements + * @param {Function} fn iterator function called with (element, index, recursionDepth) + * @param {Number} [depth] maximum recursion depth + */ +function eachElement(elements, fn, depth) { + + depth = depth || 0; + + if (!(0, _minDash.isArray)(elements)) { + elements = [elements]; + } + + (0, _minDash.forEach)(elements, function (s, i) { + var filter = fn(s, i, depth); + + if ((0, _minDash.isArray)(filter) && filter.length) { + eachElement(filter, fn, depth + 1); + } + }); +} + +/** + * Collects self + child elements up to a given depth from a list of elements. + * + * @param {djs.model.Base|Array} elements the elements to select the children from + * @param {Boolean} unique whether to return a unique result set (no duplicates) + * @param {Number} maxDepth the depth to search through or -1 for infinite + * + * @return {Array} found elements + */ +function selfAndChildren(elements, unique, maxDepth) { + var result = [], + processedChildren = []; + + eachElement(elements, function (element, i, depth) { + add(result, element, unique); + + var children = element.children; + + // max traversal depth not reached yet + if (maxDepth === -1 || depth < maxDepth) { + + // children exist && children not yet processed + if (children && add(processedChildren, children, unique)) { + return children; + } + } + }); + + return result; +} + +/** + * Return self + direct children for a number of elements + * + * @param {Array} elements to query + * @param {Boolean} allowDuplicates to allow duplicates in the result set + * + * @return {Array} the collected elements + */ +function selfAndDirectChildren(elements, allowDuplicates) { + return selfAndChildren(elements, !allowDuplicates, 1); +} + +/** + * Return self + ALL children for a number of elements + * + * @param {Array} elements to query + * @param {Boolean} allowDuplicates to allow duplicates in the result set + * + * @return {Array} the collected elements + */ +function selfAndAllChildren(elements, allowDuplicates) { + return selfAndChildren(elements, !allowDuplicates, -1); +} + +/** + * Gets the the closure for all selected elements, + * their enclosed children and connections. + * + * @param {Array} elements + * @param {Boolean} [isTopLevel=true] + * @param {Object} [existingClosure] + * + * @return {Object} newClosure + */ +function getClosure(elements, isTopLevel, closure) { + + if ((0, _minDash.isUndefined)(isTopLevel)) { + isTopLevel = true; + } + + if ((0, _minDash.isObject)(isTopLevel)) { + closure = isTopLevel; + isTopLevel = true; + } + + closure = closure || {}; + + var allShapes = copyObject(closure.allShapes), + allConnections = copyObject(closure.allConnections), + enclosedElements = copyObject(closure.enclosedElements), + enclosedConnections = copyObject(closure.enclosedConnections); + + var topLevel = copyObject(closure.topLevel, isTopLevel && (0, _minDash.groupBy)(elements, function (e) { + return e.id; + })); + + function handleConnection(c) { + if (topLevel[c.source.id] && topLevel[c.target.id]) { + topLevel[c.id] = [c]; + } + + // not enclosed as a child, but maybe logically + // (connecting two moved elements?) + if (allShapes[c.source.id] && allShapes[c.target.id]) { + enclosedConnections[c.id] = enclosedElements[c.id] = c; + } + + allConnections[c.id] = c; + } + + function handleElement(element) { + + enclosedElements[element.id] = element; + + if (element.waypoints) { + // remember connection + enclosedConnections[element.id] = allConnections[element.id] = element; + } else { + // remember shape + allShapes[element.id] = element; + + // remember all connections + (0, _minDash.forEach)(element.incoming, handleConnection); + + (0, _minDash.forEach)(element.outgoing, handleConnection); + + // recurse into children + return element.children; + } + } + + eachElement(elements, handleElement); + + return { + allShapes: allShapes, + allConnections: allConnections, + topLevel: topLevel, + enclosedConnections: enclosedConnections, + enclosedElements: enclosedElements + }; +} + +/** + * Returns the surrounding bbox for all elements in + * the array or the element primitive. + * + * @param {Array|djs.model.Shape} elements + * @param {Boolean} stopRecursion + */ +function getBBox(elements, stopRecursion) { + + stopRecursion = !!stopRecursion; + if (!(0, _minDash.isArray)(elements)) { + elements = [elements]; + } + + var minX, minY, maxX, maxY; + + (0, _minDash.forEach)(elements, function (element) { + + // If element is a connection the bbox must be computed first + var bbox = element; + if (element.waypoints && !stopRecursion) { + bbox = getBBox(element.waypoints, true); + } + + var x = bbox.x, + y = bbox.y, + height = bbox.height || 0, + width = bbox.width || 0; + + if (x < minX || minX === undefined) { + minX = x; + } + if (y < minY || minY === undefined) { + minY = y; + } + + if (x + width > maxX || maxX === undefined) { + maxX = x + width; + } + if (y + height > maxY || maxY === undefined) { + maxY = y + height; + } + }); + + return { + x: minX, + y: minY, + height: maxY - minY, + width: maxX - minX + }; +} + +/** + * Returns all elements that are enclosed from the bounding box. + * + * * If bbox.(width|height) is not specified the method returns + * all elements with element.x/y > bbox.x/y + * * If only bbox.x or bbox.y is specified, method return all elements with + * e.x > bbox.x or e.y > bbox.y + * + * @param {Array} elements List of Elements to search through + * @param {djs.model.Shape} bbox the enclosing bbox. + * + * @return {Array} enclosed elements + */ +function getEnclosedElements(elements, bbox) { + + var filteredElements = {}; + + (0, _minDash.forEach)(elements, function (element) { + + var e = element; + + if (e.waypoints) { + e = getBBox(e); + } + + if (!(0, _minDash.isNumber)(bbox.y) && e.x > bbox.x) { + filteredElements[element.id] = element; + } + if (!(0, _minDash.isNumber)(bbox.x) && e.y > bbox.y) { + filteredElements[element.id] = element; + } + if (e.x > bbox.x && e.y > bbox.y) { + if ((0, _minDash.isNumber)(bbox.width) && (0, _minDash.isNumber)(bbox.height) && e.width + e.x < bbox.width + bbox.x && e.height + e.y < bbox.height + bbox.y) { + + filteredElements[element.id] = element; + } else if (!(0, _minDash.isNumber)(bbox.width) || !(0, _minDash.isNumber)(bbox.height)) { + filteredElements[element.id] = element; + } + } + }); + + return filteredElements; +} + +function getType(element) { + + if ('waypoints' in element) { + return 'connection'; + } + + if ('x' in element) { + return 'shape'; + } + + return 'root'; +} + +// helpers /////////////////////////////// + +function copyObject(src1, src2) { + return (0, _minDash.assign)({}, src1 || {}, src2 || {}); +} + +},{"min-dash":505}],397:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getOriginal = getOriginal; +exports.stopPropagation = stopPropagation; +exports.toPoint = toPoint; +function __stopPropagation(event) { + if (!event || typeof event.stopPropagation !== 'function') { + return; + } + + event.stopPropagation(); +} + +function getOriginal(event) { + return event.originalEvent || event.srcEvent; +} + +function stopPropagation(event, immediate) { + __stopPropagation(event, immediate); + __stopPropagation(getOriginal(event), immediate); +} + +function toPoint(event) { + + if (event.pointers && event.pointers.length) { + event = event.pointers[0]; + } + + if (event.touches && event.touches.length) { + event = event.touches[0]; + } + + return event ? { + x: event.clientX, + y: event.clientY + } : null; +} + +},{}],398:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.pointDistance = pointDistance; +exports.pointsOnLine = pointsOnLine; +exports.pointsAligned = pointsAligned; +exports.pointInRect = pointInRect; +exports.getMidPoint = getMidPoint; +/** + * Computes the distance between two points + * + * @param {Point} p + * @param {Point} q + * + * @return {Number} distance + */ +function pointDistance(a, b) { + if (!a || !b) { + return -1; + } + + return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); +} + +/** + * Returns true if the point r is on the line between p and q + * + * @param {Point} p + * @param {Point} q + * @param {Point} r + * @param {Number} [accuracy=5] accuracy for points on line check (lower is better) + * + * @return {Boolean} + */ +function pointsOnLine(p, q, r, accuracy) { + + if (typeof accuracy === 'undefined') { + accuracy = 5; + } + + if (!p || !q || !r) { + return false; + } + + var val = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x), + dist = pointDistance(p, q); + + // @see http://stackoverflow.com/a/907491/412190 + return Math.abs(val / dist) <= accuracy; +} + +var ALIGNED_THRESHOLD = 2; + +/** + * Returns whether two points are in a horizontal or vertical line. + * + * @param {Point} a + * @param {Point} b + * + * @return {String|Boolean} returns false if the points are not + * aligned or 'h|v' if they are aligned + * horizontally / vertically. + */ +function pointsAligned(a, b) { + if (Math.abs(a.x - b.x) <= ALIGNED_THRESHOLD) { + return 'h'; + } + + if (Math.abs(a.y - b.y) <= ALIGNED_THRESHOLD) { + return 'v'; + } + + return false; +} + +/** + * Returns true if the point p is inside the rectangle rect + * + * @param {Point} p + * @param {Rect} rect + * @param {Number} tolerance + * + * @return {Boolean} + */ +function pointInRect(p, rect, tolerance) { + tolerance = tolerance || 0; + + return p.x > rect.x - tolerance && p.y > rect.y - tolerance && p.x < rect.x + rect.width + tolerance && p.y < rect.y + rect.height + tolerance; +} + +/** + * Returns a point in the middle of points p and q + * + * @param {Point} p + * @param {Point} q + * + * @return {Point} middle point + */ +function getMidPoint(p, q) { + return { + x: Math.round(p.x + (q.x - p.x) / 2.0), + y: Math.round(p.y + (q.y - p.y) / 2.0) + }; +} + +},{}],399:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getVisual = getVisual; +exports.getChildren = getChildren; + +var _minDom = require('min-dom'); + +/** + * SVGs for elements are generated by the {@link GraphicsFactory}. + * + * This utility gives quick access to the important semantic + * parts of an element. + */ + +/** + * Returns the visual part of a diagram element + * + * @param {Snap} gfx + * + * @return {Snap} + */ +function getVisual(gfx) { + return (0, _minDom.query)('.djs-visual', gfx); +} + +/** + * Returns the children for a given diagram element. + * + * @param {Snap} gfx + * @return {Snap} + */ +function getChildren(gfx) { + return gfx.parentNode.childNodes[1]; +} + +},{"min-dom":506}],400:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = IdGenerator; +/** + * Util that provides unique IDs. + * + * @class djs.util.IdGenerator + * @constructor + * @memberOf djs.util + * + * The ids can be customized via a given prefix and contain a random value to avoid collisions. + * + * @param {String} prefix a prefix to prepend to generated ids (for better readability) + */ +function IdGenerator(prefix) { + + this._counter = 0; + this._prefix = (prefix ? prefix + '-' : '') + Math.floor(Math.random() * 1000000000) + '-'; +} + +/** + * Returns a next unique ID. + * + * @method djs.util.IdGenerator#next + * + * @returns {String} the id + */ +IdGenerator.prototype.next = function () { + return this._prefix + ++this._counter; +}; + +},{}],401:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getApproxIntersection = getApproxIntersection; + +var _Geometry = require('./Geometry'); + +var _pathIntersection = require('path-intersection'); + +var _pathIntersection2 = _interopRequireDefault(_pathIntersection); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var round = Math.round, + max = Math.max; + +function circlePath(center, r) { + var x = center.x, + y = center.y; + + return [['M', x, y], ['m', 0, -r], ['a', r, r, 0, 1, 1, 0, 2 * r], ['a', r, r, 0, 1, 1, 0, -2 * r], ['z']]; +} + +function linePath(points) { + var segments = []; + + points.forEach(function (p, idx) { + segments.push([idx === 0 ? 'M' : 'L', p.x, p.y]); + }); + + return segments; +} + +var INTERSECTION_THRESHOLD = 10; + +function getBendpointIntersection(waypoints, reference) { + + var i, w; + + for (i = 0; w = waypoints[i]; i++) { + + if ((0, _Geometry.pointDistance)(w, reference) <= INTERSECTION_THRESHOLD) { + return { + point: waypoints[i], + bendpoint: true, + index: i + }; + } + } + + return null; +} + +function getPathIntersection(waypoints, reference) { + + var intersections = (0, _pathIntersection2.default)(circlePath(reference, INTERSECTION_THRESHOLD), linePath(waypoints)); + + var a = intersections[0], + b = intersections[intersections.length - 1], + idx; + + if (!a) { + // no intersection + return null; + } + + if (a !== b) { + + if (a.segment2 !== b.segment2) { + // we use the bendpoint in between both segments + // as the intersection point + + idx = max(a.segment2, b.segment2) - 1; + + return { + point: waypoints[idx], + bendpoint: true, + index: idx + }; + } + + return { + point: { + x: round(a.x + b.x) / 2, + y: round(a.y + b.y) / 2 + }, + index: a.segment2 + }; + } + + return { + point: { + x: round(a.x), + y: round(a.y) + }, + index: a.segment2 + }; +} + +/** + * Returns the closest point on the connection towards a given reference point. + * + * @param {Array} waypoints + * @param {Point} reference + * + * @return {Object} intersection data (segment, point) + */ +function getApproxIntersection(waypoints, reference) { + return getBendpointIntersection(waypoints, reference) || getPathIntersection(waypoints, reference); +} + +},{"./Geometry":398,"path-intersection":523}],402:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.log10 = log10; + +var _PositionUtil = require('./PositionUtil'); + +Object.defineProperty(exports, 'substract', { + enumerable: true, + get: function get() { + return _PositionUtil.delta; + } +}); +/** + * Get the logarithm of x with base 10 + * @param {Integer} value + */ +function log10(x) { + return Math.log(x) / Math.log(10); +} + +},{"./PositionUtil":405}],403:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isMac = undefined; + +var _Platform = require('./Platform'); + +Object.defineProperty(exports, 'isMac', { + enumerable: true, + get: function get() { + return _Platform.isMac; + } +}); +exports.isPrimaryButton = isPrimaryButton; +exports.hasPrimaryModifier = hasPrimaryModifier; +exports.hasSecondaryModifier = hasSecondaryModifier; + +var _Event = require('./Event'); + +function isPrimaryButton(event) { + // button === 0 -> left áka primary mouse button + return !((0, _Event.getOriginal)(event) || event).button; +} + +function hasPrimaryModifier(event) { + var originalEvent = (0, _Event.getOriginal)(event) || event; + + if (!isPrimaryButton(event)) { + return false; + } + + // Use alt as primary modifier key for mac OS + if ((0, _Platform.isMac)()) { + return originalEvent.metaKey; + } else { + return originalEvent.ctrlKey; + } +} + +function hasSecondaryModifier(event) { + var originalEvent = (0, _Event.getOriginal)(event) || event; + + return isPrimaryButton(event) && originalEvent.shiftKey; +} + +},{"./Event":397,"./Platform":404}],404:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isMac = isMac; +function isMac() { + return (/mac/i.test(navigator.platform) + ); +} + +},{}],405:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.center = center; +exports.delta = delta; +function center(bounds) { + return { + x: bounds.x + bounds.width / 2, + y: bounds.y + bounds.height / 2 + }; +} + +function delta(a, b) { + return { + x: a.x - b.x, + y: a.y - b.y + }; +} + +},{}],406:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.saveClear = saveClear; +/** + * Remove from the beginning of a collection until it is empty. + * + * This is a null-safe operation that ensures elements + * are being removed from the given collection until the + * collection is empty. + * + * The implementation deals with the fact that a remove operation + * may touch, i.e. remove multiple elements in the collection + * at a time. + * + * @param {Array} [collection] + * @param {Function} removeFn + * + * @return {Array} the cleared collection + */ +function saveClear(collection, removeFn) { + + if (typeof removeFn !== 'function') { + throw new Error('removeFn iterator must be a function'); + } + + if (!collection) { + return; + } + + var e; + + while (e = collection[0]) { + removeFn(e); + } + + return collection; +} + +},{}],407:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.componentsToPath = componentsToPath; +exports.toSVGPoints = toSVGPoints; +exports.createLine = createLine; +exports.updateLine = updateLine; + +var _tinySvg = require('tiny-svg'); + +function componentsToPath(elements) { + return elements.join(',').replace(/,?([A-z]),?/g, '$1'); +} + +function toSVGPoints(points) { + var result = ''; + + for (var i = 0, p; p = points[i]; i++) { + result += p.x + ',' + p.y + ' '; + } + + return result; +} + +function createLine(points, attrs) { + + var line = (0, _tinySvg.create)('polyline'); + (0, _tinySvg.attr)(line, { points: toSVGPoints(points) }); + + if (attrs) { + (0, _tinySvg.attr)(line, attrs); + } + + return line; +} + +function updateLine(gfx, points) { + (0, _tinySvg.attr)(gfx, { points: toSVGPoints(points) }); + + return gfx; +} + +},{"tiny-svg":535}],408:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transform = transform; +exports.translate = translate; +exports.rotate = rotate; +exports.scale = scale; + +var _tinySvg = require('tiny-svg'); + +/** + * @param {} element + * @param {Number} x + * @param {Number} y + * @param {Number} angle + * @param {Number} amount + */ +function transform(gfx, x, y, angle, amount) { + var translate = (0, _tinySvg.createTransform)(); + translate.setTranslate(x, y); + + var rotate = (0, _tinySvg.createTransform)(); + rotate.setRotate(angle, 0, 0); + + var scale = (0, _tinySvg.createTransform)(); + scale.setScale(amount || 1, amount || 1); + + (0, _tinySvg.transform)(gfx, [translate, rotate, scale]); +} + +/** + * @param {SVGElement} element + * @param {Number} x + * @param {Number} y + */ +function translate(gfx, x, y) { + var translate = (0, _tinySvg.createTransform)(); + translate.setTranslate(x, y); + + (0, _tinySvg.transform)(gfx, translate); +} + +/** + * @param {SVGElement} element + * @param {Number} angle + */ +function rotate(gfx, angle) { + var rotate = (0, _tinySvg.createTransform)(); + rotate.setRotate(angle, 0, 0); + + (0, _tinySvg.transform)(gfx, rotate); +} + +/** + * @param {SVGElement} element + * @param {Number} amount + */ +function scale(gfx, amount) { + var scale = (0, _tinySvg.createTransform)(); + scale.setScale(amount, amount); + + (0, _tinySvg.transform)(gfx, scale); +} + +},{"tiny-svg":535}],409:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = Text; + +var _minDash = require('min-dash'); + +var _tinySvg = require('tiny-svg'); + +var DEFAULT_BOX_PADDING = 0; + +var DEFAULT_LABEL_SIZE = { + width: 150, + height: 50 +}; + +function parseAlign(align) { + + var parts = align.split('-'); + + return { + horizontal: parts[0] || 'center', + vertical: parts[1] || 'top' + }; +} + +function parsePadding(padding) { + + if ((0, _minDash.isObject)(padding)) { + return (0, _minDash.assign)({ top: 0, left: 0, right: 0, bottom: 0 }, padding); + } else { + return { + top: padding, + left: padding, + right: padding, + bottom: padding + }; + } +} + +function getTextBBox(text, fakeText) { + + fakeText.textContent = text; + + var textBBox; + + try { + var bbox, + emptyLine = text === ''; + + // add dummy text, when line is empty to + // determine correct height + fakeText.textContent = emptyLine ? 'dummy' : text; + + textBBox = fakeText.getBBox(); + + // take text rendering related horizontal + // padding into account + bbox = { + width: textBBox.width + textBBox.x * 2, + height: textBBox.height + }; + + if (emptyLine) { + // correct width + bbox.width = 0; + } + + return bbox; + } catch (e) { + return { width: 0, height: 0 }; + } +} + +/** + * Layout the next line and return the layouted element. + * + * Alters the lines passed. + * + * @param {Array} lines + * @return {Object} the line descriptor, an object { width, height, text } + */ +function layoutNext(lines, maxWidth, fakeText) { + + var originalLine = lines.shift(), + fitLine = originalLine; + + var textBBox; + + for (;;) { + textBBox = getTextBBox(fitLine, fakeText); + + textBBox.width = fitLine ? textBBox.width : 0; + + // try to fit + if (fitLine === ' ' || fitLine === '' || textBBox.width < Math.round(maxWidth) || fitLine.length < 2) { + return fit(lines, fitLine, originalLine, textBBox); + } + + fitLine = shortenLine(fitLine, textBBox.width, maxWidth); + } +} + +function fit(lines, fitLine, originalLine, textBBox) { + if (fitLine.length < originalLine.length) { + var remainder = originalLine.slice(fitLine.length).trim(); + + lines.unshift(remainder); + } + + return { + width: textBBox.width, + height: textBBox.height, + text: fitLine + }; +} + +/** + * Shortens a line based on spacing and hyphens. + * Returns the shortened result on success. + * + * @param {String} line + * @param {Number} maxLength the maximum characters of the string + * @return {String} the shortened string + */ +function semanticShorten(line, maxLength) { + var parts = line.split(/(\s|-)/g), + part, + shortenedParts = [], + length = 0; + + // try to shorten via spaces + hyphens + if (parts.length > 1) { + while (part = parts.shift()) { + if (part.length + length < maxLength) { + shortenedParts.push(part); + length += part.length; + } else { + // remove previous part, too if hyphen does not fit anymore + if (part === '-') { + shortenedParts.pop(); + } + + break; + } + } + } + + return shortenedParts.join(''); +} + +function shortenLine(line, width, maxWidth) { + var length = Math.max(line.length * (maxWidth / width), 1); + + // try to shorten semantically (i.e. based on spaces and hyphens) + var shortenedLine = semanticShorten(line, length); + + if (!shortenedLine) { + + // force shorten by cutting the long word + shortenedLine = line.slice(0, Math.max(Math.round(length - 1), 1)); + } + + return shortenedLine; +} + +function getHelperSvg() { + var helperSvg = document.getElementById('helper-svg'); + + if (!helperSvg) { + helperSvg = (0, _tinySvg.create)('svg'); + + (0, _tinySvg.attr)(helperSvg, { + id: 'helper-svg', + width: 0, + height: 0, + style: 'visibility: hidden; position: fixed' + }); + + document.body.appendChild(helperSvg); + } + + return helperSvg; +} + +/** + * Creates a new label utility + * + * @param {Object} config + * @param {Dimensions} config.size + * @param {Number} config.padding + * @param {Object} config.style + * @param {String} config.align + */ +function Text(config) { + + this._config = (0, _minDash.assign)({}, { + size: DEFAULT_LABEL_SIZE, + padding: DEFAULT_BOX_PADDING, + style: {}, + align: 'center-top' + }, config || {}); +} + +/** + * Returns the layouted text as an SVG element. + * + * @param {String} text + * @param {Object} options + * + * @return {SVGElement} + */ +Text.prototype.createText = function (text, options) { + return this.layoutText(text, options).element; +}; + +/** + * Returns a labels layouted dimensions. + * + * @param {String} text to layout + * @param {Object} options + * + * @return {Dimensions} + */ +Text.prototype.getDimensions = function (text, options) { + return this.layoutText(text, options).dimensions; +}; + +/** + * Creates and returns a label and its bounding box. + * + * @method Text#createText + * + * @param {String} text the text to render on the label + * @param {Object} options + * @param {String} options.align how to align in the bounding box. + * Any of { 'center-middle', 'center-top' }, + * defaults to 'center-top'. + * @param {String} options.style style to be applied to the text + * @param {boolean} options.fitBox indicates if box will be recalculated to + * fit text + * + * @return {Object} { element, dimensions } + */ +Text.prototype.layoutText = function (text, options) { + var box = (0, _minDash.assign)({}, this._config.size, options.box), + style = (0, _minDash.assign)({}, this._config.style, options.style), + align = parseAlign(options.align || this._config.align), + padding = parsePadding(options.padding !== undefined ? options.padding : this._config.padding), + fitBox = options.fitBox || false; + + var lineHeight = getLineHeight(style); + + var lines = text.split(/\r?\n/g), + layouted = []; + + var maxWidth = box.width - padding.left - padding.right; + + // ensure correct rendering by attaching helper text node to invisible SVG + var helperText = (0, _tinySvg.create)('text'); + (0, _tinySvg.attr)(helperText, { x: 0, y: 0 }); + (0, _tinySvg.attr)(helperText, style); + + var helperSvg = getHelperSvg(); + + (0, _tinySvg.append)(helperSvg, helperText); + + while (lines.length) { + layouted.push(layoutNext(lines, maxWidth, helperText)); + } + + if (align.vertical === 'middle') { + padding.top = padding.bottom = 0; + } + + var totalHeight = (0, _minDash.reduce)(layouted, function (sum, line, idx) { + return sum + (lineHeight || line.height); + }, 0) + padding.top + padding.bottom; + + var maxLineWidth = (0, _minDash.reduce)(layouted, function (sum, line, idx) { + return line.width > sum ? line.width : sum; + }, 0); + + // the y position of the next line + var y = padding.top; + + if (align.vertical === 'middle') { + y += (box.height - totalHeight) / 2; + } + + // magic number initial offset + y -= (lineHeight || layouted[0].height) / 4; + + var textElement = (0, _tinySvg.create)('text'); + + (0, _tinySvg.attr)(textElement, style); + + // layout each line taking into account that parent + // shape might resize to fit text size + (0, _minDash.forEach)(layouted, function (line) { + + var x; + + y += lineHeight || line.height; + + switch (align.horizontal) { + case 'left': + x = padding.left; + break; + + case 'right': + x = (fitBox ? maxLineWidth : maxWidth) - padding.right - line.width; + break; + + default: + // aka center + x = Math.max(((fitBox ? maxLineWidth : maxWidth) - line.width) / 2 + padding.left, 0); + } + + var tspan = (0, _tinySvg.create)('tspan'); + (0, _tinySvg.attr)(tspan, { x: x, y: y }); + + tspan.textContent = line.text; + + (0, _tinySvg.append)(textElement, tspan); + }); + + (0, _tinySvg.remove)(helperText); + + var dimensions = { + width: maxLineWidth, + height: totalHeight + }; + + return { + dimensions: dimensions, + element: textElement + }; +}; + +function getLineHeight(style) { + if ('fontSize' in style && 'lineHeight' in style) { + return style.lineHeight * parseInt(style.fontSize, 10); + } +} + +},{"min-dash":505,"tiny-svg":535}],410:[function(require,module,exports){ +'use strict'; + +var _typeof2 = 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; }; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var CLASS_PATTERN = /^class /; + +function isClass(fn) { + return CLASS_PATTERN.test(fn.toString()); +} + +function isArray(obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; +} + +function annotate() { + var args = Array.prototype.slice.call(arguments); + + if (args.length === 1 && isArray(args[0])) { + args = args[0]; + } + + var fn = args.pop(); + + fn.$inject = args; + + return fn; +} + +// Current limitations: +// - can't put into "function arg" comments +// function /* (no parenthesis like this) */ (){} +// function abc( /* xx (no parenthesis like this) */ a, b) {} +// +// Just put the comment before function or inside: +// /* (((this is fine))) */ function(a, b) {} +// function abc(a) { /* (((this is fine))) */} +// +// - can't reliably auto-annotate constructor; we'll match the +// first constructor(...) pattern found which may be the one +// of a nested class, too. + +var CONSTRUCTOR_ARGS = /constructor\s*[^(]*\(\s*([^)]*)\)/m; +var FN_ARGS = /^function\s*[^(]*\(\s*([^)]*)\)/m; +var FN_ARG = /\/\*([^*]*)\*\//m; + +function parse(fn) { + + if (typeof fn !== 'function') { + throw new Error('Cannot annotate "' + fn + '". Expected a function!'); + } + + var match = fn.toString().match(isClass(fn) ? CONSTRUCTOR_ARGS : FN_ARGS); + + // may parse class without constructor + if (!match) { + return []; + } + + return match[1] && match[1].split(',').map(function (arg) { + match = arg.match(FN_ARG); + return match ? match[1].trim() : arg.trim(); + }) || []; +} + +function Module() { + var providers = []; + + this.factory = function (name, factory) { + providers.push([name, 'factory', factory]); + return this; + }; + + this.value = function (name, value) { + providers.push([name, 'value', value]); + return this; + }; + + this.type = function (name, type) { + providers.push([name, 'type', type]); + return this; + }; + + this.forEach = function (iterator) { + providers.forEach(iterator); + }; +} + +var _typeof = typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol" ? function (obj) { + return typeof obj === 'undefined' ? 'undefined' : _typeof2(obj); +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj === 'undefined' ? 'undefined' : _typeof2(obj); +}; + +function _toConsumableArray(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { + arr2[i] = arr[i]; + }return arr2; + } else { + return Array.from(arr); + } +} + +function Injector(modules, parent) { + parent = parent || { + get: function get(name, strict) { + currentlyResolving.push(name); + + if (strict === false) { + return null; + } else { + throw error('No provider for "' + name + '"!'); + } + } + }; + + var currentlyResolving = []; + var providers = this._providers = Object.create(parent._providers || null); + var instances = this._instances = Object.create(null); + + var self = instances.injector = this; + + var error = function error(msg) { + var stack = currentlyResolving.join(' -> '); + currentlyResolving.length = 0; + return new Error(stack ? msg + ' (Resolving: ' + stack + ')' : msg); + }; + + /** + * Return a named service. + * + * @param {String} name + * @param {Boolean} [strict=true] if false, resolve missing services to null + * + * @return {Object} + */ + var get = function get(name, strict) { + if (!providers[name] && name.indexOf('.') !== -1) { + var parts = name.split('.'); + var pivot = get(parts.shift()); + + while (parts.length) { + pivot = pivot[parts.shift()]; + } + + return pivot; + } + + if (hasProp(instances, name)) { + return instances[name]; + } + + if (hasProp(providers, name)) { + if (currentlyResolving.indexOf(name) !== -1) { + currentlyResolving.push(name); + throw error('Cannot resolve circular dependency!'); + } + + currentlyResolving.push(name); + instances[name] = providers[name][0](providers[name][1]); + currentlyResolving.pop(); + + return instances[name]; + } + + return parent.get(name, strict); + }; + + var fnDef = function fnDef(fn) { + var locals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (typeof fn !== 'function') { + if (isArray(fn)) { + fn = annotate(fn.slice()); + } else { + throw new Error('Cannot invoke "' + fn + '". Expected a function!'); + } + } + + var inject = fn.$inject || parse(fn); + var dependencies = inject.map(function (dep) { + if (hasProp(locals, dep)) { + return locals[dep]; + } else { + return get(dep); + } + }); + + return { + fn: fn, + dependencies: dependencies + }; + }; + + var instantiate = function instantiate(Type) { + var _fnDef = fnDef(Type), + dependencies = _fnDef.dependencies, + fn = _fnDef.fn; + + return new (Function.prototype.bind.apply(fn, [null].concat(_toConsumableArray(dependencies))))(); + }; + + var invoke = function invoke(func, context, locals) { + var _fnDef2 = fnDef(func, locals), + dependencies = _fnDef2.dependencies, + fn = _fnDef2.fn; + + return fn.call.apply(fn, [context].concat(_toConsumableArray(dependencies))); + }; + + var createPrivateInjectorFactory = function createPrivateInjectorFactory(privateChildInjector) { + return annotate(function (key) { + return privateChildInjector.get(key); + }); + }; + + var createChild = function createChild(modules, forceNewInstances) { + if (forceNewInstances && forceNewInstances.length) { + var fromParentModule = Object.create(null); + var matchedScopes = Object.create(null); + + var privateInjectorsCache = []; + var privateChildInjectors = []; + var privateChildFactories = []; + + var provider; + var cacheIdx; + var privateChildInjector; + var privateChildInjectorFactory; + for (var name in providers) { + provider = providers[name]; + + if (forceNewInstances.indexOf(name) !== -1) { + if (provider[2] === 'private') { + cacheIdx = privateInjectorsCache.indexOf(provider[3]); + if (cacheIdx === -1) { + privateChildInjector = provider[3].createChild([], forceNewInstances); + privateChildInjectorFactory = createPrivateInjectorFactory(privateChildInjector); + privateInjectorsCache.push(provider[3]); + privateChildInjectors.push(privateChildInjector); + privateChildFactories.push(privateChildInjectorFactory); + fromParentModule[name] = [privateChildInjectorFactory, name, 'private', privateChildInjector]; + } else { + fromParentModule[name] = [privateChildFactories[cacheIdx], name, 'private', privateChildInjectors[cacheIdx]]; + } + } else { + fromParentModule[name] = [provider[2], provider[1]]; + } + matchedScopes[name] = true; + } + + if ((provider[2] === 'factory' || provider[2] === 'type') && provider[1].$scope) { + /* jshint -W083 */ + forceNewInstances.forEach(function (scope) { + if (provider[1].$scope.indexOf(scope) !== -1) { + fromParentModule[name] = [provider[2], provider[1]]; + matchedScopes[scope] = true; + } + }); + } + } + + forceNewInstances.forEach(function (scope) { + if (!matchedScopes[scope]) { + throw new Error('No provider for "' + scope + '". Cannot use provider from the parent!'); + } + }); + + modules.unshift(fromParentModule); + } + + return new Injector(modules, self); + }; + + var factoryMap = { + factory: invoke, + type: instantiate, + value: function value(_value) { + return _value; + } + }; + + modules.forEach(function (module) { + + function arrayUnwrap(type, value) { + if (type !== 'value' && isArray(value)) { + value = annotate(value.slice()); + } + + return value; + } + + // TODO(vojta): handle wrong inputs (modules) + if (module instanceof Module) { + module.forEach(function (provider) { + var name = provider[0]; + var type = provider[1]; + var value = provider[2]; + + providers[name] = [factoryMap[type], arrayUnwrap(type, value), type]; + }); + } else if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') { + if (module.__exports__) { + var clonedModule = Object.keys(module).reduce(function (m, key) { + if (key.substring(0, 2) !== '__') { + m[key] = module[key]; + } + return m; + }, Object.create(null)); + + var privateInjector = new Injector((module.__modules__ || []).concat([clonedModule]), self); + var getFromPrivateInjector = annotate(function (key) { + return privateInjector.get(key); + }); + module.__exports__.forEach(function (key) { + providers[key] = [getFromPrivateInjector, key, 'private', privateInjector]; + }); + } else { + Object.keys(module).forEach(function (name) { + if (module[name][2] === 'private') { + providers[name] = module[name]; + return; + } + + var type = module[name][0]; + var value = module[name][1]; + + providers[name] = [factoryMap[type], arrayUnwrap(type, value), type]; + }); + } + } + }); + + // public API + this.get = get; + this.invoke = invoke; + this.instantiate = instantiate; + this.createChild = createChild; +} + +// helpers ///////////////// + +function hasProp(obj, prop) { + return Object.hasOwnProperty.call(obj, prop); +} + +exports.annotate = annotate; +exports.Module = Module; +exports.Injector = Injector; + +},{}],411:[function(require,module,exports){ +'use strict'; + +/** + * Expose `parse`. + */ + +module.exports = parse; + +/** + * Tests for browser support. + */ + +var innerHTMLBug = false; +var bugTestDiv; +if (typeof document !== 'undefined') { + bugTestDiv = document.createElement('div'); + // Setup + bugTestDiv.innerHTML = '
a'; + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length; + bugTestDiv = undefined; +} + +/** + * Wrap map from jquery. + */ + +var map = { + legend: [1, '
', '
'], + tr: [2, '', '
'], + col: [2, '', '
'], + // for script/link/style tags to work in IE6-8, you have to wrap + // in a div with a non-whitespace character in front, ha! + _default: innerHTMLBug ? [1, 'X
', '
'] : [0, '', ''] +}; + +map.td = map.th = [3, '', '
']; + +map.option = map.optgroup = [1, '']; + +map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '', '
']; + +map.polyline = map.ellipse = map.polygon = map.circle = map.text = map.line = map.path = map.rect = map.g = [1, '', '']; + +/** + * Parse `html` and return a DOM Node instance, which could be a TextNode, + * HTML DOM Node of some kind (
for example), or a DocumentFragment + * instance, depending on the contents of the `html` string. + * + * @param {String} html - HTML string to "domify" + * @param {Document} doc - The `document` instance to create the Node for + * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance + * @api private + */ + +function parse(html, doc) { + if ('string' != typeof html) throw new TypeError('String expected'); + + // default to the global `document` object + if (!doc) doc = document; + + // tag name + var m = /<([\w:]+)/.exec(html); + if (!m) return doc.createTextNode(html); + + html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace + + var tag = m[1]; + + // body support + if (tag == 'body') { + var el = doc.createElement('html'); + el.innerHTML = html; + return el.removeChild(el.lastChild); + } + + // wrap map + var wrap = map[tag] || map._default; + var depth = wrap[0]; + var prefix = wrap[1]; + var suffix = wrap[2]; + var el = doc.createElement('div'); + el.innerHTML = prefix + html + suffix; + while (depth--) { + el = el.lastChild; + } // one element + if (el.firstChild == el.lastChild) { + return el.removeChild(el.firstChild); + } + + // several elements + var fragment = doc.createDocumentFragment(); + while (el.firstChild) { + fragment.appendChild(el.removeChild(el.firstChild)); + } + + return fragment; +} + +},{}],412:[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; }; + +/*! Hammer.JS - v2.0.7 - 2016-04-22 + * http://hammerjs.github.io/ + * + * Copyright (c) 2016 Jorik Tangelder; + * Licensed under the MIT license */ +(function (window, document, exportName, undefined) { + 'use strict'; + + var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o']; + var TEST_ELEMENT = document.createElement('div'); + + var TYPE_FUNCTION = 'function'; + + var round = Math.round; + var abs = Math.abs; + var now = Date.now; + + /** + * set a timeout with a given scope + * @param {Function} fn + * @param {Number} timeout + * @param {Object} context + * @returns {number} + */ + function setTimeoutContext(fn, timeout, context) { + return setTimeout(bindFn(fn, context), timeout); + } + + /** + * if the argument is an array, we want to execute the fn on each entry + * if it aint an array we don't want to do a thing. + * this is used by all the methods that accept a single and array argument. + * @param {*|Array} arg + * @param {String} fn + * @param {Object} [context] + * @returns {Boolean} + */ + function invokeArrayArg(arg, fn, context) { + if (Array.isArray(arg)) { + each(arg, context[fn], context); + return true; + } + return false; + } + + /** + * walk objects and arrays + * @param {Object} obj + * @param {Function} iterator + * @param {Object} context + */ + function each(obj, iterator, context) { + var i; + + if (!obj) { + return; + } + + if (obj.forEach) { + obj.forEach(iterator, context); + } else if (obj.length !== undefined) { + i = 0; + while (i < obj.length) { + iterator.call(context, obj[i], i, obj); + i++; + } + } else { + for (i in obj) { + obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj); + } + } + } + + /** + * wrap a method with a deprecation warning and stack trace + * @param {Function} method + * @param {String} name + * @param {String} message + * @returns {Function} A new function wrapping the supplied method. + */ + function deprecate(method, name, message) { + var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n'; + return function () { + var e = new Error('get-stack-trace'); + var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace'; + + var log = window.console && (window.console.warn || window.console.log); + if (log) { + log.call(window.console, deprecationMessage, stack); + } + return method.apply(this, arguments); + }; + } + + /** + * extend object. + * means that properties in dest will be overwritten by the ones in src. + * @param {Object} target + * @param {...Object} objects_to_assign + * @returns {Object} target + */ + var assign; + if (typeof Object.assign !== 'function') { + assign = function assign(target) { + if (target === undefined || target === null) { + throw new TypeError('Cannot convert undefined or null to object'); + } + + var output = Object(target); + for (var index = 1; index < arguments.length; index++) { + var source = arguments[index]; + if (source !== undefined && source !== null) { + for (var nextKey in source) { + if (source.hasOwnProperty(nextKey)) { + output[nextKey] = source[nextKey]; + } + } + } + } + return output; + }; + } else { + assign = Object.assign; + } + + /** + * extend object. + * means that properties in dest will be overwritten by the ones in src. + * @param {Object} dest + * @param {Object} src + * @param {Boolean} [merge=false] + * @returns {Object} dest + */ + var extend = deprecate(function extend(dest, src, merge) { + var keys = Object.keys(src); + var i = 0; + while (i < keys.length) { + if (!merge || merge && dest[keys[i]] === undefined) { + dest[keys[i]] = src[keys[i]]; + } + i++; + } + return dest; + }, 'extend', 'Use `assign`.'); + + /** + * merge the values from src in the dest. + * means that properties that exist in dest will not be overwritten by src + * @param {Object} dest + * @param {Object} src + * @returns {Object} dest + */ + var merge = deprecate(function merge(dest, src) { + return extend(dest, src, true); + }, 'merge', 'Use `assign`.'); + + /** + * simple class inheritance + * @param {Function} child + * @param {Function} base + * @param {Object} [properties] + */ + function inherit(child, base, properties) { + var baseP = base.prototype, + childP; + + childP = child.prototype = Object.create(baseP); + childP.constructor = child; + childP._super = baseP; + + if (properties) { + assign(childP, properties); + } + } + + /** + * simple function bind + * @param {Function} fn + * @param {Object} context + * @returns {Function} + */ + function bindFn(fn, context) { + return function boundFn() { + return fn.apply(context, arguments); + }; + } + + /** + * let a boolean value also be a function that must return a boolean + * this first item in args will be used as the context + * @param {Boolean|Function} val + * @param {Array} [args] + * @returns {Boolean} + */ + function boolOrFn(val, args) { + if ((typeof val === 'undefined' ? 'undefined' : _typeof(val)) == TYPE_FUNCTION) { + return val.apply(args ? args[0] || undefined : undefined, args); + } + return val; + } + + /** + * use the val2 when val1 is undefined + * @param {*} val1 + * @param {*} val2 + * @returns {*} + */ + function ifUndefined(val1, val2) { + return val1 === undefined ? val2 : val1; + } + + /** + * addEventListener with multiple events at once + * @param {EventTarget} target + * @param {String} types + * @param {Function} handler + */ + function addEventListeners(target, types, handler) { + each(splitStr(types), function (type) { + target.addEventListener(type, handler, false); + }); + } + + /** + * removeEventListener with multiple events at once + * @param {EventTarget} target + * @param {String} types + * @param {Function} handler + */ + function removeEventListeners(target, types, handler) { + each(splitStr(types), function (type) { + target.removeEventListener(type, handler, false); + }); + } + + /** + * find if a node is in the given parent + * @method hasParent + * @param {HTMLElement} node + * @param {HTMLElement} parent + * @return {Boolean} found + */ + function hasParent(node, parent) { + while (node) { + if (node == parent) { + return true; + } + node = node.parentNode; + } + return false; + } + + /** + * small indexOf wrapper + * @param {String} str + * @param {String} find + * @returns {Boolean} found + */ + function inStr(str, find) { + return str.indexOf(find) > -1; + } + + /** + * split string on whitespace + * @param {String} str + * @returns {Array} words + */ + function splitStr(str) { + return str.trim().split(/\s+/g); + } + + /** + * find if a array contains the object using indexOf or a simple polyFill + * @param {Array} src + * @param {String} find + * @param {String} [findByKey] + * @return {Boolean|Number} false when not found, or the index + */ + function inArray(src, find, findByKey) { + if (src.indexOf && !findByKey) { + return src.indexOf(find); + } else { + var i = 0; + while (i < src.length) { + if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) { + return i; + } + i++; + } + return -1; + } + } + + /** + * convert array-like objects to real arrays + * @param {Object} obj + * @returns {Array} + */ + function toArray(obj) { + return Array.prototype.slice.call(obj, 0); + } + + /** + * unique array with objects based on a key (like 'id') or just by the array's value + * @param {Array} src [{id:1},{id:2},{id:1}] + * @param {String} [key] + * @param {Boolean} [sort=False] + * @returns {Array} [{id:1},{id:2}] + */ + function uniqueArray(src, key, sort) { + var results = []; + var values = []; + var i = 0; + + while (i < src.length) { + var val = key ? src[i][key] : src[i]; + if (inArray(values, val) < 0) { + results.push(src[i]); + } + values[i] = val; + i++; + } + + if (sort) { + if (!key) { + results = results.sort(); + } else { + results = results.sort(function sortUniqueArray(a, b) { + return a[key] > b[key]; + }); + } + } + + return results; + } + + /** + * get the prefixed property + * @param {Object} obj + * @param {String} property + * @returns {String|Undefined} prefixed + */ + function prefixed(obj, property) { + var prefix, prop; + var camelProp = property[0].toUpperCase() + property.slice(1); + + var i = 0; + while (i < VENDOR_PREFIXES.length) { + prefix = VENDOR_PREFIXES[i]; + prop = prefix ? prefix + camelProp : property; + + if (prop in obj) { + return prop; + } + i++; + } + return undefined; + } + + /** + * get a unique id + * @returns {number} uniqueId + */ + var _uniqueId = 1; + function uniqueId() { + return _uniqueId++; + } + + /** + * get the window object of an element + * @param {HTMLElement} element + * @returns {DocumentView|Window} + */ + function getWindowForElement(element) { + var doc = element.ownerDocument || element; + return doc.defaultView || doc.parentWindow || window; + } + + var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i; + + var SUPPORT_TOUCH = 'ontouchstart' in window; + var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined; + var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent); + + var INPUT_TYPE_TOUCH = 'touch'; + var INPUT_TYPE_PEN = 'pen'; + var INPUT_TYPE_MOUSE = 'mouse'; + var INPUT_TYPE_KINECT = 'kinect'; + + var COMPUTE_INTERVAL = 25; + + var INPUT_START = 1; + var INPUT_MOVE = 2; + var INPUT_END = 4; + var INPUT_CANCEL = 8; + + var DIRECTION_NONE = 1; + var DIRECTION_LEFT = 2; + var DIRECTION_RIGHT = 4; + var DIRECTION_UP = 8; + var DIRECTION_DOWN = 16; + + var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT; + var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN; + var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL; + + var PROPS_XY = ['x', 'y']; + var PROPS_CLIENT_XY = ['clientX', 'clientY']; + + /** + * create new input type manager + * @param {Manager} manager + * @param {Function} callback + * @returns {Input} + * @constructor + */ + function Input(manager, callback) { + var self = this; + this.manager = manager; + this.callback = callback; + this.element = manager.element; + this.target = manager.options.inputTarget; + + // smaller wrapper around the handler, for the scope and the enabled state of the manager, + // so when disabled the input events are completely bypassed. + this.domHandler = function (ev) { + if (boolOrFn(manager.options.enable, [manager])) { + self.handler(ev); + } + }; + + this.init(); + } + + Input.prototype = { + /** + * should handle the inputEvent data and trigger the callback + * @virtual + */ + handler: function handler() {}, + + /** + * bind the events + */ + init: function init() { + this.evEl && addEventListeners(this.element, this.evEl, this.domHandler); + this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler); + this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); + }, + + /** + * unbind the events + */ + destroy: function destroy() { + this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler); + this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler); + this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); + } + }; + + /** + * create new input type manager + * called by the Manager constructor + * @param {Hammer} manager + * @returns {Input} + */ + function createInputInstance(manager) { + var Type; + var inputClass = manager.options.inputClass; + + if (inputClass) { + Type = inputClass; + } else if (SUPPORT_POINTER_EVENTS) { + Type = PointerEventInput; + } else if (SUPPORT_ONLY_TOUCH) { + Type = TouchInput; + } else if (!SUPPORT_TOUCH) { + Type = MouseInput; + } else { + Type = TouchMouseInput; + } + return new Type(manager, inputHandler); + } + + /** + * handle input events + * @param {Manager} manager + * @param {String} eventType + * @param {Object} input + */ + function inputHandler(manager, eventType, input) { + var pointersLen = input.pointers.length; + var changedPointersLen = input.changedPointers.length; + var isFirst = eventType & INPUT_START && pointersLen - changedPointersLen === 0; + var isFinal = eventType & (INPUT_END | INPUT_CANCEL) && pointersLen - changedPointersLen === 0; + + input.isFirst = !!isFirst; + input.isFinal = !!isFinal; + + if (isFirst) { + manager.session = {}; + } + + // source event is the normalized value of the domEvents + // like 'touchstart, mouseup, pointerdown' + input.eventType = eventType; + + // compute scale, rotation etc + computeInputData(manager, input); + + // emit secret event + manager.emit('hammer.input', input); + + manager.recognize(input); + manager.session.prevInput = input; + } + + /** + * extend the data with some usable properties like scale, rotate, velocity etc + * @param {Object} manager + * @param {Object} input + */ + function computeInputData(manager, input) { + var session = manager.session; + var pointers = input.pointers; + var pointersLength = pointers.length; + + // store the first input to calculate the distance and direction + if (!session.firstInput) { + session.firstInput = simpleCloneInputData(input); + } + + // to compute scale and rotation we need to store the multiple touches + if (pointersLength > 1 && !session.firstMultiple) { + session.firstMultiple = simpleCloneInputData(input); + } else if (pointersLength === 1) { + session.firstMultiple = false; + } + + var firstInput = session.firstInput; + var firstMultiple = session.firstMultiple; + var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center; + + var center = input.center = getCenter(pointers); + input.timeStamp = now(); + input.deltaTime = input.timeStamp - firstInput.timeStamp; + + input.angle = getAngle(offsetCenter, center); + input.distance = getDistance(offsetCenter, center); + + computeDeltaXY(session, input); + input.offsetDirection = getDirection(input.deltaX, input.deltaY); + + var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY); + input.overallVelocityX = overallVelocity.x; + input.overallVelocityY = overallVelocity.y; + input.overallVelocity = abs(overallVelocity.x) > abs(overallVelocity.y) ? overallVelocity.x : overallVelocity.y; + + input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1; + input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0; + + input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers; + + computeIntervalInputData(session, input); + + // find the correct target + var target = manager.element; + if (hasParent(input.srcEvent.target, target)) { + target = input.srcEvent.target; + } + input.target = target; + } + + function computeDeltaXY(session, input) { + var center = input.center; + var offset = session.offsetDelta || {}; + var prevDelta = session.prevDelta || {}; + var prevInput = session.prevInput || {}; + + if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) { + prevDelta = session.prevDelta = { + x: prevInput.deltaX || 0, + y: prevInput.deltaY || 0 + }; + + offset = session.offsetDelta = { + x: center.x, + y: center.y + }; + } + + input.deltaX = prevDelta.x + (center.x - offset.x); + input.deltaY = prevDelta.y + (center.y - offset.y); + } + + /** + * velocity is calculated every x ms + * @param {Object} session + * @param {Object} input + */ + function computeIntervalInputData(session, input) { + var last = session.lastInterval || input, + deltaTime = input.timeStamp - last.timeStamp, + velocity, + velocityX, + velocityY, + direction; + + if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) { + var deltaX = input.deltaX - last.deltaX; + var deltaY = input.deltaY - last.deltaY; + + var v = getVelocity(deltaTime, deltaX, deltaY); + velocityX = v.x; + velocityY = v.y; + velocity = abs(v.x) > abs(v.y) ? v.x : v.y; + direction = getDirection(deltaX, deltaY); + + session.lastInterval = input; + } else { + // use latest velocity info if it doesn't overtake a minimum period + velocity = last.velocity; + velocityX = last.velocityX; + velocityY = last.velocityY; + direction = last.direction; + } + + input.velocity = velocity; + input.velocityX = velocityX; + input.velocityY = velocityY; + input.direction = direction; + } + + /** + * create a simple clone from the input used for storage of firstInput and firstMultiple + * @param {Object} input + * @returns {Object} clonedInputData + */ + function simpleCloneInputData(input) { + // make a simple copy of the pointers because we will get a reference if we don't + // we only need clientXY for the calculations + var pointers = []; + var i = 0; + while (i < input.pointers.length) { + pointers[i] = { + clientX: round(input.pointers[i].clientX), + clientY: round(input.pointers[i].clientY) + }; + i++; + } + + return { + timeStamp: now(), + pointers: pointers, + center: getCenter(pointers), + deltaX: input.deltaX, + deltaY: input.deltaY + }; + } + + /** + * get the center of all the pointers + * @param {Array} pointers + * @return {Object} center contains `x` and `y` properties + */ + function getCenter(pointers) { + var pointersLength = pointers.length; + + // no need to loop when only one touch + if (pointersLength === 1) { + return { + x: round(pointers[0].clientX), + y: round(pointers[0].clientY) + }; + } + + var x = 0, + y = 0, + i = 0; + while (i < pointersLength) { + x += pointers[i].clientX; + y += pointers[i].clientY; + i++; + } + + return { + x: round(x / pointersLength), + y: round(y / pointersLength) + }; + } + + /** + * calculate the velocity between two points. unit is in px per ms. + * @param {Number} deltaTime + * @param {Number} x + * @param {Number} y + * @return {Object} velocity `x` and `y` + */ + function getVelocity(deltaTime, x, y) { + return { + x: x / deltaTime || 0, + y: y / deltaTime || 0 + }; + } + + /** + * get the direction between two points + * @param {Number} x + * @param {Number} y + * @return {Number} direction + */ + function getDirection(x, y) { + if (x === y) { + return DIRECTION_NONE; + } + + if (abs(x) >= abs(y)) { + return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; + } + return y < 0 ? DIRECTION_UP : DIRECTION_DOWN; + } + + /** + * calculate the absolute distance between two points + * @param {Object} p1 {x, y} + * @param {Object} p2 {x, y} + * @param {Array} [props] containing x and y keys + * @return {Number} distance + */ + function getDistance(p1, p2, props) { + if (!props) { + props = PROPS_XY; + } + var x = p2[props[0]] - p1[props[0]], + y = p2[props[1]] - p1[props[1]]; + + return Math.sqrt(x * x + y * y); + } + + /** + * calculate the angle between two coordinates + * @param {Object} p1 + * @param {Object} p2 + * @param {Array} [props] containing x and y keys + * @return {Number} angle + */ + function getAngle(p1, p2, props) { + if (!props) { + props = PROPS_XY; + } + var x = p2[props[0]] - p1[props[0]], + y = p2[props[1]] - p1[props[1]]; + return Math.atan2(y, x) * 180 / Math.PI; + } + + /** + * calculate the rotation degrees between two pointersets + * @param {Array} start array of pointers + * @param {Array} end array of pointers + * @return {Number} rotation + */ + function getRotation(start, end) { + return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY); + } + + /** + * calculate the scale factor between two pointersets + * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out + * @param {Array} start array of pointers + * @param {Array} end array of pointers + * @return {Number} scale + */ + function getScale(start, end) { + return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY); + } + + var MOUSE_INPUT_MAP = { + mousedown: INPUT_START, + mousemove: INPUT_MOVE, + mouseup: INPUT_END + }; + + var MOUSE_ELEMENT_EVENTS = 'mousedown'; + var MOUSE_WINDOW_EVENTS = 'mousemove mouseup'; + + /** + * Mouse events input + * @constructor + * @extends Input + */ + function MouseInput() { + this.evEl = MOUSE_ELEMENT_EVENTS; + this.evWin = MOUSE_WINDOW_EVENTS; + + this.pressed = false; // mousedown state + + Input.apply(this, arguments); + } + + inherit(MouseInput, Input, { + /** + * handle mouse events + * @param {Object} ev + */ + handler: function MEhandler(ev) { + var eventType = MOUSE_INPUT_MAP[ev.type]; + + // on start we want to have the left mouse button down + if (eventType & INPUT_START && ev.button === 0) { + this.pressed = true; + } + + if (eventType & INPUT_MOVE && ev.which !== 1) { + eventType = INPUT_END; + } + + // mouse must be down + if (!this.pressed) { + return; + } + + if (eventType & INPUT_END) { + this.pressed = false; + } + + this.callback(this.manager, eventType, { + pointers: [ev], + changedPointers: [ev], + pointerType: INPUT_TYPE_MOUSE, + srcEvent: ev + }); + } + }); + + var POINTER_INPUT_MAP = { + pointerdown: INPUT_START, + pointermove: INPUT_MOVE, + pointerup: INPUT_END, + pointercancel: INPUT_CANCEL, + pointerout: INPUT_CANCEL + }; + + // in IE10 the pointer types is defined as an enum + var IE10_POINTER_TYPE_ENUM = { + 2: INPUT_TYPE_TOUCH, + 3: INPUT_TYPE_PEN, + 4: INPUT_TYPE_MOUSE, + 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816 + }; + + var POINTER_ELEMENT_EVENTS = 'pointerdown'; + var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; + + // IE10 has prefixed support, and case-sensitive + if (window.MSPointerEvent && !window.PointerEvent) { + POINTER_ELEMENT_EVENTS = 'MSPointerDown'; + POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel'; + } + + /** + * Pointer events input + * @constructor + * @extends Input + */ + function PointerEventInput() { + this.evEl = POINTER_ELEMENT_EVENTS; + this.evWin = POINTER_WINDOW_EVENTS; + + Input.apply(this, arguments); + + this.store = this.manager.session.pointerEvents = []; + } + + inherit(PointerEventInput, Input, { + /** + * handle mouse events + * @param {Object} ev + */ + handler: function PEhandler(ev) { + var store = this.store; + var removePointer = false; + + var eventTypeNormalized = ev.type.toLowerCase().replace('ms', ''); + var eventType = POINTER_INPUT_MAP[eventTypeNormalized]; + var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType; + + var isTouch = pointerType == INPUT_TYPE_TOUCH; + + // get index of the event in the store + var storeIndex = inArray(store, ev.pointerId, 'pointerId'); + + // start and mouse must be down + if (eventType & INPUT_START && (ev.button === 0 || isTouch)) { + if (storeIndex < 0) { + store.push(ev); + storeIndex = store.length - 1; + } + } else if (eventType & (INPUT_END | INPUT_CANCEL)) { + removePointer = true; + } + + // it not found, so the pointer hasn't been down (so it's probably a hover) + if (storeIndex < 0) { + return; + } + + // update the event in the store + store[storeIndex] = ev; + + this.callback(this.manager, eventType, { + pointers: store, + changedPointers: [ev], + pointerType: pointerType, + srcEvent: ev + }); + + if (removePointer) { + // remove from the store + store.splice(storeIndex, 1); + } + } + }); + + var SINGLE_TOUCH_INPUT_MAP = { + touchstart: INPUT_START, + touchmove: INPUT_MOVE, + touchend: INPUT_END, + touchcancel: INPUT_CANCEL + }; + + var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart'; + var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel'; + + /** + * Touch events input + * @constructor + * @extends Input + */ + function SingleTouchInput() { + this.evTarget = SINGLE_TOUCH_TARGET_EVENTS; + this.evWin = SINGLE_TOUCH_WINDOW_EVENTS; + this.started = false; + + Input.apply(this, arguments); + } + + inherit(SingleTouchInput, Input, { + handler: function TEhandler(ev) { + var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; + + // should we handle the touch events? + if (type === INPUT_START) { + this.started = true; + } + + if (!this.started) { + return; + } + + var touches = normalizeSingleTouches.call(this, ev, type); + + // when done, reset the started state + if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) { + this.started = false; + } + + this.callback(this.manager, type, { + pointers: touches[0], + changedPointers: touches[1], + pointerType: INPUT_TYPE_TOUCH, + srcEvent: ev + }); + } + }); + + /** + * @this {TouchInput} + * @param {Object} ev + * @param {Number} type flag + * @returns {undefined|Array} [all, changed] + */ + function normalizeSingleTouches(ev, type) { + var all = toArray(ev.touches); + var changed = toArray(ev.changedTouches); + + if (type & (INPUT_END | INPUT_CANCEL)) { + all = uniqueArray(all.concat(changed), 'identifier', true); + } + + return [all, changed]; + } + + var TOUCH_INPUT_MAP = { + touchstart: INPUT_START, + touchmove: INPUT_MOVE, + touchend: INPUT_END, + touchcancel: INPUT_CANCEL + }; + + var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel'; + + /** + * Multi-user touch events input + * @constructor + * @extends Input + */ + function TouchInput() { + this.evTarget = TOUCH_TARGET_EVENTS; + this.targetIds = {}; + + Input.apply(this, arguments); + } + + inherit(TouchInput, Input, { + handler: function MTEhandler(ev) { + var type = TOUCH_INPUT_MAP[ev.type]; + var touches = getTouches.call(this, ev, type); + if (!touches) { + return; + } + + this.callback(this.manager, type, { + pointers: touches[0], + changedPointers: touches[1], + pointerType: INPUT_TYPE_TOUCH, + srcEvent: ev + }); + } + }); + + /** + * @this {TouchInput} + * @param {Object} ev + * @param {Number} type flag + * @returns {undefined|Array} [all, changed] + */ + function getTouches(ev, type) { + var allTouches = toArray(ev.touches); + var targetIds = this.targetIds; + + // when there is only one touch, the process can be simplified + if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) { + targetIds[allTouches[0].identifier] = true; + return [allTouches, allTouches]; + } + + var i, + targetTouches, + changedTouches = toArray(ev.changedTouches), + changedTargetTouches = [], + target = this.target; + + // get target touches from touches + targetTouches = allTouches.filter(function (touch) { + return hasParent(touch.target, target); + }); + + // collect touches + if (type === INPUT_START) { + i = 0; + while (i < targetTouches.length) { + targetIds[targetTouches[i].identifier] = true; + i++; + } + } + + // filter changed touches to only contain touches that exist in the collected target ids + i = 0; + while (i < changedTouches.length) { + if (targetIds[changedTouches[i].identifier]) { + changedTargetTouches.push(changedTouches[i]); + } + + // cleanup removed touches + if (type & (INPUT_END | INPUT_CANCEL)) { + delete targetIds[changedTouches[i].identifier]; + } + i++; + } + + if (!changedTargetTouches.length) { + return; + } + + return [ + // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel' + uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), changedTargetTouches]; + } + + /** + * Combined touch and mouse input + * + * Touch has a higher priority then mouse, and while touching no mouse events are allowed. + * This because touch devices also emit mouse events while doing a touch. + * + * @constructor + * @extends Input + */ + + var DEDUP_TIMEOUT = 2500; + var DEDUP_DISTANCE = 25; + + function TouchMouseInput() { + Input.apply(this, arguments); + + var handler = bindFn(this.handler, this); + this.touch = new TouchInput(this.manager, handler); + this.mouse = new MouseInput(this.manager, handler); + + this.primaryTouch = null; + this.lastTouches = []; + } + + inherit(TouchMouseInput, Input, { + /** + * handle mouse and touch events + * @param {Hammer} manager + * @param {String} inputEvent + * @param {Object} inputData + */ + handler: function TMEhandler(manager, inputEvent, inputData) { + var isTouch = inputData.pointerType == INPUT_TYPE_TOUCH, + isMouse = inputData.pointerType == INPUT_TYPE_MOUSE; + + if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) { + return; + } + + // when we're in a touch event, record touches to de-dupe synthetic mouse event + if (isTouch) { + recordTouches.call(this, inputEvent, inputData); + } else if (isMouse && isSyntheticEvent.call(this, inputData)) { + return; + } + + this.callback(manager, inputEvent, inputData); + }, + + /** + * remove the event listeners + */ + destroy: function destroy() { + this.touch.destroy(); + this.mouse.destroy(); + } + }); + + function recordTouches(eventType, eventData) { + if (eventType & INPUT_START) { + this.primaryTouch = eventData.changedPointers[0].identifier; + setLastTouch.call(this, eventData); + } else if (eventType & (INPUT_END | INPUT_CANCEL)) { + setLastTouch.call(this, eventData); + } + } + + function setLastTouch(eventData) { + var touch = eventData.changedPointers[0]; + + if (touch.identifier === this.primaryTouch) { + var lastTouch = { x: touch.clientX, y: touch.clientY }; + this.lastTouches.push(lastTouch); + var lts = this.lastTouches; + var removeLastTouch = function removeLastTouch() { + var i = lts.indexOf(lastTouch); + if (i > -1) { + lts.splice(i, 1); + } + }; + setTimeout(removeLastTouch, DEDUP_TIMEOUT); + } + } + + function isSyntheticEvent(eventData) { + var x = eventData.srcEvent.clientX, + y = eventData.srcEvent.clientY; + for (var i = 0; i < this.lastTouches.length; i++) { + var t = this.lastTouches[i]; + var dx = Math.abs(x - t.x), + dy = Math.abs(y - t.y); + if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) { + return true; + } + } + return false; + } + + var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction'); + var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined; + + // magical touchAction value + var TOUCH_ACTION_COMPUTE = 'compute'; + var TOUCH_ACTION_AUTO = 'auto'; + var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented + var TOUCH_ACTION_NONE = 'none'; + var TOUCH_ACTION_PAN_X = 'pan-x'; + var TOUCH_ACTION_PAN_Y = 'pan-y'; + var TOUCH_ACTION_MAP = getTouchActionProps(); + + /** + * Touch Action + * sets the touchAction property or uses the js alternative + * @param {Manager} manager + * @param {String} value + * @constructor + */ + function TouchAction(manager, value) { + this.manager = manager; + this.set(value); + } + + TouchAction.prototype = { + /** + * set the touchAction value on the element or enable the polyfill + * @param {String} value + */ + set: function set(value) { + // find out the touch-action by the event handlers + if (value == TOUCH_ACTION_COMPUTE) { + value = this.compute(); + } + + if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) { + this.manager.element.style[PREFIXED_TOUCH_ACTION] = value; + } + this.actions = value.toLowerCase().trim(); + }, + + /** + * just re-set the touchAction value + */ + update: function update() { + this.set(this.manager.options.touchAction); + }, + + /** + * compute the value for the touchAction property based on the recognizer's settings + * @returns {String} value + */ + compute: function compute() { + var actions = []; + each(this.manager.recognizers, function (recognizer) { + if (boolOrFn(recognizer.options.enable, [recognizer])) { + actions = actions.concat(recognizer.getTouchAction()); + } + }); + return cleanTouchActions(actions.join(' ')); + }, + + /** + * this method is called on each input cycle and provides the preventing of the browser behavior + * @param {Object} input + */ + preventDefaults: function preventDefaults(input) { + var srcEvent = input.srcEvent; + var direction = input.offsetDirection; + + // if the touch action did prevented once this session + if (this.manager.session.prevented) { + srcEvent.preventDefault(); + return; + } + + var actions = this.actions; + var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE]; + var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y]; + var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X]; + + if (hasNone) { + //do not prevent defaults if this is a tap gesture + + var isTapPointer = input.pointers.length === 1; + var isTapMovement = input.distance < 2; + var isTapTouchTime = input.deltaTime < 250; + + if (isTapPointer && isTapMovement && isTapTouchTime) { + return; + } + } + + if (hasPanX && hasPanY) { + // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent + return; + } + + if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) { + return this.preventSrc(srcEvent); + } + }, + + /** + * call preventDefault to prevent the browser's default behavior (scrolling in most cases) + * @param {Object} srcEvent + */ + preventSrc: function preventSrc(srcEvent) { + this.manager.session.prevented = true; + srcEvent.preventDefault(); + } + }; + + /** + * when the touchActions are collected they are not a valid value, so we need to clean things up. * + * @param {String} actions + * @returns {*} + */ + function cleanTouchActions(actions) { + // none + if (inStr(actions, TOUCH_ACTION_NONE)) { + return TOUCH_ACTION_NONE; + } + + var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X); + var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); + + // if both pan-x and pan-y are set (different recognizers + // for different directions, e.g. horizontal pan but vertical swipe?) + // we need none (as otherwise with pan-x pan-y combined none of these + // recognizers will work, since the browser would handle all panning + if (hasPanX && hasPanY) { + return TOUCH_ACTION_NONE; + } + + // pan-x OR pan-y + if (hasPanX || hasPanY) { + return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y; + } + + // manipulation + if (inStr(actions, TOUCH_ACTION_MANIPULATION)) { + return TOUCH_ACTION_MANIPULATION; + } + + return TOUCH_ACTION_AUTO; + } + + function getTouchActionProps() { + if (!NATIVE_TOUCH_ACTION) { + return false; + } + var touchMap = {}; + var cssSupports = window.CSS && window.CSS.supports; + ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) { + + // If css.supports is not supported but there is native touch-action assume it supports + // all values. This is the case for IE 10 and 11. + touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true; + }); + return touchMap; + } + + /** + * Recognizer flow explained; * + * All recognizers have the initial state of POSSIBLE when a input session starts. + * The definition of a input session is from the first input until the last input, with all it's movement in it. * + * Example session for mouse-input: mousedown -> mousemove -> mouseup + * + * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed + * which determines with state it should be. + * + * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to + * POSSIBLE to give it another change on the next cycle. + * + * Possible + * | + * +-----+---------------+ + * | | + * +-----+-----+ | + * | | | + * Failed Cancelled | + * +-------+------+ + * | | + * Recognized Began + * | + * Changed + * | + * Ended/Recognized + */ + var STATE_POSSIBLE = 1; + var STATE_BEGAN = 2; + var STATE_CHANGED = 4; + var STATE_ENDED = 8; + var STATE_RECOGNIZED = STATE_ENDED; + var STATE_CANCELLED = 16; + var STATE_FAILED = 32; + + /** + * Recognizer + * Every recognizer needs to extend from this class. + * @constructor + * @param {Object} options + */ + function Recognizer(options) { + this.options = assign({}, this.defaults, options || {}); + + this.id = uniqueId(); + + this.manager = null; + + // default is enable true + this.options.enable = ifUndefined(this.options.enable, true); + + this.state = STATE_POSSIBLE; + + this.simultaneous = {}; + this.requireFail = []; + } + + Recognizer.prototype = { + /** + * @virtual + * @type {Object} + */ + defaults: {}, + + /** + * set options + * @param {Object} options + * @return {Recognizer} + */ + set: function set(options) { + assign(this.options, options); + + // also update the touchAction, in case something changed about the directions/enabled state + this.manager && this.manager.touchAction.update(); + return this; + }, + + /** + * recognize simultaneous with an other recognizer. + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + recognizeWith: function recognizeWith(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) { + return this; + } + + var simultaneous = this.simultaneous; + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + if (!simultaneous[otherRecognizer.id]) { + simultaneous[otherRecognizer.id] = otherRecognizer; + otherRecognizer.recognizeWith(this); + } + return this; + }, + + /** + * drop the simultaneous link. it doesnt remove the link on the other recognizer. + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + dropRecognizeWith: function dropRecognizeWith(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) { + return this; + } + + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + delete this.simultaneous[otherRecognizer.id]; + return this; + }, + + /** + * recognizer can only run when an other is failing + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + requireFailure: function requireFailure(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) { + return this; + } + + var requireFail = this.requireFail; + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + if (inArray(requireFail, otherRecognizer) === -1) { + requireFail.push(otherRecognizer); + otherRecognizer.requireFailure(this); + } + return this; + }, + + /** + * drop the requireFailure link. it does not remove the link on the other recognizer. + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + dropRequireFailure: function dropRequireFailure(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) { + return this; + } + + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + var index = inArray(this.requireFail, otherRecognizer); + if (index > -1) { + this.requireFail.splice(index, 1); + } + return this; + }, + + /** + * has require failures boolean + * @returns {boolean} + */ + hasRequireFailures: function hasRequireFailures() { + return this.requireFail.length > 0; + }, + + /** + * if the recognizer can recognize simultaneous with an other recognizer + * @param {Recognizer} otherRecognizer + * @returns {Boolean} + */ + canRecognizeWith: function canRecognizeWith(otherRecognizer) { + return !!this.simultaneous[otherRecognizer.id]; + }, + + /** + * You should use `tryEmit` instead of `emit` directly to check + * that all the needed recognizers has failed before emitting. + * @param {Object} input + */ + emit: function emit(input) { + var self = this; + var state = this.state; + + function emit(event) { + self.manager.emit(event, input); + } + + // 'panstart' and 'panmove' + if (state < STATE_ENDED) { + emit(self.options.event + stateStr(state)); + } + + emit(self.options.event); // simple 'eventName' events + + if (input.additionalEvent) { + // additional event(panleft, panright, pinchin, pinchout...) + emit(input.additionalEvent); + } + + // panend and pancancel + if (state >= STATE_ENDED) { + emit(self.options.event + stateStr(state)); + } + }, + + /** + * Check that all the require failure recognizers has failed, + * if true, it emits a gesture event, + * otherwise, setup the state to FAILED. + * @param {Object} input + */ + tryEmit: function tryEmit(input) { + if (this.canEmit()) { + return this.emit(input); + } + // it's failing anyway + this.state = STATE_FAILED; + }, + + /** + * can we emit? + * @returns {boolean} + */ + canEmit: function canEmit() { + var i = 0; + while (i < this.requireFail.length) { + if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) { + return false; + } + i++; + } + return true; + }, + + /** + * update the recognizer + * @param {Object} inputData + */ + recognize: function recognize(inputData) { + // make a new copy of the inputData + // so we can change the inputData without messing up the other recognizers + var inputDataClone = assign({}, inputData); + + // is is enabled and allow recognizing? + if (!boolOrFn(this.options.enable, [this, inputDataClone])) { + this.reset(); + this.state = STATE_FAILED; + return; + } + + // reset when we've reached the end + if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) { + this.state = STATE_POSSIBLE; + } + + this.state = this.process(inputDataClone); + + // the recognizer has recognized a gesture + // so trigger an event + if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) { + this.tryEmit(inputDataClone); + } + }, + + /** + * return the state of the recognizer + * the actual recognizing happens in this method + * @virtual + * @param {Object} inputData + * @returns {Const} STATE + */ + process: function process(inputData) {}, // jshint ignore:line + + /** + * return the preferred touch-action + * @virtual + * @returns {Array} + */ + getTouchAction: function getTouchAction() {}, + + /** + * called when the gesture isn't allowed to recognize + * like when another is being recognized or it is disabled + * @virtual + */ + reset: function reset() {} + }; + + /** + * get a usable string, used as event postfix + * @param {Const} state + * @returns {String} state + */ + function stateStr(state) { + if (state & STATE_CANCELLED) { + return 'cancel'; + } else if (state & STATE_ENDED) { + return 'end'; + } else if (state & STATE_CHANGED) { + return 'move'; + } else if (state & STATE_BEGAN) { + return 'start'; + } + return ''; + } + + /** + * direction cons to string + * @param {Const} direction + * @returns {String} + */ + function directionStr(direction) { + if (direction == DIRECTION_DOWN) { + return 'down'; + } else if (direction == DIRECTION_UP) { + return 'up'; + } else if (direction == DIRECTION_LEFT) { + return 'left'; + } else if (direction == DIRECTION_RIGHT) { + return 'right'; + } + return ''; + } + + /** + * get a recognizer by name if it is bound to a manager + * @param {Recognizer|String} otherRecognizer + * @param {Recognizer} recognizer + * @returns {Recognizer} + */ + function getRecognizerByNameIfManager(otherRecognizer, recognizer) { + var manager = recognizer.manager; + if (manager) { + return manager.get(otherRecognizer); + } + return otherRecognizer; + } + + /** + * This recognizer is just used as a base for the simple attribute recognizers. + * @constructor + * @extends Recognizer + */ + function AttrRecognizer() { + Recognizer.apply(this, arguments); + } + + inherit(AttrRecognizer, Recognizer, { + /** + * @namespace + * @memberof AttrRecognizer + */ + defaults: { + /** + * @type {Number} + * @default 1 + */ + pointers: 1 + }, + + /** + * Used to check if it the recognizer receives valid input, like input.distance > 10. + * @memberof AttrRecognizer + * @param {Object} input + * @returns {Boolean} recognized + */ + attrTest: function attrTest(input) { + var optionPointers = this.options.pointers; + return optionPointers === 0 || input.pointers.length === optionPointers; + }, + + /** + * Process the input and return the state for the recognizer + * @memberof AttrRecognizer + * @param {Object} input + * @returns {*} State + */ + process: function process(input) { + var state = this.state; + var eventType = input.eventType; + + var isRecognized = state & (STATE_BEGAN | STATE_CHANGED); + var isValid = this.attrTest(input); + + // on cancel input and we've recognized before, return STATE_CANCELLED + if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) { + return state | STATE_CANCELLED; + } else if (isRecognized || isValid) { + if (eventType & INPUT_END) { + return state | STATE_ENDED; + } else if (!(state & STATE_BEGAN)) { + return STATE_BEGAN; + } + return state | STATE_CHANGED; + } + return STATE_FAILED; + } + }); + + /** + * Pan + * Recognized when the pointer is down and moved in the allowed direction. + * @constructor + * @extends AttrRecognizer + */ + function PanRecognizer() { + AttrRecognizer.apply(this, arguments); + + this.pX = null; + this.pY = null; + } + + inherit(PanRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof PanRecognizer + */ + defaults: { + event: 'pan', + threshold: 10, + pointers: 1, + direction: DIRECTION_ALL + }, + + getTouchAction: function getTouchAction() { + var direction = this.options.direction; + var actions = []; + if (direction & DIRECTION_HORIZONTAL) { + actions.push(TOUCH_ACTION_PAN_Y); + } + if (direction & DIRECTION_VERTICAL) { + actions.push(TOUCH_ACTION_PAN_X); + } + return actions; + }, + + directionTest: function directionTest(input) { + var options = this.options; + var hasMoved = true; + var distance = input.distance; + var direction = input.direction; + var x = input.deltaX; + var y = input.deltaY; + + // lock to axis? + if (!(direction & options.direction)) { + if (options.direction & DIRECTION_HORIZONTAL) { + direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; + hasMoved = x != this.pX; + distance = Math.abs(input.deltaX); + } else { + direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN; + hasMoved = y != this.pY; + distance = Math.abs(input.deltaY); + } + } + input.direction = direction; + return hasMoved && distance > options.threshold && direction & options.direction; + }, + + attrTest: function attrTest(input) { + return AttrRecognizer.prototype.attrTest.call(this, input) && (this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input)); + }, + + emit: function emit(input) { + + this.pX = input.deltaX; + this.pY = input.deltaY; + + var direction = directionStr(input.direction); + + if (direction) { + input.additionalEvent = this.options.event + direction; + } + this._super.emit.call(this, input); + } + }); + + /** + * Pinch + * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out). + * @constructor + * @extends AttrRecognizer + */ + function PinchRecognizer() { + AttrRecognizer.apply(this, arguments); + } + + inherit(PinchRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof PinchRecognizer + */ + defaults: { + event: 'pinch', + threshold: 0, + pointers: 2 + }, + + getTouchAction: function getTouchAction() { + return [TOUCH_ACTION_NONE]; + }, + + attrTest: function attrTest(input) { + return this._super.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN); + }, + + emit: function emit(input) { + if (input.scale !== 1) { + var inOut = input.scale < 1 ? 'in' : 'out'; + input.additionalEvent = this.options.event + inOut; + } + this._super.emit.call(this, input); + } + }); + + /** + * Press + * Recognized when the pointer is down for x ms without any movement. + * @constructor + * @extends Recognizer + */ + function PressRecognizer() { + Recognizer.apply(this, arguments); + + this._timer = null; + this._input = null; + } + + inherit(PressRecognizer, Recognizer, { + /** + * @namespace + * @memberof PressRecognizer + */ + defaults: { + event: 'press', + pointers: 1, + time: 251, // minimal time of the pointer to be pressed + threshold: 9 // a minimal movement is ok, but keep it low + }, + + getTouchAction: function getTouchAction() { + return [TOUCH_ACTION_AUTO]; + }, + + process: function process(input) { + var options = this.options; + var validPointers = input.pointers.length === options.pointers; + var validMovement = input.distance < options.threshold; + var validTime = input.deltaTime > options.time; + + this._input = input; + + // we only allow little movement + // and we've reached an end event, so a tap is possible + if (!validMovement || !validPointers || input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime) { + this.reset(); + } else if (input.eventType & INPUT_START) { + this.reset(); + this._timer = setTimeoutContext(function () { + this.state = STATE_RECOGNIZED; + this.tryEmit(); + }, options.time, this); + } else if (input.eventType & INPUT_END) { + return STATE_RECOGNIZED; + } + return STATE_FAILED; + }, + + reset: function reset() { + clearTimeout(this._timer); + }, + + emit: function emit(input) { + if (this.state !== STATE_RECOGNIZED) { + return; + } + + if (input && input.eventType & INPUT_END) { + this.manager.emit(this.options.event + 'up', input); + } else { + this._input.timeStamp = now(); + this.manager.emit(this.options.event, this._input); + } + } + }); + + /** + * Rotate + * Recognized when two or more pointer are moving in a circular motion. + * @constructor + * @extends AttrRecognizer + */ + function RotateRecognizer() { + AttrRecognizer.apply(this, arguments); + } + + inherit(RotateRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof RotateRecognizer + */ + defaults: { + event: 'rotate', + threshold: 0, + pointers: 2 + }, + + getTouchAction: function getTouchAction() { + return [TOUCH_ACTION_NONE]; + }, + + attrTest: function attrTest(input) { + return this._super.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN); + } + }); + + /** + * Swipe + * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction. + * @constructor + * @extends AttrRecognizer + */ + function SwipeRecognizer() { + AttrRecognizer.apply(this, arguments); + } + + inherit(SwipeRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof SwipeRecognizer + */ + defaults: { + event: 'swipe', + threshold: 10, + velocity: 0.3, + direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL, + pointers: 1 + }, + + getTouchAction: function getTouchAction() { + return PanRecognizer.prototype.getTouchAction.call(this); + }, + + attrTest: function attrTest(input) { + var direction = this.options.direction; + var velocity; + + if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) { + velocity = input.overallVelocity; + } else if (direction & DIRECTION_HORIZONTAL) { + velocity = input.overallVelocityX; + } else if (direction & DIRECTION_VERTICAL) { + velocity = input.overallVelocityY; + } + + return this._super.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers == this.options.pointers && abs(velocity) > this.options.velocity && input.eventType & INPUT_END; + }, + + emit: function emit(input) { + var direction = directionStr(input.offsetDirection); + if (direction) { + this.manager.emit(this.options.event + direction, input); + } + + this.manager.emit(this.options.event, input); + } + }); + + /** + * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur + * between the given interval and position. The delay option can be used to recognize multi-taps without firing + * a single tap. + * + * The eventData from the emitted event contains the property `tapCount`, which contains the amount of + * multi-taps being recognized. + * @constructor + * @extends Recognizer + */ + function TapRecognizer() { + Recognizer.apply(this, arguments); + + // previous time and center, + // used for tap counting + this.pTime = false; + this.pCenter = false; + + this._timer = null; + this._input = null; + this.count = 0; + } + + inherit(TapRecognizer, Recognizer, { + /** + * @namespace + * @memberof PinchRecognizer + */ + defaults: { + event: 'tap', + pointers: 1, + taps: 1, + interval: 300, // max time between the multi-tap taps + time: 250, // max time of the pointer to be down (like finger on the screen) + threshold: 9, // a minimal movement is ok, but keep it low + posThreshold: 10 // a multi-tap can be a bit off the initial position + }, + + getTouchAction: function getTouchAction() { + return [TOUCH_ACTION_MANIPULATION]; + }, + + process: function process(input) { + var options = this.options; + + var validPointers = input.pointers.length === options.pointers; + var validMovement = input.distance < options.threshold; + var validTouchTime = input.deltaTime < options.time; + + this.reset(); + + if (input.eventType & INPUT_START && this.count === 0) { + return this.failTimeout(); + } + + // we only allow little movement + // and we've reached an end event, so a tap is possible + if (validMovement && validTouchTime && validPointers) { + if (input.eventType != INPUT_END) { + return this.failTimeout(); + } + + var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true; + var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold; + + this.pTime = input.timeStamp; + this.pCenter = input.center; + + if (!validMultiTap || !validInterval) { + this.count = 1; + } else { + this.count += 1; + } + + this._input = input; + + // if tap count matches we have recognized it, + // else it has began recognizing... + var tapCount = this.count % options.taps; + if (tapCount === 0) { + // no failing requirements, immediately trigger the tap event + // or wait as long as the multitap interval to trigger + if (!this.hasRequireFailures()) { + return STATE_RECOGNIZED; + } else { + this._timer = setTimeoutContext(function () { + this.state = STATE_RECOGNIZED; + this.tryEmit(); + }, options.interval, this); + return STATE_BEGAN; + } + } + } + return STATE_FAILED; + }, + + failTimeout: function failTimeout() { + this._timer = setTimeoutContext(function () { + this.state = STATE_FAILED; + }, this.options.interval, this); + return STATE_FAILED; + }, + + reset: function reset() { + clearTimeout(this._timer); + }, + + emit: function emit() { + if (this.state == STATE_RECOGNIZED) { + this._input.tapCount = this.count; + this.manager.emit(this.options.event, this._input); + } + } + }); + + /** + * Simple way to create a manager with a default set of recognizers. + * @param {HTMLElement} element + * @param {Object} [options] + * @constructor + */ + function Hammer(element, options) { + options = options || {}; + options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset); + return new Manager(element, options); + } + + /** + * @const {string} + */ + Hammer.VERSION = '2.0.7'; + + /** + * default settings + * @namespace + */ + Hammer.defaults = { + /** + * set if DOM events are being triggered. + * But this is slower and unused by simple implementations, so disabled by default. + * @type {Boolean} + * @default false + */ + domEvents: false, + + /** + * The value for the touchAction property/fallback. + * When set to `compute` it will magically set the correct value based on the added recognizers. + * @type {String} + * @default compute + */ + touchAction: TOUCH_ACTION_COMPUTE, + + /** + * @type {Boolean} + * @default true + */ + enable: true, + + /** + * EXPERIMENTAL FEATURE -- can be removed/changed + * Change the parent input target element. + * If Null, then it is being set the to main element. + * @type {Null|EventTarget} + * @default null + */ + inputTarget: null, + + /** + * force an input class + * @type {Null|Function} + * @default null + */ + inputClass: null, + + /** + * Default recognizer setup when calling `Hammer()` + * When creating a new Manager these will be skipped. + * @type {Array} + */ + preset: [ + // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...] + [RotateRecognizer, { enable: false }], [PinchRecognizer, { enable: false }, ['rotate']], [SwipeRecognizer, { direction: DIRECTION_HORIZONTAL }], [PanRecognizer, { direction: DIRECTION_HORIZONTAL }, ['swipe']], [TapRecognizer], [TapRecognizer, { event: 'doubletap', taps: 2 }, ['tap']], [PressRecognizer]], + + /** + * Some CSS properties can be used to improve the working of Hammer. + * Add them to this method and they will be set when creating a new Manager. + * @namespace + */ + cssProps: { + /** + * Disables text selection to improve the dragging gesture. Mainly for desktop browsers. + * @type {String} + * @default 'none' + */ + userSelect: 'none', + + /** + * Disable the Windows Phone grippers when pressing an element. + * @type {String} + * @default 'none' + */ + touchSelect: 'none', + + /** + * Disables the default callout shown when you touch and hold a touch target. + * On iOS, when you touch and hold a touch target such as a link, Safari displays + * a callout containing information about the link. This property allows you to disable that callout. + * @type {String} + * @default 'none' + */ + touchCallout: 'none', + + /** + * Specifies whether zooming is enabled. Used by IE10> + * @type {String} + * @default 'none' + */ + contentZooming: 'none', + + /** + * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers. + * @type {String} + * @default 'none' + */ + userDrag: 'none', + + /** + * Overrides the highlight color shown when the user taps a link or a JavaScript + * clickable element in iOS. This property obeys the alpha value, if specified. + * @type {String} + * @default 'rgba(0,0,0,0)' + */ + tapHighlightColor: 'rgba(0,0,0,0)' + } + }; + + var STOP = 1; + var FORCED_STOP = 2; + + /** + * Manager + * @param {HTMLElement} element + * @param {Object} [options] + * @constructor + */ + function Manager(element, options) { + this.options = assign({}, Hammer.defaults, options || {}); + + this.options.inputTarget = this.options.inputTarget || element; + + this.handlers = {}; + this.session = {}; + this.recognizers = []; + this.oldCssProps = {}; + + this.element = element; + this.input = createInputInstance(this); + this.touchAction = new TouchAction(this, this.options.touchAction); + + toggleCssProps(this, true); + + each(this.options.recognizers, function (item) { + var recognizer = this.add(new item[0](item[1])); + item[2] && recognizer.recognizeWith(item[2]); + item[3] && recognizer.requireFailure(item[3]); + }, this); + } + + Manager.prototype = { + /** + * set options + * @param {Object} options + * @returns {Manager} + */ + set: function set(options) { + assign(this.options, options); + + // Options that need a little more setup + if (options.touchAction) { + this.touchAction.update(); + } + if (options.inputTarget) { + // Clean up existing event listeners and reinitialize + this.input.destroy(); + this.input.target = options.inputTarget; + this.input.init(); + } + return this; + }, + + /** + * stop recognizing for this session. + * This session will be discarded, when a new [input]start event is fired. + * When forced, the recognizer cycle is stopped immediately. + * @param {Boolean} [force] + */ + stop: function stop(force) { + this.session.stopped = force ? FORCED_STOP : STOP; + }, + + /** + * run the recognizers! + * called by the inputHandler function on every movement of the pointers (touches) + * it walks through all the recognizers and tries to detect the gesture that is being made + * @param {Object} inputData + */ + recognize: function recognize(inputData) { + var session = this.session; + if (session.stopped) { + return; + } + + // run the touch-action polyfill + this.touchAction.preventDefaults(inputData); + + var recognizer; + var recognizers = this.recognizers; + + // this holds the recognizer that is being recognized. + // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED + // if no recognizer is detecting a thing, it is set to `null` + var curRecognizer = session.curRecognizer; + + // reset when the last recognizer is recognized + // or when we're in a new session + if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) { + curRecognizer = session.curRecognizer = null; + } + + var i = 0; + while (i < recognizers.length) { + recognizer = recognizers[i]; + + // find out if we are allowed try to recognize the input for this one. + // 1. allow if the session is NOT forced stopped (see the .stop() method) + // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one + // that is being recognized. + // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer. + // this can be setup with the `recognizeWith()` method on the recognizer. + if (session.stopped !== FORCED_STOP && ( // 1 + !curRecognizer || recognizer == curRecognizer || // 2 + recognizer.canRecognizeWith(curRecognizer))) { + // 3 + recognizer.recognize(inputData); + } else { + recognizer.reset(); + } + + // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the + // current active recognizer. but only if we don't already have an active recognizer + if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) { + curRecognizer = session.curRecognizer = recognizer; + } + i++; + } + }, + + /** + * get a recognizer by its event name. + * @param {Recognizer|String} recognizer + * @returns {Recognizer|Null} + */ + get: function get(recognizer) { + if (recognizer instanceof Recognizer) { + return recognizer; + } + + var recognizers = this.recognizers; + for (var i = 0; i < recognizers.length; i++) { + if (recognizers[i].options.event == recognizer) { + return recognizers[i]; + } + } + return null; + }, + + /** + * add a recognizer to the manager + * existing recognizers with the same event name will be removed + * @param {Recognizer} recognizer + * @returns {Recognizer|Manager} + */ + add: function add(recognizer) { + if (invokeArrayArg(recognizer, 'add', this)) { + return this; + } + + // remove existing + var existing = this.get(recognizer.options.event); + if (existing) { + this.remove(existing); + } + + this.recognizers.push(recognizer); + recognizer.manager = this; + + this.touchAction.update(); + return recognizer; + }, + + /** + * remove a recognizer by name or instance + * @param {Recognizer|String} recognizer + * @returns {Manager} + */ + remove: function remove(recognizer) { + if (invokeArrayArg(recognizer, 'remove', this)) { + return this; + } + + recognizer = this.get(recognizer); + + // let's make sure this recognizer exists + if (recognizer) { + var recognizers = this.recognizers; + var index = inArray(recognizers, recognizer); + + if (index !== -1) { + recognizers.splice(index, 1); + this.touchAction.update(); + } + } + + return this; + }, + + /** + * bind event + * @param {String} events + * @param {Function} handler + * @returns {EventEmitter} this + */ + on: function on(events, handler) { + if (events === undefined) { + return; + } + if (handler === undefined) { + return; + } + + var handlers = this.handlers; + each(splitStr(events), function (event) { + handlers[event] = handlers[event] || []; + handlers[event].push(handler); + }); + return this; + }, + + /** + * unbind event, leave emit blank to remove all handlers + * @param {String} events + * @param {Function} [handler] + * @returns {EventEmitter} this + */ + off: function off(events, handler) { + if (events === undefined) { + return; + } + + var handlers = this.handlers; + each(splitStr(events), function (event) { + if (!handler) { + delete handlers[event]; + } else { + handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1); + } + }); + return this; + }, + + /** + * emit event to the listeners + * @param {String} event + * @param {Object} data + */ + emit: function emit(event, data) { + // we also want to trigger dom events + if (this.options.domEvents) { + triggerDomEvent(event, data); + } + + // no handlers, so skip it all + var handlers = this.handlers[event] && this.handlers[event].slice(); + if (!handlers || !handlers.length) { + return; + } + + data.type = event; + data.preventDefault = function () { + data.srcEvent.preventDefault(); + }; + + var i = 0; + while (i < handlers.length) { + handlers[i](data); + i++; + } + }, + + /** + * destroy the manager and unbinds all events + * it doesn't unbind dom events, that is the user own responsibility + */ + destroy: function destroy() { + this.element && toggleCssProps(this, false); + + this.handlers = {}; + this.session = {}; + this.input.destroy(); + this.element = null; + } + }; + + /** + * add/remove the css properties as defined in manager.options.cssProps + * @param {Manager} manager + * @param {Boolean} add + */ + function toggleCssProps(manager, add) { + var element = manager.element; + if (!element.style) { + return; + } + var prop; + each(manager.options.cssProps, function (value, name) { + prop = prefixed(element.style, name); + if (add) { + manager.oldCssProps[prop] = element.style[prop]; + element.style[prop] = value; + } else { + element.style[prop] = manager.oldCssProps[prop] || ''; + } + }); + if (!add) { + manager.oldCssProps = {}; + } + } + + /** + * trigger dom event + * @param {String} event + * @param {Object} data + */ + function triggerDomEvent(event, data) { + var gestureEvent = document.createEvent('Event'); + gestureEvent.initEvent(event, true, true); + gestureEvent.gesture = data; + data.target.dispatchEvent(gestureEvent); + } + + assign(Hammer, { + INPUT_START: INPUT_START, + INPUT_MOVE: INPUT_MOVE, + INPUT_END: INPUT_END, + INPUT_CANCEL: INPUT_CANCEL, + + STATE_POSSIBLE: STATE_POSSIBLE, + STATE_BEGAN: STATE_BEGAN, + STATE_CHANGED: STATE_CHANGED, + STATE_ENDED: STATE_ENDED, + STATE_RECOGNIZED: STATE_RECOGNIZED, + STATE_CANCELLED: STATE_CANCELLED, + STATE_FAILED: STATE_FAILED, + + DIRECTION_NONE: DIRECTION_NONE, + DIRECTION_LEFT: DIRECTION_LEFT, + DIRECTION_RIGHT: DIRECTION_RIGHT, + DIRECTION_UP: DIRECTION_UP, + DIRECTION_DOWN: DIRECTION_DOWN, + DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL, + DIRECTION_VERTICAL: DIRECTION_VERTICAL, + DIRECTION_ALL: DIRECTION_ALL, + + Manager: Manager, + Input: Input, + TouchAction: TouchAction, + + TouchInput: TouchInput, + MouseInput: MouseInput, + PointerEventInput: PointerEventInput, + TouchMouseInput: TouchMouseInput, + SingleTouchInput: SingleTouchInput, + + Recognizer: Recognizer, + AttrRecognizer: AttrRecognizer, + Tap: TapRecognizer, + Pan: PanRecognizer, + Swipe: SwipeRecognizer, + Pinch: PinchRecognizer, + Rotate: RotateRecognizer, + Press: PressRecognizer, + + on: addEventListeners, + off: removeEventListeners, + each: each, + merge: merge, + extend: extend, + assign: assign, + inherit: inherit, + bindFn: bindFn, + prefixed: prefixed + }); + + // this prevents errors when Hammer is loaded in the presence of an AMD + // style loader but by script tag, not by the loader. + var freeGlobal = typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}; // jshint ignore:line + freeGlobal.Hammer = Hammer; + + if (typeof define === 'function' && define.amd) { + define(function () { + return Hammer; + }); + } else if (typeof module != 'undefined' && module.exports) { + module.exports = Hammer; + } else { + window[exportName] = Hammer; + } +})(window, document, 'Hammer'); + +},{}],413:[function(require,module,exports){ +'use strict'; + +var hat = module.exports = function (bits, base) { + if (!base) base = 16; + if (bits === undefined) bits = 128; + if (bits <= 0) return '0'; + + var digits = Math.log(Math.pow(2, bits)) / Math.log(base); + for (var i = 2; digits === Infinity; i *= 2) { + digits = Math.log(Math.pow(2, bits / i)) / Math.log(base) * i; + } + + var rem = digits - Math.floor(digits); + + var res = ''; + + for (var i = 0; i < Math.floor(digits); i++) { + var x = Math.floor(Math.random() * base).toString(base); + res = x + res; + } + + if (rem) { + var b = Math.pow(base, rem); + var x = Math.floor(Math.random() * b).toString(base); + res = x + res; + } + + var parsed = parseInt(res, base); + if (parsed !== Infinity && parsed >= Math.pow(2, bits)) { + return hat(bits, base); + } else return res; +}; + +hat.rack = function (bits, base, expandBy) { + var fn = function fn(data) { + var iters = 0; + do { + if (iters++ > 10) { + if (expandBy) bits += expandBy;else throw new Error('too many ID collisions, use more bits'); + } + + var id = hat(bits, base); + } while (Object.hasOwnProperty.call(hats, id)); + + hats[id] = data; + return id; + }; + var hats = fn.hats = {}; + + fn.get = function (id) { + return fn.hats[id]; + }; + + fn.set = function (id, value) { + fn.hats[id] = value; + return fn; + }; + + fn.bits = bits || 128; + fn.base = base || 16; + return fn; +}; + +},{}],414:[function(require,module,exports){ +'use strict'; + +var hat = require('hat'); + +/** + * Create a new id generator / cache instance. + * + * You may optionally provide a seed that is used internally. + * + * @param {Seed} seed + */ +function Ids(seed) { + + if (!(this instanceof Ids)) { + return new Ids(seed); + } + + seed = seed || [128, 36, 1]; + this._seed = seed.length ? hat.rack(seed[0], seed[1], seed[2]) : seed; +} + +module.exports = Ids; + +/** + * Generate a next id. + * + * @param {Object} [element] element to bind the id to + * + * @return {String} id + */ +Ids.prototype.next = function (element) { + return this._seed(element || true); +}; + +/** + * Generate a next id with a given prefix. + * + * @param {Object} [element] element to bind the id to + * + * @return {String} id + */ +Ids.prototype.nextPrefixed = function (prefix, element) { + var id; + + do { + id = prefix + this.next(true); + } while (this.assigned(id)); + + // claim {prefix}{random} + this.claim(id, element); + + // return + return id; +}; + +/** + * Manually claim an existing id. + * + * @param {String} id + * @param {String} [element] element the id is claimed by + */ +Ids.prototype.claim = function (id, element) { + this._seed.set(id, element || true); +}; + +/** + * Returns true if the given id has already been assigned. + * + * @param {String} id + * @return {Boolean} + */ +Ids.prototype.assigned = function (id) { + return this._seed.get(id) || false; +}; + +/** + * Unclaim an id. + * + * @param {String} id the id to unclaim + */ +Ids.prototype.unclaim = function (id) { + delete this._seed.hats[id]; +}; + +/** + * Clear all claimed ids. + */ +Ids.prototype.clear = function () { + + var hats = this._seed.hats, + id; + + for (id in hats) { + this.unclaim(id); + } +}; + +},{"hat":413}],415:[function(require,module,exports){ +'use strict'; + +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor; + var TempCtor = function TempCtor() {}; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; + }; +} + +},{}],416:[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; }; + +/*! + * jQuery JavaScript Library v3.3.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2018-01-20T17:24Z + */ +(function (global, factory) { + + "use strict"; + + if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && _typeof(module.exports) === "object") { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? factory(global, true) : function (w) { + if (!w.document) { + throw new Error("jQuery requires a window with a document"); + } + return factory(w); + }; + } else { + factory(global); + } + + // Pass this if window is not defined yet +})(typeof window !== "undefined" ? window : undefined, function (window, noGlobal) { + + // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 + // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode + // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common + // enough that all such attempts are guarded in a try block. + "use strict"; + + var arr = []; + + var document = window.document; + + var getProto = Object.getPrototypeOf; + + var _slice = arr.slice; + + var concat = arr.concat; + + var push = arr.push; + + var indexOf = arr.indexOf; + + var class2type = {}; + + var toString = class2type.toString; + + var hasOwn = class2type.hasOwnProperty; + + var fnToString = hasOwn.toString; + + var ObjectFunctionString = fnToString.call(Object); + + var support = {}; + + var isFunction = function isFunction(obj) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + var isWindow = function isWindow(obj) { + return obj != null && obj === obj.window; + }; + + var preservedScriptAttributes = { + type: true, + src: true, + noModule: true + }; + + function DOMEval(code, doc, node) { + doc = doc || document; + + var i, + script = doc.createElement("script"); + + script.text = code; + if (node) { + for (i in preservedScriptAttributes) { + if (node[i]) { + script[i] = node[i]; + } + } + } + doc.head.appendChild(script).parentNode.removeChild(script); + } + + function toType(obj) { + if (obj == null) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return (typeof obj === "undefined" ? "undefined" : _typeof(obj)) === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj === "undefined" ? "undefined" : _typeof(obj); + } + /* global Symbol */ + // Defining this global in .eslintrc.json would create a danger of using the global + // unguarded in another place, it seems safer to define global only for this module + + + var version = "3.3.1", + + + // Define a local copy of jQuery + jQuery = function jQuery(selector, context) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init(selector, context); + }, + + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + + jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function toArray() { + return _slice.call(this); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function get(num) { + + // Return all the elements in a clean array + if (num == null) { + return _slice.call(this); + } + + // Return just the one element from the set + return num < 0 ? this[num + this.length] : this[num]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function pushStack(elems) { + + // Build a new jQuery matched element set + var ret = jQuery.merge(this.constructor(), elems); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function each(callback) { + return jQuery.each(this, callback); + }, + + map: function map(callback) { + return this.pushStack(jQuery.map(this, function (elem, i) { + return callback.call(elem, i, elem); + })); + }, + + slice: function slice() { + return this.pushStack(_slice.apply(this, arguments)); + }, + + first: function first() { + return this.eq(0); + }, + + last: function last() { + return this.eq(-1); + }, + + eq: function eq(i) { + var len = this.length, + j = +i + (i < 0 ? len : 0); + return this.pushStack(j >= 0 && j < len ? [this[j]] : []); + }, + + end: function end() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice + }; + + jQuery.extend = jQuery.fn.extend = function () { + var options, + name, + src, + copy, + copyIsArray, + clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if (typeof target === "boolean") { + deep = target; + + // Skip the boolean and the target + target = arguments[i] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ((typeof target === "undefined" ? "undefined" : _typeof(target)) !== "object" && !isFunction(target)) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if (i === length) { + target = this; + i--; + } + + for (; i < length; i++) { + + // Only deal with non-null/undefined values + if ((options = arguments[i]) != null) { + + // Extend the base object + for (name in options) { + src = target[name]; + copy = options[name]; + + // Prevent never-ending loop + if (target === copy) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) { + + if (copyIsArray) { + copyIsArray = false; + clone = src && Array.isArray(src) ? src : []; + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[name] = jQuery.extend(deep, clone, copy); + + // Don't bring in undefined values + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + + // Return the modified object + return target; + }; + + jQuery.extend({ + + // Unique for each copy of jQuery on the page + expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function error(msg) { + throw new Error(msg); + }, + + noop: function noop() {}, + + isPlainObject: function isPlainObject(obj) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if (!obj || toString.call(obj) !== "[object Object]") { + return false; + } + + proto = getProto(obj); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if (!proto) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call(proto, "constructor") && proto.constructor; + return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString; + }, + + isEmptyObject: function isEmptyObject(obj) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; + + for (name in obj) { + return false; + } + return true; + }, + + // Evaluates a script in a global context + globalEval: function globalEval(code) { + DOMEval(code); + }, + + each: function each(obj, callback) { + var length, + i = 0; + + if (isArrayLike(obj)) { + length = obj.length; + for (; i < length; i++) { + if (callback.call(obj[i], i, obj[i]) === false) { + break; + } + } + } else { + for (i in obj) { + if (callback.call(obj[i], i, obj[i]) === false) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function trim(text) { + return text == null ? "" : (text + "").replace(rtrim, ""); + }, + + // results is for internal usage only + makeArray: function makeArray(arr, results) { + var ret = results || []; + + if (arr != null) { + if (isArrayLike(Object(arr))) { + jQuery.merge(ret, typeof arr === "string" ? [arr] : arr); + } else { + push.call(ret, arr); + } + } + + return ret; + }, + + inArray: function inArray(elem, arr, i) { + return arr == null ? -1 : indexOf.call(arr, elem, i); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function merge(first, second) { + var len = +second.length, + j = 0, + i = first.length; + + for (; j < len; j++) { + first[i++] = second[j]; + } + + first.length = i; + + return first; + }, + + grep: function grep(elems, callback, invert) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for (; i < length; i++) { + callbackInverse = !callback(elems[i], i); + if (callbackInverse !== callbackExpect) { + matches.push(elems[i]); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function map(elems, callback, arg) { + var length, + value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if (isArrayLike(elems)) { + length = elems.length; + for (; i < length; i++) { + value = callback(elems[i], i, arg); + + if (value != null) { + ret.push(value); + } + } + + // Go through every key on the object, + } else { + for (i in elems) { + value = callback(elems[i], i, arg); + + if (value != null) { + ret.push(value); + } + } + } + + // Flatten any nested arrays + return concat.apply([], ret); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support + }); + + if (typeof Symbol === "function") { + jQuery.fn[Symbol.iterator] = arr[Symbol.iterator]; + } + + // Populate the class2type map + jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (i, name) { + class2type["[object " + name + "]"] = name.toLowerCase(); + }); + + function isArrayLike(obj) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType(obj); + + if (isFunction(obj) || isWindow(obj)) { + return false; + } + + return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj; + } + var Sizzle = + /*! + * Sizzle CSS Selector Engine v2.3.3 + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-08-08 + */ + function (window) { + + var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function sortOrder(a, b) { + if (a === b) { + hasDuplicate = true; + } + return 0; + }, + + + // Instance methods + hasOwn = {}.hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function indexOf(list, elem) { + var i = 0, + len = list.length; + for (; i < len; i++) { + if (list[i] === elem) { + return i; + } + } + return -1; + }, + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + ")\\)|)", + + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp(whitespace + "+", "g"), + rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"), + rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"), + rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"), + rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"), + rpseudo = new RegExp(pseudos), + ridentifier = new RegExp("^" + identifier + "$"), + matchExpr = { + "ID": new RegExp("^#(" + identifier + ")"), + "CLASS": new RegExp("^\\.(" + identifier + ")"), + "TAG": new RegExp("^(" + identifier + "|[*])"), + "ATTR": new RegExp("^" + attributes), + "PSEUDO": new RegExp("^" + pseudos), + "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"), + "bool": new RegExp("^(?:" + booleans + ")$", "i"), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i") + }, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + rnative = /^[^{]+\{\s*\[native \w/, + + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + rsibling = /[+~]/, + + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"), + funescape = function funescape(_, escaped, escapedWhitespace) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? escaped : high < 0 ? + // BMP codepoint + String.fromCharCode(high + 0x10000) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00); + }, + + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function fcssescape(ch, asCodePoint) { + if (asCodePoint) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if (ch === "\0") { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function unloadHandler() { + setDocument(); + }, + disabledAncestor = addCombinator(function (elem) { + return elem.disabled === true && ("form" in elem || "label" in elem); + }, { dir: "parentNode", next: "legend" }); + + // Optimize for push.apply( _, NodeList ) + try { + push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[preferredDoc.childNodes.length].nodeType; + } catch (e) { + push = { apply: arr.length ? + + // Leverage slice if possible + function (target, els) { + push_native.apply(target, slice.call(els)); + } : + + // Support: IE<9 + // Otherwise append directly + function (target, els) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while (target[j++] = els[i++]) {} + target.length = j - 1; + } + }; + } + + function Sizzle(selector, context, results, seed) { + var m, + i, + elem, + nid, + match, + groups, + newSelector, + newContext = context && context.ownerDocument, + + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if (!seed) { + + if ((context ? context.ownerDocument || context : preferredDoc) !== document) { + setDocument(context); + } + context = context || document; + + if (documentIsHTML) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if (nodeType !== 11 && (match = rquickExpr.exec(selector))) { + + // ID selector + if (m = match[1]) { + + // Document context + if (nodeType === 9) { + if (elem = context.getElementById(m)) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if (elem.id === m) { + results.push(elem); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) { + + results.push(elem); + return results; + } + } + + // Type selector + } else if (match[2]) { + push.apply(results, context.getElementsByTagName(selector)); + return results; + + // Class selector + } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) { + + push.apply(results, context.getElementsByClassName(m)); + return results; + } + } + + // Take advantage of querySelectorAll + if (support.qsa && !compilerCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) { + + if (nodeType !== 1) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if (context.nodeName.toLowerCase() !== "object") { + + // Capture the context ID, setting it first if necessary + if (nid = context.getAttribute("id")) { + nid = nid.replace(rcssescape, fcssescape); + } else { + context.setAttribute("id", nid = expando); + } + + // Prefix every selector in the list + groups = tokenize(selector); + i = groups.length; + while (i--) { + groups[i] = "#" + nid + " " + toSelector(groups[i]); + } + newSelector = groups.join(","); + + // Expand context for sibling selectors + newContext = rsibling.test(selector) && testContext(context.parentNode) || context; + } + + if (newSelector) { + try { + push.apply(results, newContext.querySelectorAll(newSelector)); + return results; + } catch (qsaError) {} finally { + if (nid === expando) { + context.removeAttribute("id"); + } + } + } + } + } + } + + // All others + return select(selector.replace(rtrim, "$1"), context, results, seed); + } + + /** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ + function createCache() { + var keys = []; + + function cache(key, value) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if (keys.push(key + " ") > Expr.cacheLength) { + // Only keep the most recent entries + delete cache[keys.shift()]; + } + return cache[key + " "] = value; + } + return cache; + } + + /** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ + function markFunction(fn) { + fn[expando] = true; + return fn; + } + + /** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ + function assert(fn) { + var el = document.createElement("fieldset"); + + try { + return !!fn(el); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if (el.parentNode) { + el.parentNode.removeChild(el); + } + // release memory in IE + el = null; + } + } + + /** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ + function addHandle(attrs, handler) { + var arr = attrs.split("|"), + i = arr.length; + + while (i--) { + Expr.attrHandle[arr[i]] = handler; + } + } + + /** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ + function siblingCheck(a, b) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if (diff) { + return diff; + } + + // Check if b follows a + if (cur) { + while (cur = cur.nextSibling) { + if (cur === b) { + return -1; + } + } + } + + return a ? 1 : -1; + } + + /** + * Returns a function to use in pseudos for input types + * @param {String} type + */ + function createInputPseudo(type) { + return function (elem) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; + } + + /** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ + function createButtonPseudo(type) { + return function (elem) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; + } + + /** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ + function createDisabledPseudo(disabled) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function (elem) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ("form" in elem) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if (elem.parentNode && elem.disabled === false) { + + // Option elements defer to a parent optgroup if present + if ("label" in elem) { + if ("label" in elem.parentNode) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && disabledAncestor(elem) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ("label" in elem) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; + } + + /** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ + function createPositionalPseudo(fn) { + return markFunction(function (argument) { + argument = +argument; + return markFunction(function (seed, matches) { + var j, + matchIndexes = fn([], seed.length, argument), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while (i--) { + if (seed[j = matchIndexes[i]]) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); + } + + /** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ + function testContext(context) { + return context && typeof context.getElementsByTagName !== "undefined" && context; + } + + // Expose support vars for convenience + support = Sizzle.support = {}; + + /** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ + isXML = Sizzle.isXML = function (elem) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; + }; + + /** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ + setDocument = Sizzle.setDocument = function (node) { + var hasCompare, + subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if (doc === document || doc.nodeType !== 9 || !doc.documentElement) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML(document); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if (preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow) { + + // Support: IE 11, Edge + if (subWindow.addEventListener) { + subWindow.addEventListener("unload", unloadHandler, false); + + // Support: IE 9 - 10 only + } else if (subWindow.attachEvent) { + subWindow.attachEvent("onunload", unloadHandler); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function (el) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function (el) { + el.appendChild(document.createComment("")); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test(document.getElementsByClassName); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function (el) { + docElem.appendChild(el).id = expando; + return !document.getElementsByName || !document.getElementsByName(expando).length; + }); + + // ID filter and find + if (support.getById) { + Expr.filter["ID"] = function (id) { + var attrId = id.replace(runescape, funescape); + return function (elem) { + return elem.getAttribute("id") === attrId; + }; + }; + Expr.find["ID"] = function (id, context) { + if (typeof context.getElementById !== "undefined" && documentIsHTML) { + var elem = context.getElementById(id); + return elem ? [elem] : []; + } + }; + } else { + Expr.filter["ID"] = function (id) { + var attrId = id.replace(runescape, funescape); + return function (elem) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find["ID"] = function (id, context) { + if (typeof context.getElementById !== "undefined" && documentIsHTML) { + var node, + i, + elems, + elem = context.getElementById(id); + + if (elem) { + + // Verify the id attribute + node = elem.getAttributeNode("id"); + if (node && node.value === id) { + return [elem]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName(id); + i = 0; + while (elem = elems[i++]) { + node = elem.getAttributeNode("id"); + if (node && node.value === id) { + return [elem]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) { + if (typeof context.getElementsByTagName !== "undefined") { + return context.getElementsByTagName(tag); + + // DocumentFragment nodes don't have gEBTN + } else if (support.qsa) { + return context.querySelectorAll(tag); + } + } : function (tag, context) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName(tag); + + // Filter out possible comments + if (tag === "*") { + while (elem = results[i++]) { + if (elem.nodeType === 1) { + tmp.push(elem); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) { + if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) { + return context.getElementsByClassName(className); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if (support.qsa = rnative.test(document.querySelectorAll)) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function (el) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild(el).innerHTML = "" + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if (el.querySelectorAll("[msallowcapture^='']").length) { + rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")"); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if (!el.querySelectorAll("[selected]").length) { + rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")"); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if (!el.querySelectorAll("[id~=" + expando + "-]").length) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if (!el.querySelectorAll(":checked").length) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if (!el.querySelectorAll("a#" + expando + "+*").length) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function (el) { + el.innerHTML = "" + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute("type", "hidden"); + el.appendChild(input).setAttribute("name", "D"); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if (el.querySelectorAll("[name=d]").length) { + rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?="); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if (el.querySelectorAll(":enabled").length !== 2) { + rbuggyQSA.push(":enabled", ":disabled"); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild(el).disabled = true; + if (el.querySelectorAll(":disabled").length !== 2) { + rbuggyQSA.push(":enabled", ":disabled"); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) { + + assert(function (el) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call(el, "*"); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call(el, "[s!='']:x"); + rbuggyMatches.push("!=", pseudos); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|")); + rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|")); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test(docElem.compareDocumentPosition); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16)); + } : function (a, b) { + if (b) { + while (b = b.parentNode) { + if (b === a) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? function (a, b) { + + // Flag for duplicate removal + if (a === b) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if (compare) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) { + + // Choose the first element that is related to our preferred document + if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) { + return -1; + } + if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) { + return 1; + } + + // Maintain original order + return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; + } + + return compare & 4 ? -1 : 1; + } : function (a, b) { + // Exit early if the nodes are identical + if (a === b) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [a], + bp = [b]; + + // Parentless nodes are either documents or disconnected + if (!aup || !bup) { + return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; + + // If the nodes are siblings, we can do a quick check + } else if (aup === bup) { + return siblingCheck(a, b); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while (cur = cur.parentNode) { + ap.unshift(cur); + } + cur = b; + while (cur = cur.parentNode) { + bp.unshift(cur); + } + + // Walk down the tree looking for a discrepancy + while (ap[i] === bp[i]) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck(ap[i], bp[i]) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; + }; + + return document; + }; + + Sizzle.matches = function (expr, elements) { + return Sizzle(expr, null, null, elements); + }; + + Sizzle.matchesSelector = function (elem, expr) { + // Set document vars if needed + if ((elem.ownerDocument || elem) !== document) { + setDocument(elem); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace(rattributeQuotes, "='$1']"); + + if (support.matchesSelector && documentIsHTML && !compilerCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) { + + try { + var ret = matches.call(elem, expr); + + // IE 9's matchesSelector returns false on disconnected nodes + if (ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11) { + return ret; + } + } catch (e) {} + } + + return Sizzle(expr, document, null, [elem]).length > 0; + }; + + Sizzle.contains = function (context, elem) { + // Set document vars if needed + if ((context.ownerDocument || context) !== document) { + setDocument(context); + } + return contains(context, elem); + }; + + Sizzle.attr = function (elem, name) { + // Set document vars if needed + if ((elem.ownerDocument || elem) !== document) { + setDocument(elem); + } + + var fn = Expr.attrHandle[name.toLowerCase()], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined; + + return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; + }; + + Sizzle.escape = function (sel) { + return (sel + "").replace(rcssescape, fcssescape); + }; + + Sizzle.error = function (msg) { + throw new Error("Syntax error, unrecognized expression: " + msg); + }; + + /** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ + Sizzle.uniqueSort = function (results) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice(0); + results.sort(sortOrder); + + if (hasDuplicate) { + while (elem = results[i++]) { + if (elem === results[i]) { + j = duplicates.push(i); + } + } + while (j--) { + results.splice(duplicates[j], 1); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; + }; + + /** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ + getText = Sizzle.getText = function (elem) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if (!nodeType) { + // If no nodeType, this is expected to be an array + while (node = elem[i++]) { + // Do not traverse comment nodes + ret += getText(node); + } + } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if (typeof elem.textContent === "string") { + return elem.textContent; + } else { + // Traverse its children + for (elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText(elem); + } + } + } else if (nodeType === 3 || nodeType === 4) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; + }; + + Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function ATTR(match) { + match[1] = match[1].replace(runescape, funescape); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape); + + if (match[2] === "~=") { + match[3] = " " + match[3] + " "; + } + + return match.slice(0, 4); + }, + + "CHILD": function CHILD(match) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if (match[1].slice(0, 3) === "nth") { + // nth-* requires argument + if (!match[3]) { + Sizzle.error(match[0]); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd")); + match[5] = +(match[7] + match[8] || match[3] === "odd"); + + // other types prohibit arguments + } else if (match[3]) { + Sizzle.error(match[0]); + } + + return match; + }, + + "PSEUDO": function PSEUDO(match) { + var excess, + unquoted = !match[6] && match[2]; + + if (matchExpr["CHILD"].test(match[0])) { + return null; + } + + // Accept quoted arguments as-is + if (match[3]) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if (unquoted && rpseudo.test(unquoted) && ( + // Get excess from tokenize (recursively) + excess = tokenize(unquoted, true)) && ( + // advance to the next closing parenthesis + excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) { + + // excess is a negative index + match[0] = match[0].slice(0, excess); + match[2] = unquoted.slice(0, excess); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice(0, 3); + } + }, + + filter: { + + "TAG": function TAG(nodeNameSelector) { + var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); + return nodeNameSelector === "*" ? function () { + return true; + } : function (elem) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function CLASS(className) { + var pattern = classCache[className + " "]; + + return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) { + return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || ""); + }); + }, + + "ATTR": function ATTR(name, operator, check) { + return function (elem) { + var result = Sizzle.attr(elem, name); + + if (result == null) { + return operator === "!="; + } + if (!operator) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false; + }; + }, + + "CHILD": function CHILD(type, what, argument, first, last) { + var simple = type.slice(0, 3) !== "nth", + forward = type.slice(-4) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function (elem) { + return !!elem.parentNode; + } : function (elem, context, xml) { + var cache, + uniqueCache, + outerCache, + node, + nodeIndex, + start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if (parent) { + + // :(first|last|only)-(child|of-type) + if (simple) { + while (dir) { + node = elem; + while (node = node[dir]) { + if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [forward ? parent.firstChild : parent.lastChild]; + + // non-xml :nth-child(...) stores cache data on `parent` + if (forward && useCache) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[expando] || (node[expando] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); + + cache = uniqueCache[type] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = nodeIndex && cache[2]; + node = nodeIndex && parent.childNodes[nodeIndex]; + + while (node = ++nodeIndex && node && node[dir] || ( + + // Fallback to seeking `elem` from the start + diff = nodeIndex = 0) || start.pop()) { + + // When found, cache indexes on `parent` and break + if (node.nodeType === 1 && ++diff && node === elem) { + uniqueCache[type] = [dirruns, nodeIndex, diff]; + break; + } + } + } else { + // Use previously-cached element index if available + if (useCache) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[expando] || (node[expando] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); + + cache = uniqueCache[type] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if (diff === false) { + // Use the same loop as above to seek `elem` from the start + while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { + + if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) { + + // Cache the index of each encountered element + if (useCache) { + outerCache = node[expando] || (node[expando] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); + + uniqueCache[type] = [dirruns, diff]; + } + + if (node === elem) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || diff % first === 0 && diff / first >= 0; + } + }; + }, + + "PSEUDO": function PSEUDO(pseudo, argument) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if (fn[expando]) { + return fn(argument); + } + + // But maintain support for old signatures + if (fn.length > 1) { + args = [pseudo, pseudo, "", argument]; + return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) { + var idx, + matched = fn(seed, argument), + i = matched.length; + while (i--) { + idx = indexOf(seed, matched[i]); + seed[idx] = !(matches[idx] = matched[i]); + } + }) : function (elem) { + return fn(elem, 0, args); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function (selector) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile(selector.replace(rtrim, "$1")); + + return matcher[expando] ? markFunction(function (seed, matches, context, xml) { + var elem, + unmatched = matcher(seed, null, xml, []), + i = seed.length; + + // Match elements unmatched by `matcher` + while (i--) { + if (elem = unmatched[i]) { + seed[i] = !(matches[i] = elem); + } + } + }) : function (elem, context, xml) { + input[0] = elem; + matcher(input, null, xml, results); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function (selector) { + return function (elem) { + return Sizzle(selector, elem).length > 0; + }; + }), + + "contains": markFunction(function (text) { + text = text.replace(runescape, funescape); + return function (elem) { + return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction(function (lang) { + // lang value must be a valid identifier + if (!ridentifier.test(lang || "")) { + Sizzle.error("unsupported lang: " + lang); + } + lang = lang.replace(runescape, funescape).toLowerCase(); + return function (elem) { + var elemLang; + do { + if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf(lang + "-") === 0; + } + } while ((elem = elem.parentNode) && elem.nodeType === 1); + return false; + }; + }), + + // Miscellaneous + "target": function target(elem) { + var hash = window.location && window.location.hash; + return hash && hash.slice(1) === elem.id; + }, + + "root": function root(elem) { + return elem === docElem; + }, + + "focus": function focus(elem) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo(false), + "disabled": createDisabledPseudo(true), + + "checked": function checked(elem) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected; + }, + + "selected": function selected(elem) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if (elem.parentNode) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function empty(elem) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for (elem = elem.firstChild; elem; elem = elem.nextSibling) { + if (elem.nodeType < 6) { + return false; + } + } + return true; + }, + + "parent": function parent(elem) { + return !Expr.pseudos["empty"](elem); + }, + + // Element/input types + "header": function header(elem) { + return rheader.test(elem.nodeName); + }, + + "input": function input(elem) { + return rinputs.test(elem.nodeName); + }, + + "button": function button(elem) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function text(elem) { + var attr; + return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text"); + }, + + // Position-in-collection + "first": createPositionalPseudo(function () { + return [0]; + }), + + "last": createPositionalPseudo(function (matchIndexes, length) { + return [length - 1]; + }), + + "eq": createPositionalPseudo(function (matchIndexes, length, argument) { + return [argument < 0 ? argument + length : argument]; + }), + + "even": createPositionalPseudo(function (matchIndexes, length) { + var i = 0; + for (; i < length; i += 2) { + matchIndexes.push(i); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function (matchIndexes, length) { + var i = 1; + for (; i < length; i += 2) { + matchIndexes.push(i); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function (matchIndexes, length, argument) { + var i = argument < 0 ? argument + length : argument; + for (; --i >= 0;) { + matchIndexes.push(i); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function (matchIndexes, length, argument) { + var i = argument < 0 ? argument + length : argument; + for (; ++i < length;) { + matchIndexes.push(i); + } + return matchIndexes; + }) + } + }; + + Expr.pseudos["nth"] = Expr.pseudos["eq"]; + + // Add button/input type pseudos + for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) { + Expr.pseudos[i] = createInputPseudo(i); + } + for (i in { submit: true, reset: true }) { + Expr.pseudos[i] = createButtonPseudo(i); + } + + // Easy API for creating new setFilters + function setFilters() {} + setFilters.prototype = Expr.filters = Expr.pseudos; + Expr.setFilters = new setFilters(); + + tokenize = Sizzle.tokenize = function (selector, parseOnly) { + var matched, + match, + tokens, + type, + soFar, + groups, + preFilters, + cached = tokenCache[selector + " "]; + + if (cached) { + return parseOnly ? 0 : cached.slice(0); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while (soFar) { + + // Comma and first run + if (!matched || (match = rcomma.exec(soFar))) { + if (match) { + // Don't consume trailing commas as valid + soFar = soFar.slice(match[0].length) || soFar; + } + groups.push(tokens = []); + } + + matched = false; + + // Combinators + if (match = rcombinators.exec(soFar)) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace(rtrim, " ") + }); + soFar = soFar.slice(matched.length); + } + + // Filters + for (type in Expr.filter) { + if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice(matched.length); + } + } + + if (!matched) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : + // Cache the tokens + tokenCache(selector, groups).slice(0); + }; + + function toSelector(tokens) { + var i = 0, + len = tokens.length, + selector = ""; + for (; i < len; i++) { + selector += tokens[i].value; + } + return selector; + } + + function addCombinator(matcher, combinator, base) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function (elem, context, xml) { + while (elem = elem[dir]) { + if (elem.nodeType === 1 || checkNonElements) { + return matcher(elem, context, xml); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function (elem, context, xml) { + var oldCache, + uniqueCache, + outerCache, + newCache = [dirruns, doneName]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if (xml) { + while (elem = elem[dir]) { + if (elem.nodeType === 1 || checkNonElements) { + if (matcher(elem, context, xml)) { + return true; + } + } + } + } else { + while (elem = elem[dir]) { + if (elem.nodeType === 1 || checkNonElements) { + outerCache = elem[expando] || (elem[expando] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {}); + + if (skip && skip === elem.nodeName.toLowerCase()) { + elem = elem[dir] || elem; + } else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) { + + // Assign to newCache so results back-propagate to previous elements + return newCache[2] = oldCache[2]; + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[key] = newCache; + + // A match means we're done; a fail means we have to keep checking + if (newCache[2] = matcher(elem, context, xml)) { + return true; + } + } + } + } + } + return false; + }; + } + + function elementMatcher(matchers) { + return matchers.length > 1 ? function (elem, context, xml) { + var i = matchers.length; + while (i--) { + if (!matchers[i](elem, context, xml)) { + return false; + } + } + return true; + } : matchers[0]; + } + + function multipleContexts(selector, contexts, results) { + var i = 0, + len = contexts.length; + for (; i < len; i++) { + Sizzle(selector, contexts[i], results); + } + return results; + } + + function condense(unmatched, map, filter, context, xml) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for (; i < len; i++) { + if (elem = unmatched[i]) { + if (!filter || filter(elem, context, xml)) { + newUnmatched.push(elem); + if (mapped) { + map.push(i); + } + } + } + } + + return newUnmatched; + } + + function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { + if (postFilter && !postFilter[expando]) { + postFilter = setMatcher(postFilter); + } + if (postFinder && !postFinder[expando]) { + postFinder = setMatcher(postFinder, postSelector); + } + return markFunction(function (seed, results, context, xml) { + var temp, + i, + elem, + preMap = [], + postMap = [], + preexisting = results.length, + + + // Get initial elements from seed or context + elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []), + + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || (seed ? preFilter : preexisting || postFilter) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : matcherIn; + + // Find primary matches + if (matcher) { + matcher(matcherIn, matcherOut, context, xml); + } + + // Apply postFilter + if (postFilter) { + temp = condense(matcherOut, postMap); + postFilter(temp, [], context, xml); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while (i--) { + if (elem = temp[i]) { + matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); + } + } + } + + if (seed) { + if (postFinder || preFilter) { + if (postFinder) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while (i--) { + if (elem = matcherOut[i]) { + // Restore matcherIn since elem is not yet a final match + temp.push(matcherIn[i] = elem); + } + } + postFinder(null, matcherOut = [], temp, xml); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while (i--) { + if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut); + if (postFinder) { + postFinder(null, results, matcherOut, xml); + } else { + push.apply(results, matcherOut); + } + } + }); + } + + function matcherFromTokens(tokens) { + var checkContext, + matcher, + j, + len = tokens.length, + leadingRelative = Expr.relative[tokens[0].type], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator(function (elem) { + return elem === checkContext; + }, implicitRelative, true), + matchAnyContext = addCombinator(function (elem) { + return indexOf(checkContext, elem) > -1; + }, implicitRelative, true), + matchers = [function (elem, context, xml) { + var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + }]; + + for (; i < len; i++) { + if (matcher = Expr.relative[tokens[i].type]) { + matchers = [addCombinator(elementMatcher(matchers), matcher)]; + } else { + matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); + + // Return special upon seeing a positional matcher + if (matcher[expando]) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for (; j < len; j++) { + if (Expr.relative[tokens[j].type]) { + break; + } + } + return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === " " ? "*" : "" })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens)); + } + matchers.push(matcher); + } + } + + return elementMatcher(matchers); + } + + function matcherFromGroupMatchers(elementMatchers, setMatchers) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function superMatcher(seed, context, xml, results, outermost) { + var elem, + j, + matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]("*", outermost), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, + len = elems.length; + + if (outermost) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for (; i !== len && (elem = elems[i]) != null; i++) { + if (byElement && elem) { + j = 0; + if (!context && elem.ownerDocument !== document) { + setDocument(elem); + xml = !documentIsHTML; + } + while (matcher = elementMatchers[j++]) { + if (matcher(elem, context || document, xml)) { + results.push(elem); + break; + } + } + if (outermost) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if (bySet) { + // They will have gone through all possible matchers + if (elem = !matcher && elem) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if (seed) { + unmatched.push(elem); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if (bySet && i !== matchedCount) { + j = 0; + while (matcher = setMatchers[j++]) { + matcher(unmatched, setMatched, context, xml); + } + + if (seed) { + // Reintegrate element matches to eliminate the need for sorting + if (matchedCount > 0) { + while (i--) { + if (!(unmatched[i] || setMatched[i])) { + setMatched[i] = pop.call(results); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense(setMatched); + } + + // Add matches to results + push.apply(results, setMatched); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) { + + Sizzle.uniqueSort(results); + } + } + + // Override manipulation of globals by nested matchers + if (outermost) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? markFunction(superMatcher) : superMatcher; + } + + compile = Sizzle.compile = function (selector, match /* Internal Use Only */) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[selector + " "]; + + if (!cached) { + // Generate a function of recursive functions that can be used to check each element + if (!match) { + match = tokenize(selector); + } + i = match.length; + while (i--) { + cached = matcherFromTokens(match[i]); + if (cached[expando]) { + setMatchers.push(cached); + } else { + elementMatchers.push(cached); + } + } + + // Cache the compiled function + cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; + }; + + /** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ + select = Sizzle.select = function (selector, context, results, seed) { + var i, + tokens, + token, + type, + find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize(selector = compiled.selector || selector); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if (match.length === 1) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice(0); + if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { + + context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0]; + if (!context) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if (compiled) { + context = context.parentNode; + } + + selector = selector.slice(tokens.shift().value.length); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length; + while (i--) { + token = tokens[i]; + + // Abort if we hit a combinator + if (Expr.relative[type = token.type]) { + break; + } + if (find = Expr.find[type]) { + // Search, expanding context for leading sibling combinators + if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice(i, 1); + selector = seed.length && toSelector(tokens); + if (!selector) { + push.apply(results, seed); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context); + return results; + }; + + // One-time assignments + + // Sort stability + support.sortStable = expando.split("").sort(sortOrder).join("") === expando; + + // Support: Chrome 14-35+ + // Always assume duplicates if they aren't passed to the comparison function + support.detectDuplicates = !!hasDuplicate; + + // Initialize against the default document + setDocument(); + + // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) + // Detached nodes confoundingly follow *each other* + support.sortDetached = assert(function (el) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition(document.createElement("fieldset")) & 1; + }); + + // Support: IE<8 + // Prevent attribute/property "interpolation" + // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx + if (!assert(function (el) { + el.innerHTML = ""; + return el.firstChild.getAttribute("href") === "#"; + })) { + addHandle("type|href|height|width", function (elem, name, isXML) { + if (!isXML) { + return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2); + } + }); + } + + // Support: IE<9 + // Use defaultValue in place of getAttribute("value") + if (!support.attributes || !assert(function (el) { + el.innerHTML = ""; + el.firstChild.setAttribute("value", ""); + return el.firstChild.getAttribute("value") === ""; + })) { + addHandle("value", function (elem, name, isXML) { + if (!isXML && elem.nodeName.toLowerCase() === "input") { + return elem.defaultValue; + } + }); + } + + // Support: IE<9 + // Use getAttributeNode to fetch booleans when getAttribute lies + if (!assert(function (el) { + return el.getAttribute("disabled") == null; + })) { + addHandle(booleans, function (elem, name, isXML) { + var val; + if (!isXML) { + return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; + } + }); + } + + return Sizzle; + }(window); + + jQuery.find = Sizzle; + jQuery.expr = Sizzle.selectors; + + // Deprecated + jQuery.expr[":"] = jQuery.expr.pseudos; + jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; + jQuery.text = Sizzle.getText; + jQuery.isXMLDoc = Sizzle.isXML; + jQuery.contains = Sizzle.contains; + jQuery.escapeSelector = Sizzle.escape; + + var dir = function dir(elem, _dir, until) { + var matched = [], + truncate = until !== undefined; + + while ((elem = elem[_dir]) && elem.nodeType !== 9) { + if (elem.nodeType === 1) { + if (truncate && jQuery(elem).is(until)) { + break; + } + matched.push(elem); + } + } + return matched; + }; + + var _siblings = function _siblings(n, elem) { + var matched = []; + + for (; n; n = n.nextSibling) { + if (n.nodeType === 1 && n !== elem) { + matched.push(n); + } + } + + return matched; + }; + + var rneedsContext = jQuery.expr.match.needsContext; + + function nodeName(elem, name) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }; + var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; + + // Implement the identical functionality for filter and not + function winnow(elements, qualifier, not) { + if (isFunction(qualifier)) { + return jQuery.grep(elements, function (elem, i) { + return !!qualifier.call(elem, i, elem) !== not; + }); + } + + // Single element + if (qualifier.nodeType) { + return jQuery.grep(elements, function (elem) { + return elem === qualifier !== not; + }); + } + + // Arraylike of elements (jQuery, arguments, Array) + if (typeof qualifier !== "string") { + return jQuery.grep(elements, function (elem) { + return indexOf.call(qualifier, elem) > -1 !== not; + }); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter(qualifier, elements, not); + } + + jQuery.filter = function (expr, elems, not) { + var elem = elems[0]; + + if (not) { + expr = ":not(" + expr + ")"; + } + + if (elems.length === 1 && elem.nodeType === 1) { + return jQuery.find.matchesSelector(elem, expr) ? [elem] : []; + } + + return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) { + return elem.nodeType === 1; + })); + }; + + jQuery.fn.extend({ + find: function find(selector) { + var i, + ret, + len = this.length, + self = this; + + if (typeof selector !== "string") { + return this.pushStack(jQuery(selector).filter(function () { + for (i = 0; i < len; i++) { + if (jQuery.contains(self[i], this)) { + return true; + } + } + })); + } + + ret = this.pushStack([]); + + for (i = 0; i < len; i++) { + jQuery.find(selector, self[i], ret); + } + + return len > 1 ? jQuery.uniqueSort(ret) : ret; + }, + filter: function filter(selector) { + return this.pushStack(winnow(this, selector || [], false)); + }, + not: function not(selector) { + return this.pushStack(winnow(this, selector || [], true)); + }, + is: function is(selector) { + return !!winnow(this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length; + } + }); + + // Initialize a jQuery object + + + // A central reference to the root jQuery(document) + var rootjQuery, + + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + init = jQuery.fn.init = function (selector, context, root) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if (!selector) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if (typeof selector === "string") { + if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [null, selector, null]; + } else { + match = rquickExpr.exec(selector); + } + + // Match html or make sure no context is specified for #id + if (match && (match[1] || !context)) { + + // HANDLE: $(html) -> $(array) + if (match[1]) { + context = context instanceof jQuery ? context[0] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true)); + + // HANDLE: $(html, props) + if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { + for (match in context) { + + // Properties of context are called as methods if possible + if (isFunction(this[match])) { + this[match](context[match]); + + // ...and otherwise set as attributes + } else { + this.attr(match, context[match]); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById(match[2]); + + if (elem) { + + // Inject the element directly into the jQuery object + this[0] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if (!context || context.jquery) { + return (context || root).find(selector); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor(context).find(selector); + } + + // HANDLE: $(DOMElement) + } else if (selector.nodeType) { + this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if (isFunction(selector)) { + return root.ready !== undefined ? root.ready(selector) : + + // Execute immediately if ready is not present + selector(jQuery); + } + + return jQuery.makeArray(selector, this); + }; + + // Give the init function the jQuery prototype for later instantiation + init.prototype = jQuery.fn; + + // Initialize central reference + rootjQuery = jQuery(document); + + var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + + jQuery.fn.extend({ + has: function has(target) { + var targets = jQuery(target, this), + l = targets.length; + + return this.filter(function () { + var i = 0; + for (; i < l; i++) { + if (jQuery.contains(this, targets[i])) { + return true; + } + } + }); + }, + + closest: function closest(selectors, context) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery(selectors); + + // Positional selectors never match, since there's no _selection_ context + if (!rneedsContext.test(selectors)) { + for (; i < l; i++) { + for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { + + // Always skip document fragments + if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) { + + matched.push(cur); + break; + } + } + } + } + + return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched); + }, + + // Determine the position of an element within the set + index: function index(elem) { + + // No argument, return index in parent + if (!elem) { + return this[0] && this[0].parentNode ? this.first().prevAll().length : -1; + } + + // Index in selector + if (typeof elem === "string") { + return indexOf.call(jQuery(elem), this[0]); + } + + // Locate the position of the desired element + return indexOf.call(this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem); + }, + + add: function add(selector, context) { + return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context)))); + }, + + addBack: function addBack(selector) { + return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector)); + } + }); + + function sibling(cur, dir) { + while ((cur = cur[dir]) && cur.nodeType !== 1) {} + return cur; + } + + jQuery.each({ + parent: function parent(elem) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function parents(elem) { + return dir(elem, "parentNode"); + }, + parentsUntil: function parentsUntil(elem, i, until) { + return dir(elem, "parentNode", until); + }, + next: function next(elem) { + return sibling(elem, "nextSibling"); + }, + prev: function prev(elem) { + return sibling(elem, "previousSibling"); + }, + nextAll: function nextAll(elem) { + return dir(elem, "nextSibling"); + }, + prevAll: function prevAll(elem) { + return dir(elem, "previousSibling"); + }, + nextUntil: function nextUntil(elem, i, until) { + return dir(elem, "nextSibling", until); + }, + prevUntil: function prevUntil(elem, i, until) { + return dir(elem, "previousSibling", until); + }, + siblings: function siblings(elem) { + return _siblings((elem.parentNode || {}).firstChild, elem); + }, + children: function children(elem) { + return _siblings(elem.firstChild); + }, + contents: function contents(elem) { + if (nodeName(elem, "iframe")) { + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if (nodeName(elem, "template")) { + elem = elem.content || elem; + } + + return jQuery.merge([], elem.childNodes); + } + }, function (name, fn) { + jQuery.fn[name] = function (until, selector) { + var matched = jQuery.map(this, fn, until); + + if (name.slice(-5) !== "Until") { + selector = until; + } + + if (selector && typeof selector === "string") { + matched = jQuery.filter(selector, matched); + } + + if (this.length > 1) { + + // Remove duplicates + if (!guaranteedUnique[name]) { + jQuery.uniqueSort(matched); + } + + // Reverse order for parents* and prev-derivatives + if (rparentsprev.test(name)) { + matched.reverse(); + } + } + + return this.pushStack(matched); + }; + }); + var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; + + // Convert String-formatted options into Object-formatted ones + function createOptions(options) { + var object = {}; + jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) { + object[flag] = true; + }); + return object; + } + + /* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ + jQuery.Callbacks = function (options) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options); + + var // Flag to know if list is currently firing + firing, + + + // Last fire value for non-forgettable lists + memory, + + + // Flag to know if list was already fired + _fired, + + + // Flag to prevent firing + _locked, + + + // Actual callback list + list = [], + + + // Queue of execution data for repeatable lists + queue = [], + + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + + // Fire callbacks + fire = function fire() { + + // Enforce single-firing + _locked = _locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + _fired = firing = true; + for (; queue.length; firingIndex = -1) { + memory = queue.shift(); + while (++firingIndex < list.length) { + + // Run callback and check for early termination + if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if (!options.memory) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if (_locked) { + + // Keep an empty list if we have data for future add calls + if (memory) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function add() { + if (list) { + + // If we have memory from a past run, we should fire after adding + if (memory && !firing) { + firingIndex = list.length - 1; + queue.push(memory); + } + + (function add(args) { + jQuery.each(args, function (_, arg) { + if (isFunction(arg)) { + if (!options.unique || !self.has(arg)) { + list.push(arg); + } + } else if (arg && arg.length && toType(arg) !== "string") { + + // Inspect recursively + add(arg); + } + }); + })(arguments); + + if (memory && !firing) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function remove() { + jQuery.each(arguments, function (_, arg) { + var index; + while ((index = jQuery.inArray(arg, list, index)) > -1) { + list.splice(index, 1); + + // Handle firing indexes + if (index <= firingIndex) { + firingIndex--; + } + } + }); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function has(fn) { + return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0; + }, + + // Remove all callbacks from the list + empty: function empty() { + if (list) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function disable() { + _locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function disabled() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function lock() { + _locked = queue = []; + if (!memory && !firing) { + list = memory = ""; + } + return this; + }, + locked: function locked() { + return !!_locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function fireWith(context, args) { + if (!_locked) { + args = args || []; + args = [context, args.slice ? args.slice() : args]; + queue.push(args); + if (!firing) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function fire() { + self.fireWith(this, arguments); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function fired() { + return !!_fired; + } + }; + + return self; + }; + + function Identity(v) { + return v; + } + function Thrower(ex) { + throw ex; + } + + function adoptValue(value, resolve, reject, noValue) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if (value && isFunction(method = value.promise)) { + method.call(value).done(resolve).fail(reject); + + // Other thenables + } else if (value && isFunction(method = value.then)) { + method.call(value, resolve, reject); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply(undefined, [value].slice(noValue)); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch (value) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply(undefined, [value]); + } + } + + jQuery.extend({ + + Deferred: function Deferred(func) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + ["notify", "progress", jQuery.Callbacks("memory"), jQuery.Callbacks("memory"), 2], ["resolve", "done", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 0, "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 1, "rejected"]], + _state = "pending", + _promise = { + state: function state() { + return _state; + }, + always: function always() { + deferred.done(arguments).fail(arguments); + return this; + }, + "catch": function _catch(fn) { + return _promise.then(null, fn); + }, + + // Keep pipe for back-compat + pipe: function pipe() /* fnDone, fnFail, fnProgress */{ + var fns = arguments; + + return jQuery.Deferred(function (newDefer) { + jQuery.each(tuples, function (i, tuple) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[tuple[1]](function () { + var returned = fn && fn.apply(this, arguments); + if (returned && isFunction(returned.promise)) { + returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject); + } else { + newDefer[tuple[0] + "With"](this, fn ? [returned] : arguments); + } + }); + }); + fns = null; + }).promise(); + }, + then: function then(onFulfilled, onRejected, onProgress) { + var maxDepth = 0; + function resolve(depth, deferred, handler, special) { + return function () { + var that = this, + args = arguments, + mightThrow = function mightThrow() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if (depth < maxDepth) { + return; + } + + returned = handler.apply(that, args); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if (returned === deferred.promise()) { + throw new TypeError("Thenable self-resolution"); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && ( + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + (typeof returned === "undefined" ? "undefined" : _typeof(returned)) === "object" || typeof returned === "function") && returned.then; + + // Handle a returned thenable + if (isFunction(then)) { + + // Special processors (notify) just wait for resolution + if (special) { + then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special)); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith)); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if (handler !== Identity) { + that = undefined; + args = [returned]; + } + + // Process the value(s) + // Default process is resolve + (special || deferred.resolveWith)(that, args); + } + }, + + + // Only normal processors (resolve) catch and reject exceptions + process = special ? mightThrow : function () { + try { + mightThrow(); + } catch (e) { + + if (jQuery.Deferred.exceptionHook) { + jQuery.Deferred.exceptionHook(e, process.stackTrace); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if (depth + 1 >= maxDepth) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if (handler !== Thrower) { + that = undefined; + args = [e]; + } + + deferred.rejectWith(that, args); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if (depth) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if (jQuery.Deferred.getStackHook) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout(process); + } + }; + } + + return jQuery.Deferred(function (newDefer) { + + // progress_handlers.add( ... ) + tuples[0][3].add(resolve(0, newDefer, isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith)); + + // fulfilled_handlers.add( ... ) + tuples[1][3].add(resolve(0, newDefer, isFunction(onFulfilled) ? onFulfilled : Identity)); + + // rejected_handlers.add( ... ) + tuples[2][3].add(resolve(0, newDefer, isFunction(onRejected) ? onRejected : Thrower)); + }).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function promise(obj) { + return obj != null ? jQuery.extend(obj, _promise) : _promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each(tuples, function (i, tuple) { + var list = tuple[2], + stateString = tuple[5]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + _promise[tuple[1]] = list.add; + + // Handle state + if (stateString) { + list.add(function () { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + _state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[3 - i][2].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[3 - i][3].disable, + + // progress_callbacks.lock + tuples[0][2].lock, + + // progress_handlers.lock + tuples[0][3].lock); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add(tuple[3].fire); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[tuple[0]] = function () { + deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[tuple[0] + "With"] = list.fireWith; + }); + + // Make the deferred a promise + _promise.promise(deferred); + + // Call given func if any + if (func) { + func.call(deferred, deferred); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function when(singleValue) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + + // count of unprocessed arguments + i = remaining, + + + // subordinate fulfillment data + resolveContexts = Array(i), + resolveValues = _slice.call(arguments), + + + // the master Deferred + master = jQuery.Deferred(), + + + // subordinate callback factory + updateFunc = function updateFunc(i) { + return function (value) { + resolveContexts[i] = this; + resolveValues[i] = arguments.length > 1 ? _slice.call(arguments) : value; + if (! --remaining) { + master.resolveWith(resolveContexts, resolveValues); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if (remaining <= 1) { + adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, !remaining); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if (master.state() === "pending" || isFunction(resolveValues[i] && resolveValues[i].then)) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while (i--) { + adoptValue(resolveValues[i], updateFunc(i), master.reject); + } + + return master.promise(); + } + }); + + // These usually indicate a programmer mistake during development, + // warn about them ASAP rather than swallowing them by default. + var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + + jQuery.Deferred.exceptionHook = function (error, stack) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if (window.console && window.console.warn && error && rerrorNames.test(error.name)) { + window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack); + } + }; + + jQuery.readyException = function (error) { + window.setTimeout(function () { + throw error; + }); + }; + + // The deferred used on DOM ready + var readyList = jQuery.Deferred(); + + jQuery.fn.ready = function (fn) { + + readyList.then(fn) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch(function (error) { + jQuery.readyException(error); + }); + + return this; + }; + + jQuery.extend({ + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function ready(wait) { + + // Abort if there are pending holds or we're already ready + if (wait === true ? --jQuery.readyWait : jQuery.isReady) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if (wait !== true && --jQuery.readyWait > 0) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith(document, [jQuery]); + } + }); + + jQuery.ready.then = readyList.then; + + // The ready event handler and self cleanup method + function completed() { + document.removeEventListener("DOMContentLoaded", completed); + window.removeEventListener("load", completed); + jQuery.ready(); + } + + // Catch cases where $(document).ready() is called + // after the browser event has already occurred. + // Support: IE <=9 - 10 only + // Older IE sometimes signals "interactive" too soon + if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout(jQuery.ready); + } else { + + // Use the handy event callback + document.addEventListener("DOMContentLoaded", completed); + + // A fallback to window.onload, that will always work + window.addEventListener("load", completed); + } + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + var access = function access(elems, fn, key, value, chainable, emptyGet, raw) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if (toType(key) === "object") { + chainable = true; + for (i in key) { + access(elems, fn, i, key[i], true, emptyGet, raw); + } + + // Sets one value + } else if (value !== undefined) { + chainable = true; + + if (!isFunction(value)) { + raw = true; + } + + if (bulk) { + + // Bulk operations run against the entire set + if (raw) { + fn.call(elems, value); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function fn(elem, key, value) { + return bulk.call(jQuery(elem), value); + }; + } + } + + if (fn) { + for (; i < len; i++) { + fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key))); + } + } + } + + if (chainable) { + return elems; + } + + // Gets + if (bulk) { + return fn.call(elems); + } + + return len ? fn(elems[0], key) : emptyGet; + }; + + // Matches dashed string for camelizing + var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + + // Used by camelCase as callback to replace() + function fcamelCase(all, letter) { + return letter.toUpperCase(); + } + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE <=9 - 11, Edge 12 - 15 + // Microsoft forgot to hump their vendor prefix (#9572) + function camelCase(string) { + return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase); + } + var acceptData = function acceptData(owner) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType; + }; + + function Data() { + this.expando = jQuery.expando + Data.uid++; + } + + Data.uid = 1; + + Data.prototype = { + + cache: function cache(owner) { + + // Check if the owner object already has a cache + var value = owner[this.expando]; + + // If not, create one + if (!value) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if (acceptData(owner)) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if (owner.nodeType) { + owner[this.expando] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty(owner, this.expando, { + value: value, + configurable: true + }); + } + } + } + + return value; + }, + set: function set(owner, data, value) { + var prop, + cache = this.cache(owner); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if (typeof data === "string") { + cache[camelCase(data)] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for (prop in data) { + cache[camelCase(prop)] = data[prop]; + } + } + return cache; + }, + get: function get(owner, key) { + return key === undefined ? this.cache(owner) : + + // Always use camelCase key (gh-2257) + owner[this.expando] && owner[this.expando][camelCase(key)]; + }, + access: function access(owner, key, value) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if (key === undefined || key && typeof key === "string" && value === undefined) { + + return this.get(owner, key); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set(owner, key, value); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function remove(owner, key) { + var i, + cache = owner[this.expando]; + + if (cache === undefined) { + return; + } + + if (key !== undefined) { + + // Support array or space separated string of keys + if (Array.isArray(key)) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map(camelCase); + } else { + key = camelCase(key); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? [key] : key.match(rnothtmlwhite) || []; + } + + i = key.length; + + while (i--) { + delete cache[key[i]]; + } + } + + // Remove the expando if there's no more data + if (key === undefined || jQuery.isEmptyObject(cache)) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if (owner.nodeType) { + owner[this.expando] = undefined; + } else { + delete owner[this.expando]; + } + } + }, + hasData: function hasData(owner) { + var cache = owner[this.expando]; + return cache !== undefined && !jQuery.isEmptyObject(cache); + } + }; + var dataPriv = new Data(); + + var dataUser = new Data(); + + // Implementation Summary + // + // 1. Enforce API surface and semantic compatibility with 1.9.x branch + // 2. Improve the module's maintainability by reducing the storage + // paths to a single mechanism. + // 3. Use the same single mechanism to support "private" and "user" data. + // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) + // 5. Avoid exposing implementation details on user objects (eg. expando properties) + // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + + var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + + function getData(data) { + if (data === "true") { + return true; + } + + if (data === "false") { + return false; + } + + if (data === "null") { + return null; + } + + // Only convert to a number if it doesn't change the string + if (data === +data + "") { + return +data; + } + + if (rbrace.test(data)) { + return JSON.parse(data); + } + + return data; + } + + function dataAttr(elem, key, data) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if (data === undefined && elem.nodeType === 1) { + name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase(); + data = elem.getAttribute(name); + + if (typeof data === "string") { + try { + data = getData(data); + } catch (e) {} + + // Make sure we set the data so it isn't changed later + dataUser.set(elem, key, data); + } else { + data = undefined; + } + } + return data; + } + + jQuery.extend({ + hasData: function hasData(elem) { + return dataUser.hasData(elem) || dataPriv.hasData(elem); + }, + + data: function data(elem, name, _data) { + return dataUser.access(elem, name, _data); + }, + + removeData: function removeData(elem, name) { + dataUser.remove(elem, name); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function _data(elem, name, data) { + return dataPriv.access(elem, name, data); + }, + + _removeData: function _removeData(elem, name) { + dataPriv.remove(elem, name); + } + }); + + jQuery.fn.extend({ + data: function data(key, value) { + var i, + name, + data, + elem = this[0], + attrs = elem && elem.attributes; + + // Gets all values + if (key === undefined) { + if (this.length) { + data = dataUser.get(elem); + + if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) { + i = attrs.length; + while (i--) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if (attrs[i]) { + name = attrs[i].name; + if (name.indexOf("data-") === 0) { + name = camelCase(name.slice(5)); + dataAttr(elem, name, data[name]); + } + } + } + dataPriv.set(elem, "hasDataAttrs", true); + } + } + + return data; + } + + // Sets multiple values + if ((typeof key === "undefined" ? "undefined" : _typeof(key)) === "object") { + return this.each(function () { + dataUser.set(this, key); + }); + } + + return access(this, function (value) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if (elem && value === undefined) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get(elem, key); + if (data !== undefined) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr(elem, key); + if (data !== undefined) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each(function () { + + // We always store the camelCased key + dataUser.set(this, key, value); + }); + }, null, value, arguments.length > 1, null, true); + }, + + removeData: function removeData(key) { + return this.each(function () { + dataUser.remove(this, key); + }); + } + }); + + jQuery.extend({ + queue: function queue(elem, type, data) { + var queue; + + if (elem) { + type = (type || "fx") + "queue"; + queue = dataPriv.get(elem, type); + + // Speed up dequeue by getting out quickly if this is just a lookup + if (data) { + if (!queue || Array.isArray(data)) { + queue = dataPriv.access(elem, type, jQuery.makeArray(data)); + } else { + queue.push(data); + } + } + return queue || []; + } + }, + + dequeue: function dequeue(elem, type) { + type = type || "fx"; + + var queue = jQuery.queue(elem, type), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks(elem, type), + next = function next() { + jQuery.dequeue(elem, type); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if (fn === "inprogress") { + fn = queue.shift(); + startLength--; + } + + if (fn) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if (type === "fx") { + queue.unshift("inprogress"); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call(elem, next, hooks); + } + + if (!startLength && hooks) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function _queueHooks(elem, type) { + var key = type + "queueHooks"; + return dataPriv.get(elem, key) || dataPriv.access(elem, key, { + empty: jQuery.Callbacks("once memory").add(function () { + dataPriv.remove(elem, [type + "queue", key]); + }) + }); + } + }); + + jQuery.fn.extend({ + queue: function queue(type, data) { + var setter = 2; + + if (typeof type !== "string") { + data = type; + type = "fx"; + setter--; + } + + if (arguments.length < setter) { + return jQuery.queue(this[0], type); + } + + return data === undefined ? this : this.each(function () { + var queue = jQuery.queue(this, type, data); + + // Ensure a hooks for this queue + jQuery._queueHooks(this, type); + + if (type === "fx" && queue[0] !== "inprogress") { + jQuery.dequeue(this, type); + } + }); + }, + dequeue: function dequeue(type) { + return this.each(function () { + jQuery.dequeue(this, type); + }); + }, + clearQueue: function clearQueue(type) { + return this.queue(type || "fx", []); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function promise(type, obj) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function resolve() { + if (! --count) { + defer.resolveWith(elements, [elements]); + } + }; + + if (typeof type !== "string") { + obj = type; + type = undefined; + } + type = type || "fx"; + + while (i--) { + tmp = dataPriv.get(elements[i], type + "queueHooks"); + if (tmp && tmp.empty) { + count++; + tmp.empty.add(resolve); + } + } + resolve(); + return defer.promise(obj); + } + }); + var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; + + var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i"); + + var cssExpand = ["Top", "Right", "Bottom", "Left"]; + + var isHiddenWithinTree = function isHiddenWithinTree(elem, el) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + jQuery.contains(elem.ownerDocument, elem) && jQuery.css(elem, "display") === "none"; + }; + + var swap = function swap(elem, options, callback, args) { + var ret, + name, + old = {}; + + // Remember the old values, and insert the new ones + for (name in options) { + old[name] = elem.style[name]; + elem.style[name] = options[name]; + } + + ret = callback.apply(elem, args || []); + + // Revert the old values + for (name in options) { + elem.style[name] = old[name]; + } + + return ret; + }; + + function adjustCSS(elem, prop, valueParts, tween) { + var adjusted, + scale, + maxIterations = 20, + currentValue = tween ? function () { + return tween.cur(); + } : function () { + return jQuery.css(elem, prop, ""); + }, + initial = currentValue(), + unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"), + + + // Starting value computation is required for potential unit mismatches + initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop)); + + if (initialInUnit && initialInUnit[3] !== unit) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[3]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while (maxIterations--) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style(elem, prop, initialInUnit + unit); + if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + } + + initialInUnit = initialInUnit * 2; + jQuery.style(elem, prop, initialInUnit + unit); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if (valueParts) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2]; + if (tween) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; + } + + var defaultDisplayMap = {}; + + function getDefaultDisplay(elem) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[nodeName]; + + if (display) { + return display; + } + + temp = doc.body.appendChild(doc.createElement(nodeName)); + display = jQuery.css(temp, "display"); + + temp.parentNode.removeChild(temp); + + if (display === "none") { + display = "block"; + } + defaultDisplayMap[nodeName] = display; + + return display; + } + + function showHide(elements, show) { + var display, + elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for (; index < length; index++) { + elem = elements[index]; + if (!elem.style) { + continue; + } + + display = elem.style.display; + if (show) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if (display === "none") { + values[index] = dataPriv.get(elem, "display") || null; + if (!values[index]) { + elem.style.display = ""; + } + } + if (elem.style.display === "" && isHiddenWithinTree(elem)) { + values[index] = getDefaultDisplay(elem); + } + } else { + if (display !== "none") { + values[index] = "none"; + + // Remember what we're overwriting + dataPriv.set(elem, "display", display); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for (index = 0; index < length; index++) { + if (values[index] != null) { + elements[index].style.display = values[index]; + } + } + + return elements; + } + + jQuery.fn.extend({ + show: function show() { + return showHide(this, true); + }, + hide: function hide() { + return showHide(this); + }, + toggle: function toggle(state) { + if (typeof state === "boolean") { + return state ? this.show() : this.hide(); + } + + return this.each(function () { + if (isHiddenWithinTree(this)) { + jQuery(this).show(); + } else { + jQuery(this).hide(); + } + }); + } + }); + var rcheckableType = /^(?:checkbox|radio)$/i; + + var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]+)/i; + + var rscriptType = /^$|^module$|\/(?:java|ecma)script/i; + + // We have to close these tags to support XHTML (#13200) + var wrapMap = { + + // Support: IE <=9 only + option: [1, ""], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [1, "", "
"], + col: [2, "", "
"], + tr: [2, "", "
"], + td: [3, "", "
"], + + _default: [0, "", ""] + }; + + // Support: IE <=9 only + wrapMap.optgroup = wrapMap.option; + + wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; + wrapMap.th = wrapMap.td; + + function getAll(context, tag) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if (typeof context.getElementsByTagName !== "undefined") { + ret = context.getElementsByTagName(tag || "*"); + } else if (typeof context.querySelectorAll !== "undefined") { + ret = context.querySelectorAll(tag || "*"); + } else { + ret = []; + } + + if (tag === undefined || tag && nodeName(context, tag)) { + return jQuery.merge([context], ret); + } + + return ret; + } + + // Mark scripts as having already been evaluated + function setGlobalEval(elems, refElements) { + var i = 0, + l = elems.length; + + for (; i < l; i++) { + dataPriv.set(elems[i], "globalEval", !refElements || dataPriv.get(refElements[i], "globalEval")); + } + } + + var rhtml = /<|&#?\w+;/; + + function buildFragment(elems, context, scripts, selection, ignored) { + var elem, + tmp, + tag, + wrap, + contains, + j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for (; i < l; i++) { + elem = elems[i]; + + if (elem || elem === 0) { + + // Add nodes directly + if (toType(elem) === "object") { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge(nodes, elem.nodeType ? [elem] : elem); + + // Convert non-html into a text node + } else if (!rhtml.test(elem)) { + nodes.push(context.createTextNode(elem)); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild(context.createElement("div")); + + // Deserialize a standard representation + tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase(); + wrap = wrapMap[tag] || wrapMap._default; + tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while (j--) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge(nodes, tmp.childNodes); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while (elem = nodes[i++]) { + + // Skip elements already in the context collection (trac-4087) + if (selection && jQuery.inArray(elem, selection) > -1) { + if (ignored) { + ignored.push(elem); + } + continue; + } + + contains = jQuery.contains(elem.ownerDocument, elem); + + // Append to fragment + tmp = getAll(fragment.appendChild(elem), "script"); + + // Preserve script evaluation history + if (contains) { + setGlobalEval(tmp); + } + + // Capture executables + if (scripts) { + j = 0; + while (elem = tmp[j++]) { + if (rscriptType.test(elem.type || "")) { + scripts.push(elem); + } + } + } + } + + return fragment; + } + + (function () { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild(document.createElement("div")), + input = document.createElement("input"); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute("type", "radio"); + input.setAttribute("checked", "checked"); + input.setAttribute("name", "t"); + + div.appendChild(input); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; + })(); + var documentElement = document.documentElement; + + var rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + + function returnTrue() { + return true; + } + + function returnFalse() { + return false; + } + + // Support: IE <=9 only + // See #13393 for more info + function safeActiveElement() { + try { + return document.activeElement; + } catch (err) {} + } + + function _on(elem, types, selector, data, fn, one) { + var origFn, type; + + // Types can be a map of types/handlers + if ((typeof types === "undefined" ? "undefined" : _typeof(types)) === "object") { + + // ( types-Object, selector, data ) + if (typeof selector !== "string") { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for (type in types) { + _on(elem, type, selector, data, types[type], one); + } + return elem; + } + + if (data == null && fn == null) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if (fn == null) { + if (typeof selector === "string") { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if (fn === false) { + fn = returnFalse; + } else if (!fn) { + return elem; + } + + if (one === 1) { + origFn = fn; + fn = function fn(event) { + + // Can use an empty set, since event contains the info + jQuery().off(event); + return origFn.apply(this, arguments); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); + } + return elem.each(function () { + jQuery.event.add(this, types, fn, data, selector); + }); + } + + /* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ + jQuery.event = { + + global: {}, + + add: function add(elem, types, handler, data, selector) { + + var handleObjIn, + eventHandle, + tmp, + events, + t, + handleObj, + special, + handlers, + type, + namespaces, + origType, + elemData = dataPriv.get(elem); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if (!elemData) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if (handler.handler) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if (selector) { + jQuery.find.matchesSelector(documentElement, selector); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if (!handler.guid) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if (!(events = elemData.events)) { + events = elemData.events = {}; + } + if (!(eventHandle = elemData.handle)) { + eventHandle = elemData.handle = function (e) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined; + }; + } + + // Handle multiple events separated by a space + types = (types || "").match(rnothtmlwhite) || [""]; + t = types.length; + while (t--) { + tmp = rtypenamespace.exec(types[t]) || []; + type = origType = tmp[1]; + namespaces = (tmp[2] || "").split(".").sort(); + + // There *must* be a type, no attaching namespace-only handlers + if (!type) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[type] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = (selector ? special.delegateType : special.bindType) || type; + + // Update special based on newly reset type + special = jQuery.event.special[type] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test(selector), + namespace: namespaces.join(".") + }, handleObjIn); + + // Init the event handler queue if we're the first + if (!(handlers = events[type])) { + handlers = events[type] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) { + + if (elem.addEventListener) { + elem.addEventListener(type, eventHandle); + } + } + } + + if (special.add) { + special.add.call(elem, handleObj); + + if (!handleObj.handler.guid) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if (selector) { + handlers.splice(handlers.delegateCount++, 0, handleObj); + } else { + handlers.push(handleObj); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[type] = true; + } + }, + + // Detach an event or set of events from an element + remove: function remove(elem, types, handler, selector, mappedTypes) { + + var j, + origCount, + tmp, + events, + t, + handleObj, + special, + handlers, + type, + namespaces, + origType, + elemData = dataPriv.hasData(elem) && dataPriv.get(elem); + + if (!elemData || !(events = elemData.events)) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = (types || "").match(rnothtmlwhite) || [""]; + t = types.length; + while (t--) { + tmp = rtypenamespace.exec(types[t]) || []; + type = origType = tmp[1]; + namespaces = (tmp[2] || "").split(".").sort(); + + // Unbind all events (on this namespace, if provided) for the element + if (!type) { + for (type in events) { + jQuery.event.remove(elem, type + types[t], handler, selector, true); + } + continue; + } + + special = jQuery.event.special[type] || {}; + type = (selector ? special.delegateType : special.bindType) || type; + handlers = events[type] || []; + tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); + + // Remove matching events + origCount = j = handlers.length; + while (j--) { + handleObj = handlers[j]; + + if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) { + handlers.splice(j, 1); + + if (handleObj.selector) { + handlers.delegateCount--; + } + if (special.remove) { + special.remove.call(elem, handleObj); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if (origCount && !handlers.length) { + if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) { + + jQuery.removeEvent(elem, type, elemData.handle); + } + + delete events[type]; + } + } + + // Remove data and the expando if it's no longer used + if (jQuery.isEmptyObject(events)) { + dataPriv.remove(elem, "handle events"); + } + }, + + dispatch: function dispatch(nativeEvent) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix(nativeEvent); + + var i, + j, + ret, + matched, + handleObj, + handlerQueue, + args = new Array(arguments.length), + handlers = (dataPriv.get(this, "events") || {})[event.type] || [], + special = jQuery.event.special[event.type] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + + for (i = 1; i < arguments.length; i++) { + args[i] = arguments[i]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if (special.preDispatch && special.preDispatch.call(this, event) === false) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call(this, event, handlers); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { + event.currentTarget = matched.elem; + + j = 0; + while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args); + + if (ret !== undefined) { + if ((event.result = ret) === false) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if (special.postDispatch) { + special.postDispatch.call(this, event); + } + + return event.result; + }, + + handlers: function handlers(event, _handlers) { + var i, + handleObj, + sel, + matchedHandlers, + matchedSelectors, + handlerQueue = [], + delegateCount = _handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if (delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !(event.type === "click" && event.button >= 1)) { + + for (; cur !== this; cur = cur.parentNode || this) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) { + matchedHandlers = []; + matchedSelectors = {}; + for (i = 0; i < delegateCount; i++) { + handleObj = _handlers[i]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if (matchedSelectors[sel] === undefined) { + matchedSelectors[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length; + } + if (matchedSelectors[sel]) { + matchedHandlers.push(handleObj); + } + } + if (matchedHandlers.length) { + handlerQueue.push({ elem: cur, handlers: matchedHandlers }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if (delegateCount < _handlers.length) { + handlerQueue.push({ elem: cur, handlers: _handlers.slice(delegateCount) }); + } + + return handlerQueue; + }, + + addProp: function addProp(name, hook) { + Object.defineProperty(jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction(hook) ? function () { + if (this.originalEvent) { + return hook(this.originalEvent); + } + } : function () { + if (this.originalEvent) { + return this.originalEvent[name]; + } + }, + + set: function set(value) { + Object.defineProperty(this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + }); + } + }); + }, + + fix: function fix(originalEvent) { + return originalEvent[jQuery.expando] ? originalEvent : new jQuery.Event(originalEvent); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function trigger() { + if (this !== safeActiveElement() && this.focus) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function trigger() { + if (this === safeActiveElement() && this.blur) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function trigger() { + if (this.type === "checkbox" && this.click && nodeName(this, "input")) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function _default(event) { + return nodeName(event.target, "a"); + } + }, + + beforeunload: { + postDispatch: function postDispatch(event) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if (event.result !== undefined && event.originalEvent) { + event.originalEvent.returnValue = event.result; + } + } + } + } + }; + + jQuery.removeEvent = function (elem, type, handle) { + + // This "if" is needed for plain objects + if (elem.removeEventListener) { + elem.removeEventListener(type, handle); + } + }; + + jQuery.Event = function (src, props) { + + // Allow instantiation without the 'new' keyword + if (!(this instanceof jQuery.Event)) { + return new jQuery.Event(src, props); + } + + // Event object + if (src && src.type) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? returnTrue : returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if (props) { + jQuery.extend(this, props); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[jQuery.expando] = true; + }; + + // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding + // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html + jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function preventDefault() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if (e && !this.isSimulated) { + e.preventDefault(); + } + }, + stopPropagation: function stopPropagation() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if (e && !this.isSimulated) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function stopImmediatePropagation() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if (e && !this.isSimulated) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } + }; + + // Includes all common event props including KeyEvent and MouseEvent specific props + jQuery.each({ + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function which(event) { + var button = event.button; + + // Add which for key events + if (event.which == null && rkeyEvent.test(event.type)) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if (!event.which && button !== undefined && rmouseEvent.test(event.type)) { + if (button & 1) { + return 1; + } + + if (button & 2) { + return 3; + } + + if (button & 4) { + return 2; + } + + return 0; + } + + return event.which; + } + }, jQuery.event.addProp); + + // Create mouseenter/leave events using mouseover/out and event-time checks + // so that event delegation works in jQuery. + // Do the same for pointerenter/pointerleave and pointerover/pointerout + // + // Support: Safari 7 only + // Safari sends mouseenter too often; see: + // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 + // for the description of the bug (it existed in older Chrome versions as well). + jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" + }, function (orig, fix) { + jQuery.event.special[orig] = { + delegateType: fix, + bindType: fix, + + handle: function handle(event) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if (!related || related !== target && !jQuery.contains(target, related)) { + event.type = handleObj.origType; + ret = handleObj.handler.apply(this, arguments); + event.type = fix; + } + return ret; + } + }; + }); + + jQuery.fn.extend({ + + on: function on(types, selector, data, fn) { + return _on(this, types, selector, data, fn); + }, + one: function one(types, selector, data, fn) { + return _on(this, types, selector, data, fn, 1); + }, + off: function off(types, selector, fn) { + var handleObj, type; + if (types && types.preventDefault && types.handleObj) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler); + return this; + } + if ((typeof types === "undefined" ? "undefined" : _typeof(types)) === "object") { + + // ( types-object [, selector] ) + for (type in types) { + this.off(type, selector, types[type]); + } + return this; + } + if (selector === false || typeof selector === "function") { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if (fn === false) { + fn = returnFalse; + } + return this.each(function () { + jQuery.event.remove(this, types, fn, selector); + }); + } + }); + + var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + + // Prefer a tbody over its parent table for containing new rows + function manipulationTarget(elem, content) { + if (nodeName(elem, "table") && nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) { + + return jQuery(elem).children("tbody")[0] || elem; + } + + return elem; + } + + // Replace/restore the type attribute of script elements for safe DOM manipulation + function disableScript(elem) { + elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + return elem; + } + function restoreScript(elem) { + if ((elem.type || "").slice(0, 5) === "true/") { + elem.type = elem.type.slice(5); + } else { + elem.removeAttribute("type"); + } + + return elem; + } + + function cloneCopyEvent(src, dest) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if (dest.nodeType !== 1) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if (dataPriv.hasData(src)) { + pdataOld = dataPriv.access(src); + pdataCur = dataPriv.set(dest, pdataOld); + events = pdataOld.events; + + if (events) { + delete pdataCur.handle; + pdataCur.events = {}; + + for (type in events) { + for (i = 0, l = events[type].length; i < l; i++) { + jQuery.event.add(dest, type, events[type][i]); + } + } + } + } + + // 2. Copy user data + if (dataUser.hasData(src)) { + udataOld = dataUser.access(src); + udataCur = jQuery.extend({}, udataOld); + + dataUser.set(dest, udataCur); + } + } + + // Fix IE bugs, see support tests + function fixInput(src, dest) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if (nodeName === "input" && rcheckableType.test(src.type)) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if (nodeName === "input" || nodeName === "textarea") { + dest.defaultValue = src.defaultValue; + } + } + + function domManip(collection, args, callback, ignored) { + + // Flatten any nested arrays + args = concat.apply([], args); + + var fragment, + first, + scripts, + hasScripts, + node, + doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[0], + valueIsFunction = isFunction(value); + + // We can't cloneNode fragments that contain checked, in WebKit + if (valueIsFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) { + return collection.each(function (index) { + var self = collection.eq(index); + if (valueIsFunction) { + args[0] = value.call(this, index, self.html()); + } + domManip(self, args, callback, ignored); + }); + } + + if (l) { + fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored); + first = fragment.firstChild; + + if (fragment.childNodes.length === 1) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if (first || ignored) { + scripts = jQuery.map(getAll(fragment, "script"), disableScript); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for (; i < l; i++) { + node = fragment; + + if (i !== iNoClone) { + node = jQuery.clone(node, true, true); + + // Keep references to cloned scripts for later restoration + if (hasScripts) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge(scripts, getAll(node, "script")); + } + } + + callback.call(collection[i], node, i); + } + + if (hasScripts) { + doc = scripts[scripts.length - 1].ownerDocument; + + // Reenable scripts + jQuery.map(scripts, restoreScript); + + // Evaluate executable scripts on first document insertion + for (i = 0; i < hasScripts; i++) { + node = scripts[i]; + if (rscriptType.test(node.type || "") && !dataPriv.access(node, "globalEval") && jQuery.contains(doc, node)) { + + if (node.src && (node.type || "").toLowerCase() !== "module") { + + // Optional AJAX dependency, but won't run scripts if not present + if (jQuery._evalUrl) { + jQuery._evalUrl(node.src); + } + } else { + DOMEval(node.textContent.replace(rcleanScript, ""), doc, node); + } + } + } + } + } + } + + return collection; + } + + function _remove(elem, selector, keepData) { + var node, + nodes = selector ? jQuery.filter(selector, elem) : elem, + i = 0; + + for (; (node = nodes[i]) != null; i++) { + if (!keepData && node.nodeType === 1) { + jQuery.cleanData(getAll(node)); + } + + if (node.parentNode) { + if (keepData && jQuery.contains(node.ownerDocument, node)) { + setGlobalEval(getAll(node, "script")); + } + node.parentNode.removeChild(node); + } + } + + return elem; + } + + jQuery.extend({ + htmlPrefilter: function htmlPrefilter(html) { + return html.replace(rxhtmlTag, "<$1>"); + }, + + clone: function clone(elem, dataAndEvents, deepDataAndEvents) { + var i, + l, + srcElements, + destElements, + clone = elem.cloneNode(true), + inPage = jQuery.contains(elem.ownerDocument, elem); + + // Fix IE cloning issues + if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll(clone); + srcElements = getAll(elem); + + for (i = 0, l = srcElements.length; i < l; i++) { + fixInput(srcElements[i], destElements[i]); + } + } + + // Copy the events from the original to the clone + if (dataAndEvents) { + if (deepDataAndEvents) { + srcElements = srcElements || getAll(elem); + destElements = destElements || getAll(clone); + + for (i = 0, l = srcElements.length; i < l; i++) { + cloneCopyEvent(srcElements[i], destElements[i]); + } + } else { + cloneCopyEvent(elem, clone); + } + } + + // Preserve script evaluation history + destElements = getAll(clone, "script"); + if (destElements.length > 0) { + setGlobalEval(destElements, !inPage && getAll(elem, "script")); + } + + // Return the cloned set + return clone; + }, + + cleanData: function cleanData(elems) { + var data, + elem, + type, + special = jQuery.event.special, + i = 0; + + for (; (elem = elems[i]) !== undefined; i++) { + if (acceptData(elem)) { + if (data = elem[dataPriv.expando]) { + if (data.events) { + for (type in data.events) { + if (special[type]) { + jQuery.event.remove(elem, type); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent(elem, type, data.handle); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[dataPriv.expando] = undefined; + } + if (elem[dataUser.expando]) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[dataUser.expando] = undefined; + } + } + } + } + }); + + jQuery.fn.extend({ + detach: function detach(selector) { + return _remove(this, selector, true); + }, + + remove: function remove(selector) { + return _remove(this, selector); + }, + + text: function text(value) { + return access(this, function (value) { + return value === undefined ? jQuery.text(this) : this.empty().each(function () { + if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { + this.textContent = value; + } + }); + }, null, value, arguments.length); + }, + + append: function append() { + return domManip(this, arguments, function (elem) { + if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { + var target = manipulationTarget(this, elem); + target.appendChild(elem); + } + }); + }, + + prepend: function prepend() { + return domManip(this, arguments, function (elem) { + if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { + var target = manipulationTarget(this, elem); + target.insertBefore(elem, target.firstChild); + } + }); + }, + + before: function before() { + return domManip(this, arguments, function (elem) { + if (this.parentNode) { + this.parentNode.insertBefore(elem, this); + } + }); + }, + + after: function after() { + return domManip(this, arguments, function (elem) { + if (this.parentNode) { + this.parentNode.insertBefore(elem, this.nextSibling); + } + }); + }, + + empty: function empty() { + var elem, + i = 0; + + for (; (elem = this[i]) != null; i++) { + if (elem.nodeType === 1) { + + // Prevent memory leaks + jQuery.cleanData(getAll(elem, false)); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function clone(dataAndEvents, deepDataAndEvents) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function () { + return jQuery.clone(this, dataAndEvents, deepDataAndEvents); + }); + }, + + html: function html(value) { + return access(this, function (value) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if (value === undefined && elem.nodeType === 1) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if (typeof value === "string" && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) { + + value = jQuery.htmlPrefilter(value); + + try { + for (; i < l; i++) { + elem = this[i] || {}; + + // Remove element nodes and prevent memory leaks + if (elem.nodeType === 1) { + jQuery.cleanData(getAll(elem, false)); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch (e) {} + } + + if (elem) { + this.empty().append(value); + } + }, null, value, arguments.length); + }, + + replaceWith: function replaceWith() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip(this, arguments, function (elem) { + var parent = this.parentNode; + + if (jQuery.inArray(this, ignored) < 0) { + jQuery.cleanData(getAll(this)); + if (parent) { + parent.replaceChild(elem, this); + } + } + + // Force callback invocation + }, ignored); + } + }); + + jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" + }, function (name, original) { + jQuery.fn[name] = function (selector) { + var elems, + ret = [], + insert = jQuery(selector), + last = insert.length - 1, + i = 0; + + for (; i <= last; i++) { + elems = i === last ? this : this.clone(true); + jQuery(insert[i])[original](elems); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply(ret, elems.get()); + } + + return this.pushStack(ret); + }; + }); + var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i"); + + var getStyles = function getStyles(elem) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if (!view || !view.opener) { + view = window; + } + + return view.getComputedStyle(elem); + }; + + var rboxStyle = new RegExp(cssExpand.join("|"), "i"); + + (function () { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if (!div) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0"; + div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%"; + documentElement.appendChild(container).appendChild(div); + + var divStyle = window.getComputedStyle(div); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + div.style.position = "absolute"; + scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; + + documentElement.removeChild(container); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures(measure) { + return Math.round(parseFloat(measure)); + } + + var pixelPositionVal, + boxSizingReliableVal, + scrollboxSizeVal, + pixelBoxStylesVal, + reliableMarginLeftVal, + container = document.createElement("div"), + div = document.createElement("div"); + + // Finish early in limited (non-browser) environments + if (!div.style) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode(true).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend(support, { + boxSizingReliable: function boxSizingReliable() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function pixelBoxStyles() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function pixelPosition() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function reliableMarginLeft() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function scrollboxSize() { + computeStyleTests(); + return scrollboxSizeVal; + } + }); + })(); + + function curCSS(elem, name, computed) { + var width, + minWidth, + maxWidth, + ret, + + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles(elem); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if (computed) { + ret = computed.getPropertyValue(name) || computed[name]; + + if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) { + ret = jQuery.style(elem, name); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : ret; + } + + function addGetHookIf(conditionFn, hookFn) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function get() { + if (conditionFn()) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return (this.get = hookFn).apply(this, arguments); + } + }; + } + + var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + cssPrefixes = ["Webkit", "Moz", "ms"], + emptyStyle = document.createElement("div").style; + + // Return a css property mapped to a potentially vendor prefixed property + function vendorPropName(name) { + + // Shortcut for names that are not vendor prefixed + if (name in emptyStyle) { + return name; + } + + // Check for vendor prefixed names + var capName = name[0].toUpperCase() + name.slice(1), + i = cssPrefixes.length; + + while (i--) { + name = cssPrefixes[i] + capName; + if (name in emptyStyle) { + return name; + } + } + } + + // Return a property mapped along what jQuery.cssProps suggests or to + // a vendor prefixed property. + function finalPropName(name) { + var ret = jQuery.cssProps[name]; + if (!ret) { + ret = jQuery.cssProps[name] = vendorPropName(name) || name; + } + return ret; + } + + function setPositiveNumber(elem, value, subtract) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec(value); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : value; + } + + function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if (box === (isBorderBox ? "border" : "content")) { + return 0; + } + + for (; i < 4; i += 2) { + + // Both box models exclude margin + if (box === "margin") { + delta += jQuery.css(elem, box + cssExpand[i], true, styles); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if (!isBorderBox) { + + // Add padding + delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles); + + // For "border" or "margin", add border + if (box !== "padding") { + delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); + + // But still keep track of it otherwise + } else { + extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if (box === "content") { + delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles); + } + + // For "content" or "padding", subtract border + if (box !== "margin") { + delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if (!isBorderBox && computedVal >= 0) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max(0, Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - computedVal - delta - extra - 0.5)); + } + + return delta; + } + + function getWidthOrHeight(elem, dimension, extra) { + + // Start with computed style + var styles = getStyles(elem), + val = curCSS(elem, dimension, styles), + isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", + valueIsBorderBox = isBorderBox; + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if (rnumnonpx.test(val)) { + if (!extra) { + return val; + } + val = "auto"; + } + + // Check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = valueIsBorderBox && (support.boxSizingReliable() || val === elem.style[dimension]); + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + if (val === "auto" || !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") { + + val = elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)]; + + // offsetWidth/offsetHeight provide border-box values + valueIsBorderBox = true; + } + + // Normalize "" and auto + val = parseFloat(val) || 0; + + // Adjust for the element's box model + return val + boxModelAdjustment(elem, dimension, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val) + "px"; + } + + jQuery.extend({ + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function get(elem, computed) { + if (computed) { + + // We should always get a number back from opacity + var ret = curCSS(elem, "opacity"); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function style(elem, name, value, extra) { + + // Don't set styles on text and comment nodes + if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { + return; + } + + // Make sure that we're working with the right name + var ret, + type, + hooks, + origName = camelCase(name), + isCustomProp = rcustomProp.test(name), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if (!isCustomProp) { + name = finalPropName(origName); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; + + // Check if we're setting a value + if (value !== undefined) { + type = typeof value === "undefined" ? "undefined" : _typeof(value); + + // Convert "+=" or "-=" to relative numbers (#7345) + if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) { + value = adjustCSS(elem, name, ret); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if (value == null || value !== value) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + if (type === "number") { + value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px"); + } + + // background-* props affect original clone's values + if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) { + style[name] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) { + + if (isCustomProp) { + style.setProperty(name, value); + } else { + style[name] = value; + } + } + } else { + + // If a hook was provided get the non-computed value from there + if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[name]; + } + }, + + css: function css(elem, name, extra, styles) { + var val, + num, + hooks, + origName = camelCase(name), + isCustomProp = rcustomProp.test(name); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if (!isCustomProp) { + name = finalPropName(origName); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; + + // If a hook was provided get the computed value from there + if (hooks && "get" in hooks) { + val = hooks.get(elem, true, extra); + } + + // Otherwise, if a way to get the computed value exists, use that + if (val === undefined) { + val = curCSS(elem, name, styles); + } + + // Convert "normal" to computed value + if (val === "normal" && name in cssNormalTransform) { + val = cssNormalTransform[name]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if (extra === "" || extra) { + num = parseFloat(val); + return extra === true || isFinite(num) ? num || 0 : val; + } + + return val; + } + }); + + jQuery.each(["height", "width"], function (i, dimension) { + jQuery.cssHooks[dimension] = { + get: function get(elem, computed, extra) { + if (computed) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test(jQuery.css(elem, "display")) && ( + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + !elem.getClientRects().length || !elem.getBoundingClientRect().width) ? swap(elem, cssShow, function () { + return getWidthOrHeight(elem, dimension, extra); + }) : getWidthOrHeight(elem, dimension, extra); + } + }, + + set: function set(elem, value, extra) { + var matches, + styles = getStyles(elem), + isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", + subtract = extra && boxModelAdjustment(elem, dimension, extra, isBorderBox, styles); + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if (isBorderBox && support.scrollboxSize() === styles.position) { + subtract -= Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - parseFloat(styles[dimension]) - boxModelAdjustment(elem, dimension, "border", false, styles) - 0.5); + } + + // Convert to pixels if value adjustment is needed + if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || "px") !== "px") { + + elem.style[dimension] = value; + value = jQuery.css(elem, dimension); + } + + return setPositiveNumber(elem, value, subtract); + } + }; + }); + + jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) { + if (computed) { + return (parseFloat(curCSS(elem, "marginLeft")) || elem.getBoundingClientRect().left - swap(elem, { marginLeft: 0 }, function () { + return elem.getBoundingClientRect().left; + })) + "px"; + } + }); + + // These hooks are used by animate to expand properties + jQuery.each({ + margin: "", + padding: "", + border: "Width" + }, function (prefix, suffix) { + jQuery.cssHooks[prefix + suffix] = { + expand: function expand(value) { + var i = 0, + expanded = {}, + + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [value]; + + for (; i < 4; i++) { + expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0]; + } + + return expanded; + } + }; + + if (prefix !== "margin") { + jQuery.cssHooks[prefix + suffix].set = setPositiveNumber; + } + }); + + jQuery.fn.extend({ + css: function css(name, value) { + return access(this, function (elem, name, value) { + var styles, + len, + map = {}, + i = 0; + + if (Array.isArray(name)) { + styles = getStyles(elem); + len = name.length; + + for (; i < len; i++) { + map[name[i]] = jQuery.css(elem, name[i], false, styles); + } + + return map; + } + + return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name); + }, name, value, arguments.length > 1); + } + }); + + function Tween(elem, options, prop, end, easing) { + return new Tween.prototype.init(elem, options, prop, end, easing); + } + jQuery.Tween = Tween; + + Tween.prototype = { + constructor: Tween, + init: function init(elem, options, prop, end, easing, unit) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px"); + }, + cur: function cur() { + var hooks = Tween.propHooks[this.prop]; + + return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this); + }, + run: function run(percent) { + var eased, + hooks = Tween.propHooks[this.prop]; + + if (this.options.duration) { + this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration); + } else { + this.pos = eased = percent; + } + this.now = (this.end - this.start) * eased + this.start; + + if (this.options.step) { + this.options.step.call(this.elem, this.now, this); + } + + if (hooks && hooks.set) { + hooks.set(this); + } else { + Tween.propHooks._default.set(this); + } + return this; + } + }; + + Tween.prototype.init.prototype = Tween.prototype; + + Tween.propHooks = { + _default: { + get: function get(tween) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) { + return tween.elem[tween.prop]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css(tween.elem, tween.prop, ""); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function set(tween) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if (jQuery.fx.step[tween.prop]) { + jQuery.fx.step[tween.prop](tween); + } else if (tween.elem.nodeType === 1 && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) { + jQuery.style(tween.elem, tween.prop, tween.now + tween.unit); + } else { + tween.elem[tween.prop] = tween.now; + } + } + } + }; + + // Support: IE <=9 only + // Panic based approach to setting things on disconnected nodes + Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function set(tween) { + if (tween.elem.nodeType && tween.elem.parentNode) { + tween.elem[tween.prop] = tween.now; + } + } + }; + + jQuery.easing = { + linear: function linear(p) { + return p; + }, + swing: function swing(p) { + return 0.5 - Math.cos(p * Math.PI) / 2; + }, + _default: "swing" + }; + + jQuery.fx = Tween.prototype.init; + + // Back compat <1.8 extension point + jQuery.fx.step = {}; + + var fxNow, + inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + + function schedule() { + if (inProgress) { + if (document.hidden === false && window.requestAnimationFrame) { + window.requestAnimationFrame(schedule); + } else { + window.setTimeout(schedule, jQuery.fx.interval); + } + + jQuery.fx.tick(); + } + } + + // Animations created synchronously will run synchronously + function createFxNow() { + window.setTimeout(function () { + fxNow = undefined; + }); + return fxNow = Date.now(); + } + + // Generate parameters to create a standard animation + function genFx(type, includeWidth) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for (; i < 4; i += 2 - includeWidth) { + which = cssExpand[i]; + attrs["margin" + which] = attrs["padding" + which] = type; + } + + if (includeWidth) { + attrs.opacity = attrs.width = type; + } + + return attrs; + } + + function createTween(value, prop, animation) { + var tween, + collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]), + index = 0, + length = collection.length; + for (; index < length; index++) { + if (tween = collection[index].call(animation, prop, value)) { + + // We're done with this property + return tween; + } + } + } + + function defaultPrefilter(elem, props, opts) { + var prop, + value, + toggle, + hooks, + oldfire, + propTween, + restoreDisplay, + display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree(elem), + dataShow = dataPriv.get(elem, "fxshow"); + + // Queue-skipping animations hijack the fx hooks + if (!opts.queue) { + hooks = jQuery._queueHooks(elem, "fx"); + if (hooks.unqueued == null) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function () { + if (!hooks.unqueued) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function () { + + // Ensure the complete handler is called before this completes + anim.always(function () { + hooks.unqueued--; + if (!jQuery.queue(elem, "fx").length) { + hooks.empty.fire(); + } + }); + }); + } + + // Detect show/hide animations + for (prop in props) { + value = props[prop]; + if (rfxtypes.test(value)) { + delete props[prop]; + toggle = toggle || value === "toggle"; + if (value === (hidden ? "hide" : "show")) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if (value === "show" && dataShow && dataShow[prop] !== undefined) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject(props); + if (!propTween && jQuery.isEmptyObject(orig)) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if (isBox && elem.nodeType === 1) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [style.overflow, style.overflowX, style.overflowY]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if (restoreDisplay == null) { + restoreDisplay = dataPriv.get(elem, "display"); + } + display = jQuery.css(elem, "display"); + if (display === "none") { + if (restoreDisplay) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide([elem], true); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css(elem, "display"); + showHide([elem]); + } + } + + // Animate inline elements as inline-block + if (display === "inline" || display === "inline-block" && restoreDisplay != null) { + if (jQuery.css(elem, "float") === "none") { + + // Restore the original display value at the end of pure show/hide animations + if (!propTween) { + anim.done(function () { + style.display = restoreDisplay; + }); + if (restoreDisplay == null) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if (opts.overflow) { + style.overflow = "hidden"; + anim.always(function () { + style.overflow = opts.overflow[0]; + style.overflowX = opts.overflow[1]; + style.overflowY = opts.overflow[2]; + }); + } + + // Implement show/hide animations + propTween = false; + for (prop in orig) { + + // General show/hide setup for this element animation + if (!propTween) { + if (dataShow) { + if ("hidden" in dataShow) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access(elem, "fxshow", { display: restoreDisplay }); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if (toggle) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if (hidden) { + showHide([elem], true); + } + + /* eslint-disable no-loop-func */ + + anim.done(function () { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if (!hidden) { + showHide([elem]); + } + dataPriv.remove(elem, "fxshow"); + for (prop in orig) { + jQuery.style(elem, prop, orig[prop]); + } + }); + } + + // Per-property setup + propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim); + if (!(prop in dataShow)) { + dataShow[prop] = propTween.start; + if (hidden) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } + } + + function propFilter(props, specialEasing) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for (index in props) { + name = camelCase(index); + easing = specialEasing[name]; + value = props[index]; + if (Array.isArray(value)) { + easing = value[1]; + value = props[index] = value[0]; + } + + if (index !== name) { + props[name] = value; + delete props[index]; + } + + hooks = jQuery.cssHooks[name]; + if (hooks && "expand" in hooks) { + value = hooks.expand(value); + delete props[name]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for (index in value) { + if (!(index in props)) { + props[index] = value[index]; + specialEasing[index] = easing; + } + } + } else { + specialEasing[name] = easing; + } + } + } + + function Animation(elem, properties, options) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always(function () { + + // Don't match elem in the :animated selector + delete tick.elem; + }), + tick = function tick() { + if (stopped) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max(0, animation.startTime + animation.duration - currentTime), + + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for (; index < length; index++) { + animation.tweens[index].run(percent); + } + + deferred.notifyWith(elem, [animation, percent, remaining]); + + // If there's more to do, yield + if (percent < 1 && length) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if (!length) { + deferred.notifyWith(elem, [animation, 1, 0]); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith(elem, [animation]); + return false; + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend({}, properties), + opts: jQuery.extend(true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function createTween(prop, end) { + var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing); + animation.tweens.push(tween); + return tween; + }, + stop: function stop(gotoEnd) { + var index = 0, + + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if (stopped) { + return this; + } + stopped = true; + for (; index < length; index++) { + animation.tweens[index].run(1); + } + + // Resolve when we played the last frame; otherwise, reject + if (gotoEnd) { + deferred.notifyWith(elem, [animation, 1, 0]); + deferred.resolveWith(elem, [animation, gotoEnd]); + } else { + deferred.rejectWith(elem, [animation, gotoEnd]); + } + return this; + } + }), + props = animation.props; + + propFilter(props, animation.opts.specialEasing); + + for (; index < length; index++) { + result = Animation.prefilters[index].call(animation, elem, props, animation.opts); + if (result) { + if (isFunction(result.stop)) { + jQuery._queueHooks(animation.elem, animation.opts.queue).stop = result.stop.bind(result); + } + return result; + } + } + + jQuery.map(props, createTween, animation); + + if (isFunction(animation.opts.start)) { + animation.opts.start.call(elem, animation); + } + + // Attach callbacks from options + animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always); + + jQuery.fx.timer(jQuery.extend(tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + })); + + return animation; + } + + jQuery.Animation = jQuery.extend(Animation, { + + tweeners: { + "*": [function (prop, value) { + var tween = this.createTween(prop, value); + adjustCSS(tween.elem, prop, rcssNum.exec(value), tween); + return tween; + }] + }, + + tweener: function tweener(props, callback) { + if (isFunction(props)) { + callback = props; + props = ["*"]; + } else { + props = props.match(rnothtmlwhite); + } + + var prop, + index = 0, + length = props.length; + + for (; index < length; index++) { + prop = props[index]; + Animation.tweeners[prop] = Animation.tweeners[prop] || []; + Animation.tweeners[prop].unshift(callback); + } + }, + + prefilters: [defaultPrefilter], + + prefilter: function prefilter(callback, prepend) { + if (prepend) { + Animation.prefilters.unshift(callback); + } else { + Animation.prefilters.push(callback); + } + } + }); + + jQuery.speed = function (speed, easing, fn) { + var opt = speed && (typeof speed === "undefined" ? "undefined" : _typeof(speed)) === "object" ? jQuery.extend({}, speed) : { + complete: fn || !fn && easing || isFunction(speed) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction(easing) && easing + }; + + // Go to the end state if fx are off + if (jQuery.fx.off) { + opt.duration = 0; + } else { + if (typeof opt.duration !== "number") { + if (opt.duration in jQuery.fx.speeds) { + opt.duration = jQuery.fx.speeds[opt.duration]; + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if (opt.queue == null || opt.queue === true) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function () { + if (isFunction(opt.old)) { + opt.old.call(this); + } + + if (opt.queue) { + jQuery.dequeue(this, opt.queue); + } + }; + + return opt; + }; + + jQuery.fn.extend({ + fadeTo: function fadeTo(speed, to, easing, callback) { + + // Show any hidden elements after setting opacity to 0 + return this.filter(isHiddenWithinTree).css("opacity", 0).show() + + // Animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback); + }, + animate: function animate(prop, speed, easing, callback) { + var empty = jQuery.isEmptyObject(prop), + optall = jQuery.speed(speed, easing, callback), + doAnimation = function doAnimation() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation(this, jQuery.extend({}, prop), optall); + + // Empty animations, or finishing resolves immediately + if (empty || dataPriv.get(this, "finish")) { + anim.stop(true); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation); + }, + stop: function stop(type, clearQueue, gotoEnd) { + var stopQueue = function stopQueue(hooks) { + var stop = hooks.stop; + delete hooks.stop; + stop(gotoEnd); + }; + + if (typeof type !== "string") { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if (clearQueue && type !== false) { + this.queue(type || "fx", []); + } + + return this.each(function () { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get(this); + + if (index) { + if (data[index] && data[index].stop) { + stopQueue(data[index]); + } + } else { + for (index in data) { + if (data[index] && data[index].stop && rrun.test(index)) { + stopQueue(data[index]); + } + } + } + + for (index = timers.length; index--;) { + if (timers[index].elem === this && (type == null || timers[index].queue === type)) { + + timers[index].anim.stop(gotoEnd); + dequeue = false; + timers.splice(index, 1); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if (dequeue || !gotoEnd) { + jQuery.dequeue(this, type); + } + }); + }, + finish: function finish(type) { + if (type !== false) { + type = type || "fx"; + } + return this.each(function () { + var index, + data = dataPriv.get(this), + queue = data[type + "queue"], + hooks = data[type + "queueHooks"], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue(this, type, []); + + if (hooks && hooks.stop) { + hooks.stop.call(this, true); + } + + // Look for any active animations, and finish them + for (index = timers.length; index--;) { + if (timers[index].elem === this && timers[index].queue === type) { + timers[index].anim.stop(true); + timers.splice(index, 1); + } + } + + // Look for any animations in the old queue and finish them + for (index = 0; index < length; index++) { + if (queue[index] && queue[index].finish) { + queue[index].finish.call(this); + } + } + + // Turn off finishing flag + delete data.finish; + }); + } + }); + + jQuery.each(["toggle", "show", "hide"], function (i, name) { + var cssFn = jQuery.fn[name]; + jQuery.fn[name] = function (speed, easing, callback) { + return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback); + }; + }); + + // Generate shortcuts for custom animations + jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } + }, function (name, props) { + jQuery.fn[name] = function (speed, easing, callback) { + return this.animate(props, speed, easing, callback); + }; + }); + + jQuery.timers = []; + jQuery.fx.tick = function () { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for (; i < timers.length; i++) { + timer = timers[i]; + + // Run the timer and safely remove it when done (allowing for external removal) + if (!timer() && timers[i] === timer) { + timers.splice(i--, 1); + } + } + + if (!timers.length) { + jQuery.fx.stop(); + } + fxNow = undefined; + }; + + jQuery.fx.timer = function (timer) { + jQuery.timers.push(timer); + jQuery.fx.start(); + }; + + jQuery.fx.interval = 13; + jQuery.fx.start = function () { + if (inProgress) { + return; + } + + inProgress = true; + schedule(); + }; + + jQuery.fx.stop = function () { + inProgress = null; + }; + + jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 + }; + + // Based off of the plugin by Clint Helfers, with permission. + // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ + jQuery.fn.delay = function (time, type) { + time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; + type = type || "fx"; + + return this.queue(type, function (next, hooks) { + var timeout = window.setTimeout(next, time); + hooks.stop = function () { + window.clearTimeout(timeout); + }; + }); + }; + + (function () { + var input = document.createElement("input"), + select = document.createElement("select"), + opt = select.appendChild(document.createElement("option")); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement("input"); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; + })(); + + var boolHook, + attrHandle = jQuery.expr.attrHandle; + + jQuery.fn.extend({ + attr: function attr(name, value) { + return access(this, jQuery.attr, name, value, arguments.length > 1); + }, + + removeAttr: function removeAttr(name) { + return this.each(function () { + jQuery.removeAttr(this, name); + }); + } + }); + + jQuery.extend({ + attr: function attr(elem, name, value) { + var ret, + hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if (nType === 3 || nType === 8 || nType === 2) { + return; + } + + // Fallback to prop when attributes are not supported + if (typeof elem.getAttribute === "undefined") { + return jQuery.prop(elem, name, value); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if (nType !== 1 || !jQuery.isXMLDoc(elem)) { + hooks = jQuery.attrHooks[name.toLowerCase()] || (jQuery.expr.match.bool.test(name) ? boolHook : undefined); + } + + if (value !== undefined) { + if (value === null) { + jQuery.removeAttr(elem, name); + return; + } + + if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { + return ret; + } + + elem.setAttribute(name, value + ""); + return value; + } + + if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { + return ret; + } + + ret = jQuery.find.attr(elem, name); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function set(elem, value) { + if (!support.radioValue && value === "radio" && nodeName(elem, "input")) { + var val = elem.value; + elem.setAttribute("type", value); + if (val) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function removeAttr(elem, value) { + var name, + i = 0, + + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match(rnothtmlwhite); + + if (attrNames && elem.nodeType === 1) { + while (name = attrNames[i++]) { + elem.removeAttribute(name); + } + } + } + }); + + // Hooks for boolean attributes + boolHook = { + set: function set(elem, value, name) { + if (value === false) { + + // Remove boolean attributes when set to false + jQuery.removeAttr(elem, name); + } else { + elem.setAttribute(name, name); + } + return name; + } + }; + + jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) { + var getter = attrHandle[name] || jQuery.find.attr; + + attrHandle[name] = function (elem, name, isXML) { + var ret, + handle, + lowercaseName = name.toLowerCase(); + + if (!isXML) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[lowercaseName]; + attrHandle[lowercaseName] = ret; + ret = getter(elem, name, isXML) != null ? lowercaseName : null; + attrHandle[lowercaseName] = handle; + } + return ret; + }; + }); + + var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + + jQuery.fn.extend({ + prop: function prop(name, value) { + return access(this, jQuery.prop, name, value, arguments.length > 1); + }, + + removeProp: function removeProp(name) { + return this.each(function () { + delete this[jQuery.propFix[name] || name]; + }); + } + }); + + jQuery.extend({ + prop: function prop(elem, name, value) { + var ret, + hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if (nType === 3 || nType === 8 || nType === 2) { + return; + } + + if (nType !== 1 || !jQuery.isXMLDoc(elem)) { + + // Fix name and attach hooks + name = jQuery.propFix[name] || name; + hooks = jQuery.propHooks[name]; + } + + if (value !== undefined) { + if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { + return ret; + } + + return elem[name] = value; + } + + if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { + return ret; + } + + return elem[name]; + }, + + propHooks: { + tabIndex: { + get: function get(elem) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr(elem, "tabindex"); + + if (tabindex) { + return parseInt(tabindex, 10); + } + + if (rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } + }); + + // Support: IE <=11 only + // Accessing the selectedIndex property + // forces the browser to respect setting selected + // on the option + // The getter ensures a default option is selected + // when in an optgroup + // eslint rule "no-unused-expressions" is disabled for this code + // since it considers such accessions noop + if (!support.optSelected) { + jQuery.propHooks.selected = { + get: function get(elem) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if (parent && parent.parentNode) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function set(elem) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if (parent) { + parent.selectedIndex; + + if (parent.parentNode) { + parent.parentNode.selectedIndex; + } + } + } + }; + } + + jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () { + jQuery.propFix[this.toLowerCase()] = this; + }); + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse(value) { + var tokens = value.match(rnothtmlwhite) || []; + return tokens.join(" "); + } + + function getClass(elem) { + return elem.getAttribute && elem.getAttribute("class") || ""; + } + + function classesToArray(value) { + if (Array.isArray(value)) { + return value; + } + if (typeof value === "string") { + return value.match(rnothtmlwhite) || []; + } + return []; + } + + jQuery.fn.extend({ + addClass: function addClass(value) { + var classes, + elem, + cur, + curValue, + clazz, + j, + finalValue, + i = 0; + + if (isFunction(value)) { + return this.each(function (j) { + jQuery(this).addClass(value.call(this, j, getClass(this))); + }); + } + + classes = classesToArray(value); + + if (classes.length) { + while (elem = this[i++]) { + curValue = getClass(elem); + cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " "; + + if (cur) { + j = 0; + while (clazz = classes[j++]) { + if (cur.indexOf(" " + clazz + " ") < 0) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) { + elem.setAttribute("class", finalValue); + } + } + } + } + + return this; + }, + + removeClass: function removeClass(value) { + var classes, + elem, + cur, + curValue, + clazz, + j, + finalValue, + i = 0; + + if (isFunction(value)) { + return this.each(function (j) { + jQuery(this).removeClass(value.call(this, j, getClass(this))); + }); + } + + if (!arguments.length) { + return this.attr("class", ""); + } + + classes = classesToArray(value); + + if (classes.length) { + while (elem = this[i++]) { + curValue = getClass(elem); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " "; + + if (cur) { + j = 0; + while (clazz = classes[j++]) { + + // Remove *all* instances + while (cur.indexOf(" " + clazz + " ") > -1) { + cur = cur.replace(" " + clazz + " ", " "); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) { + elem.setAttribute("class", finalValue); + } + } + } + } + + return this; + }, + + toggleClass: function toggleClass(value, stateVal) { + var type = typeof value === "undefined" ? "undefined" : _typeof(value), + isValidValue = type === "string" || Array.isArray(value); + + if (typeof stateVal === "boolean" && isValidValue) { + return stateVal ? this.addClass(value) : this.removeClass(value); + } + + if (isFunction(value)) { + return this.each(function (i) { + jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal); + }); + } + + return this.each(function () { + var className, i, self, classNames; + + if (isValidValue) { + + // Toggle individual class names + i = 0; + self = jQuery(this); + classNames = classesToArray(value); + + while (className = classNames[i++]) { + + // Check each className given, space separated list + if (self.hasClass(className)) { + self.removeClass(className); + } else { + self.addClass(className); + } + } + + // Toggle whole class name + } else if (value === undefined || type === "boolean") { + className = getClass(this); + if (className) { + + // Store className if set + dataPriv.set(this, "__className__", className); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if (this.setAttribute) { + this.setAttribute("class", className || value === false ? "" : dataPriv.get(this, "__className__") || ""); + } + } + }); + }, + + hasClass: function hasClass(selector) { + var className, + elem, + i = 0; + + className = " " + selector + " "; + while (elem = this[i++]) { + if (elem.nodeType === 1 && (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) { + return true; + } + } + + return false; + } + }); + + var rreturn = /\r/g; + + jQuery.fn.extend({ + val: function val(value) { + var hooks, + ret, + valueIsFunction, + elem = this[0]; + + if (!arguments.length) { + if (elem) { + hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()]; + + if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if (typeof ret === "string") { + return ret.replace(rreturn, ""); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction(value); + + return this.each(function (i) { + var val; + + if (this.nodeType !== 1) { + return; + } + + if (valueIsFunction) { + val = value.call(this, i, jQuery(this).val()); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if (val == null) { + val = ""; + } else if (typeof val === "number") { + val += ""; + } else if (Array.isArray(val)) { + val = jQuery.map(val, function (value) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; + + // If set returns undefined, fall back to normal setting + if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) { + this.value = val; + } + }); + } + }); + + jQuery.extend({ + valHooks: { + option: { + get: function get(elem) { + + var val = jQuery.find.attr(elem, "value"); + return val != null ? val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse(jQuery.text(elem)); + } + }, + select: { + get: function get(elem) { + var value, + option, + i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if (index < 0) { + i = max; + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for (; i < max; i++) { + option = options[i]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ((option.selected || i === index) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && (!option.parentNode.disabled || !nodeName(option.parentNode, "optgroup"))) { + + // Get the specific value for the option + value = jQuery(option).val(); + + // We don't need an array for one selects + if (one) { + return value; + } + + // Multi-Selects return an array + values.push(value); + } + } + + return values; + }, + + set: function set(elem, value) { + var optionSet, + option, + options = elem.options, + values = jQuery.makeArray(value), + i = options.length; + + while (i--) { + option = options[i]; + + /* eslint-disable no-cond-assign */ + + if (option.selected = jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if (!optionSet) { + elem.selectedIndex = -1; + } + return values; + } + } + } + }); + + // Radios and checkboxes getter/setter + jQuery.each(["radio", "checkbox"], function () { + jQuery.valHooks[this] = { + set: function set(elem, value) { + if (Array.isArray(value)) { + return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1; + } + } + }; + if (!support.checkOn) { + jQuery.valHooks[this].get = function (elem) { + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } + }); + + // Return jQuery for attributes-only inclusion + + + support.focusin = "onfocusin" in window; + + var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function stopPropagationCallback(e) { + e.stopPropagation(); + }; + + jQuery.extend(jQuery.event, { + + trigger: function trigger(event, data, elem, onlyHandlers) { + + var i, + cur, + tmp, + bubbleType, + ontype, + handle, + special, + lastElement, + eventPath = [elem || document], + type = hasOwn.call(event, "type") ? event.type : event, + namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if (elem.nodeType === 3 || elem.nodeType === 8) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if (rfocusMorph.test(type + jQuery.event.triggered)) { + return; + } + + if (type.indexOf(".") > -1) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[jQuery.expando] ? event : new jQuery.Event(type, (typeof event === "undefined" ? "undefined" : _typeof(event)) === "object" && event); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.rnamespace = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Clean up the event in case it is being reused + event.result = undefined; + if (!event.target) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? [event] : jQuery.makeArray(data, [event]); + + // Allow special events to draw outside the lines + special = jQuery.event.special[type] || {}; + if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if (!onlyHandlers && !special.noBubble && !isWindow(elem)) { + + bubbleType = special.delegateType || type; + if (!rfocusMorph.test(bubbleType + type)) { + cur = cur.parentNode; + } + for (; cur; cur = cur.parentNode) { + eventPath.push(cur); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if (tmp === (elem.ownerDocument || document)) { + eventPath.push(tmp.defaultView || tmp.parentWindow || window); + } + } + + // Fire handlers on the event path + i = 0; + while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { + lastElement = cur; + event.type = i > 1 ? bubbleType : special.bindType || type; + + // jQuery handler + handle = (dataPriv.get(cur, "events") || {})[event.type] && dataPriv.get(cur, "handle"); + if (handle) { + handle.apply(cur, data); + } + + // Native handler + handle = ontype && cur[ontype]; + if (handle && handle.apply && acceptData(cur)) { + event.result = handle.apply(cur, data); + if (event.result === false) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if (!onlyHandlers && !event.isDefaultPrevented()) { + + if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if (ontype && isFunction(elem[type]) && !isWindow(elem)) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ontype]; + + if (tmp) { + elem[ontype] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if (event.isPropagationStopped()) { + lastElement.addEventListener(type, stopPropagationCallback); + } + + elem[type](); + + if (event.isPropagationStopped()) { + lastElement.removeEventListener(type, stopPropagationCallback); + } + + jQuery.event.triggered = undefined; + + if (tmp) { + elem[ontype] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function simulate(type, elem, event) { + var e = jQuery.extend(new jQuery.Event(), event, { + type: type, + isSimulated: true + }); + + jQuery.event.trigger(e, null, elem); + } + + }); + + jQuery.fn.extend({ + + trigger: function trigger(type, data) { + return this.each(function () { + jQuery.event.trigger(type, data, this); + }); + }, + triggerHandler: function triggerHandler(type, data) { + var elem = this[0]; + if (elem) { + return jQuery.event.trigger(type, data, elem, true); + } + } + }); + + // Support: Firefox <=44 + // Firefox doesn't have focus(in | out) events + // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 + // + // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 + // focus(in | out) events fire after focus & blur events, + // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order + // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 + if (!support.focusin) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function (orig, fix) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function handler(event) { + jQuery.event.simulate(fix, event.target, jQuery.event.fix(event)); + }; + + jQuery.event.special[fix] = { + setup: function setup() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access(doc, fix); + + if (!attaches) { + doc.addEventListener(orig, handler, true); + } + dataPriv.access(doc, fix, (attaches || 0) + 1); + }, + teardown: function teardown() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access(doc, fix) - 1; + + if (!attaches) { + doc.removeEventListener(orig, handler, true); + dataPriv.remove(doc, fix); + } else { + dataPriv.access(doc, fix, attaches); + } + } + }; + }); + } + var location = window.location; + + var nonce = Date.now(); + + var rquery = /\?/; + + // Cross-browser xml parsing + jQuery.parseXML = function (data) { + var xml; + if (!data || typeof data !== "string") { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = new window.DOMParser().parseFromString(data, "text/xml"); + } catch (e) { + xml = undefined; + } + + if (!xml || xml.getElementsByTagName("parsererror").length) { + jQuery.error("Invalid XML: " + data); + } + return xml; + }; + + var rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + + function buildParams(prefix, obj, traditional, add) { + var name; + + if (Array.isArray(obj)) { + + // Serialize array item. + jQuery.each(obj, function (i, v) { + if (traditional || rbracket.test(prefix)) { + + // Treat each array item as a scalar. + add(prefix, v); + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams(prefix + "[" + ((typeof v === "undefined" ? "undefined" : _typeof(v)) === "object" && v != null ? i : "") + "]", v, traditional, add); + } + }); + } else if (!traditional && toType(obj) === "object") { + + // Serialize object item. + for (name in obj) { + buildParams(prefix + "[" + name + "]", obj[name], traditional, add); + } + } else { + + // Serialize scalar item. + add(prefix, obj); + } + } + + // Serialize an array of form elements or a set of + // key/values into a query string + jQuery.param = function (a, traditional) { + var prefix, + s = [], + add = function add(key, valueOrFunction) { + + // If value is a function, invoke it and use its return value + var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction; + + s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value); + }; + + // If an array was passed in, assume that it is an array of form elements. + if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) { + + // Serialize the form elements + jQuery.each(a, function () { + add(this.name, this.value); + }); + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for (prefix in a) { + buildParams(prefix, a[prefix], traditional, add); + } + } + + // Return the resulting serialization + return s.join("&"); + }; + + jQuery.fn.extend({ + serialize: function serialize() { + return jQuery.param(this.serializeArray()); + }, + serializeArray: function serializeArray() { + return this.map(function () { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop(this, "elements"); + return elements ? jQuery.makeArray(elements) : this; + }).filter(function () { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type)); + }).map(function (i, elem) { + var val = jQuery(this).val(); + + if (val == null) { + return null; + } + + if (Array.isArray(val)) { + return jQuery.map(val, function (val) { + return { name: elem.name, value: val.replace(rCRLF, "\r\n") }; + }); + } + + return { name: elem.name, value: val.replace(rCRLF, "\r\n") }; + }).get(); + } + }); + + var r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat("*"), + + + // Anchor tag for parsing the document origin + originAnchor = document.createElement("a"); + originAnchor.href = location.href; + + // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport + function addToPrefiltersOrTransports(structure) { + + // dataTypeExpression is optional and defaults to "*" + return function (dataTypeExpression, func) { + + if (typeof dataTypeExpression !== "string") { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || []; + + if (isFunction(func)) { + + // For each dataType in the dataTypeExpression + while (dataType = dataTypes[i++]) { + + // Prepend if requested + if (dataType[0] === "+") { + dataType = dataType.slice(1) || "*"; + (structure[dataType] = structure[dataType] || []).unshift(func); + + // Otherwise append + } else { + (structure[dataType] = structure[dataType] || []).push(func); + } + } + } + }; + } + + // Base inspection function for prefilters and transports + function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) { + + var inspected = {}, + seekingTransport = structure === transports; + + function inspect(dataType) { + var selected; + inspected[dataType] = true; + jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) { + var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR); + if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) { + + options.dataTypes.unshift(dataTypeOrTransport); + inspect(dataTypeOrTransport); + return false; + } else if (seekingTransport) { + return !(selected = dataTypeOrTransport); + } + }); + return selected; + } + + return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*"); + } + + // A special extend for ajax options + // that takes "flat" options (not to be deep extended) + // Fixes #9887 + function ajaxExtend(target, src) { + var key, + deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for (key in src) { + if (src[key] !== undefined) { + (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key]; + } + } + if (deep) { + jQuery.extend(true, target, deep); + } + + return target; + } + + /* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ + function ajaxHandleResponses(s, jqXHR, responses) { + + var ct, + type, + finalDataType, + firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while (dataTypes[0] === "*") { + dataTypes.shift(); + if (ct === undefined) { + ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); + } + } + + // Check if we're dealing with a known content-type + if (ct) { + for (type in contents) { + if (contents[type] && contents[type].test(ct)) { + dataTypes.unshift(type); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if (dataTypes[0] in responses) { + finalDataType = dataTypes[0]; + } else { + + // Try convertible dataTypes + for (type in responses) { + if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) { + finalDataType = type; + break; + } + if (!firstDataType) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if (finalDataType) { + if (finalDataType !== dataTypes[0]) { + dataTypes.unshift(finalDataType); + } + return responses[finalDataType]; + } + } + + /* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ + function ajaxConvert(s, response, jqXHR, isSuccess) { + var conv2, + current, + conv, + tmp, + prev, + converters = {}, + + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if (dataTypes[1]) { + for (conv in s.converters) { + converters[conv.toLowerCase()] = s.converters[conv]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while (current) { + + if (s.responseFields[current]) { + jqXHR[s.responseFields[current]] = response; + } + + // Apply the dataFilter if provided + if (!prev && isSuccess && s.dataFilter) { + response = s.dataFilter(response, s.dataType); + } + + prev = current; + current = dataTypes.shift(); + + if (current) { + + // There's only work to do if current dataType is non-auto + if (current === "*") { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if (prev !== "*" && prev !== current) { + + // Seek a direct converter + conv = converters[prev + " " + current] || converters["* " + current]; + + // If none found, seek a pair + if (!conv) { + for (conv2 in converters) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if (tmp[1] === current) { + + // If prev can be converted to accepted input + conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]]; + if (conv) { + + // Condense equivalence converters + if (conv === true) { + conv = converters[conv2]; + + // Otherwise, insert the intermediate dataType + } else if (converters[conv2] !== true) { + current = tmp[0]; + dataTypes.unshift(tmp[1]); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if (conv !== true) { + + // Unless errors are allowed to bubble, catch and return them + if (conv && s.throws) { + response = conv(response); + } else { + try { + response = conv(response); + } catch (e) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; + } + + jQuery.extend({ + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test(location.protocol), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function ajaxSetup(target, settings) { + return settings ? + + // Building a settings object + ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) : + + // Extending ajaxSettings + ajaxExtend(jQuery.ajaxSettings, target); + }, + + ajaxPrefilter: addToPrefiltersOrTransports(prefilters), + ajaxTransport: addToPrefiltersOrTransports(transports), + + // Main method + ajax: function ajax(url, options) { + + // If url is an object, simulate pre-1.5 signature + if ((typeof url === "undefined" ? "undefined" : _typeof(url)) === "object") { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + + // URL without anti-cache param + cacheURL, + + + // Response headers + responseHeadersString, + responseHeaders, + + + // timeout handle + timeoutTimer, + + + // Url cleanup var + urlAnchor, + + + // Request state (becomes false upon send and true upon completion) + completed, + + + // To know if global events are to be dispatched + fireGlobals, + + + // Loop variable + i, + + + // uncached part of the url + uncached, + + + // Create the final options object + s = jQuery.ajaxSetup({}, options), + + + // Callbacks context + callbackContext = s.context || s, + + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event, + + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks("once memory"), + + + // Status-dependent callbacks + _statusCode = s.statusCode || {}, + + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + + // Default abort message + strAbort = "canceled", + + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function getResponseHeader(key) { + var match; + if (completed) { + if (!responseHeaders) { + responseHeaders = {}; + while (match = rheaders.exec(responseHeadersString)) { + responseHeaders[match[1].toLowerCase()] = match[2]; + } + } + match = responseHeaders[key.toLowerCase()]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function getAllResponseHeaders() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function setRequestHeader(name, value) { + if (completed == null) { + name = requestHeadersNames[name.toLowerCase()] = requestHeadersNames[name.toLowerCase()] || name; + requestHeaders[name] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function overrideMimeType(type) { + if (completed == null) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function statusCode(map) { + var code; + if (map) { + if (completed) { + + // Execute the appropriate callbacks + jqXHR.always(map[jqXHR.status]); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for (code in map) { + _statusCode[code] = [_statusCode[code], map[code]]; + } + } + } + return this; + }, + + // Cancel the request + abort: function abort(statusText) { + var finalText = statusText || strAbort; + if (transport) { + transport.abort(finalText); + } + done(0, finalText); + return this; + } + }; + + // Attach deferreds + deferred.promise(jqXHR); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ((url || s.url || location.href) + "").replace(rprotocol, location.protocol + "//"); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if (s.crossDomain == null) { + urlAnchor = document.createElement("a"); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host; + } catch (e) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if (s.data && s.processData && typeof s.data !== "string") { + s.data = jQuery.param(s.data, s.traditional); + } + + // Apply prefilters + inspectPrefiltersOrTransports(prefilters, s, options, jqXHR); + + // If request was aborted inside a prefilter, stop there + if (completed) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if (fireGlobals && jQuery.active++ === 0) { + jQuery.event.trigger("ajaxStart"); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test(s.type); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace(rhash, ""); + + // More options handling for requests with no content + if (!s.hasContent) { + + // Remember the hash so we can put it back + uncached = s.url.slice(cacheURL.length); + + // If data is available and should be processed, append data to url + if (s.data && (s.processData || typeof s.data === "string")) { + cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if (s.cache === false) { + cacheURL = cacheURL.replace(rantiCache, "$1"); + uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++ + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if (s.data && s.processData && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) { + s.data = s.data.replace(r20, "+"); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if (s.ifModified) { + if (jQuery.lastModified[cacheURL]) { + jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]); + } + if (jQuery.etag[cacheURL]) { + jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]); + } + } + + // Set the correct header, if data is being sent + if (s.data && s.hasContent && s.contentType !== false || options.contentType) { + jqXHR.setRequestHeader("Content-Type", s.contentType); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : s.accepts["*"]); + + // Check for headers option + for (i in s.headers) { + jqXHR.setRequestHeader(i, s.headers[i]); + } + + // Allow custom headers/mimetypes and early abort + if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add(s.complete); + jqXHR.done(s.success); + jqXHR.fail(s.error); + + // Get transport + transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR); + + // If no transport, we auto-abort + if (!transport) { + done(-1, "No Transport"); + } else { + jqXHR.readyState = 1; + + // Send global event + if (fireGlobals) { + globalEventContext.trigger("ajaxSend", [jqXHR, s]); + } + + // If request was aborted inside ajaxSend, stop there + if (completed) { + return jqXHR; + } + + // Timeout + if (s.async && s.timeout > 0) { + timeoutTimer = window.setTimeout(function () { + jqXHR.abort("timeout"); + }, s.timeout); + } + + try { + completed = false; + transport.send(requestHeaders, done); + } catch (e) { + + // Rethrow post-completion exceptions + if (completed) { + throw e; + } + + // Propagate others as results + done(-1, e); + } + } + + // Callback for when everything is done + function done(status, nativeStatusText, responses, headers) { + var isSuccess, + success, + error, + response, + modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if (completed) { + return; + } + + completed = true; + + // Clear timeout if it exists + if (timeoutTimer) { + window.clearTimeout(timeoutTimer); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if (responses) { + response = ajaxHandleResponses(s, jqXHR, responses); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert(s, response, jqXHR, isSuccess); + + // If successful, handle type chaining + if (isSuccess) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if (s.ifModified) { + modified = jqXHR.getResponseHeader("Last-Modified"); + if (modified) { + jQuery.lastModified[cacheURL] = modified; + } + modified = jqXHR.getResponseHeader("etag"); + if (modified) { + jQuery.etag[cacheURL] = modified; + } + } + + // if no content + if (status === 204 || s.type === "HEAD") { + statusText = "nocontent"; + + // if not modified + } else if (status === 304) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if (status || !statusText) { + statusText = "error"; + if (status < 0) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = (nativeStatusText || statusText) + ""; + + // Success/Error + if (isSuccess) { + deferred.resolveWith(callbackContext, [success, statusText, jqXHR]); + } else { + deferred.rejectWith(callbackContext, [jqXHR, statusText, error]); + } + + // Status-dependent callbacks + jqXHR.statusCode(_statusCode); + _statusCode = undefined; + + if (fireGlobals) { + globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]); + } + + // Complete + completeDeferred.fireWith(callbackContext, [jqXHR, statusText]); + + if (fireGlobals) { + globalEventContext.trigger("ajaxComplete", [jqXHR, s]); + + // Handle the global AJAX counter + if (! --jQuery.active) { + jQuery.event.trigger("ajaxStop"); + } + } + } + + return jqXHR; + }, + + getJSON: function getJSON(url, data, callback) { + return jQuery.get(url, data, callback, "json"); + }, + + getScript: function getScript(url, callback) { + return jQuery.get(url, undefined, callback, "script"); + } + }); + + jQuery.each(["get", "post"], function (i, method) { + jQuery[method] = function (url, data, callback, type) { + + // Shift arguments if data argument was omitted + if (isFunction(data)) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax(jQuery.extend({ + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject(url) && url)); + }; + }); + + jQuery._evalUrl = function (url) { + return jQuery.ajax({ + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + "throws": true + }); + }; + + jQuery.fn.extend({ + wrapAll: function wrapAll(html) { + var wrap; + + if (this[0]) { + if (isFunction(html)) { + html = html.call(this[0]); + } + + // The elements to wrap the target around + wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true); + + if (this[0].parentNode) { + wrap.insertBefore(this[0]); + } + + wrap.map(function () { + var elem = this; + + while (elem.firstElementChild) { + elem = elem.firstElementChild; + } + + return elem; + }).append(this); + } + + return this; + }, + + wrapInner: function wrapInner(html) { + if (isFunction(html)) { + return this.each(function (i) { + jQuery(this).wrapInner(html.call(this, i)); + }); + } + + return this.each(function () { + var self = jQuery(this), + contents = self.contents(); + + if (contents.length) { + contents.wrapAll(html); + } else { + self.append(html); + } + }); + }, + + wrap: function wrap(html) { + var htmlIsFunction = isFunction(html); + + return this.each(function (i) { + jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html); + }); + }, + + unwrap: function unwrap(selector) { + this.parent(selector).not("body").each(function () { + jQuery(this).replaceWith(this.childNodes); + }); + return this; + } + }); + + jQuery.expr.pseudos.hidden = function (elem) { + return !jQuery.expr.pseudos.visible(elem); + }; + jQuery.expr.pseudos.visible = function (elem) { + return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); + }; + + jQuery.ajaxSettings.xhr = function () { + try { + return new window.XMLHttpRequest(); + } catch (e) {} + }; + + var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + + support.cors = !!xhrSupported && "withCredentials" in xhrSupported; + support.ajax = xhrSupported = !!xhrSupported; + + jQuery.ajaxTransport(function (options) { + var _callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if (support.cors || xhrSupported && !options.crossDomain) { + return { + send: function send(headers, complete) { + var i, + xhr = options.xhr(); + + xhr.open(options.type, options.url, options.async, options.username, options.password); + + // Apply custom fields if provided + if (options.xhrFields) { + for (i in options.xhrFields) { + xhr[i] = options.xhrFields[i]; + } + } + + // Override mime type if needed + if (options.mimeType && xhr.overrideMimeType) { + xhr.overrideMimeType(options.mimeType); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if (!options.crossDomain && !headers["X-Requested-With"]) { + headers["X-Requested-With"] = "XMLHttpRequest"; + } + + // Set headers + for (i in headers) { + xhr.setRequestHeader(i, headers[i]); + } + + // Callback + _callback = function callback(type) { + return function () { + if (_callback) { + _callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null; + + if (type === "abort") { + xhr.abort(); + } else if (type === "error") { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if (typeof xhr.status !== "number") { + complete(0, "error"); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, xhr.statusText); + } + } else { + complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + (xhr.responseType || "text") !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders()); + } + } + }; + }; + + // Listen to events + xhr.onload = _callback(); + errorCallback = xhr.onerror = xhr.ontimeout = _callback("error"); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if (xhr.onabort !== undefined) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function () { + + // Check readyState before timeout as it changes + if (xhr.readyState === 4) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout(function () { + if (_callback) { + errorCallback(); + } + }); + } + }; + } + + // Create the abort callback + _callback = _callback("abort"); + + try { + + // Do send the request (this may raise an exception) + xhr.send(options.hasContent && options.data || null); + } catch (e) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if (_callback) { + throw e; + } + } + }, + + abort: function abort() { + if (_callback) { + _callback(); + } + } + }; + } + }); + + // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) + jQuery.ajaxPrefilter(function (s) { + if (s.crossDomain) { + s.contents.script = false; + } + }); + + // Install script dataType + jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function textScript(text) { + jQuery.globalEval(text); + return text; + } + } + }); + + // Handle cache's special case and crossDomain + jQuery.ajaxPrefilter("script", function (s) { + if (s.cache === undefined) { + s.cache = false; + } + if (s.crossDomain) { + s.type = "GET"; + } + }); + + // Bind script tag hack transport + jQuery.ajaxTransport("script", function (s) { + + // This transport only deals with cross domain requests + if (s.crossDomain) { + var script, _callback2; + return { + send: function send(_, complete) { + script = jQuery(" + diff --git a/src/main/resources/static/vendor/bpmn-font/css/bpmn-codes.css b/src/main/resources/static/vendor/bpmn-font/css/bpmn-codes.css new file mode 100644 index 0000000..c57fe9c --- /dev/null +++ b/src/main/resources/static/vendor/bpmn-font/css/bpmn-codes.css @@ -0,0 +1,107 @@ + +.bpmn-icon-screw-wrench:before { content: '\e800'; } /* '' */ +.bpmn-icon-trash:before { content: '\e801'; } /* '' */ +.bpmn-icon-conditional-flow:before { content: '\e802'; } /* '' */ +.bpmn-icon-default-flow:before { content: '\e803'; } /* '' */ +.bpmn-icon-gateway-parallel:before { content: '\e804'; } /* '' */ +.bpmn-icon-intermediate-event-catch-cancel:before { content: '\e805'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-message:before { content: '\e806'; } /* '' */ +.bpmn-icon-start-event-compensation:before { content: '\e807'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-parallel-multiple:before { content: '\e808'; } /* '' */ +.bpmn-icon-loop-marker:before { content: '\e809'; } /* '' */ +.bpmn-icon-parallel-mi-marker:before { content: '\e80a'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-signal:before { content: '\e80b'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-timer:before { content: '\e80c'; } /* '' */ +.bpmn-icon-intermediate-event-catch-parallel-multiple:before { content: '\e80d'; } /* '' */ +.bpmn-icon-intermediate-event-catch-compensation:before { content: '\e80e'; } /* '' */ +.bpmn-icon-gateway-xor:before { content: '\e80f'; } /* '' */ +.bpmn-icon-connection:before { content: '\e810'; } /* '' */ +.bpmn-icon-end-event-cancel:before { content: '\e811'; } /* '' */ +.bpmn-icon-intermediate-event-catch-condition:before { content: '\e812'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-parallel-multiple:before { content: '\e813'; } /* '' */ +.bpmn-icon-start-event-condition:before { content: '\e814'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-timer:before { content: '\e815'; } /* '' */ +.bpmn-icon-sequential-mi-marker:before { content: '\e816'; } /* '' */ +.bpmn-icon-user-task:before { content: '\e817'; } /* '' */ +.bpmn-icon-business-rule:before { content: '\e818'; } /* '' */ +.bpmn-icon-sub-process-marker:before { content: '\e819'; } /* '' */ +.bpmn-icon-start-event-parallel-multiple:before { content: '\e81a'; } /* '' */ +.bpmn-icon-start-event-error:before { content: '\e81b'; } /* '' */ +.bpmn-icon-intermediate-event-catch-signal:before { content: '\e81c'; } /* '' */ +.bpmn-icon-intermediate-event-catch-error:before { content: '\e81d'; } /* '' */ +.bpmn-icon-end-event-compensation:before { content: '\e81e'; } /* '' */ +.bpmn-icon-subprocess-collapsed:before { content: '\e81f'; } /* '' */ +.bpmn-icon-subprocess-expanded:before { content: '\e820'; } /* '' */ +.bpmn-icon-task:before { content: '\e821'; } /* '' */ +.bpmn-icon-end-event-error:before { content: '\e822'; } /* '' */ +.bpmn-icon-intermediate-event-catch-escalation:before { content: '\e823'; } /* '' */ +.bpmn-icon-intermediate-event-catch-timer:before { content: '\e824'; } /* '' */ +.bpmn-icon-start-event-escalation:before { content: '\e825'; } /* '' */ +.bpmn-icon-start-event-signal:before { content: '\e826'; } /* '' */ +.bpmn-icon-business-rule-task:before { content: '\e827'; } /* '' */ +.bpmn-icon-manual:before { content: '\e828'; } /* '' */ +.bpmn-icon-receive:before { content: '\e829'; } /* '' */ +.bpmn-icon-call-activity:before { content: '\e82a'; } /* '' */ +.bpmn-icon-start-event-timer:before { content: '\e82b'; } /* '' */ +.bpmn-icon-start-event-message:before { content: '\e82c'; } /* '' */ +.bpmn-icon-intermediate-event-none:before { content: '\e82d'; } /* '' */ +.bpmn-icon-intermediate-event-catch-link:before { content: '\e82e'; } /* '' */ +.bpmn-icon-end-event-escalation:before { content: '\e82f'; } /* '' */ +.bpmn-icon-text-annotation:before { content: '\e830'; } /* '' */ +.bpmn-icon-bpmn-io:before { content: '\e831'; } /* '' */ +.bpmn-icon-gateway-complex:before { content: '\e832'; } /* '' */ +.bpmn-icon-gateway-eventbased:before { content: '\e833'; } /* '' */ +.bpmn-icon-gateway-none:before { content: '\e834'; } /* '' */ +.bpmn-icon-gateway-or:before { content: '\e835'; } /* '' */ +.bpmn-icon-end-event-terminate:before { content: '\e836'; } /* '' */ +.bpmn-icon-end-event-signal:before { content: '\e837'; } /* '' */ +.bpmn-icon-end-event-none:before { content: '\e838'; } /* '' */ +.bpmn-icon-end-event-multiple:before { content: '\e839'; } /* '' */ +.bpmn-icon-end-event-message:before { content: '\e83a'; } /* '' */ +.bpmn-icon-end-event-link:before { content: '\e83b'; } /* '' */ +.bpmn-icon-intermediate-event-catch-message:before { content: '\e83c'; } /* '' */ +.bpmn-icon-intermediate-event-throw-compensation:before { content: '\e83d'; } /* '' */ +.bpmn-icon-start-event-multiple:before { content: '\e83e'; } /* '' */ +.bpmn-icon-script:before { content: '\e83f'; } /* '' */ +.bpmn-icon-manual-task:before { content: '\e840'; } /* '' */ +.bpmn-icon-send:before { content: '\e841'; } /* '' */ +.bpmn-icon-service:before { content: '\e842'; } /* '' */ +.bpmn-icon-receive-task:before { content: '\e843'; } /* '' */ +.bpmn-icon-user:before { content: '\e844'; } /* '' */ +.bpmn-icon-start-event-none:before { content: '\e845'; } /* '' */ +.bpmn-icon-intermediate-event-throw-escalation:before { content: '\e846'; } /* '' */ +.bpmn-icon-intermediate-event-catch-multiple:before { content: '\e847'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-escalation:before { content: '\e848'; } /* '' */ +.bpmn-icon-intermediate-event-throw-link:before { content: '\e849'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-condition:before { content: '\e84a'; } /* '' */ +.bpmn-icon-data-object:before { content: '\e84b'; } /* '' */ +.bpmn-icon-script-task:before { content: '\e84c'; } /* '' */ +.bpmn-icon-send-task:before { content: '\e84d'; } /* '' */ +.bpmn-icon-data-store:before { content: '\e84e'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-escalation:before { content: '\e84f'; } /* '' */ +.bpmn-icon-intermediate-event-throw-message:before { content: '\e850'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-multiple:before { content: '\e851'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-signal:before { content: '\e852'; } /* '' */ +.bpmn-icon-intermediate-event-throw-multiple:before { content: '\e853'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-message:before { content: '\e854'; } /* '' */ +.bpmn-icon-ad-hoc-marker:before { content: '\e855'; } /* '' */ +.bpmn-icon-service-task:before { content: '\e856'; } /* '' */ +.bpmn-icon-task-none:before { content: '\e857'; } /* '' */ +.bpmn-icon-compensation-marker:before { content: '\e858'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-multiple:before { content: '\e859'; } /* '' */ +.bpmn-icon-intermediate-event-throw-signal:before { content: '\e85a'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-condition:before { content: '\e85b'; } /* '' */ +.bpmn-icon-participant:before { content: '\e85c'; } /* '' */ +.bpmn-icon-event-subprocess-expanded:before { content: '\e85d'; } /* '' */ +.bpmn-icon-lane-insert-below:before { content: '\e85e'; } /* '' */ +.bpmn-icon-space-tool:before { content: '\e85f'; } /* '' */ +.bpmn-icon-connection-multi:before { content: '\e860'; } /* '' */ +.bpmn-icon-lane:before { content: '\e861'; } /* '' */ +.bpmn-icon-lasso-tool:before { content: '\e862'; } /* '' */ +.bpmn-icon-lane-insert-above:before { content: '\e863'; } /* '' */ +.bpmn-icon-lane-divide-three:before { content: '\e864'; } /* '' */ +.bpmn-icon-lane-divide-two:before { content: '\e865'; } /* '' */ +.bpmn-icon-data-input:before { content: '\e866'; } /* '' */ +.bpmn-icon-data-output:before { content: '\e867'; } /* '' */ +.bpmn-icon-hand-tool:before { content: '\e868'; } /* '' */ +.bpmn-icon-transaction:before { content: '\e8c4'; } /* '' */ \ No newline at end of file diff --git a/src/main/resources/static/vendor/bpmn-font/css/bpmn-embedded.css b/src/main/resources/static/vendor/bpmn-font/css/bpmn-embedded.css new file mode 100644 index 0000000..a271e3b --- /dev/null +++ b/src/main/resources/static/vendor/bpmn-font/css/bpmn-embedded.css @@ -0,0 +1,160 @@ +@font-face { + font-family: 'bpmn'; + src: url('../font/bpmn.eot?43681877'); + src: url('../font/bpmn.eot?43681877#iefix') format('embedded-opentype'), + url('../font/bpmn.svg?43681877#bpmn') format('svg'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: 'bpmn'; + src: url('data:application/octet-stream;base64,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') format('woff'), + url('data:application/octet-stream;base64,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AQEBAQIIAgECAgQBFgEBBAMMBQkEBgUEAwoCCAECAQICAgcBAQEBAQQDBAj8pwUICAQCAQEBAgYCAgIBBAEGAgoDBAEDBgQFCQQEBAMEAgESAQIBAgECAgIHAgEBAQECBwMFAvAEBQQEAwQCAgcCAwUCBAECAwwKAwQCBAEBBAMEBAkIBQcDDwIBBgUIAQEBBgECAQIBAgICCQECAgMECP2tBAgEAwICAgUGDAYBDAEGBwMBAwMBBwcDAQcHAQMBAwQIBAQMBAQEBAkEBAQFAgEBBAQDFQMECgcZAwoCAwMDAwMDAwIGAwIDAgMCCAGcBQQEAQcKHAsHEgQLBAcEBAcECAQQCAQDAgIBBAQDBAUMBQ0EBQQFCAUmBAkEBAQEBAQBBAMBAwEDBAQIBAkEAgIBAgYDBAX+RAQFBAYCAgECAwMFBAEEDQkBDQEEBQUEAQQFBQoFGQEEARQGBQUFCwoJBQQEAwQBAgMDBAcTBQQFBQQFBQQlHggEBAkMAw0CEgUEBQMBFAQECQgWLAUFBAUFBQQFGwQGBAEBAgMDBAQECQMGBQsFBQUGFAEeBQoFBQQBBAEEBRwNBAEEBQMCAQICAwQIAfr+yAE4MVo+urp9AfIBAQEBBwICBAMEBAQJBAUGAwIJAgEBAQEBAQIFAQIDAwgEBQQJAwMDBwEBAQFTAQICBAcJCQoBCQcGBwMEAwQDBAcIBxQEDQQEIAMDAgICAgMDCAkFBgUFBAEEAQQFHA0EAQgEAQQEBAgBAwEDAQMECAMBAwQDAQYEBwgBBAQBAwQDAQMMAwEDAQMBCAQEBAEEBAQBBA0XBQUEAQQBCQUKBQwEBQQEAwQBAgUHDB4IBAkEFAcIBwQDBAMEAwcGBAMHBQQECQQEAwQBAgIFDAUJBAMGAgEBAQEBAgIHAgIDAgICAQIDAwgFCQgDBQIBAgECAQICAgkCAQEBJwIDBQIEAQIPAwIBAgkMCQEJBAMDAQMDAQMLBwcJCQQDBAQBAQQDDAMEBgMDAgMDAwMDAwIDAwIDAgMCAwIDBAMWAwMICQkHAwQ7AQIDAwQNBQsCAwMDAwMDAgMDCiMDBwMHBA4LAwcDCAMDAgEBAwIECAkEAgQJBAQEBAQFAwEDAQMEAQMQBAMBAwgDAQoBAwMBAwMBAwMBBgQJAQMCAwOpAQQEAwQIBAQJBQQJDQQbBQ0JBAQJ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CAQmBAgDBAQEBwQIAxoDCAcHAwkFBAQEAwQBBAMHAQMFBAQEBAQJBCYECQUEBAUNsQUDBgcBAwgDARUDAQMDAQkBDAEJCQMDAgECAwMIBAEEAgICAwMIBAUECQMIAwIEAwIDAgMCAwIDAwMCAwMDAwMDAwMGAyMCAwQEAgIFBAgFAYQEBAQDAwMBBgMDAgMCAwIDAgMHFgEEAQQBBgMCAgQEAwQFCQQEBAMEAQICAgECAQIBAgICAQEBCAEBAQICBAECBwMCAQIDAgECBgMJAwMDBAn9xwQIAwMCAgECAQEBAQEBAgEIAgEBAQMDBAQEBQkEAwMEAQIFAwIBAQEBAQECAQECAwMJBAKNBQQEAwQCAgcCAwUCBAECAwwKAwQCBAEBBAMEBAkIBQcDDwIBBgUIAQEBBgECAQIBAgICCQECAgMECAX9rgQEBAMCAgIFBgwGAQwBBgcDAQMDAQcHAwEHBwEDAQMECAQEDAQEBAQJBAQEBQIBAQQEAxUDBAoHGQMKAgMDAwMDAwMCBgMCAwIDAggOAaUEBAEHChwLBxIECwQHBAQHBAgEEAgEAwICAQQEAwQFEQ0EBQQFCAUmBAkEBAQEBAQBBAMBAwEDBAQIBAkEAgIBAgYDBAUEpwUGBgsFDAUFBiYGCggEAgMBAQIGBAkEKwUJBQUFBQoFHgUKBQUFBQoEGAkFBAMEBAEBBAMEByYFBgULBgsG7wQFAwQEAgIIAgwHCAcEAwQDBAMHBgcPAgkCAxEEAwQJCQQEAwQBAgMCAQIDAgECEgEJBAYBAwQDAQMIBAMBAwEDAQgEBAQBBAgBBAoI/fQECAUEAQQEBAwEBAQIAwEDBAMEAwQJAQ8CAQIDAwUCAQQDAwECAwMIBAkFBwUFEAYCBgIPBwYHAwQDBAMEBwgEBAcCAQICAwQIBAKvBAgGAgEBAQEBAggCAQICBAEWAQEEAwwFCQQGBQQDCgIIAQIBAgICBwEBAQEBBAMECAT8pgQECAQCAQEBAgYCAgIBBAEGAgoDBAEDBgQFCQQEBAMEAgESAQIBAgECAgIHAgEBAQECBwMFBJQFBAYCAgECAwMFBAEEDQkBDQEEBQUEAQQFBQoFGQEEARQGBQUFCwoJBQQEAwQBAgMDBAcTBQQFBQQFBQQlHggEBAkMAw0NAhoEBQMBFAQECQgWLAUFBAUFBQQFGwQGBAEBAgMDBAQECQMGBQsFBQUGFAEeBQoFBQQBBAEEBRwNBAEEBQMCAQICAwQIBAI0SXd8Wx4VFmqCbRwVJ0lybB4fDld7NCUrMTU2AxoHBQkZMzMG7wECAgUMBQkEAwYCAQEBAQECAgcCAgMCAgIBAgMDCAUJCAMFAgECAQIBAgICCQIBAQEnAQEDBQIEAQIPAwIBAgkMCQEJBAMDAQMDAQMLBwcJCQQDBAQBAQQDDAMEBgMDAgMDAwMDAwIDAwIDAgMCAwIDBAMWAwMICQkHAwQ8AQEDAwQNBQsCAwMDAwMDAgMDCiMDBwMHBA4LAwcDCAMDAgEBAwIECAkEAgQJBAQEBAQFAwEDAQMEAQMQBAMBAwgDAQoBAwMBAwMBAwMBBgQJAQMCAwMCqwEEBAMECAQECQUECQ0EGwUNCQQECQQBBCIEBQEEBAMDAgECAgMECAkFBBIECwQHBAQHBAgEHgQIBAcEBAcEBAkEBAQDBAF3AQIDAwgHBAcEGgMLCwcGBAMHFA8DBwEIBQQFCAMDAgICAgcBAxUBAwsBBxAEBAwEBAQEBAQJBCYFBQgEBAMEoQICAwMECQkJBgEMAQYMBgUDAwIBBAEEAQIFBAICAQEBBAEBAQYBAQECAQECAwcFBAUECAMDCQIBBgMQAwYDAgMCAwIDAgMGAgMDAwMDBwNNAQIBAwYMAwMFAwIBAQEEAwMECQUECAMDAgEBAQECCQICAgECAQIBAQECAgIBAQEEAQEBBQQDBQQFCAgDAgECzgEBAQEHAgIEAwQEBAkEBQYDAgkCAQEBAQEBAgUBAgMDCAQFBAkDAwMHAQEBAVMBAgIEBwkJCgEJBwYHAwQDBAMEBwgHFAQNBAQgAwMCAgICAwMICQUGBQUEAQQBBAUcDQQBCAQBBAQECAEDAQMBAwQIAwEDBAMBBgQHAgoBBAQBAwQDAQMMAwEDAQMBCAQEBAEEBAQBBA0XBQUEAQQBCQUKBQwEBQQEAwQBAgUHDB4IBAkEFAcIBwQDBAMEAwcGBAMHBQQECQQEAwT+xQEECAQEBAQeBQoFBQUFCQUnBQQFCQoEMgQFBAgEBgICBggKBRkBBAEUBgUFBQsGJgUGBQsGCwYWBgkIAwMEEAEBBggICQYRBQYFBgsFIQYLBQUKBg8BBAEZBQoBBAYCAQEDAgQICQgBKQQFBQQFBQkFIgUJBQUFBQoF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AQMGBAUJBAQEAwQCARIBAgECAQICAgcCAQEBAQIHAwUC8AQFBAQDBAICBwIDBQIEAQIDDAoDBAIEAQEEAwQECQgFBwMPAgEGBQgBAQEGAQIBAgECAgIJAQICAwQI/a0ECAQDAgICBQYMBgEMAQYHAwEDAwEHBwMBBwcBAwEDBAgEBAwEBAQECQQEBAUCAQEEBAMVAwQKBxkDCgIDAwMDAwMDAgYDAgMCAwIIAZwFBAQBBwocCwcSBAsEBwQEBwQIBBAIBAMCAgEEBAMEBQwFDQQFBAUIBSYECQQEBAQEBAEEAwEDAQMEBAgECQQCAgECBgMEBf5EBAUEBgICAQIDAwUEAQQNCQENAQQFBQQBBAUFCgUZAQQBFAYFBQULCgkFBAQDBAECAwMEBxMFBAUFBAUFBCUeCAQECQwDDQISBQQFAwEUBAQJCBYsBQUEBQUFBAUbBAYEAQECAwMEBAQJAwYFCwUFBQYUAR4FCgUFBAEEAQQFHA0EAQQFAwIBAgIDBAgCIX2MfX2MfRd9Xn1+XQGVAQEBAQcCAgQDBAQECQQFBgMCCQIBAQEBAQECBQECAwMIBAUECQMDAwcBAQEBUwECAgQHCQkKAQkHBgcDBAMEAwQHCAcUBA0EBCADAwICAgIDAwgJBQYFBQQBBAEEBRwNBAEIBAEEBAQIAQMBAwEDBAgDAQMEAwEGBAcIAQQEAQMEAwEDDAMBAwEDAQgEBAQBBAQEAQQNFwUFBAEEAQkFCgUMBAUEBAMEAQIFBwweCAQJBBQHCAcEAwQDBAMHBgQDBwUEBAkEBAMEAQICBQwFCQQDBgIBAQEBAQICBwICAwICAgECAwMIBQkIAwUCAQIBAgECAgIJAgEBAScCAwUCBAECDwMCAQIJDAkBCQQDAwEDAwEDCwcHCQkEAwQEAQEEAwwDBAYDAwIDAwMDAwMCAwMCAwIDAgMCAwQDFgMDCAkJBwMEOwECAwMEDQULAgMDAwMDAwIDAwojAwcDBwQOCwMHAwgDAwIBAQMCBAgJBAIECQQEBAQEBQMBAwEDBAEDEAQDAQMIAwEKAQMDAQMDAQMDAQYECQEDAgMDqQEEBAMECAQECQUECQ0EGwUNCQQECQQBBCIEBQEEBAMDAgECAgMECAkFBBIECwQHBAQHBAgEHgQIBAcEBAcEBAkEBAQDBC0BBAgEBAQEHgUKBQUFBQkF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CgUGAwkECQQEAwQCBAYBBAMCAwIDAgECCAEFAwQCBAICBQIHAgIBAgkBAgIDBwMCAwIBAgMCBgIKBf3zBQcBAgMCAwIDAgMCAwQBAgIDAgQBBAQBAgICAgICAQICAgQCAgQBAQECAwICCgECAgIBBAECAQIBAgECAgEEBAMOBAgEAwEBAgMBAgICAQIBAgECAQICAwIBAggCAQICAgEEAgQBBgIKAgYDCgMGAwUDAgEEBggFArIEBQMGAgEBAQEBAQEBAgEDBQMFAwQDAgYDAQIDBgQJCQQEAwIBAQMCAQIDAwIBBQEMAwECAQEBAQEBAQEEAwQECPymBAUDBAQBAQMCAQMCAQQBCgEEAwIDAgECAwECBAcJCQQEAwQCBAIDAgcEAQYBAgECCAEBAQEFCAgCsQQECQQFCgQPBQULDwYFCwUhBgsQCAQFAgIEAwQNCQYGFAUBEgYHBQEFAQUBBQEcAQsFAQUFAQULDwEEAQMDAgEEAwQECP3eBAQEAwICAQIDBA0CAQIDAgECAwMLAgEIAwMFAQIBAgECAQIDAwECAQIBAgQDBgMNAx0CAw0EAw0JBQgFAgEEAwQEAwQIAxQCEQMJBRECBgUDBQUFAgEPAgUCAgEEAwQRBAQFAhwM/pABfBj+tAEnGRlKGBhVGBhNGBgCLQECBgECBAIDBAgJBQQEAwQBAgICBAIBAQEBAQUBBgQDCQUICAIEBgEBAU8BAQMDBAQEBQkEBgECAQYDBAIIDgMIAwYDBAECAgMEAwQDBwcDCAMSCggCBAICAwMICgcHAQwIBAQEBAQEBAsBBwMGAgYCAwUDBwMCAwkDAgIHAgICAgEBAQICBAIFDAEEAgICAgIBAgICAgIBBAIBAgIDBAEEAQQBAgMCAwIBAgMCAQIGAgECBgMDAgUCAQIPAwIBAgECAwYDAwMDAwMDAwEECQUIAwMDAQQDAwQGBQMCBQECAwIDAgMCAwMCBQIDAgwCAwIDAgMEAwQDBgMKAwYCCgEGAgUEBAQJCQYEAf7GAQICCAQEBAQzAwkDBgIGAwMDAwMDBgIDAwkCDgMIAQ0FCwUGCgcEBQkEBgICAgIDAwMDBgYGBQEFBw8mAwoDAwcDAwQDAwQDAwQDBwMOAywFCQgEAgMCEwECAwMIBBsGBxMHDRMGBw0GHw0FAQUBBQEFAQUBBQEBBAQEAgICAwMJCQgGBgUGEAsGEQUGBgUvBgUGBgwGBwUHBgL+sgECBgQEBgQJBAMFCQIDBAMMAQQDBAMHCQkIAwMDAgIBBgIGAwIDAgMDDwYBAwMBAwQHDAQBAwQEBAkIBAMCAgIBAwIEBAkEBQQEAwEKAgICAgICAQEHAgUBAQEDAgIBAgECAQEBAQECAgIEAgkBAQQBBAEEBwUECQgEAgMBAwcGAwMGAgIDAQMCAwIJAgMCAQQBBA0BAgAAAAMAAP/SAyMC6gAFAAwAEAAAASIjESERJxQVMxEhEQUWFyMCctbXAl7luP38AXk/Pn0C6vzoAmKJXV39/AK+DEBBAAAACAAA/9MD1ALpAA8AHwA4AE8AUwBXAFsAXwAAEw4BBxEeARchPgE3ES4BJwUhHgEXEQ4BByEuAScRPgEXByMOARQeAwYPASE3PgEuBDY/AQczBgcGHgQGByM2NzYnLgQ2FxUzNQcVMzUHFTM1BxUzNddSbwICb1ICOlNuAgJuU/3GAjo6TAEBTDr9xjpMAQFMlAMBMCscIhkFHCopAQEDLCYGHyEXASMuKfmeFQwXAR0iGAUbKJ4RCRMCBB4iFgEiB3uAgEZ8aoAC6QJuUv5uUm4CAm5SAZJSbgI8AUs6/m46SwEBSzoBkjpLWwIcNDMoIh4bIxkZAhswLyUiHx0qHBgaEA8ZMygiHhsjGA0NGRgXJSIfHSkSDAxADAxBDAxBDAwAAAQAAP/TA9QC6QAPAB8AIgAnAAATDgEHER4BFyE+ATcRLgEnBSEeARcRDgEHIS4BJxE+AR8BNwURIREH11JvAgJvUgI6U24CAm5T/cYCOjpMAQFMOv3GOkwBAUwQ+vr+DQH0+wLpAm5S/m5SbgICblIBklJuAjwBSzr+bjpLAQFLOgGSOktejY00/ukBF4wAAAUAAAAAA0kCqQAfADYATgBmAH4AAAEiDgEHDgEPAREeARceAjI+ATc+ATcRNCcuAScuAgcyHgEXFhcGBw4CIi4BJyYnNjc+AgcWFx4CMj4BPwEVDgEHDgIiLgEnJicVFhceAjI+AT8BFQ4BBw4CIi4BJyYnFRYXHgIyPgE/ARUOAQcOAiIuAScmJwH0PHFdIA8WBAEEFw8gXXF4cV0gEBYEAQQWDyBdcTw6blgZEwQEExlYbnRuWBkTBAQTGVhu9wQDIF1xeHFdIAcBCwwZWG50blgZFgIEAyBdcXhxXSAHAQsMGVhudG5YGRYCBAMgXXF4cV0gBwELDBlYbnRuWBkWAgKpChQRBxYOBP4lEBYIERMKChMRCBYQAdsCAg4WBxEUCiMKEw0LCAgLDhIKChIOCwgICw0TCmsCAhAUCgoUEAQpBAsGDhIKChIODQgwAgIQFAoKFBAEKQQLBg4SCgoSDg0IMAICEBQKChQQBPMECwYOEwkJEw4NCAAACQAA/6ADvQMhAAgAEQAfAC0AQABPAF4AbQB/AAABDgEHPgE3FyYnFhcnDgE1PgETIgYHBhY3PgEXPgEnJhciBhceARcWNicuAScmBQYPAQ4BBw4BFjY3Njc+ATc0JgEiBhcWBgcGFjc+AScuAQUiBhceARcWNicuAScuAQEOAQcOAQcGFjc+ATc2JiEOARceARceATc2JicuAScuAQH0IjgiIDwgfT89IiJEETESHhUgQR4RDxQwZDAVBxMvyRQJESg7FxAgCBlGLAX98Q8MFhsrEggGGhgEITELGQINAq0QDAMDGBkFIw0fGgcCDfykEA0DAhsXDSMFFxcBAgwCrhAZDiBHJRIPFDZjKgoM/dMSCA8kUywNHwkHEQ4qUCIFDAImY8pjIUUhh8h1bW5KEToHNWsBggcKDCUEDAIKASYIDFAlCh1NKw4WEzFVIAMLAwsVGj4hDBsTEA4/NAsSEAkO/sgbDjNjLRQRDzd7PwgIEhoOM2QtDxEULWMyCAv+swMWCBUcCgslAwwxJAwbAiIKHikMBQUPDhcBCiMcBQgAAAAABgAA/40DzQMiAA4AHQAsADsAQABGAAABBgQHBhYXFiQ2EgImJyYHNhYXFgYHBiQnJhI3PgEXIgYHBhYXFjY3NiYnLgEHHgEXDgEHBiYnJjY3PgEHFhc2NwUUFSERBwHzqv8AFhCGgXwBEc5HWtWHERed6REMkIKB/vxPTQdYOZ9hkNIHBJ+AeN04NSxcMXpDf7YCAZl2b74jH0teJFF9VlVUVv6FAZrJAyIC4amP/UE8IrgBCAECpQoCMQHQm4rqMC1Pb3EBEGlETivIkIPPHRdobW3wUSswMAG0f3azDwx2a2jNNxUWm0VFRUUgjIwBEqMAABAAAP+gA7sDIgAGAA4AGwApADgARgBVAGMAcgCBAJAAnwCsALsAyQDYAAABJicHFyE2NwYHIyc2NxYDDgEHBhY3NhcyNicmFyIGFx4BFxY2Jy4BJyYFDgEHDgEHBhY3PgE3NiY3IgYHBhY3NhYXFjYnJgcOAQcOAQcGFjc+ATc2JgUiBhceARcWNicuAScmBSIGBwYWFxY2Jy4BNzQmBSIGFxYGBwYWNz4BJy4BBSIGFx4BFxY2Jy4BNy4BBSIGFQ4BBwYWNz4BNy4BBQ4BFx4BFxY2JyYnJgUOAQcOAQcGFhc+ATc2JgUOARceARc+AScuAScmBQ4BBw4BBwYWNz4BNzYmAstrbNdSAQoqDCQk5kheXV1dHz0dEg8VYWMUBxIyyxQKESc9FQ0jBRhJLgP99BAXDCAxEQQjDRQ+KAkL+RAhCAUYDyZMIxQPEEXnER8OGi0PBSQMFz4kCwsBeRMKDxwmCw0jBA0vIgb9xREMAQUIDQslAg0FCA0C6RAMAwEZFwUjDR0bBAIN/KMQDQMBGRkNIgUXFwECDALsEAwIIRYHIw4dJgYBDf2oEQgMHkorFA0QTzcGAZ8RIBEaNhoSCBQvWigMCv43EggPKmM1FAgTMVsnBgIYEBkOIEglEQ0VNmQqCgwBok5OnP1/dW9t3ERDQwFFAQcKDCQEGRYmCQxTJQodSysPERQzViECCgIXCx5IKBQPEC5PIAwbAQMPEBQEAw0PBCQMHycEFAoUMBwVEBAjNxQMHDoiDB1GJhEQFS1RIASqGw4pUycRDBQoUykKDi0ZDjNjLRQQDzZ5PggKEBkONGQtDxIULWIyCAs4GQ4kQR0UFBAlVi8JDqACIAsjNA8CJAsfQQZNBBIFCQcDCSUBARkYDB4mAiIKIi8KASYICywgAwMDFgcVGwkLJQILMCQMGwAAAAAQAAD/oAO7AyIAAwAIABUAIwAyAEAATwBdAGwAewCKAJkApgC1AMMA0gAAAQYHIQMWFyE2Ew4BBwYWNzYXMjYnJhciBhceARcWNicuAScmBQ4BBw4BBwYWNz4BNzYmNyIGBwYWNzYWFxY2JyYHDgEHDgEHBhY3PgE3NiYFIgYXHgEXFjYnLgEnJgUiBgcGFhcWNicuATc0JgUiBhcWBgcGFjc+AScuAQUiBhceARcWNicuATcuAQUiBhUOAQcGFjc+ATcuAQUOARceARcWNicmJyYFDgEHDgEHBhYXPgE3NiYFDgEXHgEXPgEnLgEnJgUOAQcOAQcGFjc+ATc2JgH0YGABgMBLTP7STEsfPR0SDxVhYxQHEjLLFAoRJz0VDSMFGEkuA/30EBcMIDERBCMNFD4oCQv5ECEIBRgPJkwjFA8QRecRHw4aLQ8FJAwXPiQLCwF5EwoPHCYLDSMEDS8iBv3FEQwBBQgNCyUCDQUIDQLpEAwDARkXBSMNHRsEAg38oxANAwEZGQ0iBRcXAQIMAuwQDAghFgcjDh0mBgEN/agRCAweSisUDRBPNwYBnxEgERo2GhIIFC9aKAwK/jcSCA8qYzUUCBMxWycGAhgQGQ4gSCURDRU2ZCoKDAIyrK0BJoeHhwGqAQcKDCQEGRYmCQxTJQodSysPERQzViECCgIXCx5IKBQPEC5PIAwbAQMPEBQEAw0PBCQMHycEFAoUMBwVEBAjNxQMHDoiDB1GJhEQFS1RIASqGw4pUycRDBQoUykKDi0ZDjNjLRQQDzZ5PggKEBkONGQtDxIULWIyCAs4GQ4kQR0UFBAlVi8JDqACIAsjNA8CJAsfQQZNBBIFCQcDCSUBARkYDB4mAiIKIi8KASYICywgAwMDFgcVGwkLJQILMCQMGwAAAAAFAAD/jQPNAyIADgAdACwAOwBDAAABBgQHBhYXFiQ2EgImJyYHNhYXFgYHBiQnJhI3PgEXIgYHBhYXFjY3NiYnLgEHHgEXDgEHBiYnJjY3PgEXBgcXITY3JgHzqv8AFhCGgXwBEc5HWtWHERed6REMkIKB/vxPTQdYOZ9hkNIHBJ+AeN04NSxcMXpDf7YCAZl2b74jH0teJFEqbGtSAQoqKGsDIgLhqY/9QTwiuAEIAQKlCgIxAdCbiuowLU9vcQEQaUROK8iQg88dF2htbfBRKzAwAbR/drMPDHZraM03FRZXTk79f35OAAAAAAoAAP+gA70DIQAEAAsAEQAfAC0AQABPAF4AbQB/AAABFBUhEQUyMw4BByY3FBUhNRcTIgYHBhY3PgEXPgEnJhciBhceARcWNicuAScmBQYPAQ4BBw4BFjY3Njc+ATc0JgEiBhcWBgcGFjc+AScuAQUiBhceARcWNicuAScuAQEOAQcOAQcGFjc+ATc2JiEOARceARceATc2JicuAScuAQEnAZr+wXJyHj0eNdj+yJwEIEEeEQ8UMGQwFQcTL8kUCREoOxcQIAgZRiwF/fEPDBYbKxIIBhoYBCExCxkCDQKtEAwDAxgZBSMNHxoHAg38pBANAwIbFw0jBRcXAQIMAq4QGQ4gRyUSDxQ2YyoKDP3TEggPJFMsDR8JBxEOKlAiBQwB+pycATgxFDoHKw5dXbp9AfAHCgwlBAwCCgEmCAxQJQodTSsOFhMxVSADCwMLFRo+IQwbExAOPzQLEhAJDv7IGw4zYy0UEQ83ez8ICBIaDjNkLQ8RFC1jMggL/rMDFggVHAoLJQMMMSQMGwIiCh4pDAUFDw4XAQojHAUIAAAAAQAAAAADUgITAB8AABM+ATc2FhceARcWNjc+ATcVDgEHBiYnLgEnJgYHBg8BlhU/MSZSIzNaMiBDFxw2ERc/LyhSIjBVNBs6FyYbNQFKNWEeFRAWIVMiERQaH0EnpS9TGBAPGSNUHA4HFCMuWgAAAAcAAP/TA9QC6QAPAB8ARQBtAKUArgC3AAATDgEHER4BFyE+ATcRLgEnBSEeARcRDgEHIS4BJxE+ARcUFQYHJwcXBgcjFTMWFzUjNTM3Nj8BJzcXNzY/ATUzFTMuASc1BxUGBycHFwYHIxUzFhcHFzcWFxUzNTY3FzcnNj8BNQcmJzcnByYnNQczFRcWHwE3FwcXFh8BNxUjBwYPARcHJwcGDwEVIzUnJi8BByc3JyYvASM1Mzc2PwEnNxc3Nj8BFw4BFBYyNjQmBzIWFAYiJjQ211JvAgJvUgI6U24CAm5T/cYCOjpMAQFMOv3GOkwBAUxeDQ4ZLhgGBSMkBgsfHwIDCwUVDxYIERMIFzsFGQcEDw0YLxkIAyQkBQcaLxoMD0IPDRkvGggEIiMFBhgvGA0PLBYJFBAIFRAVBQsEAh4eAgMMBRcQFggQFAkWCRMRCBYQFwYKBQIfHwIFCgUWEBYHERMJCxUbGyscHBYMEBAYDw8C6QJuUv5uUm4CAm5SAZJSbgI8AUs6/m46SwEBSzoBkjpLMRIRBAgZLxgND0ITEDkWCRQQCBUQFgUMBAEfHgUKAiNAIgQIGS8ZDA9CDwwZLxoHBSQlAwgZLxkODQFCAQ8NGC4YBwQiFR8BBAsFFQ8WBxAUCQEXCRMRBxYQFgUKBQIgIAIDDAQWEBYIERIJFgkUEAgVEBYFDAMCMgEbKhwcKhsVDxgQEBgPAAIAAP/TA9QC6QAPAB8AABMOAQcRHgEXIT4BNxEuAScFIR4BFxEOAQchLgEnET4B11JvAgJvUgI6U24CAm5T/cYCOjpMAQFMOv3GOkwBAUwC6QJuUv5uUm4CAm5SAZJSbgI8AUs6/m46SwEBSzoBkjpLAAAAAwAAAAADXgJTABoAHgAkAAABDgEHBgcGFhcFFjYnNRYXFjYnES4BBwUnLgEHFBUnJRQVJic2AfYPGAyNiw0GDwE1ER4CjY4RHQICIw7+7AEDECjlAixyc3MCTgMSCF5eDCAIzwkWEp9gXgkWEgGiEwwMuqoLDVaampqamppOTEwAAAAACQAA/6ADvQMhAAYADgAcACoAPQBMAFsAagB8AAABJicHFyE2NwYHIyc2NxYDIgYHBhY3PgEXPgEnJhciBhceARcWNicuAScmBQYPAQ4BBw4BFjY3Njc+ATc0JgEiBhcWBgcGFjc+AScuAQUiBhceARcWNicuAScuAQEOAQcOAQcGFjc+ATc2JiEOARceARceATc2JicuAScuAQLLa2zXUgEKKgwkJOZIXl1dWSBBHhEPFDBkMBUHEy/JFAkRKDsXECAIGUYsBf3xDwwWGysSCAYaGAQhMQsZAg0CrRAMAwMYGQUjDR8aBwIN/KQQDQMCGxcNIwUXFwECDAKuEBkOIEclEg8UNmMqCgz90xIIDyRTLA0fCQcRDipQIgUMAaJOTpz9f3VvbdxEQ0MBQwcKDCUEDAIKASYIDFAlCh1NKw4WEzFVIAMLAwsVGj4hDBsTEA4/NAsSEAkO/sgbDjNjLRQRDzd7PwgIEhoOM2QtDxEULWMyCAv+swMWCBUcCgslAwwxJAwbAiIKHikMBQUPDhcBCiMcBQgABQAA/40DzQMiAA4AHQAsADsAPwAAAQYEBwYWFxYkNhICJicmBzYWFxYGBwYkJyYSNz4BFyIGBwYWFxY2NzYmJy4BBx4BFw4BBwYmJyY2Nz4BFwYHIQHzqv8AFhCGgXwBEc5HWtWHERed6REMkIKB/vxPTQdYOZ9hkNIHBJ+AeN04NSxcMXpDf7YCAZl2b74jH0teJFEqYGABgAMiAuGpj/1BPCK4AQgBAqUKAjEB0JuK6jAtT29xARBpRE4ryJCDzx0XaG1t8FErMDABtH92sw8MdmtozTcVFmOsrQAAAAAUAAD/owO4AyIABAAIAAwAEAAUABgAWwCzAQkBTAGhAf4CSQKLAs8DEgNpA7YEAgRMAAABFREhEQUzESMTFTM1BxUzNQcVMzUHFTM1AzEjByMHIxUjByMPBxUfBDM3MzczNzM3MzczFzMXMxczFzMXMz8FNS8FIycjNSMnIycXIw8FHxk/BDUvAyMnNSc1JyMvASMvATUnIyc1LwEjLwE1JzUnIzUnIycjLwE1LwEjJzUnIy8BBSMPAhUHIw8BFQ8CFQcVBxUPASMPARUPAhUPASMPASMPARUHFQ8BIw8CFR8FMz8ZNS8EITEjFSMPAxUfBDM3MzczFzMXMxczFzMXMx8GMz8FNS8CIy8JIycjJyMnIzUHIw8CIw8BFQcjDwEjBxUHIwcjByMHFQ8DIxUPARUPAiMPAR8FMz8dMz8DLwMFDwUfFhUfBDM/BDUnNS8INSc1LwQjJyMnNS8BIyc1JzUvATUjLwE1JyMnNS8CNS8DBSMPBRUjFQcVBxUjFQcVFxUzFRcVFxUXFR8JMz8ENS8CNSc1JzUnNSc1JzU3NTc1NzU3NTc1LwQFIw8DFQcXFQcVBxUHFQcVDwgVHwMzPwY1NzU/BzU3NTM1NzU3NSc1LwMFIw8DFRcVFxUXFRcVHwcVFxUfAjMVHwMzPwQ1Lws1JzUnNSc1JzUvBAUjDwUVBxUPDxUfBT8CNT8BNTczNzU/AjM/CjU3LwQFDwUfAhUXFRczFzMfAjMfATMVFxUXFRczHwEzFzMXFRcVHwEVHwIVHwIzPwU1LxwFIw8IIwcjByMHIwcjByMPBBUfBTM3MzczNzM3Mz8LMzczPwE1PwE1NzU/BDUvBAUPBRUfBTMfARUXMxczHwEVHwEzFxUfBDMXMx8GMz8FNS8WISMPFxUfBjM/CDM/BDU3MzczNzU/ATU/ATM/BDUvBAFdAS7+6v7+GsrKysrKysplCwYLBQwFBQYmBgoIBAIDAQECBgQJBCsFCQUFBQUKBR4FCgUFBQUKBBgJBQQDBAQBAQQDBAcmBQYFCwYLBvQFBAUDBAQCAggCDAcIBwQDBAMEAwcGBw8CCQIDEQQDBAkJBAQDBAECAwIBAgMCAQISAQkEBgEDBAMBAwgEAwEDAQMBCAQEBAEECAEECv3xBQQIBQQBBAQEDAQEBAgDAQMEAwQDBAkBDwIBAgMDBQIBBAMDAQIDAwgECQUHBQUQBgIGAg8HBgcDBAMEAwQHCAQEBwIBAgIDBAgBBBINCgUHBgICAwgIBAEIBCYECAMEBAQHBAgDGgMIBwcDCQUEBAQDBAEEAwcBAwUEBAQEBAkEJgQJBQQEBQ2tBAgGBwEDCAMBFQMBAwMBCQEMAQkJAwMCAQIDAwgEAQQCAgIDAwgEBQQJAwgDAgQDAgMCAwIDAgMDAwIDAwMDAwMDAwYDIwIDBAQCAgUECAGEBQgEAwMDAQYDAwIDAgMCAwIDBxYBBAEEAQYDAgIEBAMEBQkEBAQDBAECAgIBAgECAQICAgEBAQgBAQECAgQBAgcDAgECAwIBAgYDCQMDAwT9wwUECAMDAgIBAgEBAQEBAQIBCAIBAQEDAwQEBAUJBAMDBAECBQMCAQEBAQEBAgEBAgMDCQLuBQQIBgIBAQEBAQIIAgECAgQBFgEBBAMMBQkEBgUEAwoCCAECAQICAgcBAQEBAQQDBAj8pwUICAQCAQEBAgYCAgIBBAEGAgoDBAEDBgQFCQQEBAMEAgESAQIBAgECAgIHAgEBAQECBwMFAvAEBQQEAwQCAgcCAwUCBAECAwwKAwQCBAEBBAMEBAkIBQcDDwIBBgUIAQEBBgECAQIBAgICCQECAgMECP2tBAgEAwICAgUGDAYBDAEGBwMBAwMBBwcDAQcHAQMBAwQIBAQMBAQEBAkEBAQFAgEBBAQDFQMECgcZAwoCAwMDAwMDAwIGAwIDAgMCCAGcBQQEAQcKHAsHEgQLBAcEBAcECAQQCAQDAgIBBAQDBAUMBQ0EBQQFCAUmBAkEBAQEBAQBBAMBAwEDBAQIBAkEAgIBAgYDBAX+RAQFBAYCAgECAwMFBAEEDQkBDQEEBQUEAQQFBQoFGQEEARQGBQUFCwoJBQQEAwQBAgMDBAcTBQQFBQQFBQQlHggEBAkMAw0CEgUEBQMBFAQECQgWLAUFBAUFBQQFGwQGBAEBAgMDBAQECQMGBQsFBQUGFAEeBQoFBQQBBAEEBRwNBAEEBQMCAQICAwQIAhwM/pABfBj+tAEnGRlKGBhVGBhNGBgCLwEBAQEHAgIEAwQEBAkEBQYDAgkCAQEBAQEBAgUBAgMDCAQFBAkDAwMHAQEBAVMBAgIEBwkJCgEJBwYHAwQDBAMEBwgHFAQNBAQgAwMCAgICAwMICQUGBQUEAQQBBAUcDQQBCAQBBAQECAEDAQMBAwQIAwEDBAMBBgQHCAEEBAEDBAMBAwwDAQMBAwEIBAQEAQQEBAEEDRcFBQQBBAEJBQoFDAQFBAQDBAECBQcMHggECQQUBwgHBAMEAwQDBwYEAwcFBAQJBAQDBAECAgUM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bHRpcGxlJWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb21wZW5zYXRpb24LZ2F0ZXdheS14b3IKY29ubmVjdGlvbhBlbmQtZXZlbnQtY2FuY2VsImludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb25kaXRpb247aW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW5vbi1pbnRlcnJ1cHRpbmctcGFyYWxsZWwtbXVsdGlwbGUVc3RhcnQtZXZlbnQtY29uZGl0aW9uInN0YXJ0LWV2ZW50LW5vbi1pbnRlcnJ1cHRpbmctdGltZXIUc2VxdWVudGlhbC1taS1tYXJrZXIJdXNlci10YXNrDWJ1c2luZXNzLXJ1bGUSc3ViLXByb2Nlc3MtbWFya2VyHXN0YXJ0LWV2ZW50LXBhcmFsbGVsLW11bHRpcGxlEXN0YXJ0LWV2ZW50LWVycm9yH2ludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1zaWduYWweaW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWVycm9yFmVuZC1ldmVudC1jb21wZW5zYXRpb24Uc3VicHJvY2Vzcy1jb2xsYXBzZWQTc3VicHJvY2Vzcy1leHBhbmRlZAR0YXNrD2VuZC1ldmVudC1lcnJvciNpbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtZXNjYWxhdGlvbh5pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtdGltZXIWc3RhcnQtZXZlbnQtZXNjYWxhdGlvbhJzdGFydC1ldmVudC1zaWduYWwSYnVzaW5lc3MtcnVsZS10YXNrBm1hbnVhbAdyZWNlaXZlDWNhbGwtYWN0aXZpdHkRc3RhcnQtZXZlbnQtdGltZXITc3RhcnQtZXZlbnQtbWVzc2FnZRdpbnRlcm1lZGlhdGUtZXZlbnQtbm9uZR1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbGluaxRlbmQtZXZlbnQtZXNjYWxhdGlvbg90ZXh0LWFubm90YXRpb24HYnBtbi1pbw9nYXRld2F5LWNvbXBsZXgSZ2F0ZXdheS1ldmVudGJhc2VkDGdhdGV3YXktbm9uZQpnYXRld2F5LW9yE2VuZC1ldmVudC10ZXJtaW5hdGUQZW5kLWV2ZW50LXNpZ25hbA5lbmQtZXZlbnQtbm9uZRJlbmQtZXZlbnQtbXVsdGlwbGURZW5kLWV2ZW50LW1lc3NhZ2UOZW5kLWV2ZW50LWxpbmsgaW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW1lc3NhZ2UlaW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LWNvbXBlbnNhdGlvbhRzdGFydC1ldmVudC1tdWx0aXBsZQZzY3JpcHQLbWFudWFsLXRhc2sEc2VuZAdzZXJ2aWNlDHJlY2VpdmUtdGFzawR1c2VyEHN0YXJ0LWV2ZW50LW5vbmUjaW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LWVzY2FsYXRpb24haW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW11bHRpcGxlNGludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1ub24taW50ZXJydXB0aW5nLWVzY2FsYXRpb24daW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LWxpbmsmc3RhcnQtZXZlbnQtbm9uLWludGVycnVwdGluZy1jb25kaXRpb24LZGF0YS1vYmplY3QLc2NyaXB0LXRhc2sJc2VuZC10YXNrCmRhdGEtc3RvcmUnc3RhcnQtZXZlbnQtbm9uLWludGVycnVwdGluZy1lc2NhbGF0aW9uIGludGVybWVkaWF0ZS1ldmVudC10aHJvdy1tZXNzYWdlMmludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1ub24taW50ZXJydXB0aW5nLW11bHRpcGxlMGludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1ub24taW50ZXJydXB0aW5nLXNpZ25hbCFpbnRlcm1lZGlhdGUtZXZlbnQtdGhyb3ctbXVsdGlwbGUkc3RhcnQtZXZlbnQtbm9uLWludGVycnVwdGluZy1tZXNzYWdlDWFkLWhvYy1tYXJrZXIMc2VydmljZS10YXNrCXRhc2stbm9uZRNjb21wZW5zYXRpb24tbWFya2VyJXN0YXJ0LWV2ZW50LW5vbi1pbnRlcnJ1cHRpbmctbXVsdGlwbGUfaW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LXNpZ25hbDNpbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbm9uLWludGVycnVwdGluZy1jb25kaXRpb24LcGFydGljaXBhbnQZZXZlbnQtc3VicHJvY2Vzcy1leHBhbmRlZBFsYW5lLWluc2VydC1iZWxvdwpzcGFjZS10b29sEGNvbm5lY3Rpb24tbXVsdGkEbGFuZQpsYXNzby10b29sEWxhbmUtaW5zZXJ0LWFib3ZlEWxhbmUtZGl2aWRlLXRocmVlD2xhbmUtZGl2aWRlLXR3bwpkYXRhLWlucHV0C2RhdGEtb3V0cHV0CWhhbmQtdG9vbAt0cmFuc2FjdGlvbgAAAA==') format('truetype'); +} +/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ +/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ +/* +@media screen and (-webkit-min-device-pixel-ratio:0) { + @font-face { + font-family: 'bpmn'; + src: url('../font/bpmn.svg?43681877#bpmn') format('svg'); + } +} +*/ + + [class^="bpmn-icon-"]:before, [class*=" bpmn-icon-"]:before { + font-family: "bpmn"; + font-style: normal; + font-weight: normal; + speak: none; + + display: inline-block; + text-decoration: inherit; + width: 1em; + /* margin-right: .2em; */ + text-align: center; + /* opacity: .8; */ + + /* For safety - reset parent styles, that can break glyph codes*/ + font-variant: normal; + text-transform: none; + + /* fix buttons height, for twitter bootstrap */ + line-height: 1em; + + /* Animation center compensation - margins should be symmetric */ + /* remove if not needed */ + /* margin-left: .2em; */ + + /* you can be more comfortable with increased icons size */ + /* font-size: 120%; */ + + /* Uncomment for 3D effect */ + /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ +} +.bpmn-icon-screw-wrench:before { content: '\e800'; } /* '' */ +.bpmn-icon-trash:before { content: '\e801'; } /* '' */ +.bpmn-icon-conditional-flow:before { content: '\e802'; } /* '' */ +.bpmn-icon-default-flow:before { content: '\e803'; } /* '' */ +.bpmn-icon-gateway-parallel:before { content: '\e804'; } /* '' */ +.bpmn-icon-intermediate-event-catch-cancel:before { content: '\e805'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-message:before { content: '\e806'; } /* '' */ +.bpmn-icon-start-event-compensation:before { content: '\e807'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-parallel-multiple:before { content: '\e808'; } /* '' */ +.bpmn-icon-loop-marker:before { content: '\e809'; } /* '' */ +.bpmn-icon-parallel-mi-marker:before { content: '\e80a'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-signal:before { content: '\e80b'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-timer:before { content: '\e80c'; } /* '' */ +.bpmn-icon-intermediate-event-catch-parallel-multiple:before { content: '\e80d'; } /* '' */ +.bpmn-icon-intermediate-event-catch-compensation:before { content: '\e80e'; } /* '' */ +.bpmn-icon-gateway-xor:before { content: '\e80f'; } /* '' */ +.bpmn-icon-connection:before { content: '\e810'; } /* '' */ +.bpmn-icon-end-event-cancel:before { content: '\e811'; } /* '' */ +.bpmn-icon-intermediate-event-catch-condition:before { content: '\e812'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-parallel-multiple:before { content: '\e813'; } /* '' */ +.bpmn-icon-start-event-condition:before { content: '\e814'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-timer:before { content: '\e815'; } /* '' */ +.bpmn-icon-sequential-mi-marker:before { content: '\e816'; } /* '' */ +.bpmn-icon-user-task:before { content: '\e817'; } /* '' */ +.bpmn-icon-business-rule:before { content: '\e818'; } /* '' */ +.bpmn-icon-sub-process-marker:before { content: '\e819'; } /* '' */ +.bpmn-icon-start-event-parallel-multiple:before { content: '\e81a'; } /* '' */ +.bpmn-icon-start-event-error:before { content: '\e81b'; } /* '' */ +.bpmn-icon-intermediate-event-catch-signal:before { content: '\e81c'; } /* '' */ +.bpmn-icon-intermediate-event-catch-error:before { content: '\e81d'; } /* '' */ +.bpmn-icon-end-event-compensation:before { content: '\e81e'; } /* '' */ +.bpmn-icon-subprocess-collapsed:before { content: '\e81f'; } /* '' */ +.bpmn-icon-subprocess-expanded:before { content: '\e820'; } /* '' */ +.bpmn-icon-task:before { content: '\e821'; } /* '' */ +.bpmn-icon-end-event-error:before { content: '\e822'; } /* '' */ +.bpmn-icon-intermediate-event-catch-escalation:before { content: '\e823'; } /* '' */ +.bpmn-icon-intermediate-event-catch-timer:before { content: '\e824'; } /* '' */ +.bpmn-icon-start-event-escalation:before { content: '\e825'; } /* '' */ +.bpmn-icon-start-event-signal:before { content: '\e826'; } /* '' */ +.bpmn-icon-business-rule-task:before { content: '\e827'; } /* '' */ +.bpmn-icon-manual:before { content: '\e828'; } /* '' */ +.bpmn-icon-receive:before { content: '\e829'; } /* '' */ +.bpmn-icon-call-activity:before { content: '\e82a'; } /* '' */ +.bpmn-icon-start-event-timer:before { content: '\e82b'; } /* '' */ +.bpmn-icon-start-event-message:before { content: '\e82c'; } /* '' */ +.bpmn-icon-intermediate-event-none:before { content: '\e82d'; } /* '' */ +.bpmn-icon-intermediate-event-catch-link:before { content: '\e82e'; } /* '' */ +.bpmn-icon-end-event-escalation:before { content: '\e82f'; } /* '' */ +.bpmn-icon-text-annotation:before { content: '\e830'; } /* '' */ +.bpmn-icon-bpmn-io:before { content: '\e831'; } /* '' */ +.bpmn-icon-gateway-complex:before { content: '\e832'; } /* '' */ +.bpmn-icon-gateway-eventbased:before { content: '\e833'; } /* '' */ +.bpmn-icon-gateway-none:before { content: '\e834'; } /* '' */ +.bpmn-icon-gateway-or:before { content: '\e835'; } /* '' */ +.bpmn-icon-end-event-terminate:before { content: '\e836'; } /* '' */ +.bpmn-icon-end-event-signal:before { content: '\e837'; } /* '' */ +.bpmn-icon-end-event-none:before { content: '\e838'; } /* '' */ +.bpmn-icon-end-event-multiple:before { content: '\e839'; } /* '' */ +.bpmn-icon-end-event-message:before { content: '\e83a'; } /* '' */ +.bpmn-icon-end-event-link:before { content: '\e83b'; } /* '' */ +.bpmn-icon-intermediate-event-catch-message:before { content: '\e83c'; } /* '' */ +.bpmn-icon-intermediate-event-throw-compensation:before { content: '\e83d'; } /* '' */ +.bpmn-icon-start-event-multiple:before { content: '\e83e'; } /* '' */ +.bpmn-icon-script:before { content: '\e83f'; } /* '' */ +.bpmn-icon-manual-task:before { content: '\e840'; } /* '' */ +.bpmn-icon-send:before { content: '\e841'; } /* '' */ +.bpmn-icon-service:before { content: '\e842'; } /* '' */ +.bpmn-icon-receive-task:before { content: '\e843'; } /* '' */ +.bpmn-icon-user:before { content: '\e844'; } /* '' */ +.bpmn-icon-start-event-none:before { content: '\e845'; } /* '' */ +.bpmn-icon-intermediate-event-throw-escalation:before { content: '\e846'; } /* '' */ +.bpmn-icon-intermediate-event-catch-multiple:before { content: '\e847'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-escalation:before { content: '\e848'; } /* '' */ +.bpmn-icon-intermediate-event-throw-link:before { content: '\e849'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-condition:before { content: '\e84a'; } /* '' */ +.bpmn-icon-data-object:before { content: '\e84b'; } /* '' */ +.bpmn-icon-script-task:before { content: '\e84c'; } /* '' */ +.bpmn-icon-send-task:before { content: '\e84d'; } /* '' */ +.bpmn-icon-data-store:before { content: '\e84e'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-escalation:before { content: '\e84f'; } /* '' */ +.bpmn-icon-intermediate-event-throw-message:before { content: '\e850'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-multiple:before { content: '\e851'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-signal:before { content: '\e852'; } /* '' */ +.bpmn-icon-intermediate-event-throw-multiple:before { content: '\e853'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-message:before { content: '\e854'; } /* '' */ +.bpmn-icon-ad-hoc-marker:before { content: '\e855'; } /* '' */ +.bpmn-icon-service-task:before { content: '\e856'; } /* '' */ +.bpmn-icon-task-none:before { content: '\e857'; } /* '' */ +.bpmn-icon-compensation-marker:before { content: '\e858'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-multiple:before { content: '\e859'; } /* '' */ +.bpmn-icon-intermediate-event-throw-signal:before { content: '\e85a'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-condition:before { content: '\e85b'; } /* '' */ +.bpmn-icon-participant:before { content: '\e85c'; } /* '' */ +.bpmn-icon-event-subprocess-expanded:before { content: '\e85d'; } /* '' */ +.bpmn-icon-lane-insert-below:before { content: '\e85e'; } /* '' */ +.bpmn-icon-space-tool:before { content: '\e85f'; } /* '' */ +.bpmn-icon-connection-multi:before { content: '\e860'; } /* '' */ +.bpmn-icon-lane:before { content: '\e861'; } /* '' */ +.bpmn-icon-lasso-tool:before { content: '\e862'; } /* '' */ +.bpmn-icon-lane-insert-above:before { content: '\e863'; } /* '' */ +.bpmn-icon-lane-divide-three:before { content: '\e864'; } /* '' */ +.bpmn-icon-lane-divide-two:before { content: '\e865'; } /* '' */ +.bpmn-icon-data-input:before { content: '\e866'; } /* '' */ +.bpmn-icon-data-output:before { content: '\e867'; } /* '' */ +.bpmn-icon-hand-tool:before { content: '\e868'; } /* '' */ +.bpmn-icon-transaction:before { content: '\e8c4'; } /* '' */ \ No newline at end of file diff --git a/src/main/resources/static/vendor/bpmn-font/css/bpmn.css b/src/main/resources/static/vendor/bpmn-font/css/bpmn.css new file mode 100644 index 0000000..3ce3e23 --- /dev/null +++ b/src/main/resources/static/vendor/bpmn-font/css/bpmn.css @@ -0,0 +1,162 @@ +@font-face { + font-family: 'bpmn'; + src: url('../font/bpmn.eot?70672887'); + src: url('../font/bpmn.eot?70672887#iefix') format('embedded-opentype'), + url('../font/bpmn.woff?70672887') format('woff'), + url('../font/bpmn.ttf?70672887') format('truetype'), + url('../font/bpmn.svg?70672887#bpmn') format('svg'); + font-weight: normal; + font-style: normal; +} +/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ +/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ +/* +@media screen and (-webkit-min-device-pixel-ratio:0) { + @font-face { + font-family: 'bpmn'; + src: url('../font/bpmn.svg?70672887#bpmn') format('svg'); + } +} +*/ + + [class^="bpmn-icon-"]:before, [class*=" bpmn-icon-"]:before { + font-family: "bpmn"; + font-style: normal; + font-weight: normal; + speak: none; + + display: inline-block; + text-decoration: inherit; + width: 1em; + /* margin-right: .2em; */ + text-align: center; + /* opacity: .8; */ + + /* For safety - reset parent styles, that can break glyph codes*/ + font-variant: normal; + text-transform: none; + + /* fix buttons height, for twitter bootstrap */ + line-height: 1em; + + /* Animation center compensation - margins should be symmetric */ + /* remove if not needed */ + /* margin-left: .2em; */ + + /* you can be more comfortable with increased icons size */ + /* font-size: 120%; */ + + /* Font smoothing. That was taken from TWBS */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + /* Uncomment for 3D effect */ + /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ +} + +.bpmn-icon-screw-wrench:before { content: '\e800'; } /* '' */ +.bpmn-icon-trash:before { content: '\e801'; } /* '' */ +.bpmn-icon-conditional-flow:before { content: '\e802'; } /* '' */ +.bpmn-icon-default-flow:before { content: '\e803'; } /* '' */ +.bpmn-icon-gateway-parallel:before { content: '\e804'; } /* '' */ +.bpmn-icon-intermediate-event-catch-cancel:before { content: '\e805'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-message:before { content: '\e806'; } /* '' */ +.bpmn-icon-start-event-compensation:before { content: '\e807'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-parallel-multiple:before { content: '\e808'; } /* '' */ +.bpmn-icon-loop-marker:before { content: '\e809'; } /* '' */ +.bpmn-icon-parallel-mi-marker:before { content: '\e80a'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-signal:before { content: '\e80b'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-timer:before { content: '\e80c'; } /* '' */ +.bpmn-icon-intermediate-event-catch-parallel-multiple:before { content: '\e80d'; } /* '' */ +.bpmn-icon-intermediate-event-catch-compensation:before { content: '\e80e'; } /* '' */ +.bpmn-icon-gateway-xor:before { content: '\e80f'; } /* '' */ +.bpmn-icon-connection:before { content: '\e810'; } /* '' */ +.bpmn-icon-end-event-cancel:before { content: '\e811'; } /* '' */ +.bpmn-icon-intermediate-event-catch-condition:before { content: '\e812'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-parallel-multiple:before { content: '\e813'; } /* '' */ +.bpmn-icon-start-event-condition:before { content: '\e814'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-timer:before { content: '\e815'; } /* '' */ +.bpmn-icon-sequential-mi-marker:before { content: '\e816'; } /* '' */ +.bpmn-icon-user-task:before { content: '\e817'; } /* '' */ +.bpmn-icon-business-rule:before { content: '\e818'; } /* '' */ +.bpmn-icon-sub-process-marker:before { content: '\e819'; } /* '' */ +.bpmn-icon-start-event-parallel-multiple:before { content: '\e81a'; } /* '' */ +.bpmn-icon-start-event-error:before { content: '\e81b'; } /* '' */ +.bpmn-icon-intermediate-event-catch-signal:before { content: '\e81c'; } /* '' */ +.bpmn-icon-intermediate-event-catch-error:before { content: '\e81d'; } /* '' */ +.bpmn-icon-end-event-compensation:before { content: '\e81e'; } /* '' */ +.bpmn-icon-subprocess-collapsed:before { content: '\e81f'; } /* '' */ +.bpmn-icon-subprocess-expanded:before { content: '\e820'; } /* '' */ +.bpmn-icon-task:before { content: '\e821'; } /* '' */ +.bpmn-icon-end-event-error:before { content: '\e822'; } /* '' */ +.bpmn-icon-intermediate-event-catch-escalation:before { content: '\e823'; } /* '' */ +.bpmn-icon-intermediate-event-catch-timer:before { content: '\e824'; } /* '' */ +.bpmn-icon-start-event-escalation:before { content: '\e825'; } /* '' */ +.bpmn-icon-start-event-signal:before { content: '\e826'; } /* '' */ +.bpmn-icon-business-rule-task:before { content: '\e827'; } /* '' */ +.bpmn-icon-manual:before { content: '\e828'; } /* '' */ +.bpmn-icon-receive:before { content: '\e829'; } /* '' */ +.bpmn-icon-call-activity:before { content: '\e82a'; } /* '' */ +.bpmn-icon-start-event-timer:before { content: '\e82b'; } /* '' */ +.bpmn-icon-start-event-message:before { content: '\e82c'; } /* '' */ +.bpmn-icon-intermediate-event-none:before { content: '\e82d'; } /* '' */ +.bpmn-icon-intermediate-event-catch-link:before { content: '\e82e'; } /* '' */ +.bpmn-icon-end-event-escalation:before { content: '\e82f'; } /* '' */ +.bpmn-icon-text-annotation:before { content: '\e830'; } /* '' */ +.bpmn-icon-bpmn-io:before { content: '\e831'; } /* '' */ +.bpmn-icon-gateway-complex:before { content: '\e832'; } /* '' */ +.bpmn-icon-gateway-eventbased:before { content: '\e833'; } /* '' */ +.bpmn-icon-gateway-none:before { content: '\e834'; } /* '' */ +.bpmn-icon-gateway-or:before { content: '\e835'; } /* '' */ +.bpmn-icon-end-event-terminate:before { content: '\e836'; } /* '' */ +.bpmn-icon-end-event-signal:before { content: '\e837'; } /* '' */ +.bpmn-icon-end-event-none:before { content: '\e838'; } /* '' */ +.bpmn-icon-end-event-multiple:before { content: '\e839'; } /* '' */ +.bpmn-icon-end-event-message:before { content: '\e83a'; } /* '' */ +.bpmn-icon-end-event-link:before { content: '\e83b'; } /* '' */ +.bpmn-icon-intermediate-event-catch-message:before { content: '\e83c'; } /* '' */ +.bpmn-icon-intermediate-event-throw-compensation:before { content: '\e83d'; } /* '' */ +.bpmn-icon-start-event-multiple:before { content: '\e83e'; } /* '' */ +.bpmn-icon-script:before { content: '\e83f'; } /* '' */ +.bpmn-icon-manual-task:before { content: '\e840'; } /* '' */ +.bpmn-icon-send:before { content: '\e841'; } /* '' */ +.bpmn-icon-service:before { content: '\e842'; } /* '' */ +.bpmn-icon-receive-task:before { content: '\e843'; } /* '' */ +.bpmn-icon-user:before { content: '\e844'; } /* '' */ +.bpmn-icon-start-event-none:before { content: '\e845'; } /* '' */ +.bpmn-icon-intermediate-event-throw-escalation:before { content: '\e846'; } /* '' */ +.bpmn-icon-intermediate-event-catch-multiple:before { content: '\e847'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-escalation:before { content: '\e848'; } /* '' */ +.bpmn-icon-intermediate-event-throw-link:before { content: '\e849'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-condition:before { content: '\e84a'; } /* '' */ +.bpmn-icon-data-object:before { content: '\e84b'; } /* '' */ +.bpmn-icon-script-task:before { content: '\e84c'; } /* '' */ +.bpmn-icon-send-task:before { content: '\e84d'; } /* '' */ +.bpmn-icon-data-store:before { content: '\e84e'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-escalation:before { content: '\e84f'; } /* '' */ +.bpmn-icon-intermediate-event-throw-message:before { content: '\e850'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-multiple:before { content: '\e851'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-signal:before { content: '\e852'; } /* '' */ +.bpmn-icon-intermediate-event-throw-multiple:before { content: '\e853'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-message:before { content: '\e854'; } /* '' */ +.bpmn-icon-ad-hoc-marker:before { content: '\e855'; } /* '' */ +.bpmn-icon-service-task:before { content: '\e856'; } /* '' */ +.bpmn-icon-task-none:before { content: '\e857'; } /* '' */ +.bpmn-icon-compensation-marker:before { content: '\e858'; } /* '' */ +.bpmn-icon-start-event-non-interrupting-multiple:before { content: '\e859'; } /* '' */ +.bpmn-icon-intermediate-event-throw-signal:before { content: '\e85a'; } /* '' */ +.bpmn-icon-intermediate-event-catch-non-interrupting-condition:before { content: '\e85b'; } /* '' */ +.bpmn-icon-participant:before { content: '\e85c'; } /* '' */ +.bpmn-icon-event-subprocess-expanded:before { content: '\e85d'; } /* '' */ +.bpmn-icon-lane-insert-below:before { content: '\e85e'; } /* '' */ +.bpmn-icon-space-tool:before { content: '\e85f'; } /* '' */ +.bpmn-icon-connection-multi:before { content: '\e860'; } /* '' */ +.bpmn-icon-lane:before { content: '\e861'; } /* '' */ +.bpmn-icon-lasso-tool:before { content: '\e862'; } /* '' */ +.bpmn-icon-lane-insert-above:before { content: '\e863'; } /* '' */ +.bpmn-icon-lane-divide-three:before { content: '\e864'; } /* '' */ +.bpmn-icon-lane-divide-two:before { content: '\e865'; } /* '' */ +.bpmn-icon-data-input:before { content: '\e866'; } /* '' */ +.bpmn-icon-data-output:before { content: '\e867'; } /* '' */ +.bpmn-icon-hand-tool:before { content: '\e868'; } /* '' */ +.bpmn-icon-transaction:before { content: '\e8c4'; } /* '' */ \ No newline at end of file diff --git a/src/main/resources/static/vendor/bpmn-font/font/bpmn.eot b/src/main/resources/static/vendor/bpmn-font/font/bpmn.eot new file mode 100644 index 0000000000000000000000000000000000000000..f7900ea2d19d7792f2d79bc75ecb50684cf09322 GIT binary patch literal 41724 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 + + +camunda Services GmbH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/vendor/bpmn-font/font/bpmn.ttf b/src/main/resources/static/vendor/bpmn-font/font/bpmn.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aa4c957352bda73f56e5fd247b2752f3290240b4 GIT binary patch literal 41572 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/vendor/diagram-js.css b/src/main/resources/static/vendor/diagram-js.css new file mode 100644 index 0000000..7c6f320 --- /dev/null +++ b/src/main/resources/static/vendor/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/test/java/com/fs/camunda/bpm/example/ExampleApplicationTests.java b/src/test/java/com/fs/camunda/bpm/example/ExampleApplicationTests.java new file mode 100644 index 0000000..e82797b --- /dev/null +++ b/src/test/java/com/fs/camunda/bpm/example/ExampleApplicationTests.java @@ -0,0 +1,13 @@ +package com.fs.camunda.bpm.example; + +/*import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ExampleApplicationTests { + + @Test + void contextLoads() { + } + +}*/