(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|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 keyBy(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 keyBy(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 canvas = this._canvas, eventBus = this._eventBus; var self = this; /** * Select the root element once it is added to the canvas */ eventBus.on('root.added', function(e) { var element = e.element; if (isImplicitRoot(element)) { return; } self.update(element); }); eventBus.on('selection.changed', function(e) { var newElement = e.newSelection[0]; var rootElement = canvas.getRootElement(); if (isImplicitRoot(rootElement)) { return; } 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 = domQueryAll('.bpp-properties-tab', panelNode), allTabLinkNodes = domQueryAll('.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 {Boolean} */ 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 inputNode = event.delegateTarget, entryNode = domClosest(inputNode, '[data-entry]'), entryId, entry; // change from outside a [data-entry] element, simply ignore if (!entryNode) { return; } entryId = domAttr(entryNode, 'data-entry'); entry = self.getEntry(entryId); var values = getFormControlValues(entryNode); 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 = domAttr(inputNode, 'data-on-change'); if (onChangeAction) { var isEntryDirty = self.executeAction(entry, entryNode, onChangeAction, event); if (!isEntryDirty) { return self.update(self._current.element); } } } self.applyChanges(entry, values, entryNode); self.updateState(entry, entryNode); }; // 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); // handle key events domDelegate.bind(container, 'select', 'keydown', function(e) { // DEL if (e.keyCode === 46) { e.stopPropagation(); e.preventDefault(); } }); domDelegate.bind(container, '[data-action]', 'click', function onClick(event) { // triggers on all inputs var inputNode = event.delegateTarget, 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 = domQueryAll('[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 = domQueryAll('[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.textContent = 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/flattenDeep'), keyBy = require('lodash/keyBy'), map = require('lodash/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('
' + '' + '' + escapeHTML(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); } function isImplicitRoot(element) { return element.id === '__implicitroot'; } },{"./Utils":4,"bpmn-js/lib/util/ModelUtil":141,"lodash/debounce":516,"lodash/filter":518,"lodash/flattenDeep":521,"lodash/forEach":522,"lodash/get":523,"lodash/isArray":527,"lodash/isEmpty":531,"lodash/keyBy":538,"lodash/keys":539,"lodash/map":540,"lodash/xor":554,"min-dom":556,"scroll-tabs":565,"selection-update":566}],4:[function(require,module,exports){ 'use strict'; var domQuery = require('min-dom').query, domClear = require('min-dom').clear, is = require('bpmn-js/lib/util/ModelUtil').is, forEach = require('lodash/forEach'), domify = require('min-dom').domify, Ids = require('ids').default; 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; var HTML_ESCAPE_MAP = { '&': '&', '<': '<', '>': '>', '"': '"', '\'': ''' }; 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 * @param {Function} translate * * @return {String} error message */ function isIdValid(bo, idValue, translate) { var assigned = bo.$model.ids.assigned(idValue); var idExists = assigned && assigned !== bo; if (!idValue || idExists) { return translate('Element must have an unique id.'); } return validateId(idValue, translate); } module.exports.isIdValid = isIdValid; function validateId(idValue, translate) { idValue = stripPlaceholders(idValue); if (containsSpace(idValue)) { return translate('Id must not contain spaces.'); } if (!ID_REGEX.test(idValue)) { if (QNAME_REGEX.test(idValue)) { return translate('Id must not contain prefix.'); } return translate('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; function escapeHTML(str) { str = '' + str; return str && str.replace(/[&<>"']/g, function(match) { return HTML_ESCAPE_MAP[match]; }); } module.exports.escapeHTML = escapeHTML; },{"bpmn-js/lib/util/ModelUtil":141,"ids":346,"lodash/forEach":522,"min-dom":556}],5:[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; // 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; }; // helpers ////////////// function ensureNotNull(prop, name) { if (!prop) { throw new Error(name + ' required'); } return prop; } },{"../helper/ElementHelper":11}],6:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/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":11,"lodash/forEach":522}],7:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/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/forEach":522}],8:[function(require,module,exports){ 'use strict'; var reduce = require('lodash/transform'), is = require('bpmn-js/lib/util/ModelUtil').is, keys = require('lodash/keys'), forEach = require('lodash/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":141,"lodash/forEach":522,"lodash/keys":539,"lodash/transform":551}],9:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/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/forEach":522}],10:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/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":5,"./CreateBusinessObjectListHandler":6,"./MultiCommandHandler":7,"./UpdateBusinessObjectHandler":8,"./UpdateBusinessObjectListHandler":9,"lodash/forEach":522}],11:[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; }; },{}],12:[function(require,module,exports){ module.exports = { __depends__: [ require('./cmd'), require('diagram-js/lib/i18n/translate').default ], __init__: [ 'propertiesPanel' ], propertiesPanel: [ 'type', require('./PropertiesPanel') ] }; },{"./PropertiesPanel":3,"./cmd":10,"diagram-js/lib/i18n/translate":337}],13:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BaseModeler; var _inherits = _interopRequireDefault(require("inherits")); var _ids = _interopRequireDefault(require("ids")); var _BaseViewer = _interopRequireDefault(require("./BaseViewer")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A base modeler for BPMN 2.0 diagrams. * * Have a look at {@link Modeler} for a bundle that includes actual features. * * @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 BaseModeler(options) { _BaseViewer.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.elementsById); } }, this); this.on('diagram.destroy', function () { this.get('moddle').ids.clear(); }, this); } (0, _inherits.default)(BaseModeler, _BaseViewer.default); /** * Create a moddle instance, attaching ids to it. * * @param {Object} options */ BaseModeler.prototype._createModdle = function (options) { var moddle = _BaseViewer.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 _ids.default([32, 36, 1]); return moddle; }; /** * Collect ids processed during parsing of the * definitions object. * * @param {ModdleElement} definitions * @param {Context} context */ BaseModeler.prototype._collectIds = function (definitions, elementsById) { var moddle = definitions.$model, ids = moddle.ids, id; // remove references from previous import ids.clear(); for (id in elementsById) { ids.claim(id, elementsById[id]); } }; },{"./BaseViewer":14,"ids":346,"inherits":347}],14:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BaseViewer; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _tinySvg = require("tiny-svg"); var _diagramJs = _interopRequireDefault(require("diagram-js")); var _bpmnModdle = _interopRequireDefault(require("bpmn-moddle")); var _inherits = _interopRequireDefault(require("inherits")); var _Importer = require("./import/Importer"); var _CompatibilityUtil = require("./util/CompatibilityUtil"); var _PoweredByUtil = require("./util/PoweredByUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * The code in the area * must not be changed. * * @see http://bpmn.io/license for more information. */ /** * A base viewer for BPMN 2.0 diagrams. * * Have a look at {@link Viewer}, {@link NavigatedViewer} or {@link Modeler} for * bundles that include actual features. * * @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 BaseViewer(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, _inherits.default)(BaseViewer, _diagramJs.default); /** * The importXML result. * * @typedef {Object} ImportXMLResult * * @property {Array} warnings */ /** * The importXML error. * * @typedef {Error} ImportXMLError * * @property {Array} warnings */ /** * 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 {ModdleElement|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered) * * Returns {Promise} */ BaseViewer.prototype.importXML = (0, _CompatibilityUtil.wrapForCompatibility)(function importXML(xml, bpmnDiagram) { var self = this; function ParseCompleteEvent(data) { var event = self.get('eventBus').createEvent(data); // TODO(nikku): remove with future bpmn-js version Object.defineProperty(event, 'context', { enumerable: true, get: function () { console.warn(new Error('import.parse.complete is deprecated ' + 'and will be removed in future library versions')); return { warnings: data.warnings, references: data.references, elementsById: data.elementsById }; } }); return event; } return new Promise(function (resolve, reject) { // hook in pre-parse listeners + // allow xml manipulation xml = self._emit('import.parse.start', { xml: xml }) || xml; self._moddle.fromXML(xml, 'bpmn:Definitions').then(function (result) { var definitions = result.rootElement; var references = result.references; var parseWarnings = result.warnings; var elementsById = result.elementsById; // hook in post parse listeners + // allow definitions manipulation definitions = self._emit('import.parse.complete', ParseCompleteEvent({ error: null, definitions: definitions, elementsById: elementsById, references: references, warnings: parseWarnings })) || definitions; self.importDefinitions(definitions, bpmnDiagram).then(function (result) { var allWarnings = [].concat(parseWarnings, result.warnings || []); self._emit('import.done', { error: null, warnings: allWarnings }); return resolve({ warnings: allWarnings }); }).catch(function (err) { var allWarnings = [].concat(parseWarnings, err.warnings || []); self._emit('import.done', { error: err, warnings: allWarnings }); return reject(addWarningsToError(err, allWarnings)); }); }).catch(function (err) { self._emit('import.parse.complete', { error: err }); err = checkValidationError(err); self._emit('import.done', { error: err, warnings: err.warnings }); return reject(err); }); }); }); /** * The importDefinitions result. * * @typedef {Object} ImportDefinitionsResult * * @property {Array} warnings */ /** * The importDefinitions error. * * @typedef {Error} ImportDefinitionsError * * @property {Array} warnings */ /** * Import parsed definitions 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.render.start (graphical import start) * * import.render.complete (graphical import finished) * * You can use these events to hook into the life-cycle. * * @param {ModdleElement} definitions parsed BPMN 2.0 definitions * @param {ModdleElement|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered) * * Returns {Promise} */ BaseViewer.prototype.importDefinitions = (0, _CompatibilityUtil.wrapForCompatibility)(function importDefinitions(definitions, bpmnDiagram) { var self = this; return new Promise(function (resolve, reject) { self._setDefinitions(definitions); self.open(bpmnDiagram).then(function (result) { var warnings = result.warnings; return resolve({ warnings: warnings }); }).catch(function (err) { return reject(err); }); }); }); /** * The open result. * * @typedef {Object} OpenResult * * @property {Array} warnings */ /** * The open error. * * @typedef {Error} OpenError * * @property {Array} warnings */ /** * Open diagram of previously imported XML. * * Once finished the viewer reports back the result to the * provided callback function with (err, warnings). * * ## Life-Cycle Events * * During switch the viewer will fire life-cycle events: * * * import.render.start (graphical import start) * * import.render.complete (graphical import finished) * * You can use these events to hook into the life-cycle. * * @param {string|ModdleElement} [bpmnDiagramOrId] id or the diagram to open * * Returns {Promise} */ BaseViewer.prototype.open = (0, _CompatibilityUtil.wrapForCompatibility)(function open(bpmnDiagramOrId) { var definitions = this._definitions; var bpmnDiagram = bpmnDiagramOrId; var self = this; return new Promise(function (resolve, reject) { if (!definitions) { var err1 = new Error('no XML imported'); return reject(addWarningsToError(err1, [])); } if (typeof bpmnDiagramOrId === 'string') { bpmnDiagram = findBPMNDiagram(definitions, bpmnDiagramOrId); if (!bpmnDiagram) { var err2 = new Error('BPMNDiagram <' + bpmnDiagramOrId + '> not found'); return reject(addWarningsToError(err2, [])); } } // clear existing rendered diagram // catch synchronous exceptions during #clear() try { self.clear(); } catch (error) { return reject(addWarningsToError(error, [])); } // perform graphical import (0, _Importer.importBpmnDiagram)(self, definitions, bpmnDiagram).then(function (result) { var warnings = result.warnings; return resolve({ warnings: warnings }); }).catch(function (err) { return reject(err); }); }); }); /** * The saveXML result. * * @typedef {Object} SaveXMLResult * * @property {string} xml */ /** * 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 formatted XML * @param {boolean} [options.preamble=true] output preamble * * Returns {Promise} */ BaseViewer.prototype.saveXML = (0, _CompatibilityUtil.wrapForCompatibility)(function saveXML(options) { options = options || {}; var self = this; var definitions = this._definitions; return new Promise(function (resolve, reject) { if (!definitions) { var err = new Error('no definitions loaded'); return reject(err); } // allow to fiddle around with definitions definitions = self._emit('saveXML.start', { definitions: definitions }) || definitions; self._moddle.toXML(definitions, options).then(function (result) { var xml = result.xml; try { xml = self._emit('saveXML.serialized', { error: null, xml: xml }) || xml; self._emit('saveXML.done', { error: null, xml: xml }); } catch (e) { console.error('error in saveXML life-cycle listener', e); } return resolve({ xml: xml }); }).catch(function (err) { return reject(err); }); }); }); /** * The saveSVG result. * * @typedef {Object} SaveSVGResult * * @property {string} svg */ /** * 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] * * Returns {Promise} */ BaseViewer.prototype.saveSVG = (0, _CompatibilityUtil.wrapForCompatibility)(function saveSVG(options) { options = options || {}; var self = this; return new Promise(function (resolve, reject) { self._emit('saveSVG.start'); var svg, err; try { var canvas = self.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; } self._emit('saveSVG.done', { error: err, svg: svg }); if (!err) { return resolve({ svg: svg }); } return reject(err); }); }); /** * 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 BaseViewer#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 BaseViewer#invoke */ BaseViewer.prototype._setDefinitions = function (definitions) { this._definitions = definitions; }; BaseViewer.prototype.getModules = function () { return this._modules; }; /** * Remove all drawn elements from the viewer. * * After calling this method the viewer can still * be reused for opening another diagram. * * @method BaseViewer#clear */ BaseViewer.prototype.clear = function () { if (!this.getDefinitions()) { // no diagram to clear return; } // remove businessObject#di binding // // this is necessary, as we establish the bindings // in the BpmnTreeWalker (and assume none are given // on reimport) this.get('elementRegistry').forEach(function (element) { var bo = element.businessObject; if (bo && bo.di) { delete bo.di; } }); // remove drawn elements _diagramJs.default.prototype.clear.call(this); }; /** * Destroy the viewer instance and remove all its * remainders from the document tree. */ BaseViewer.prototype.destroy = function () { // diagram destroy _diagramJs.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] */ BaseViewer.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 */ BaseViewer.prototype.off = function (event, callback) { this.get('eventBus').off(event, callback); }; BaseViewer.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(); }; BaseViewer.prototype.getDefinitions = function () { return this._definitions; }; BaseViewer.prototype.detach = function () { var container = this._container, parentNode = container.parentNode; if (!parentNode) { return; } this._emit('detach', {}); parentNode.removeChild(container); }; BaseViewer.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 _diagramJs.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) */ BaseViewer.prototype._emit = function (type, event) { return this.get('eventBus').fire(type, event); }; BaseViewer.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; }; BaseViewer.prototype._createModdle = function (options) { var moddleOptions = (0, _minDash.assign)({}, this._moddleExtensions, options.moddleExtensions); return new _bpmnModdle.default(moddleOptions); }; BaseViewer.prototype._modules = []; // helpers /////////////// function addWarningsToError(err, warningsAry) { err.warnings = warningsAry; return err; } 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; } 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' : ''); } /** * Find BPMNDiagram in definitions by ID * * @param {ModdleElement} definitions * @param {string} diagramId * * @return {ModdleElement|null} */ function findBPMNDiagram(definitions, diagramId) { if (!diagramId) { return null; } return (0, _minDash.find)(definitions.diagrams, function (element) { return element.id === diagramId; }) || null; } /* */ /** * 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(); }); } /* */ },{"./import/Importer":135,"./util/CompatibilityUtil":138,"./util/PoweredByUtil":142,"bpmn-moddle":330,"diagram-js":143,"inherits":347,"min-dash":555,"min-dom":556,"tiny-svg":567}],15:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Modeler; var _inherits = _interopRequireDefault(require("inherits")); var _BaseModeler = _interopRequireDefault(require("./BaseModeler")); var _Viewer = _interopRequireDefault(require("./Viewer")); var _NavigatedViewer = _interopRequireDefault(require("./NavigatedViewer")); var _keyboardMove = _interopRequireDefault(require("diagram-js/lib/navigation/keyboard-move")); var _movecanvas = _interopRequireDefault(require("diagram-js/lib/navigation/movecanvas")); var _touch = _interopRequireDefault(require("diagram-js/lib/navigation/touch")); var _zoomscroll = _interopRequireDefault(require("diagram-js/lib/navigation/zoomscroll")); var _alignElements = _interopRequireDefault(require("diagram-js/lib/features/align-elements")); var _autoPlace = _interopRequireDefault(require("./features/auto-place")); var _autoResize = _interopRequireDefault(require("./features/auto-resize")); var _autoScroll = _interopRequireDefault(require("diagram-js/lib/features/auto-scroll")); var _bendpoints = _interopRequireDefault(require("diagram-js/lib/features/bendpoints")); var _connect = _interopRequireDefault(require("diagram-js/lib/features/connect")); var _connectionPreview = _interopRequireDefault(require("diagram-js/lib/features/connection-preview")); var _contextPad = _interopRequireDefault(require("./features/context-pad")); var _copyPaste = _interopRequireDefault(require("./features/copy-paste")); var _create = _interopRequireDefault(require("diagram-js/lib/features/create")); var _distributeElements = _interopRequireDefault(require("./features/distribute-elements")); var _editorActions = _interopRequireDefault(require("./features/editor-actions")); var _gridSnapping = _interopRequireDefault(require("./features/grid-snapping")); var _interactionEvents = _interopRequireDefault(require("./features/interaction-events")); var _keyboard = _interopRequireDefault(require("./features/keyboard")); var _keyboardMoveSelection = _interopRequireDefault(require("diagram-js/lib/features/keyboard-move-selection")); var _labelEditing = _interopRequireDefault(require("./features/label-editing")); var _modeling = _interopRequireDefault(require("./features/modeling")); var _move = _interopRequireDefault(require("diagram-js/lib/features/move")); var _palette = _interopRequireDefault(require("./features/palette")); var _replacePreview = _interopRequireDefault(require("./features/replace-preview")); var _resize = _interopRequireDefault(require("diagram-js/lib/features/resize")); var _snapping = _interopRequireDefault(require("./features/snapping")); var _search = _interopRequireDefault(require("./features/search")); var _CompatibilityUtil = require("./util/CompatibilityUtil"); 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) { _BaseModeler.default.call(this, options); } (0, _inherits.default)(Modeler, _BaseModeler.default); Modeler.Viewer = _Viewer.default; Modeler.NavigatedViewer = _NavigatedViewer.default; /** * The createDiagram result. * * @typedef {Object} CreateDiagramResult * * @property {Array} warnings */ /** * The createDiagram error. * * @typedef {Error} CreateDiagramError * * @property {Array} warnings */ /** * Create a new diagram to start modeling. * * Returns {Promise} */ Modeler.prototype.createDiagram = (0, _CompatibilityUtil.wrapForCompatibility)(function createDiagram() { return this.importXML(initialDiagram); }); Modeler.prototype._interactionModules = [// non-modeling components _keyboardMove.default, _movecanvas.default, _touch.default, _zoomscroll.default]; Modeler.prototype._modelingModules = [// modeling components _alignElements.default, _autoPlace.default, _autoScroll.default, _autoResize.default, _bendpoints.default, _connect.default, _connectionPreview.default, _contextPad.default, _copyPaste.default, _create.default, _distributeElements.default, _editorActions.default, _gridSnapping.default, _interactionEvents.default, _keyboard.default, _keyboardMoveSelection.default, _labelEditing.default, _modeling.default, _move.default, _palette.default, _replacePreview.default, _resize.default, _snapping.default, _search.default]; // modules the modeler is composed of // // - viewer modules // - interaction modules // - modeling modules Modeler.prototype._modules = [].concat(_Viewer.default.prototype._modules, Modeler.prototype._interactionModules, Modeler.prototype._modelingModules); },{"./BaseModeler":13,"./NavigatedViewer":16,"./Viewer":17,"./features/auto-place":26,"./features/auto-resize":29,"./features/context-pad":31,"./features/copy-paste":34,"./features/distribute-elements":38,"./features/editor-actions":40,"./features/grid-snapping":46,"./features/interaction-events":48,"./features/keyboard":50,"./features/label-editing":55,"./features/modeling":110,"./features/palette":116,"./features/replace-preview":121,"./features/search":128,"./features/snapping":132,"./util/CompatibilityUtil":138,"diagram-js/lib/features/align-elements":159,"diagram-js/lib/features/auto-scroll":169,"diagram-js/lib/features/bendpoints":176,"diagram-js/lib/features/connect":183,"diagram-js/lib/features/connection-preview":185,"diagram-js/lib/features/create":192,"diagram-js/lib/features/keyboard-move-selection":213,"diagram-js/lib/features/move":251,"diagram-js/lib/features/resize":269,"diagram-js/lib/navigation/keyboard-move":304,"diagram-js/lib/navigation/movecanvas":306,"diagram-js/lib/navigation/touch":307,"diagram-js/lib/navigation/zoomscroll":310,"inherits":347}],16:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = NavigatedViewer; var _inherits = _interopRequireDefault(require("inherits")); var _Viewer = _interopRequireDefault(require("./Viewer")); var _keyboardMove = _interopRequireDefault(require("diagram-js/lib/navigation/keyboard-move")); var _movecanvas = _interopRequireDefault(require("diagram-js/lib/navigation/movecanvas")); var _zoomscroll = _interopRequireDefault(require("diagram-js/lib/navigation/zoomscroll")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A viewer that includes mouse navigation facilities * * @param {Object} options */ function NavigatedViewer(options) { _Viewer.default.call(this, options); } (0, _inherits.default)(NavigatedViewer, _Viewer.default); NavigatedViewer.prototype._navigationModules = [_keyboardMove.default, _movecanvas.default, _zoomscroll.default]; NavigatedViewer.prototype._modules = [].concat(_Viewer.default.prototype._modules, NavigatedViewer.prototype._navigationModules); },{"./Viewer":17,"diagram-js/lib/navigation/keyboard-move":304,"diagram-js/lib/navigation/movecanvas":306,"diagram-js/lib/navigation/zoomscroll":310,"inherits":347}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Viewer; var _inherits = _interopRequireDefault(require("inherits")); var _core = _interopRequireDefault(require("./core")); var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate")); var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection")); var _overlays = _interopRequireDefault(require("diagram-js/lib/features/overlays")); var _BaseViewer = _interopRequireDefault(require("./BaseViewer")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * 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) { _BaseViewer.default.call(this, options); } (0, _inherits.default)(Viewer, _BaseViewer.default); // modules the viewer is composed of Viewer.prototype._modules = [_core.default, _translate.default, _selection.default, _overlays.default]; // default moddle extensions the viewer is composed of Viewer.prototype._moddleExtensions = {}; },{"./BaseViewer":14,"./core":18,"diagram-js/lib/features/overlays":256,"diagram-js/lib/features/selection":278,"diagram-js/lib/i18n/translate":296,"inherits":347}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _draw = _interopRequireDefault(require("../draw")); var _import = _interopRequireDefault(require("../import")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_draw.default, _import.default] }; exports.default = _default; },{"../draw":23,"../import":137}],19:[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":327,"min-dash":555}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnRenderer; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _BaseRenderer = _interopRequireDefault(require("diagram-js/lib/draw/BaseRenderer")); var _DiUtil = require("../util/DiUtil"); var _LabelUtil = require("../features/label-editing/LabelUtil"); 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 = _interopRequireDefault(require("ids")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var RENDERER_IDS = new _ids.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) { _BaseRenderer.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 colorEscape(str) { // only allow characters and numbers return str.replace(/[^0-9a-zA-z]+/g, '_'); } function marker(type, fill, stroke) { var id = type + '-' + colorEscape(fill) + '-' + colorEscape(stroke) + '-' + rendererId; if (!markers[id]) { createMarker(id, type, fill, stroke); } return 'url(#' + id + ')'; } function createMarker(id, type, fill, stroke) { 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 (event.eventDefinitions && event.eventDefinitions.length > 1) { if (event.parallelMultiple) { return renderer('bpmn:ParallelMultipleEventDefinition')(parentGfx, element, isThrowing); } else { return renderer('bpmn:MultipleEventDefinition')(parentGfx, element, isThrowing); } } 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: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 box = { width: 90, height: 30, x: element.width / 2 + element.x, y: element.height / 2 + element.y }; return renderLabel(parentGfx, (0, _LabelUtil.getLabel)(element), { 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 (parentGfx, element, attrs) { if (!('fillOpacity' in attrs)) { attrs.fillOpacity = DEFAULT_FILL_OPACITY; } return drawCircle(parentGfx, element.width, element.height, attrs); }, 'bpmn:StartEvent': function (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (parentGfx, element) { return renderer('bpmn:SubProcess')(parentGfx, element); }, 'bpmn:Transaction': function (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 (parentGfx, element) { return renderer('bpmn:SubProcess')(parentGfx, element, { strokeWidth: 5 }); }, 'bpmn:Participant': function (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (parentGfx, element) { var group = drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, { stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), strokeWidth: 1, strokeDasharray: '8,3,1,3', fill: 'none', pointerEvents: 'none' }); return group; }, 'label': function (parentGfx, element) { return renderExternalLabel(parentGfx, element); }, 'bpmn:TextAnnotation': function (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 (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 (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 (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 (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 (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 (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 (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, _inherits.default)(BpmnRenderer, _BaseRenderer.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); }; },{"../features/label-editing/LabelUtil":53,"../util/DiUtil":139,"../util/ModelUtil":141,"./BpmnRenderUtil":19,"diagram-js/lib/draw/BaseRenderer":154,"diagram-js/lib/util/RenderUtil":327,"diagram-js/lib/util/SvgTransformUtil":328,"ids":346,"inherits":347,"min-dash":555,"min-dom":556,"tiny-svg":567}],21:[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); }); } },{}],22:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TextRenderer; var _minDash = require("min-dash"); var _Text = _interopRequireDefault(require("diagram-js/lib/util/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 _Text.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":329,"min-dash":555}],23:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnRenderer = _interopRequireDefault(require("./BpmnRenderer")); var _TextRenderer = _interopRequireDefault(require("./TextRenderer")); var _PathMap = _interopRequireDefault(require("./PathMap")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['bpmnRenderer'], bpmnRenderer: ['type', _BpmnRenderer.default], textRenderer: ['type', _TextRenderer.default], pathMap: ['type', _PathMap.default] }; exports.default = _default; },{"./BpmnRenderer":20,"./PathMap":21,"./TextRenderer":22}],24:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoPlace; var _BpmnAutoPlaceUtil = require("./BpmnAutoPlaceUtil"); /** * BPMN auto-place behavior. * * @param {EventBus} eventBus */ function AutoPlace(eventBus) { eventBus.on('autoPlace', function (context) { var shape = context.shape, source = context.source; return (0, _BpmnAutoPlaceUtil.getNewShapePosition)(source, shape); }); } AutoPlace.$inject = ['eventBus']; },{"./BpmnAutoPlaceUtil":25}],25:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNewShapePosition = getNewShapePosition; exports.getFlowNodePosition = getFlowNodePosition; exports.getTextAnnotationPosition = getTextAnnotationPosition; exports.getDataElementPosition = getDataElementPosition; var _ModelUtil = require("../../util/ModelUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _AutoPlaceUtil = require("diagram-js/lib/features/auto-place/AutoPlaceUtil"); /** * 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 getTextAnnotationPosition(source, element); } if ((0, _ModelingUtil.isAny)(element, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) { return getDataElementPosition(source, element); } if ((0, _ModelUtil.is)(element, 'bpmn:FlowNode')) { return getFlowNodePosition(source, element); } } /** * 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 = (0, _AutoPlaceUtil.getConnectedDistance)(source, { filter: function (connection) { return (0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow'); } }); var margin = 30, minDistance = 80, orientation = 'left'; if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) { orientation = (0, _LayoutUtil.getOrientation)(source, source.host, -25); if (orientation.indexOf('top') !== -1) { margin *= -1; } } var position = { x: sourceTrbl.right + horizontalDistance + element.width / 2, y: sourceMid.y + getVerticalDistance(orientation, minDistance) }; var nextPositionDirection = { y: { margin: margin, minDistance: minDistance } }; return (0, _AutoPlaceUtil.findFreePosition)(source, element, position, (0, _AutoPlaceUtil.generateGetNextPosition)(nextPositionDirection)); } function getVerticalDistance(orientation, minDistance) { if (orientation.indexOf('top') != -1) { return -1 * minDistance; } else if (orientation.indexOf('bottom') != -1) { return minDistance; } else { return 0; } } /** * 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 nextPositionDirection = { y: { margin: -30, minDistance: 20 } }; return (0, _AutoPlaceUtil.findFreePosition)(source, element, position, (0, _AutoPlaceUtil.generateGetNextPosition)(nextPositionDirection)); } /** * 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 nextPositionDirection = { x: { margin: 30, minDistance: 30 } }; return (0, _AutoPlaceUtil.findFreePosition)(source, element, position, (0, _AutoPlaceUtil.generateGetNextPosition)(nextPositionDirection)); } },{"../../util/ModelUtil":141,"../modeling/util/ModelingUtil":112,"diagram-js/lib/features/auto-place/AutoPlaceUtil":164,"diagram-js/lib/layout/LayoutUtil":300}],26:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _autoPlace = _interopRequireDefault(require("diagram-js/lib/features/auto-place")); var _BpmnAutoPlace = _interopRequireDefault(require("./BpmnAutoPlace")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_autoPlace.default], __init__: ['bpmnAutoPlace'], bpmnAutoPlace: ['type', _BpmnAutoPlace.default] }; exports.default = _default; },{"./BpmnAutoPlace":24,"diagram-js/lib/features/auto-place":165}],27:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnAutoResize; var _AutoResize = _interopRequireDefault(require("diagram-js/lib/features/auto-resize/AutoResize")); var _inherits = _interopRequireDefault(require("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(_AutoResize.default, this); } BpmnAutoResize.$inject = ['injector']; (0, _inherits.default)(BpmnAutoResize, _AutoResize.default); /** * Resize shapes and lanes. * * @param {djs.model.Shape} target * @param {Bounds} newBounds * @param {Object} hints */ BpmnAutoResize.prototype.resize = function (target, newBounds, hints) { if ((0, _ModelUtil.is)(target, 'bpmn:Participant')) { this._modeling.resizeLane(target, newBounds, null, hints); } else { this._modeling.resizeShape(target, newBounds, null, hints); } }; },{"../../util/ModelUtil":141,"diagram-js/lib/features/auto-resize/AutoResize":166,"inherits":347}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnAutoResizeProvider; var _ModelUtil = require("../../util/ModelUtil"); var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _AutoResizeProvider = _interopRequireDefault(require("diagram-js/lib/features/auto-resize/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) { _AutoResizeProvider.default.call(this, eventBus); this._modeling = modeling; } (0, _inherits.default)(BpmnAutoResizeProvider, _AutoResizeProvider.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":141,"diagram-js/lib/features/auto-resize/AutoResizeProvider":167,"inherits":347,"min-dash":555}],29:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnAutoResize = _interopRequireDefault(require("./BpmnAutoResize")); var _BpmnAutoResizeProvider = _interopRequireDefault(require("./BpmnAutoResizeProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['bpmnAutoResize', 'bpmnAutoResizeProvider'], bpmnAutoResize: ['type', _BpmnAutoResize.default], bpmnAutoResizeProvider: ['type', _BpmnAutoResizeProvider.default] }; exports.default = _default; },{"./BpmnAutoResize":27,"./BpmnAutoResizeProvider":28}],30:[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 context = event.context, shape = context.shape; if (!(0, _Mouse.hasPrimaryModifier)(event) || !contextPad.isOpen(shape)) { 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, { source: 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 (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 (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', translate('Append ReceiveTask')), '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.condition-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', translate('Append EndEvent')), 'append.gateway': appendAction('bpmn:ExclusiveGateway', 'bpmn-icon-gateway-none', translate('Append Gateway')), 'append.append-task': appendAction('bpmn:Task', 'bpmn-icon-task', translate('Append 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 (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 } } }); } if ((0, _ModelUtil.is)(businessObject, 'bpmn:Group')) { (0, _minDash.assign)(actions, { 'append.text-annotation': appendAction('bpmn:TextAnnotation', 'bpmn-icon-text-annotation') }); } // 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; }; // helpers ///////// 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":139,"../../util/ModelUtil":141,"../modeling/util/LaneUtil":111,"../modeling/util/ModelingUtil":112,"diagram-js/lib/util/Mouse":323,"min-dash":555}],31:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _diagramJsDirectEditing = _interopRequireDefault(require("diagram-js-direct-editing")); var _contextPad = _interopRequireDefault(require("diagram-js/lib/features/context-pad")); var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection")); var _connect = _interopRequireDefault(require("diagram-js/lib/features/connect")); var _create = _interopRequireDefault(require("diagram-js/lib/features/create")); var _popupMenu = _interopRequireDefault(require("../popup-menu")); var _ContextPadProvider = _interopRequireDefault(require("./ContextPadProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_diagramJsDirectEditing.default, _contextPad.default, _selection.default, _connect.default, _create.default, _popupMenu.default], __init__: ['contextPadProvider'], contextPadProvider: ['type', _ContextPadProvider.default] }; exports.default = _default; },{"../popup-menu":118,"./ContextPadProvider":30,"diagram-js-direct-editing":332,"diagram-js/lib/features/connect":183,"diagram-js/lib/features/context-pad":187,"diagram-js/lib/features/create":192,"diagram-js/lib/features/selection":278}],32:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnCopyPaste; var _ModelUtil = require("../../util/ModelUtil"); var _minDash = require("min-dash"); function copyProperties(source, target, properties) { if (!(0, _minDash.isArray)(properties)) { properties = [properties]; } (0, _minDash.forEach)(properties, function (property) { if (!(0, _minDash.isUndefined)(source[property])) { target[property] = source[property]; } }); } function removeProperties(element, properties) { if (!(0, _minDash.isArray)(properties)) { properties = [properties]; } (0, _minDash.forEach)(properties, function (property) { if (element[property]) { delete element[property]; } }); } var LOW_PRIORITY = 750; function BpmnCopyPaste(bpmnFactory, eventBus, moddleCopy) { eventBus.on('copyPaste.copyElement', LOW_PRIORITY, function (context) { var descriptor = context.descriptor, element = context.element; var businessObject = descriptor.oldBusinessObject = (0, _ModelUtil.getBusinessObject)(element); descriptor.type = element.type; copyProperties(businessObject, descriptor, 'name'); descriptor.di = {}; // fill and stroke will be set to DI copyProperties(businessObject.di, descriptor.di, ['fill', 'stroke']); copyProperties(businessObject.di, descriptor, 'isExpanded'); if (isLabel(descriptor)) { return descriptor; } // default sequence flow if (businessObject.default) { descriptor.default = businessObject.default.id; } }); eventBus.on('moddleCopy.canCopyProperty', function (context) { var parent = context.parent, property = context.property, propertyName = context.propertyName, bpmnProcess; if (propertyName === 'processRef' && (0, _ModelUtil.is)(parent, 'bpmn:Participant') && (0, _ModelUtil.is)(property, 'bpmn:Process')) { bpmnProcess = bpmnFactory.create('bpmn:Process'); // return copy of process return moddleCopy.copyElement(property, bpmnProcess); } }); var references; function resolveReferences(descriptor, cache) { var businessObject = (0, _ModelUtil.getBusinessObject)(descriptor); // default sequence flows if (descriptor.default) { // relationship cannot be resolved immediately references[descriptor.default] = { element: businessObject, property: 'default' }; } // boundary events if (descriptor.host) { // relationship can be resolved immediately (0, _ModelUtil.getBusinessObject)(descriptor).attachedToRef = (0, _ModelUtil.getBusinessObject)(cache[descriptor.host]); } references = (0, _minDash.omit)(references, (0, _minDash.reduce)(references, function (array, reference, key) { var element = reference.element, property = reference.property; if (key === descriptor.id) { element[property] = businessObject; array.push(descriptor.id); } return array; }, [])); } eventBus.on('copyPaste.pasteElements', function () { references = {}; }); eventBus.on('copyPaste.pasteElement', function (context) { var cache = context.cache, descriptor = context.descriptor, oldBusinessObject = descriptor.oldBusinessObject, newBusinessObject; // do NOT copy business object if external label if (isLabel(descriptor)) { descriptor.businessObject = (0, _ModelUtil.getBusinessObject)(cache[descriptor.labelTarget]); return; } newBusinessObject = bpmnFactory.create(oldBusinessObject.$type); descriptor.businessObject = moddleCopy.copyElement(oldBusinessObject, newBusinessObject); // resolve references e.g. default sequence flow resolveReferences(descriptor, cache); copyProperties(descriptor, newBusinessObject, ['isExpanded', 'name']); removeProperties(descriptor, 'oldBusinessObject'); }); } BpmnCopyPaste.$inject = ['bpmnFactory', 'eventBus', 'moddleCopy']; // helpers ////////// function isLabel(element) { return !!element.labelTarget; } },{"../../util/ModelUtil":141,"min-dash":555}],33:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ModdleCopy; exports.getPropertyNames = getPropertyNames; var _minDash = require("min-dash"); var DISALLOWED_PROPERTIES = ['artifacts', 'dataInputAssociations', 'dataOutputAssociations', 'default', 'flowElements', 'lanes', 'incoming', 'outgoing']; /** * @typedef {Function} listener * * @param {Object} context * @param {Array} context.propertyNames * @param {ModdleElement} context.sourceElement * @param {ModdleElement} context.targetElement * * @returns {Array|boolean} - Return properties to be copied or false to disallow * copying. */ /** * @typedef {Function} listener * * @param {Object} context * @param {ModdleElement} context.parent * @param {*} context.property * @param {string} context.propertyName * * @returns {*|boolean} - Return copied property or false to disallow * copying. */ /** * @typedef {Function} listener * * @param {Object} context * @param {ModdleElement} context.parent * @param {*} context.property * @param {string} context.propertyName * * @returns {boolean} - Return false to disallow * setting copied property. */ /** * Utility for copying model properties from source element to target element. * * @param {EventBus} eventBus * @param {BpmnFactory} bpmnFactory * @param {BpmnModdle} moddle */ function ModdleCopy(eventBus, bpmnFactory, moddle) { this._bpmnFactory = bpmnFactory; this._eventBus = eventBus; this._moddle = moddle; // copy extension elements last eventBus.on('moddleCopy.canCopyProperties', function (context) { var propertyNames = context.propertyNames; if (!propertyNames || !propertyNames.length) { return; } return (0, _minDash.sortBy)(propertyNames, function (propertyName) { return propertyName === 'extensionElements'; }); }); // default check whether property can be copied eventBus.on('moddleCopy.canCopyProperty', function (context) { var parent = context.parent, parentDescriptor = (0, _minDash.isObject)(parent) && parent.$descriptor, propertyName = context.propertyName; if (propertyName && DISALLOWED_PROPERTIES.indexOf(propertyName) !== -1) { // disallow copying property return false; } if (propertyName && parentDescriptor && !(0, _minDash.find)(parentDescriptor.properties, (0, _minDash.matchPattern)({ name: propertyName }))) { // disallow copying property return false; } }); // do NOT allow to copy empty extension elements eventBus.on('moddleCopy.canSetCopiedProperty', function (context) { var property = context.property; if (is(property, 'bpmn:ExtensionElements') && (!property.values || !property.values.length)) { // disallow setting copied property return false; } }); } ModdleCopy.$inject = ['eventBus', 'bpmnFactory', 'moddle']; /** * Copy model properties of source element to target element. * * @param {ModdleElement} sourceElement * @param {ModdleElement} targetElement * @param {Array} [propertyNames] * * @param {ModdleElement} */ ModdleCopy.prototype.copyElement = function (sourceElement, targetElement, propertyNames) { var self = this; if (propertyNames && !(0, _minDash.isArray)(propertyNames)) { propertyNames = [propertyNames]; } propertyNames = propertyNames || getPropertyNames(sourceElement.$descriptor); var canCopyProperties = this._eventBus.fire('moddleCopy.canCopyProperties', { propertyNames: propertyNames, sourceElement: sourceElement, targetElement: targetElement }); if (canCopyProperties === false) { return targetElement; } if ((0, _minDash.isArray)(canCopyProperties)) { propertyNames = canCopyProperties; } // copy properties (0, _minDash.forEach)(propertyNames, function (propertyName) { var sourceProperty; if ((0, _minDash.has)(sourceElement, propertyName)) { sourceProperty = sourceElement.get(propertyName); } var copiedProperty = self.copyProperty(sourceProperty, targetElement, propertyName); var canSetProperty = self._eventBus.fire('moddleCopy.canSetCopiedProperty', { parent: targetElement, property: copiedProperty, propertyName: propertyName }); if (canSetProperty === false) { return; } if ((0, _minDash.isDefined)(copiedProperty)) { targetElement.set(propertyName, copiedProperty); } }); return targetElement; }; /** * Copy model property. * * @param {*} property * @param {ModdleElement} parent * @param {string} propertyName * * @returns {*} */ ModdleCopy.prototype.copyProperty = function (property, parent, propertyName) { var self = this; // allow others to copy property var copiedProperty = this._eventBus.fire('moddleCopy.canCopyProperty', { parent: parent, property: property, propertyName: propertyName }); // return if copying is NOT allowed if (copiedProperty === false) { return; } if (copiedProperty) { if ((0, _minDash.isObject)(copiedProperty) && copiedProperty.$type && !copiedProperty.$parent) { copiedProperty.$parent = parent; } return copiedProperty; } var propertyDescriptor = this._moddle.getPropertyDescriptor(parent, propertyName); // do NOT copy Ids and references if (propertyDescriptor.isId || propertyDescriptor.isReference) { return; } // copy arrays if ((0, _minDash.isArray)(property)) { return (0, _minDash.reduce)(property, function (childProperties, childProperty) { // recursion copiedProperty = self.copyProperty(childProperty, parent, propertyName); // copying might NOT be allowed if (copiedProperty) { copiedProperty.$parent = parent; return childProperties.concat(copiedProperty); } return childProperties; }, []); } // copy model elements if ((0, _minDash.isObject)(property) && property.$type) { if (this._moddle.getElementDescriptor(property).isGeneric) { return; } copiedProperty = self._bpmnFactory.create(property.$type); copiedProperty.$parent = parent; // recursion copiedProperty = self.copyElement(property, copiedProperty); return copiedProperty; } // copy primitive properties return property; }; // helpers ////////// function getPropertyNames(descriptor, keepDefaultProperties) { return (0, _minDash.reduce)(descriptor.properties, function (properties, property) { if (keepDefaultProperties && property.default) { return properties; } return properties.concat(property.name); }, []); } function is(element, type) { return element && typeof element.$instanceOf === 'function' && element.$instanceOf(type); } },{"min-dash":555}],34:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _copyPaste = _interopRequireDefault(require("diagram-js/lib/features/copy-paste")); var _BpmnCopyPaste = _interopRequireDefault(require("./BpmnCopyPaste")); var _ModdleCopy = _interopRequireDefault(require("./ModdleCopy")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_copyPaste.default], __init__: ['bpmnCopyPaste', 'moddleCopy'], bpmnCopyPaste: ['type', _BpmnCopyPaste.default], moddleCopy: ['type', _ModdleCopy.default] }; exports.default = _default; },{"./BpmnCopyPaste":32,"./ModdleCopy":33,"diagram-js/lib/features/copy-paste":189}],35:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnDiOrdering; var _BpmnRenderUtil = require("../../draw/BpmnRenderUtil"); var _ModelUtil = require("../../util/ModelUtil"); var _minDash = require("min-dash"); var _Elements = require("diagram-js/lib/util/Elements"); var HIGH_PRIORITY = 2000; function BpmnDiOrdering(eventBus, canvas) { eventBus.on('saveXML.start', HIGH_PRIORITY, orderDi); function orderDi() { var root = canvas.getRootElement(), rootDi = (0, _ModelUtil.getBusinessObject)(root).di, elements, diElements; elements = (0, _Elements.selfAndAllChildren)([root], false); // only bpmndi:Shape and bpmndi:Edge can be direct children of bpmndi:Plane elements = (0, _minDash.filter)(elements, function (element) { return element !== root && !element.labelTarget; }); diElements = (0, _minDash.map)(elements, _BpmnRenderUtil.getDi); rootDi.set('planeElement', diElements); } } BpmnDiOrdering.$inject = ['eventBus', 'canvas']; },{"../../draw/BpmnRenderUtil":19,"../../util/ModelUtil":141,"diagram-js/lib/util/Elements":315,"min-dash":555}],36:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnDiOrdering = _interopRequireDefault(require("../di-ordering/BpmnDiOrdering")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['bpmnDiOrdering'], bpmnDiOrdering: ['type', _BpmnDiOrdering.default] }; exports.default = _default; },{"../di-ordering/BpmnDiOrdering":35}],37:[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":112,"min-dash":555}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _distributeElements = _interopRequireDefault(require("diagram-js/lib/features/distribute-elements")); var _BpmnDistributeElements = _interopRequireDefault(require("./BpmnDistributeElements")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_distributeElements.default], __init__: ['bpmnDistributeElements'], bpmnDistributeElements: ['type', _BpmnDistributeElements.default] }; exports.default = _default; },{"./BpmnDistributeElements":37,"diagram-js/lib/features/distribute-elements":194}],39:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnEditorActions; var _inherits = _interopRequireDefault(require("inherits")); var _EditorActions = _interopRequireDefault(require("diagram-js/lib/features/editor-actions/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(_EditorActions.default, this); } (0, _inherits.default)(BpmnEditorActions, _EditorActions.default); BpmnEditorActions.$inject = ['injector']; /** * Register default actions. * * @param {Injector} injector */ BpmnEditorActions.prototype._registerDefaultActions = function (injector) { // (0) invoke super method _EditorActions.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":141,"diagram-js/lib/features/editor-actions/EditorActions":198,"diagram-js/lib/util/Elements":315,"inherits":347,"min-dash":555}],40:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _editorActions = _interopRequireDefault(require("diagram-js/lib/features/editor-actions")); var _BpmnEditorActions = _interopRequireDefault(require("./BpmnEditorActions")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_editorActions.default], editorActions: ['type', _BpmnEditorActions.default] }; exports.default = _default; },{"./BpmnEditorActions":39,"diagram-js/lib/features/editor-actions":199}],41:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnGridSnapping; var _ModelingUtil = require("../modeling/util/ModelingUtil"); function BpmnGridSnapping(eventBus) { eventBus.on(['create.init', 'shape.move.init'], function (event) { var context = event.context, shape = event.shape; if ((0, _ModelingUtil.isAny)(shape, ['bpmn:Participant', 'bpmn:SubProcess', 'bpmn:TextAnnotation'])) { if (!context.gridSnappingContext) { context.gridSnappingContext = {}; } context.gridSnappingContext.snapLocation = 'top-left'; } }); } BpmnGridSnapping.$inject = ['eventBus']; },{"../modeling/util/ModelingUtil":112}],42:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoPlaceBehavior; var _BpmnAutoPlaceUtil = require("../../auto-place/BpmnAutoPlaceUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _ModelUtil = require("../../../util/ModelUtil"); var HIGH_PRIORITY = 2000; function AutoPlaceBehavior(eventBus, gridSnapping) { eventBus.on('autoPlace', HIGH_PRIORITY, function (context) { var source = context.source, sourceMid = (0, _LayoutUtil.getMid)(source), shape = context.shape; var position = (0, _BpmnAutoPlaceUtil.getNewShapePosition)(source, shape); ['x', 'y'].forEach(function (axis) { var options = {}; // do not snap if x/y equal if (position[axis] === sourceMid[axis]) { return; } if (position[axis] > sourceMid[axis]) { options.min = position[axis]; } else { options.max = position[axis]; } if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) { if (isHorizontal(axis)) { options.offset = -shape.width / 2; } else { options.offset = -shape.height / 2; } } position[axis] = gridSnapping.snapValue(position[axis], options); }); // must be returned to be considered by auto place return position; }); } AutoPlaceBehavior.$inject = ['eventBus', 'gridSnapping']; // helpers ////////// function isHorizontal(axis) { return axis === 'x'; } },{"../../../util/ModelUtil":141,"../../auto-place/BpmnAutoPlaceUtil":25,"diagram-js/lib/layout/LayoutUtil":300}],43:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateParticipantBehavior; var _ModelUtil = require("../../../util/ModelUtil"); var HIGHER_PRIORITY = 1750; function CreateParticipantBehavior(canvas, eventBus, gridSnapping) { eventBus.on(['create.start', 'shape.move.start'], HIGHER_PRIORITY, function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(); if (!(0, _ModelUtil.is)(shape, 'bpmn:Participant') || !(0, _ModelUtil.is)(rootElement, 'bpmn:Process') || !rootElement.children.length) { return; } var createConstraints = context.createConstraints; if (!createConstraints) { return; } shape.width = gridSnapping.snapValue(shape.width, { min: shape.width }); shape.height = gridSnapping.snapValue(shape.height, { min: shape.height }); }); } CreateParticipantBehavior.$inject = ['canvas', 'eventBus', 'gridSnapping']; },{"../../../util/ModelUtil":141}],44:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LayoutConnectionBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _Geometry = require("diagram-js/lib/util/Geometry"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGH_PRIORITY = 3000; /** * Snaps connections with Manhattan layout. */ function LayoutConnectionBehavior(eventBus, gridSnapping, modeling) { _CommandInterceptor.default.call(this, eventBus); this._gridSnapping = gridSnapping; var self = this; this.postExecuted(['connection.create', 'connection.layout'], HIGH_PRIORITY, function (event) { var context = event.context, connection = context.connection, hints = context.hints || {}, waypoints = connection.waypoints; if (hints.connectionStart || hints.connectionEnd || hints.createElementsBehavior === false) { return; } if (!hasMiddleSegments(waypoints)) { return; } modeling.updateWaypoints(connection, self.snapMiddleSegments(waypoints)); }); } LayoutConnectionBehavior.$inject = ['eventBus', 'gridSnapping', 'modeling']; (0, _inherits.default)(LayoutConnectionBehavior, _CommandInterceptor.default); /** * Snap middle segments of a given connection. * * @param {Array} waypoints * * @returns {Array} */ LayoutConnectionBehavior.prototype.snapMiddleSegments = function (waypoints) { var gridSnapping = this._gridSnapping, snapped; waypoints = waypoints.slice(); for (var i = 1; i < waypoints.length - 2; i++) { snapped = snapSegment(gridSnapping, waypoints[i], waypoints[i + 1]); waypoints[i] = snapped[0]; waypoints[i + 1] = snapped[1]; } return waypoints; }; // helpers ////////// /** * Check whether a connection has a middle segments. * * @param {Array} waypoints * * @returns {boolean} */ function hasMiddleSegments(waypoints) { return waypoints.length > 3; } /** * Check whether an alignment is horizontal. * * @param {string} aligned * * @returns {boolean} */ function horizontallyAligned(aligned) { return aligned === 'h'; } /** * Check whether an alignment is vertical. * * @param {string} aligned * * @returns {boolean} */ function verticallyAligned(aligned) { return aligned === 'v'; } /** * Get middle segments from a given connection. * * @param {Array} waypoints * * @returns {Array} */ function snapSegment(gridSnapping, segmentStart, segmentEnd) { var aligned = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd); var snapped = {}; if (horizontallyAligned(aligned)) { // snap horizontally snapped.y = gridSnapping.snapValue(segmentStart.y); } if (verticallyAligned(aligned)) { // snap vertically snapped.x = gridSnapping.snapValue(segmentStart.x); } if ('x' in snapped || 'y' in snapped) { segmentStart = (0, _minDash.assign)({}, segmentStart, snapped); segmentEnd = (0, _minDash.assign)({}, segmentEnd, snapped); } return [segmentStart, segmentEnd]; } },{"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Geometry":318,"inherits":347,"min-dash":555}],45:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _AutoPlaceBehavior = _interopRequireDefault(require("./AutoPlaceBehavior")); var _CreateParticipantBehavior = _interopRequireDefault(require("./CreateParticipantBehavior")); var _LayoutConnectionBehavior = _interopRequireDefault(require("./LayoutConnectionBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['gridSnappingAutoPlaceBehavior', 'gridSnappingCreateParticipantBehavior', 'gridSnappingLayoutConnectionBehavior'], gridSnappingAutoPlaceBehavior: ['type', _AutoPlaceBehavior.default], gridSnappingCreateParticipantBehavior: ['type', _CreateParticipantBehavior.default], gridSnappingLayoutConnectionBehavior: ['type', _LayoutConnectionBehavior.default] }; exports.default = _default; },{"./AutoPlaceBehavior":42,"./CreateParticipantBehavior":43,"./LayoutConnectionBehavior":44}],46:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnGridSnapping = _interopRequireDefault(require("./BpmnGridSnapping")); var _gridSnapping = _interopRequireDefault(require("diagram-js/lib/features/grid-snapping")); var _behavior = _interopRequireDefault(require("./behavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_gridSnapping.default, _behavior.default], __init__: ['bpmnGridSnapping'], bpmnGridSnapping: ['type', _BpmnGridSnapping.default] }; exports.default = _default; },{"./BpmnGridSnapping":41,"./behavior":45,"diagram-js/lib/features/grid-snapping":207}],47:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnInteractionEvents; var _ModelUtil = require("../../util/ModelUtil"); var _DiUtil = require("../../util/DiUtil"); var LABEL_WIDTH = 30, LABEL_HEIGHT = 30; /** * BPMN-specific hit zones and interaction fixes. * * @param {EventBus} eventBus * @param {InteractionEvents} interactionEvents */ function BpmnInteractionEvents(eventBus, interactionEvents) { this._interactionEvents = interactionEvents; var self = this; eventBus.on(['interactionEvents.createHit', 'interactionEvents.updateHit'], function (context) { var element = context.element, gfx = context.gfx; if ((0, _ModelUtil.is)(element, 'bpmn:Lane')) { return self.createParticipantHit(element, gfx); } else if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) { if ((0, _DiUtil.isExpanded)(element)) { return self.createParticipantHit(element, gfx); } else { return self.createDefaultHit(element, gfx); } } else if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess')) { if ((0, _DiUtil.isExpanded)(element)) { return self.createSubProcessHit(element, gfx); } else { return self.createDefaultHit(element, gfx); } } }); } BpmnInteractionEvents.$inject = ['eventBus', 'interactionEvents']; BpmnInteractionEvents.prototype.createDefaultHit = function (element, gfx) { this._interactionEvents.removeHits(gfx); this._interactionEvents.createDefaultHit(element, gfx); // indicate that we created a hit return true; }; BpmnInteractionEvents.prototype.createParticipantHit = function (element, gfx) { // remove existing hits this._interactionEvents.removeHits(gfx); // add outline hit this._interactionEvents.createBoxHit(gfx, 'click-stroke', { width: element.width, height: element.height }); // add label hit this._interactionEvents.createBoxHit(gfx, 'all', { width: LABEL_WIDTH, height: element.height }); // indicate that we created a hit return true; }; BpmnInteractionEvents.prototype.createSubProcessHit = function (element, gfx) { // remove existing hits this._interactionEvents.removeHits(gfx); // add outline hit this._interactionEvents.createBoxHit(gfx, 'click-stroke', { width: element.width, height: element.height }); // add label hit this._interactionEvents.createBoxHit(gfx, 'all', { width: element.width, height: LABEL_HEIGHT }); // indicate that we created a hit return true; }; },{"../../util/DiUtil":139,"../../util/ModelUtil":141}],48:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnInteractionEvents = _interopRequireDefault(require("./BpmnInteractionEvents")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['bpmnInteractionEvents'], bpmnInteractionEvents: ['type', _BpmnInteractionEvents.default] }; exports.default = _default; },{"./BpmnInteractionEvents":47}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnKeyboardBindings; var _inherits = _interopRequireDefault(require("inherits")); var _KeyboardBindings = _interopRequireDefault(require("diagram-js/lib/features/keyboard/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(_KeyboardBindings.default, this); } (0, _inherits.default)(BpmnKeyboardBindings, _KeyboardBindings.default); BpmnKeyboardBindings.$inject = ['injector']; /** * Register available keyboard bindings. * * @param {Keyboard} keyboard * @param {EditorActions} editorActions */ BpmnKeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) { // inherit default bindings _KeyboardBindings.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":215,"inherits":347}],50:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _keyboard = _interopRequireDefault(require("diagram-js/lib/features/keyboard")); var _BpmnKeyboardBindings = _interopRequireDefault(require("./BpmnKeyboardBindings")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_keyboard.default], __init__: ['keyboardBindings'], keyboardBindings: ['type', _BpmnKeyboardBindings.default] }; exports.default = _default; },{"./BpmnKeyboardBindings":49,"diagram-js/lib/features/keyboard":217}],51:[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":141,"diagram-js/lib/util/SvgTransformUtil":328,"tiny-svg":567}],52:[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 _CategoryUtil = require("../modeling/behavior/util/CategoryUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _DiUtil = require("../../util/DiUtil"); var _LabelUtil2 = require("../../util/LabelUtil"); function LabelEditingProvider(eventBus, bpmnFactory, canvas, directEditing, modeling, resizeHandles, textRenderer) { this._bpmnFactory = bpmnFactory; 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(['autoPlace.start', 'canvas.viewbox.changing', 'drag.init', 'element.mousedown', '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 context = event.context, element = context.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; } if (context.hints && context.hints.createElementsBehavior === false) { 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', 'bpmn:Group']) || isCollapsedSubProcess(element)) { directEditing.activate(element); } } } LabelEditingProvider.$inject = ['eventBus', 'bpmnFactory', '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, groups 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 ((0, _ModelUtil.is)(element, 'bpmn:Group')) { var businessObject = (0, _ModelUtil.getBusinessObject)(element); // initialize categoryValue if not existing if (!businessObject.categoryValueRef) { var rootElement = this._canvas.getRootElement(), definitions = (0, _ModelUtil.getBusinessObject)(rootElement).$parent; var categoryValue = (0, _CategoryUtil.createCategoryValue)(definitions, this._bpmnFactory); (0, _ModelUtil.getBusinessObject)(element).categoryValueRef = categoryValue; } } 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":139,"../../util/LabelUtil":140,"../../util/ModelUtil":141,"../modeling/behavior/util/CategoryUtil":95,"../modeling/util/ModelingUtil":112,"./LabelUtil":53,"min-dash":555}],53:[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') || (0, _ModelUtil.is)(semantic, 'bpmn:DataInput') || (0, _ModelUtil.is)(semantic, 'bpmn:DataOutput')) { return 'name'; } if ((0, _ModelUtil.is)(semantic, 'bpmn:TextAnnotation')) { return 'text'; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Group')) { return 'categoryValueRef'; } } function getCategoryValue(semantic) { var categoryValueRef = semantic['categoryValueRef']; if (!categoryValueRef) { return ''; } return categoryValueRef.value || ''; } function getLabel(element) { var semantic = element.businessObject, attr = getLabelAttr(semantic); if (attr) { if (attr === 'categoryValueRef') { return getCategoryValue(semantic); } return semantic[attr] || ''; } } function setLabel(element, text, isExternal) { var semantic = element.businessObject, attr = getLabelAttr(semantic); if (attr) { if (attr === 'categoryValueRef') { semantic['categoryValueRef'].value = text; } else { semantic[attr] = text; } } return element; } },{"../../util/ModelUtil":141}],54:[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 || {}; // ignore internal labels for elements except text annotations if (!(0, _LabelUtil2.isLabel)(label) && !(0, _ModelUtil.is)(label, 'bpmn:TextAnnotation')) { return; } if ((0, _LabelUtil2.isLabel)(label) && isEmptyText(newLabel)) { if (hints.removeShape !== false) { modeling.removeShape(label, { unsetLabel: false }); } return; } var text = (0, _LabelUtil.getLabel)(label); // 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":140,"../../../util/ModelUtil":141,"../LabelUtil":53}],55:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _changeSupport = _interopRequireDefault(require("diagram-js/lib/features/change-support")); var _resize = _interopRequireDefault(require("diagram-js/lib/features/resize")); var _diagramJsDirectEditing = _interopRequireDefault(require("diagram-js-direct-editing")); var _LabelEditingProvider = _interopRequireDefault(require("./LabelEditingProvider")); var _LabelEditingPreview = _interopRequireDefault(require("./LabelEditingPreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_changeSupport.default, _resize.default, _diagramJsDirectEditing.default], __init__: ['labelEditingProvider', 'labelEditingPreview'], labelEditingProvider: ['type', _LabelEditingProvider.default], labelEditingPreview: ['type', _LabelEditingPreview.default] }; exports.default = _default; },{"./LabelEditingPreview":51,"./LabelEditingProvider":52,"diagram-js-direct-editing":332,"diagram-js/lib/features/change-support":178,"diagram-js/lib/features/resize":269}],56:[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"); var _ModelUtil = require("../../util/ModelUtil"); 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', 'bpmn:CategoryValue']); }; BpmnFactory.prototype._ensureId = function (element) { // generate semantic ids for elements // bpmn:SequenceFlow -> SequenceFlow_ID var prefix; if ((0, _ModelUtil.is)(element, 'bpmn:Activity')) { prefix = 'Activity'; } else if ((0, _ModelUtil.is)(element, 'bpmn:Event')) { prefix = 'Event'; } else if ((0, _ModelUtil.is)(element, 'bpmn:Gateway')) { prefix = 'Gateway'; } else if ((0, _ModelingUtil.isAny)(element, ['bpmn:SequenceFlow', 'bpmn:MessageFlow'])) { prefix = 'Flow'; } else { prefix = (element.$type || '').replace(/^[^:]*:/g, ''); } prefix += '_'; 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/ModelUtil":141,"./util/ModelingUtil":112,"min-dash":555}],57:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnLayouter; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _BaseLayouter = _interopRequireDefault(require("diagram-js/lib/layout/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 }; } var ATTACH_ORIENTATION_PADDING = -10, BOUNDARY_TO_HOST_THRESHOLD = 40; 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 BpmnLayouter() {} (0, _inherits.default)(BpmnLayouter, _BaseLayouter.default); BpmnLayouter.prototype.layoutConnection = function (connection, hints) { if (!hints) { hints = {}; } var source = hints.source || connection.source, target = hints.target || connection.target, waypoints = hints.waypoints || connection.waypoints, connectionStart = hints.connectionStart, connectionEnd = hints.connectionEnd; var manhattanOptions, updatedWaypoints; if (!connectionStart) { connectionStart = getConnectionDocking(waypoints && waypoints[0], source); } if (!connectionEnd) { connectionEnd = 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(source, target)) { return [].concat([connectionStart], waypoints.slice(1, -1), [connectionEnd]); } } if ((0, _ModelUtil.is)(connection, 'bpmn:MessageFlow')) { manhattanOptions = getMessageFlowManhattanOptions(source, target); } else if ((0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow') || isCompensationAssociation(source, target)) { // layout all connection between flow elements h:h, except for // (1) outgoing of boundary events -> layout based on attach orientation and target orientation // (2) incoming/outgoing of gateways -> v:h for outgoing, h:v for incoming // (3) loops if (source === target) { manhattanOptions = { preferredLayouts: getLoopPreferredLayout(source, connection) }; } else if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) { manhattanOptions = { preferredLayouts: getBoundaryEventPreferredLayouts(source, target, connectionEnd) }; } else if (isExpandedSubProcess(source) || isExpandedSubProcess(target)) { manhattanOptions = getSubProcessManhattanOptions(source); } 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, connectionStart, connectionEnd, waypoints, manhattanOptions)); } return updatedWaypoints || [connectionStart, connectionEnd]; }; // helpers ////////// function getAttachOrientation(attachedElement) { var hostElement = attachedElement.host; return (0, _LayoutUtil.getOrientation)((0, _LayoutUtil.getMid)(attachedElement), hostElement, ATTACH_ORIENTATION_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 getSubProcessManhattanOptions(source) { return { preferredLayouts: ['straight', 'h:h'], preserveDocking: getSubProcessPreserveDocking(source) }; } function getSubProcessPreserveDocking(source) { return isExpandedSubProcess(source) ? 'target' : 'source'; } function getConnectionDocking(point, shape) { return point ? point.original || point : (0, _LayoutUtil.getMid)(shape); } function isCompensationAssociation(source, 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; } 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 getLoopPreferredLayout(source, connection) { var waypoints = connection.waypoints; var orientation = waypoints && waypoints.length && (0, _LayoutUtil.getOrientation)(waypoints[0], source); if (orientation === 'top') { return ['t:r']; } else if (orientation === 'right') { return ['r:b']; } else if (orientation === 'left') { return ['l:t']; } return ['b:l']; } function getBoundaryEventPreferredLayouts(source, target, end) { 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 targetOrientation = (0, _LayoutUtil.getOrientation)(targetMid, sourceMid, { x: source.width / 2 + target.width / 2, y: source.height / 2 + target.height / 2 }); if (isLoop) { return getBoundaryEventLoopLayout(attachOrientation, attachedToSide, source, target, end); } // source layout sourceLayout = getBoundaryEventSourceLayout(attachOrientation, targetOrientation, attachedToSide); // target layout targetLayout = getBoundaryEventTargetLayout(attachOrientation, targetOrientation, attachedToSide); return [sourceLayout + ':' + targetLayout]; } function getBoundaryEventLoopLayout(attachOrientation, attachedToSide, source, target, end) { var orientation = attachedToSide ? attachOrientation : getVerticalOrientation(attachOrientation), sourceLayout = orientationDirectionMapping[orientation], targetLayout; if (attachedToSide) { if (isHorizontalOrientation(attachOrientation)) { targetLayout = shouldConnectToSameSide('y', source, target, end) ? 'h' : 'b'; } else { targetLayout = shouldConnectToSameSide('x', source, target, end) ? 'v' : 'l'; } } else { targetLayout = 'v'; } return [sourceLayout + ':' + targetLayout]; } function shouldConnectToSameSide(axis, source, target, end) { var threshold = BOUNDARY_TO_HOST_THRESHOLD; return !(areCloseOnAxis(axis, end, target, threshold) || areCloseOnAxis(axis, end, { x: target.x + target.width, y: target.y + target.height }, threshold) || areCloseOnAxis(axis, end, (0, _LayoutUtil.getMid)(source), threshold)); } function areCloseOnAxis(axis, a, b, threshold) { return Math.abs(a[axis] - b[axis]) < threshold; } function getBoundaryEventSourceLayout(attachOrientation, targetOrientation, attachedToSide) { // attached to either top, right, bottom or left side if (attachedToSide) { return orientationDirectionMapping[attachOrientation]; } // attached to either top-right, top-left, bottom-right or bottom-left corner // same vertical or opposite horizontal orientation if (isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) || isOppositeOrientation(getHorizontalOrientation(attachOrientation), getHorizontalOrientation(targetOrientation))) { return orientationDirectionMapping[getVerticalOrientation(attachOrientation)]; } // fallback return orientationDirectionMapping[getHorizontalOrientation(attachOrientation)]; } function getBoundaryEventTargetLayout(attachOrientation, targetOrientation, attachedToSide) { // attached to either top, right, bottom or left side if (attachedToSide) { if (isHorizontalOrientation(attachOrientation)) { // orientation is right or left // opposite horizontal orientation or same orientation if (isOppositeHorizontalOrientation(attachOrientation, targetOrientation) || isSame(attachOrientation, targetOrientation)) { return 'h'; } // fallback return 'v'; } else { // orientation is top or bottom // opposite vertical orientation or same orientation if (isOppositeVerticalOrientation(attachOrientation, targetOrientation) || isSame(attachOrientation, targetOrientation)) { return 'v'; } // fallback return 'h'; } } // 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)) { return 'h'; } else { return 'v'; } } },{"../../util/DiUtil":139,"../../util/ModelUtil":141,"diagram-js/lib/layout/BaseLayouter":298,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/layout/ManhattanLayout":301,"inherits":347,"min-dash":555}],58:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnUpdater; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _Collections = require("diagram-js/lib/util/Collections"); var _model = require("diagram-js/lib/model"); var _ModelUtil = require("../../util/ModelUtil"); var _ModelingUtil = require("./util/ModelingUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/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) { _CommandInterceptor.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, hints = context.hints || {}, connection; if (!context.cropped && hints.createElementsBehavior !== false) { connection = context.connection; connection.waypoints = connectionDocking.getCroppedWaypoints(connection); context.cropped = true; } } this.executed(['connection.layout', 'connection.create'], 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.reconnect'], ifBpmn(updateConnection)); this.reverted(['connection.create', 'connection.move', 'connection.delete', 'connection.reconnect'], ifBpmn(updateConnection)); // update waypoints function updateConnectionWaypoints(e) { self.updateConnectionWaypoints(e.context.connection); } this.executed(['connection.layout', 'connection.move', 'connection.updateWaypoints'], ifBpmn(updateConnectionWaypoints)); this.reverted(['connection.layout', 'connection.move', 'connection.updateWaypoints'], ifBpmn(updateConnectionWaypoints)); // update conditional/default flows this.executed('connection.reconnect', ifBpmn(function (event) { var context = event.context, connection = context.connection, oldSource = context.oldSource, newSource = context.newSource, connectionBo = (0, _ModelUtil.getBusinessObject)(connection), oldSourceBo = (0, _ModelUtil.getBusinessObject)(oldSource), newSourceBo = (0, _ModelUtil.getBusinessObject)(newSource); // remove condition from connection on reconnect to new source // if new source can NOT have condional sequence flow if (connectionBo.conditionExpression && !(0, _ModelingUtil.isAny)(newSourceBo, ['bpmn:Activity', 'bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway'])) { context.oldConditionExpression = connectionBo.conditionExpression; delete connectionBo.conditionExpression; } // remove default from old source flow on reconnect to new source // if source changed if (oldSource !== newSource && oldSourceBo.default === connectionBo) { context.oldDefault = oldSourceBo.default; delete oldSourceBo.default; } })); this.reverted('connection.reconnect', ifBpmn(function (event) { var context = event.context, connection = context.connection, oldSource = context.oldSource, newSource = context.newSource, connectionBo = (0, _ModelUtil.getBusinessObject)(connection), oldSourceBo = (0, _ModelUtil.getBusinessObject)(oldSource), newSourceBo = (0, _ModelUtil.getBusinessObject)(newSource); // add condition to connection on revert reconnect to new source if (context.oldConditionExpression) { connectionBo.conditionExpression = context.oldConditionExpression; } // add default to old source on revert reconnect to new source if (context.oldDefault) { oldSourceBo.default = context.oldDefault; delete newSourceBo.default; } })); // update attachments function updateAttachment(e) { self.updateAttachment(e.context); } this.executed(['element.updateAttachment'], ifBpmn(updateAttachment)); this.reverted(['element.updateAttachment'], ifBpmn(updateAttachment)); } (0, _inherits.default)(BpmnUpdater, _CommandInterceptor.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 separately 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:DataInput') || (0, _ModelUtil.is)(businessObject, 'bpmn:DataOutput')) { if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant') && 'processRef' in newParent) { newParent = newParent.processRef; } // already in correct ioSpecification if ('ioSpecification' in newParent && newParent.ioSpecification === businessObject.$parent) { 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, visualParent); } 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":141,"./util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/model":302,"diagram-js/lib/util/Collections":313,"inherits":347,"min-dash":555}],59:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ElementFactory; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../util/ModelUtil"); var _DiUtil = require("../../util/DiUtil"); var _ElementFactory = _interopRequireDefault(require("diagram-js/lib/core/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) { _ElementFactory.default.call(this); this._bpmnFactory = bpmnFactory; this._moddle = moddle; this._translate = translate; } (0, _inherits.default)(ElementFactory, _ElementFactory.default); ElementFactory.$inject = ['bpmnFactory', 'moddle', 'translate']; ElementFactory.prototype.baseCreate = _ElementFactory.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 ((0, _ModelUtil.is)(businessObject, 'bpmn:Group')) { attrs = (0, _minDash.assign)({ isFrame: true }, attrs); } if (attrs.di) { (0, _minDash.assign)(businessObject.di, attrs.di); delete attrs.di; } 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._bpmnFactory.create(attrs.eventDefinitionType, attrs.eventDefinitionAttrs); if (attrs.eventDefinitionType === 'bpmn:ConditionalEventDefinition') { newEventDefinition.condition = this._bpmnFactory.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: 600, height: 250 }; } else { return { width: 400, height: 60 }; } } 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 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Group')) { return { width: 300, height: 300 }; } return { width: 100, height: 80 }; }; /** * Create participant. * * @param {boolean|Object} [attrs] attrs * * @returns {djs.model.Shape} */ ElementFactory.prototype.createParticipantShape = function (attrs) { if (!(0, _minDash.isObject)(attrs)) { attrs = { isExpanded: attrs }; } attrs = (0, _minDash.assign)({ type: 'bpmn:Participant' }, attrs || {}); // participants are expanded by default if (attrs.isExpanded !== false) { 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":139,"../../util/LabelUtil":140,"../../util/ModelUtil":141,"diagram-js/lib/core/ElementFactory":149,"inherits":347,"min-dash":555}],60:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Modeling; var _inherits = _interopRequireDefault(require("inherits")); var _Modeling = _interopRequireDefault(require("diagram-js/lib/features/modeling/Modeling")); var _UpdatePropertiesHandler = _interopRequireDefault(require("./cmd/UpdatePropertiesHandler")); var _UpdateCanvasRootHandler = _interopRequireDefault(require("./cmd/UpdateCanvasRootHandler")); var _AddLaneHandler = _interopRequireDefault(require("./cmd/AddLaneHandler")); var _SplitLaneHandler = _interopRequireDefault(require("./cmd/SplitLaneHandler")); var _ResizeLaneHandler = _interopRequireDefault(require("./cmd/ResizeLaneHandler")); var _UpdateFlowNodeRefsHandler = _interopRequireDefault(require("./cmd/UpdateFlowNodeRefsHandler")); var _IdClaimHandler = _interopRequireDefault(require("./cmd/IdClaimHandler")); var _SetColorHandler = _interopRequireDefault(require("./cmd/SetColorHandler")); var _UpdateLabelHandler = _interopRequireDefault(require("../label-editing/cmd/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) { _Modeling.default.call(this, eventBus, elementFactory, commandStack); this._bpmnRules = bpmnRules; } (0, _inherits.default)(Modeling, _Modeling.default); Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack', 'bpmnRules']; Modeling.prototype.getHandlers = function () { var handlers = _Modeling.default.prototype.getHandlers.call(this); handlers['element.updateProperties'] = _UpdatePropertiesHandler.default; handlers['canvas.updateRoot'] = _UpdateCanvasRootHandler.default; handlers['lane.add'] = _AddLaneHandler.default; handlers['lane.resize'] = _ResizeLaneHandler.default; handlers['lane.split'] = _SplitLaneHandler.default; handlers['lane.updateRefs'] = _UpdateFlowNodeRefsHandler.default; handlers['id.updateClaim'] = _IdClaimHandler.default; handlers['element.setColor'] = _SetColorHandler.default; handlers['element.updateLabel'] = _UpdateLabelHandler.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":54,"./cmd/AddLaneHandler":101,"./cmd/IdClaimHandler":102,"./cmd/ResizeLaneHandler":103,"./cmd/SetColorHandler":104,"./cmd/SplitLaneHandler":105,"./cmd/UpdateCanvasRootHandler":106,"./cmd/UpdateFlowNodeRefsHandler":107,"./cmd/UpdatePropertiesHandler":108,"diagram-js/lib/features/modeling/Modeling":222,"inherits":347}],61:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AdaptiveLabelPositioningBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _Math = require("diagram-js/lib/util/Math"); var _LabelUtil = require("../../../util/LabelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var ALIGNMENTS = ['top', 'bottom', 'left', 'right']; var ELEMENT_LABEL_DISTANCE = 10; /** * 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) { _CommandInterceptor.default.call(this, eventBus); this.postExecuted(['connection.create', 'connection.layout', 'connection.updateWaypoints'], function (event) { var context = event.context, connection = context.connection, source = connection.source, target = connection.target, hints = context.hints || {}; if (hints.createElementsBehavior !== false) { checkLabelAdjustment(source); checkLabelAdjustment(target); } }); this.postExecuted(['label.create'], function (event) { var context = event.context, shape = context.shape, hints = context.hints || {}; if (hints.createElementsBehavior !== false) { checkLabelAdjustment(shape.labelTarget); } }); this.postExecuted(['elements.create'], function (event) { var context = event.context, elements = context.elements, hints = context.hints || {}; if (hints.createElementsBehavior !== false) { elements.forEach(function (element) { checkLabelAdjustment(element); }); } }); 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); } function adjustLabelPosition(element, orientation) { var elementMid = (0, _LayoutUtil.getMid)(element), label = element.label, labelMid = (0, _LayoutUtil.getMid)(label); // ignore labels that are being created if (!label.parent) { return; } 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, _inherits.default)(AdaptiveLabelPositioningBehavior, _CommandInterceptor.default); AdaptiveLabelPositioningBehavior.$inject = ['eventBus', 'modeling']; // helpers ////////////////////// /** * Return alignments which are taken by a boundary's host element * * @param {Shape} element * * @return {Array} */ function getTakenHostAlignments(element) { var hostElement = element.host, elementMid = (0, _LayoutUtil.getMid)(element), hostOrientation = (0, _LayoutUtil.getOrientation)(elementMid, hostElement); var freeAlignments; // check whether there is a multi-orientation, e.g. 'top-left' if (hostOrientation.indexOf('-') >= 0) { freeAlignments = hostOrientation.split('-'); } else { freeAlignments = [hostOrientation]; } var takenAlignments = ALIGNMENTS.filter(function (alignment) { return freeAlignments.indexOf(alignment) === -1; }); return takenAlignments; } /** * Return alignments which are taken by related connections * * @param {Shape} element * * @return {Array} */ function getTakenConnectionAlignments(element) { var elementMid = (0, _LayoutUtil.getMid)(element); 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); }); return takenAlignments; } /** * 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 = getTakenConnectionAlignments(element); if (element.host) { var takenHostAlignments = getTakenHostAlignments(element); takenAlignments = takenAlignments.concat(takenHostAlignments); } 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]; } function getApproximateOrientation(p0, p1) { return (0, _LayoutUtil.getOrientation)(p1, p0, 5); } function isAligned(orientation) { return ALIGNMENTS.indexOf(orientation) !== -1; } },{"../../../util/LabelUtil":140,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Math":322,"inherits":347}],62:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AppendBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function AppendBehavior(eventBus, elementFactory, bpmnRules) { _CommandInterceptor.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, _inherits.default)(AppendBehavior, _CommandInterceptor.default); AppendBehavior.$inject = ['eventBus', 'elementFactory', 'bpmnRules']; },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],63:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AssociationBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function AssociationBehavior(injector, modeling) { injector.invoke(_CommandInterceptor.default, this); this.postExecute('shape.move', function (context) { var newParent = context.newParent, shape = context.shape; var associations = (0, _minDash.filter)(shape.incoming.concat(shape.outgoing), function (connection) { return (0, _ModelUtil.is)(connection, 'bpmn:Association'); }); (0, _minDash.forEach)(associations, function (association) { modeling.moveConnection(association, { x: 0, y: 0 }, newParent); }); }, true); } (0, _inherits.default)(AssociationBehavior, _CommandInterceptor.default); AssociationBehavior.$inject = ['injector', 'modeling']; },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],64:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AttachEventBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); var _LabelUtil = require("../../../util/LabelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; /** * Replace intermediate event with boundary event when creating or moving results in attached event. */ function AttachEventBehavior(bpmnReplace, injector) { injector.invoke(_CommandInterceptor.default, this); this._bpmnReplace = bpmnReplace; var self = this; this.postExecuted('elements.create', LOW_PRIORITY, function (context) { var elements = context.elements; elements = elements.filter(function (shape) { var host = shape.host; return shouldReplace(shape, host); }); if (elements.length !== 1) { return; } elements.map(function (element) { return elements.indexOf(element); }).forEach(function (index) { var host = elements[index]; context.elements[index] = self.replaceShape(elements[index], host); }); }, true); this.preExecute('elements.move', LOW_PRIORITY, function (context) { var shapes = context.shapes, host = context.newHost; if (shapes.length !== 1) { return; } var shape = shapes[0]; if (shouldReplace(shape, host)) { context.shapes = [self.replaceShape(shape, host)]; } }, true); } AttachEventBehavior.$inject = ['bpmnReplace', 'injector']; (0, _inherits.default)(AttachEventBehavior, _CommandInterceptor.default); AttachEventBehavior.prototype.replaceShape = function (shape, host) { var eventDefinition = getEventDefinition(shape); var boundaryEvent = { type: 'bpmn:BoundaryEvent', host: host }; if (eventDefinition) { boundaryEvent.eventDefinitionType = eventDefinition.$type; } return this._bpmnReplace.replaceElement(shape, boundaryEvent, { layoutConnection: false }); }; // helpers ////////// function getEventDefinition(element) { var businessObject = (0, _ModelUtil.getBusinessObject)(element), eventDefinitions = businessObject.eventDefinitions; return eventDefinitions && eventDefinitions[0]; } function shouldReplace(shape, host) { return !(0, _LabelUtil.isLabel)(shape) && (0, _ModelingUtil.isAny)(shape, ['bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent']) && !!host; } },{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],65:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BoundaryEventBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/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) { _CommandInterceptor.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.reconnect', 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, _inherits.default)(BoundaryEventBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],66:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelingUtil = require("../util/ModelingUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function CreateBehavior(injector) { injector.invoke(_CommandInterceptor.default, this); this.preExecute('shape.create', 1500, function (event) { var context = event.context, parent = context.parent, shape = context.shape; if ((0, _ModelUtil.is)(parent, 'bpmn:Lane') && !(0, _ModelUtil.is)(shape, 'bpmn:Lane')) { context.parent = (0, _ModelingUtil.getParent)(parent, 'bpmn:Participant'); } }); } CreateBehavior.$inject = ['injector']; (0, _inherits.default)(CreateBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],67:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateDataObjectBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/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) { _CommandInterceptor.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, _inherits.default)(CreateDataObjectBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],68:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateParticipantBehavior; exports.PARTICIPANT_BORDER_WIDTH = void 0; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _LabelUtil = require("../../../util/LabelUtil"); var _Elements = require("diagram-js/lib/util/Elements"); var _minDash = require("min-dash"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HORIZONTAL_PARTICIPANT_PADDING = 20, VERTICAL_PARTICIPANT_PADDING = 20; var PARTICIPANT_BORDER_WIDTH = 30; exports.PARTICIPANT_BORDER_WIDTH = PARTICIPANT_BORDER_WIDTH; var HIGH_PRIORITY = 2000; /** * BPMN-specific behavior for creating participants. */ function CreateParticipantBehavior(canvas, eventBus, modeling) { _CommandInterceptor.default.call(this, eventBus); // fit participant eventBus.on(['create.start', 'shape.move.start'], HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(); if (!(0, _ModelUtil.is)(shape, 'bpmn:Participant') || !(0, _ModelUtil.is)(rootElement, 'bpmn:Process') || !rootElement.children.length) { return; } // ignore connections, groups and labels var children = rootElement.children.filter(function (element) { return !(0, _ModelUtil.is)(element, 'bpmn:Group') && !(0, _LabelUtil.isLabel)(element) && !isConnection(element); }); // ensure for available children to calculate bounds if (!children.length) { return; } var childrenBBox = (0, _Elements.getBBox)(children); var participantBounds = getParticipantBounds(shape, childrenBBox); // assign width and height (0, _minDash.assign)(shape, participantBounds); // assign create constraints context.createConstraints = getParticipantCreateConstraints(shape, childrenBBox); }); // force hovering process when creating first participant eventBus.on('create.start', HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(), rootElementGfx = canvas.getGraphics(rootElement); function ensureHoveringProcess(event) { event.element = rootElement; event.gfx = rootElementGfx; } if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(rootElement, 'bpmn:Process')) { eventBus.on('element.hover', HIGH_PRIORITY, ensureHoveringProcess); eventBus.once('create.cleanup', function () { eventBus.off('element.hover', ensureHoveringProcess); }); } }); function ensureCollaboration(context) { var parent = context.parent, collaboration; var rootElement = canvas.getRootElement(); if ((0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) { collaboration = rootElement; } else { // update root element by making collaboration collaboration = modeling.makeCollaboration(); // re-use process when creating first participant context.process = parent; } context.parent = collaboration; } // turn process into collaboration before adding participant this.preExecute('shape.create', function (context) { var parent = context.parent, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(parent, 'bpmn:Process')) { ensureCollaboration(context); } }, true); this.execute('shape.create', function (context) { var process = context.process, shape = context.shape; if (process) { context.oldProcessRef = shape.businessObject.processRef; // re-use process when creating first participant shape.businessObject.processRef = process.businessObject; } }, true); this.revert('shape.create', function (context) { var process = context.process, shape = context.shape; if (process) { // re-use process when creating first participant shape.businessObject.processRef = context.oldProcessRef; } }, true); this.postExecute('shape.create', function (context) { var process = context.process, shape = context.shape; if (process) { // move children from process to participant var processChildren = process.children.slice(); modeling.moveElements(processChildren, { x: 0, y: 0 }, shape); } }, true); // turn process into collaboration when creating participants this.preExecute('elements.create', HIGH_PRIORITY, function (context) { var elements = context.elements, parent = context.parent, participant; var hasParticipants = findParticipant(elements); if (hasParticipants && (0, _ModelUtil.is)(parent, 'bpmn:Process')) { ensureCollaboration(context); participant = findParticipant(elements); context.oldProcessRef = participant.businessObject.processRef; // re-use process when creating first participant participant.businessObject.processRef = parent.businessObject; } }, true); this.revert('elements.create', function (context) { var elements = context.elements, process = context.process, participant; if (process) { participant = findParticipant(elements); // re-use process when creating first participant participant.businessObject.processRef = context.oldProcessRef; } }, true); this.postExecute('elements.create', function (context) { var elements = context.elements, process = context.process, participant; if (process) { participant = findParticipant(elements); // move children from process to first participant var processChildren = process.children.slice(); modeling.moveElements(processChildren, { x: 0, y: 0 }, participant); } }, true); } CreateParticipantBehavior.$inject = ['canvas', 'eventBus', 'modeling']; (0, _inherits.default)(CreateParticipantBehavior, _CommandInterceptor.default); // helpers ////////// function getParticipantBounds(shape, childrenBBox) { childrenBBox = { width: childrenBBox.width + HORIZONTAL_PARTICIPANT_PADDING * 2 + PARTICIPANT_BORDER_WIDTH, height: childrenBBox.height + VERTICAL_PARTICIPANT_PADDING * 2 }; var width = Math.max(shape.width, childrenBBox.width), height = Math.max(shape.height, childrenBBox.height); return { x: -width / 2, y: -height / 2, width: width, height: height }; } function getParticipantCreateConstraints(shape, childrenBBox) { childrenBBox = (0, _LayoutUtil.asTRBL)(childrenBBox); return { bottom: childrenBBox.top + shape.height / 2 - VERTICAL_PARTICIPANT_PADDING, left: childrenBBox.right - shape.width / 2 + HORIZONTAL_PARTICIPANT_PADDING, top: childrenBBox.bottom - shape.height / 2 + VERTICAL_PARTICIPANT_PADDING, right: childrenBBox.left + shape.width / 2 - HORIZONTAL_PARTICIPANT_PADDING - PARTICIPANT_BORDER_WIDTH }; } function isConnection(element) { return !!element.waypoints; } function findParticipant(elements) { return (0, _minDash.find)(elements, function (element) { return (0, _ModelUtil.is)(element, 'bpmn:Participant'); }); } },{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Elements":315,"inherits":347,"min-dash":555}],69:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DataInputAssociationBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/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) { _CommandInterceptor.default.call(this, eventBus); this.executed(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnect'], ifDataInputAssociation(fixTargetRef)); this.reverted(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnect'], 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, _inherits.default)(DataInputAssociationBehavior, _CommandInterceptor.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":141,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Collections":313,"inherits":347,"min-dash":555}],70:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DataStoreBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); var _UpdateSemanticParentHandler = _interopRequireDefault(require("../cmd/UpdateSemanticParentHandler")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific data store behavior */ function DataStoreBehavior(canvas, commandStack, elementRegistry, eventBus) { _CommandInterceptor.default.call(this, eventBus); commandStack.registerHandler('dataStore.updateContainment', _UpdateSemanticParentHandler.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, _inherits.default)(DataStoreBehavior, _CommandInterceptor.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":141,"../cmd/UpdateSemanticParentHandler":109,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],71:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteLaneBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/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) { _CommandInterceptor.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, _inherits.default)(DeleteLaneBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Elements":315,"inherits":347}],72:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DetachEventBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _LabelUtil = require("../../../util/LabelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; /** * Replace boundary event with intermediate event when creating or moving results in detached event. */ function DetachEventBehavior(bpmnReplace, injector) { injector.invoke(_CommandInterceptor.default, this); this._bpmnReplace = bpmnReplace; var self = this; this.postExecuted('elements.create', LOW_PRIORITY, function (context) { var elements = context.elements; elements.filter(function (shape) { var host = shape.host; return shouldReplace(shape, host); }).map(function (shape) { return elements.indexOf(shape); }).forEach(function (index) { context.elements[index] = self.replaceShape(elements[index]); }); }, true); this.preExecute('elements.move', LOW_PRIORITY, function (context) { var shapes = context.shapes, newHost = context.newHost; shapes.forEach(function (shape, index) { var host = shape.host; if (shouldReplace(shape, includes(shapes, host) ? host : newHost)) { shapes[index] = self.replaceShape(shape); } }); }, true); } DetachEventBehavior.$inject = ['bpmnReplace', 'injector']; (0, _inherits.default)(DetachEventBehavior, _CommandInterceptor.default); DetachEventBehavior.prototype.replaceShape = function (shape) { var eventDefinition = getEventDefinition(shape), intermediateEvent; if (eventDefinition) { intermediateEvent = { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: eventDefinition.$type }; } else { intermediateEvent = { type: 'bpmn:IntermediateThrowEvent' }; } return this._bpmnReplace.replaceElement(shape, intermediateEvent, { layoutConnection: false }); }; // helpers ////////// function getEventDefinition(element) { var businessObject = (0, _ModelUtil.getBusinessObject)(element), eventDefinitions = businessObject.eventDefinitions; return eventDefinitions && eventDefinitions[0]; } function shouldReplace(shape, host) { return !(0, _LabelUtil.isLabel)(shape) && (0, _ModelUtil.is)(shape, 'bpmn:BoundaryEvent') && !host; } function includes(array, item) { return array.indexOf(item) !== -1; } },{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],73:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DropOnFlowBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _LineIntersection = require("diagram-js/lib/util/LineIntersection"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function DropOnFlowBehavior(eventBus, bpmnRules, modeling) { _CommandInterceptor.default.call(this, eventBus); /** * Reconnect start / end of a connection after * dropping an element on a flow. */ function insertShape(shape, targetFlow, positionOrBounds) { var waypoints = targetFlow.waypoints, waypointsBefore, waypointsAfter, dockingPoint, source, target, incomingConnection, outgoingConnection, oldOutgoing = shape.outgoing.slice(), oldIncoming = shape.incoming.slice(); var mid; if ((0, _minDash.isNumber)(positionOrBounds.width)) { mid = (0, _LayoutUtil.getMid)(positionOrBounds); } else { mid = positionOrBounds; } var intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, mid); 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] : mid; // 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 || mid); incomingConnection = targetFlow; } if (bpmnRules.canConnect(shape, target, targetFlow)) { if (!incomingConnection) { // reconnect inserted shape -> end modeling.reconnectStart(targetFlow, shape, waypointsAfter || mid); 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.target === outgoingConnection.target; }) || []); 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 = (0, _LayoutUtil.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, positionOrBounds = context.position; if (targetFlow) { insertShape(shape, targetFlow, positionOrBounds); } }, true); } (0, _inherits.default)(DropOnFlowBehavior, _CommandInterceptor.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); } },{"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/LineIntersection":321,"inherits":347,"min-dash":555}],74:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = EventBasedGatewayBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function EventBasedGatewayBehavior(eventBus, modeling) { _CommandInterceptor.default.call(this, eventBus); /** * Remove existing sequence flows of event-based target before connecting * from event-based gateway. */ this.preExecuted('connection.create', function (event) { var context = event.context, source = context.source, target = context.target, existingIncomingConnections = target.incoming.slice(); if (context.hints && context.hints.createElementsBehavior === false) { return; } if ((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && target.incoming.length) { existingIncomingConnections.filter(isSequenceFlow).forEach(function (sequenceFlow) { modeling.removeConnection(sequenceFlow); }); } }); /** * After replacing shape with event-based gateway, remove incoming sequence * flows of event-based targets which do not belong to event-based gateway * source. */ this.preExecuted('shape.replace', function (event) { var newShape = event.context.newShape, newShapeTargets, newShapeTargetsIncomingSequenceFlows; if (!(0, _ModelUtil.is)(newShape, 'bpmn:EventBasedGateway')) { return; } newShapeTargets = newShape.outgoing.filter(isSequenceFlow).map(function (sequenceFlow) { return sequenceFlow.target; }); newShapeTargetsIncomingSequenceFlows = newShapeTargets.reduce(function (sequenceFlows, target) { var incomingSequenceFlows = target.incoming.filter(isSequenceFlow); return sequenceFlows.concat(incomingSequenceFlows); }, []); newShapeTargetsIncomingSequenceFlows.forEach(function (sequenceFlow) { if (sequenceFlow.source !== newShape) { modeling.removeConnection(sequenceFlow); } }); }); } EventBasedGatewayBehavior.$inject = ['eventBus', 'modeling']; (0, _inherits.default)(EventBasedGatewayBehavior, _CommandInterceptor.default); // helpers ////////////////////// function isSequenceFlow(connection) { return (0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow'); } },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],75:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = FixHoverBehavior; var _LaneUtil = require("../util/LaneUtil"); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); var HIGH_PRIORITY = 1500; var HIGHEST_PRIORITY = 2000; /** * Correct hover targets in certain situations to improve diagram interaction. * * @param {ElementRegistry} elementRegistry * @param {EventBus} eventBus * @param {Canvas} canvas */ function FixHoverBehavior(elementRegistry, eventBus, canvas) { eventBus.on(['create.hover', 'create.move', 'create.end', 'shape.move.hover', 'shape.move.move', 'shape.move.end'], HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape || event.shape, hover = event.hover; // ensure elements are not dropped onto a bpmn:Lane but onto // the underlying bpmn:Participant 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); } var rootElement = canvas.getRootElement(); // ensure bpmn:Group and label elements are dropped // always onto the root if (hover !== rootElement && (shape.labelTarget || (0, _ModelUtil.is)(shape, 'bpmn:Group'))) { event.hover = rootElement; event.hoverGfx = elementRegistry.getGraphics(event.hover); } }); eventBus.on(['connect.hover', 'connect.out', 'connect.end', 'connect.cleanup', 'global-connect.hover', 'global-connect.out', 'global-connect.end', 'global-connect.cleanup'], HIGH_PRIORITY, function (event) { var hover = event.hover; // ensure connections start/end on bpmn:Participant, // not the underlying bpmn:Lane if ((0, _ModelUtil.is)(hover, 'bpmn:Lane')) { event.hover = (0, _LaneUtil.getLanesRoot)(hover) || hover; event.hoverGfx = elementRegistry.getGraphics(event.hover); } }); eventBus.on(['bendpoint.move.hover'], HIGH_PRIORITY, function (event) { var context = event.context, hover = event.hover, type = context.type; // ensure reconnect start/end on bpmn:Participant, // not the underlying bpmn:Lane if ((0, _ModelUtil.is)(hover, 'bpmn:Lane') && /reconnect/.test(type)) { event.hover = (0, _LaneUtil.getLanesRoot)(hover) || hover; event.hoverGfx = elementRegistry.getGraphics(event.hover); } }); eventBus.on(['connect.start'], HIGH_PRIORITY, function (event) { var context = event.context, start = context.start; // ensure connect start on bpmn:Participant, // not the underlying bpmn:Lane if ((0, _ModelUtil.is)(start, 'bpmn:Lane')) { context.start = (0, _LaneUtil.getLanesRoot)(start) || start; } }); // allow movement of participants from lanes eventBus.on('shape.move.start', HIGHEST_PRIORITY, function (event) { var shape = event.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) { event.shape = (0, _LaneUtil.getLanesRoot)(shape) || shape; } }); } FixHoverBehavior.$inject = ['elementRegistry', 'eventBus', 'canvas']; },{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"../util/ModelingUtil":112}],76:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = GroupBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _Collections = require("diagram-js/lib/util/Collections"); var _ModelUtil = require("../../../util/ModelUtil"); var _CategoryUtil = require("./util/CategoryUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGH_PRIORITY = 2000; /** * BPMN specific Group behavior */ function GroupBehavior(bpmnFactory, canvas, elementRegistry, eventBus, injector, moddleCopy) { injector.invoke(_CommandInterceptor.default, this); /** * Gets process definitions * * @return {ModdleElement} definitions */ function getDefinitions() { var rootElement = canvas.getRootElement(), businessObject = (0, _ModelUtil.getBusinessObject)(rootElement); return businessObject.$parent; } /** * Removes a referenced category value for a given group shape * * @param {djs.model.Shape} shape */ function removeReferencedCategoryValue(shape) { var businessObject = (0, _ModelUtil.getBusinessObject)(shape), categoryValue = businessObject.categoryValueRef; if (!categoryValue) { return; } var category = categoryValue.$parent; if (!categoryValue) { return; } (0, _Collections.remove)(category.categoryValue, categoryValue); // cleanup category if it is empty if (category && !category.categoryValue.length) { removeCategory(category); } } /** * Removes a given category from the definitions * * @param {ModdleElement} category */ function removeCategory(category) { var definitions = getDefinitions(); (0, _Collections.remove)(definitions.get('rootElements'), category); } /** * Returns all group element in the current registry * * @return {Array} a list of group shapes */ function getGroupElements() { return elementRegistry.filter(function (e) { return (0, _ModelUtil.is)(e, 'bpmn:Group'); }); } /** * Returns true if given categoryValue is referenced in one of the given elements * * @param {Array} elements * @param {ModdleElement} categoryValue * @return {boolean} */ function isReferenced(elements, categoryValue) { return elements.some(function (e) { var businessObject = (0, _ModelUtil.getBusinessObject)(e); return businessObject.categoryValueRef && businessObject.categoryValueRef === categoryValue; }); } /** * remove referenced category + value when group was deleted */ this.executed('shape.delete', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Group')) { var businessObject = (0, _ModelUtil.getBusinessObject)(shape), categoryValueRef = businessObject.categoryValueRef, groupElements = getGroupElements(); if (!isReferenced(groupElements, categoryValueRef)) { removeReferencedCategoryValue(shape); } } }); /** * re-attach removed category */ this.reverted('shape.delete', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Group')) { var businessObject = (0, _ModelUtil.getBusinessObject)(shape), categoryValueRef = businessObject.categoryValueRef, definitions = getDefinitions(), category = categoryValueRef ? categoryValueRef.$parent : null; (0, _Collections.add)(category.get('categoryValue'), categoryValueRef); (0, _Collections.add)(definitions.get('rootElements'), category); } }); /** * create new category + value when group was created */ this.execute('shape.create', function (event) { var context = event.context, shape = context.shape, businessObject = (0, _ModelUtil.getBusinessObject)(shape); if ((0, _ModelUtil.is)(businessObject, 'bpmn:Group') && !businessObject.categoryValueRef) { var definitions = getDefinitions(), categoryValue = (0, _CategoryUtil.createCategoryValue)(definitions, bpmnFactory); // link the reference to the Group businessObject.categoryValueRef = categoryValue; } }); this.revert('shape.create', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Group')) { removeReferencedCategoryValue(shape); delete (0, _ModelUtil.getBusinessObject)(shape).categoryValueRef; } }); // copy bpmn:CategoryValue when copying element eventBus.on('moddleCopy.canCopyProperty', HIGH_PRIORITY, function (context) { var property = context.property, categoryValue; if ((0, _ModelUtil.is)(property, 'bpmn:CategoryValue')) { categoryValue = (0, _CategoryUtil.createCategoryValue)(getDefinitions(), bpmnFactory); // return copy of category return moddleCopy.copyElement(property, categoryValue); } }); } GroupBehavior.$inject = ['bpmnFactory', 'canvas', 'elementRegistry', 'eventBus', 'injector', 'moddleCopy']; (0, _inherits.default)(GroupBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"./util/CategoryUtil":95,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Collections":313,"inherits":347}],77:[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 = _interopRequireDefault(require("./util/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, _LineIntersect.default)(startPoint, nextPoint, elementMid, elementTop), horizontalIntersect = (0, _LineIntersect.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":99,"diagram-js/lib/layout/LayoutUtil":300}],78:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = IsHorizontalFix; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A component that makes sure that each created or updated * Pool and Lane is assigned an isHorizontal property set to true. * * @param {EventBus} eventBus */ function IsHorizontalFix(eventBus) { _CommandInterceptor.default.call(this, eventBus); var elementTypesToUpdate = ['bpmn:Participant', 'bpmn:Lane']; this.executed(['shape.move', 'shape.create', 'shape.resize'], function (event) { var bo = (0, _ModelUtil.getBusinessObject)(event.context.shape); if ((0, _ModelingUtil.isAny)(bo, elementTypesToUpdate) && !bo.di.get('isHorizontal')) { // set attribute directly to avoid modeling#updateProperty side effects bo.di.set('isHorizontal', true); } }); } IsHorizontalFix.$inject = ['eventBus']; (0, _inherits.default)(IsHorizontalFix, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],79:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelBehavior; exports.getReferencePointDelta = getReferencePointDelta; exports.getReferencePoint = getReferencePoint; exports.asEdges = asEdges; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _LabelUtil = require("../../../util/LabelUtil"); var _LabelUtil2 = require("../../label-editing/LabelUtil"); var _LabelLayoutUtil = require("./util/LabelLayoutUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _AttachUtil = require("diagram-js/lib/util/AttachUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _PositionUtil = require("diagram-js/lib/util/PositionUtil"); var _GeometricUtil = require("./util/GeometricUtil"); 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) { _CommandInterceptor.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, hints = context.hints || {}; if (hints.createElementsBehavior === false) { return; } var element = context.shape || context.connection, businessObject = element.businessObject; if ((0, _LabelUtil.isLabel)(element) || !(0, _LabelUtil.isLabelExternal)(element)) { return; } // only create label if attribute available if (!(0, _LabelUtil2.getLabel)(element)) { return; } var labelCenter = (0, _LabelUtil.getExternalLabelMid)(element); // we don't care about x and y var labelDimensions = textRenderer.getExternalLabelBounds(DEFAULT_LABEL_DIMENSIONS, (0, _LabelUtil2.getLabel)(element)); 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 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 = !!hints.connectionStart; } if (typeof hints.endChanged === 'undefined') { hints.endChanged = !!hints.connectionEnd; } return (0, _LabelLayoutUtil.getLabelAdjustment)(label, newWaypoints, oldWaypoints, hints); } this.postExecute(['connection.layout', 'connection.updateWaypoints'], function (event) { var context = event.context, hints = context.hints || {}; if (hints.labelBehavior === false) { return; } var connection = context.connection, label = connection.label, labelAdjustment; // handle missing label as well as the case // that the label parent does not exist (yet), // because it is being pasted / created via multi element create // // Cf. https://github.com/bpmn-io/bpmn-js/pull/1227 if (!label || !label.parent) { 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; } }); // move external label after resizing this.postExecute('shape.resize', function (event) { var context = event.context, shape = context.shape, newBounds = context.newBounds, oldBounds = context.oldBounds; if ((0, _LabelUtil.hasExternalLabel)(shape)) { var label = shape.label, labelMid = (0, _LayoutUtil.getMid)(label), edges = asEdges(oldBounds); // get nearest border point to label as reference point var referencePoint = getReferencePoint(labelMid, edges); var delta = getReferencePointDelta(referencePoint, oldBounds, newBounds); modeling.moveShape(label, delta); } }); } (0, _inherits.default)(LabelBehavior, _CommandInterceptor.default); LabelBehavior.$inject = ['eventBus', 'modeling', 'bpmnFactory', 'textRenderer']; // helpers ////////////////////// /** * Calculates a reference point delta relative to a new position * of a certain element's bounds * * @param {Point} point * @param {Bounds} oldBounds * @param {Bounds} newBounds * * @return {Delta} delta */ function getReferencePointDelta(referencePoint, oldBounds, newBounds) { var newReferencePoint = (0, _AttachUtil.getNewAttachPoint)(referencePoint, oldBounds, newBounds); return (0, _LayoutUtil.roundPoint)((0, _PositionUtil.delta)(newReferencePoint, referencePoint)); } /** * Generates the nearest point (reference point) for a given point * onto given set of lines * * @param {Array} lines * @param {Point} point * * @param {Point} */ function getReferencePoint(point, lines) { if (!lines.length) { return; } var nearestLine = getNearestLine(point, lines); return (0, _GeometricUtil.perpendicularFoot)(point, nearestLine); } /** * Convert the given bounds to a lines array containing all edges * * @param {Bounds|Point} bounds * * @return Array */ function asEdges(bounds) { return [[// top { x: bounds.x, y: bounds.y }, { x: bounds.x + (bounds.width || 0), y: bounds.y }], [// right { x: bounds.x + (bounds.width || 0), y: bounds.y }, { x: bounds.x + (bounds.width || 0), y: bounds.y + (bounds.height || 0) }], [// bottom { x: bounds.x, y: bounds.y + (bounds.height || 0) }, { x: bounds.x + (bounds.width || 0), y: bounds.y + (bounds.height || 0) }], [// left { x: bounds.x, y: bounds.y }, { x: bounds.x, y: bounds.y + (bounds.height || 0) }]]; } /** * Returns the nearest line for a given point by distance * @param {Point} point * @param Array lines * * @return Array */ function getNearestLine(point, lines) { var distances = lines.map(function (l) { return { line: l, distance: (0, _GeometricUtil.getDistancePointLine)(point, l) }; }); var sorted = (0, _minDash.sortBy)(distances, 'distance'); return sorted[0].line; } },{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"../../label-editing/LabelUtil":53,"./util/GeometricUtil":96,"./util/LabelLayoutUtil":97,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/AttachUtil":311,"diagram-js/lib/util/PositionUtil":325,"inherits":347,"min-dash":555}],80:[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":141}],81:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RemoveElementBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _LineIntersect = _interopRequireDefault(require("./util/LineIntersect")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function RemoveElementBehavior(eventBus, bpmnRules, modeling) { _CommandInterceptor.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, _inherits.default)(RemoveElementBehavior, _CommandInterceptor.default); RemoveElementBehavior.$inject = ['eventBus', 'bpmnRules', 'modeling']; // helpers ////////////////////// function getDocking(point) { return point.original || point; } function getNewWaypoints(inWaypoints, outWaypoints) { var intersection = (0, _LineIntersect.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":141,"./util/LineIntersect":99,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],82:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RemoveParticipantBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific remove behavior */ function RemoveParticipantBehavior(eventBus, modeling) { _CommandInterceptor.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, _inherits.default)(RemoveParticipantBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],83:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceConnectionBehavior; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function ReplaceConnectionBehavior(eventBus, modeling, bpmnRules, injector) { _CommandInterceptor.default.call(this, eventBus); var dragging = injector.get('dragging', false); 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() }); } } function replaceReconnectedConnection(event) { var context = event.context, connection = context.connection, source = context.newSource || connection.source, target = context.newTarget || connection.target, allowed, replacement; allowed = bpmnRules.canConnect(source, target); if (!allowed || allowed.type === connection.type) { return; } replacement = modeling.connect(source, target, { type: allowed.type, waypoints: connection.waypoints.slice() }); // remove old connection modeling.removeConnection(connection); // replace connection in context to reconnect end/start context.connection = replacement; if (dragging) { cleanDraggingSelection(connection, replacement); } } // monkey-patch selection saved in dragging in order to re-select it when operation is finished function cleanDraggingSelection(oldConnection, newConnection) { var context = dragging.context(), previousSelection = context && context.payload.previousSelection, index; // do nothing if not dragging or no selection was present if (!previousSelection || !previousSelection.length) { return; } index = previousSelection.indexOf(oldConnection); if (index === -1) { return; } previousSelection.splice(index, 1, newConnection); } // lifecycle hooks this.postExecuted('elements.move', function (context) { var closure = context.closure, allConnections = closure.allConnections; (0, _minDash.forEach)(allConnections, fixConnection); }, true); this.preExecute('connection.reconnect', replaceReconnectedConnection); this.postExecuted('element.updateProperties', function (event) { var context = event.context, properties = context.properties, element = context.element, businessObject = element.businessObject, connection; // remove condition on change to default 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 from source on change to conditional if (properties.conditionExpression && businessObject.sourceRef.default === businessObject) { modeling.updateProperties(element.source, { default: undefined }); } }); } (0, _inherits.default)(ReplaceConnectionBehavior, _CommandInterceptor.default); ReplaceConnectionBehavior.$inject = ['eventBus', 'modeling', 'bpmnRules', 'injector']; },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],84:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceElementBehaviour; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _DiUtil = require("../../../util/DiUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN-specific replace behavior. */ function ReplaceElementBehaviour(bpmnReplace, bpmnRules, elementRegistry, injector, modeling, selection) { injector.invoke(_CommandInterceptor.default, this); this._bpmnReplace = bpmnReplace; this._elementRegistry = elementRegistry; this._selection = selection; // replace elements on move 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); } }); // set target to host if attaching if (elements.length === 1 && newHost) { target = newHost; } var canReplace = bpmnRules.canReplace(elements, target); if (canReplace) { this.replaceElements(elements, canReplace.replacements, newHost); } }, this); // update attachments on host replace 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); // keep ID on shape replace 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, _inherits.default)(ReplaceElementBehaviour, _CommandInterceptor.default); ReplaceElementBehaviour.prototype.replaceElements = function (elements, newElements) { var elementRegistry = this._elementRegistry, bpmnReplace = this._bpmnReplace, selection = this._selection; (0, _minDash.forEach)(newElements, function (replacement) { var newElement = { type: replacement.newElementType }; var oldElement = elementRegistry.get(replacement.oldElementId); var idx = elements.indexOf(oldElement); elements[idx] = bpmnReplace.replaceElement(oldElement, newElement, { select: false }); }); if (newElements) { selection.select(elements); } }; ReplaceElementBehaviour.$inject = ['bpmnReplace', 'bpmnRules', 'elementRegistry', 'injector', 'modeling', 'selection']; },{"../../../util/DiUtil":139,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],85:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeBehavior; exports.TEXT_ANNOTATION_MIN_DIMENSIONS = exports.SUB_PROCESS_MIN_DIMENSIONS = exports.PARTICIPANT_MIN_DIMENSIONS = exports.LANE_MIN_DIMENSIONS = void 0; var _ModelUtil = require("../../../util/ModelUtil"); var _DiUtil = require("../../../util/DiUtil"); var _ResizeUtil = require("./util/ResizeUtil"); var HIGH_PRIORITY = 1500; var LANE_MIN_DIMENSIONS = { width: 300, height: 60 }; exports.LANE_MIN_DIMENSIONS = LANE_MIN_DIMENSIONS; var PARTICIPANT_MIN_DIMENSIONS = { width: 300, height: 150 }; exports.PARTICIPANT_MIN_DIMENSIONS = PARTICIPANT_MIN_DIMENSIONS; var SUB_PROCESS_MIN_DIMENSIONS = { width: 140, height: 120 }; exports.SUB_PROCESS_MIN_DIMENSIONS = SUB_PROCESS_MIN_DIMENSIONS; var TEXT_ANNOTATION_MIN_DIMENSIONS = { width: 50, height: 30 }; /** * Set minimum bounds/resize constraints on resize. * * @param {EventBus} eventBus */ exports.TEXT_ANNOTATION_MIN_DIMENSIONS = TEXT_ANNOTATION_MIN_DIMENSIONS; function ResizeBehavior(eventBus) { eventBus.on('resize.start', HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape, direction = context.direction, balanced = context.balanced; if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) { context.resizeConstraints = (0, _ResizeUtil.getParticipantResizeConstraints)(shape, direction, balanced); } if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { context.minDimensions = PARTICIPANT_MIN_DIMENSIONS; } if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(shape)) { context.minDimensions = SUB_PROCESS_MIN_DIMENSIONS; } if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) { context.minDimensions = TEXT_ANNOTATION_MIN_DIMENSIONS; } }); } ResizeBehavior.$inject = ['eventBus']; },{"../../../util/DiUtil":139,"../../../util/ModelUtil":141,"./util/ResizeUtil":100}],86:[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":141,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Mouse":323}],87:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RootElementReferenceBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _Collections = require("diagram-js/lib/util/Collections"); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); var _DiUtil = require("../../../util/DiUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; /** * Add referenced root elements (error, escalation, message, signal) if they don't exist. * Copy referenced root elements on copy & paste. */ function RootElementReferenceBehavior(bpmnjs, eventBus, injector, moddleCopy, bpmnFactory) { injector.invoke(_CommandInterceptor.default, this); function canHaveRootElementReference(element) { return (0, _ModelingUtil.isAny)(element, ['bpmn:ReceiveTask', 'bpmn:SendTask']) || hasAnyEventDefinition(element, ['bpmn:ErrorEventDefinition', 'bpmn:EscalationEventDefinition', 'bpmn:MessageEventDefinition', 'bpmn:SignalEventDefinition']); } function hasRootElement(rootElement) { var definitions = bpmnjs.getDefinitions(), rootElements = definitions.get('rootElements'); return !!(0, _minDash.find)(rootElements, (0, _minDash.matchPattern)({ id: rootElement.id })); } function getRootElementReferencePropertyName(eventDefinition) { if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:ErrorEventDefinition')) { return 'errorRef'; } else if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:EscalationEventDefinition')) { return 'escalationRef'; } else if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:MessageEventDefinition')) { return 'messageRef'; } else if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:SignalEventDefinition')) { return 'signalRef'; } } function getRootElement(businessObject) { if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:ReceiveTask', 'bpmn:SendTask'])) { return businessObject.get('messageRef'); } var eventDefinitions = businessObject.get('eventDefinitions'), eventDefinition = eventDefinitions[0]; return eventDefinition.get(getRootElementReferencePropertyName(eventDefinition)); } function setRootElement(businessObject, rootElement) { if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:ReceiveTask', 'bpmn:SendTask'])) { return businessObject.set('messageRef', rootElement); } var eventDefinitions = businessObject.get('eventDefinitions'), eventDefinition = eventDefinitions[0]; return eventDefinition.set(getRootElementReferencePropertyName(eventDefinition), rootElement); } // create shape this.executed('shape.create', function (context) { var shape = context.shape; if (!canHaveRootElementReference(shape)) { return; } var businessObject = (0, _ModelUtil.getBusinessObject)(shape), rootElement = getRootElement(businessObject), rootElements; if (rootElement && !hasRootElement(rootElement)) { rootElements = bpmnjs.getDefinitions().get('rootElements'); // add root element (0, _Collections.add)(rootElements, rootElement); context.addedRootElement = rootElement; } }, true); this.reverted('shape.create', function (context) { var addedRootElement = context.addedRootElement; if (!addedRootElement) { return; } var rootElements = bpmnjs.getDefinitions().get('rootElements'); // remove root element (0, _Collections.remove)(rootElements, addedRootElement); }, true); eventBus.on('copyPaste.copyElement', function (context) { var descriptor = context.descriptor, element = context.element; if (!canHaveRootElementReference(element)) { return; } var businessObject = (0, _ModelUtil.getBusinessObject)(element), rootElement = getRootElement(businessObject); if (rootElement) { descriptor.referencedRootElement = rootElement; } }); eventBus.on('copyPaste.pasteElement', LOW_PRIORITY, function (context) { var descriptor = context.descriptor, businessObject = descriptor.businessObject; if (!canHaveRootElementReference(businessObject)) { return; } var referencedRootElement = descriptor.referencedRootElement; if (!referencedRootElement) { return; } if (!hasRootElement(referencedRootElement)) { referencedRootElement = moddleCopy.copyElement(referencedRootElement, bpmnFactory.create(referencedRootElement.$type)); } setRootElement(businessObject, referencedRootElement); }); } RootElementReferenceBehavior.$inject = ['bpmnjs', 'eventBus', 'injector', 'moddleCopy', 'bpmnFactory']; (0, _inherits.default)(RootElementReferenceBehavior, _CommandInterceptor.default); // helpers ////////// function hasAnyEventDefinition(element, types) { if (!(0, _minDash.isArray)(types)) { types = [types]; } return (0, _minDash.some)(types, function (type) { return (0, _DiUtil.hasEventDefinition)(element, type); }); } },{"../../../util/DiUtil":139,"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Collections":313,"inherits":347,"min-dash":555}],88:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceToolBehavior; var _minDash = require("min-dash"); var _ModelUtil = require("../../../util/ModelUtil"); var _DiUtil = require("../../../util/DiUtil"); var _ResizeBehavior = require("./ResizeBehavior"); var _LaneUtil = require("../util/LaneUtil"); var max = Math.max; function SpaceToolBehavior(eventBus) { eventBus.on('spaceTool.getMinDimensions', function (context) { var shapes = context.shapes, axis = context.axis, start = context.start, minDimensions = {}; (0, _minDash.forEach)(shapes, function (shape) { var id = shape.id; if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { if (isHorizontal(axis)) { minDimensions[id] = _ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS; } else { minDimensions[id] = { width: _ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS.width, height: getParticipantMinHeight(shape, start) }; } } if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(shape)) { minDimensions[id] = _ResizeBehavior.SUB_PROCESS_MIN_DIMENSIONS; } if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) { minDimensions[id] = _ResizeBehavior.TEXT_ANNOTATION_MIN_DIMENSIONS; } }); return minDimensions; }); } SpaceToolBehavior.$inject = ['eventBus']; // helpers ////////// function isHorizontal(axis) { return axis === 'x'; } /** * Get minimum height for participant taking lanes into account. * * @param {} participant * @param {number} start * * @returns {Object} */ function getParticipantMinHeight(participant, start) { var lanesMinHeight; if (!hasChildLanes(participant)) { return _ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS.height; } lanesMinHeight = getLanesMinHeight(participant, start); return max(_ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS.height, lanesMinHeight); } function hasChildLanes(element) { return !!(0, _LaneUtil.getChildLanes)(element).length; } function getLanesMinHeight(participant, resizeStart) { var lanes = (0, _LaneUtil.getChildLanes)(participant), resizedLane; // find the nested lane which is currently resized resizedLane = findResizedLane(lanes, resizeStart); // resized lane cannot shrink below the minimum height // but remaining lanes' dimensions are kept intact return participant.height - resizedLane.height + _ResizeBehavior.LANE_MIN_DIMENSIONS.height; } /** * Find nested lane which is currently resized. * * @param {Array} lanes * @param {number} resizeStart */ function findResizedLane(lanes, resizeStart) { var i, lane, childLanes; for (i = 0; i < lanes.length; i++) { lane = lanes[i]; // resizing current lane or a lane nested if (resizeStart >= lane.y && resizeStart <= lane.y + lane.height) { childLanes = (0, _LaneUtil.getChildLanes)(lane); // a nested lane is resized if (childLanes.length) { return findResizedLane(childLanes, resizeStart); } // current lane is the resized one return lane; } } } },{"../../../util/DiUtil":139,"../../../util/ModelUtil":141,"../util/LaneUtil":111,"./ResizeBehavior":85,"min-dash":555}],89:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SubProcessStartEventBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _DiUtil = require("../../../util/DiUtil.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Add start event replacing element with expanded sub process. * * @param {Injector} injector * @param {Modeling} modeling */ function SubProcessStartEventBehavior(injector, modeling) { injector.invoke(_CommandInterceptor.default, this); this.postExecuted('shape.replace', function (event) { var oldShape = event.context.oldShape, newShape = event.context.newShape; if (!(0, _ModelUtil.is)(newShape, 'bpmn:SubProcess') || !(0, _ModelUtil.is)(oldShape, 'bpmn:Task') || !(0, _DiUtil.isExpanded)(newShape)) { return; } var position = getStartEventPosition(newShape); modeling.createShape({ type: 'bpmn:StartEvent' }, position, newShape); }); } SubProcessStartEventBehavior.$inject = ['injector', 'modeling']; (0, _inherits.default)(SubProcessStartEventBehavior, _CommandInterceptor.default); // helpers ////////// function getStartEventPosition(shape) { return { x: shape.x + shape.width / 6, y: shape.y + shape.height / 2 }; } },{"../../../util/DiUtil.js":139,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],90:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ToggleElementCollapseBehaviour; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/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) { _CommandInterceptor.default.call(this, eventBus); function hideEmptyLabels(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 hideEmptyLabels(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, null, { autoResize: shape.collapsed ? false : 'nwse' }); }); } (0, _inherits.default)(ToggleElementCollapseBehaviour, _CommandInterceptor.default); ToggleElementCollapseBehaviour.$inject = ['eventBus', 'elementFactory', 'modeling']; // helpers ////////////////////// function filterVisible(elements) { return elements.filter(function (e) { return !e.hidden; }); } },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/features/resize/ResizeUtil":268,"inherits":347}],91:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UnclaimIdBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _DiUtil = require("../../../util/DiUtil"); var _LabelUtil = require("../../../util/LabelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Unclaims model IDs on element deletion. * * @param {Canvas} canvas * @param {Injector} injector * @param {Moddle} moddle * @param {Modeling} modeling */ function UnclaimIdBehavior(canvas, injector, moddle, modeling) { injector.invoke(_CommandInterceptor.default, this); this.preExecute('shape.delete', function (event) { var context = event.context, shape = context.shape, shapeBo = shape.businessObject; if ((0, _LabelUtil.isLabel)(shape)) { return; } if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _DiUtil.isExpanded)(shape)) { moddle.ids.unclaim(shapeBo.processRef.id); } modeling.unclaimId(shapeBo.id, shapeBo); }); this.preExecute('connection.delete', function (event) { var context = event.context, connection = context.connection, connectionBo = connection.businessObject; modeling.unclaimId(connectionBo.id, connectionBo); }); this.preExecute('canvas.updateRoot', function () { var rootElement = canvas.getRootElement(), rootElementBo = rootElement.businessObject; moddle.ids.unclaim(rootElementBo.id); }); } (0, _inherits.default)(UnclaimIdBehavior, _CommandInterceptor.default); UnclaimIdBehavior.$inject = ['canvas', 'injector', 'moddle', 'modeling']; },{"../../../util/DiUtil":139,"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],92:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteSequenceFlowBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/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) { _CommandInterceptor.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, _inherits.default)(DeleteSequenceFlowBehavior, _CommandInterceptor.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":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],93:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateFlowNodeRefsBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/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) { _CommandInterceptor.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.create', 'elements.delete', 'elements.move', '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, _inherits.default)(UpdateFlowNodeRefsBehavior, _CommandInterceptor.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":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],94:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _AdaptiveLabelPositioningBehavior = _interopRequireDefault(require("./AdaptiveLabelPositioningBehavior")); var _AppendBehavior = _interopRequireDefault(require("./AppendBehavior")); var _AssociationBehavior = _interopRequireDefault(require("./AssociationBehavior")); var _AttachEventBehavior = _interopRequireDefault(require("./AttachEventBehavior")); var _BoundaryEventBehavior = _interopRequireDefault(require("./BoundaryEventBehavior")); var _RootElementReferenceBehavior = _interopRequireDefault(require("./RootElementReferenceBehavior")); var _CreateBehavior = _interopRequireDefault(require("./CreateBehavior")); var _FixHoverBehavior = _interopRequireDefault(require("./FixHoverBehavior")); var _CreateDataObjectBehavior = _interopRequireDefault(require("./CreateDataObjectBehavior")); var _CreateParticipantBehavior = _interopRequireDefault(require("./CreateParticipantBehavior")); var _DataInputAssociationBehavior = _interopRequireDefault(require("./DataInputAssociationBehavior")); var _DataStoreBehavior = _interopRequireDefault(require("./DataStoreBehavior")); var _DeleteLaneBehavior = _interopRequireDefault(require("./DeleteLaneBehavior")); var _DetachEventBehavior = _interopRequireDefault(require("./DetachEventBehavior")); var _DropOnFlowBehavior = _interopRequireDefault(require("./DropOnFlowBehavior")); var _EventBasedGatewayBehavior = _interopRequireDefault(require("./EventBasedGatewayBehavior")); var _GroupBehavior = _interopRequireDefault(require("./GroupBehavior")); var _ImportDockingFix = _interopRequireDefault(require("./ImportDockingFix")); var _IsHorizontalFix = _interopRequireDefault(require("./IsHorizontalFix")); var _LabelBehavior = _interopRequireDefault(require("./LabelBehavior")); var _ModelingFeedback = _interopRequireDefault(require("./ModelingFeedback")); var _ReplaceConnectionBehavior = _interopRequireDefault(require("./ReplaceConnectionBehavior")); var _RemoveParticipantBehavior = _interopRequireDefault(require("./RemoveParticipantBehavior")); var _ReplaceElementBehaviour = _interopRequireDefault(require("./ReplaceElementBehaviour")); var _ResizeBehavior = _interopRequireDefault(require("./ResizeBehavior")); var _ResizeLaneBehavior = _interopRequireDefault(require("./ResizeLaneBehavior")); var _RemoveElementBehavior = _interopRequireDefault(require("./RemoveElementBehavior")); var _SpaceToolBehavior = _interopRequireDefault(require("./SpaceToolBehavior")); var _SubProcessStartEventBehavior = _interopRequireDefault(require("./SubProcessStartEventBehavior")); var _ToggleElementCollapseBehaviour = _interopRequireDefault(require("./ToggleElementCollapseBehaviour")); var _UnclaimIdBehavior = _interopRequireDefault(require("./UnclaimIdBehavior")); var _UpdateFlowNodeRefsBehavior = _interopRequireDefault(require("./UpdateFlowNodeRefsBehavior")); var _UnsetDefaultFlowBehavior = _interopRequireDefault(require("./UnsetDefaultFlowBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['adaptiveLabelPositioningBehavior', 'appendBehavior', 'associationBehavior', 'attachEventBehavior', 'boundaryEventBehavior', 'rootElementReferenceBehavior', 'createBehavior', 'fixHoverBehavior', 'createDataObjectBehavior', 'createParticipantBehavior', 'dataStoreBehavior', 'dataInputAssociationBehavior', 'deleteLaneBehavior', 'detachEventBehavior', 'dropOnFlowBehavior', 'eventBasedGatewayBehavior', 'groupBehavior', 'importDockingFix', 'isHorizontalFix', 'labelBehavior', 'modelingFeedback', 'removeElementBehavior', 'removeParticipantBehavior', 'replaceConnectionBehavior', 'replaceElementBehaviour', 'resizeBehavior', 'resizeLaneBehavior', 'toggleElementCollapseBehaviour', 'spaceToolBehavior', 'subProcessStartEventBehavior', 'unclaimIdBehavior', 'unsetDefaultFlowBehavior', 'updateFlowNodeRefsBehavior'], adaptiveLabelPositioningBehavior: ['type', _AdaptiveLabelPositioningBehavior.default], appendBehavior: ['type', _AppendBehavior.default], associationBehavior: ['type', _AssociationBehavior.default], attachEventBehavior: ['type', _AttachEventBehavior.default], boundaryEventBehavior: ['type', _BoundaryEventBehavior.default], rootElementReferenceBehavior: ['type', _RootElementReferenceBehavior.default], createBehavior: ['type', _CreateBehavior.default], fixHoverBehavior: ['type', _FixHoverBehavior.default], createDataObjectBehavior: ['type', _CreateDataObjectBehavior.default], createParticipantBehavior: ['type', _CreateParticipantBehavior.default], dataInputAssociationBehavior: ['type', _DataInputAssociationBehavior.default], dataStoreBehavior: ['type', _DataStoreBehavior.default], deleteLaneBehavior: ['type', _DeleteLaneBehavior.default], detachEventBehavior: ['type', _DetachEventBehavior.default], dropOnFlowBehavior: ['type', _DropOnFlowBehavior.default], eventBasedGatewayBehavior: ['type', _EventBasedGatewayBehavior.default], groupBehavior: ['type', _GroupBehavior.default], importDockingFix: ['type', _ImportDockingFix.default], isHorizontalFix: ['type', _IsHorizontalFix.default], labelBehavior: ['type', _LabelBehavior.default], modelingFeedback: ['type', _ModelingFeedback.default], replaceConnectionBehavior: ['type', _ReplaceConnectionBehavior.default], removeParticipantBehavior: ['type', _RemoveParticipantBehavior.default], replaceElementBehaviour: ['type', _ReplaceElementBehaviour.default], resizeBehavior: ['type', _ResizeBehavior.default], resizeLaneBehavior: ['type', _ResizeLaneBehavior.default], removeElementBehavior: ['type', _RemoveElementBehavior.default], toggleElementCollapseBehaviour: ['type', _ToggleElementCollapseBehaviour.default], spaceToolBehavior: ['type', _SpaceToolBehavior.default], subProcessStartEventBehavior: ['type', _SubProcessStartEventBehavior.default], unclaimIdBehavior: ['type', _UnclaimIdBehavior.default], updateFlowNodeRefsBehavior: ['type', _UpdateFlowNodeRefsBehavior.default], unsetDefaultFlowBehavior: ['type', _UnsetDefaultFlowBehavior.default] }; exports.default = _default; },{"./AdaptiveLabelPositioningBehavior":61,"./AppendBehavior":62,"./AssociationBehavior":63,"./AttachEventBehavior":64,"./BoundaryEventBehavior":65,"./CreateBehavior":66,"./CreateDataObjectBehavior":67,"./CreateParticipantBehavior":68,"./DataInputAssociationBehavior":69,"./DataStoreBehavior":70,"./DeleteLaneBehavior":71,"./DetachEventBehavior":72,"./DropOnFlowBehavior":73,"./EventBasedGatewayBehavior":74,"./FixHoverBehavior":75,"./GroupBehavior":76,"./ImportDockingFix":77,"./IsHorizontalFix":78,"./LabelBehavior":79,"./ModelingFeedback":80,"./RemoveElementBehavior":81,"./RemoveParticipantBehavior":82,"./ReplaceConnectionBehavior":83,"./ReplaceElementBehaviour":84,"./ResizeBehavior":85,"./ResizeLaneBehavior":86,"./RootElementReferenceBehavior":87,"./SpaceToolBehavior":88,"./SubProcessStartEventBehavior":89,"./ToggleElementCollapseBehaviour":90,"./UnclaimIdBehavior":91,"./UnsetDefaultFlowBehavior":92,"./UpdateFlowNodeRefsBehavior":93}],95:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCategoryValue = createCategoryValue; var _Collections = require("diagram-js/lib/util/Collections"); var _ModelUtil = require("../../../../util/ModelUtil"); /** * Creates a new bpmn:CategoryValue inside a new bpmn:Category * * @param {ModdleElement} definitions * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} categoryValue. */ function createCategoryValue(definitions, bpmnFactory) { var categoryValue = bpmnFactory.create('bpmn:CategoryValue'), category = bpmnFactory.create('bpmn:Category', { categoryValue: [categoryValue] }); // add to correct place (0, _Collections.add)(definitions.get('rootElements'), category); (0, _ModelUtil.getBusinessObject)(category).$parent = definitions; (0, _ModelUtil.getBusinessObject)(categoryValue).$parent = category; return categoryValue; } },{"../../../../util/ModelUtil":141,"diagram-js/lib/util/Collections":313}],96:[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 through 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 through 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 }); } },{}],97:[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 happened 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 happened 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 hasn't 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":96,"./LineAttachmentUtil":98,"diagram-js/lib/layout/LayoutUtil":300}],98:[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 // precision 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; } },{}],99:[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)) }; } },{}],100:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getParticipantResizeConstraints = getParticipantResizeConstraints; var _ModelUtil = require("../../../../util/ModelUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _LaneUtil = require("../../../modeling/util/LaneUtil"); var _ResizeBehavior = require("../ResizeBehavior"); 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_RIGHT_PADDING = 20, LANE_LEFT_PADDING = 50, LANE_TOP_PADDING = 20, LANE_BOTTOM_PADDING = 20; function getParticipantResizeConstraints(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 + _ResizeBehavior.LANE_MIN_DIMENSIONS.width; } else if (/w/.test(resizeDirection)) { minTrbl.left = laneTrbl.right - _ResizeBehavior.LANE_MIN_DIMENSIONS.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 + _ResizeBehavior.LANE_MIN_DIMENSIONS.height); } // min top size (based on self or nested element) if (abs(laneTrbl.top - otherTrbl.top) < 5) { addMin(minTrbl, 'top', otherTrbl.bottom - _ResizeBehavior.LANE_MIN_DIMENSIONS.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 - _ResizeBehavior.LANE_MIN_DIMENSIONS.height); } // min bottom size (based on self or nested element) if (abs(laneTrbl.bottom - otherTrbl.bottom) < 5) { addMax(minTrbl, 'bottom', otherTrbl.top + _ResizeBehavior.LANE_MIN_DIMENSIONS.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":141,"../../../modeling/util/LaneUtil":111,"../ResizeBehavior":85,"diagram-js/lib/layout/LayoutUtil":300}],101:[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 * @param {SpaceTool} spaceTool */ 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); // handle element labels in the diagram root if (element.label) { allAffected.push(element.label); } 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, spacePos); // (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":111,"diagram-js/lib/util/Elements":315,"min-dash":555}],102:[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); } }; },{}],103:[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":141,"../util/LaneUtil":111,"diagram-js/lib/features/resize/ResizeUtil":268,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Elements":315}],104:[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":555}],105:[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 necessary. * * @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":111}],106:[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":313}],107:[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.indexOf(flowNodeShape) === -1) { allFlowNodeShapes.push(flowNodeShape); handledNodes.push(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.indexOf(root) !== -1) { return; } var children = root.children.filter(function (c) { return (0, _ModelUtil.is)(c, 'bpmn:FlowNode'); }); children.forEach(addFlowNodeShape); handledNodes.push(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":141,"../util/LaneUtil":111,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Collections":313}],108:[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 separately 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":141,"min-dash":555}],109:[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); }; },{}],110:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _behavior = _interopRequireDefault(require("./behavior")); var _rules = _interopRequireDefault(require("../rules")); var _diOrdering = _interopRequireDefault(require("../di-ordering")); var _ordering = _interopRequireDefault(require("../ordering")); var _replace = _interopRequireDefault(require("../replace")); var _command = _interopRequireDefault(require("diagram-js/lib/command")); var _tooltips = _interopRequireDefault(require("diagram-js/lib/features/tooltips")); var _labelSupport = _interopRequireDefault(require("diagram-js/lib/features/label-support")); var _attachSupport = _interopRequireDefault(require("diagram-js/lib/features/attach-support")); var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection")); var _changeSupport = _interopRequireDefault(require("diagram-js/lib/features/change-support")); var _spaceTool = _interopRequireDefault(require("diagram-js/lib/features/space-tool")); var _BpmnFactory = _interopRequireDefault(require("./BpmnFactory")); var _BpmnUpdater = _interopRequireDefault(require("./BpmnUpdater")); var _ElementFactory = _interopRequireDefault(require("./ElementFactory")); var _Modeling = _interopRequireDefault(require("./Modeling")); var _BpmnLayouter = _interopRequireDefault(require("./BpmnLayouter")); var _CroppingConnectionDocking = _interopRequireDefault(require("diagram-js/lib/layout/CroppingConnectionDocking")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['modeling', 'bpmnUpdater'], __depends__: [_behavior.default, _rules.default, _diOrdering.default, _ordering.default, _replace.default, _command.default, _tooltips.default, _labelSupport.default, _attachSupport.default, _selection.default, _changeSupport.default, _spaceTool.default], bpmnFactory: ['type', _BpmnFactory.default], bpmnUpdater: ['type', _BpmnUpdater.default], elementFactory: ['type', _ElementFactory.default], modeling: ['type', _Modeling.default], layouter: ['type', _BpmnLayouter.default], connectionDocking: ['type', _CroppingConnectionDocking.default] }; exports.default = _default; },{"../di-ordering":36,"../ordering":114,"../replace":124,"../rules":126,"./BpmnFactory":56,"./BpmnLayouter":57,"./BpmnUpdater":58,"./ElementFactory":59,"./Modeling":60,"./behavior":94,"diagram-js/lib/command":147,"diagram-js/lib/features/attach-support":161,"diagram-js/lib/features/change-support":178,"diagram-js/lib/features/label-support":219,"diagram-js/lib/features/selection":278,"diagram-js/lib/features/space-tool":288,"diagram-js/lib/features/tooltips":292,"diagram-js/lib/layout/CroppingConnectionDocking":299}],111:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.collectLanes = collectLanes; exports.getChildLanes = getChildLanes; exports.getLanesRoot = getLanesRoot; exports.computeLanesResize = computeLanesResize; exports.LANE_INDENTATION = void 0; 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 = 30; /** * Collect all lane shapes in the given paren * * @param {djs.model.Shape} shape * @param {Array} [collectedShapes] * * @return {Array} */ exports.LANE_INDENTATION = LANE_INDENTATION; 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":141,"./ModelingUtil":112,"diagram-js/lib/features/resize/ResizeUtil":268,"diagram-js/lib/layout/LayoutUtil":300}],112:[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":141,"min-dash":555}],113:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnOrderingProvider; var _inherits = _interopRequireDefault(require("inherits")); var _OrderingProvider = _interopRequireDefault(require("diagram-js/lib/features/ordering/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 and groups are rendered always on top * (1) elements are ordered by a {level} property */ function BpmnOrderingProvider(eventBus, canvas, translate) { _OrderingProvider.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:Group', order: { level: 10, containers: ['bpmn:Collaboration', 'bpmn:Process'] } }, { 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 insert 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, _inherits.default)(BpmnOrderingProvider, _OrderingProvider.default); },{"../modeling/util/ModelingUtil":112,"diagram-js/lib/features/ordering/OrderingProvider":252,"inherits":347,"min-dash":555}],114:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate")); var _BpmnOrderingProvider = _interopRequireDefault(require("./BpmnOrderingProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_translate.default], __init__: ['bpmnOrderingProvider'], bpmnOrderingProvider: ['type', _BpmnOrderingProvider.default] }; exports.default = _default; },{"./BpmnOrderingProvider":113,"diagram-js/lib/i18n/translate":296}],115:[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 createSubprocess(event) { var subProcess = elementFactory.createShape({ type: 'bpmn:SubProcess', x: 0, y: 0, isExpanded: true }); var startEvent = elementFactory.createShape({ type: 'bpmn:StartEvent', x: 40, y: 82, parent: subProcess }); create.start(event, [subProcess, startEvent], { hints: { autoSelect: [startEvent] } }); } function createParticipant(event) { create.start(event, elementFactory.createParticipantShape()); } (0, _minDash.assign)(actions, { 'hand-tool': { group: 'tools', className: 'bpmn-icon-hand-tool', title: translate('Activate the hand tool'), action: { click: function (event) { handTool.activateHand(event); } } }, 'lasso-tool': { group: 'tools', className: 'bpmn-icon-lasso-tool', title: translate('Activate the lasso tool'), action: { click: function (event) { lassoTool.activateSelection(event); } } }, 'space-tool': { group: 'tools', className: 'bpmn-icon-space-tool', title: translate('Activate the create/remove space tool'), action: { click: function (event) { spaceTool.activateSelection(event); } } }, 'global-connect-tool': { group: 'tools', className: 'bpmn-icon-connection-multi', title: translate('Activate the global connect tool'), action: { click: function (event) { globalConnect.toggle(event); } } }, 'tool-separator': { group: 'tools', separator: true }, 'create.start-event': createAction('bpmn:StartEvent', 'event', 'bpmn-icon-start-event-none', translate('Create StartEvent')), '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', translate('Create EndEvent')), 'create.exclusive-gateway': createAction('bpmn:ExclusiveGateway', 'gateway', 'bpmn-icon-gateway-none', translate('Create Gateway')), 'create.task': createAction('bpmn:Task', 'activity', 'bpmn-icon-task', translate('Create Task')), 'create.data-object': createAction('bpmn:DataObjectReference', 'data-object', 'bpmn-icon-data-object', translate('Create DataObjectReference')), 'create.data-store': createAction('bpmn:DataStoreReference', 'data-store', 'bpmn-icon-data-store', translate('Create DataStoreReference')), 'create.subprocess-expanded': { group: 'activity', className: 'bpmn-icon-subprocess-expanded', title: translate('Create expanded SubProcess'), action: { dragstart: createSubprocess, click: createSubprocess } }, 'create.participant-expanded': { group: 'collaboration', className: 'bpmn-icon-participant', title: translate('Create Pool/Participant'), action: { dragstart: createParticipant, click: createParticipant } }, 'create.group': createAction('bpmn:Group', 'artifact', 'bpmn-icon-group', translate('Create Group')) }); return actions; }; },{"min-dash":555}],116:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _palette = _interopRequireDefault(require("diagram-js/lib/features/palette")); var _create = _interopRequireDefault(require("diagram-js/lib/features/create")); var _spaceTool = _interopRequireDefault(require("diagram-js/lib/features/space-tool")); var _lassoTool = _interopRequireDefault(require("diagram-js/lib/features/lasso-tool")); var _handTool = _interopRequireDefault(require("diagram-js/lib/features/hand-tool")); var _globalConnect = _interopRequireDefault(require("diagram-js/lib/features/global-connect")); var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate")); var _PaletteProvider = _interopRequireDefault(require("./PaletteProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_palette.default, _create.default, _spaceTool.default, _lassoTool.default, _handTool.default, _globalConnect.default, _translate.default], __init__: ['paletteProvider'], paletteProvider: ['type', _PaletteProvider.default] }; exports.default = _default; },{"./PaletteProvider":115,"diagram-js/lib/features/create":192,"diagram-js/lib/features/global-connect":201,"diagram-js/lib/features/hand-tool":209,"diagram-js/lib/features/lasso-tool":221,"diagram-js/lib/features/palette":258,"diagram-js/lib/features/space-tool":288,"diagram-js/lib/i18n/translate":296}],117:[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 = _interopRequireWildcard(require("../replace/ReplaceOptions")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } 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 sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && !(0, _ModelUtil.is)(businessObject.$parent, 'bpmn:SubProcess')) { 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); } // start events inside sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && !(0, _DiUtil.isEventSubProcess)(businessObject.$parent) && (0, _ModelUtil.is)(businessObject.$parent, 'bpmn:SubProcess')) { entries = (0, _minDash.filter)(replaceOptions.START_EVENT_SUB_PROCESS, differentType); 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 () { 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 (event, entry) { if (isAdHoc) { return replaceElement(element, { type: 'bpmn:SubProcess' }, { autoResize: false, layoutConnection: false }); } else { return replaceElement(element, { type: 'bpmn:AdHocSubProcess' }, { autoResize: false, layoutConnection: false }); } } }; return adHocEntry; }; },{"../../util/DiUtil":139,"../../util/ModelUtil":141,"../replace/ReplaceOptions":123,"./util/TypeUtil":119,"min-dash":555}],118:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _popupMenu = _interopRequireDefault(require("diagram-js/lib/features/popup-menu")); var _replace = _interopRequireDefault(require("../replace")); var _ReplaceMenuProvider = _interopRequireDefault(require("./ReplaceMenuProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_popupMenu.default, _replace.default], __init__: ['replaceMenuProvider'], replaceMenuProvider: ['type', _ReplaceMenuProvider.default] }; exports.default = _default; },{"../replace":124,"./ReplaceMenuProvider":117,"diagram-js/lib/features/popup-menu":260}],119:[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":139,"../../../util/ModelUtil":141}],120:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnReplacePreview; var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _inherits = _interopRequireDefault(require("inherits")); var _css = _interopRequireDefault(require("css.escape")); 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) { _CommandInterceptor.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, _css.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, _css.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 && canExecute.replacements) { replaceVisual(context); } else { restoreVisual(context); } }); } BpmnReplacePreview.$inject = ['eventBus', 'elementRegistry', 'elementFactory', 'canvas', 'previewSupport']; (0, _inherits.default)(BpmnReplacePreview, _CommandInterceptor.default); },{"css.escape":331,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555,"min-dom":556,"tiny-svg":567}],121:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _previewSupport = _interopRequireDefault(require("diagram-js/lib/features/preview-support")); var _BpmnReplacePreview = _interopRequireDefault(require("./BpmnReplacePreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_previewSupport.default], __init__: ['bpmnReplacePreview'], bpmnReplacePreview: ['type', _BpmnReplacePreview.default] }; exports.default = _default; },{"./BpmnReplacePreview":120,"diagram-js/lib/features/preview-support":262}],122:[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 _ModdleCopy = require("../copy-paste/ModdleCopy"); function copyProperties(source, target, properties) { if (!(0, _minDash.isArray)(properties)) { properties = [properties]; } (0, _minDash.forEach)(properties, function (property) { if (!(0, _minDash.isUndefined)(source[property])) { target[property] = source[property]; } }); } 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, elementFactory, moddleCopy, modeling, replace, selection) { /** * 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, _ModdleCopy.getPropertyNames)(oldBusinessObject.$descriptor), newElementProps = (0, _ModdleCopy.getPropertyNames)(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 (propertyName) { // copying event definitions, unless we replace if (propertyName === 'eventDefinitions') { return hasEventDefinition(element, target.eventDefinitionType); } // retain loop characteristics if the target element // is not an event sub process if (propertyName === 'loopCharacteristics') { return !(0, _DiUtil.isEventSubProcess)(newBusinessObject); } // so the applied properties from 'target' don't get lost if (newBusinessObject.hasOwnProperty(propertyName)) { return false; } if (propertyName === 'processRef' && target.isExpanded === false) { return false; } if (propertyName === 'triggeredByEvent') { return false; } return true; }); newBusinessObject = moddleCopy.copyElement(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 copied it if (!hasEventDefinition(newBusinessObject, target.eventDefinitionType)) { newElement.eventDefinitionType = target.eventDefinitionType; newElement.eventDefinitionAttrs = target.eventDefinitionAttrs; } } 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 width and default height newElement.width = element.width; newElement.height = elementFactory._getDefaultSize(newBusinessObject).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 (target.host && !(0, _ModelUtil.is)(oldBusinessObject, 'bpmn:BoundaryEvent') && (0, _ModelUtil.is)(newBusinessObject, 'bpmn:BoundaryEvent')) { newElement.host = target.host; } newElement.di = {}; // fill and stroke will be set to DI copyProperties(oldBusinessObject.di, newElement.di, ['fill', 'stroke']); newElement = replace.replaceElement(element, newElement, hints); if (hints.select !== false) { selection.select(newElement); } return newElement; } this.replaceElement = replaceElement; } BpmnReplace.$inject = ['bpmnFactory', 'elementFactory', 'moddleCopy', 'modeling', 'replace', 'selection']; 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":139,"../../util/ModelUtil":141,"../copy-paste/ModdleCopy":33,"../modeling/util/ModelingUtil":112,"min-dash":555}],123:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PARTICIPANT = exports.SEQUENCE_FLOW = exports.EVENT_SUB_PROCESS_START_EVENT = exports.BOUNDARY_EVENT = exports.TASK = exports.EVENT_SUB_PROCESS = exports.TRANSACTION = exports.SUBPROCESS_EXPANDED = exports.GATEWAY = exports.END_EVENT = exports.INTERMEDIATE_EVENT = exports.START_EVENT_SUB_PROCESS = exports.START_EVENT = void 0; var 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' } }]; exports.START_EVENT = START_EVENT; var START_EVENT_SUB_PROCESS = [{ 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' } }]; exports.START_EVENT_SUB_PROCESS = START_EVENT_SUB_PROCESS; var 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', eventDefinitionAttrs: { name: '' } } }, { 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', eventDefinitionAttrs: { name: '' } } }, { 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' } }]; exports.INTERMEDIATE_EVENT = INTERMEDIATE_EVENT; var 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' } }]; exports.END_EVENT = END_EVENT; var 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' } // } // } ]; exports.GATEWAY = GATEWAY; var 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 } }]; exports.SUBPROCESS_EXPANDED = SUBPROCESS_EXPANDED; var 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 } }]; exports.TRANSACTION = TRANSACTION; var 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 } }]; exports.EVENT_SUB_PROCESS = EVENT_SUB_PROCESS; var 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 } }]; exports.TASK = TASK; var 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 } }]; exports.BOUNDARY_EVENT = BOUNDARY_EVENT; var 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 } }]; exports.EVENT_SUB_PROCESS_START_EVENT = EVENT_SUB_PROCESS_START_EVENT; var 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' }]; exports.SEQUENCE_FLOW = SEQUENCE_FLOW; var 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 } }]; exports.PARTICIPANT = PARTICIPANT; },{}],124:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _copyPaste = _interopRequireDefault(require("../copy-paste")); var _replace = _interopRequireDefault(require("diagram-js/lib/features/replace")); var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection")); var _BpmnReplace = _interopRequireDefault(require("./BpmnReplace")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_copyPaste.default, _replace.default, _selection.default], bpmnReplace: ['type', _BpmnReplace.default] }; exports.default = _default; },{"../copy-paste":34,"./BpmnReplace":122,"diagram-js/lib/features/replace":264,"diagram-js/lib/features/selection":278}],125:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnRules; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../util/ModelUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _LabelUtil = require("../../util/LabelUtil"); var _DiUtil = require("../../util/DiUtil"); var _RuleProvider = _interopRequireDefault(require("diagram-js/lib/features/rules/RuleProvider")); var _BpmnSnappingUtil = require("../snapping/BpmnSnappingUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific modeling rule */ function BpmnRules(eventBus) { _RuleProvider.default.call(this, eventBus); } (0, _inherits.default)(BpmnRules, _RuleProvider.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.reconnect', function (context) { var connection = context.connection, source = context.source, target = context.target; return canConnect(source, target, connection); }); this.addRule('connection.updateWaypoints', function (context) { return { type: context.connection.type }; }); this.addRule('shape.resize', function (context) { var shape = context.shape, newBounds = context.newBounds; return canResize(shape, newBounds); }); this.addRule('elements.create', function (context) { var elements = context.elements, position = context.position, target = context.target; return (0, _minDash.every)(elements, function (element) { if (isConnection(element)) { return canConnect(element.source, element.target, element); } if (element.host) { return canAttach(element, element.host, null, position); } return canCreate(element, target, null, position); }); }); 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 element = context.element, elements = context.elements; return canCopy(elements, element); }); }; 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', 'bpmn:Group']); } 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 isGroup(element) { return (0, _ModelUtil.is)(element, 'bpmn:Group') && !element.labelTarget; } 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:BoundaryEvent') && (!(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') && !(0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !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 === 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 and groups everywhere if ((0, _LabelUtil.isLabel)(element) || isGroup(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 // 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 moving DataInput / DataOutput within its original container only if ((0, _ModelingUtil.isAny)(element, ['bpmn:DataInput', 'bpmn:DataOutput'])) { if (element.parent) { return target === element.parent; } } // 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'); } // disallow dropping boundary events which cannot replace with intermediate event if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !isDroppableBoundaryEvent(element)) { 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 isDroppableBoundaryEvent(event) { return (0, _ModelUtil.getBusinessObject)(event).cancelActivity && (hasNoEventDefinition(event) || hasCommonBoundaryIntermediateEventDefinition(event)); } 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) { if (isBoundaryEvent(element)) { return true; } if ((0, _ModelUtil.is)(element, 'bpmn:IntermediateThrowEvent') && hasNoEventDefinition(element)) { return true; } return (0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && hasCommonBoundaryIntermediateEventDefinition(element); } function hasNoEventDefinition(element) { var bo = (0, _ModelUtil.getBusinessObject)(element); return bo && !(bo.eventDefinitions && bo.eventDefinitions.length); } function hasCommonBoundaryIntermediateEventDefinition(element) { return hasOneOfEventDefinitions(element, ['bpmn:MessageEventDefinition', 'bpmn:TimerEventDefinition', 'bpmn:SignalEventDefinition', 'bpmn:ConditionalEventDefinition']); } function hasOneOfEventDefinitions(element, eventDefinitions) { return eventDefinitions.some(function (definition) { return hasEventDefinition(element, definition); }); } 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]; } // 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; } // 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/compensate 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' }); } // replace a typed start event by a blank interrupting start event // when the target is a sub process but not an event sub process if (hasOneOfEventDefinitions(element, ['bpmn:MessageEventDefinition', 'bpmn:TimerEventDefinition', 'bpmn:SignalEventDefinition', 'bpmn:ConditionalEventDefinition']) && (0, _ModelUtil.is)(target, 'bpmn:SubProcess')) { 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 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)(shape) || isGroup(shape)) { return true; } 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; } if (isGroup(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 if (isOneTextAnnotation(source, target)) { return true; } // can connect associations where we can connect // data associations, too (!) return !!canConnectDataAssociation(source, target); } function canConnectMessageFlow(source, target) { // during connect user might move mouse out of canvas // https://github.com/bpmn-io/bpmn-js/issues/1033 if (getRootElement(source) && !getRootElement(target)) { return false; } return isMessageFlowSource(source) && isMessageFlowTarget(target) && !isSameOrganization(source, target); } function canConnectSequenceFlow(source, target) { if (isEventBasedTarget(target) && target.incoming.length > 0 && areOutgoingEventBasedGatewayConnections(target.incoming) && !(0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway')) { return false; } 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 includes(elements, element) { return elements && element && elements.indexOf(element) !== -1; } function canCopy(elements, element) { if ((0, _LabelUtil.isLabel)(element)) { return true; } if ((0, _ModelUtil.is)(element, 'bpmn:Lane') && !includes(elements, element.parent)) { return false; } return true; } function isOutgoingEventBasedGatewayConnection(connection) { if (connection && connection.source) { return (0, _ModelUtil.is)(connection.source, 'bpmn:EventBasedGateway'); } } function areOutgoingEventBasedGatewayConnections(connections) { connections = connections || []; return connections.some(isOutgoingEventBasedGatewayConnection); } function getRootElement(element) { return (0, _ModelingUtil.getParent)(element, 'bpmn:Process') || (0, _ModelingUtil.getParent)(element, 'bpmn:Collaboration'); } },{"../../util/DiUtil":139,"../../util/LabelUtil":140,"../../util/ModelUtil":141,"../modeling/util/ModelingUtil":112,"../snapping/BpmnSnappingUtil":131,"diagram-js/lib/features/rules/RuleProvider":270,"inherits":347,"min-dash":555}],126:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _rules = _interopRequireDefault(require("diagram-js/lib/features/rules")); var _BpmnRules = _interopRequireDefault(require("./BpmnRules")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_rules.default], __init__: ['bpmnRules'], bpmnRules: ['type', _BpmnRules.default] }; exports.default = _default; },{"./BpmnRules":125,"diagram-js/lib/features/rules":272}],127:[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":53,"min-dash":555}],128:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _searchPad = _interopRequireDefault(require("diagram-js/lib/features/search-pad")); var _BpmnSearchProvider = _interopRequireDefault(require("./BpmnSearchProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_searchPad.default], __init__: ['bpmnSearch'], bpmnSearch: ['type', _BpmnSearchProvider.default] }; exports.default = _default; },{"./BpmnSearchProvider":127,"diagram-js/lib/features/search-pad":274}],129:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnConnectSnapping; var _SnapUtil = require("diagram-js/lib/features/snapping/SnapUtil"); var _KeyboardUtil = require("diagram-js/lib/features/keyboard/KeyboardUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _ModelUtil = require("../../util/ModelUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _minDash = require("min-dash"); var HIGHER_PRIORITY = 1250; var BOUNDARY_TO_HOST_THRESHOLD = 40; var TARGET_BOUNDS_PADDING = 20, TASK_BOUNDS_PADDING = 10; var TARGET_CENTER_PADDING = 20; var AXES = ['x', 'y']; var abs = Math.abs; /** * Snap during connect. * * @param {EventBus} eventBus */ function BpmnConnectSnapping(eventBus) { eventBus.on(['connect.hover', 'connect.move', 'connect.end'], HIGHER_PRIORITY, function (event) { var context = event.context, canExecute = context.canExecute, start = context.start, hover = context.hover, source = context.source, target = context.target; // do NOT snap on CMD if (event.originalEvent && (0, _KeyboardUtil.isCmd)(event.originalEvent)) { return; } if (!context.initialConnectionStart) { context.initialConnectionStart = context.connectionStart; } // snap hover if (canExecute && hover) { snapToShape(event, hover, getTargetBoundsPadding(hover)); } if (hover && isAnyType(canExecute, ['bpmn:Association', 'bpmn:DataInputAssociation', 'bpmn:DataOutputAssociation', 'bpmn:SequenceFlow'])) { context.connectionStart = (0, _SnapUtil.mid)(start); // snap hover if ((0, _ModelingUtil.isAny)(hover, ['bpmn:Event', 'bpmn:Gateway'])) { snapToPosition(event, (0, _SnapUtil.mid)(hover)); } // snap hover if ((0, _ModelingUtil.isAny)(hover, ['bpmn:Task', 'bpmn:SubProcess'])) { snapToTargetMid(event, hover); } // snap source and target if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent') && target === source.host) { snapBoundaryEventLoop(event); } } else if (isType(canExecute, 'bpmn:MessageFlow')) { if ((0, _ModelUtil.is)(start, 'bpmn:Event')) { // snap start context.connectionStart = (0, _SnapUtil.mid)(start); } if ((0, _ModelUtil.is)(hover, 'bpmn:Event')) { // snap hover snapToPosition(event, (0, _SnapUtil.mid)(hover)); } } else { // un-snap source context.connectionStart = context.initialConnectionStart; } }); } BpmnConnectSnapping.$inject = ['eventBus']; // helpers ////////// // snap to target if event in target function snapToShape(event, target, padding) { AXES.forEach(function (axis) { var dimensionForAxis = getDimensionForAxis(axis, target); if (event[axis] < target[axis] + padding) { (0, _SnapUtil.setSnapped)(event, axis, target[axis] + padding); } else if (event[axis] > target[axis] + dimensionForAxis - padding) { (0, _SnapUtil.setSnapped)(event, axis, target[axis] + dimensionForAxis - padding); } }); } // snap to target mid if event in target mid function snapToTargetMid(event, target) { var targetMid = (0, _SnapUtil.mid)(target); AXES.forEach(function (axis) { if (isMid(event, target, axis)) { (0, _SnapUtil.setSnapped)(event, axis, targetMid[axis]); } }); } // snap to prevent loop overlapping boundary event function snapBoundaryEventLoop(event) { var context = event.context, source = context.source, target = context.target; if (isReverse(context)) { return; } var sourceMid = (0, _SnapUtil.mid)(source), orientation = (0, _LayoutUtil.getOrientation)(sourceMid, target, -10), axes = []; if (/top|bottom/.test(orientation)) { axes.push('x'); } if (/left|right/.test(orientation)) { axes.push('y'); } axes.forEach(function (axis) { var coordinate = event[axis], newCoordinate; if (abs(coordinate - sourceMid[axis]) < BOUNDARY_TO_HOST_THRESHOLD) { if (coordinate > sourceMid[axis]) { newCoordinate = sourceMid[axis] + BOUNDARY_TO_HOST_THRESHOLD; } else { newCoordinate = sourceMid[axis] - BOUNDARY_TO_HOST_THRESHOLD; } (0, _SnapUtil.setSnapped)(event, axis, newCoordinate); } }); } function snapToPosition(event, position) { (0, _SnapUtil.setSnapped)(event, 'x', position.x); (0, _SnapUtil.setSnapped)(event, 'y', position.y); } function isType(attrs, type) { return attrs && attrs.type === type; } function isAnyType(attrs, types) { return (0, _minDash.some)(types, function (type) { return isType(attrs, type); }); } function getDimensionForAxis(axis, element) { return axis === 'x' ? element.width : element.height; } function getTargetBoundsPadding(target) { if ((0, _ModelUtil.is)(target, 'bpmn:Task')) { return TASK_BOUNDS_PADDING; } else { return TARGET_BOUNDS_PADDING; } } function isMid(event, target, axis) { return event[axis] > target[axis] + TARGET_CENTER_PADDING && event[axis] < target[axis] + getDimensionForAxis(axis, target) - TARGET_CENTER_PADDING; } function isReverse(context) { var hover = context.hover, source = context.source; return hover && source && hover === source; } },{"../../util/ModelUtil":141,"../modeling/util/ModelingUtil":112,"diagram-js/lib/features/keyboard/KeyboardUtil":216,"diagram-js/lib/features/snapping/SnapUtil":282,"diagram-js/lib/layout/LayoutUtil":300,"min-dash":555}],130:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnCreateMoveSnapping; var _inherits = _interopRequireDefault(require("inherits")); var _CreateMoveSnapping = _interopRequireDefault(require("diagram-js/lib/features/snapping/CreateMoveSnapping")); var _SnapUtil = require("diagram-js/lib/features/snapping/SnapUtil"); var _DiUtil = require("../../util/DiUtil"); var _ModelUtil = require("../../util/ModelUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _BpmnSnappingUtil = require("./BpmnSnappingUtil"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGH_PRIORITY = 1500; /** * Snap during create and move. * * @param {EventBus} eventBus * @param {Injector} injector */ function BpmnCreateMoveSnapping(eventBus, injector) { injector.invoke(_CreateMoveSnapping.default, this); // creating first participant eventBus.on(['create.move', 'create.end'], HIGH_PRIORITY, setSnappedIfConstrained); // snap boundary events eventBus.on(['create.move', 'create.end', 'shape.move.move', 'shape.move.end'], HIGH_PRIORITY, function (event) { var context = event.context, canExecute = context.canExecute, target = context.target; var canAttach = canExecute && (canExecute === 'attach' || canExecute.attach); if (canAttach && !(0, _SnapUtil.isSnapped)(event)) { snapBoundaryEvent(event, target); } }); } (0, _inherits.default)(BpmnCreateMoveSnapping, _CreateMoveSnapping.default); BpmnCreateMoveSnapping.$inject = ['eventBus', 'injector']; BpmnCreateMoveSnapping.prototype.initSnap = function (event) { var snapContext = _CreateMoveSnapping.default.prototype.initSnap.call(this, event); var shape = event.shape; var isMove = !!this._elementRegistry.get(shape.id); // snap to docking points (0, _minDash.forEach)(shape.outgoing, function (connection) { var docking = connection.waypoints[0]; docking = docking.original || docking; snapContext.setSnapOrigin(connection.id + '-docking', getDockingSnapOrigin(docking, isMove, event)); }); (0, _minDash.forEach)(shape.incoming, function (connection) { var docking = connection.waypoints[connection.waypoints.length - 1]; docking = docking.original || docking; snapContext.setSnapOrigin(connection.id + '-docking', getDockingSnapOrigin(docking, isMove, event)); }); if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { // snap to borders with higher priority snapContext.setSnapLocations(['top-left', 'bottom-right', 'mid']); } return snapContext; }; BpmnCreateMoveSnapping.prototype.addSnapTargetPoints = function (snapPoints, shape, target) { _CreateMoveSnapping.default.prototype.addSnapTargetPoints.call(this, snapPoints, shape, target); var snapTargets = this.getSnapTargets(shape, target); (0, _minDash.forEach)(snapTargets, function (snapTarget) { // handle TRBL alignment // // * with container elements // * with text annotations if (isContainer(snapTarget) || areAll([shape, snapTarget], 'bpmn:TextAnnotation')) { snapPoints.add('top-left', (0, _SnapUtil.topLeft)(snapTarget)); snapPoints.add('bottom-right', (0, _SnapUtil.bottomRight)(snapTarget)); } }); var elementRegistry = this._elementRegistry; // snap to docking points if not create mode (0, _minDash.forEach)(shape.incoming, function (connection) { if (elementRegistry.get(shape.id)) { if (!includes(snapTargets, connection.source)) { snapPoints.add('mid', (0, _LayoutUtil.getMid)(connection.source)); } var docking = connection.waypoints[0]; snapPoints.add(connection.id + '-docking', docking.original || docking); } }); (0, _minDash.forEach)(shape.outgoing, function (connection) { if (elementRegistry.get(shape.id)) { if (!includes(snapTargets, connection.target)) { snapPoints.add('mid', (0, _LayoutUtil.getMid)(connection.target)); } var docking = connection.waypoints[connection.waypoints.length - 1]; snapPoints.add(connection.id + '-docking', docking.original || docking); } }); // add sequence flow parents as snap targets if ((0, _ModelUtil.is)(target, 'bpmn:SequenceFlow')) { snapPoints = this.addSnapTargetPoints(snapPoints, shape, target.parent); } return snapPoints; }; BpmnCreateMoveSnapping.prototype.getSnapTargets = function (shape, target) { return _CreateMoveSnapping.default.prototype.getSnapTargets.call(this, shape, target).filter(function (snapTarget) { // do not snap to lanes return !(0, _ModelUtil.is)(snapTarget, 'bpmn:Lane'); }); }; // helpers ////////// function snapBoundaryEvent(event, target) { var targetTRBL = (0, _LayoutUtil.asTRBL)(target); var direction = (0, _BpmnSnappingUtil.getBoundaryAttachment)(event, target); var context = event.context, shape = context.shape; var offset; if (shape.parent) { offset = { x: 0, y: 0 }; } else { offset = (0, _LayoutUtil.getMid)(shape); } if (/top/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.top - offset.y); } else if (/bottom/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.bottom - offset.y); } if (/left/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.left - offset.x); } else if (/right/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.right - offset.x); } } function areAll(elements, type) { return elements.every(function (el) { return (0, _ModelUtil.is)(el, type); }); } function isContainer(element) { if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element)) { return true; } return (0, _ModelUtil.is)(element, 'bpmn:Participant'); } function setSnappedIfConstrained(event) { var context = event.context, createConstraints = context.createConstraints; if (!createConstraints) { return; } var top = createConstraints.top, right = createConstraints.right, bottom = createConstraints.bottom, left = createConstraints.left; if (left && left >= event.x || right && right <= event.x) { (0, _SnapUtil.setSnapped)(event, 'x', event.x); } if (top && top >= event.y || bottom && bottom <= event.y) { (0, _SnapUtil.setSnapped)(event, 'y', event.y); } } function includes(array, value) { return array.indexOf(value) !== -1; } function getDockingSnapOrigin(docking, isMove, event) { return isMove ? { x: docking.x - event.x, y: docking.y - event.y } : { x: docking.x, y: docking.y }; } },{"../../util/DiUtil":139,"../../util/ModelUtil":141,"./BpmnSnappingUtil":131,"diagram-js/lib/features/snapping/CreateMoveSnapping":279,"diagram-js/lib/features/snapping/SnapUtil":282,"diagram-js/lib/layout/LayoutUtil":300,"inherits":347,"min-dash":555}],131:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getBoundaryAttachment = getBoundaryAttachment; var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); function getBoundaryAttachment(position, targetBounds) { var orientation = (0, _LayoutUtil.getOrientation)(position, targetBounds, -15); if (orientation !== 'intersect') { return orientation; } else { return null; } } },{"diagram-js/lib/layout/LayoutUtil":300}],132:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnConnectSnapping = _interopRequireDefault(require("./BpmnConnectSnapping")); var _BpmnCreateMoveSnapping = _interopRequireDefault(require("./BpmnCreateMoveSnapping")); var _snapping = _interopRequireDefault(require("diagram-js/lib/features/snapping")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_snapping.default], __init__: ['connectSnapping', 'createMoveSnapping'], connectSnapping: ['type', _BpmnConnectSnapping.default], createMoveSnapping: ['type', _BpmnCreateMoveSnapping.default] }; exports.default = _default; },{"./BpmnConnectSnapping":129,"./BpmnCreateMoveSnapping":130,"diagram-js/lib/features/snapping":284}],133:[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 _LabelUtil2 = require("../features/label-editing/LabelUtil"); var _Util = require("./Util"); function elementData(semantic, attrs) { return (0, _minDash.assign)({ id: semantic.id, type: semantic.$type, businessObject: semantic }, attrs); } function getWaypoints(bo, source, target) { var waypoints = bo.di.waypoint; if (!waypoints || waypoints.length < 2) { return [(0, _LayoutUtil.getMid)(source), (0, _LayoutUtil.getMid)(target)]; } return waypoints.map(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), isFrame = isFrameElement(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), isFrame: isFrame })); 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 whether 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: getWaypoints(semantic, source, target) })); 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) && (0, _LabelUtil2.getLabel)(element)) { 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 = (0, _LabelUtil2.getLabel)(element); 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 || !(0, _LabelUtil2.getLabel)(element), 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; } function isFrameElement(semantic) { return (0, _ModelUtil.is)(semantic, 'bpmn:Group'); } },{"../features/label-editing/LabelUtil":53,"../util/DiUtil":139,"../util/LabelUtil":140,"../util/ModelUtil":141,"./Util":136,"diagram-js/lib/layout/LayoutUtil":300,"min-dash":555}],134:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnTreeWalker; var _minDash = require("min-dash"); var _objectRefs = _interopRequireDefault(require("object-refs")); var _Util = require("./Util"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var diRefs = new _objectRefs.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, ctx) { // 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, ctx)); } 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 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 () { handleFlowNode(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":136,"min-dash":555,"object-refs":560}],135:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.importBpmnDiagram = importBpmnDiagram; var _BpmnTreeWalker = _interopRequireDefault(require("./BpmnTreeWalker")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * The importBpmnDiagram result. * * @typedef {Object} ImportBPMNDiagramResult * * @property {Array} warnings */ /** * The importBpmnDiagram error. * * @typedef {Error} ImportBPMNDiagramError * * @property {Array} warnings */ /** * Import the definitions into a diagram. * * Errors and warnings are reported through the specified callback. * * @param {djs.Diagram} diagram * @param {ModdleElement} definitions * @param {ModdleElement} [bpmnDiagram] the diagram to be rendered * (if not provided, the first one will be rendered) * * Returns {Promise} */ function importBpmnDiagram(diagram, definitions, bpmnDiagram) { var importer, eventBus, translate; var error, warnings = []; /** * Walk the diagram semantically, importing (=drawing) * all elements you encounter. * * @param {ModdleElement} definitions * @param {ModdleElement} bpmnDiagram */ function render(definitions, bpmnDiagram) { var visitor = { root: function (element) { return importer.add(element); }, element: function (element, parentShape) { return importer.add(element, parentShape); }, error: function (message, context) { warnings.push({ message: message, context: context }); } }; var walker = new _BpmnTreeWalker.default(visitor, translate); // traverse BPMN 2.0 document model, // starting at definitions walker.handleDefinitions(definitions, bpmnDiagram); } return new Promise(function (resolve, reject) { try { importer = diagram.get('bpmnImporter'); eventBus = diagram.get('eventBus'); translate = diagram.get('translate'); eventBus.fire('import.render.start', { definitions: definitions }); render(definitions, bpmnDiagram); eventBus.fire('import.render.complete', { error: error, warnings: warnings }); return resolve({ warnings: warnings }); } catch (e) { e.warnings = warnings; return reject(e); } }); } },{"./BpmnTreeWalker":134}],136:[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 : '') + '" />'; } },{}],137:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate")); var _BpmnImporter = _interopRequireDefault(require("./BpmnImporter")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_translate.default], bpmnImporter: ['type', _BpmnImporter.default] }; exports.default = _default; },{"./BpmnImporter":133,"diagram-js/lib/i18n/translate":296}],138:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.wrapForCompatibility = wrapForCompatibility; var _minDash = require("min-dash"); // TODO(nikku): remove with future bpmn-js version /** * Wraps APIs to check: * * 1) If a callback is passed -> Warn users about callback deprecation. * 2) If Promise class is implemented in current environment. * * @private */ function wrapForCompatibility(api) { return function () { if (!window.Promise) { throw new Error('Promises is not supported in this environment. Please polyfill Promise.'); } var argLen = arguments.length; if (argLen >= 1 && (0, _minDash.isFunction)(arguments[argLen - 1])) { var callback = arguments[argLen - 1]; console.warn(new Error('Passing callbacks to ' + api.name + ' is deprecated and will be removed in a future major release. ' + 'Please switch to promises: https://bpmn.io/l/moving-to-promises.html')); var argsWithoutCallback = Array.prototype.slice.call(arguments, 0, -1); api.apply(this, argsWithoutCallback).then(function (result) { var firstKey = Object.keys(result)[0]; // The APIs we are wrapping all resolve a single item depending on the API. // For instance, importXML resolves { warnings } and saveXML returns { xml }. // That's why we can call the callback with the first item of result. return callback(null, result[firstKey]); // Passing a second paramter instead of catch because we don't want to // catch errors thrown by callback(). }, function (err) { return callback(err, err.warnings); }); } else { return api.apply(this, arguments); } }; } },{"min-dash":555}],139:[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":141,"min-dash":555}],140:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isLabelExternal = isLabelExternal; exports.hasExternalLabel = hasExternalLabel; exports.getFlowLabelPosition = getFlowLabelPosition; exports.getWaypointsMid = getWaypointsMid; exports.getExternalLabelMid = getExternalLabelMid; exports.getExternalLabelBounds = getExternalLabelBounds; exports.isLabel = isLabel; exports.FLOW_LABEL_INDENT = exports.DEFAULT_LABEL_SIZE = void 0; var _minDash = require("min-dash"); var _ModelUtil = require("./ModelUtil"); var DEFAULT_LABEL_SIZE = { width: 90, height: 20 }; exports.DEFAULT_LABEL_SIZE = DEFAULT_LABEL_SIZE; var FLOW_LABEL_INDENT = 15; /** * Returns true if the given semantic has an external label * * @param {BpmnElement} semantic * @return {boolean} true if has label */ exports.FLOW_LABEL_INDENT = FLOW_LABEL_INDENT; 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:DataInput') || (0, _ModelUtil.is)(semantic, 'bpmn:DataOutput') || (0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:MessageFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:Group'); } /** * 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 if ((0, _ModelUtil.is)(element, 'bpmn:Group')) { return { x: element.x + element.width / 2, y: element.y + DEFAULT_LABEL_SIZE.height / 2 }; } 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":141,"min-dash":555}],141:[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; } },{}],142:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.open = open; exports.LINK_STYLES = exports.BPMNIO_IMG = void 0; var _minDom = require("min-dom"); /** * This file must not be changed or exchanged. * * @see http://bpmn.io/license for more information. */ // inlined ../../resources/logo.svg var BPMNIO_LOGO_SVG = ''; var BPMNIO_IMG = BPMNIO_LOGO_SVG; exports.BPMNIO_IMG = BPMNIO_IMG; function css(attrs) { return attrs.join(';'); } var LINK_STYLES = css(['color: #404040']); exports.LINK_STYLES = LINK_STYLES; 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(40,40,40,0.2)']); var NOTICE_STYLES = css(['position: absolute', 'left: 50%', 'top: 40%', 'transform: translate(-50%)', 'width: 260px', 'padding: 10px', 'background: white', 'box-shadow: 0 1px 4px rgba(0,0,0,0.3)', 'font-family: Helvetica, Arial, sans-serif', 'font-size: 14px', 'display: flex', 'line-height: 1.3']); 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":556}],143:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function () { return _Diagram.default; } }); var _Diagram = _interopRequireDefault(require("./lib/Diagram")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } },{"./lib/Diagram":144}],144:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Diagram; var _didi = require("didi"); var _core = _interopRequireDefault(require("./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, _core.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":153,"didi":344}],145:[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":555}],146:[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.reverse()) }); 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":555}],147:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _CommandStack = _interopRequireDefault(require("./CommandStack")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { commandStack: ['type', _CommandStack.default] }; exports.default = _default; },{"./CommandStack":146}],148:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 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 !== '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":313,"../util/Elements":315,"min-dash":555,"tiny-svg":567}],149:[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":302,"min-dash":555}],150:[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":567}],151:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 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 {number} [priority=1000] the priority in which this listener is called, larger is higher * @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 === 'object') { data = type; type = data.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":555}],152:[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"); var _Elements = require("../util/Elements"); /** * 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._getChildrenContainer = 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 {string} type the type of the element, i.e. shape | connection * @param {SVGElement} [childrenGfx] * @param {number} [parentIndex] position to create container in parent * @param {boolean} [isFrame] is frame element * * @return {SVGElement} */ GraphicsFactory.prototype._createContainer = function (type, childrenGfx, parentIndex, isFrame) { 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); if (isFrame) { (0, _tinySvg.classes)(gfx).add('djs-frame'); } (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._getChildrenContainer(element.parent); return this._createContainer(type, childrenGfx, parentIndex, (0, _Elements.isFrameElement)(element)); }; 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 childrenGfx = self._getChildrenContainer(parent); (0, _minDash.forEach)(children.slice().reverse(), function (child) { var childGfx = elementRegistry.getGraphics(child); prependTo(childGfx.parentNode, childrenGfx); }); }); }; 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) { var node = siblingNode || parentNode.firstChild; // do not prepend node to itself to prevent IE from crashing // https://github.com/bpmn-io/bpmn-js/issues/746 if (newNode === node) { return; } parentNode.insertBefore(newNode, node); } },{"../util/Elements":315,"../util/GraphicsUtil":319,"../util/SvgTransformUtil":328,"min-dash":555,"min-dom":556,"tiny-svg":567}],153:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _draw = _interopRequireDefault(require("../draw")); var _Canvas = _interopRequireDefault(require("./Canvas")); var _ElementRegistry = _interopRequireDefault(require("./ElementRegistry")); var _ElementFactory = _interopRequireDefault(require("./ElementFactory")); var _EventBus = _interopRequireDefault(require("./EventBus")); var _GraphicsFactory = _interopRequireDefault(require("./GraphicsFactory")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_draw.default], __init__: ['canvas'], canvas: ['type', _Canvas.default], elementRegistry: ['type', _ElementRegistry.default], elementFactory: ['type', _ElementFactory.default], eventBus: ['type', _EventBus.default], graphicsFactory: ['type', _GraphicsFactory.default] }; exports.default = _default; },{"../draw":157,"./Canvas":148,"./ElementFactory":149,"./ElementRegistry":150,"./EventBus":151,"./GraphicsFactory":152}],154:[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 () {}; },{}],155:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DefaultRenderer; var _inherits = _interopRequireDefault(require("inherits")); var _BaseRenderer = _interopRequireDefault(require("./BaseRenderer")); var _RenderUtil = require("../util/RenderUtil"); var _tinySvg = require("tiny-svg"); var _Elements = require("../util/Elements"); 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) { // _BaseRenderer.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 }); this.FRAME_STYLE = styles.style(['no-fill'], { stroke: 'fuchsia', strokeDasharray: 4, strokeWidth: 2 }); } (0, _inherits.default)(DefaultRenderer, _BaseRenderer.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 }); if ((0, _Elements.isFrameElement)(element)) { (0, _tinySvg.attr)(rect, this.FRAME_STYLE); } else { (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/Elements":315,"../util/RenderUtil":327,"./BaseRenderer":154,"inherits":347,"tiny-svg":567}],156:[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":555}],157:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _DefaultRenderer = _interopRequireDefault(require("./DefaultRenderer")); var _Styles = _interopRequireDefault(require("./Styles")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['defaultRenderer'], defaultRenderer: ['type', _DefaultRenderer.default], styles: ['type', _Styles.default] }; exports.default = _default; },{"./DefaultRenderer":155,"./Styles":156}],158:[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 (element) { return element.x + element.width; }, top: sortTopOrMiddle, middle: sortTopOrMiddle, bottom: function (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":555}],159:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _AlignElements = _interopRequireDefault(require("./AlignElements")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['alignElements'], alignElements: ['type', _AlignElements.default] }; exports.default = _default; },{"./AlignElements":158}],160:[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 _AttachUtil = require("../../util/AttachUtil"); var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 251, HIGH_PRIORITY = 1401; var MARKER_ATTACH = 'attach-ok'; /** * 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 {Canvas} canvas * @param {Rules} rules * @param {Modeling} modeling */ function AttachSupport(injector, eventBus, canvas, rules, modeling) { _CommandInterceptor.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 attach-ok marker to current host movePreview && eventBus.on('shape.move.start', function (event) { var context = event.context, shapes = context.shapes; if (shapes.length !== 1) { return; } var shape = shapes[0]; var host = shape.host; if (host) { canvas.addMarker(host, MARKER_ATTACH); eventBus.once(['shape.move.out', 'shape.move.cleanup'], function () { canvas.removeMarker(host, MARKER_ATTACH); }); } }); // 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; // only single elements can be attached // multiply elements can be detached if (newHost && shapes.length !== 1) { return; } if (newHost) { attachers = shapes; } else { // find attachers moved without host attachers = (0, _minDash.filter)(shapes, function (shape) { var host = shape.host; return isAttacher(shape) && !includes(shapes, 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.reconnect', { 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.reconnect', { 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, hints = context.hints || {}; if (hints.attachSupport === false) { return; } (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); } }); } (0, _inherits.default)(AttachSupport, _CommandInterceptor.default); AttachSupport.$inject = ['injector', 'eventBus', 'canvas', '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; }); } function isAttacher(shape) { return !!shape.host; } function includes(array, item) { return array.indexOf(item) !== -1; } },{"../../command/CommandInterceptor":145,"../../util/AttachUtil":311,"../../util/Removal":326,"inherits":347,"min-dash":555}],161:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _rules = _interopRequireDefault(require("../rules")); var _AttachSupport = _interopRequireDefault(require("./AttachSupport")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_rules.default], __init__: ['attachSupport'], attachSupport: ['type', _AttachSupport.default] }; exports.default = _default; },{"../rules":272,"./AttachSupport":160}],162:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoPlace; var _LayoutUtil = require("../../layout/LayoutUtil"); var _AutoPlaceUtil = require("./AutoPlaceUtil"); var LOW_PRIORITY = 100; /** * 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) { eventBus.on('autoPlace', LOW_PRIORITY, function (context) { var shape = context.shape, source = context.source; return getNewShapePosition(source, shape); }); /** * 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, hints) { eventBus.fire('autoPlace.start', { source: source, shape: shape }); // allow others to provide the position var position = eventBus.fire('autoPlace', { source: source, shape: shape }); var newShape = modeling.appendShape(source, shape, position, source.parent, hints); eventBus.fire('autoPlace.end', { source: source, 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 * @param {Object} [hints] * @param {Object} [hints.defaultDistance] * * @returns {Point} */ function getNewShapePosition(source, element, hints) { if (!hints) { hints = {}; } var distance = hints.defaultDistance || _AutoPlaceUtil.DEFAULT_DISTANCE; var sourceMid = (0, _LayoutUtil.getMid)(source), sourceTrbl = (0, _LayoutUtil.asTRBL)(source); // simply put element right next to source return { x: sourceTrbl.right + distance + element.width / 2, y: sourceMid.y }; } },{"../../layout/LayoutUtil":300,"./AutoPlaceUtil":164}],163:[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']; },{}],164:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findFreePosition = findFreePosition; exports.generateGetNextPosition = generateGetNextPosition; exports.getConnectedAtPosition = getConnectedAtPosition; exports.getConnectedDistance = getConnectedDistance; exports.DEFAULT_DISTANCE = void 0; var _LayoutUtil = require("../../layout/LayoutUtil"); var _minDash = require("min-dash"); // padding to detect element placement var PLACEMENT_DETECTION_PAD = 10; var DEFAULT_DISTANCE = 50; exports.DEFAULT_DISTANCE = DEFAULT_DISTANCE; var DEFAULT_MAX_DISTANCE = 250; /** * Get free position starting from given position. * * @param {djs.model.Shape} source * @param {djs.model.Shape} element * @param {Point} position * @param {Function} getNextPosition * * @return {Point} */ function findFreePosition(source, element, position, getNextPosition) { var connectedAtPosition; while (connectedAtPosition = getConnectedAtPosition(source, position, element)) { position = getNextPosition(element, position, connectedAtPosition); } return position; } /** * Returns function that returns next position. * * @param {Object} nextPositionDirection * @param {Object} [nextPositionDirection.x] * @param {Object} [nextPositionDirection.y] * * @returns {Function} */ function generateGetNextPosition(nextPositionDirection) { return function (element, previousPosition, connectedAtPosition) { var nextPosition = { x: previousPosition.x, y: previousPosition.y }; ['x', 'y'].forEach(function (axis) { var nextPositionDirectionForAxis = nextPositionDirection[axis]; if (!nextPositionDirectionForAxis) { return; } var dimension = axis === 'x' ? 'width' : 'height'; var margin = nextPositionDirectionForAxis.margin, minDistance = nextPositionDirectionForAxis.minDistance; if (margin < 0) { nextPosition[axis] = Math.min(connectedAtPosition[axis] + margin - element[dimension] / 2, previousPosition[axis] - minDistance + margin); } else { nextPosition[axis] = Math.max(connectedAtPosition[axis] + connectedAtPosition[dimension] + margin + element[dimension] / 2, previousPosition[axis] + minDistance + margin); } }); return nextPosition; }; } /** * 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'; }); } /** * Compute optimal distance between source and target based on existing connections to and from source. * Assumes left-to-right and top-to-down modeling. * * @param {djs.model.Shape} source * @param {Object} [hints] * @param {number} [hints.defaultDistance] * @param {string} [hints.direction] * @param {Function} [hints.filter] * @param {Function} [hints.getWeight] * @param {number} [hints.maxDistance] * @param {string} [hints.reference] * * @return {number} */ function getConnectedDistance(source, hints) { if (!hints) { hints = {}; } // targets > sources by default function getDefaultWeight(connection) { return connection.source === source ? 1 : -1; } var defaultDistance = hints.defaultDistance || DEFAULT_DISTANCE, direction = hints.direction || 'e', filter = hints.filter, getWeight = hints.getWeight || getDefaultWeight, maxDistance = hints.maxDistance || DEFAULT_MAX_DISTANCE, reference = hints.reference || 'start'; if (!filter) { filter = noneFilter; } function getDistance(a, b) { if (direction === 'n') { if (reference === 'start') { return (0, _LayoutUtil.asTRBL)(a).top - (0, _LayoutUtil.asTRBL)(b).bottom; } else if (reference === 'center') { return (0, _LayoutUtil.asTRBL)(a).top - (0, _LayoutUtil.getMid)(b).y; } else { return (0, _LayoutUtil.asTRBL)(a).top - (0, _LayoutUtil.asTRBL)(b).top; } } else if (direction === 'w') { if (reference === 'start') { return (0, _LayoutUtil.asTRBL)(a).left - (0, _LayoutUtil.asTRBL)(b).right; } else if (reference === 'center') { return (0, _LayoutUtil.asTRBL)(a).left - (0, _LayoutUtil.getMid)(b).x; } else { return (0, _LayoutUtil.asTRBL)(a).left - (0, _LayoutUtil.asTRBL)(b).left; } } else if (direction === 's') { if (reference === 'start') { return (0, _LayoutUtil.asTRBL)(b).top - (0, _LayoutUtil.asTRBL)(a).bottom; } else if (reference === 'center') { return (0, _LayoutUtil.getMid)(b).y - (0, _LayoutUtil.asTRBL)(a).bottom; } else { return (0, _LayoutUtil.asTRBL)(b).bottom - (0, _LayoutUtil.asTRBL)(a).bottom; } } else { if (reference === 'start') { return (0, _LayoutUtil.asTRBL)(b).left - (0, _LayoutUtil.asTRBL)(a).right; } else if (reference === 'center') { return (0, _LayoutUtil.getMid)(b).x - (0, _LayoutUtil.asTRBL)(a).right; } else { return (0, _LayoutUtil.asTRBL)(b).right - (0, _LayoutUtil.asTRBL)(a).right; } } } var sourcesDistances = source.incoming.filter(filter).map(function (connection) { var weight = getWeight(connection); var distance = weight < 0 ? getDistance(connection.source, source) : getDistance(source, connection.source); return { id: connection.source.id, distance: distance, weight: weight }; }); var targetsDistances = source.outgoing.filter(filter).map(function (connection) { var weight = getWeight(connection); var distance = weight > 0 ? getDistance(source, connection.target) : getDistance(connection.target, source); return { id: connection.target.id, distance: distance, weight: weight }; }); var distances = sourcesDistances.concat(targetsDistances).reduce(function (accumulator, currentValue) { accumulator[currentValue.id + '__weight_' + currentValue.weight] = currentValue; return accumulator; }, {}); var distancesGrouped = (0, _minDash.reduce)(distances, function (accumulator, currentValue) { var distance = currentValue.distance, weight = currentValue.weight; if (distance < 0 || distance > maxDistance) { return accumulator; } if (!accumulator[String(distance)]) { accumulator[String(distance)] = 0; } accumulator[String(distance)] += 1 * weight; if (!accumulator.distance || accumulator[accumulator.distance] < accumulator[String(distance)]) { accumulator.distance = distance; } return accumulator; }, {}); return distancesGrouped.distance || defaultDistance; } /** * Returns all connected elements around the given source. * * This includes: * * - connected elements * - host connected elements * - attachers connected elements * * @param {djs.model.Shape} source * * @return {Array} */ function getAutoPlaceClosure(source) { 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; } function getConnected(element) { return getTargets(element).concat(getSources(element)); } function getSources(shape) { return shape.incoming.map(function (connection) { return connection.source; }); } function getTargets(shape) { return shape.outgoing.map(function (connection) { return connection.target; }); } function noneFilter() { return true; } },{"../../layout/LayoutUtil":300,"min-dash":555}],165:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _AutoPlace = _interopRequireDefault(require("./AutoPlace")); var _AutoPlaceSelectionBehavior = _interopRequireDefault(require("./AutoPlaceSelectionBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['autoPlaceSelectionBehavior'], autoPlace: ['type', _AutoPlace.default], autoPlaceSelectionBehavior: ['type', _AutoPlaceSelectionBehavior.default] }; exports.default = _default; },{"./AutoPlace":162,"./AutoPlaceSelectionBehavior":163}],166:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoResize; var _inherits = _interopRequireDefault(require("inherits")); var _Elements = require("../../util/Elements"); var _LayoutUtil = require("../../layout/LayoutUtil"); var _minDash = require("min-dash"); var _CommandInterceptor = _interopRequireDefault(require("../../command/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) { _CommandInterceptor.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.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 (0, _minDash.find)(autoResize, (0, _minDash.matchPattern)({ id: element.id })); }); } self._expand(elements, parentId); }); }); this.postExecuted(['shape.toggleCollapse'], function (event) { var context = event.context, hints = context.hints, shape = context.shape; if (hints && 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.autoResize === false) { return; } if (parent) { self._expand([shape], parent); } }); } AutoResize.$inject = ['eventBus', 'elementRegistry', 'modeling', 'rules']; (0, _inherits.default)(AutoResize, _CommandInterceptor.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; } var resizeDirections = getResizeDirections((0, _minDash.pick)(target, ['x', 'y', 'width', 'height']), newBounds); // resize the parent shape this.resize(target, newBounds, { autoResize: resizeDirections }); 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 {TRBL} */ 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 {TRBL} */ AutoResize.prototype.getPadding = function (shape) { return { top: 2, bottom: 2, left: 15, right: 15 }; }; /** * Perform the actual resize operation. * * @param {djs.model.Shape} shape * @param {Bounds} newBounds * @param {Object} [hints] * @param {string} [hints.autoResize] */ AutoResize.prototype.resize = function (shape, newBounds, hints) { this._modeling.resizeShape(shape, newBounds, null, hints); }; function boundsChanged(newBounds, oldBounds) { return newBounds.x !== oldBounds.x || newBounds.y !== oldBounds.y || newBounds.width !== oldBounds.width || newBounds.height !== oldBounds.height; } /** * Get directions of resize as {n|w|s|e} e.g. "nw". * * @param {Bounds} oldBounds * @param {Bounds} newBounds * * @returns {string} Resize directions as {n|w|s|e}. */ function getResizeDirections(oldBounds, newBounds) { var directions = ''; oldBounds = (0, _LayoutUtil.asTRBL)(oldBounds); newBounds = (0, _LayoutUtil.asTRBL)(newBounds); if (oldBounds.top > newBounds.top) { directions = directions.concat('n'); } if (oldBounds.right < newBounds.right) { directions = directions.concat('w'); } if (oldBounds.bottom < newBounds.bottom) { directions = directions.concat('s'); } if (oldBounds.left > newBounds.left) { directions = directions.concat('e'); } return directions; } },{"../../command/CommandInterceptor":145,"../../layout/LayoutUtil":300,"../../util/Elements":315,"inherits":347,"min-dash":555}],167:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoResizeProvider; var _RuleProvider = _interopRequireDefault(require("../rules/RuleProvider")); var _inherits = _interopRequireDefault(require("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) { _RuleProvider.default.call(this, eventBus); var self = this; this.addRule('element.autoResize', function (context) { return self.canResize(context.elements, context.target); }); } AutoResizeProvider.$inject = ['eventBus']; (0, _inherits.default)(AutoResizeProvider, _RuleProvider.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":270,"inherits":347}],168:[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) { this._canvas = canvas; 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']; /** * 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":317,"min-dash":555}],169:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _AutoScroll = _interopRequireDefault(require("./AutoScroll")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_dragging.default], __init__: ['autoScroll'], autoScroll: ['type', _AutoScroll.default] }; exports.default = _default; },{"../dragging":197,"./AutoScroll":168}],170:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BendpointMove; exports.isReverse = isReverse; var _LayoutUtil = require("../../layout/LayoutUtil"); var round = Math.round; var RECONNECT_START = 'reconnectStart', RECONNECT_END = 'reconnectEnd', UPDATE_WAYPOINTS = 'updateWaypoints'; /** * Move bendpoints through drag and drop to add/remove bendpoints or reconnect connection. */ function BendpointMove(injector, eventBus, canvas, dragging, rules, modeling) { this._injector = injector; this.start = function (event, connection, bendpointIndex, insert) { var gfx = canvas.getGraphics(connection), source = connection.source, target = connection.target, waypoints = connection.waypoints, type; if (!insert && bendpointIndex === 0) { type = RECONNECT_START; } else if (!insert && bendpointIndex === waypoints.length - 1) { type = RECONNECT_END; } else { type = UPDATE_WAYPOINTS; } var command = type === UPDATE_WAYPOINTS ? 'connection.updateWaypoints' : 'connection.reconnect'; var allowed = rules.allowed(command, { connection: connection, source: source, target: target }); if (allowed === false) { allowed = rules.allowed(command, { connection: connection, source: target, target: source }); } if (allowed === false) { return; } dragging.init(event, 'bendpoint.move', { data: { connection: connection, connectionGfx: gfx, context: { allowed: allowed, bendpointIndex: bendpointIndex, connection: connection, source: source, target: target, insert: insert, type: type } } }); }; eventBus.on('bendpoint.move.hover', function (event) { var context = event.context, connection = context.connection, source = connection.source, target = connection.target, hover = event.hover, type = context.type; // cache hover state context.hover = hover; var allowed; if (!hover) { return; } var command = type === UPDATE_WAYPOINTS ? 'connection.updateWaypoints' : 'connection.reconnect'; allowed = context.allowed = rules.allowed(command, { connection: connection, source: type === RECONNECT_START ? hover : source, target: type === RECONNECT_END ? hover : target }); if (allowed) { context.source = type === RECONNECT_START ? hover : source; context.target = type === RECONNECT_END ? hover : target; return; } if (allowed === false) { allowed = context.allowed = rules.allowed(command, { connection: connection, source: type === RECONNECT_END ? hover : target, target: type === RECONNECT_START ? hover : source }); } if (allowed) { context.source = type === RECONNECT_END ? hover : target; context.target = type === RECONNECT_START ? hover : source; } }); eventBus.on(['bendpoint.move.out', 'bendpoint.move.cleanup'], function (event) { var context = event.context; context.hover = null; context.source = null; context.target = null; context.allowed = false; }); eventBus.on('bendpoint.move.end', function (event) { var context = event.context, allowed = context.allowed, bendpointIndex = context.bendpointIndex, connection = context.connection, insert = context.insert, newWaypoints = connection.waypoints.slice(), source = context.source, target = context.target, type = context.type, hints = context.hints || {}; // ensure integer values (important if zoom level was > 1 during move) var docking = { x: round(event.x), y: round(event.y) }; if (!allowed) { return false; } if (type === UPDATE_WAYPOINTS) { if (insert) { // insert new bendpoint newWaypoints.splice(bendpointIndex, 0, docking); } else { // swap previous waypoint with moved one newWaypoints[bendpointIndex] = docking; } // pass hints about actual moved bendpoint // useful for connection/label layout hints.bendpointMove = { insert: insert, bendpointIndex: bendpointIndex }; newWaypoints = this.cropWaypoints(connection, newWaypoints); modeling.updateWaypoints(connection, (0, _LayoutUtil.filterRedundantWaypoints)(newWaypoints), hints); } else { if (type === RECONNECT_START) { hints.docking = 'source'; if (isReverse(context)) { hints.docking = 'target'; hints.newWaypoints = newWaypoints.reverse(); } } else if (type === RECONNECT_END) { hints.docking = 'target'; if (isReverse(context)) { hints.docking = 'source'; hints.newWaypoints = newWaypoints.reverse(); } } modeling.reconnect(connection, source, target, docking, hints); } }, this); } BendpointMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'rules', 'modeling']; BendpointMove.prototype.cropWaypoints = function (connection, newWaypoints) { var connectionDocking = this._injector.get('connectionDocking', false); if (!connectionDocking) { return newWaypoints; } var waypoints = connection.waypoints; connection.waypoints = newWaypoints; connection.waypoints = connectionDocking.getCroppedWaypoints(connection); newWaypoints = connection.waypoints; connection.waypoints = waypoints; return newWaypoints; }; // helpers ////////// function isReverse(context) { var hover = context.hover, source = context.source, target = context.target, type = context.type; if (type === RECONNECT_START) { return hover && target && hover === target && source !== target; } if (type === RECONNECT_END) { return hover && source && hover === source && source !== target; } } },{"../../layout/LayoutUtil":300}],171:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BendpointMovePreview; var _tinySvg = require("tiny-svg"); var _BendpointUtil = require("./BendpointUtil"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var _BendpointMove = require("./BendpointMove"); var RECONNECT_START = 'reconnectStart', RECONNECT_END = 'reconnectEnd', UPDATE_WAYPOINTS = 'updateWaypoints'; var MARKER_OK = 'connect-ok', MARKER_NOT_OK = 'connect-not-ok', MARKER_CONNECT_HOVER = 'connect-hover', MARKER_CONNECT_UPDATING = 'djs-updating', MARKER_ELEMENT_HIDDEN = 'djs-element-hidden'; var HIGH_PRIORITY = 1100; /** * Preview connection while moving bendpoints. */ function BendpointMovePreview(bendpointMove, injector, eventBus, canvas) { this._injector = injector; var connectionPreview = injector.get('connectionPreview', false); eventBus.on('bendpoint.move.start', function (event) { var context = event.context, bendpointIndex = context.bendpointIndex, connection = context.connection, insert = context.insert, waypoints = connection.waypoints, newWaypoints = waypoints.slice(); context.waypoints = waypoints; if (insert) { // insert placeholder for new bendpoint newWaypoints.splice(bendpointIndex, 0, { x: event.x, y: event.y }); } connection.waypoints = newWaypoints; // add dragger gfx var draggerGfx = context.draggerGfx = (0, _BendpointUtil.addBendpoint)(canvas.getLayer('overlays')); (0, _tinySvg.classes)(draggerGfx).add('djs-dragging'); canvas.addMarker(connection, MARKER_ELEMENT_HIDDEN); canvas.addMarker(connection, MARKER_CONNECT_UPDATING); }); eventBus.on('bendpoint.move.hover', function (event) { var context = event.context, allowed = context.allowed, hover = context.hover, type = context.type; if (hover) { canvas.addMarker(hover, MARKER_CONNECT_HOVER); if (type === UPDATE_WAYPOINTS) { return; } if (allowed) { canvas.removeMarker(hover, MARKER_NOT_OK); canvas.addMarker(hover, MARKER_OK); } else if (allowed === false) { canvas.removeMarker(hover, MARKER_OK); canvas.addMarker(hover, MARKER_NOT_OK); } } }); eventBus.on(['bendpoint.move.out', 'bendpoint.move.cleanup'], HIGH_PRIORITY, function (event) { var context = event.context, hover = context.hover, target = context.target; if (hover) { canvas.removeMarker(hover, MARKER_CONNECT_HOVER); canvas.removeMarker(hover, target ? MARKER_OK : MARKER_NOT_OK); } }); eventBus.on('bendpoint.move.move', function (event) { var context = event.context, allowed = context.allowed, bendpointIndex = context.bendpointIndex, draggerGfx = context.draggerGfx, hover = context.hover, type = context.type, connection = context.connection, source = connection.source, target = connection.target, newWaypoints = connection.waypoints.slice(), bendpoint = { x: event.x, y: event.y }, hints = context.hints || {}, drawPreviewHints = {}; if (connectionPreview) { if (hints.connectionStart) { drawPreviewHints.connectionStart = hints.connectionStart; } if (hints.connectionEnd) { drawPreviewHints.connectionEnd = hints.connectionEnd; } if (type === RECONNECT_START) { if ((0, _BendpointMove.isReverse)(context)) { drawPreviewHints.connectionEnd = drawPreviewHints.connectionEnd || bendpoint; drawPreviewHints.source = target; drawPreviewHints.target = hover || source; newWaypoints = newWaypoints.reverse(); } else { drawPreviewHints.connectionStart = drawPreviewHints.connectionStart || bendpoint; drawPreviewHints.source = hover || source; drawPreviewHints.target = target; } } else if (type === RECONNECT_END) { if ((0, _BendpointMove.isReverse)(context)) { drawPreviewHints.connectionStart = drawPreviewHints.connectionStart || bendpoint; drawPreviewHints.source = hover || target; drawPreviewHints.target = source; newWaypoints = newWaypoints.reverse(); } else { drawPreviewHints.connectionEnd = drawPreviewHints.connectionEnd || bendpoint; drawPreviewHints.source = source; drawPreviewHints.target = hover || target; } } else { drawPreviewHints.noCropping = true; drawPreviewHints.noLayout = true; newWaypoints[bendpointIndex] = bendpoint; } if (type === UPDATE_WAYPOINTS) { newWaypoints = bendpointMove.cropWaypoints(connection, newWaypoints); } drawPreviewHints.waypoints = newWaypoints; connectionPreview.drawPreview(context, allowed, drawPreviewHints); } (0, _SvgTransformUtil.translate)(draggerGfx, event.x, event.y); }, this); eventBus.on(['bendpoint.move.end', 'bendpoint.move.cancel'], HIGH_PRIORITY, function (event) { var context = event.context, connection = context.connection, draggerGfx = context.draggerGfx, hover = context.hover, target = context.target, waypoints = context.waypoints; connection.waypoints = waypoints; // remove dragger gfx (0, _tinySvg.remove)(draggerGfx); canvas.removeMarker(connection, MARKER_CONNECT_UPDATING); canvas.removeMarker(connection, MARKER_ELEMENT_HIDDEN); if (hover) { canvas.removeMarker(hover, MARKER_OK); canvas.removeMarker(hover, target ? MARKER_OK : MARKER_NOT_OK); } if (connectionPreview) { connectionPreview.cleanUp(context); } }); } BendpointMovePreview.$inject = ['bendpointMove', 'injector', 'eventBus', 'canvas']; },{"../../util/SvgTransformUtil":328,"./BendpointMove":170,"./BendpointUtil":173,"tiny-svg":567}],172:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BendpointSnapping; var _minDash = require("min-dash"); var _SnapUtil = require("../snapping/SnapUtil"); 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 }); // only set snapped if actually snapped if (cx || snapPoints.vertical.indexOf(x) !== -1) { (0, _SnapUtil.setSnapped)(event, 'x', sx); } if (cy || snapPoints.horizontal.indexOf(y) !== -1) { (0, _SnapUtil.setSnapped)(event, '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', 'bendpoint.move.end'], 1500, function (event) { var context = event.context, snapPoints = getBendpointSnaps(context), hover = context.hover, hoverMid = hover && mid(hover), x = event.x, y = event.y, sx, sy; if (!snapPoints) { return; } // snap to hover mid sx = snapTo(hoverMid ? snapPoints.vertical.concat([hoverMid.x]) : snapPoints.vertical, x); sy = snapTo(hoverMid ? snapPoints.horizontal.concat([hoverMid.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 }); // only set snapped if actually snapped if (cx || snapPoints.vertical.indexOf(x) !== -1) { (0, _SnapUtil.setSnapped)(event, 'x', sx); } if (cy || snapPoints.horizontal.indexOf(y) !== -1) { (0, _SnapUtil.setSnapped)(event, 'y', sy); } }); } BendpointSnapping.$inject = ['eventBus']; },{"../snapping/SnapUtil":282,"min-dash":555}],173:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.toCanvasCoordinates = toCanvasCoordinates; exports.getConnectionIntersection = getConnectionIntersection; exports.addBendpoint = addBendpoint; exports.addSegmentDragger = addSegmentDragger; exports.calculateSegmentMoveRegion = calculateSegmentMoveRegion; exports.SEGMENT_DRAGGER_CLS = exports.BENDPOINT_CLS = void 0; var _Event = require("../../util/Event"); var _Geometry = require("../../util/Geometry"); var _tinySvg = require("tiny-svg"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var _LineIntersection = require("../../util/LineIntersection"); var BENDPOINT_CLS = 'djs-bendpoint'; exports.BENDPOINT_CLS = BENDPOINT_CLS; var SEGMENT_DRAGGER_CLS = 'djs-segment-dragger'; exports.SEGMENT_DRAGGER_CLS = SEGMENT_DRAGGER_CLS; 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 getConnectionIntersection(canvas, waypoints, event) { var localPosition = toCanvasCoordinates(canvas, event), intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, localPosition); return intersection; } 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, segmentStart, segmentEnd, alignment) { var draggerGfx = (0, _tinySvg.create)('g'); (0, _tinySvg.append)(parentGfx, draggerGfx); var width = 14, height = 3, padding = 11, hitWidth = calculateHitWidth(segmentStart, segmentEnd, alignment), 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 === 'v' ? 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, segmentStart, segmentEnd, alignment); (0, _tinySvg.classes)(groupGfx).add(SEGMENT_DRAGGER_CLS); (0, _tinySvg.classes)(groupGfx).add(alignment === 'h' ? 'horizontal' : 'vertical'); (0, _SvgTransformUtil.translate)(groupGfx, mid.x, mid.y); return groupGfx; } /** * Calculates region for segment move which is 2/3 of the full segment length * @param {number} segmentLength * * @return {number} */ function calculateSegmentMoveRegion(segmentLength) { return Math.abs(Math.round(segmentLength * 2 / 3)); } // helper ////////// function calculateHitWidth(segmentStart, segmentEnd, alignment) { var segmentLengthXAxis = segmentEnd.x - segmentStart.x, segmentLengthYAxis = segmentEnd.y - segmentStart.y; return alignment === 'h' ? calculateSegmentMoveRegion(segmentLengthXAxis) : calculateSegmentMoveRegion(segmentLengthYAxis); } },{"../../util/Event":317,"../../util/Geometry":318,"../../util/LineIntersection":321,"../../util/SvgTransformUtil":328,"tiny-svg":567}],174:[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 _EscapeUtil = require("../../util/EscapeUtil"); var _Geometry = require("../../util/Geometry"); var _tinySvg = require("tiny-svg"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); /** * A service that adds editable bendpoints to connections. */ function Bendpoints(eventBus, canvas, interactionEvents, bendpointMove, connectionSegmentMove) { /** * Returns true if intersection point is inside middle region of segment, adjusted by * optional threshold */ 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; } /** * Calculates the threshold from a connection's middle which fits the two-third-region */ function calculateIntersectionThreshold(connection, intersection) { var waypoints = connection.waypoints, relevantSegment, alignment, segmentLength, threshold; if (intersection.index <= 0 || intersection.bendpoint) { return null; } // segment relative to connection intersection relevantSegment = { start: waypoints[intersection.index - 1], end: waypoints[intersection.index] }; alignment = (0, _Geometry.pointsAligned)(relevantSegment.start, relevantSegment.end); if (!alignment) { return null; } if (alignment === 'h') { segmentLength = relevantSegment.end.x - relevantSegment.start.x; } else { segmentLength = relevantSegment.end.y - relevantSegment.start.y; } // calculate threshold relative to 2/3 of segment length threshold = (0, _BendpointUtil.calculateSegmentMoveRegion)(segmentLength) / 2; return threshold; } function activateBendpointMove(event, connection) { var waypoints = connection.waypoints, intersection = (0, _BendpointUtil.getConnectionIntersection)(canvas, waypoints, event), threshold; if (!intersection) { return; } threshold = calculateIntersectionThreshold(connection, intersection); if (isIntersectionMiddle(intersection, waypoints, threshold)) { 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, _EscapeUtil.escapeCSS)(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 getSegmentDragger(idx, parentGfx) { return (0, _minDom.query)('.djs-segment-dragger[data-segment-idx="' + idx + '"]', parentGfx); } 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, segmentDraggerGfx; for (var i = 1; i < waypoints.length; i++) { segmentStart = waypoints[i - 1]; segmentEnd = waypoints[i]; if ((0, _Geometry.pointsAligned)(segmentStart, segmentEnd)) { segmentDraggerGfx = (0, _BendpointUtil.addSegmentDragger)(gfx, segmentStart, segmentEnd); (0, _tinySvg.attr)(segmentDraggerGfx, { 'data-segment-idx': i }); bindInteractionEvents(segmentDraggerGfx, 'mousemove', connection); } } } 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); } } function updateFloatingBendpointPosition(parentGfx, intersection) { var floating = (0, _minDom.query)('.floating', parentGfx), point = intersection.point; if (!floating) { return; } (0, _SvgTransformUtil.translate)(floating, point.x, point.y); } function updateSegmentDraggerPosition(parentGfx, intersection, waypoints) { var draggerGfx = getSegmentDragger(intersection.index, parentGfx), segmentStart = waypoints[intersection.index - 1], segmentEnd = waypoints[intersection.index], point = intersection.point, mid = (0, _Geometry.getMidPoint)(segmentStart, segmentEnd), alignment = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd), draggerVisual, relativePosition; if (!draggerGfx) { return; } draggerVisual = getDraggerVisual(draggerGfx); relativePosition = { x: point.x - mid.x, y: point.y - mid.y }; if (alignment === 'v') { // rotate position relativePosition = { x: relativePosition.y, y: relativePosition.x }; } (0, _SvgTransformUtil.translate)(draggerVisual, relativePosition.x, relativePosition.y); } 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, intersection; if (waypoints) { bendpointsGfx = getBendpointsContainer(element, true); intersection = (0, _BendpointUtil.getConnectionIntersection)(canvas, waypoints, event.originalEvent); if (!intersection) { return; } updateFloatingBendpointPosition(bendpointsGfx, intersection); if (!intersection.bendpoint) { updateSegmentDraggerPosition(bendpointsGfx, intersection, waypoints); } } }); eventBus.on('element.mousedown', function (event) { var originalEvent = event.originalEvent, element = event.element; if (!element.waypoints) { return; } return activateBendpointMove(originalEvent, element); }); 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; this.getSegmentDragger = getSegmentDragger; } Bendpoints.$inject = ['eventBus', 'canvas', 'interactionEvents', 'bendpointMove', 'connectionSegmentMove']; // helper ///////////// function getDraggerVisual(draggerGfx) { return (0, _minDom.query)('.djs-visual', draggerGfx); } },{"../../util/EscapeUtil":316,"../../util/Geometry":318,"../../util/SvgTransformUtil":328,"./BendpointUtil":173,"min-dash":555,"min-dom":556,"tiny-svg":567}],175:[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, 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], intersection = (0, _BendpointUtil.getConnectionIntersection)(canvas, waypoints, event), direction, axis, dragPosition; 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' ? 'x' : 'y'; if (segmentStartIndex === 0) { segmentStart = getDocking(segmentStart, connection.source, axis); } if (segmentEndIndex === waypoints.length - 1) { segmentEnd = getDocking(segmentEnd, connection.target, axis); } if (intersection) { dragPosition = intersection.point; } else { // set to segment center as default dragPosition = { x: (segmentStart.x + segmentEnd.x) / 2, y: (segmentStart.y + segmentEnd.y) / 2 }; } context = { connection: connection, segmentStartIndex: segmentStartIndex, segmentEndIndex: segmentEndIndex, segmentStart: segmentStart, segmentEnd: segmentEnd, axis: axis, dragPosition: dragPosition }; dragging.init(event, dragPosition, '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 (event) { var context = event.context, connection = event.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 (event) { var context = event.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, event['d' + axis]), newSegmentEnd = axisAdd(segmentEnd, axis, event['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, event); // save segmentOffset in context context.newSegmentStartIndex = segmentStartIndex + segmentOffset; // redraw connection redrawConnection(event); }); eventBus.on('connectionSegment.move.hover', function (event) { event.context.hover = event.hover; canvas.addMarker(event.hover, MARKER_CONNECT_HOVER); }); eventBus.on(['connectionSegment.move.out', 'connectionSegment.move.cleanup'], function (event) { // remove connect marker // if it was added var hover = event.context.hover; if (hover) { canvas.removeMarker(hover, MARKER_CONNECT_HOVER); } }); eventBus.on('connectionSegment.move.cleanup', function (event) { var context = event.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 (event) { var context = event.context, connection = context.connection; connection.waypoints = context.originalWaypoints; redrawConnection(event); }); eventBus.on('connectionSegment.move.end', function (event) { var context = event.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', 'modeling']; },{"../../layout/LayoutUtil":300,"../../util/Geometry":318,"../../util/SvgTransformUtil":328,"./BendpointUtil":173,"tiny-svg":567}],176:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _rules = _interopRequireDefault(require("../rules")); var _Bendpoints = _interopRequireDefault(require("./Bendpoints")); var _BendpointMove = _interopRequireDefault(require("./BendpointMove")); var _BendpointMovePreview = _interopRequireDefault(require("./BendpointMovePreview")); var _ConnectionSegmentMove = _interopRequireDefault(require("./ConnectionSegmentMove")); var _BendpointSnapping = _interopRequireDefault(require("./BendpointSnapping")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_dragging.default, _rules.default], __init__: ['bendpoints', 'bendpointSnapping', 'bendpointMovePreview'], bendpoints: ['type', _Bendpoints.default], bendpointMove: ['type', _BendpointMove.default], bendpointMovePreview: ['type', _BendpointMovePreview.default], connectionSegmentMove: ['type', _ConnectionSegmentMove.default], bendpointSnapping: ['type', _BendpointSnapping.default] }; exports.default = _default; },{"../dragging":197,"../rules":272,"./BendpointMove":170,"./BendpointMovePreview":171,"./BendpointSnapping":172,"./Bendpoints":174,"./ConnectionSegmentMove":175}],177:[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":315}],178:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ChangeSupport = _interopRequireDefault(require("./ChangeSupport")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['changeSupport'], changeSupport: ['type', _ChangeSupport.default] }; exports.default = _default; },{"./ChangeSupport":177}],179:[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; }; },{}],180:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Clipboard = _interopRequireDefault(require("./Clipboard")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { clipboard: ['type', _Clipboard.default] }; exports.default = _default; },{"./Clipboard":179}],181:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Connect; exports.isReverse = isReverse; var _LayoutUtil = require("../../layout/LayoutUtil"); var _minDash = require("min-dash"); function Connect(eventBus, dragging, modeling, rules) { // rules function canConnect(source, target) { return rules.allowed('connection.create', { source: source, target: target }); } function canConnectReverse(source, target) { return canConnect(target, source); } // event handlers eventBus.on('connect.hover', function (event) { var context = event.context, start = context.start, hover = event.hover, canExecute; // cache hover state context.hover = hover; canExecute = context.canExecute = canConnect(start, hover); // ignore hover if ((0, _minDash.isNil)(canExecute)) { return; } if (canExecute !== false) { context.source = start; context.target = hover; return; } canExecute = context.canExecute = canConnectReverse(start, hover); // ignore hover if ((0, _minDash.isNil)(canExecute)) { return; } if (canExecute !== false) { context.source = hover; context.target = start; } }); eventBus.on(['connect.out', 'connect.cleanup'], function (event) { var context = event.context; context.hover = null; context.source = null; context.target = null; context.canExecute = false; }); eventBus.on('connect.end', function (event) { var context = event.context, canExecute = context.canExecute, connectionStart = context.connectionStart, connectionEnd = { x: event.x, y: event.y }, source = context.source, target = context.target; if (!canExecute) { return false; } var attrs = null, hints = { connectionStart: isReverse(context) ? connectionEnd : connectionStart, connectionEnd: isReverse(context) ? connectionStart : connectionEnd }; if ((0, _minDash.isObject)(canExecute)) { attrs = canExecute; } modeling.connect(source, target, attrs, hints); }); // API /** * Start connect operation. * * @param {DOMEvent} event * @param {djs.model.Base} start * @param {Point} [connectionStart] * @param {boolean} [autoActivate=false] */ this.start = function (event, start, connectionStart, autoActivate) { if (!(0, _minDash.isObject)(connectionStart)) { autoActivate = connectionStart; connectionStart = (0, _LayoutUtil.getMid)(start); } dragging.init(event, 'connect', { autoActivate: autoActivate, data: { shape: start, context: { start: start, connectionStart: connectionStart } } }); }; } Connect.$inject = ['eventBus', 'dragging', 'modeling', 'rules']; // helpers ////////// function isReverse(context) { var hover = context.hover, source = context.source, target = context.target; return hover && source && hover === source && source !== target; } },{"../../layout/LayoutUtil":300,"min-dash":555}],182:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ConnectPreview; var _Connect = require("./Connect"); var HIGH_PRIORITY = 1100, LOW_PRIORITY = 900; var MARKER_OK = 'connect-ok', MARKER_NOT_OK = 'connect-not-ok'; /** * Shows connection preview during connect. * * @param {didi.Injector} injector * @param {EventBus} eventBus * @param {Canvas} canvas */ function ConnectPreview(injector, eventBus, canvas) { var connectionPreview = injector.get('connectionPreview', false); connectionPreview && eventBus.on('connect.move', function (event) { var context = event.context, canConnect = context.canExecute, hover = context.hover, source = context.source, start = context.start, startPosition = context.startPosition, connectionStart = context.connectionStart, connectionEnd = context.connectionEnd, target = context.target; if (!connectionStart) { connectionStart = (0, _Connect.isReverse)(context) ? { x: event.x, y: event.y } : startPosition; } if (!connectionEnd) { connectionEnd = (0, _Connect.isReverse)(context) ? startPosition : { x: event.x, y: event.y }; } connectionPreview.drawPreview(context, canConnect, { source: source || start, target: target || hover, connectionStart: connectionStart, connectionEnd: connectionEnd }); }); eventBus.on('connect.hover', LOW_PRIORITY, function (event) { var context = event.context, hover = event.hover, canExecute = context.canExecute; // ignore hover if (canExecute === null) { return; } canvas.addMarker(hover, canExecute ? MARKER_OK : MARKER_NOT_OK); }); eventBus.on(['connect.out', 'connect.cleanup'], HIGH_PRIORITY, function (event) { var hover = event.hover; if (hover) { canvas.removeMarker(hover, MARKER_OK); canvas.removeMarker(hover, MARKER_NOT_OK); } }); connectionPreview && eventBus.on('connect.cleanup', function (event) { connectionPreview.cleanUp(event.context); }); } ConnectPreview.$inject = ['injector', 'eventBus', 'canvas']; },{"./Connect":181}],183:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _selection = _interopRequireDefault(require("../selection")); var _rules = _interopRequireDefault(require("../rules")); var _dragging = _interopRequireDefault(require("../dragging")); var _Connect = _interopRequireDefault(require("./Connect")); var _ConnectPreview = _interopRequireDefault(require("./ConnectPreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_selection.default, _rules.default, _dragging.default], __init__: ['connectPreview'], connect: ['type', _Connect.default], connectPreview: ['type', _ConnectPreview.default] }; exports.default = _default; },{"../dragging":197,"../rules":272,"../selection":278,"./Connect":181,"./ConnectPreview":182}],184:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ConnectionPreview; var _tinySvg = require("tiny-svg"); var _minDash = require("min-dash"); var _LayoutUtil = require("../../layout/LayoutUtil"); var MARKER_CONNECTION_PREVIEW = 'djs-connection-preview'; /** * Draws connection preview. Optionally, this can use layouter and connection docking to draw * better looking previews. * * @param {didi.Injector} injector * @param {Canvas} canvas * @param {GraphicsFactory} graphicsFactory * @param {ElementFactory} elementFactory */ function ConnectionPreview(injector, canvas, graphicsFactory, elementFactory) { this._canvas = canvas; this._graphicsFactory = graphicsFactory; this._elementFactory = elementFactory; // optional components this._connectionDocking = injector.get('connectionDocking', false); this._layouter = injector.get('layouter', false); } ConnectionPreview.$inject = ['injector', 'canvas', 'graphicsFactory', 'elementFactory']; /** * Draw connection preview. * * Provide at least one of and to create a preview. * In the clean up stage, call `connectionPreview#cleanUp` with the context to remove preview. * * @param {Object} context * @param {Object|boolean} canConnect * @param {Object} hints * @param {djs.model.shape} [hints.source] source element * @param {djs.model.shape} [hints.target] target element * @param {Point} [hints.connectionStart] connection preview start * @param {Point} [hints.connectionEnd] connection preview end * @param {Array} [hints.waypoints] provided waypoints for preview * @param {boolean} [hints.noLayout] true if preview should not be laid out * @param {boolean} [hints.noCropping] true if preview should not be cropped * @param {boolean} [hints.noNoop] true if simple connection should not be drawn */ ConnectionPreview.prototype.drawPreview = function (context, canConnect, hints) { hints = hints || {}; var connectionPreviewGfx = context.connectionPreviewGfx, getConnection = context.getConnection, source = hints.source, target = hints.target, waypoints = hints.waypoints, connectionStart = hints.connectionStart, connectionEnd = hints.connectionEnd, noLayout = hints.noLayout, noCropping = hints.noCropping, noNoop = hints.noNoop, connection; var self = this; if (!connectionPreviewGfx) { connectionPreviewGfx = context.connectionPreviewGfx = this.createConnectionPreviewGfx(); } (0, _tinySvg.clear)(connectionPreviewGfx); if (!getConnection) { getConnection = context.getConnection = cacheReturnValues(function (canConnect, source, target) { return self.getConnection(canConnect, source, target); }); } if (canConnect) { connection = getConnection(canConnect, source, target); } if (!connection) { !noNoop && this.drawNoopPreview(connectionPreviewGfx, hints); return; } connection.waypoints = waypoints || []; // optional layout if (this._layouter && !noLayout) { connection.waypoints = this._layouter.layoutConnection(connection, { source: source, target: target, connectionStart: connectionStart, connectionEnd: connectionEnd, waypoints: hints.waypoints || connection.waypoints }); } // fallback if no waypoints were provided nor created with layouter if (!connection.waypoints || !connection.waypoints.length) { connection.waypoints = [source ? (0, _LayoutUtil.getMid)(source) : connectionStart, target ? (0, _LayoutUtil.getMid)(target) : connectionEnd]; } // optional cropping if (this._connectionDocking && (source || target) && !noCropping) { connection.waypoints = this._connectionDocking.getCroppedWaypoints(connection, source, target); } this._graphicsFactory.drawConnection(connectionPreviewGfx, connection); }; /** * Draw simple connection between source and target or provided points. * * @param {SVGElement} connectionPreviewGfx container for the connection * @param {Object} hints * @param {djs.model.shape} [hints.source] source element * @param {djs.model.shape} [hints.target] target element * @param {Point} [hints.connectionStart] required if source is not provided * @param {Point} [hints.connectionEnd] required if target is not provided */ ConnectionPreview.prototype.drawNoopPreview = function (connectionPreviewGfx, hints) { var source = hints.source, target = hints.target, start = hints.connectionStart || (0, _LayoutUtil.getMid)(source), end = hints.connectionEnd || (0, _LayoutUtil.getMid)(target); var waypoints = this.cropWaypoints(start, end, source, target); var connection = this.createNoopConnection(waypoints[0], waypoints[1]); (0, _tinySvg.append)(connectionPreviewGfx, connection); }; /** * Return cropped waypoints. * * @param {Point} start * @param {Point} end * @param {djs.model.shape} source * @param {djs.model.shape} target * * @returns {Array} */ ConnectionPreview.prototype.cropWaypoints = function (start, end, source, target) { var graphicsFactory = this._graphicsFactory, sourcePath = source && graphicsFactory.getShapePath(source), targetPath = target && graphicsFactory.getShapePath(target), connectionPath = graphicsFactory.getConnectionPath({ waypoints: [start, end] }); start = source && (0, _LayoutUtil.getElementLineIntersection)(sourcePath, connectionPath, true) || start; end = target && (0, _LayoutUtil.getElementLineIntersection)(targetPath, connectionPath, false) || end; return [start, end]; }; /** * Remove connection preview container if it exists. * * @param {Object} [context] * @param {SVGElement} [context.connectionPreviewGfx] preview container */ ConnectionPreview.prototype.cleanUp = function (context) { if (context && context.connectionPreviewGfx) { (0, _tinySvg.remove)(context.connectionPreviewGfx); } }; /** * Get connection that connects source and target. * * @param {Object|boolean} canConnect * * @returns {djs.model.connection} */ ConnectionPreview.prototype.getConnection = function (canConnect) { var attrs = ensureConnectionAttrs(canConnect); return this._elementFactory.createConnection(attrs); }; /** * Add and return preview graphics. * * @returns {SVGElement} */ ConnectionPreview.prototype.createConnectionPreviewGfx = function () { var gfx = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(gfx, { pointerEvents: 'none' }); (0, _tinySvg.classes)(gfx).add(MARKER_CONNECTION_PREVIEW); (0, _tinySvg.append)(this._canvas.getDefaultLayer(), gfx); return gfx; }; /** * Create and return simple connection. * * @param {Point} start * @param {Point} end * * @returns {SVGElement} */ ConnectionPreview.prototype.createNoopConnection = function (start, end) { var connection = (0, _tinySvg.create)('polyline'); (0, _tinySvg.attr)(connection, { 'stroke': '#333', 'strokeDasharray': [1], 'strokeWidth': 2, 'pointer-events': 'none' }); (0, _tinySvg.attr)(connection, { 'points': [start.x, start.y, end.x, end.y] }); return connection; }; // helpers ////////// /** * Returns function that returns cached return values referenced by stringified first argument. * * @param {Function} fn * * @return {Function} */ function cacheReturnValues(fn) { var returnValues = {}; /** * Return cached return value referenced by stringified first argument. * * @returns {*} */ return function (firstArgument) { var key = JSON.stringify(firstArgument); var returnValue = returnValues[key]; if (!returnValue) { returnValue = returnValues[key] = fn.apply(null, arguments); } return returnValue; }; } /** * Ensure connection attributes is object. * * @param {Object|boolean} canConnect * * @returns {Object} */ function ensureConnectionAttrs(canConnect) { if ((0, _minDash.isObject)(canConnect)) { return canConnect; } else { return {}; } } },{"../../layout/LayoutUtil":300,"min-dash":555,"tiny-svg":567}],185:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ConnectionPreview = _interopRequireDefault(require("./ConnectionPreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['connectionPreview'], connectionPreview: ['type', _ConnectionPreview.default] }; exports.default = _default; },{"./ConnectionPreview":184}],186:[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'; var DEFAULT_PRIORITY = 1000; /** * 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._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 {number} [priority=1000] * @param {ContextPadProvider} provider * * @example * const contextPadProvider = { * getContextPadEntries: function(element) { * return function(entries) { * return { * ...entries, * 'entry-1': { * label: 'My Entry', * action: function() { alert("I have been clicked!"); } * } * }; * } * } * }; * * contextPad.registerProvider(800, contextPadProvider); */ ContextPad.prototype.registerProvider = function (priority, provider) { if (!provider) { provider = priority; priority = DEFAULT_PRIORITY; } this._eventBus.on('contextPad.getProviders', priority, function (event) { event.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 providers = this._getProviders(); var entries = {}; // loop through all providers and their entries. // group entries by id so that overriding an entry is possible (0, _minDash.forEach)(providers, function (provider) { var entriesOrUpdater = provider.getContextPadEntries(element); if ((0, _minDash.isFunction)(entriesOrUpdater)) { entries = entriesOrUpdater(entries); } else { (0, _minDash.forEach)(entriesOrUpdater, 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._getProviders = function (id) { var event = this._eventBus.createEvent({ type: 'contextPad.getProviders', providers: [] }); this._eventBus.fire(event); return event.providers; }; 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":555,"min-dom":556}],187:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("../interaction-events")); var _overlays = _interopRequireDefault(require("../overlays")); var _ContextPad = _interopRequireDefault(require("./ContextPad")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_interactionEvents.default, _overlays.default], contextPad: ['type', _ContextPad.default] }; exports.default = _default; },{"../interaction-events":211,"../overlays":256,"./ContextPad":186}],188:[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"); /** * @typedef {Function} listener * * @param {Object} context * @param {Array} context.elements * * @returns {Array|boolean} - Return elements to be copied or false to disallow * copying. */ /** * @typedef {Function} listener * * @param {Object} context * @param {Object} context.descriptor * @param {djs.model.Base} context.element * @param {Array} context.elements */ /** * @typedef {Function} listener * * @param {Object} context * @param {Object} context.elements * @param {Object} context.tree */ /** * @typedef {Function} listener * * @param {Object} context * @param {Object} context.cache - Already created elements. * @param {Object} context.descriptor */ /** * @typedef {Function} listener * * @param {Object} context * @param {Object} context.hints - Add hints before pasting. */ /** * Copy and paste elements. * * @param {Canvas} canvas * @param {Create} create * @param {Clipboard} clipboard * @param {ElementFactory} elementFactory * @param {EventBus} eventBus * @param {Modeling} modeling * @param {Mouse} mouse * @param {Rules} rules */ function CopyPaste(canvas, create, clipboard, elementFactory, eventBus, modeling, mouse, rules) { this._canvas = canvas; this._create = create; this._clipboard = clipboard; this._elementFactory = elementFactory; this._eventBus = eventBus; this._modeling = modeling; this._mouse = mouse; this._rules = rules; eventBus.on('copyPaste.copyElement', function (context) { var descriptor = context.descriptor, element = context.element, elements = context.elements; // default priority (priority = 1) descriptor.priority = 1; descriptor.id = element.id; var parentCopied = (0, _minDash.find)(elements, function (e) { return e === element.parent; }); // do NOT reference parent if parent wasn't copied if (parentCopied) { descriptor.parent = element.parent.id; } // attachers (priority = 2) if (isAttacher(element)) { descriptor.priority = 2; descriptor.host = element.host.id; } // connections (priority = 3) if (isConnection(element)) { descriptor.priority = 3; descriptor.source = element.source.id; descriptor.target = element.target.id; descriptor.waypoints = copyWaypoints(element); } // labels (priority = 4) if (isLabel(element)) { descriptor.priority = 4; descriptor.labelTarget = element.labelTarget.id; } (0, _minDash.forEach)(['x', 'y', 'width', 'height'], function (property) { if ((0, _minDash.isNumber)(element[property])) { descriptor[property] = element[property]; } }); descriptor.hidden = element.hidden; descriptor.collapsed = element.collapsed; }); eventBus.on('copyPaste.pasteElements', function (context) { var hints = context.hints; (0, _minDash.assign)(hints, { createElementsBehavior: false }); }); } CopyPaste.$inject = ['canvas', 'create', 'clipboard', 'elementFactory', 'eventBus', 'modeling', 'mouse', 'rules']; /** * Copy elements. * * @param {Array} elements * * @returns {Object} */ CopyPaste.prototype.copy = function (elements) { var allowed, tree; if (!(0, _minDash.isArray)(elements)) { elements = elements ? [elements] : []; } allowed = this._eventBus.fire('copyPaste.canCopyElements', { elements: elements }); if (allowed === false) { tree = {}; } else { tree = this.createTree((0, _minDash.isArray)(allowed) ? allowed : elements); } // we set an empty tree, selection of elements // to copy was empty. this._clipboard.set(tree); this._eventBus.fire('copyPaste.elementsCopied', { elements: elements, tree: tree }); return tree; }; /** * Paste elements. * * @param {Object} [context] * @param {djs.model.base} [context.element] - Parent. * @param {Point} [context.point] - Position. * @param {Object} [context.hints] - Hints. */ CopyPaste.prototype.paste = function (context) { var tree = this._clipboard.get(); if (this._clipboard.isEmpty()) { return; } var hints = context && context.hints || {}; this._eventBus.fire('copyPaste.pasteElements', { hints: hints }); var elements = this._createElements(tree); // paste directly if (context && context.element && context.point) { return this._paste(elements, context.element, context.point, hints); } this._create.start(this._mouse.getLastMoveEvent(), elements, { hints: hints || {} }); }; /** * Paste elements directly. * * @param {Array} elements * @param {djs.model.base} target * @param {Point} position * @param {Object} [hints] */ CopyPaste.prototype._paste = function (elements, target, position, hints) { // make sure each element has x and y (0, _minDash.forEach)(elements, function (element) { if (!(0, _minDash.isNumber)(element.x)) { element.x = 0; } if (!(0, _minDash.isNumber)(element.y)) { element.y = 0; } }); var bbox = (0, _Elements.getBBox)(elements); // center elements around cursor (0, _minDash.forEach)(elements, function (element) { if (isConnection(element)) { element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint) { return { x: waypoint.x - bbox.x - bbox.width / 2, y: waypoint.y - bbox.y - bbox.height / 2 }; }); } (0, _minDash.assign)(element, { x: element.x - bbox.x - bbox.width / 2, y: element.y - bbox.y - bbox.height / 2 }); }); return this._modeling.createElements(elements, position, target, (0, _minDash.assign)({}, hints)); }; /** * Create elements from tree. */ CopyPaste.prototype._createElements = function (tree) { var self = this; var eventBus = this._eventBus; var cache = {}; var elements = []; (0, _minDash.forEach)(tree, function (branch, depth) { depth = parseInt(depth, 10); // sort by priority branch = (0, _minDash.sortBy)(branch, 'priority'); (0, _minDash.forEach)(branch, function (descriptor) { // remove priority var attrs = (0, _minDash.assign)({}, (0, _minDash.omit)(descriptor, ['priority'])); if (cache[descriptor.parent]) { attrs.parent = cache[descriptor.parent]; } else { delete attrs.parent; } eventBus.fire('copyPaste.pasteElement', { cache: cache, descriptor: attrs }); var element; if (isConnection(attrs)) { attrs.source = cache[descriptor.source]; attrs.target = cache[descriptor.target]; element = cache[descriptor.id] = self.createConnection(attrs); elements.push(element); return; } if (isLabel(attrs)) { attrs.labelTarget = cache[attrs.labelTarget]; element = cache[descriptor.id] = self.createLabel(attrs); elements.push(element); return; } if (attrs.host) { attrs.host = cache[attrs.host]; } element = cache[descriptor.id] = self.createShape(attrs); elements.push(element); }); }); return elements; }; CopyPaste.prototype.createConnection = function (attrs) { var connection = this._elementFactory.createConnection((0, _minDash.omit)(attrs, ['id'])); return connection; }; CopyPaste.prototype.createLabel = function (attrs) { var label = this._elementFactory.createLabel((0, _minDash.omit)(attrs, ['id'])); return label; }; CopyPaste.prototype.createShape = function (attrs) { var shape = this._elementFactory.createShape((0, _minDash.omit)(attrs, ['id'])); return shape; }; /** * Check wether element has relations to other elements e.g. attachers, labels and connections. * * @param {Object} element * @param {Array} elements * * @returns {boolean} */ CopyPaste.prototype.hasRelations = function (element, elements) { var labelTarget, source, target; if (isConnection(element)) { 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 (isLabel(element)) { labelTarget = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.labelTarget.id })); if (!labelTarget) { return false; } } return true; }; /** * Create a tree-like structure from elements. * * @example * tree: { * 0: [ * { id: 'Shape_1', priority: 1, ... }, * { id: 'Shape_2', priority: 1, ... }, * { id: 'Connection_1', source: 'Shape_1', target: 'Shape_2', priority: 3, ... }, * ... * ], * 1: [ * { id: 'Shape_3', parent: 'Shape1', priority: 1, ... }, * ... * ] * }; * * @param {Array} elements * * @return {Object} */ CopyPaste.prototype.createTree = function (elements) { var rules = this._rules, self = this; var tree = {}, elementsData = []; var parents = (0, _Elements.getParents)(elements); function canCopy(element, elements) { return rules.allowed('element.copy', { element: element, elements: elements }); } function addElementData(element, depth) { // (1) check wether element has already been added var foundElementData = (0, _minDash.find)(elementsData, function (elementsData) { return element === elementsData.element; }); // (2) add element if not already added if (!foundElementData) { elementsData.push({ element: element, depth: depth }); return; } // (3) update depth if (foundElementData.depth < depth) { elementsData = removeElementData(foundElementData, elementsData); elementsData.push({ element: foundElementData.element, depth: depth }); } } function removeElementData(elementData, elementsData) { var index = elementsData.indexOf(elementData); if (index !== -1) { elementsData.splice(index, 1); } return elementsData; } // (1) add elements (0, _Elements.eachElement)(parents, function (element, _index, depth) { // do NOT add external labels directly if (isLabel(element)) { return; } // always copy external labels (0, _minDash.forEach)(element.labels, function (label) { addElementData(label, depth); }); function addRelatedElements(elements) { elements && elements.length && (0, _minDash.forEach)(elements, function (element) { // add external labels (0, _minDash.forEach)(element.labels, function (label) { addElementData(label, depth); }); addElementData(element, depth); }); } (0, _minDash.forEach)([element.attachers, element.incoming, element.outgoing], addRelatedElements); addElementData(element, depth); return element.children; }); elements = (0, _minDash.map)(elementsData, function (elementData) { return elementData.element; }); // (2) copy elements elementsData = (0, _minDash.map)(elementsData, function (elementData) { elementData.descriptor = {}; self._eventBus.fire('copyPaste.copyElement', { descriptor: elementData.descriptor, element: elementData.element, elements: elements }); return elementData; }); // (3) sort elements by priority elementsData = (0, _minDash.sortBy)(elementsData, function (elementData) { return elementData.descriptor.priority; }); elements = (0, _minDash.map)(elementsData, function (elementData) { return elementData.element; }); // (4) create tree (0, _minDash.forEach)(elementsData, function (elementData) { var depth = elementData.depth; if (!self.hasRelations(elementData.element, elements)) { removeElement(elementData.element, elements); return; } if (!canCopy(elementData.element, elements)) { removeElement(elementData.element, elements); return; } if (!tree[depth]) { tree[depth] = []; } tree[depth].push(elementData.descriptor); }); return tree; }; // helpers ////////// function isAttacher(element) { return !!element.host; } function isConnection(element) { return !!element.waypoints; } function isLabel(element) { return !!element.labelTarget; } function copyWaypoints(element) { return (0, _minDash.map)(element.waypoints, function (waypoint) { waypoint = copyWaypoint(waypoint); if (waypoint.original) { waypoint.original = copyWaypoint(waypoint.original); } return waypoint; }); } function copyWaypoint(waypoint) { return (0, _minDash.assign)({}, waypoint); } function removeElement(element, elements) { var index = elements.indexOf(element); if (index === -1) { return elements; } return elements.splice(index, 1); } },{"../../util/Elements":315,"min-dash":555}],189:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _clipboard = _interopRequireDefault(require("../clipboard")); var _create = _interopRequireDefault(require("../create")); var _mouse = _interopRequireDefault(require("../mouse")); var _rules = _interopRequireDefault(require("../rules")); var _CopyPaste = _interopRequireDefault(require("./CopyPaste")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_clipboard.default, _create.default, _mouse.default, _rules.default], __init__: ['copyPaste'], copyPaste: ['type', _CopyPaste.default] }; exports.default = _default; },{"../clipboard":180,"../create":192,"../mouse":248,"../rules":272,"./CopyPaste":188}],190:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Create; var _minDash = require("min-dash"); var _Elements = require("../../util/Elements"); var MARKER_OK = 'drop-ok', MARKER_NOT_OK = 'drop-not-ok', MARKER_ATTACH = 'attach-ok', MARKER_NEW_PARENT = 'new-parent'; var PREFIX = 'create'; var HIGH_PRIORITY = 2000; /** * Create new elements through drag and drop. * * @param {Canvas} canvas * @param {Dragging} dragging * @param {EventBus} eventBus * @param {Modeling} modeling * @param {Rules} rules */ function Create(canvas, dragging, eventBus, modeling, rules) { // rules ////////// /** * Check wether elements can be created. * * @param {Array} elements * @param {djs.model.Base} target * @param {Point} position * @param {djs.model.Base} [source] * * @returns {boolean|null|Object} */ function canCreate(elements, target, position, source, hints) { if (!target) { return false; } // ignore child elements and external labels elements = (0, _minDash.filter)(elements, function (element) { var labelTarget = element.labelTarget; return !element.parent && !(isLabel(element) && elements.indexOf(labelTarget) !== -1); }); var shape = (0, _minDash.find)(elements, function (element) { return !isConnection(element); }); var attach = false, connect = false, create = false; // (1) attaching single shapes if (isSingleShape(elements)) { attach = rules.allowed('shape.attach', { position: position, shape: shape, target: target }); } if (!attach) { // (2) creating elements if (isSingleShape(elements)) { create = rules.allowed('shape.create', { position: position, shape: shape, source: source, target: target }); } else { create = rules.allowed('elements.create', { elements: elements, position: position, target: target }); } } var connectionTarget = hints.connectionTarget; // (3) appending single shapes if (create || attach) { if (shape && source) { connect = rules.allowed('connection.create', { source: connectionTarget === source ? shape : source, target: connectionTarget === source ? source : shape, hints: { targetParent: target, targetAttach: attach } }); } return { attach: attach, connect: connect }; } // ignore wether or not elements can be created if (create === null || attach === null) { return null; } return false; } 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); } }); } // event handling ////////// eventBus.on(['create.move', 'create.hover'], function (event) { var context = event.context, elements = context.elements, hover = event.hover, source = context.source, hints = context.hints || {}; if (!hover) { context.canExecute = false; context.target = null; return; } ensureConstraints(event); var position = { x: event.x, y: event.y }; var canExecute = context.canExecute = hover && canCreate(elements, hover, position, source, hints); 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.end', 'create.out', 'create.cleanup'], function (event) { var hover = event.hover; if (hover) { setMarker(hover, null); } }); eventBus.on('create.end', function (event) { var context = event.context, source = context.source, shape = context.shape, elements = context.elements, target = context.target, canExecute = context.canExecute, attach = canExecute && canExecute.attach, connect = canExecute && canExecute.connect, hints = context.hints || {}; if (canExecute === false || !target) { return false; } ensureConstraints(event); var position = { x: event.x, y: event.y }; if (connect) { shape = modeling.appendShape(source, shape, position, target, { attach: attach, connection: connect === true ? {} : connect, connectionTarget: hints.connectionTarget }); } else { elements = modeling.createElements(elements, position, target, (0, _minDash.assign)({}, hints, { attach: attach })); // update shape shape = (0, _minDash.find)(elements, function (element) { return !isConnection(element); }); } // update elements and shape (0, _minDash.assign)(context, { elements: elements, shape: shape }); (0, _minDash.assign)(event, { elements: elements, shape: shape }); }); function cancel() { var context = dragging.context(); if (context && context.prefix === PREFIX) { dragging.cancel(); } } // cancel on that is not result of eventBus.on('create.init', function () { eventBus.on('elements.changed', cancel); eventBus.once(['create.cancel', 'create.end'], HIGH_PRIORITY, function () { eventBus.off('elements.changed', cancel); }); }); // API ////////// this.start = function (event, elements, context) { if (!(0, _minDash.isArray)(elements)) { elements = [elements]; } var shape = (0, _minDash.find)(elements, function (element) { return !isConnection(element); }); if (!shape) { // at least one shape is required return; } context = (0, _minDash.assign)({ elements: elements, hints: {}, shape: shape }, context || {}); // make sure each element has x and y (0, _minDash.forEach)(elements, function (element) { if (!(0, _minDash.isNumber)(element.x)) { element.x = 0; } if (!(0, _minDash.isNumber)(element.y)) { element.y = 0; } }); var bbox = (0, _Elements.getBBox)(elements); // center elements around cursor (0, _minDash.forEach)(elements, function (element) { if (isConnection(element)) { element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint) { return { x: waypoint.x - bbox.x - bbox.width / 2, y: waypoint.y - bbox.y - bbox.height / 2 }; }); } (0, _minDash.assign)(element, { x: element.x - bbox.x - bbox.width / 2, y: element.y - bbox.y - bbox.height / 2 }); }); dragging.init(event, PREFIX, { cursor: 'grabbing', autoActivate: true, data: { shape: shape, elements: elements, context: context } }); }; } Create.$inject = ['canvas', 'dragging', 'eventBus', 'modeling', 'rules']; // helpers ////////// function ensureConstraints(event) { var context = event.context, createConstraints = context.createConstraints; if (!createConstraints) { return; } if (createConstraints.left) { event.x = Math.max(event.x, createConstraints.left); } if (createConstraints.right) { event.x = Math.min(event.x, createConstraints.right); } if (createConstraints.top) { event.y = Math.max(event.y, createConstraints.top); } if (createConstraints.bottom) { event.y = Math.min(event.y, createConstraints.bottom); } } function isConnection(element) { return !!element.waypoints; } function isSingleShape(elements) { return elements && elements.length === 1 && !isConnection(elements[0]); } function isLabel(element) { return !!element.labelTarget; } },{"../../util/Elements":315,"min-dash":555}],191:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreatePreview; var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var _GraphicsUtil = require("../../util/GraphicsUtil"); var _tinySvg = require("tiny-svg"); var LOW_PRIORITY = 750; function CreatePreview(canvas, eventBus, graphicsFactory, previewSupport, styles) { function createDragGroup(elements) { var dragGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events'])); var childrenGfx = (0, _tinySvg.create)('g'); elements.forEach(function (element) { // create graphics var gfx; if (element.hidden) { return; } if (element.waypoints) { gfx = graphicsFactory._createContainer('connection', childrenGfx); graphicsFactory.drawConnection((0, _GraphicsUtil.getVisual)(gfx), element); } else { gfx = graphicsFactory._createContainer('shape', childrenGfx); graphicsFactory.drawShape((0, _GraphicsUtil.getVisual)(gfx), element); (0, _SvgTransformUtil.translate)(gfx, element.x, element.y); } // add preview previewSupport.addDragger(element, dragGroup, gfx); }); return dragGroup; } eventBus.on('create.move', LOW_PRIORITY, function (event) { var hover = event.hover, context = event.context, elements = context.elements, dragGroup = context.dragGroup; // lazily create previews if (!dragGroup) { dragGroup = context.dragGroup = createDragGroup(elements); } var defaultLayer; if (hover) { if (!dragGroup.parentNode) { defaultLayer = canvas.getDefaultLayer(); (0, _tinySvg.append)(defaultLayer, dragGroup); } (0, _SvgTransformUtil.translate)(dragGroup, event.x, event.y); } else { (0, _tinySvg.remove)(dragGroup); } }); eventBus.on('create.cleanup', function (event) { var context = event.context, dragGroup = context.dragGroup; if (dragGroup) { (0, _tinySvg.remove)(dragGroup); } }); } CreatePreview.$inject = ['canvas', 'eventBus', 'graphicsFactory', 'previewSupport', 'styles']; },{"../../util/GraphicsUtil":319,"../../util/SvgTransformUtil":328,"tiny-svg":567}],192:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _previewSupport = _interopRequireDefault(require("../preview-support")); var _rules = _interopRequireDefault(require("../rules")); var _selection = _interopRequireDefault(require("../selection")); var _Create = _interopRequireDefault(require("./Create")); var _CreatePreview = _interopRequireDefault(require("./CreatePreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_dragging.default, _previewSupport.default, _rules.default, _selection.default], __init__: ['create', 'createPreview'], create: ['type', _Create.default], createPreview: ['type', _CreatePreview.default] }; exports.default = _default; },{"../dragging":197,"../preview-support":262,"../rules":272,"../selection":278,"./Create":190,"./CreatePreview":191}],193:[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":555}],194:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _DistributeElements = _interopRequireDefault(require("./DistributeElements")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['distributeElements'], distributeElements: ['type', _DistributeElements.default] }; exports.default = _default; },{"./DistributeElements":193}],195:[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 if elements still exist * * 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, elementRegistry) { 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); } function restoreSelection(previousSelection) { var existingSelection = previousSelection.filter(function (element) { return elementRegistry.get(element.id); }); existingSelection.length && selection.select(existingSelection); } // 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) { restoreSelection(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', 'elementRegistry']; },{"../../util/ClickTrap":312,"../../util/Cursor":314,"../../util/Event":317,"../../util/PositionUtil":325,"min-dash":555,"min-dom":556}],196:[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"); var HIGH_PRIORITY = 1500; /** * Browsers may swallow certain events (hover, out ...) 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 * * 1) have a hover state after a successful drag.move event * 2) have an out event when dragging leaves an element * * @param {EventBus} eventBus * @param {Dragging} dragging * @param {ElementRegistry} elementRegistry */ function HoverFix(eventBus, dragging, elementRegistry) { var self = this; /** * Make sure we are god damn hovering! * * @param {Event} dragging event */ function ensureHover(event) { if (event.hover) { return; } var originalEvent = event.originalEvent; var gfx = self._findTargetGfx(originalEvent); var element = gfx && elementRegistry.get(gfx); if (gfx && element) { // 1) cancel current mousemove event.stopPropagation(); // 2) emit fake hover for new target dragging.hover({ element: element, gfx: gfx }); // 3) re-trigger move event dragging.move(originalEvent); } } /** * We wait for a specific sequence of events before * emitting a fake drag.hover event. * * Event Sequence: * * drag.start * drag.move >> ensure we are hovering */ eventBus.on('drag.start', function (event) { eventBus.once('drag.move', HIGH_PRIORITY, function (event) { ensureHover(event); }); }); /** * We make sure that drag.out is always fired, even if the * browser swallows an element.out event. * * Event sequence: * * drag.hover * (element.out >> sometimes swallowed) * element.hover >> ensure we fired drag.out */ eventBus.on('drag.init', function () { var hover, hoverGfx; function setDragHover(event) { hover = event.hover; hoverGfx = event.hoverGfx; } function unsetHover() { hover = null; hoverGfx = null; } function ensureOut() { if (!hover) { return; } var element = hover, gfx = hoverGfx; hover = null; hoverGfx = null; // emit synthetic out event dragging.out({ element: element, gfx: gfx }); } eventBus.on('drag.hover', setDragHover); eventBus.on('element.out', unsetHover); eventBus.on('element.hover', HIGH_PRIORITY, ensureOut); eventBus.once('drag.cleanup', function () { eventBus.off('drag.hover', setDragHover); eventBus.off('element.out', unsetHover); eventBus.off('element.hover', ensureOut); }); }); this._findTargetGfx = function (event) { var position, target; if (!(event instanceof MouseEvent)) { return; } position = (0, _Event.toPoint)(event); // damn expensive operation, ouch! target = document.elementFromPoint(position.x, position.y); return getGfx(target); }; } HoverFix.$inject = ['eventBus', 'dragging', 'elementRegistry']; // helpers ///////////////////// function getGfx(target) { return (0, _minDom.closest)(target, 'svg, .djs-element', true); } },{"../../util/Event":317,"min-dom":556}],197:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _selection = _interopRequireDefault(require("../selection")); var _Dragging = _interopRequireDefault(require("./Dragging")); var _HoverFix = _interopRequireDefault(require("./HoverFix")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['hoverFix'], __depends__: [_selection.default], dragging: ['type', _Dragging.default], hoverFix: ['type', _HoverFix.default] }; exports.default = _default; },{"../selection":278,"./Dragging":195,"./HoverFix":196}],198:[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 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 (copyPaste) { this.register('paste', function () { copyPaste.paste(); }); } 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":555}],199:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _EditorActions = _interopRequireDefault(require("./EditorActions")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['editorActions'], editorActions: ['type', _EditorActions.default] }; exports.default = _default; },{"./EditorActions":198}],200:[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 }); }; },{}],201:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _connect = _interopRequireDefault(require("../connect")); var _rules = _interopRequireDefault(require("../rules")); var _dragging = _interopRequireDefault(require("../dragging")); var _toolManager = _interopRequireDefault(require("../tool-manager")); var _GlobalConnect = _interopRequireDefault(require("./GlobalConnect")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_connect.default, _rules.default, _dragging.default, _toolManager.default], globalConnect: ['type', _GlobalConnect.default] }; exports.default = _default; },{"../connect":183,"../dragging":197,"../rules":272,"../tool-manager":290,"./GlobalConnect":200}],202:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = GridSnapping; var _SnapUtil = require("../snapping/SnapUtil"); var _KeyboardUtil = require("../keyboard/KeyboardUtil"); var _minDash = require("min-dash"); var _GridUtil = require("./GridUtil"); var LOWER_PRIORITY = 1200; var LOW_PRIORITY = 800; /** * Basic grid snapping that covers connecting, creating, moving, resizing shapes, moving bendpoints * and connection segments. */ function GridSnapping(elementRegistry, eventBus, config) { var active = !config || config.active !== false; this._eventBus = eventBus; var self = this; eventBus.on('diagram.init', LOW_PRIORITY, function () { self.setActive(active); }); eventBus.on(['create.move', 'create.end', 'bendpoint.move.move', 'bendpoint.move.end', 'connect.move', 'connect.end', 'connectionSegment.move.move', 'connectionSegment.move.end', 'resize.move', 'resize.end', 'shape.move.move', 'shape.move.end'], LOWER_PRIORITY, function (event) { var originalEvent = event.originalEvent; if (!self.active || originalEvent && (0, _KeyboardUtil.isCmd)(originalEvent)) { return; } var context = event.context, gridSnappingContext = context.gridSnappingContext; if (!gridSnappingContext) { gridSnappingContext = context.gridSnappingContext = {}; } ['x', 'y'].forEach(function (axis) { var options = {}; // allow snapping with offset var snapOffset = getSnapOffset(event, axis, elementRegistry); if (snapOffset) { options.offset = snapOffset; } // allow snapping with min and max var snapConstraints = getSnapConstraints(event, axis); if (snapConstraints) { (0, _minDash.assign)(options, snapConstraints); } if (!(0, _SnapUtil.isSnapped)(event, axis)) { self.snapEvent(event, axis, options); } }); }); } /** * Snap an events x or y with optional min, max and offset. * * @param {Object} event * @param {string} axis * @param {number} [options.min] * @param {number} [options.max] * @param {number} [options.offset] */ GridSnapping.prototype.snapEvent = function (event, axis, options) { var snappedValue = this.snapValue(event[axis], options); (0, _SnapUtil.setSnapped)(event, axis, snappedValue); }; /** * Expose grid spacing for third parties (i.e. extensions). * * @return {number} spacing of grid dots */ GridSnapping.prototype.getGridSpacing = function () { return _GridUtil.SPACING; }; /** * Snap value with optional min, max and offset. * * @param {number} value * @param {Object} options * @param {number} [options.min] * @param {number} [options.max] * @param {number} [options.offset] */ GridSnapping.prototype.snapValue = function (value, options) { var offset = 0; if (options && options.offset) { offset = options.offset; } value += offset; value = (0, _GridUtil.quantize)(value, _GridUtil.SPACING); var min, max; if (options && options.min) { min = options.min; if ((0, _minDash.isNumber)(min)) { min = (0, _GridUtil.quantize)(min + offset, _GridUtil.SPACING, 'ceil'); value = Math.max(value, min); } } if (options && options.max) { max = options.max; if ((0, _minDash.isNumber)(max)) { max = (0, _GridUtil.quantize)(max + offset, _GridUtil.SPACING, 'floor'); value = Math.min(value, max); } } value -= offset; return value; }; GridSnapping.prototype.isActive = function () { return this.active; }; GridSnapping.prototype.setActive = function (active) { this.active = active; this._eventBus.fire('gridSnapping.toggle', { active: active }); }; GridSnapping.prototype.toggleActive = function () { this.setActive(!this.active); }; GridSnapping.$inject = ['elementRegistry', 'eventBus', 'config.gridSnapping']; // helpers ////////// /** * Get minimum and maximum snap constraints. * Constraints are cached. * * @param {Object} event * @param {Object} event.context * @param {string} axis * * @returns {boolean|Object} */ function getSnapConstraints(event, axis) { var context = event.context, createConstraints = context.createConstraints, resizeConstraints = context.resizeConstraints || {}, gridSnappingContext = context.gridSnappingContext, snapConstraints = gridSnappingContext.snapConstraints; // cache snap constraints if (snapConstraints && snapConstraints[axis]) { return snapConstraints[axis]; } if (!snapConstraints) { snapConstraints = gridSnappingContext.snapConstraints = {}; } if (!snapConstraints[axis]) { snapConstraints[axis] = {}; } var direction = context.direction; // create if (createConstraints) { if (isHorizontal(axis)) { snapConstraints.x.min = createConstraints.left; snapConstraints.x.max = createConstraints.right; } else { snapConstraints.y.min = createConstraints.top; snapConstraints.y.max = createConstraints.bottom; } } // resize var minResizeConstraints = resizeConstraints.min, maxResizeConstraints = resizeConstraints.max; if (minResizeConstraints) { if (isHorizontal(axis)) { if (isWest(direction)) { snapConstraints.x.max = minResizeConstraints.left; } else { snapConstraints.x.min = minResizeConstraints.right; } } else { if (isNorth(direction)) { snapConstraints.y.max = minResizeConstraints.top; } else { snapConstraints.y.min = minResizeConstraints.bottom; } } } if (maxResizeConstraints) { if (isHorizontal(axis)) { if (isWest(direction)) { snapConstraints.x.min = maxResizeConstraints.left; } else { snapConstraints.x.max = maxResizeConstraints.right; } } else { if (isNorth(direction)) { snapConstraints.y.min = maxResizeConstraints.top; } else { snapConstraints.y.max = maxResizeConstraints.bottom; } } } return snapConstraints[axis]; } /** * Get snap offset. * Offset is cached. * * @param {Object} event * @param {string} axis * @param {ElementRegistry} elementRegistry * * @returns {number} */ function getSnapOffset(event, axis, elementRegistry) { var context = event.context, shape = event.shape, gridSnappingContext = context.gridSnappingContext, snapLocation = gridSnappingContext.snapLocation, snapOffset = gridSnappingContext.snapOffset; // cache snap offset if (snapOffset && (0, _minDash.isNumber)(snapOffset[axis])) { return snapOffset[axis]; } if (!snapOffset) { snapOffset = gridSnappingContext.snapOffset = {}; } if (!(0, _minDash.isNumber)(snapOffset[axis])) { snapOffset[axis] = 0; } if (!shape) { return snapOffset[axis]; } if (!elementRegistry.get(shape.id)) { if (isHorizontal(axis)) { snapOffset[axis] += shape[axis] + shape.width / 2; } else { snapOffset[axis] += shape[axis] + shape.height / 2; } } if (!snapLocation) { return snapOffset[axis]; } if (axis === 'x') { if (/left/.test(snapLocation)) { snapOffset[axis] -= shape.width / 2; } else if (/right/.test(snapLocation)) { snapOffset[axis] += shape.width / 2; } } else { if (/top/.test(snapLocation)) { snapOffset[axis] -= shape.height / 2; } else if (/bottom/.test(snapLocation)) { snapOffset[axis] += shape.height / 2; } } return snapOffset[axis]; } function isHorizontal(axis) { return axis === 'x'; } function isNorth(direction) { return direction.indexOf('n') !== -1; } function isWest(direction) { return direction.indexOf('w') !== -1; } },{"../keyboard/KeyboardUtil":216,"../snapping/SnapUtil":282,"./GridUtil":203,"min-dash":555}],203:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.quantize = quantize; exports.SPACING = void 0; var SPACING = 10; exports.SPACING = SPACING; function quantize(value, quantum, fn) { if (!fn) { fn = 'round'; } return Math[fn](value / quantum) * quantum; } },{}],204:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("../../../command/CommandInterceptor")); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Integrates resizing with grid snapping. */ function ResizeBehavior(eventBus, gridSnapping) { _CommandInterceptor.default.call(this, eventBus); this._gridSnapping = gridSnapping; var self = this; this.preExecute('shape.resize', function (event) { var context = event.context, hints = context.hints || {}, autoResize = hints.autoResize; if (!autoResize) { return; } var shape = context.shape, newBounds = context.newBounds; if ((0, _minDash.isString)(autoResize)) { context.newBounds = self.snapComplex(newBounds, autoResize); } else { context.newBounds = self.snapSimple(shape, newBounds); } }); } ResizeBehavior.$inject = ['eventBus', 'gridSnapping', 'modeling']; (0, _inherits.default)(ResizeBehavior, _CommandInterceptor.default); /** * Snap width and height in relation to center. * * @param {djs.model.shape} shape * @param {Bounds} newBounds * * @returns {Bounds} Snapped bounds. */ ResizeBehavior.prototype.snapSimple = function (shape, newBounds) { var gridSnapping = this._gridSnapping; newBounds.width = gridSnapping.snapValue(newBounds.width, { min: newBounds.width }); newBounds.height = gridSnapping.snapValue(newBounds.height, { min: newBounds.height }); newBounds.x = shape.x + shape.width / 2 - newBounds.width / 2; newBounds.y = shape.y + shape.height / 2 - newBounds.height / 2; return newBounds; }; /** * Snap x, y, width and height according to given directions. * * @param {Bounds} newBounds * @param {string} directions - Directions as {n|w|s|e}. * * @returns {Bounds} Snapped bounds. */ ResizeBehavior.prototype.snapComplex = function (newBounds, directions) { if (/w|e/.test(directions)) { newBounds = this.snapHorizontally(newBounds, directions); } if (/n|s/.test(directions)) { newBounds = this.snapVertically(newBounds, directions); } return newBounds; }; /** * Snap in one or both directions horizontally. * * @param {Bounds} newBounds * @param {string} directions - Directions as {n|w|s|e}. * * @returns {Bounds} Snapped bounds. */ ResizeBehavior.prototype.snapHorizontally = function (newBounds, directions) { var gridSnapping = this._gridSnapping, west = /w/.test(directions), east = /e/.test(directions); var snappedNewBounds = {}; snappedNewBounds.width = gridSnapping.snapValue(newBounds.width, { min: newBounds.width }); if (east) { // handle if (west) { snappedNewBounds.x = gridSnapping.snapValue(newBounds.x, { max: newBounds.x }); snappedNewBounds.width += gridSnapping.snapValue(newBounds.x - snappedNewBounds.x, { min: newBounds.x - snappedNewBounds.x }); } // handle else { newBounds.x = newBounds.x + newBounds.width - snappedNewBounds.width; } } // assign snapped x and width (0, _minDash.assign)(newBounds, snappedNewBounds); return newBounds; }; /** * Snap in one or both directions vertically. * * @param {Bounds} newBounds * @param {string} directions - Directions as {n|w|s|e}. * * @returns {Bounds} Snapped bounds. */ ResizeBehavior.prototype.snapVertically = function (newBounds, directions) { var gridSnapping = this._gridSnapping, north = /n/.test(directions), south = /s/.test(directions); var snappedNewBounds = {}; snappedNewBounds.height = gridSnapping.snapValue(newBounds.height, { min: newBounds.height }); if (north) { // handle if (south) { snappedNewBounds.y = gridSnapping.snapValue(newBounds.y, { max: newBounds.y }); snappedNewBounds.height += gridSnapping.snapValue(newBounds.y - snappedNewBounds.y, { min: newBounds.y - snappedNewBounds.y }); } // handle else { newBounds.y = newBounds.y + newBounds.height - snappedNewBounds.height; } } // assign snapped y and height (0, _minDash.assign)(newBounds, snappedNewBounds); return newBounds; }; },{"../../../command/CommandInterceptor":145,"inherits":347,"min-dash":555}],205:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceToolBehavior; var HIGH_PRIORITY = 2000; /** * Integrates space tool with grid snapping. */ function SpaceToolBehavior(eventBus, gridSnapping) { eventBus.on(['spaceTool.move', 'spaceTool.end'], HIGH_PRIORITY, function (event) { var context = event.context; if (!context.initialized) { return; } var axis = context.axis; var snapped; if (axis === 'x') { // snap delta x to multiple of 10 snapped = gridSnapping.snapValue(event.dx); event.x = event.x + snapped - event.dx; event.dx = snapped; } else { // snap delta y to multiple of 10 snapped = gridSnapping.snapValue(event.dy); event.y = event.y + snapped - event.dy; event.dy = snapped; } }); } SpaceToolBehavior.$inject = ['eventBus', 'gridSnapping']; },{}],206:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ResizeBehavior = _interopRequireDefault(require("./ResizeBehavior")); var _SpaceToolBehavior = _interopRequireDefault(require("./SpaceToolBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['gridSnappingResizeBehavior', 'gridSnappingSpaceToolBehavior'], gridSnappingResizeBehavior: ['type', _ResizeBehavior.default], gridSnappingSpaceToolBehavior: ['type', _SpaceToolBehavior.default] }; exports.default = _default; },{"./ResizeBehavior":204,"./SpaceToolBehavior":205}],207:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _GridSnapping = _interopRequireDefault(require("./GridSnapping")); var _behavior = _interopRequireDefault(require("./behavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_behavior.default], __init__: ['gridSnapping'], gridSnapping: ['type', _GridSnapping.default] }; exports.default = _default; },{"./GridSnapping":202,"./behavior":206}],208:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = HandTool; var _Mouse = require("../../util/Mouse"); var _KeyboardUtil = require("../../features/keyboard/KeyboardUtil"); var HIGH_PRIORITY = 1500; var HAND_CURSOR = 'grab'; function HandTool(eventBus, canvas, dragging, injector, toolManager) { this._dragging = dragging; var self = this, keyboard = injector.get('keyboard', false); 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); keyboard && keyboard.addListener(HIGH_PRIORITY, function (e) { if (!isSpace(e.keyEvent)) { return; } if (self.isActive()) { return; } function activateMove(event) { self.activateMove(event); window.removeEventListener('mousemove', activateMove); } window.addEventListener('mousemove', activateMove); function deactivateMove(e) { if (!isSpace(e.keyEvent)) { return; } window.removeEventListener('mousemove', activateMove); keyboard.removeListener(deactivateMove, 'keyboard.keyup'); dragging.cancel(); } keyboard.addListener(HIGH_PRIORITY, deactivateMove, 'keyboard.keyup'); }, 'keyboard.keydown'); 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', 'injector', 'toolManager']; HandTool.prototype.activateMove = function (event, autoActivate, context) { if (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(); if (context) { return /^(hand|hand\.move)$/.test(context.prefix); } return false; }; // helpers ////////// function isSpace(keyEvent) { return (0, _KeyboardUtil.isKey)(' ', keyEvent); } },{"../../features/keyboard/KeyboardUtil":216,"../../util/Mouse":323}],209:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _toolManager = _interopRequireDefault(require("../tool-manager")); var _HandTool = _interopRequireDefault(require("./HandTool")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_toolManager.default], __init__: ['handTool'], handTool: ['type', _HandTool.default] }; exports.default = _default; },{"../tool-manager":290,"./HandTool":208}],210:[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.click * * element.contextmenu * * element.dblclick * * element.hover * * element.mousedown * * element.mousemove * * element.mouseup * * element.out * * 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 self = this; /** * 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 = { click: 'element.click', contextmenu: 'element.contextmenu', dblclick: 'element.dblclick', mousedown: 'element.mousedown', mousemove: 'element.mousemove', mouseover: 'element.hover', mouseout: 'element.out', mouseup: 'element.mouseup' }; 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 ELEMENT_SELECTOR = 'svg, .djs-element'; // event handling /////// 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, ELEMENT_SELECTOR, 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); }); // hit box updating //////////////// eventBus.on(['shape.added', 'connection.added'], function (event) { var element = event.element, gfx = event.gfx; eventBus.fire('interactionEvents.createHit', { element: element, gfx: gfx }); }); // 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', 'connection.changed'], LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; eventBus.fire('interactionEvents.updateHit', { element: element, gfx: gfx }); }); eventBus.on('interactionEvents.createHit', LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; self.createDefaultHit(element, gfx); }); eventBus.on('interactionEvents.updateHit', function (event) { var element = event.element, gfx = event.gfx; self.updateDefaultHit(element, gfx); }); // hit styles //////////// var STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-stroke'); var CLICK_STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-click-stroke'); var ALL_HIT_STYLE = createHitStyle('djs-hit djs-hit-all'); var HIT_TYPES = { 'all': ALL_HIT_STYLE, 'click-stroke': CLICK_STROKE_HIT_STYLE, 'stroke': STROKE_HIT_STYLE }; function createHitStyle(classNames, attrs) { attrs = (0, _minDash.assign)({ stroke: 'white', strokeWidth: 15 }, attrs || {}); return styles.cls(classNames, ['no-fill', 'no-border'], attrs); } // style helpers /////////////// function applyStyle(hit, type) { var attrs = HIT_TYPES[type]; if (!attrs) { throw new Error('invalid hit type <' + type + '>'); } (0, _tinySvg.attr)(hit, attrs); return hit; } function appendHit(gfx, hit) { (0, _tinySvg.append)(gfx, hit); } // API /** * Remove hints on the given graphics. * * @param {SVGElement} gfx */ this.removeHits = function (gfx) { var hits = (0, _minDom.queryAll)('.djs-hit', gfx); (0, _minDash.forEach)(hits, _tinySvg.remove); }; /** * Create default hit for the given element. * * @param {djs.model.Base} element * @param {SVGElement} gfx * * @return {SVGElement} created hit */ this.createDefaultHit = function (element, gfx) { var waypoints = element.waypoints, isFrame = element.isFrame, boxType; if (waypoints) { return this.createWaypointsHit(gfx, waypoints); } else { boxType = isFrame ? 'stroke' : 'all'; return this.createBoxHit(gfx, boxType, { width: element.width, height: element.height }); } }; /** * Create hits for the given waypoints. * * @param {SVGElement} gfx * @param {Array} waypoints * * @return {SVGElement} */ this.createWaypointsHit = function (gfx, waypoints) { var hit = (0, _RenderUtil.createLine)(waypoints); applyStyle(hit, 'stroke'); appendHit(gfx, hit); return hit; }; /** * Create hits for a box. * * @param {SVGElement} gfx * @param {string} hitType * @param {Object} attrs * * @return {SVGElement} */ this.createBoxHit = function (gfx, type, attrs) { attrs = (0, _minDash.assign)({ x: 0, y: 0 }, attrs); var hit = (0, _tinySvg.create)('rect'); applyStyle(hit, type); (0, _tinySvg.attr)(hit, attrs); appendHit(gfx, hit); return hit; }; /** * Update default hit of the element. * * @param {djs.model.Base} element * @param {SVGElement} gfx * * @return {SVGElement} updated hit */ this.updateDefaultHit = function (element, gfx) { var hit = (0, _minDom.query)('.djs-hit', gfx); if (!hit) { return; } if (element.waypoints) { (0, _RenderUtil.updateLine)(hit, element.waypoints); } else { (0, _tinySvg.attr)(hit, { width: element.width, height: element.height }); } return hit; }; 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":323,"../../util/RenderUtil":327,"min-dash":555,"min-dom":556,"tiny-svg":567}],211:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _InteractionEvents = _interopRequireDefault(require("./InteractionEvents")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['interactionEvents'], interactionEvents: ['type', _InteractionEvents.default] }; exports.default = _default; },{"./InteractionEvents":210}],212:[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 (speed) { return { x: -speed, y: 0 }; }, up: function (speed) { return { x: 0, y: -speed }; }, right: function (speed) { return { x: speed, y: 0 }; }, down: function (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, rules, 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); var canMove = rules.allowed('elements.move', { shapes: selectedElements }); if (canMove) { modeling.moveElements(selectedElements, delta); } }; } KeyboardMoveSelection.$inject = ['config.keyboardMoveSelection', 'keyboard', 'modeling', 'rules', 'selection']; },{"min-dash":555}],213:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _keyboard = _interopRequireDefault(require("../keyboard")); var _selection = _interopRequireDefault(require("../selection")); var _KeyboardMoveSelection = _interopRequireDefault(require("./KeyboardMoveSelection")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_keyboard.default, _selection.default], __init__: ['keyboardMoveSelection'], keyboardMoveSelection: ['type', _KeyboardMoveSelection.default] }; exports.default = _default; },{"../keyboard":217,"../selection":278,"./KeyboardMoveSelection":212}],214:[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', KEYUP_EVENT = 'keyboard.keyup'; 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._keydownHandler = this._keydownHandler.bind(this); this._keyupHandler = this._keyupHandler.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._keydownHandler = function (event) { this._keyHandler(event, KEYDOWN_EVENT); }; Keyboard.prototype._keyupHandler = function (event) { this._keyHandler(event, KEYUP_EVENT); }; Keyboard.prototype._keyHandler = function (event, type) { var target = event.target, eventBusResult; if (isInput(target)) { return; } var context = { keyEvent: event }; eventBusResult = this._eventBus.fire(type || 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._keydownHandler, true); _minDom.event.bind(node, 'keyup', this._keyupHandler, 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._keydownHandler, true); _minDom.event.unbind(node, 'keyup', this._keyupHandler, 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 * @param {string} type */ Keyboard.prototype.addListener = function (priority, listener, type) { if ((0, _minDash.isFunction)(priority)) { type = listener; listener = priority; priority = DEFAULT_PRIORITY; } this._eventBus.on(type || KEYDOWN_EVENT, priority, listener); }; Keyboard.prototype.removeListener = function (listener, type) { this._eventBus.off(type || KEYDOWN_EVENT, 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":216,"min-dash":555,"min-dom":556}],215:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = KeyboardBindings; exports.KEYS_UNDO = exports.KEYS_REDO = exports.KEYS_PASTE = exports.KEYS_COPY = exports.KEYCODE_Z = exports.KEYCODE_Y = exports.KEYCODE_V = exports.KEYCODE_C = void 0; var _KeyboardUtil = require("./KeyboardUtil"); var LOW_PRIORITY = 500; var KEYCODE_C = 67; exports.KEYCODE_C = KEYCODE_C; var KEYCODE_V = 86; exports.KEYCODE_V = KEYCODE_V; var KEYCODE_Y = 89; exports.KEYCODE_Y = KEYCODE_Y; var KEYCODE_Z = 90; exports.KEYCODE_Z = KEYCODE_Z; var KEYS_COPY = ['c', 'C', KEYCODE_C]; exports.KEYS_COPY = KEYS_COPY; var KEYS_PASTE = ['v', 'V', KEYCODE_V]; exports.KEYS_PASTE = KEYS_PASTE; var KEYS_REDO = ['y', 'Y', KEYCODE_Y]; exports.KEYS_REDO = KEYS_REDO; var KEYS_UNDO = ['z', 'Z', KEYCODE_Z]; /** * 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 */ exports.KEYS_UNDO = KEYS_UNDO; 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)(KEYS_UNDO, 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)(KEYS_REDO, event) || (0, _KeyboardUtil.isKey)(KEYS_UNDO, 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)(KEYS_COPY, 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)(KEYS_PASTE, 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":216}],216:[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|Array} keys * @param {KeyboardEvent} event */ function isKey(keys, event) { keys = (0, _minDash.isArray)(keys) ? keys : [keys]; return keys.indexOf(event.key) !== -1 || keys.indexOf(event.keyCode) !== -1; } /** * @param {KeyboardEvent} event */ function isShift(event) { return event.shiftKey; } },{"min-dash":555}],217:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Keyboard = _interopRequireDefault(require("./Keyboard")); var _KeyboardBindings = _interopRequireDefault(require("./KeyboardBindings")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['keyboard', 'keyboardBindings'], keyboard: ['type', _Keyboard.default], keyboardBindings: ['type', _KeyboardBindings.default] }; exports.default = _default; },{"./Keyboard":214,"./KeyboardBindings":215}],218:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelSupport; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _Collections = require("../../util/Collections"); var _Removal = require("../../util/Removal"); var _CommandInterceptor = _interopRequireDefault(require("../../command/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) { _CommandInterceptor.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, _inherits.default)(LabelSupport, _CommandInterceptor.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":145,"../../util/Collections":313,"../../util/Removal":326,"inherits":347,"min-dash":555}],219:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _LabelSupport = _interopRequireDefault(require("./LabelSupport")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['labelSupport'], labelSupport: ['type', _LabelSupport.default] }; exports.default = _default; },{"./LabelSupport":218}],220:[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 (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 (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 (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":315,"../../util/Mouse":323,"min-dash":555,"tiny-svg":567}],221:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _toolManager = _interopRequireDefault(require("../tool-manager")); var _LassoTool = _interopRequireDefault(require("./LassoTool")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_toolManager.default], __init__: ['lassoTool'], lassoTool: ['type', _LassoTool.default] }; exports.default = _default; },{"../tool-manager":290,"./LassoTool":220}],222:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Modeling; var _minDash = require("min-dash"); var _model = require("../../model"); var _AlignElementsHandler = _interopRequireDefault(require("./cmd/AlignElementsHandler")); var _AppendShapeHandler = _interopRequireDefault(require("./cmd/AppendShapeHandler")); var _CreateConnectionHandler = _interopRequireDefault(require("./cmd/CreateConnectionHandler")); var _CreateElementsHandler = _interopRequireDefault(require("./cmd/CreateElementsHandler")); var _CreateLabelHandler = _interopRequireDefault(require("./cmd/CreateLabelHandler")); var _CreateShapeHandler = _interopRequireDefault(require("./cmd/CreateShapeHandler")); var _DeleteConnectionHandler = _interopRequireDefault(require("./cmd/DeleteConnectionHandler")); var _DeleteElementsHandler = _interopRequireDefault(require("./cmd/DeleteElementsHandler")); var _DeleteShapeHandler = _interopRequireDefault(require("./cmd/DeleteShapeHandler")); var _DistributeElementsHandler = _interopRequireDefault(require("./cmd/DistributeElementsHandler")); var _LayoutConnectionHandler = _interopRequireDefault(require("./cmd/LayoutConnectionHandler")); var _MoveConnectionHandler = _interopRequireDefault(require("./cmd/MoveConnectionHandler")); var _MoveElementsHandler = _interopRequireDefault(require("./cmd/MoveElementsHandler")); var _MoveShapeHandler = _interopRequireDefault(require("./cmd/MoveShapeHandler")); var _ReconnectConnectionHandler = _interopRequireDefault(require("./cmd/ReconnectConnectionHandler")); var _ReplaceShapeHandler = _interopRequireDefault(require("./cmd/ReplaceShapeHandler")); var _ResizeShapeHandler = _interopRequireDefault(require("./cmd/ResizeShapeHandler")); var _SpaceToolHandler = _interopRequireDefault(require("./cmd/SpaceToolHandler")); var _ToggleShapeCollapseHandler = _interopRequireDefault(require("./cmd/ToggleShapeCollapseHandler")); var _UpdateAttachmentHandler = _interopRequireDefault(require("./cmd/UpdateAttachmentHandler")); var _UpdateWaypointsHandler = _interopRequireDefault(require("./cmd/UpdateWaypointsHandler")); 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': _AppendShapeHandler.default, 'shape.create': _CreateShapeHandler.default, 'shape.delete': _DeleteShapeHandler.default, 'shape.move': _MoveShapeHandler.default, 'shape.resize': _ResizeShapeHandler.default, 'shape.replace': _ReplaceShapeHandler.default, 'shape.toggleCollapse': _ToggleShapeCollapseHandler.default, 'spaceTool': _SpaceToolHandler.default, 'label.create': _CreateLabelHandler.default, 'connection.create': _CreateConnectionHandler.default, 'connection.delete': _DeleteConnectionHandler.default, 'connection.move': _MoveConnectionHandler.default, 'connection.layout': _LayoutConnectionHandler.default, 'connection.updateWaypoints': _UpdateWaypointsHandler.default, 'connection.reconnect': _ReconnectConnectionHandler.default, 'elements.create': _CreateElementsHandler.default, 'elements.move': _MoveElementsHandler.default, 'elements.delete': _DeleteElementsHandler.default, 'elements.distribute': _DistributeElementsHandler.default, 'elements.align': _AlignElementsHandler.default, 'element.updateAttachment': _UpdateAttachmentHandler.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 === '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 === '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} [parentIndex] * @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 === '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.createElements = function (elements, position, parent, parentIndex, hints) { if (!(0, _minDash.isArray)(elements)) { elements = [elements]; } if (typeof parentIndex !== 'number') { hints = parentIndex; parentIndex = undefined; } hints = hints || {}; var context = { position: position, elements: elements, parent: parent, parentIndex: parentIndex, hints: hints }; this._commandStack.execute('elements.create', context); return context.elements; }; 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, hints: hints }; 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.alignElements = function (elements, alignment) { var context = { elements: elements, alignment: alignment }; this._commandStack.execute('elements.align', context); }; Modeling.prototype.resizeShape = function (shape, newBounds, minBounds, hints) { var context = { shape: shape, newBounds: newBounds, minBounds: minBounds, hints: hints }; this._commandStack.execute('shape.resize', context); }; Modeling.prototype.createSpace = function (movingShapes, resizingShapes, delta, direction, start) { var context = { delta: delta, direction: direction, movingShapes: movingShapes, resizingShapes: resizingShapes, start: start }; 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.reconnect = function (connection, source, target, dockingOrPoints, hints) { var context = { connection: connection, newSource: source, newTarget: target, dockingOrPoints: dockingOrPoints, hints: hints || {} }; this._commandStack.execute('connection.reconnect', context); }; Modeling.prototype.reconnectStart = function (connection, newSource, dockingOrPoints, hints) { if (!hints) { hints = {}; } this.reconnect(connection, newSource, connection.target, dockingOrPoints, (0, _minDash.assign)(hints, { docking: 'source' })); }; Modeling.prototype.reconnectEnd = function (connection, newTarget, dockingOrPoints, hints) { if (!hints) { hints = {}; } this.reconnect(connection, connection.source, newTarget, dockingOrPoints, (0, _minDash.assign)(hints, { docking: 'target' })); }; 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":302,"./cmd/AlignElementsHandler":223,"./cmd/AppendShapeHandler":224,"./cmd/CreateConnectionHandler":225,"./cmd/CreateElementsHandler":226,"./cmd/CreateLabelHandler":227,"./cmd/CreateShapeHandler":228,"./cmd/DeleteConnectionHandler":229,"./cmd/DeleteElementsHandler":230,"./cmd/DeleteShapeHandler":231,"./cmd/DistributeElementsHandler":232,"./cmd/LayoutConnectionHandler":233,"./cmd/MoveConnectionHandler":234,"./cmd/MoveElementsHandler":235,"./cmd/MoveShapeHandler":236,"./cmd/ReconnectConnectionHandler":237,"./cmd/ReplaceShapeHandler":238,"./cmd/ResizeShapeHandler":239,"./cmd/SpaceToolHandler":240,"./cmd/ToggleShapeCollapseHandler":241,"./cmd/UpdateAttachmentHandler":242,"./cmd/UpdateWaypointsHandler":243,"min-dash":555}],223:[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":555}],224:[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, hints = context.hints || {}; shape = context.shape = this._modeling.createShape(shape, context.position, target, { attach: hints.attach }); context.shape = shape; }; AppendShapeHandler.prototype.postExecute = function (context) { var hints = context.hints || {}; if (!existsConnection(context.source, context.shape)) { // create connection if (hints.connectionTarget === context.source) { this._modeling.connect(context.shape, context.source, context.connection); } else { this._modeling.connect(context.source, context.shape, context.connection); } } }; function existsConnection(source, target) { return (0, _minDash.some)(source.outgoing, function (c) { return c.target === target; }); } },{"min-dash":555}],225:[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; return connection; }; },{}],226:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateElementsHandler; var _minDash = require("min-dash"); var _Elements = require("../../../util/Elements"); var round = Math.round; function CreateElementsHandler(modeling) { this._modeling = modeling; } CreateElementsHandler.$inject = ['modeling']; CreateElementsHandler.prototype.preExecute = function (context) { var elements = context.elements, parent = context.parent, parentIndex = context.parentIndex, position = context.position, hints = context.hints; var modeling = this._modeling; // make sure each element has x and y (0, _minDash.forEach)(elements, function (element) { if (!(0, _minDash.isNumber)(element.x)) { element.x = 0; } if (!(0, _minDash.isNumber)(element.y)) { element.y = 0; } }); var bbox = (0, _Elements.getBBox)(elements); // center elements around position (0, _minDash.forEach)(elements, function (element) { if (isConnection(element)) { element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint) { return { x: round(waypoint.x - bbox.x - bbox.width / 2 + position.x), y: round(waypoint.y - bbox.y - bbox.height / 2 + position.y) }; }); } (0, _minDash.assign)(element, { x: round(element.x - bbox.x - bbox.width / 2 + position.x), y: round(element.y - bbox.y - bbox.height / 2 + position.y) }); }); var parents = (0, _Elements.getParents)(elements); var cache = {}; (0, _minDash.forEach)(elements, function (element) { if (isConnection(element)) { cache[element.id] = (0, _minDash.isNumber)(parentIndex) ? modeling.createConnection(cache[element.source.id], cache[element.target.id], parentIndex, element, element.parent || parent, hints) : modeling.createConnection(cache[element.source.id], cache[element.target.id], element, element.parent || parent, hints); return; } var createShapeHints = (0, _minDash.assign)({}, hints); if (parents.indexOf(element) === -1) { createShapeHints.autoResize = false; } cache[element.id] = (0, _minDash.isNumber)(parentIndex) ? modeling.createShape(element, (0, _minDash.pick)(element, ['x', 'y', 'width', 'height']), element.parent || parent, parentIndex, createShapeHints) : modeling.createShape(element, (0, _minDash.pick)(element, ['x', 'y', 'width', 'height']), element.parent || parent, createShapeHints); }); context.elements = (0, _minDash.values)(cache); }; // helpers ////////// function isConnection(element) { return !!element.waypoints; } },{"../../../util/Elements":315,"min-dash":555}],227:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateLabelHandler; var _inherits = _interopRequireDefault(require("inherits")); var _CreateShapeHandler = _interopRequireDefault(require("./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) { _CreateShapeHandler.default.call(this, canvas); } (0, _inherits.default)(CreateLabelHandler, _CreateShapeHandler.default); CreateLabelHandler.$inject = ['canvas']; // api ////////////////////// var originalExecute = _CreateShapeHandler.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 = _CreateShapeHandler.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":228,"inherits":347}],228:[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) { var shape = context.shape; // (3) remove form canvas this._canvas.removeShape(shape); return shape; }; },{"min-dash":555}],229:[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":313}],230:[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":555}],231:[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":313,"../../../util/Removal":326}],232:[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":555}],233:[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":555}],234:[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":313,"min-dash":555}],235:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveElementsHandler; var _MoveHelper = _interopRequireDefault(require("./helper/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 _MoveHelper.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":246}],236:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveShapeHandler; var _minDash = require("min-dash"); var _MoveHelper = _interopRequireDefault(require("./helper/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 _MoveHelper.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":313,"./helper/AnchorsHelper":244,"./helper/MoveHelper":246,"min-dash":555}],237:[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(modeling) { this._modeling = modeling; } ReconnectConnectionHandler.$inject = ['modeling']; ReconnectConnectionHandler.prototype.execute = function (context) { var newSource = context.newSource, newTarget = context.newTarget, connection = context.connection, dockingOrPoints = context.dockingOrPoints; if (!newSource && !newTarget) { throw new Error('newSource or newTarget required'); } if ((0, _minDash.isArray)(dockingOrPoints)) { context.oldWaypoints = connection.waypoints; connection.waypoints = dockingOrPoints; } if (newSource) { context.oldSource = connection.source; connection.source = newSource; } if (newTarget) { context.oldTarget = connection.target; connection.target = newTarget; } return connection; }; ReconnectConnectionHandler.prototype.postExecute = function (context) { var connection = context.connection, newSource = context.newSource, newTarget = context.newTarget, dockingOrPoints = context.dockingOrPoints, hints = context.hints || {}; var layoutConnectionHints = {}; if (hints.connectionStart) { layoutConnectionHints.connectionStart = hints.connectionStart; } if (hints.connectionEnd) { layoutConnectionHints.connectionEnd = hints.connectionEnd; } if (hints.layoutConnection === false) { return; } if (newSource && (!newTarget || hints.docking === 'source')) { layoutConnectionHints.connectionStart = layoutConnectionHints.connectionStart || getDocking((0, _minDash.isArray)(dockingOrPoints) ? dockingOrPoints[0] : dockingOrPoints); } if (newTarget && (!newSource || hints.docking === 'target')) { layoutConnectionHints.connectionEnd = layoutConnectionHints.connectionEnd || getDocking((0, _minDash.isArray)(dockingOrPoints) ? dockingOrPoints[dockingOrPoints.length - 1] : dockingOrPoints); } if (hints.newWaypoints) { layoutConnectionHints.waypoints = hints.newWaypoints; } this._modeling.layoutConnection(connection, layoutConnectionHints); }; ReconnectConnectionHandler.prototype.revert = function (context) { var oldSource = context.oldSource, oldTarget = context.oldTarget, oldWaypoints = context.oldWaypoints, connection = context.connection; if (oldSource) { connection.source = oldSource; } if (oldTarget) { connection.target = oldTarget; } if (oldWaypoints) { connection.waypoints = oldWaypoints; } return connection; }; // helpers ////////// function getDocking(point) { return point.original || point; } },{"min-dash":555}],238:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceShapeHandler; var _minDash = require("min-dash"); var _AnchorsHelper = require("./helper/AnchorsHelper"); /** * Replace shape by adding new shape and removing old shape. Incoming and outgoing connections will * be kept if possible. * * @class * @constructor * * @param {Modeling} modeling * @param {Rules} rules */ function ReplaceShapeHandler(modeling, rules) { this._modeling = modeling; this._rules = rules; } ReplaceShapeHandler.$inject = ['modeling', 'rules']; /** * Add new shape. * * @param {Object} context * @param {djs.model.Shape} context.oldShape * @param {Object} context.newData * @param {string} context.newData.type * @param {number} context.newData.x * @param {number} context.newData.y * @param {Object} [hints] */ 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(source, target, connection) { return rules.allowed('connection.reconnect', { connection: connection, source: source, target: target }); } // (1) add new shape at given position var position = { x: newData.x, y: newData.y }; var oldBounds = { x: oldShape.x, y: oldShape.y, width: oldShape.width, height: oldShape.height }; newShape = context.newShape = context.newShape || self.createShape(newData, position, oldShape.parent, hints); // (2) update host if (oldShape.host) { modeling.updateAttachment(newShape, oldShape.host); } // (3) adopt all children from old shape var children; if (hints.moveChildren !== false) { children = oldShape.children.slice(); modeling.moveElements(children, { x: 0, y: 0 }, newShape, hints); } // (4) reconnect connections to new shape if possible var incoming = oldShape.incoming.slice(), outgoing = oldShape.outgoing.slice(); (0, _minDash.forEach)(incoming, function (connection) { var source = connection.source, allowed = canReconnect(source, newShape, connection); if (allowed) { self.reconnectEnd(connection, newShape, (0, _AnchorsHelper.getResizedTargetAnchor)(connection, newShape, oldBounds), hints); } }); (0, _minDash.forEach)(outgoing, function (connection) { var target = connection.target, allowed = canReconnect(newShape, target, connection); if (allowed) { self.reconnectStart(connection, newShape, (0, _AnchorsHelper.getResizedSourceAnchor)(connection, newShape, oldBounds), hints); } }); }; /** * Remove old shape. */ ReplaceShapeHandler.prototype.postExecute = function (context) { var oldShape = context.oldShape; this._modeling.removeShape(oldShape); }; ReplaceShapeHandler.prototype.execute = function (context) {}; ReplaceShapeHandler.prototype.revert = function (context) {}; ReplaceShapeHandler.prototype.createShape = function (shape, position, target, hints) { return this._modeling.createShape(shape, position, target, hints); }; ReplaceShapeHandler.prototype.reconnectStart = function (connection, newSource, dockingPoint, hints) { this._modeling.reconnectStart(connection, newSource, dockingPoint, hints); }; ReplaceShapeHandler.prototype.reconnectEnd = function (connection, newTarget, dockingPoint, hints) { this._modeling.reconnectEnd(connection, newTarget, dockingPoint, hints); }; },{"./helper/AnchorsHelper":244,"min-dash":555}],239:[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 modeling = this._modeling; var shape = context.shape, oldBounds = context.oldBounds, hints = context.hints || {}; if (hints.layout === false) { return; } (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":244,"min-dash":555}],240:[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"); var _AnchorsHelper = require("./helper/AnchorsHelper"); /** * Add or remove space by moving and resizing shapes and updating connection waypoints. */ function SpaceToolHandler(modeling) { this._modeling = modeling; } SpaceToolHandler.$inject = ['modeling']; SpaceToolHandler.prototype.preExecute = function (context) { var delta = context.delta, direction = context.direction, movingShapes = context.movingShapes, resizingShapes = context.resizingShapes, start = context.start, oldBounds = {}; // (1) move shapes this.moveShapes(movingShapes, delta); // (2a) save old bounds of resized shapes (0, _minDash.forEach)(resizingShapes, function (shape) { oldBounds[shape.id] = getBounds(shape); }); // (2b) resize shapes this.resizeShapes(resizingShapes, delta, direction); // (3) update connection waypoints this.updateConnectionWaypoints((0, _SpaceUtil.getWaypointsUpdatingConnections)(movingShapes, resizingShapes), delta, direction, start, movingShapes, resizingShapes, oldBounds); }; SpaceToolHandler.prototype.execute = function () {}; SpaceToolHandler.prototype.revert = function () {}; SpaceToolHandler.prototype.moveShapes = function (shapes, delta) { var self = this; (0, _minDash.forEach)(shapes, function (element) { self._modeling.moveShape(element, delta, null, { autoResize: false, layout: false, recurse: false }); }); }; SpaceToolHandler.prototype.resizeShapes = function (shapes, delta, direction) { var self = this; (0, _minDash.forEach)(shapes, function (shape) { var newBounds = (0, _SpaceUtil.resizeBounds)(shape, direction, delta); self._modeling.resizeShape(shape, newBounds, null, { attachSupport: false, autoResize: false, layout: false }); }); }; /** * Update connections waypoints according to the rules: * 1. Both source and target are moved/resized => move waypoints by the delta * 2. Only one of source and target is moved/resized => re-layout connection with moved start/end */ SpaceToolHandler.prototype.updateConnectionWaypoints = function (connections, delta, direction, start, movingShapes, resizingShapes, oldBounds) { var self = this, affectedShapes = movingShapes.concat(resizingShapes); (0, _minDash.forEach)(connections, function (connection) { var source = connection.source, target = connection.target, waypoints = copyWaypoints(connection), axis = getAxisFromDirection(direction), layoutHints = { labelBehavior: false }; if (includes(affectedShapes, source) && includes(affectedShapes, target)) { // move waypoints waypoints = (0, _minDash.map)(waypoints, function (waypoint) { if (shouldMoveWaypoint(waypoint, start, direction)) { // move waypoint waypoint[axis] = waypoint[axis] + delta[axis]; } if (waypoint.original && shouldMoveWaypoint(waypoint.original, start, direction)) { // move waypoint original waypoint.original[axis] = waypoint.original[axis] + delta[axis]; } return waypoint; }); self._modeling.updateWaypoints(connection, waypoints, { labelBehavior: false }); } else if (includes(affectedShapes, source) || includes(affectedShapes, target)) { // re-layout connection with moved start/end if (includes(movingShapes, source)) { layoutHints.connectionStart = (0, _AnchorsHelper.getMovedSourceAnchor)(connection, source, delta); } else if (includes(movingShapes, target)) { layoutHints.connectionEnd = (0, _AnchorsHelper.getMovedTargetAnchor)(connection, target, delta); } else if (includes(resizingShapes, source)) { layoutHints.connectionStart = (0, _AnchorsHelper.getResizedSourceAnchor)(connection, source, oldBounds[source.id]); } else if (includes(resizingShapes, target)) { layoutHints.connectionEnd = (0, _AnchorsHelper.getResizedTargetAnchor)(connection, target, oldBounds[target.id]); } self._modeling.layoutConnection(connection, layoutHints); } }); }; // helpers ////////// function copyWaypoint(waypoint) { return (0, _minDash.assign)({}, waypoint); } function copyWaypoints(connection) { return (0, _minDash.map)(connection.waypoints, function (waypoint) { waypoint = copyWaypoint(waypoint); if (waypoint.original) { waypoint.original = copyWaypoint(waypoint.original); } return waypoint; }); } function getAxisFromDirection(direction) { switch (direction) { case 'n': return 'y'; case 'w': return 'x'; case 's': return 'y'; case 'e': return 'x'; } } function shouldMoveWaypoint(waypoint, start, direction) { var relevantAxis = getAxisFromDirection(direction); if (/e|s/.test(direction)) { return waypoint[relevantAxis] > start; } else if (/n|w/.test(direction)) { return waypoint[relevantAxis] < start; } } function includes(array, item) { return array.indexOf(item) !== -1; } function getBounds(shape) { return { x: shape.x, y: shape.y, height: shape.height, width: shape.width }; } },{"../../space-tool/SpaceUtil":287,"./helper/AnchorsHelper":244,"min-dash":555}],241:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ToggleShapeCollapseHandler; var _minDash = require("min-dash"); /** * 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; // recursively remember previous visibility of children context.oldChildrenVisibility = getElementsVisibilityRecursive(children); // toggle state shape.collapsed = !shape.collapsed; // recursively hide/show children var result = setHiddenRecursive(children, shape.collapsed); return [shape].concat(result); }; ToggleShapeCollapseHandler.prototype.revert = function (context) { var shape = context.shape, oldChildrenVisibility = context.oldChildrenVisibility; var children = shape.children; // recursively set old visability of children var result = restoreVisibilityRecursive(children, oldChildrenVisibility); // retoggle state shape.collapsed = !shape.collapsed; return [shape].concat(result); }; // helpers ////////////////////// /** * Return a map { elementId -> hiddenState}. * * @param {Array} elements * * @return {Object} */ function getElementsVisibilityRecursive(elements) { var result = {}; (0, _minDash.forEach)(elements, function (element) { result[element.id] = element.hidden; if (element.children) { result = (0, _minDash.assign)({}, result, getElementsVisibilityRecursive(element.children)); } }); return result; } function setHiddenRecursive(elements, newHidden) { var result = []; (0, _minDash.forEach)(elements, function (element) { element.hidden = newHidden; result = result.concat(element); if (element.children) { result = result.concat(setHiddenRecursive(element.children, element.collapsed || newHidden)); } }); return result; } function restoreVisibilityRecursive(elements, lastState) { var result = []; (0, _minDash.forEach)(elements, function (element) { element.hidden = lastState[element.id]; result = result.concat(element); if (element.children) { result = result.concat(restoreVisibilityRecursive(element.children, lastState)); } }); return result; } },{"min-dash":555}],242:[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":313}],243:[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; }; },{}],244:[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"); var _LayoutUtil = require("../../../../layout/LayoutUtil"); var _minDash = require("min-dash"); function getResizedSourceAnchor(connection, shape, oldBounds) { var waypoints = safeGetWaypoints(connection), waypointsInsideNewBounds = getWaypointsInsideBounds(waypoints, shape), oldAnchor = waypoints[0]; // new anchor is the last waypoint enclosed be resized source if (waypointsInsideNewBounds.length) { return waypointsInsideNewBounds[waypointsInsideNewBounds.length - 1]; } return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape); } function getResizedTargetAnchor(connection, shape, oldBounds) { var waypoints = safeGetWaypoints(connection), waypointsInsideNewBounds = getWaypointsInsideBounds(waypoints, shape), oldAnchor = waypoints[waypoints.length - 1]; // new anchor is the first waypoint enclosed be resized target if (waypointsInsideNewBounds.length) { return waypointsInsideNewBounds[0]; } return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape); } function getMovedSourceAnchor(connection, source, moveDelta) { var waypoints = safeGetWaypoints(connection), oldBounds = subtract(source, moveDelta), oldAnchor = waypoints[0]; return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, source); } function getMovedTargetAnchor(connection, target, moveDelta) { var waypoints = safeGetWaypoints(connection), oldBounds = subtract(target, moveDelta), oldAnchor = waypoints[waypoints.length - 1]; return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, target); } // helpers ////////////////////// function subtract(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; } function getWaypointsInsideBounds(waypoints, bounds) { var originalWaypoints = (0, _minDash.map)(waypoints, getOriginal); return (0, _minDash.filter)(originalWaypoints, function (waypoint) { return isInsideBounds(waypoint, bounds); }); } /** * Checks if point is inside bounds, incl. edges. * * @param {Point} point * @param {Bounds} bounds */ function isInsideBounds(point, bounds) { return (0, _LayoutUtil.getOrientation)(bounds, point, 1) === 'intersect'; } function getOriginal(point) { return point.original || point; } },{"../../../../layout/LayoutUtil":300,"../../../../util/AttachUtil":311,"min-dash":555}],245:[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":315,"min-dash":555}],246:[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 = _interopRequireDefault(require("./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 _MoveClosure.default().addAll(elements, true); }; },{"./AnchorsHelper":244,"./MoveClosure":245,"min-dash":555}],247:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Mouse; exports.createMoveEvent = createMoveEvent; function Mouse(eventBus) { var self = this; this._lastMoveEvent = null; function setLastMoveEvent(mousemoveEvent) { self._lastMoveEvent = mousemoveEvent; } eventBus.on('canvas.init', function (context) { var svg = self._svg = context.svg; svg.addEventListener('mousemove', setLastMoveEvent); }); eventBus.on('canvas.destroy', function () { self._lastMouseEvent = null; self._svg.removeEventListener('mousemove', setLastMoveEvent); }); } Mouse.$inject = ['eventBus']; Mouse.prototype.getLastMoveEvent = function () { return this._lastMoveEvent || createMoveEvent(0, 0); }; // helpers ////////// function createMoveEvent(x, y) { var event = document.createEvent('MouseEvent'); var screenX = x, screenY = y, clientX = x, clientY = y; if (event.initMouseEvent) { event.initMouseEvent('mousemove', true, true, window, 0, screenX, screenY, clientX, clientY, false, false, false, false, 0, null); } return event; } },{}],248:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Mouse = _interopRequireDefault(require("./Mouse")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['mouse'], mouse: ['type', _Mouse.default] }; exports.default = _default; },{"./Mouse":247}],249:[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 === false) { 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); if (delta.x === 0 && delta.y === 0) { // didn't move return; } 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); }); /** * Start move. * * @param {MouseEvent} event * @param {djs.model.Shape} shape * @param {boolean} [activate] * @param {Object} [context] */ function start(event, element, activate, context) { if ((0, _minDash.isObject)(activate)) { context = activate; activate = false; } // 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: 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":317,"min-dash":555}],250:[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, 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.remove)(dragGroup); } }); // API ////////////////////// /** * Make an element draggable. * * @param {Object} context * @param {djs.model.Base} element * @param {boolean} addMarker */ this.makeDraggable = makeDraggable; } MovePreview.$inject = ['eventBus', '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":315,"../../util/SvgTransformUtil":328,"min-dash":555,"tiny-svg":567}],251:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("../interaction-events")); var _selection = _interopRequireDefault(require("../selection")); var _outline = _interopRequireDefault(require("../outline")); var _rules = _interopRequireDefault(require("../rules")); var _dragging = _interopRequireDefault(require("../dragging")); var _previewSupport = _interopRequireDefault(require("../preview-support")); var _Move = _interopRequireDefault(require("./Move")); var _MovePreview = _interopRequireDefault(require("./MovePreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_interactionEvents.default, _selection.default, _outline.default, _rules.default, _dragging.default, _previewSupport.default], __init__: ['move', 'movePreview'], move: ['type', _Move.default], movePreview: ['type', _MovePreview.default] }; exports.default = _default; },{"../dragging":197,"../interaction-events":211,"../outline":254,"../preview-support":262,"../rules":272,"../selection":278,"./Move":249,"./MovePreview":250}],252:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = OrderingProvider; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("../../command/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) { _CommandInterceptor.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, _inherits.default)(OrderingProvider, _CommandInterceptor.default); },{"../../command/CommandInterceptor":145,"inherits":347}],253:[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":315,"min-dash":555,"min-dom":556,"tiny-svg":567}],254:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Outline = _interopRequireDefault(require("./Outline")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['outline'], outline: ['type', _Outline.default] }; exports.default = _default; },{"./Outline":253}],255:[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 = _interopRequireDefault(require("../../util/IdGenerator")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // document wide unique overlay ids var ids = new _IdGenerator.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":315,"../../util/IdGenerator":320,"min-dash":555,"min-dom":556}],256:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Overlays = _interopRequireDefault(require("./Overlays")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['overlays'], overlays: ['type', _Overlays.default] }; exports.default = _default; },{"./Overlays":255}],257:[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'; var DEFAULT_PRIORITY = 1000; /** * A palette containing modeling elements. */ function Palette(eventBus, canvas) { this._eventBus = eventBus; this._canvas = canvas; 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; self._rebuild(); }); } Palette.$inject = ['eventBus', 'canvas']; /** * Register a provider with the palette * * @param {number} [priority=1000] * @param {PaletteProvider} provider * * @example * const paletteProvider = { * getPaletteEntries: function() { * return function(entries) { * return { * ...entries, * 'entry-1': { * label: 'My Entry', * action: function() { alert("I have been clicked!"); } * } * }; * } * } * }; * * palette.registerProvider(800, paletteProvider); */ Palette.prototype.registerProvider = function (priority, provider) { if (!provider) { provider = priority; priority = DEFAULT_PRIORITY; } this._eventBus.on('palette.getProviders', priority, function (event) { event.providers.push(provider); }); this._rebuild(); }; /** * Returns the palette entries * * @return {Object} map of entries */ Palette.prototype.getEntries = function () { var providers = this._getProviders(); return providers.reduce(addPaletteEntries, {}); }; Palette.prototype._rebuild = function () { if (!this._diagramInitialized) { return; } var providers = this._getProviders(); if (!providers.length) { return; } if (!this._container) { this._init(); } this._update(); }; /** * Initialize */ Palette.prototype._init = function () { var self = this; var eventBus = this._eventBus; var parentContainer = this._getParentContainer(); var container = this._container = (0, _minDom.domify)(Palette.HTML_MARKUP); parentContainer.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 }); }; Palette.prototype._getProviders = function (id) { var event = this._eventBus.createEvent({ type: 'palette.getProviders', providers: [] }); this._eventBus.fire(event); return event.providers; }; /** * 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); }); } function addPaletteEntries(entries, provider) { var entriesOrUpdater = provider.getPaletteEntries(); if ((0, _minDash.isFunction)(entriesOrUpdater)) { return entriesOrUpdater(entries); } (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) { entries[id] = entry; }); return entries; } },{"min-dash":555,"min-dom":556}],258:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Palette = _interopRequireDefault(require("./Palette")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['palette'], palette: ['type', _Palette.default] }; exports.default = _default; },{"./Palette":257}],259:[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'; var CLOSE_EVENTS = ['contextPad.close', 'canvas.viewbox.changing', 'commandStack.changed']; var DEFAULT_PRIORITY = 1000; /** * 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 {number} [priority=1000] * @param {Object} provider * * @example * const popupMenuProvider = { * getPopupMenuEntries: function(element) { * return { * 'entry-1': { * label: 'My Entry', * action: function() { alert("I have been clicked!"); } * } * } * } * }; * * popupMenu.registerProvider('myMenuID', popupMenuProvider); */ PopupMenu.prototype.registerProvider = function (id, priority, provider) { if (!provider) { provider = priority; priority = DEFAULT_PRIORITY; } this._eventBus.on('popupMenu.getProviders.' + id, priority, function (event) { event.providers.push(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 providers = this._getProviders(providerId); if (!providers) { return true; } var entries = this._getEntries(element, providers), headerEntries = this._getHeaderEntries(element, providers); var hasEntries = (0, _minDash.size)(entries) > 0, hasHeaderEntries = headerEntries && (0, _minDash.size)(headerEntries) > 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 providers = this._getProviders(id); if (!element) { throw new Error('Element is missing'); } if (!providers || !providers.length) { throw new Error('No registered providers for: ' + id); } if (!position) { throw new Error('the position argument is missing'); } if (this.isOpen()) { this.close(); } this._emit('open'); var current = this._current = { className: id, element: element, position: position }; var entries = this._getEntries(element, providers), headerEntries = this._getHeaderEntries(element, providers); current.entries = (0, _minDash.assign)({}, entries, headerEntries); current.container = this._createContainer(); if ((0, _minDash.size)(headerEntries)) { current.container.appendChild(this._createEntries(headerEntries, 'djs-popup-header')); } if ((0, _minDash.size)(entries)) { current.container.appendChild(this._createEntries(entries, 'djs-popup-body')); } var canvas = this._canvas, parent = canvas.getContainer(); this._attachContainer(current.container, parent, position.cursor); this._bindAutoClose(); }; /** * Removes the popup menu and unbinds the event handlers. */ PopupMenu.prototype.close = function () { if (!this.isOpen()) { return; } this._emit('close'); this._unbindAutoClose(); (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); } }; PopupMenu.prototype._getProviders = function (id) { var event = this._eventBus.createEvent({ type: 'popupMenu.getProviders.' + id, providers: [] }); this._eventBus.fire(event); return event.providers; }; PopupMenu.prototype._getEntries = function (element, providers) { var entries = {}; (0, _minDash.forEach)(providers, function (provider) { // handle legacy method if (!provider.getPopupMenuEntries) { (0, _minDash.forEach)(provider.getEntries(element), function (entry) { var id = entry.id; if (!id) { throw new Error('every entry must have the id property set'); } entries[id] = (0, _minDash.omit)(entry, ['id']); }); return; } var entriesOrUpdater = provider.getPopupMenuEntries(element); if ((0, _minDash.isFunction)(entriesOrUpdater)) { entries = entriesOrUpdater(entries); } else { (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) { entries[id] = entry; }); } }); return entries; }; PopupMenu.prototype._getHeaderEntries = function (element, providers) { var entries = {}; (0, _minDash.forEach)(providers, function (provider) { // handle legacy method if (!provider.getPopupMenuHeaderEntries) { if (!provider.getHeaderEntries) { return; } (0, _minDash.forEach)(provider.getHeaderEntries(element), function (entry) { var id = entry.id; if (!id) { throw new Error('every entry must have the id property set'); } entries[id] = (0, _minDash.omit)(entry, ['id']); }); return; } var entriesOrUpdater = provider.getPopupMenuHeaderEntries(element); if ((0, _minDash.isFunction)(entriesOrUpdater)) { entries = entriesOrUpdater(entries); } else { (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) { entries[id] = entry; }); } }); return entries; }; /** * Gets an entry instance (either entry or headerEntry) by id. * * @param {string} entryId * * @return {Object} entry instance */ PopupMenu.prototype._getEntry = function (entryId) { var entry = this._current.entries[entryId]; 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. * * @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); } }; /** * 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, id) { var entryContainer = self._createEntry(entry, id); 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, id) { 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, 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; }; /** * Set up listener to close popup automatically on certain events. */ PopupMenu.prototype._bindAutoClose = function () { this._eventBus.once(CLOSE_EVENTS, this.close, this); }; /** * Remove the auto-closing listener. */ PopupMenu.prototype._unbindAutoClose = function () { this._eventBus.off(CLOSE_EVENTS, this.close, this); }; // helpers ///////////////////////////// function setTransform(element, transform) { element.style['transform-origin'] = 'top left'; ['', '-ms-', '-webkit-'].forEach(function (prefix) { element.style[prefix + 'transform'] = transform; }); } },{"min-dash":555,"min-dom":556}],260:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _PopupMenu = _interopRequireDefault(require("./PopupMenu")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['popupMenu'], popupMenu: ['type', _PopupMenu.default] }; exports.default = _default; },{"./PopupMenu":259}],261:[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"); var _minDom = require("min-dom"); var _GraphicsUtil = require("../../util/GraphicsUtil"); var MARKER_TYPES = ['marker-start', 'marker-mid', 'marker-end']; var NODES_CAN_HAVE_MARKER = ['circle', 'ellipse', 'line', 'path', 'polygon', 'polyline', 'rect']; /** * Adds support for previews of moving/resizing elements. */ function PreviewSupport(elementRegistry, eventBus, canvas, styles) { this._elementRegistry = elementRegistry; this._canvas = canvas; this._styles = styles; this._clonedMarkers = {}; var self = this; eventBus.on('drag.cleanup', function () { (0, _minDash.forEach)(self._clonedMarkers, function (clonedMarker) { (0, _tinySvg.remove)(clonedMarker); }); self._clonedMarkers = {}; }); } PreviewSupport.$inject = ['elementRegistry', 'eventBus', '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 * @param {SVGElement} [gfx] * * @return {SVGElement} dragger */ PreviewSupport.prototype.addDragger = function (element, group, gfx) { gfx = gfx || this.getGfx(element); var dragger = (0, _tinySvg.clone)(gfx); var bbox = gfx.getBoundingClientRect(); this._cloneMarkers((0, _GraphicsUtil.getVisual)(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; }; /** * Clone all markers referenced by a node and its child nodes. * * @param {SVGElement} gfx */ PreviewSupport.prototype._cloneMarkers = function (gfx) { var self = this; if (gfx.childNodes) { // TODO: use forEach once we drop PhantomJS for (var i = 0; i < gfx.childNodes.length; i++) { // recursively clone markers of child nodes self._cloneMarkers(gfx.childNodes[i]); } } if (!canHaveMarker(gfx)) { return; } MARKER_TYPES.forEach(function (markerType) { if ((0, _tinySvg.attr)(gfx, markerType)) { var marker = getMarker(gfx, markerType, self._canvas.getContainer()); self._cloneMarker(gfx, marker, markerType); } }); }; /** * Clone marker referenced by an element. * * @param {SVGElement} gfx * @param {SVGElement} marker * @param {string} markerType */ PreviewSupport.prototype._cloneMarker = function (gfx, marker, markerType) { var markerId = marker.id; var clonedMarker = this._clonedMarkers[markerId]; if (!clonedMarker) { clonedMarker = (0, _tinySvg.clone)(marker); var clonedMarkerId = markerId + '-clone'; clonedMarker.id = clonedMarkerId; (0, _tinySvg.classes)(clonedMarker).add('djs-dragger').add('djs-dragger-marker'); this._clonedMarkers[markerId] = clonedMarker; var defs = (0, _minDom.query)('defs', this._canvas._svg); if (!defs) { defs = (0, _tinySvg.create)('defs'); (0, _tinySvg.append)(this._canvas._svg, defs); } (0, _tinySvg.append)(defs, clonedMarker); } var reference = idToReference(this._clonedMarkers[markerId].id); (0, _tinySvg.attr)(gfx, markerType, reference); }; // helpers ////////// /** * Get marker of given type referenced by node. * * @param {Node} node * @param {string} markerType * @param {Node} [parentNode] * * @param {Node} */ function getMarker(node, markerType, parentNode) { var id = referenceToId((0, _tinySvg.attr)(node, markerType)); return (0, _minDom.query)('marker#' + id, parentNode || document); } /** * Get ID of fragment within current document from its functional IRI reference. * References may use single or double quotes. * * @param {string} reference * * @returns {string} */ function referenceToId(reference) { return reference.match(/url\(['"]?#([^'"]*)['"]?\)/)[1]; } /** * Get functional IRI reference for given ID of fragment within current document. * * @param {string} id * * @returns {string} */ function idToReference(id) { return 'url(#' + id + ')'; } /** * Check wether node type can have marker attributes. * * @param {Node} node * * @returns {boolean} */ function canHaveMarker(node) { return NODES_CAN_HAVE_MARKER.indexOf(node.nodeName) !== -1; } },{"../../util/GraphicsUtil":319,"min-dash":555,"min-dom":556,"tiny-svg":567}],262:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _PreviewSupport = _interopRequireDefault(require("./PreviewSupport")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['previewSupport'], previewSupport: ['type', _PreviewSupport.default] }; exports.default = _default; },{"./PreviewSupport":261}],263:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Replace; var _minDash = require("min-dash"); 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 the new bounds and 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) { if (oldElement.waypoints) { // TODO(nikku): we do not replace connections, yet return null; } var modeling = this._modeling; var width = newElementData.width || oldElement.width, height = newElementData.height || oldElement.height, x = newElementData.x || oldElement.x, y = newElementData.y || oldElement.y, centerX = round(x + width / 2), centerY = round(y + height / 2); // modeling API requires center coordinates, // account for that when handling shape bounds return modeling.replaceShape(oldElement, (0, _minDash.assign)({}, newElementData, { x: centerX, y: centerY, width: width, height: height }), options); }; },{"min-dash":555}],264:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Replace = _interopRequireDefault(require("./Replace")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['replace'], replace: ['type', _Replace.default] }; exports.default = _default; },{"./Replace":263}],265:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Resize; exports.getReferencePoint = getReferencePoint; 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); if (!boundsChanged(shape, newBounds)) { // no resize necessary return; } // 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 (n|w|s|e|nw|se|ne|sw)'); } dragging.init(event, getReferencePoint(shape, direction), 'resize', { autoActivate: true, cursor: getCursor(direction), 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']; // helpers ////////// function boundsChanged(shape, newBounds) { return shape.x !== newBounds.x || shape.y !== newBounds.y || shape.width !== newBounds.width || shape.height !== newBounds.height; } function getReferencePoint(shape, direction) { var mid = (0, _LayoutUtil.getMid)(shape), trbl = (0, _LayoutUtil.asTRBL)(shape); var referencePoint = { x: mid.x, y: mid.y }; if (direction.indexOf('n') !== -1) { referencePoint.y = trbl.top; } else if (direction.indexOf('s') !== -1) { referencePoint.y = trbl.bottom; } if (direction.indexOf('e') !== -1) { referencePoint.x = trbl.right; } else if (direction.indexOf('w') !== -1) { referencePoint.x = trbl.left; } return referencePoint; } function getCursor(direction) { var prefix = 'resize-'; if (direction === 'n' || direction === 's') { return prefix + 'ns'; } else if (direction === 'e' || direction === 'w') { return prefix + 'ew'; } else if (direction === 'nw' || direction === 'se') { return prefix + 'nwse'; } else { return prefix + 'nesw'; } } },{"../../layout/LayoutUtil":300,"./ResizeUtil":268,"min-dash":555}],266:[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 _SvgTransformUtil = require("../../util/SvgTransformUtil"); var _Resize = require("./Resize"); var HANDLE_OFFSET = -6, HANDLE_SIZE = 4, HANDLE_HIT_SIZE = 20; var CLS_RESIZER = 'djs-resizer'; var directions = ['n', 'w', 's', 'e', 'nw', 'ne', 'se', 'sw']; /** * 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, direction) { var resizersParent = this._getResizersParent(); var offset = getHandleOffset(direction); 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 visual = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(visual, { x: -HANDLE_SIZE / 2 + offset.x, y: -HANDLE_SIZE / 2 + offset.y, 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: -HANDLE_HIT_SIZE / 2 + offset.x, y: -HANDLE_HIT_SIZE / 2 + offset.y, 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); return group; }; ResizeHandles.prototype.createResizer = function (element, direction) { var point = (0, _Resize.getReferencePoint)(element, direction); var resizer = this._createResizer(element, point.x, point.y, 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 self = this; var resize = this._resize; if (!resize.canResize({ shape: shape })) { return; } (0, _minDash.forEach)(directions, function (direction) { self.createResizer(shape, direction); }); }; /** * 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']; // helpers ////////// function getHandleOffset(direction) { var offset = { x: 0, y: 0 }; if (direction.indexOf('e') !== -1) { offset.x = -HANDLE_OFFSET; } else if (direction.indexOf('w') !== -1) { offset.x = HANDLE_OFFSET; } if (direction.indexOf('s') !== -1) { offset.y = -HANDLE_OFFSET; } else if (direction.indexOf('n') !== -1) { offset.y = HANDLE_OFFSET; } return offset; } },{"../../util/Mouse":323,"../../util/SvgTransformUtil":328,"./Resize":265,"min-dash":555,"min-dom":556,"tiny-svg":567}],267:[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":567}],268:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 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; var newBounds = { x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height }; if (direction.indexOf('n') !== -1) { newBounds.y = bounds.y + dy; newBounds.height = bounds.height - dy; } else if (direction.indexOf('s') !== -1) { newBounds.height = bounds.height + dy; } if (direction.indexOf('e') !== -1) { newBounds.width = bounds.width + dx; } else if (direction.indexOf('w') !== -1) { newBounds.x = bounds.x + dx; newBounds.width = bounds.width - dx; } return newBounds; } /** * 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 === '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":300,"../../util/Elements":315,"min-dash":555}],269:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _rules = _interopRequireDefault(require("../rules")); var _dragging = _interopRequireDefault(require("../dragging")); var _previewSupport = _interopRequireDefault(require("../preview-support")); var _Resize = _interopRequireDefault(require("./Resize")); var _ResizePreview = _interopRequireDefault(require("./ResizePreview")); var _ResizeHandles = _interopRequireDefault(require("./ResizeHandles")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_rules.default, _dragging.default, _previewSupport.default], __init__: ['resize', 'resizePreview', 'resizeHandles'], resize: ['type', _Resize.default], resizePreview: ['type', _ResizePreview.default], resizeHandles: ['type', _ResizeHandles.default] }; exports.default = _default; },{"../dragging":197,"../preview-support":262,"../rules":272,"./Resize":265,"./ResizeHandles":266,"./ResizePreview":267}],270:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RuleProvider; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("../../command/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) { _CommandInterceptor.default.call(this, eventBus); this.init(); } RuleProvider.$inject = ['eventBus']; (0, _inherits.default)(RuleProvider, _CommandInterceptor.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":145,"inherits":347}],271:[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; }; },{}],272:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Rules = _interopRequireDefault(require("./Rules")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['rules'], rules: ['type', _Rules.default] }; exports.default = _default; },{"./Rules":271}],273:[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"); var _EscapeUtil = require("../../util/EscapeUtil"); /** * 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(); }); // 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 += '' + (0, _EscapeUtil.escapeHTML)(t.matched) + ''; } else { htmlText += (0, _EscapeUtil.escapeHTML)(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":315,"../../util/EscapeUtil":316,"min-dom":556}],274:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _overlays = _interopRequireDefault(require("../overlays")); var _selection = _interopRequireDefault(require("../selection")); var _SearchPad = _interopRequireDefault(require("./SearchPad")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_overlays.default, _selection.default], searchPad: ['type', _SearchPad.default] }; exports.default = _default; },{"../overlays":256,"../selection":278,"./SearchPad":273}],275:[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":555}],276:[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) { var context = e.context, canExecute = context.canExecute, elements = context.elements, hints = context.hints || {}, autoSelect = hints.autoSelect; // select elements after they have been created if (canExecute) { if (autoSelect === false) { // select no elements return; } if ((0, _minDash.isArray)(autoSelect)) { selection.select(autoSelect); } else { // select all elements by default selection.select(elements.filter(isShown)); } } }); eventBus.on('connect.end', 500, function (e) { // select the connect end target // after a connect operation if (e.context.canExecute && e.context.hover) { selection.select(e.context.hover); } }); 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']; function isShown(element) { return !element.hidden; } },{"../../util/Mouse":323,"min-dash":555}],277:[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":555}],278:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("../interaction-events")); var _outline = _interopRequireDefault(require("../outline")); var _Selection = _interopRequireDefault(require("./Selection")); var _SelectionVisuals = _interopRequireDefault(require("./SelectionVisuals")); var _SelectionBehavior = _interopRequireDefault(require("./SelectionBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['selectionVisuals', 'selectionBehavior'], __depends__: [_interactionEvents.default, _outline.default], selection: ['type', _Selection.default], selectionVisuals: ['type', _SelectionVisuals.default], selectionBehavior: ['type', _SelectionBehavior.default] }; exports.default = _default; },{"../interaction-events":211,"../outline":254,"./Selection":275,"./SelectionBehavior":276,"./SelectionVisuals":277}],279:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateMoveSnapping; var _SnapContext = _interopRequireDefault(require("./SnapContext")); var _SnapUtil = require("./SnapUtil"); var _KeyboardUtil = require("../keyboard/KeyboardUtil"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGHER_PRIORITY = 1250; /** * Snap during create and move. * * @param {EventBus} elementRegistry * @param {EventBus} eventBus * @param {Snapping} snapping */ function CreateMoveSnapping(elementRegistry, eventBus, snapping) { var self = this; this._elementRegistry = elementRegistry; eventBus.on(['create.start', 'shape.move.start'], function (event) { self.initSnap(event); }); eventBus.on(['create.move', 'create.end', 'shape.move.move', 'shape.move.end'], HIGHER_PRIORITY, function (event) { var context = event.context, shape = context.shape, snapContext = context.snapContext, target = context.target; if (event.originalEvent && (0, _KeyboardUtil.isCmd)(event.originalEvent)) { return; } if ((0, _SnapUtil.isSnapped)(event) || !target) { return; } var snapPoints = snapContext.pointsForTarget(target); if (!snapPoints.initialized) { snapPoints = self.addSnapTargetPoints(snapPoints, shape, target); snapPoints.initialized = true; } snapping.snap(event, snapPoints); }); eventBus.on(['create.cleanup', 'shape.move.cleanup'], function () { snapping.hide(); }); } CreateMoveSnapping.$inject = ['elementRegistry', 'eventBus', 'snapping']; CreateMoveSnapping.prototype.initSnap = function (event) { var elementRegistry = this._elementRegistry; var context = event.context, shape = context.shape, snapContext = context.snapContext; if (!snapContext) { snapContext = context.snapContext = new _SnapContext.default(); } var shapeMid; if (elementRegistry.get(shape.id)) { // move shapeMid = (0, _SnapUtil.mid)(shape, event); } else { // create shapeMid = { x: event.x + (0, _SnapUtil.mid)(shape).x, y: event.y + (0, _SnapUtil.mid)(shape).y }; } var shapeTopLeft = { x: shapeMid.x - shape.width / 2, y: shapeMid.y - shape.height / 2 }, shapeBottomRight = { x: shapeMid.x + shape.width / 2, y: shapeMid.y + shape.height / 2 }; snapContext.setSnapOrigin('mid', { x: shapeMid.x - event.x, y: shapeMid.y - event.y }); // snap labels to mid only if (isLabel(shape)) { return snapContext; } 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 }); return snapContext; }; CreateMoveSnapping.prototype.addSnapTargetPoints = function (snapPoints, shape, target) { var snapTargets = this.getSnapTargets(shape, target); (0, _minDash.forEach)(snapTargets, function (snapTarget) { // handle labels if (isLabel(snapTarget)) { if (isLabel(shape)) { snapPoints.add('mid', (0, _SnapUtil.mid)(snapTarget)); } return; } // handle connections if (isConnection(snapTarget)) { // ignore single segment connections if (snapTarget.waypoints.length < 3) { return; } // ignore first and last waypoint var waypoints = snapTarget.waypoints.slice(1, -1); (0, _minDash.forEach)(waypoints, function (waypoint) { snapPoints.add('mid', waypoint); }); return; } // handle shapes snapPoints.add('mid', (0, _SnapUtil.mid)(snapTarget)); }); if (!(0, _minDash.isNumber)(shape.x) || !(0, _minDash.isNumber)(shape.y)) { return snapPoints; } // snap to original position when moving if (this._elementRegistry.get(shape.id)) { snapPoints.add('mid', (0, _SnapUtil.mid)(shape)); } return snapPoints; }; CreateMoveSnapping.prototype.getSnapTargets = function (shape, target) { return (0, _SnapUtil.getChildren)(target).filter(function (child) { return !isHidden(child); }); }; // helpers ////////// function isConnection(element) { return !!element.waypoints; } function isHidden(element) { return !!element.hidden; } function isLabel(element) { return !!element.labelTarget; } },{"../keyboard/KeyboardUtil":216,"./SnapContext":281,"./SnapUtil":282,"min-dash":555}],280:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeSnapping; var _SnapContext = _interopRequireDefault(require("./SnapContext")); var _SnapUtil = require("./SnapUtil"); var _KeyboardUtil = require("../keyboard/KeyboardUtil"); var _LayoutUtil = require("../../layout/LayoutUtil"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGHER_PRIORITY = 1250; /** * Snap during resize. * * @param {EventBus} eventBus * @param {Snapping} snapping */ function ResizeSnapping(eventBus, snapping) { var self = this; eventBus.on(['resize.start'], function (event) { self.initSnap(event); }); eventBus.on(['resize.move', 'resize.end'], HIGHER_PRIORITY, function (event) { var context = event.context, shape = context.shape, parent = shape.parent, direction = context.direction, snapContext = context.snapContext; if (event.originalEvent && (0, _KeyboardUtil.isCmd)(event.originalEvent)) { return; } if ((0, _SnapUtil.isSnapped)(event)) { return; } var snapPoints = snapContext.pointsForTarget(parent); if (!snapPoints.initialized) { snapPoints = self.addSnapTargetPoints(snapPoints, shape, parent, direction); snapPoints.initialized = true; } if (isHorizontal(direction)) { (0, _SnapUtil.setSnapped)(event, 'x', event.x); } if (isVertical(direction)) { (0, _SnapUtil.setSnapped)(event, 'y', event.y); } snapping.snap(event, snapPoints); }); eventBus.on(['resize.cleanup'], function () { snapping.hide(); }); } ResizeSnapping.prototype.initSnap = function (event) { var context = event.context, shape = context.shape, direction = context.direction, snapContext = context.snapContext; if (!snapContext) { snapContext = context.snapContext = new _SnapContext.default(); } var snapOrigin = getSnapOrigin(shape, direction); snapContext.setSnapOrigin('corner', { x: snapOrigin.x - event.x, y: snapOrigin.y - event.y }); return snapContext; }; ResizeSnapping.prototype.addSnapTargetPoints = function (snapPoints, shape, target, direction) { var snapTargets = this.getSnapTargets(shape, target); (0, _minDash.forEach)(snapTargets, function (snapTarget) { snapPoints.add('corner', (0, _SnapUtil.bottomRight)(snapTarget)); snapPoints.add('corner', (0, _SnapUtil.topLeft)(snapTarget)); }); snapPoints.add('corner', getSnapOrigin(shape, direction)); return snapPoints; }; ResizeSnapping.$inject = ['eventBus', 'snapping']; ResizeSnapping.prototype.getSnapTargets = function (shape, target) { return (0, _SnapUtil.getChildren)(target).filter(function (child) { return !isAttached(child, shape) && !isConnection(child) && !isHidden(child) && !isLabel(child); }); }; // helpers ////////// function getSnapOrigin(shape, direction) { var mid = (0, _LayoutUtil.getMid)(shape), trbl = (0, _LayoutUtil.asTRBL)(shape); var snapOrigin = { x: mid.x, y: mid.y }; if (direction.indexOf('n') !== -1) { snapOrigin.y = trbl.top; } else if (direction.indexOf('s') !== -1) { snapOrigin.y = trbl.bottom; } if (direction.indexOf('e') !== -1) { snapOrigin.x = trbl.right; } else if (direction.indexOf('w') !== -1) { snapOrigin.x = trbl.left; } return snapOrigin; } function isAttached(element, host) { return element.host === host; } function isConnection(element) { return !!element.waypoints; } function isHidden(element) { return !!element.hidden; } function isLabel(element) { return !!element.labelTarget; } function isHorizontal(direction) { return direction === 'n' || direction === 's'; } function isVertical(direction) { return direction === 'e' || direction === 'w'; } },{"../../layout/LayoutUtil":300,"../keyboard/KeyboardUtil":216,"./SnapContext":281,"./SnapUtil":282,"min-dash":555}],281:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SnapContext; exports.SnapPoints = SnapPoints; 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":282,"min-dash":555}],282:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.snapTo = snapTo; exports.topLeft = topLeft; exports.topRight = topRight; exports.bottomLeft = bottomLeft; exports.bottomRight = bottomRight; exports.mid = mid; exports.isSnapped = isSnapped; exports.setSnapped = setSnapped; exports.getChildren = getChildren; 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 topRight(bounds) { return { x: bounds.x + bounds.width, y: bounds.y }; } function bottomLeft(bounds) { return { x: bounds.x, y: bounds.y + bounds.height }; } function bottomRight(bounds) { return { x: bounds.x + bounds.width, y: bounds.y + bounds.height }; } 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) }; } /** * 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; } /** * Get children of a shape. * * @param {djs.model.Shape} parent * * @returns {Array} */ function getChildren(parent) { return parent.children || []; } },{}],283:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Snapping; exports.SNAP_LINE_HIDE_DELAY = void 0; var _minDash = require("min-dash"); var _SnapUtil = require("./SnapUtil"); var _tinySvg = require("tiny-svg"); var SNAP_TOLERANCE = 7; var SNAP_LINE_HIDE_DELAY = 1000; /** * Generic snapping feature. * * @param {EventBus} eventBus * @param {Canvas} canvas */ exports.SNAP_LINE_HIDE_DELAY = SNAP_LINE_HIDE_DELAY; function Snapping(canvas) { this._canvas = canvas; // delay hide by 1000 seconds since last snap this._asyncHide = (0, _minDash.debounce)((0, _minDash.bind)(this.hide, this), SNAP_LINE_HIDE_DELAY); } Snapping.$inject = ['canvas']; /** * Snap an event to given snap points. * * @param {Event} event * @param {SnapPoints} snapPoints */ Snapping.prototype.snap = function (event, snapPoints) { var context = event.context, snapContext = context.snapContext, snapLocations = snapContext.getSnapLocations(); 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 both axis if not snapped already (0, _minDash.forEach)(['x', 'y'], function (axis) { var locationSnapping; if (!snapping[axis]) { locationSnapping = snapPoints.snap(snapCurrent, location, axis, SNAP_TOLERANCE); if (locationSnapping !== undefined) { snapping[axis] = { value: locationSnapping, originValue: locationSnapping - snapOrigin[axis] }; } } }); // no need to continue snapping if (snapping.x && snapping.y) { return false; } }); // show snap lines this.showSnapLine('vertical', snapping.x && snapping.x.value); this.showSnapLine('horizontal', snapping.y && snapping.y.value); // snap event (0, _minDash.forEach)(['x', 'y'], function (axis) { var axisSnapping = snapping[axis]; if ((0, _minDash.isObject)(axisSnapping)) { (0, _SnapUtil.setSnapped)(event, axis, axisSnapping.originValue); } }); }; Snapping.prototype._createLine = function (orientation) { var root = this._canvas.getLayer('snap'); 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 (position) { if (!(0, _minDash.isNumber)(position)) { (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 (snapLine) { snapLine.update(); }); }; },{"./SnapUtil":282,"min-dash":555,"tiny-svg":567}],284:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _CreateMoveSnapping = _interopRequireDefault(require("./CreateMoveSnapping")); var _ResizeSnapping = _interopRequireDefault(require("./ResizeSnapping")); var _Snapping = _interopRequireDefault(require("./Snapping")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['createMoveSnapping', 'resizeSnapping', 'snapping'], createMoveSnapping: ['type', _CreateMoveSnapping.default], resizeSnapping: ['type', _ResizeSnapping.default], snapping: ['type', _Snapping.default] }; exports.default = _default; },{"./CreateMoveSnapping":279,"./ResizeSnapping":280,"./Snapping":283}],285:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceTool; var _minDash = require("min-dash"); var _LayoutUtil = require("../../layout/LayoutUtil"); var _Elements = require("../../util/Elements"); var _SpaceUtil = require("./SpaceUtil"); var _Mouse = require("../../util/Mouse"); var _Cursor = require("../../util/Cursor"); var abs = Math.abs, round = Math.round; var AXIS_TO_DIMENSION = { x: 'width', y: 'height' }; var CURSOR_CROSSHAIR = 'crosshair'; var DIRECTION_TO_TRBL = { n: 'top', w: 'left', s: 'bottom', e: 'right' }; var HIGH_PRIORITY = 1500; var DIRECTION_TO_OPPOSITE = { n: 's', w: 'e', s: 'n', e: 'w' }; var PADDING = 20; /** * Add or remove space by moving and resizing elements. * * @param {Canvas} canvas * @param {Dragging} dragging * @param {EventBus} eventBus * @param {Modeling} modeling * @param {Rules} rules * @param {toolManager} toolManager */ function SpaceTool(canvas, dragging, eventBus, modeling, rules, toolManager) { this._canvas = canvas; this._dragging = dragging; this._eventBus = eventBus; 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) { eventBus.once('spaceTool.selection.ended', function () { self.activateMakeSpace(event.originalEvent); }); }); eventBus.on('spaceTool.move', HIGH_PRIORITY, function (event) { var context = event.context, initialized = context.initialized; if (!initialized) { initialized = context.initialized = self.init(event, context); } if (initialized) { ensureConstraints(event); } }); eventBus.on('spaceTool.end', function (event) { var context = event.context, axis = context.axis, direction = context.direction, movingShapes = context.movingShapes, resizingShapes = context.resizingShapes, start = context.start; if (!context.initialized) { return; } ensureConstraints(event); var delta = { x: 0, y: 0 }; delta[axis] = round(event['d' + axis]); self.makeSpace(movingShapes, resizingShapes, delta, direction, start); eventBus.once('spaceTool.ended', function (event) { // activate space tool selection after make space self.activateSelection(event.originalEvent, true, true); }); }); } SpaceTool.$inject = ['canvas', 'dragging', 'eventBus', 'modeling', 'rules', 'toolManager']; /** * Activate space tool selection. * * @param {Object} event * @param {boolean} autoActivate */ SpaceTool.prototype.activateSelection = function (event, autoActivate, reactivate) { this._dragging.init(event, 'spaceTool.selection', { autoActivate: autoActivate, cursor: CURSOR_CROSSHAIR, data: { context: { reactivate: reactivate } }, trapClick: false }); }; /** * Activate space tool make space. * * @param {MouseEvent} event */ SpaceTool.prototype.activateMakeSpace = function (event) { this._dragging.init(event, 'spaceTool', { autoActivate: true, cursor: CURSOR_CROSSHAIR, data: { context: {} } }); }; /** * Make space. * * @param {Array} movingShapes * @param {Array} resizingShapes * @param {Object} delta * @param {number} delta.x * @param {number} delta.y * @param {string} direction * @param {number} start */ SpaceTool.prototype.makeSpace = function (movingShapes, resizingShapes, delta, direction, start) { return this._modeling.createSpace(movingShapes, resizingShapes, delta, direction, start); }; /** * Initialize make space and return true if that was successful. * * @param {Object} event * @param {Object} context * * @return {boolean} */ SpaceTool.prototype.init = function (event, context) { var axis = abs(event.dx) > abs(event.dy) ? 'x' : 'y', delta = event['d' + axis], start = event[axis] - delta; if (abs(delta) < 5) { return false; } // invert delta to remove space when moving left if (delta < 0) { delta *= -1; } // invert delta to add/remove space when removing/adding space if modifier key is pressed if ((0, _Mouse.hasPrimaryModifier)(event)) { delta *= -1; } var direction = (0, _SpaceUtil.getDirection)(axis, delta); var root = this._canvas.getRootElement(); var children = (0, _Elements.selfAndAllChildren)(root, true); var elements = this.calculateAdjustments(children, axis, delta, start); var minDimensions = this._eventBus.fire('spaceTool.getMinDimensions', { axis: axis, direction: direction, shapes: elements.resizingShapes, start: start }); var spaceToolConstraints = getSpaceToolConstraints(elements, axis, direction, start, minDimensions); (0, _minDash.assign)(context, elements, { axis: axis, direction: direction, spaceToolConstraints: spaceToolConstraints, start: start }); (0, _Cursor.set)('resize-' + (axis === 'x' ? 'ew' : 'ns')); return true; }; /** * Get elements to be moved and resized. * * @param {Array} elements * @param {string} axis * @param {number} delta * @param {number} start * * @return {Object} */ SpaceTool.prototype.calculateAdjustments = function (elements, axis, delta, start) { var rules = this._rules; var movingShapes = [], resizingShapes = []; (0, _minDash.forEach)(elements, function (element) { if (!element.parent || isConnection(element)) { return; } var shapeStart = element[axis], shapeEnd = shapeStart + element[AXIS_TO_DIMENSION[axis]]; // shape to be moved if (delta > 0 && shapeStart > start || delta < 0 && shapeEnd < start) { return movingShapes.push(element); } // shape to be resized if (shapeStart < start && shapeEnd > start && rules.allowed('shape.resize', { shape: element })) { return resizingShapes.push(element); } }); 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); }; // helpers ////////// function addPadding(trbl) { return { top: trbl.top - PADDING, right: trbl.right + PADDING, bottom: trbl.bottom + PADDING, left: trbl.left - PADDING }; } function ensureConstraints(event) { var context = event.context, spaceToolConstraints = context.spaceToolConstraints; if (!spaceToolConstraints) { return; } var x, y; if ((0, _minDash.isNumber)(spaceToolConstraints.left)) { x = Math.max(event.x, spaceToolConstraints.left); event.dx = event.dx + x - event.x; event.x = x; } if ((0, _minDash.isNumber)(spaceToolConstraints.right)) { x = Math.min(event.x, spaceToolConstraints.right); event.dx = event.dx + x - event.x; event.x = x; } if ((0, _minDash.isNumber)(spaceToolConstraints.top)) { y = Math.max(event.y, spaceToolConstraints.top); event.dy = event.dy + y - event.y; event.y = y; } if ((0, _minDash.isNumber)(spaceToolConstraints.bottom)) { y = Math.min(event.y, spaceToolConstraints.bottom); event.dy = event.dy + y - event.y; event.y = y; } } function getSpaceToolConstraints(elements, axis, direction, start, minDimensions) { var movingShapes = elements.movingShapes, resizingShapes = elements.resizingShapes; if (!resizingShapes.length) { return; } var spaceToolConstraints = {}, min, max; (0, _minDash.forEach)(resizingShapes, function (resizingShape) { var resizingShapeBBox = (0, _LayoutUtil.asTRBL)(resizingShape); // find children that are not moving or resizing var nonMovingResizingChildren = (0, _minDash.filter)(resizingShape.children, function (child) { return !isConnection(child) && !isLabel(child) && !includes(movingShapes, child) && !includes(resizingShapes, child); }); // find children that are moving var movingChildren = (0, _minDash.filter)(resizingShape.children, function (child) { return !isConnection(child) && !isLabel(child) && includes(movingShapes, child); }); var minOrMax, nonMovingResizingChildrenBBox, movingChildrenBBox; if (nonMovingResizingChildren.length) { nonMovingResizingChildrenBBox = addPadding((0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(nonMovingResizingChildren))); minOrMax = start - resizingShapeBBox[DIRECTION_TO_TRBL[direction]] + nonMovingResizingChildrenBBox[DIRECTION_TO_TRBL[direction]]; if (direction === 'n') { spaceToolConstraints.bottom = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 'w') { spaceToolConstraints.right = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 's') { spaceToolConstraints.top = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } else if (direction === 'e') { spaceToolConstraints.left = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } } if (movingChildren.length) { movingChildrenBBox = addPadding((0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(movingChildren))); minOrMax = start - movingChildrenBBox[DIRECTION_TO_TRBL[DIRECTION_TO_OPPOSITE[direction]]] + resizingShapeBBox[DIRECTION_TO_TRBL[DIRECTION_TO_OPPOSITE[direction]]]; if (direction === 'n') { spaceToolConstraints.bottom = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 'w') { spaceToolConstraints.right = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 's') { spaceToolConstraints.top = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } else if (direction === 'e') { spaceToolConstraints.left = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } } var resizingShapeMinDimensions = minDimensions && minDimensions[resizingShape.id]; if (resizingShapeMinDimensions) { if (direction === 'n') { minOrMax = start + resizingShape[AXIS_TO_DIMENSION[axis]] - resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]]; spaceToolConstraints.bottom = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 'w') { minOrMax = start + resizingShape[AXIS_TO_DIMENSION[axis]] - resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]]; spaceToolConstraints.right = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 's') { minOrMax = start - resizingShape[AXIS_TO_DIMENSION[axis]] + resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]]; spaceToolConstraints.top = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } else if (direction === 'e') { minOrMax = start - resizingShape[AXIS_TO_DIMENSION[axis]] + resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]]; spaceToolConstraints.left = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } } }); return spaceToolConstraints; } function includes(array, item) { return array.indexOf(item) !== -1; } function isConnection(element) { return !!element.waypoints; } function isLabel(element) { return !!element.labelTarget; } },{"../../layout/LayoutUtil":300,"../../util/Cursor":314,"../../util/Elements":315,"../../util/Mouse":323,"./SpaceUtil":287,"min-dash":555}],286:[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; var max = Math.max; /** * 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); var initialBounds = frame.getBBox(); frames.push({ element: frame, initialBounds: initialBounds }); 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, { d: orientation[axis] }); 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) { var element = frame.element, initialBounds = frame.initialBounds, width, height; if (context.direction === 'e') { (0, _tinySvg.attr)(element, { width: max(initialBounds.width + delta.x, 5) }); } else { width = max(initialBounds.width - delta.x, 5); (0, _tinySvg.attr)(element, { width: width, x: initialBounds.x + initialBounds.width - width }); } if (context.direction === 's') { (0, _tinySvg.attr)(element, { height: max(initialBounds.height + delta.y, 5) }); } else { height = max(initialBounds.height - delta.y, 5); (0, _tinySvg.attr)(element, { height: height, y: initialBounds.y + initialBounds.height - height }); } }); }); // 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":328,"min-dash":555,"tiny-svg":567}],287:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDirection = getDirection; exports.getWaypointsUpdatingConnections = getWaypointsUpdatingConnections; exports.resizeBounds = resizeBounds; var _minDash = require("min-dash"); /** * Return direction given axis and delta. * * @param {string} axis * @param {number} delta * * @return {string} */ function getDirection(axis, delta) { if (axis === 'x') { if (delta > 0) { return 'e'; } if (delta < 0) { return 'w'; } } if (axis === 'y') { if (delta > 0) { return 's'; } if (delta < 0) { return 'n'; } } return null; } /** * Returns connections whose waypoints are to be updated. Waypoints are to be updated if start * or end is to be moved or resized. * * @param {Array} */ function getWaypointsUpdatingConnections(movingShapes, resizingShapes) { var waypointsUpdatingConnections = []; (0, _minDash.forEach)(movingShapes.concat(resizingShapes), function (shape) { var incoming = shape.incoming, outgoing = shape.outgoing; (0, _minDash.forEach)(incoming.concat(outgoing), function (connection) { var source = connection.source, target = connection.target; if (includes(movingShapes, source) || includes(movingShapes, target) || includes(resizingShapes, source) || includes(resizingShapes, target)) { if (!includes(waypointsUpdatingConnections, connection)) { waypointsUpdatingConnections.push(connection); } } }); }); return waypointsUpdatingConnections; } function includes(array, item) { return array.indexOf(item) !== -1; } /** * Resize bounds. * * @param {Object} bounds * @param {number} bounds.x * @param {number} bounds.y * @param {number} bounds.width * @param {number} bounds.height * @param {string} direction * @param {Object} delta * @param {number} delta.x * @param {number} delta.y * * @return {Object} */ function resizeBounds(bounds, direction, delta) { var x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height, dx = delta.x, dy = delta.y; switch (direction) { case 'n': return { x: x, y: y + dy, width: width, height: height - dy }; case 's': return { x: x, y: y, width: width, height: height + dy }; case 'w': return { x: x + dx, y: y, width: width - dx, height: height }; case 'e': return { x: x, y: y, width: width + dx, height: height }; default: throw new Error('unknown direction: ' + direction); } } },{"min-dash":555}],288:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _rules = _interopRequireDefault(require("../rules")); var _toolManager = _interopRequireDefault(require("../tool-manager")); var _previewSupport = _interopRequireDefault(require("../preview-support")); var _SpaceTool = _interopRequireDefault(require("./SpaceTool")); var _SpaceToolPreview = _interopRequireDefault(require("./SpaceToolPreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['spaceToolPreview'], __depends__: [_dragging.default, _rules.default, _toolManager.default, _previewSupport.default], spaceTool: ['type', _SpaceTool.default], spaceToolPreview: ['type', _SpaceToolPreview.default] }; exports.default = _default; },{"../dragging":197,"../preview-support":262,"../rules":272,"../tool-manager":290,"./SpaceTool":285,"./SpaceToolPreview":286}],289:[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":555,"min-dom":556}],290:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _ToolManager = _interopRequireDefault(require("./ToolManager")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_dragging.default], __init__: ['toolManager'], toolManager: ['type', _ToolManager.default] }; exports.default = _default; },{"../dragging":197,"./ToolManager":289}],291:[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 = _interopRequireDefault(require("../../util/IdGenerator")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // document wide unique tooltip ids var ids = new _IdGenerator.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":320,"min-dash":555,"min-dom":556}],292:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Tooltips = _interopRequireDefault(require("./Tooltips")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['tooltips'], tooltips: ['type', _Tooltips.default] }; exports.default = _default; },{"./Tooltips":291}],293:[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":567}],294:[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 = _interopRequireDefault(require("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 _hammerjs.default.Manager(node, { inputClass: _hammerjs.default.TouchInput, recognizers: [] }); var tap = new _hammerjs.default.Tap(); var pan = new _hammerjs.default.Pan({ threshold: 10 }); var press = new _hammerjs.default.Press(); var pinch = new _hammerjs.default.Pinch(); var doubleTap = new _hammerjs.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":317,"hammerjs":345,"min-dash":555,"min-dom":556}],295:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("../interaction-events")); var _TouchInteractionEvents = _interopRequireDefault(require("./TouchInteractionEvents")); var _TouchFix = _interopRequireDefault(require("./TouchFix")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_interactionEvents.default], __init__: ['touchInteractionEvents'], touchInteractionEvents: ['type', _TouchInteractionEvents.default], touchFix: ['type', _TouchFix.default] }; exports.default = _default; },{"../interaction-events":211,"./TouchFix":293,"./TouchInteractionEvents":294}],296:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _translate = _interopRequireDefault(require("./translate")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { translate: ['value', _translate.default] }; exports.default = _default; },{"./translate":297}],297:[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 + '}'; }); } },{}],298:[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] * @param {Point} [hints.source] * @param {Point} [hints.target] * * @return {Array} the layouted connection waypoints */ BaseLayouter.prototype.layoutConnection = function (connection, hints) { hints = hints || {}; return [hints.connectionStart || (0, _LayoutUtil.getMid)(hints.source || connection.source), hints.connectionEnd || (0, _LayoutUtil.getMid)(hints.target || connection.target)]; }; },{"./LayoutUtil":300}],299:[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":300,"min-dash":555}],300:[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; exports.filterRedundantWaypoints = filterRedundantWaypoints; var _minDash = require("min-dash"); var _Geometry = require("../util/Geometry"); var _pathIntersection = _interopRequireDefault(require("path-intersection")); 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, _pathIntersection.default)(a, b); } 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; } },{"../util/Geometry":318,"min-dash":555,"path-intersection":563}],301:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.connectPoints = connectPoints; exports.connectRectangles = connectRectangles; exports.repairConnection = repairConnection; exports.tryLayoutStraight = tryLayoutStraight; 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 // attempt to layout a straight line repairedWaypoints = preferStraight && tryLayoutStraight(source, target, start, end, hints); if (repairedWaypoints) { return repairedWaypoints; } // try to layout from end repairedWaypoints = hints.connectionEnd && tryRepairConnectionEnd(target, source, end, waypoints); if (repairedWaypoints) { return repairedWaypoints; } // try to layout from start repairedWaypoints = hints.connectionStart && tryRepairConnectionStart(source, target, start, waypoints); if (repairedWaypoints) { return repairedWaypoints; } // or whether nothing seems to have changed if (!hints.connectionStart && !hints.connectionEnd && waypoints && waypoints.length) { return waypoints; } // simply reconnect if nothing else worked return connectRectangles(source, target, start, end, hints); } 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|null} waypoints if straight layout worked */ function tryLayoutStraight(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 start. * * @param {Bounds} moved * @param {Bounds} other * @param {Point} newDocking * @param {Array} points originalPoints from moved to other * * @return {Array|null} the repaired points between the two rectangles */ function tryRepairConnectionStart(moved, other, newDocking, points) { return _tryRepairConnectionSide(moved, other, newDocking, points); } /** * Repair a connection from end. * * @param {Bounds} moved * @param {Bounds} other * @param {Point} newDocking * @param {Array} points originalPoints from moved to other * * @return {Array|null} the repaired points between the two rectangles */ function tryRepairConnectionEnd(moved, other, newDocking, points) { var waypoints = points.slice().reverse(); waypoints = _tryRepairConnectionSide(moved, other, newDocking, waypoints); return waypoints ? waypoints.reverse() : null; } /** * 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 _tryRepairConnectionSide(moved, other, newDocking, points) { function needsRelayout(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 horizontal alignment return { x: newPeer.x, y: candidate.y }; case 'h': // repair vertical alignment return { x: candidate.x, y: newPeer.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(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) { newPoints = _tryRepairConnectionSide(moved, other, newDocking, slicedPoints); } // (4) do NOT repair if repaired bendpoints are aligned if (newPoints && (0, _Geometry.pointsAligned)(newPoints)) { return null; } 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":318,"./LayoutUtil":300,"min-dash":555}],302:[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 = _interopRequireDefault(require("inherits")); var _objectRefs = _interopRequireDefault(require("object-refs")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var parentRefs = new _objectRefs.default({ name: 'children', enumerable: true, collection: true }, { name: 'parent' }), labelRefs = new _objectRefs.default({ name: 'labels', enumerable: true, collection: true }, { name: 'labelTarget' }), attacherRefs = new _objectRefs.default({ name: 'attachers', collection: true }, { name: 'host' }), outgoingRefs = new _objectRefs.default({ name: 'outgoing', collection: true }, { name: 'source' }), incomingRefs = new _objectRefs.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 () { return this.labels[0]; }, set: function (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); /** * Indicates frame shapes * * @name Shape#isFrame * @type boolean */ /** * 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, _inherits.default)(Shape, Base); /** * A root graphical object * * @class * @constructor * * @extends Shape */ function Root() { Shape.call(this); } (0, _inherits.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, _inherits.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, _inherits.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":347,"min-dash":555,"object-refs":560}],303:[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":555}],304:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _keyboard = _interopRequireDefault(require("../../features/keyboard")); var _KeyboardMove = _interopRequireDefault(require("./KeyboardMove")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_keyboard.default], __init__: ['keyboardMove'], keyboardMove: ['type', _KeyboardMove.default] }; exports.default = _default; },{"../../features/keyboard":217,"./KeyboardMove":303}],305:[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":312,"../../util/Cursor":314,"../../util/Event":317,"../../util/PositionUtil":325,"min-dom":556}],306:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _MoveCanvas = _interopRequireDefault(require("./MoveCanvas")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['moveCanvas'], moveCanvas: ['type', _MoveCanvas.default] }; exports.default = _default; },{"./MoveCanvas":305}],307:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _touch = _interopRequireDefault(require("../../features/touch")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_touch.default] }; exports.default = _default; },{"../../features/touch":295}],308:[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 * @param {Object} 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 */ 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 * @param {Object} position * @param {number} stepSize */ 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":322,"./ZoomUtil":309,"min-dash":555,"min-dom":556}],309:[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 * @param {number} range.min * @param {number} range.max */ 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":322}],310:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ZoomScroll = _interopRequireDefault(require("./ZoomScroll")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['zoomScroll'], zoomScroll: ['type', _ZoomScroll.default] }; exports.default = _default; },{"./ZoomScroll":308}],311:[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), stickyPositionDelta = getStickyPositionDelta(shapeCenter, oldBounds, newBounds); if (stickyPositionDelta) { return stickyPositionDelta; } 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 }); } function getStickyPositionDelta(oldShapeCenter, oldBounds, newBounds) { var oldTRBL = (0, _LayoutUtil.asTRBL)(oldBounds), newTRBL = (0, _LayoutUtil.asTRBL)(newBounds); if (isMoved(oldTRBL, newTRBL)) { return null; } var oldOrientation = (0, _LayoutUtil.getOrientation)(oldBounds, oldShapeCenter), stickyPositionDelta, newShapeCenter, newOrientation; if (oldOrientation === 'top') { stickyPositionDelta = { x: 0, y: newTRBL.bottom - oldTRBL.bottom }; } else if (oldOrientation === 'bottom') { stickyPositionDelta = { x: 0, y: newTRBL.top - oldTRBL.top }; } else if (oldOrientation === 'right') { stickyPositionDelta = { x: newTRBL.left - oldTRBL.left, y: 0 }; } else if (oldOrientation === 'left') { stickyPositionDelta = { x: newTRBL.right - oldTRBL.right, y: 0 }; } else { // fallback to proportional movement for corner-placed attachments return null; } newShapeCenter = { x: oldShapeCenter.x + stickyPositionDelta.x, y: oldShapeCenter.y + stickyPositionDelta.y }; newOrientation = (0, _LayoutUtil.getOrientation)(newBounds, newShapeCenter); if (newOrientation !== oldOrientation) { // fallback to proportional movement if orientation would otherwise change return null; } return stickyPositionDelta; } function isMoved(oldTRBL, newTRBL) { return isHorizontallyMoved(oldTRBL, newTRBL) || isVerticallyMoved(oldTRBL, newTRBL); } function isHorizontallyMoved(oldTRBL, newTRBL) { return oldTRBL.right !== newTRBL.right && oldTRBL.left !== newTRBL.left; } function isVerticallyMoved(oldTRBL, newTRBL) { return oldTRBL.top !== newTRBL.top && oldTRBL.bottom !== newTRBL.bottom; } },{"../layout/LayoutUtil":300,"./PositionUtil":325}],312:[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); }; } },{}],313:[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); } },{}],314:[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":556}],315:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getParents = getParents; 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; exports.isFrameElement = isFrameElement; var _minDash = require("min-dash"); /** * Get parent elements. * * @param {Array} elements * * @returns {Array} */ function getParents(elements) { // find elements that are not children of any other elements return (0, _minDash.filter)(elements, function (element) { return !(0, _minDash.find)(elements, function (e) { return e !== element && getParent(element, e); }); }); } function getParent(element, parent) { if (!parent) { return; } if (element === parent) { return parent; } if (!element.parent) { return; } return getParent(element.parent, parent); } /** * 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'; } function isFrameElement(element) { return !!(element && element.isFrame); } // helpers /////////////////////////////// function copyObject(src1, src2) { return (0, _minDash.assign)({}, src1 || {}, src2 || {}); } },{"min-dash":555}],316:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.escapeHTML = escapeHTML; Object.defineProperty(exports, "escapeCSS", { enumerable: true, get: function () { return _css.default; } }); var _css = _interopRequireDefault(require("css.escape")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HTML_ESCAPE_MAP = { '&': '&', '<': '<', '>': '>', '"': '"', '\'': ''' }; function escapeHTML(str) { str = '' + str; return str && str.replace(/[&<>"']/g, function (match) { return HTML_ESCAPE_MAP[match]; }); } },{"css.escape":331}],317:[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; } },{}],318:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.pointDistance = pointDistance; exports.pointsOnLine = pointsOnLine; exports.pointsAligned = pointsAligned; exports.pointsAlignedHorizontally = pointsAlignedHorizontally; exports.pointsAlignedVertically = pointsAlignedVertically; exports.pointInRect = pointInRect; exports.getMidPoint = getMidPoint; var _minDash = require("min-dash"); /** * 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; /** * Check whether two points are horizontally or vertically aligned. * * @param {Array|Point} * @param {Point} * * @return {string|boolean} */ function pointsAligned(a, b) { var points; if ((0, _minDash.isArray)(a)) { points = a; } else { points = [a, b]; } if (pointsAlignedHorizontally(points)) { return 'h'; } if (pointsAlignedVertically(points)) { return 'v'; } return false; } function pointsAlignedHorizontally(a, b) { var points; if ((0, _minDash.isArray)(a)) { points = a; } else { points = [a, b]; } var firstPoint = points.slice().shift(); return (0, _minDash.every)(points, function (point) { return Math.abs(firstPoint.y - point.y) <= ALIGNED_THRESHOLD; }); } function pointsAlignedVertically(a, b) { var points; if ((0, _minDash.isArray)(a)) { points = a; } else { points = [a, b]; } var firstPoint = points.slice().shift(); return (0, _minDash.every)(points, function (point) { return Math.abs(firstPoint.x - point.x) <= ALIGNED_THRESHOLD; }); } /** * 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) }; } },{"min-dash":555}],319:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getVisual = getVisual; exports.getChildren = getChildren; /** * 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 gfx.childNodes[0]; } /** * Returns the children for a given diagram element. * * @param {Snap} gfx * @return {Snap} */ function getChildren(gfx) { return gfx.parentNode.childNodes[1]; } },{}],320:[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; }; },{}],321:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getApproxIntersection = getApproxIntersection; var _Geometry = require("./Geometry"); var _pathIntersection = _interopRequireDefault(require("path-intersection")); 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, _pathIntersection.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":318,"path-intersection":563}],322:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.log10 = log10; Object.defineProperty(exports, "substract", { enumerable: true, get: function () { return _PositionUtil.delta; } }); var _PositionUtil = require("./PositionUtil"); /** * Get the logarithm of x with base 10 * @param {Integer} value */ function log10(x) { return Math.log(x) / Math.log(10); } },{"./PositionUtil":325}],323:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isPrimaryButton = isPrimaryButton; exports.hasPrimaryModifier = hasPrimaryModifier; exports.hasSecondaryModifier = hasSecondaryModifier; Object.defineProperty(exports, "isMac", { enumerable: true, get: function () { return _Platform.isMac; } }); var _Event = require("./Event"); var _Platform = require("./Platform"); 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":317,"./Platform":324}],324:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isMac = isMac; function isMac() { return /mac/i.test(navigator.platform); } },{}],325:[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 }; } },{}],326:[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; } },{}],327:[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":567}],328:[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, 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":567}],329:[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":555,"tiny-svg":567}],330:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _minDash = require("min-dash"); var _moddle = require("moddle"); var _moddleXml = require("moddle-xml"); /** * 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) { _moddle.Moddle.call(this, packages, options); } BpmnModdle.prototype = Object.create(_moddle.Moddle.prototype); /** * The fromXML result. * * @typedef {Object} ParseResult * * @property {ModdleElement} rootElement * @property {Array} references * @property {Array} warnings * @property {Object} elementsById - a mapping containing each ID -> ModdleElement */ /** * The fromXML error. * * @typedef {Error} ParseError * * @property {Array} warnings */ /** * 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 * * @returns {Promise} */ BpmnModdle.prototype.fromXML = function (xmlStr, typeName, options) { if (!(0, _minDash.isString)(typeName)) { options = typeName; typeName = 'bpmn:Definitions'; } var reader = new _moddleXml.Reader((0, _minDash.assign)({ model: this, lax: true }, options)); var rootHandler = reader.handler(typeName); return reader.fromXML(xmlStr, rootHandler); }; /** * The toXML result. * * @typedef {Object} SerializationResult * * @property {String} xml */ /** * 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 * * @returns {Promise} */ BpmnModdle.prototype.toXML = function (element, options) { var writer = new _moddleXml.Writer(options); return new Promise(function (resolve, reject) { try { var result = writer.toXML(element); return resolve({ xml: result }); } catch (err) { return reject(err); } }); }; var name = "BPMN20"; var uri = "http://www.omg.org/spec/BPMN/20100524/MODEL"; var prefix = "bpmn"; var associations = []; var types = [{ name: "Interface", superClass: ["RootElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "operations", type: "Operation", isMany: true }, { name: "implementationRef", isAttr: true, type: "String" }] }, { 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", isAttr: true, type: "String" }] }, { 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", isMany: true, replaces: "FlowElementsContainer#laneSets", type: "LaneSet" }, { name: "flowElements", isMany: true, replaces: "FlowElementsContainer#flowElements", type: "FlowElement" }, { 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: "sourceRef", type: "ItemAwareElement", isMany: true, isReference: true }, { name: "targetRef", type: "ItemAwareElement", isReference: true }, { name: "transformation", type: "FormalExpression", xml: { serialize: "property" } }, { name: "assignment", type: "Assignment", isMany: true }] }, { name: "DataInput", superClass: ["ItemAwareElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "isCollection", "default": false, isAttr: true, type: "Boolean" }, { name: "inputSetRef", type: "InputSet", isMany: true, isVirtual: true, isReference: true }, { name: "inputSetWithOptional", type: "InputSet", isMany: true, isVirtual: true, isReference: true }, { name: "inputSetWithWhileExecuting", type: "InputSet", isMany: true, isVirtual: 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", isMany: true, isVirtual: true, isReference: true }, { name: "outputSetWithOptional", type: "OutputSet", isMany: true, isVirtual: true, isReference: true }, { name: "outputSetWithWhileExecuting", type: "OutputSet", isMany: true, isVirtual: 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", isBody: true, type: "String" }] }, { 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", isAttr: true, type: "String" }, { 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", isMany: true, isVirtual: 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", isMany: true, isVirtual: true, isReference: true }, { name: "outgoingConversationLinks", type: "ConversationLink", isMany: true, isVirtual: 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", isMany: true, isVirtual: 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" }] }]; var 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" }] }]; var xml = { tagAlias: "lowerCase", typePrefix: "t" }; var BpmnPackage = { name: name, uri: uri, prefix: prefix, associations: associations, types: types, enumerations: enumerations, xml: xml }; var name$1 = "BPMNDI"; var uri$1 = "http://www.omg.org/spec/BPMN/20100524/DI"; var prefix$1 = "bpmndi"; var types$1 = [{ 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"] }]; var enumerations$1 = [{ 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" }] }]; var associations$1 = []; var BpmnDiPackage = { name: name$1, uri: uri$1, prefix: prefix$1, types: types$1, enumerations: enumerations$1, associations: associations$1 }; var name$2 = "DC"; var uri$2 = "http://www.omg.org/spec/DD/20100524/DC"; var prefix$2 = "dc"; var types$2 = [{ 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 }] }]; var associations$2 = []; var DcPackage = { name: name$2, uri: uri$2, prefix: prefix$2, types: types$2, associations: associations$2 }; var name$3 = "DI"; var uri$3 = "http://www.omg.org/spec/DD/20100524/DI"; var prefix$3 = "di"; var types$3 = [{ name: "DiagramElement", isAbstract: true, properties: [{ name: "id", isAttr: true, isId: true, type: "String" }, { 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, isMany: true, isVirtual: 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", isAttr: true, isId: true, type: "String" }, { 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, isMany: true, isVirtual: 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", isMany: true, isVirtual: true }] }, { name: "LabeledShape", isAbstract: true, superClass: ["Shape"], properties: [{ name: "ownedLabel", type: "Label", isReadOnly: true, subsettedProperty: "DiagramElement-ownedElement", isMany: true, isVirtual: true }] }, { name: "Label", isAbstract: true, superClass: ["Node"], properties: [{ name: "bounds", type: "dc:Bounds" }] }, { name: "Style", isAbstract: true, properties: [{ name: "id", isAttr: true, isId: true, type: "String" }] }, { name: "Extension", properties: [{ name: "values", isMany: true, type: "Element" }] }]; var associations$3 = []; var xml$1 = { tagAlias: "lowerCase" }; var DiPackage = { name: name$3, uri: uri$3, prefix: prefix$3, types: types$3, associations: associations$3, xml: xml$1 }; var name$4 = "bpmn.io colors for BPMN"; var uri$4 = "http://bpmn.io/schema/bpmn/biocolor/1.0"; var prefix$4 = "bioc"; var types$4 = [{ 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" }] }]; var enumerations$2 = []; var associations$4 = []; var BiocPackage = { name: name$4, uri: uri$4, prefix: prefix$4, types: types$4, enumerations: enumerations$2, associations: associations$4 }; var packages = { bpmn: BpmnPackage, bpmndi: BpmnDiPackage, dc: DcPackage, di: DiPackage, bioc: BiocPackage }; function simple(additionalPackages, options) { var pks = (0, _minDash.assign)({}, packages, additionalPackages); return new BpmnModdle(pks, options); } var _default = simple; exports.default = _default; },{"min-dash":555,"moddle":559,"moddle-xml":558}],331:[function(require,module,exports){ (function (global){ /*! 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 == '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 : this, function(root) { if (root.CSS && root.CSS.escape) { return root.CSS.escape; } // https://drafts.csswg.org/cssom/#serialize-an-identifier var cssEscape = function(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 : {}) },{}],332:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("diagram-js/lib/features/interaction-events")); var _DirectEditing = _interopRequireDefault(require("./lib/DirectEditing")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_interactionEvents.default], __init__: ['directEditing'], directEditing: ['type', _DirectEditing.default] }; exports.default = _default; },{"./lib/DirectEditing":333,"diagram-js/lib/features/interaction-events":336}],333:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DirectEditing; var _minDash = require("min-dash"); var _TextBox = _interopRequireDefault(require("./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 _TextBox.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 containerBounds, previousBounds = active.context.bounds, newBounds = this.$textbox.getBoundingClientRect(), newText = this.getValue(), previousText = active.context.text; if (newText !== previousText || newBounds.height !== previousBounds.height || newBounds.width !== previousBounds.width) { containerBounds = this._textbox.container.getBoundingClientRect(); active.provider.update(active.element, newText, active.context.text, { x: newBounds.left - containerBounds.left, y: newBounds.top - containerBounds.top, width: newBounds.width, height: newBounds.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":334,"min-dash":555}],334:[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 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'); } this.insertText(text); if (options.autoResize) { var hasResized = this.autoResize(style); if (hasResized) { this.resizeHandler(hasResized); } } }; TextBox.prototype.insertText = function (text) { // insertText command not supported by Internet Explorer var success = document.execCommand('insertText', false, text); if (success) { return; } this._insertTextIE(text); }; TextBox.prototype._insertTextIE = function (text) { // 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); }); } }; /** * 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 (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 (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 (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.trim(); }; 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":555,"min-dom":556}],335:[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.click * * element.contextmenu * * element.dblclick * * element.hover * * element.mousedown * * element.mousemove * * element.mouseup * * element.out * * 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 self = this; /** * 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 = { click: 'element.click', contextmenu: 'element.contextmenu', dblclick: 'element.dblclick', mousedown: 'element.mousedown', mousemove: 'element.mousemove', mouseover: 'element.hover', mouseout: 'element.out', mouseup: 'element.mouseup' }; 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 ELEMENT_SELECTOR = 'svg, .djs-element'; // event handling /////// 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, ELEMENT_SELECTOR, 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); }); // hit box updating //////////////// eventBus.on(['shape.added', 'connection.added'], function (event) { var element = event.element, gfx = event.gfx; eventBus.fire('interactionEvents.createHit', { element: element, gfx: gfx }); }); // 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', 'connection.changed'], LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; eventBus.fire('interactionEvents.updateHit', { element: element, gfx: gfx }); }); eventBus.on('interactionEvents.createHit', LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; self.createDefaultHit(element, gfx); }); eventBus.on('interactionEvents.updateHit', function (event) { var element = event.element, gfx = event.gfx; self.updateDefaultHit(element, gfx); }); // hit styles //////////// var STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-stroke'); var CLICK_STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-click-stroke'); var ALL_HIT_STYLE = createHitStyle('djs-hit djs-hit-all'); var HIT_TYPES = { 'all': ALL_HIT_STYLE, 'click-stroke': CLICK_STROKE_HIT_STYLE, 'stroke': STROKE_HIT_STYLE }; function createHitStyle(classNames, attrs) { attrs = (0, _minDash.assign)({ stroke: 'white', strokeWidth: 15 }, attrs || {}); return styles.cls(classNames, ['no-fill', 'no-border'], attrs); } // style helpers /////////////// function applyStyle(hit, type) { var attrs = HIT_TYPES[type]; if (!attrs) { throw new Error('invalid hit type <' + type + '>'); } (0, _tinySvg.attr)(hit, attrs); return hit; } function appendHit(gfx, hit) { (0, _tinySvg.append)(gfx, hit); } // API /** * Remove hints on the given graphics. * * @param {SVGElement} gfx */ this.removeHits = function (gfx) { var hits = (0, _minDom.queryAll)('.djs-hit', gfx); (0, _minDash.forEach)(hits, _tinySvg.remove); }; /** * Create default hit for the given element. * * @param {djs.model.Base} element * @param {SVGElement} gfx * * @return {SVGElement} created hit */ this.createDefaultHit = function (element, gfx) { var waypoints = element.waypoints, isFrame = element.isFrame, boxType; if (waypoints) { return this.createWaypointsHit(gfx, waypoints); } else { boxType = isFrame ? 'stroke' : 'all'; return this.createBoxHit(gfx, boxType, { width: element.width, height: element.height }); } }; /** * Create hits for the given waypoints. * * @param {SVGElement} gfx * @param {Array} waypoints * * @return {SVGElement} */ this.createWaypointsHit = function (gfx, waypoints) { var hit = (0, _RenderUtil.createLine)(waypoints); applyStyle(hit, 'stroke'); appendHit(gfx, hit); return hit; }; /** * Create hits for a box. * * @param {SVGElement} gfx * @param {String} hitType * @param {Object} attrs * * @return {SVGElement} */ this.createBoxHit = function (gfx, type, attrs) { attrs = (0, _minDash.assign)({ x: 0, y: 0 }, attrs); var hit = (0, _tinySvg.create)('rect'); applyStyle(hit, type); (0, _tinySvg.attr)(hit, attrs); appendHit(gfx, hit); return hit; }; /** * Update default hit of the element. * * @param {djs.model.Base} element * @param {SVGElement} gfx * * @return {SVGElement} updated hit */ this.updateDefaultHit = function (element, gfx) { var hit = (0, _minDom.query)('.djs-hit', gfx); if (!hit) { return; } if (element.waypoints) { (0, _RenderUtil.updateLine)(hit, element.waypoints); } else { (0, _tinySvg.attr)(hit, { width: element.width, height: element.height }); } return hit; }; 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":341,"../../util/RenderUtil":343,"min-dash":555,"min-dom":556,"tiny-svg":567}],336:[function(require,module,exports){ arguments[4][211][0].apply(exports,arguments) },{"./InteractionEvents":335,"dup":211}],337:[function(require,module,exports){ arguments[4][296][0].apply(exports,arguments) },{"./translate":338,"dup":296}],338:[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 + '}'; }); } },{}],339:[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); } },{}],340:[function(require,module,exports){ arguments[4][317][0].apply(exports,arguments) },{"dup":317}],341:[function(require,module,exports){ arguments[4][323][0].apply(exports,arguments) },{"./Event":340,"./Platform":342,"dup":323}],342:[function(require,module,exports){ arguments[4][324][0].apply(exports,arguments) },{"dup":324}],343:[function(require,module,exports){ arguments[4][327][0].apply(exports,arguments) },{"dup":327,"tiny-svg":567}],344:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.annotate = annotate; exports.Module = Module; exports.Injector = Injector; 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" && 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; }; 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); } },{}],345:[function(require,module,exports){ /*! 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 == 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() { }, /** * bind the events */ init: function() { 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() { 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() { 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(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() { this.set(this.manager.options.touchAction); }, /** * compute the value for the touchAction property based on the recognizer's settings * @returns {String} value */ compute: function() { 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(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(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(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(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(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(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(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() { return this.requireFail.length > 0; }, /** * if the recognizer can recognize simultaneous with an other recognizer * @param {Recognizer} otherRecognizer * @returns {Boolean} */ canRecognizeWith: function(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(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(input) { if (this.canEmit()) { return this.emit(input); } // it's failing anyway this.state = STATE_FAILED; }, /** * can we emit? * @returns {boolean} */ canEmit: function() { 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(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(inputData) { }, // jshint ignore:line /** * return the preferred touch-action * @virtual * @returns {Array} */ getTouchAction: function() { }, /** * called when the gesture isn't allowed to recognize * like when another is being recognized or it is disabled * @virtual */ reset: function() { } }; /** * 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(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(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() { 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(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(input) { return AttrRecognizer.prototype.attrTest.call(this, input) && (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input))); }, emit: function(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() { return [TOUCH_ACTION_NONE]; }, attrTest: function(input) { return this._super.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN); }, emit: function(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() { return [TOUCH_ACTION_AUTO]; }, process: function(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() { clearTimeout(this._timer); }, emit: function(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() { return [TOUCH_ACTION_NONE]; }, attrTest: function(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() { return PanRecognizer.prototype.getTouchAction.call(this); }, attrTest: function(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(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() { return [TOUCH_ACTION_MANIPULATION]; }, process: function(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() { this._timer = setTimeoutContext(function() { this.state = STATE_FAILED; }, this.options.interval, this); return STATE_FAILED; }, reset: function() { clearTimeout(this._timer); }, emit: function() { 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(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(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(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(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(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(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(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(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(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() { 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'); },{}],346:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var hat_1 = createCommonjsModule(function (module) { 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 (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; }; }); /** * 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_1.rack(seed[0], seed[1], seed[2]) : seed; } /** * 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); } }; var _default = Ids; exports.default = _default; },{}],347:[function(require,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { if (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) { if (superCtor) { ctor.super_ = superCtor var TempCtor = function () {} TempCtor.prototype = superCtor.prototype ctor.prototype = new TempCtor() ctor.prototype.constructor = ctor } } } },{}],348:[function(require,module,exports){ /*! * jQuery JavaScript Library v3.5.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: 2020-05-04T22:49Z */ ( function( global, factory ) { "use strict"; if ( 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 : this, 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 getProto = Object.getPrototypeOf; var slice = arr.slice; var flat = arr.flat ? function( array ) { return arr.flat.call( array ); } : function( array ) { return arr.concat.apply( [], array ); }; 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 document = window.document; var preservedScriptAttributes = { type: true, src: true, nonce: true, noModule: true }; function DOMEval( code, node, doc ) { doc = doc || document; var i, val, script = doc.createElement( "script" ); script.text = code; if ( node ) { for ( i in preservedScriptAttributes ) { // Support: Firefox 64+, Edge 18+ // Some browsers don't support the "nonce" property on scripts. // On the other hand, just using `getAttribute` is not enough as // the `nonce` attribute is reset to an empty string whenever it // becomes browsing-context connected. // See https://github.com/whatwg/html/issues/2369 // See https://html.spec.whatwg.org/#nonce-attributes // The `node.getAttribute` check was added for the sake of // `jQuery.globalEval` so that it can fake a nonce-containing node // via an object. val = node[ i ] || node.getAttribute && node.getAttribute( i ); if ( val ) { script.setAttribute( i, val ); } } } 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 === "object" || typeof obj === "function" ? class2type[ toString.call( obj ) ] || "object" : 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.5.1", // Define a local copy of jQuery jQuery = function( 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 ); }; 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() { 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( 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( 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( callback ) { return jQuery.each( this, callback ); }, map: function( callback ) { return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); } ) ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, even: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return ( i + 1 ) % 2; } ) ); }, odd: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return i % 2; } ) ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { 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 !== "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 ) { copy = options[ name ]; // Prevent Object.prototype pollution // Prevent never-ending loop if ( name === "__proto__" || target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = Array.isArray( copy ) ) ) ) { src = target[ name ]; // Ensure proper type for the source value if ( copyIsArray && !Array.isArray( src ) ) { clone = []; } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { clone = {}; } else { clone = src; } copyIsArray = false; // 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( msg ) { throw new Error( msg ); }, noop: function() {}, isPlainObject: function( 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( obj ) { var name; for ( name in obj ) { return false; } return true; }, // Evaluates a script in a provided context; falls back to the global one // if not specified. globalEval: function( code, options, doc ) { DOMEval( code, { nonce: options && options.nonce }, doc ); }, each: function( 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; }, // results is for internal usage only makeArray: function( 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( 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( 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( 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( 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 flat( 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.5 * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://js.foundation/ * * Date: 2020-03-14 */ ( 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(), nonnativeSelectorCache = createCache(), sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; } return 0; }, // Instance methods hasOwn = ( {} ).hasOwnProperty, arr = [], pop = arr.pop, pushNative = 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( 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]", // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", // 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 + "*" ), rdescend = new RegExp( whitespace + "|>" ), 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" ) }, rhtml = /HTML$/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-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), funescape = function( escape, nonHex ) { var high = "0x" + escape.slice( 1 ) - 0x10000; return nonHex ? // Strip the backslash prefix from a non-hex escape sequence nonHex : // Replace a hexadecimal escape sequence with the encoded Unicode code point // Support: IE <=11+ // For values outside the Basic Multilingual Plane (BMP), manually construct a // surrogate pair high < 0 ? String.fromCharCode( high + 0x10000 ) : 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( 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() { setDocument(); }, inDisabledFieldset = addCombinator( function( elem ) { return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; }, { 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 // eslint-disable-next-line no-unused-expressions arr[ preferredDoc.childNodes.length ].nodeType; } catch ( e ) { push = { apply: arr.length ? // Leverage slice if possible function( target, els ) { pushNative.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 ) { 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 && !nonnativeSelectorCache[ selector + " " ] && ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && // Support: IE 8 only // Exclude object elements ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { newSelector = selector; newContext = context; // qSA considers elements outside a scoping root when evaluating child or // descendant combinators, which is not what we want. // In such cases, we work around the behavior by prefixing every selector in the // list with an ID selector referencing the scope context. // The technique has to be used as well when a leading combinator is used // as such selectors are not recognized by querySelectorAll. // Thanks to Andrew Dupont for this technique. if ( nodeType === 1 && ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { // Expand context for sibling selectors newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; // We can use :scope instead of the ID hack if the browser // supports it & if we're not changing the context. if ( newContext !== context || !support.scope ) { // 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 ? "#" + nid : ":scope" ) + " " + toSelector( groups[ i ] ); } newSelector = groups.join( "," ); } try { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch ( qsaError ) { nonnativeSelectorCache( selector, true ); } 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 && inDisabledFieldset( 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 ) { var namespace = elem.namespaceURI, docElem = ( elem.ownerDocument || elem ).documentElement; // Support: IE <=8 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes // https://bugs.jquery.com/ticket/4833 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); }; /** * 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 // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq 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 12 - 18+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq 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 ); } } // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, // Safari 4 - 5 only, Opera <=11.6 - 12.x only // IE/Edge & older browsers don't support the :scope pseudo-class. // Support: Safari 6.0 only // Safari 6.0 supports :scope but it's an alias of :root there. support.scope = assert( function( el ) { docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); return typeof el.querySelectorAll !== "undefined" && !el.querySelectorAll( ":scope fieldset div" ).length; } ); /* 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 ) { var input; // 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( "~=" ); } // Support: IE 11+, Edge 15 - 18+ // IE 11/Edge don't find elements on a `[name='']` query in some cases. // Adding a temporary attribute to the document before the selection works // around the issue. // Interestingly, IE 10 & older don't seem to have the issue. input = document.createElement( "input" ); input.setAttribute( "name", "" ); el.appendChild( input ); if ( !el.querySelectorAll( "[name='']" ).length ) { rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + whitespace + "*(?:''|\"\")" ); } // 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( ".#.+[+~]" ); } // Support: Firefox <=3.6 - 5 only // Old Firefox doesn't throw on a badly-escaped identifier. el.querySelectorAll( "\\\f" ); rbuggyQSA.push( "[\\r\\n\\f]" ); } ); 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" ); } // Support: Opera 10 - 11 only // 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 // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq 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 // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( a == document || a.ownerDocument == preferredDoc && contains( preferredDoc, a ) ) { return -1; } // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq 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 ) { // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. /* eslint-disable eqeqeq */ return a == document ? -1 : b == document ? 1 : /* eslint-enable eqeqeq */ 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 // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. /* eslint-disable eqeqeq */ ap[ i ] == preferredDoc ? -1 : bp[ i ] == preferredDoc ? 1 : /* eslint-enable eqeqeq */ 0; }; return document; }; Sizzle.matches = function( expr, elements ) { return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { setDocument( elem ); if ( support.matchesSelector && documentIsHTML && !nonnativeSelectorCache[ 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 ) { nonnativeSelectorCache( expr, true ); } } return Sizzle( expr, document, null, [ elem ] ).length > 0; }; Sizzle.contains = function( context, elem ) { // Set document vars if needed // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( ( context.ownerDocument || context ) != document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { // Set document vars if needed // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq 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( 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( 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( 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( nodeNameSelector ) { var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); return nodeNameSelector === "*" ? function() { return true; } : function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( 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( name, operator, check ) { return function( elem ) { var result = Sizzle.attr( elem, name ); if ( result == null ) { return operator === "!="; } if ( !operator ) { return true; } result += ""; /* eslint-disable max-len */ 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; /* eslint-enable max-len */ }; }, "CHILD": function( 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, 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 || 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( elem ) { var hash = window.location && window.location.hash; return hash && hash.slice( 1 ) === elem.id; }, "root": function( elem ) { return elem === docElem; }, "focus": function( 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( 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( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { // eslint-disable-next-line no-unused-expressions elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function( 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( elem ) { return !Expr.pseudos[ "empty" ]( elem ); }, // Element/input types "header": function( elem ) { return rheader.test( elem.nodeName ); }, "input": function( elem ) { return rinputs.test( elem.nodeName ); }, "button": function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function( 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 > length ? 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( 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 ) { // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq 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; // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq 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( 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( 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( 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( selector ) { return this.pushStack( winnow( this, selector || [], false ) ); }, not: function( selector ) { return this.pushStack( winnow( this, selector || [], true ) ); }, is: function( 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( 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( 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( 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( selector, context ) { return this.pushStack( jQuery.uniqueSort( jQuery.merge( this.get(), jQuery( selector, context ) ) ) ); }, addBack: function( 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( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return dir( elem, "parentNode" ); }, parentsUntil: function( elem, _i, until ) { return dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return dir( elem, "previousSibling" ); }, nextUntil: function( elem, _i, until ) { return dir( elem, "nextSibling", until ); }, prevUntil: function( elem, _i, until ) { return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return siblings( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return siblings( elem.firstChild ); }, contents: function( elem ) { if ( elem.contentDocument != null && // Support: IE 11+ // elements with no `data` attribute has an object // `contentDocument` with a `null` prototype. getProto( elem.contentDocument ) ) { 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() { // 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() { 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() { 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( fn ) { return fn ? jQuery.inArray( fn, list ) > -1 : list.length > 0; }, // Remove all callbacks from the list empty: function() { if ( list ) { list = []; } return this; }, // Disable .fire and .add // Abort any current/pending executions // Clear all callbacks and values disable: function() { locked = queue = []; list = memory = ""; return this; }, disabled: function() { return !list; }, // Disable .fire // Also disable .add unless we have memory (since it would have no effect) // Abort any pending executions lock: function() { locked = queue = []; if ( !memory && !firing ) { list = memory = ""; } return this; }, locked: function() { return !!locked; }, // Call all callbacks with the given context and arguments fireWith: function( 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() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once fired: function() { 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( 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() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, "catch": function( fn ) { return promise.then( null, fn ); }, // Keep pipe for back-compat pipe: function( /* 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( onFulfilled, onRejected, onProgress ) { var maxDepth = 0; function resolve( depth, deferred, handler, special ) { return function() { var that = this, args = arguments, mightThrow = function() { 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 === "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( 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( 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( 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( 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( 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( 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( 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( 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( 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( owner, key ) { return key === undefined ? this.cache( owner ) : // Always use camelCase key (gh-2257) owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; }, access: function( 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( 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( 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( elem ) { return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { return dataUser.access( elem, name, data ); }, removeData: function( 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( elem, name, data ) { return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { dataPriv.remove( elem, name ); } } ); jQuery.fn.extend( { data: function( 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 === "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( key ) { return this.each( function() { dataUser.remove( this, key ); } ); } } ); jQuery.extend( { queue: function( 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( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { 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( 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( 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( type ) { return this.each( function() { jQuery.dequeue( this, type ); } ); }, clearQueue: function( 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( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { 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 documentElement = document.documentElement; var isAttached = function( elem ) { return jQuery.contains( elem.ownerDocument, elem ); }, composed = { composed: true }; // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only // Check attachment across shadow DOM boundaries when possible (gh-3504) // Support: iOS 10.0-10.2 only // Early iOS 10 versions support `attachShadow` but not `getRootNode`, // leading to errors. We need to check for `getRootNode`. if ( documentElement.getRootNode ) { isAttached = function( elem ) { return jQuery.contains( elem.ownerDocument, elem ) || elem.getRootNode( composed ) === elem.ownerDocument; }; } var isHiddenWithinTree = function( 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. isAttached( elem ) && jQuery.css( elem, "display" ) === "none"; }; 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 = elem.nodeType && ( 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() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( 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 ); ( 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; // Support: IE <=9 only // IE <=9 replaces "; support.option = !!div.lastChild; } )(); // We have to close these tags to support XHTML (#13200) var wrapMap = { // 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, "", "" ] }; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; // Support: IE <=9 only if ( !support.option ) { wrapMap.optgroup = wrapMap.option = [ 1, "" ]; } 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, attached, 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; } attached = isAttached( elem ); // Append to fragment tmp = getAll( fragment.appendChild( elem ), "script" ); // Preserve script evaluation history if ( attached ) { setGlobalEval( tmp ); } // Capture executables if ( scripts ) { j = 0; while ( ( elem = tmp[ j++ ] ) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } } } } return fragment; } var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; } function returnFalse() { return false; } // Support: IE <=9 - 11+ // focus() and blur() are asynchronous, except when they are no-op. // So expect focus to be synchronous when the element is already active, // and blur to be synchronous when the element is not already active. // (focus and blur are always synchronous in other supported browsers, // this just defines when we can count on it). function expectSync( elem, type ) { return ( elem === safeActiveElement() ) === ( type === "focus" ); } // Support: IE <=9 only // Accessing document.activeElement can throw unexpectedly // https://bugs.jquery.com/ticket/13393 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 === "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( 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( elem, types, handler, data, selector ) { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get( elem ); // Only attach events to objects that accept data if ( !acceptData( elem ) ) { 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 = Object.create( null ); } 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( 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( nativeEvent ) { var i, j, ret, matched, handleObj, handlerQueue, args = new Array( arguments.length ), // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( nativeEvent ), handlers = ( dataPriv.get( this, "events" ) || Object.create( null ) )[ 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() ) { // If the event is namespaced, then each handler is only invoked if it is // specially universal or its namespaces are a superset of the event's. if ( !event.rnamespace || handleObj.namespace === false || 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( 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( 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( value ) { Object.defineProperty( this, name, { enumerable: true, configurable: true, writable: true, value: value } ); } } ); }, fix: function( originalEvent ) { return originalEvent[ jQuery.expando ] ? originalEvent : new jQuery.Event( originalEvent ); }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, click: { // Utilize native event to ensure correct state for checkable inputs setup: function( data ) { // For mutual compressibility with _default, replace `this` access with a local var. // `|| data` is dead code meant only to preserve the variable through minification. var el = this || data; // Claim the first handler if ( rcheckableType.test( el.type ) && el.click && nodeName( el, "input" ) ) { // dataPriv.set( el, "click", ... ) leverageNative( el, "click", returnTrue ); } // Return false to allow normal processing in the caller return false; }, trigger: function( data ) { // For mutual compressibility with _default, replace `this` access with a local var. // `|| data` is dead code meant only to preserve the variable through minification. var el = this || data; // Force setup before triggering a click if ( rcheckableType.test( el.type ) && el.click && nodeName( el, "input" ) ) { leverageNative( el, "click" ); } // Return non-false to allow normal event-path propagation return true; }, // For cross-browser consistency, suppress native .click() on links // Also prevent it if we're currently inside a leveraged native-event stack _default: function( event ) { var target = event.target; return rcheckableType.test( target.type ) && target.click && nodeName( target, "input" ) && dataPriv.get( target, "click" ) || nodeName( target, "a" ); } }, beforeunload: { postDispatch: function( 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; } } } } }; // Ensure the presence of an event listener that handles manually-triggered // synthetic events by interrupting progress until reinvoked in response to // *native* events that it fires directly, ensuring that state changes have // already occurred before other listeners are invoked. function leverageNative( el, type, expectSync ) { // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add if ( !expectSync ) { if ( dataPriv.get( el, type ) === undefined ) { jQuery.event.add( el, type, returnTrue ); } return; } // Register the controller as a special universal handler for all event namespaces dataPriv.set( el, type, false ); jQuery.event.add( el, type, { namespace: false, handler: function( event ) { var notAsync, result, saved = dataPriv.get( this, type ); if ( ( event.isTrigger & 1 ) && this[ type ] ) { // Interrupt processing of the outer synthetic .trigger()ed event // Saved data should be false in such cases, but might be a leftover capture object // from an async native handler (gh-4350) if ( !saved.length ) { // Store arguments for use when handling the inner native event // There will always be at least one argument (an event object), so this array // will not be confused with a leftover capture object. saved = slice.call( arguments ); dataPriv.set( this, type, saved ); // Trigger the native event and capture its result // Support: IE <=9 - 11+ // focus() and blur() are asynchronous notAsync = expectSync( this, type ); this[ type ](); result = dataPriv.get( this, type ); if ( saved !== result || notAsync ) { dataPriv.set( this, type, false ); } else { result = {}; } if ( saved !== result ) { // Cancel the outer synthetic event event.stopImmediatePropagation(); event.preventDefault(); return result.value; } // If this is an inner synthetic event for an event with a bubbling surrogate // (focus or blur), assume that the surrogate already propagated from triggering the // native event and prevent that from happening again here. // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the // bubbling surrogate propagates *after* the non-bubbling base), but that seems // less bad than duplication. } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { event.stopPropagation(); } // If this is a native event triggered above, everything is now in order // Fire an inner synthetic event with the original arguments } else if ( saved.length ) { // ...and capture the result dataPriv.set( this, type, { value: jQuery.event.trigger( // Support: IE <=9 - 11+ // Extend with the prototype to reset the above stopImmediatePropagation() jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), saved.slice( 1 ), this ) } ); // Abort handling of the native event event.stopImmediatePropagation(); } } } ); } 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() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if ( e && !this.isSimulated ) { e.preventDefault(); } }, stopPropagation: function() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopPropagation(); } }, stopImmediatePropagation: function() { 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, code: 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( 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 ); jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { jQuery.event.special[ type ] = { // Utilize native event if possible so blur/focus sequence is correct setup: function() { // Claim the first handler // dataPriv.set( this, "focus", ... ) // dataPriv.set( this, "blur", ... ) leverageNative( this, type, expectSync ); // Return false to allow normal processing in the caller return false; }, trigger: function() { // Force setup before trigger leverageNative( this, type ); // Return non-false to allow normal event-path propagation return true; }, delegateType: delegateType }; } ); // 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( 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( types, selector, data, fn ) { return on( this, types, selector, data, fn ); }, one: function( types, selector, data, fn ) { return on( this, types, selector, data, fn, 1 ); }, off: function( 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 === "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 // 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, udataOld, udataCur, events; if ( dest.nodeType !== 1 ) { return; } // 1. Copy private data: events, handlers, etc. if ( dataPriv.hasData( src ) ) { pdataOld = dataPriv.get( src ); events = pdataOld.events; if ( events ) { dataPriv.remove( dest, "handle 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 = flat( 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 && !node.noModule ) { jQuery._evalUrl( node.src, { nonce: node.nonce || node.getAttribute( "nonce" ) }, doc ); } } else { DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); } } } } } } 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 && isAttached( node ) ) { setGlobalEval( getAll( node, "script" ) ); } node.parentNode.removeChild( node ); } } return elem; } jQuery.extend( { htmlPrefilter: function( html ) { return html; }, clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, clone = elem.cloneNode( true ), inPage = isAttached( 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( 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( selector ) { return remove( this, selector, true ); }, remove: function( selector ) { return remove( this, selector ); }, text: function( 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() { 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() { 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() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } } ); }, after: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } } ); }, empty: function() { 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( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); } ); }, html: function( 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() { 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( 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 swap = function( elem, options, callback ) { 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.call( elem ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; }; 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) // Support: Chrome <=64 // Don't get tricked when zoom affects offsetWidth (gh-4029) div.style.position = "absolute"; scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 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, reliableTrDimensionsVal, 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() { computeStyleTests(); return boxSizingReliableVal; }, pixelBoxStyles: function() { computeStyleTests(); return pixelBoxStylesVal; }, pixelPosition: function() { computeStyleTests(); return pixelPositionVal; }, reliableMarginLeft: function() { computeStyleTests(); return reliableMarginLeftVal; }, scrollboxSize: function() { computeStyleTests(); return scrollboxSizeVal; }, // Support: IE 9 - 11+, Edge 15 - 18+ // IE/Edge misreport `getComputedStyle` of table rows with width/height // set in CSS while `offset*` properties report correct values. // Behavior in IE 9 is more subtle than in newer versions & it passes // some versions of this test; make sure not to make it pass there! reliableTrDimensions: function() { var table, tr, trChild, trStyle; if ( reliableTrDimensionsVal == null ) { table = document.createElement( "table" ); tr = document.createElement( "tr" ); trChild = document.createElement( "div" ); table.style.cssText = "position:absolute;left:-11111px"; tr.style.height = "1px"; trChild.style.height = "9px"; documentElement .appendChild( table ) .appendChild( tr ) .appendChild( trChild ); trStyle = window.getComputedStyle( tr ); reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; documentElement.removeChild( table ); } return reliableTrDimensionsVal; } } ); } )(); 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 === "" && !isAttached( 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() { 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 cssPrefixes = [ "Webkit", "Moz", "ms" ], emptyStyle = document.createElement( "div" ).style, vendorProps = {}; // Return a vendor-prefixed property or undefined function vendorPropName( 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 potentially-mapped jQuery.cssProps or vendor prefixed property function finalPropName( name ) { var final = jQuery.cssProps[ name ] || vendorProps[ name ]; if ( final ) { return final; } if ( name in emptyStyle ) { return name; } return vendorProps[ name ] = vendorPropName( name ) || name; } 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" }; 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 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter // Use an explicit zero to avoid NaN (gh-3964) ) ) || 0; } return delta; } function getWidthOrHeight( elem, dimension, extra ) { // Start with computed style var styles = getStyles( elem ), // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). // Fake content-box until we know it's needed to know the true value. boxSizingNeeded = !support.boxSizingReliable() || extra, isBorderBox = boxSizingNeeded && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", valueIsBorderBox = isBorderBox, val = curCSS( elem, dimension, styles ), offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); // Support: Firefox <=54 // Return a confounding non-pixel value or feign ignorance, as appropriate. if ( rnumnonpx.test( val ) ) { if ( !extra ) { return val; } val = "auto"; } // Support: IE 9 - 11 only // Use offsetWidth/offsetHeight for when box sizing is unreliable. // In those cases, the computed value can be trusted to be border-box. if ( ( !support.boxSizingReliable() && isBorderBox || // Support: IE 10 - 11+, Edge 15 - 18+ // IE/Edge misreport `getComputedStyle` of table rows with width/height // set in CSS while `offset*` properties report correct values. // Interestingly, in some cases IE 9 doesn't suffer from this issue. !support.reliableTrDimensions() && nodeName( elem, "tr" ) || // Fall back to offsetWidth/offsetHeight when value is "auto" // This happens for inline elements with no explicit setting (gh-3571) val === "auto" || // Support: Android <=4.1 - 4.3 only // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && // Make sure the element is visible & connected elem.getClientRects().length ) { isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; // Where available, offsetWidth/offsetHeight approximate border box dimensions. // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the // retrieved value as a content box dimension. valueIsBorderBox = offsetProp in elem; if ( valueIsBorderBox ) { val = elem[ offsetProp ]; } } // 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( 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, "gridArea": true, "gridColumn": true, "gridColumnEnd": true, "gridColumnStart": true, "gridRow": true, "gridRowEnd": true, "gridRowStart": 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( 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; // 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) // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append // "px" to a few hardcoded values. if ( type === "number" && !isCustomProp ) { 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( 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( 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( elem, value, extra ) { var matches, styles = getStyles( elem ), // Only read styles.position if the test has a chance to fail // to avoid forcing a reflow. scrollboxSizeBuggy = !support.scrollboxSize() && styles.position === "absolute", // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) boxSizingNeeded = scrollboxSizeBuggy || extra, isBorderBox = boxSizingNeeded && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", subtract = extra ? boxModelAdjustment( elem, dimension, extra, isBorderBox, styles ) : 0; // 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 && scrollboxSizeBuggy ) { 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( 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( 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( 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() { var hooks = Tween.propHooks[ this.prop ]; return hooks && hooks.get ? hooks.get( this ) : Tween.propHooks._default.get( this ); }, run: function( 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( 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( 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 && ( jQuery.cssHooks[ tween.prop ] || tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { 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( tween ) { if ( tween.elem.nodeType && tween.elem.parentNode ) { tween.elem[ tween.prop ] = tween.now; } } }; jQuery.easing = { linear: function( p ) { return p; }, swing: function( 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() { 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( 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( 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( 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( callback, prepend ) { if ( prepend ) { Animation.prefilters.unshift( callback ); } else { Animation.prefilters.push( callback ); } } } ); jQuery.speed = function( speed, easing, fn ) { var opt = speed && 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( 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( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { // 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( type, clearQueue, gotoEnd ) { var stopQueue = function( hooks ) { var stop = hooks.stop; delete hooks.stop; stop( gotoEnd ); }; if ( typeof type !== "string" ) { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if ( clearQueue ) { 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( 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( name, value ) { return access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each( function() { jQuery.removeAttr( this, name ); } ); } } ); jQuery.extend( { attr: function( 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( 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( 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( 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( name, value ) { return access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { return this.each( function() { delete this[ jQuery.propFix[ name ] || name ]; } ); } } ); jQuery.extend( { prop: function( 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( 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( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent && parent.parentNode ) { parent.parentNode.selectedIndex; } return null; }, set: function( 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( 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( 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( value, stateVal ) { var type = 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( 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( 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( 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( 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( 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( 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( e ) { e.stopPropagation(); }; jQuery.extend( jQuery.event, { trigger: function( 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 === "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" ) || Object.create( null ) )[ 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( 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( type, data ) { return this.each( function() { jQuery.event.trigger( type, data, this ); } ); }, triggerHandler: function( 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( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); }; jQuery.event.special[ fix ] = { setup: function() { // Handle: regular nodes (via `this.ownerDocument`), window // (via `this.document`) & document (via `this`). var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access( doc, fix ); if ( !attaches ) { doc.addEventListener( orig, handler, true ); } dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); }, teardown: function() { var doc = this.ownerDocument || this.document || 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 = { guid: 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 === "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( 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 ( a == null ) { return ""; } // 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() { return jQuery.param( this.serializeArray() ); }, serializeArray: function() { 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( 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( url, options ) { // If url is an object, simulate pre-1.5 signature if ( 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( key ) { var match; if ( completed ) { if ( !responseHeaders ) { responseHeaders = {}; while ( ( match = rheaders.exec( responseHeadersString ) ) ) { responseHeaders[ match[ 1 ].toLowerCase() + " " ] = ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) .concat( match[ 2 ] ); } } match = responseHeaders[ key.toLowerCase() + " " ]; } return match == null ? null : match.join( ", " ); }, // Raw string getAllResponseHeaders: function() { return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function( 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( type ) { if ( completed == null ) { s.mimeType = type; } return this; }, // Status-dependent callbacks statusCode: function( 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( 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.guid++ ) + 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 ); } // Use a noop converter for missing script if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { s.converters[ "text script" ] = function() {}; } // 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( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }, getScript: function( 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.ajaxPrefilter( function( s ) { var i; for ( i in s.headers ) { if ( i.toLowerCase() === "content-type" ) { s.contentType = s.headers[ i ] || ""; } } } ); jQuery._evalUrl = function( url, options, doc ) { 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, // Only evaluate the response if it is successful (gh-4126) // dataFilter is not invoked for failure responses, so using it instead // of the default converter is kludgy but it works. converters: { "text script": function() {} }, dataFilter: function( response ) { jQuery.globalEval( response, options, doc ); } } ); }; jQuery.fn.extend( { wrapAll: function( 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( 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( html ) { var htmlIsFunction = isFunction( html ); return this.each( function( i ) { jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); } ); }, unwrap: function( 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( 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( 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() { 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( 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 or forced-by-attrs requests if ( s.crossDomain || s.scriptAttrs ) { var script, callback; return { send: function( _, complete ) { script = jQuery( "