bpmn-visualization
Version:
A TypeScript library for visualizing process execution data on BPMN diagrams
52,378 lines • 1.71 MB
JavaScript
/*
Copyright 2020-2025 Bonitasoft S.A.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var bpmnvisu = (function (exports) {
'use strict';
exports.FitType = void 0;
(function (FitType) {
FitType["None"] = "None";
FitType["HorizontalVertical"] = "HorizontalVertical";
FitType["Horizontal"] = "Horizontal";
FitType["Vertical"] = "Vertical";
FitType["Center"] = "Center";
})(exports.FitType || (exports.FitType = {}));
exports.ZoomType = void 0;
(function (ZoomType) {
ZoomType["In"] = "in";
ZoomType["Out"] = "out";
})(exports.ZoomType || (exports.ZoomType = {}));
function htmlElement(element) {
if (element instanceof HTMLElement) {
return element;
}
return document.querySelector(`#${element}`);
}
exports.ShapeBpmnElementKind = void 0;
(function (ShapeBpmnElementKind) {
ShapeBpmnElementKind["LANE"] = "lane";
ShapeBpmnElementKind["POOL"] = "pool";
ShapeBpmnElementKind["CALL_ACTIVITY"] = "callActivity";
ShapeBpmnElementKind["SUB_PROCESS"] = "subProcess";
ShapeBpmnElementKind["TASK"] = "task";
ShapeBpmnElementKind["TASK_USER"] = "userTask";
ShapeBpmnElementKind["TASK_SERVICE"] = "serviceTask";
ShapeBpmnElementKind["TASK_RECEIVE"] = "receiveTask";
ShapeBpmnElementKind["TASK_SEND"] = "sendTask";
ShapeBpmnElementKind["TASK_MANUAL"] = "manualTask";
ShapeBpmnElementKind["TASK_SCRIPT"] = "scriptTask";
ShapeBpmnElementKind["TASK_BUSINESS_RULE"] = "businessRuleTask";
ShapeBpmnElementKind["GLOBAL_TASK"] = "globalTask";
ShapeBpmnElementKind["GLOBAL_TASK_USER"] = "globalUserTask";
ShapeBpmnElementKind["GLOBAL_TASK_MANUAL"] = "globalManualTask";
ShapeBpmnElementKind["GLOBAL_TASK_SCRIPT"] = "globalScriptTask";
ShapeBpmnElementKind["GLOBAL_TASK_BUSINESS_RULE"] = "globalBusinessRuleTask";
ShapeBpmnElementKind["GROUP"] = "group";
ShapeBpmnElementKind["TEXT_ANNOTATION"] = "textAnnotation";
ShapeBpmnElementKind["GATEWAY_PARALLEL"] = "parallelGateway";
ShapeBpmnElementKind["GATEWAY_EXCLUSIVE"] = "exclusiveGateway";
ShapeBpmnElementKind["GATEWAY_INCLUSIVE"] = "inclusiveGateway";
ShapeBpmnElementKind["GATEWAY_EVENT_BASED"] = "eventBasedGateway";
ShapeBpmnElementKind["GATEWAY_COMPLEX"] = "complexGateway";
ShapeBpmnElementKind["EVENT_START"] = "startEvent";
ShapeBpmnElementKind["EVENT_END"] = "endEvent";
ShapeBpmnElementKind["EVENT_INTERMEDIATE_CATCH"] = "intermediateCatchEvent";
ShapeBpmnElementKind["EVENT_INTERMEDIATE_THROW"] = "intermediateThrowEvent";
ShapeBpmnElementKind["EVENT_BOUNDARY"] = "boundaryEvent";
})(exports.ShapeBpmnElementKind || (exports.ShapeBpmnElementKind = {}));
exports.ShapeBpmnCallActivityKind = void 0;
(function (ShapeBpmnCallActivityKind) {
ShapeBpmnCallActivityKind["CALLING_PROCESS"] = "process";
ShapeBpmnCallActivityKind["CALLING_GLOBAL_TASK"] = "global task";
})(exports.ShapeBpmnCallActivityKind || (exports.ShapeBpmnCallActivityKind = {}));
exports.ShapeBpmnEventBasedGatewayKind = void 0;
(function (ShapeBpmnEventBasedGatewayKind) {
ShapeBpmnEventBasedGatewayKind["Exclusive"] = "Exclusive";
ShapeBpmnEventBasedGatewayKind["None"] = "None";
ShapeBpmnEventBasedGatewayKind["Parallel"] = "Parallel";
})(exports.ShapeBpmnEventBasedGatewayKind || (exports.ShapeBpmnEventBasedGatewayKind = {}));
exports.ShapeBpmnEventDefinitionKind = void 0;
(function (ShapeBpmnEventDefinitionKind) {
ShapeBpmnEventDefinitionKind["NONE"] = "none";
ShapeBpmnEventDefinitionKind["TERMINATE"] = "terminate";
ShapeBpmnEventDefinitionKind["CANCEL"] = "cancel";
ShapeBpmnEventDefinitionKind["COMPENSATION"] = "compensate";
ShapeBpmnEventDefinitionKind["CONDITIONAL"] = "conditional";
ShapeBpmnEventDefinitionKind["ERROR"] = "error";
ShapeBpmnEventDefinitionKind["ESCALATION"] = "escalation";
ShapeBpmnEventDefinitionKind["LINK"] = "link";
ShapeBpmnEventDefinitionKind["MESSAGE"] = "message";
ShapeBpmnEventDefinitionKind["SIGNAL"] = "signal";
ShapeBpmnEventDefinitionKind["TIMER"] = "timer";
})(exports.ShapeBpmnEventDefinitionKind || (exports.ShapeBpmnEventDefinitionKind = {}));
exports.ShapeBpmnMarkerKind = void 0;
(function (ShapeBpmnMarkerKind) {
ShapeBpmnMarkerKind["ADHOC"] = "adhoc";
ShapeBpmnMarkerKind["COMPENSATION"] = "compensation";
ShapeBpmnMarkerKind["EXPAND"] = "expand";
ShapeBpmnMarkerKind["LOOP"] = "loop";
ShapeBpmnMarkerKind["MULTI_INSTANCE_PARALLEL"] = "multi-parallel";
ShapeBpmnMarkerKind["MULTI_INSTANCE_SEQUENTIAL"] = "multi-sequential";
})(exports.ShapeBpmnMarkerKind || (exports.ShapeBpmnMarkerKind = {}));
exports.ShapeBpmnSubProcessKind = void 0;
(function (ShapeBpmnSubProcessKind) {
ShapeBpmnSubProcessKind["AD_HOC"] = "adhoc";
ShapeBpmnSubProcessKind["EMBEDDED"] = "embedded";
ShapeBpmnSubProcessKind["EVENT"] = "event";
ShapeBpmnSubProcessKind["TRANSACTION"] = "transaction";
})(exports.ShapeBpmnSubProcessKind || (exports.ShapeBpmnSubProcessKind = {}));
function convertEmptyStringAndObject(element, acceptEmptyString) {
if (element === '') {
return acceptEmptyString ? {} : undefined;
}
return element;
}
function ensureIsArray(elements, acceptEmptyString = false) {
if (elements === undefined || elements === null) {
return [];
}
return ((Array.isArray(elements) ? elements : [elements])
.map(element => convertEmptyStringAndObject(element, acceptEmptyString))
.filter(Boolean));
}
function filter(arrayToFilter, suffix, options) {
const patterns = [];
if (options === null || options === void 0 ? void 0 : options.startingWith) {
patterns.push(`^(${options.startingWith}).*`);
}
else if (options === null || options === void 0 ? void 0 : options.notStartingWith) {
patterns.push(`^(?!(${options.notStartingWith})).*`);
}
patterns.push(`${suffix}$`);
const pattern = patterns.join('');
return arrayToFilter.filter(element => ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? new RegExp(pattern, 'i').test(element) : new RegExp(pattern).test(element)));
}
class ShapeUtil {
static isEvent(kind) {
return isKindOf(EVENT_KINDS, kind);
}
static eventKinds() {
return [...EVENT_KINDS];
}
static isBoundaryEvent(kind) {
return exports.ShapeBpmnElementKind.EVENT_BOUNDARY === kind;
}
static isStartEvent(kind) {
return exports.ShapeBpmnElementKind.EVENT_START === kind;
}
static isCatchEvent(kind) {
return exports.ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH === kind || exports.ShapeBpmnElementKind.EVENT_BOUNDARY === kind || exports.ShapeBpmnElementKind.EVENT_START === kind;
}
static isIntermediateCatchEvent(kind) {
return exports.ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH === kind;
}
static isIntermediateThrowEvent(kind) {
return exports.ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW === kind;
}
static isCallActivity(kind) {
return exports.ShapeBpmnElementKind.CALL_ACTIVITY === kind;
}
static isSubProcess(kind) {
return exports.ShapeBpmnElementKind.SUB_PROCESS === kind;
}
static canHaveNoneEvent(kind) {
return exports.ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW === kind || exports.ShapeBpmnElementKind.EVENT_END === kind || exports.ShapeBpmnElementKind.EVENT_START === kind;
}
static isActivity(kind) {
return isKindOf(ACTIVITY_KINDS, kind);
}
static activityKinds() {
return [...ACTIVITY_KINDS];
}
static isWithDefaultSequenceFlow(kind) {
return FLOW_NODE_WITH_DEFAULT_SEQUENCE_FLOW_KINDS.has(kind);
}
static isTask(kind) {
return isKindOf(TASK_KINDS, kind);
}
static taskKinds() {
return [...TASK_KINDS];
}
static gatewayKinds() {
return [...GATEWAY_KINDS];
}
static isGateway(kind) {
return isKindOf(GATEWAY_KINDS, kind);
}
static flowNodeKinds() {
return Object.values(exports.ShapeBpmnElementKind).filter(kind => !ShapeUtil.isPoolOrLane(kind));
}
static isPoolOrLane(kind) {
return kind == exports.ShapeBpmnElementKind.POOL || kind == exports.ShapeBpmnElementKind.LANE;
}
}
function filterKind(suffix, options) {
return filter(Object.values(exports.ShapeBpmnElementKind), suffix, options);
}
function isKindOf(referenceKinds, kind) {
return Object.values(referenceKinds)
.map(value => value)
.includes(kind);
}
const EVENT_KINDS = filterKind('Event');
const GATEWAY_KINDS = filterKind('Gateway');
const TASK_KINDS = filterKind('Task', { ignoreCase: true, notStartingWith: 'global' });
const ACTIVITY_KINDS = [...TASK_KINDS, exports.ShapeBpmnElementKind.CALL_ACTIVITY, exports.ShapeBpmnElementKind.SUB_PROCESS];
const FLOW_NODE_WITH_DEFAULT_SEQUENCE_FLOW_KINDS = new Set([
...ACTIVITY_KINDS,
exports.ShapeBpmnElementKind.GATEWAY_EXCLUSIVE,
exports.ShapeBpmnElementKind.GATEWAY_INCLUSIVE,
exports.ShapeBpmnElementKind.GATEWAY_COMPLEX,
]);
const eventDefinitionKinds = Object.values(exports.ShapeBpmnEventDefinitionKind).filter(kind => kind != exports.ShapeBpmnEventDefinitionKind.NONE);
exports.AssociationDirectionKind = void 0;
(function (AssociationDirectionKind) {
AssociationDirectionKind["NONE"] = "None";
AssociationDirectionKind["ONE"] = "One";
AssociationDirectionKind["BOTH"] = "Both";
})(exports.AssociationDirectionKind || (exports.AssociationDirectionKind = {}));
exports.FlowKind = void 0;
(function (FlowKind) {
FlowKind["SEQUENCE_FLOW"] = "sequenceFlow";
FlowKind["MESSAGE_FLOW"] = "messageFlow";
FlowKind["ASSOCIATION_FLOW"] = "association";
})(exports.FlowKind || (exports.FlowKind = {}));
exports.MessageVisibleKind = void 0;
(function (MessageVisibleKind) {
MessageVisibleKind["NONE"] = "none";
MessageVisibleKind["INITIATING"] = "initiating";
MessageVisibleKind["NON_INITIATING"] = "non_initiating";
})(exports.MessageVisibleKind || (exports.MessageVisibleKind = {}));
exports.SequenceFlowKind = void 0;
(function (SequenceFlowKind) {
SequenceFlowKind["NORMAL"] = "normal";
SequenceFlowKind["DEFAULT"] = "default";
SequenceFlowKind["CONDITIONAL_FROM_ACTIVITY"] = "conditional_from_activity";
SequenceFlowKind["CONDITIONAL_FROM_GATEWAY"] = "conditional_from_gateway";
})(exports.SequenceFlowKind || (exports.SequenceFlowKind = {}));
class Flow {
constructor(id, name, kind, sourceReferenceId, targetReferenceId) {
Object.defineProperty(this, "id", {
enumerable: true,
configurable: true,
writable: true,
value: id
});
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: name
});
Object.defineProperty(this, "kind", {
enumerable: true,
configurable: true,
writable: true,
value: kind
});
Object.defineProperty(this, "sourceReferenceId", {
enumerable: true,
configurable: true,
writable: true,
value: sourceReferenceId
});
Object.defineProperty(this, "targetReferenceId", {
enumerable: true,
configurable: true,
writable: true,
value: targetReferenceId
});
}
}
class SequenceFlow extends Flow {
constructor(id, name, sourceReferenceId, targetReferenceId, sequenceFlowKind = exports.SequenceFlowKind.NORMAL) {
super(id, name, exports.FlowKind.SEQUENCE_FLOW, sourceReferenceId, targetReferenceId);
Object.defineProperty(this, "sequenceFlowKind", {
enumerable: true,
configurable: true,
writable: true,
value: sequenceFlowKind
});
}
}
class MessageFlow extends Flow {
constructor(id, name, sourceReferenceId, targetReferenceId) {
super(id, name, exports.FlowKind.MESSAGE_FLOW, sourceReferenceId, targetReferenceId);
}
}
class AssociationFlow extends Flow {
constructor(id, name, sourceReferenceId, targetReferenceId, associationDirectionKind = exports.AssociationDirectionKind.NONE) {
super(id, name, exports.FlowKind.ASSOCIATION_FLOW, sourceReferenceId, targetReferenceId);
Object.defineProperty(this, "associationDirectionKind", {
enumerable: true,
configurable: true,
writable: true,
value: associationDirectionKind
});
}
}
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
var build$1 = {exports: {}};
var build = build$1.exports;
var hasRequiredBuild;
function requireBuild () {
if (hasRequiredBuild) return build$1.exports;
hasRequiredBuild = 1;
(function (module) {
(function (root, factory) {
if (module.exports) {
module.exports = factory();
} else {
root.mxgraph = factory();
}
}(build, function () {
return function (opts) {
for (var name in opts) { this[name] = opts[name]; }
var __mxOutput = {};
var mxClient =
{
VERSION: '4.2.2',
IS_IE: navigator.userAgent != null && navigator.userAgent.indexOf('MSIE') >= 0,
IS_IE6: navigator.userAgent != null && navigator.userAgent.indexOf('MSIE 6') >= 0,
IS_IE11: navigator.userAgent != null && !!navigator.userAgent.match(/Trident\/7\./),
IS_EDGE: navigator.userAgent != null && !!navigator.userAgent.match(/Edge\//),
IS_QUIRKS: navigator.userAgent != null && navigator.userAgent.indexOf('MSIE') >= 0 &&
(document.documentMode == null || document.documentMode == 5),
IS_EM: 'spellcheck' in document.createElement('textarea') && document.documentMode == 8,
VML_PREFIX: 'v',
OFFICE_PREFIX: 'o',
IS_NS: navigator.userAgent != null &&
navigator.userAgent.indexOf('Mozilla/') >= 0 &&
navigator.userAgent.indexOf('MSIE') < 0 &&
navigator.userAgent.indexOf('Edge/') < 0,
IS_OP: navigator.userAgent != null &&
(navigator.userAgent.indexOf('Opera/') >= 0 ||
navigator.userAgent.indexOf('OPR/') >= 0),
IS_OT: navigator.userAgent != null &&
navigator.userAgent.indexOf('Presto/') >= 0 &&
navigator.userAgent.indexOf('Presto/2.4.') < 0 &&
navigator.userAgent.indexOf('Presto/2.3.') < 0 &&
navigator.userAgent.indexOf('Presto/2.2.') < 0 &&
navigator.userAgent.indexOf('Presto/2.1.') < 0 &&
navigator.userAgent.indexOf('Presto/2.0.') < 0 &&
navigator.userAgent.indexOf('Presto/1.') < 0,
IS_SF: /Apple Computer, Inc/.test(navigator.vendor),
IS_ANDROID: navigator.appVersion.indexOf('Android') >= 0,
IS_IOS: (/iP(hone|od|ad)/.test(navigator.platform)),
IS_GC: /Google Inc/.test(navigator.vendor),
IS_CHROMEAPP: window.chrome != null && chrome.app != null && chrome.app.runtime != null,
IS_FF: typeof InstallTrigger !== 'undefined',
IS_MT: (navigator.userAgent.indexOf('Firefox/') >= 0 &&
navigator.userAgent.indexOf('Firefox/1.') < 0 &&
navigator.userAgent.indexOf('Firefox/2.') < 0) ||
(navigator.userAgent.indexOf('Iceweasel/') >= 0 &&
navigator.userAgent.indexOf('Iceweasel/1.') < 0 &&
navigator.userAgent.indexOf('Iceweasel/2.') < 0) ||
(navigator.userAgent.indexOf('SeaMonkey/') >= 0 &&
navigator.userAgent.indexOf('SeaMonkey/1.') < 0) ||
(navigator.userAgent.indexOf('Iceape/') >= 0 &&
navigator.userAgent.indexOf('Iceape/1.') < 0),
IS_VML: navigator.appName.toUpperCase() == 'MICROSOFT INTERNET EXPLORER',
IS_SVG: navigator.appName.toUpperCase() != 'MICROSOFT INTERNET EXPLORER',
NO_FO: !document.createElementNS || document.createElementNS('http://www.w3.org/2000/svg',
'foreignObject') != '[object SVGForeignObjectElement]' || navigator.userAgent.indexOf('Opera/') >= 0,
IS_WIN: navigator.appVersion.indexOf('Win') > 0,
IS_MAC: navigator.appVersion.indexOf('Mac') > 0,
IS_CHROMEOS: /\bCrOS\b/.test(navigator.appVersion),
IS_TOUCH: 'ontouchstart' in document.documentElement,
IS_POINTER: window.PointerEvent != null && !(navigator.appVersion.indexOf('Mac') > 0),
IS_LOCAL: document.location.href.indexOf('http://') < 0 &&
document.location.href.indexOf('https://') < 0,
defaultBundles: [],
isBrowserSupported: function()
{
return mxClient.IS_VML || mxClient.IS_SVG;
},
link: function(rel, href, doc, id)
{
doc = doc || document;
if (mxClient.IS_IE6)
{
doc.write('<link rel="' + rel + '" href="' + href + '" charset="UTF-8" type="text/css"/>');
}
else
{
var link = doc.createElement('link');
link.setAttribute('rel', rel);
link.setAttribute('href', href);
link.setAttribute('charset', 'UTF-8');
link.setAttribute('type', 'text/css');
if (id)
{
link.setAttribute('id', id);
}
var head = doc.getElementsByTagName('head')[0];
head.appendChild(link);
}
},
loadResources: function(fn, lan)
{
var pending = mxClient.defaultBundles.length;
function callback()
{
if (--pending == 0)
{
fn();
}
}
for (var i = 0; i < mxClient.defaultBundles.length; i++)
{
mxResources.add(mxClient.defaultBundles[i], lan, callback);
}
},
include: function(src)
{
document.write('<script src="'+src+'"></script>');
}
};
if (typeof(mxLoadResources) == 'undefined')
{
mxLoadResources = true;
}
if (typeof(mxForceIncludes) == 'undefined')
{
mxForceIncludes = false;
}
if (typeof(mxResourceExtension) == 'undefined')
{
mxResourceExtension = '.txt';
}
if (typeof(mxLoadStylesheets) == 'undefined')
{
mxLoadStylesheets = true;
}
if (typeof(mxBasePath) != 'undefined' && mxBasePath.length > 0)
{
if (mxBasePath.substring(mxBasePath.length - 1) == '/')
{
mxBasePath = mxBasePath.substring(0, mxBasePath.length - 1);
}
mxClient.basePath = mxBasePath;
}
else
{
mxClient.basePath = '.';
}
if (typeof(mxImageBasePath) != 'undefined' && mxImageBasePath.length > 0)
{
if (mxImageBasePath.substring(mxImageBasePath.length - 1) == '/')
{
mxImageBasePath = mxImageBasePath.substring(0, mxImageBasePath.length - 1);
}
mxClient.imageBasePath = mxImageBasePath;
}
else
{
mxClient.imageBasePath = mxClient.basePath + '/images';
}
if (typeof(mxLanguage) != 'undefined' && mxLanguage != null)
{
mxClient.language = mxLanguage;
}
else
{
mxClient.language = (mxClient.IS_IE) ? navigator.userLanguage : navigator.language;
}
if (typeof(mxDefaultLanguage) != 'undefined' && mxDefaultLanguage != null)
{
mxClient.defaultLanguage = mxDefaultLanguage;
}
else
{
mxClient.defaultLanguage = 'en';
}
if (mxLoadStylesheets)
{
mxClient.link('stylesheet', mxClient.basePath + '/css/common.css');
}
if (typeof(mxLanguages) != 'undefined' && mxLanguages != null)
{
mxClient.languages = mxLanguages;
}
if (mxClient.IS_VML)
{
if (mxClient.IS_SVG)
{
mxClient.IS_VML = false;
}
else
{
if (document.namespaces != null)
{
if (document.documentMode == 8)
{
document.namespaces.add(mxClient.VML_PREFIX, 'urn:schemas-microsoft-com:vml', '#default#VML');
document.namespaces.add(mxClient.OFFICE_PREFIX, 'urn:schemas-microsoft-com:office:office', '#default#VML');
}
else
{
document.namespaces.add(mxClient.VML_PREFIX, 'urn:schemas-microsoft-com:vml');
document.namespaces.add(mxClient.OFFICE_PREFIX, 'urn:schemas-microsoft-com:office:office');
}
}
if (mxClient.IS_QUIRKS && document.styleSheets.length >= 30)
{
(function()
{
var node = document.createElement('style');
node.type = 'text/css';
node.styleSheet.cssText = mxClient.VML_PREFIX + '\\:*{behavior:url(#default#VML)}' +
mxClient.OFFICE_PREFIX + '\\:*{behavior:url(#default#VML)}';
document.getElementsByTagName('head')[0].appendChild(node);
})();
}
else
{
document.createStyleSheet().cssText = mxClient.VML_PREFIX + '\\:*{behavior:url(#default#VML)}' +
mxClient.OFFICE_PREFIX + '\\:*{behavior:url(#default#VML)}';
}
if (mxLoadStylesheets)
{
mxClient.link('stylesheet', mxClient.basePath + '/css/explorer.css');
}
}
}
if (mxForceIncludes || !(module.exports != null))
{
mxClient.include(mxClient.basePath+'/js/util/mxLog.js');
mxClient.include(mxClient.basePath+'/js/util/mxObjectIdentity.js');
mxClient.include(mxClient.basePath+'/js/util/mxDictionary.js');
mxClient.include(mxClient.basePath+'/js/util/mxResources.js');
mxClient.include(mxClient.basePath+'/js/util/mxPoint.js');
mxClient.include(mxClient.basePath+'/js/util/mxRectangle.js');
mxClient.include(mxClient.basePath+'/js/util/mxEffects.js');
mxClient.include(mxClient.basePath+'/js/util/mxUtils.js');
mxClient.include(mxClient.basePath+'/js/util/mxConstants.js');
mxClient.include(mxClient.basePath+'/js/util/mxEventObject.js');
mxClient.include(mxClient.basePath+'/js/util/mxMouseEvent.js');
mxClient.include(mxClient.basePath+'/js/util/mxEventSource.js');
mxClient.include(mxClient.basePath+'/js/util/mxEvent.js');
mxClient.include(mxClient.basePath+'/js/util/mxXmlRequest.js');
mxClient.include(mxClient.basePath+'/js/util/mxClipboard.js');
mxClient.include(mxClient.basePath+'/js/util/mxWindow.js');
mxClient.include(mxClient.basePath+'/js/util/mxForm.js');
mxClient.include(mxClient.basePath+'/js/util/mxImage.js');
mxClient.include(mxClient.basePath+'/js/util/mxDivResizer.js');
mxClient.include(mxClient.basePath+'/js/util/mxDragSource.js');
mxClient.include(mxClient.basePath+'/js/util/mxToolbar.js');
mxClient.include(mxClient.basePath+'/js/util/mxUndoableEdit.js');
mxClient.include(mxClient.basePath+'/js/util/mxUndoManager.js');
mxClient.include(mxClient.basePath+'/js/util/mxUrlConverter.js');
mxClient.include(mxClient.basePath+'/js/util/mxPanningManager.js');
mxClient.include(mxClient.basePath+'/js/util/mxPopupMenu.js');
mxClient.include(mxClient.basePath+'/js/util/mxAutoSaveManager.js');
mxClient.include(mxClient.basePath+'/js/util/mxAnimation.js');
mxClient.include(mxClient.basePath+'/js/util/mxMorphing.js');
mxClient.include(mxClient.basePath+'/js/util/mxImageBundle.js');
mxClient.include(mxClient.basePath+'/js/util/mxImageExport.js');
mxClient.include(mxClient.basePath+'/js/util/mxAbstractCanvas2D.js');
mxClient.include(mxClient.basePath+'/js/util/mxXmlCanvas2D.js');
mxClient.include(mxClient.basePath+'/js/util/mxSvgCanvas2D.js');
mxClient.include(mxClient.basePath+'/js/util/mxVmlCanvas2D.js');
mxClient.include(mxClient.basePath+'/js/util/mxGuide.js');
mxClient.include(mxClient.basePath+'/js/shape/mxShape.js');
mxClient.include(mxClient.basePath+'/js/shape/mxStencil.js');
mxClient.include(mxClient.basePath+'/js/shape/mxStencilRegistry.js');
mxClient.include(mxClient.basePath+'/js/shape/mxMarker.js');
mxClient.include(mxClient.basePath+'/js/shape/mxActor.js');
mxClient.include(mxClient.basePath+'/js/shape/mxCloud.js');
mxClient.include(mxClient.basePath+'/js/shape/mxRectangleShape.js');
mxClient.include(mxClient.basePath+'/js/shape/mxEllipse.js');
mxClient.include(mxClient.basePath+'/js/shape/mxDoubleEllipse.js');
mxClient.include(mxClient.basePath+'/js/shape/mxRhombus.js');
mxClient.include(mxClient.basePath+'/js/shape/mxPolyline.js');
mxClient.include(mxClient.basePath+'/js/shape/mxArrow.js');
mxClient.include(mxClient.basePath+'/js/shape/mxArrowConnector.js');
mxClient.include(mxClient.basePath+'/js/shape/mxText.js');
mxClient.include(mxClient.basePath+'/js/shape/mxTriangle.js');
mxClient.include(mxClient.basePath+'/js/shape/mxHexagon.js');
mxClient.include(mxClient.basePath+'/js/shape/mxLine.js');
mxClient.include(mxClient.basePath+'/js/shape/mxImageShape.js');
mxClient.include(mxClient.basePath+'/js/shape/mxLabel.js');
mxClient.include(mxClient.basePath+'/js/shape/mxCylinder.js');
mxClient.include(mxClient.basePath+'/js/shape/mxConnector.js');
mxClient.include(mxClient.basePath+'/js/shape/mxSwimlane.js');
mxClient.include(mxClient.basePath+'/js/layout/mxGraphLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/mxStackLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/mxPartitionLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/mxCompactTreeLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/mxRadialTreeLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/mxFastOrganicLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/mxCircleLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/mxParallelEdgeLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/mxCompositeLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/mxEdgeLabelLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/model/mxGraphAbstractHierarchyCell.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/model/mxGraphHierarchyNode.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/model/mxGraphHierarchyEdge.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/model/mxGraphHierarchyModel.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/model/mxSwimlaneModel.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/stage/mxHierarchicalLayoutStage.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/stage/mxMedianHybridCrossingReduction.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/stage/mxMinimumCycleRemover.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/stage/mxCoordinateAssignment.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/stage/mxSwimlaneOrdering.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/mxHierarchicalLayout.js');
mxClient.include(mxClient.basePath+'/js/layout/hierarchical/mxSwimlaneLayout.js');
mxClient.include(mxClient.basePath+'/js/model/mxGraphModel.js');
mxClient.include(mxClient.basePath+'/js/model/mxCell.js');
mxClient.include(mxClient.basePath+'/js/model/mxGeometry.js');
mxClient.include(mxClient.basePath+'/js/model/mxCellPath.js');
mxClient.include(mxClient.basePath+'/js/view/mxPerimeter.js');
mxClient.include(mxClient.basePath+'/js/view/mxPrintPreview.js');
mxClient.include(mxClient.basePath+'/js/view/mxStylesheet.js');
mxClient.include(mxClient.basePath+'/js/view/mxCellState.js');
mxClient.include(mxClient.basePath+'/js/view/mxGraphSelectionModel.js');
mxClient.include(mxClient.basePath+'/js/view/mxCellEditor.js');
mxClient.include(mxClient.basePath+'/js/view/mxCellRenderer.js');
mxClient.include(mxClient.basePath+'/js/view/mxEdgeStyle.js');
mxClient.include(mxClient.basePath+'/js/view/mxStyleRegistry.js');
mxClient.include(mxClient.basePath+'/js/view/mxGraphView.js');
mxClient.include(mxClient.basePath+'/js/view/mxGraph.js');
mxClient.include(mxClient.basePath+'/js/view/mxCellOverlay.js');
mxClient.include(mxClient.basePath+'/js/view/mxOutline.js');
mxClient.include(mxClient.basePath+'/js/view/mxMultiplicity.js');
mxClient.include(mxClient.basePath+'/js/view/mxLayoutManager.js');
mxClient.include(mxClient.basePath+'/js/view/mxSwimlaneManager.js');
mxClient.include(mxClient.basePath+'/js/view/mxTemporaryCellStates.js');
mxClient.include(mxClient.basePath+'/js/view/mxCellStatePreview.js');
mxClient.include(mxClient.basePath+'/js/view/mxConnectionConstraint.js');
mxClient.include(mxClient.basePath+'/js/handler/mxGraphHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxPanningHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxPopupMenuHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxCellMarker.js');
mxClient.include(mxClient.basePath+'/js/handler/mxSelectionCellsHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxConnectionHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxConstraintHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxRubberband.js');
mxClient.include(mxClient.basePath+'/js/handler/mxHandle.js');
mxClient.include(mxClient.basePath+'/js/handler/mxVertexHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxEdgeHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxElbowEdgeHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxEdgeSegmentHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxKeyHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxTooltipHandler.js');
mxClient.include(mxClient.basePath+'/js/handler/mxCellTracker.js');
mxClient.include(mxClient.basePath+'/js/handler/mxCellHighlight.js');
mxClient.include(mxClient.basePath+'/js/editor/mxDefaultKeyHandler.js');
mxClient.include(mxClient.basePath+'/js/editor/mxDefaultPopupMenu.js');
mxClient.include(mxClient.basePath+'/js/editor/mxDefaultToolbar.js');
mxClient.include(mxClient.basePath+'/js/editor/mxEditor.js');
mxClient.include(mxClient.basePath+'/js/io/mxCodecRegistry.js');
mxClient.include(mxClient.basePath+'/js/io/mxCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxObjectCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxCellCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxModelCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxRootChangeCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxChildChangeCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxTerminalChangeCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxGenericChangeCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxGraphCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxGraphViewCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxStylesheetCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxDefaultKeyHandlerCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxDefaultToolbarCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxDefaultPopupMenuCodec.js');
mxClient.include(mxClient.basePath+'/js/io/mxEditorCodec.js');
}
__mxOutput.mxClient = typeof mxClient !== 'undefined' ? mxClient : undefined;
var mxLog =
{
consoleName: 'Console',
TRACE: false,
DEBUG: true,
WARN: true,
buffer: '',
init: function()
{
if (mxLog.window == null && document.body != null)
{
var title = mxLog.consoleName + ' - mxGraph ' + mxClient.VERSION;
var table = document.createElement('table');
table.setAttribute('width', '100%');
table.setAttribute('height', '100%');
var tbody = document.createElement('tbody');
var tr = document.createElement('tr');
var td = document.createElement('td');
td.style.verticalAlign = 'top';
mxLog.textarea = document.createElement('textarea');
mxLog.textarea.setAttribute('wrap', 'off');
mxLog.textarea.setAttribute('readOnly', 'true');
mxLog.textarea.style.height = '100%';
mxLog.textarea.style.resize = 'none';
mxLog.textarea.value = mxLog.buffer;
if (mxClient.IS_NS && document.compatMode != 'BackCompat')
{
mxLog.textarea.style.width = '99%';
}
else
{
mxLog.textarea.style.width = '100%';
}
td.appendChild(mxLog.textarea);
tr.appendChild(td);
tbody.appendChild(tr);
tr = document.createElement('tr');
mxLog.td = document.createElement('td');
mxLog.td.style.verticalAlign = 'top';
mxLog.td.setAttribute('height', '30px');
tr.appendChild(mxLog.td);
tbody.appendChild(tr);
table.appendChild(tbody);
mxLog.addButton('Info', function (evt)
{
mxLog.info();
});
mxLog.addButton('DOM', function (evt)
{
var content = mxUtils.getInnerHtml(document.body);
mxLog.debug(content);
});
mxLog.addButton('Trace', function (evt)
{
mxLog.TRACE = !mxLog.TRACE;
if (mxLog.TRACE)
{
mxLog.debug('Tracing enabled');
}
else
{
mxLog.debug('Tracing disabled');
}
});
mxLog.addButton('Copy', function (evt)
{
try
{
mxUtils.copy(mxLog.textarea.value);
}
catch (err)
{
mxUtils.alert(err);
}
});
mxLog.addButton('Show', function (evt)
{
try
{
mxUtils.popup(mxLog.textarea.value);
}
catch (err)
{
mxUtils.alert(err);
}
});
mxLog.addButton('Clear', function (evt)
{
mxLog.textarea.value = '';
});
var h = 0;
var w = 0;
if (typeof(window.innerWidth) === 'number')
{
h = window.innerHeight;
w = window.innerWidth;
}
else
{
h = (document.documentElement.clientHeight || document.body.clientHeight);
w = document.body.clientWidth;
}
mxLog.window = new mxWindow(title, table, Math.max(0, w - 320), Math.max(0, h - 210), 300, 160);
mxLog.window.setMaximizable(true);
mxLog.window.setScrollable(false);
mxLog.window.setResizable(true);
mxLog.window.setClosable(true);
mxLog.window.destroyOnClose = false;
if (((mxClient.IS_NS || mxClient.IS_IE) && !mxClient.IS_GC &&
!mxClient.IS_SF && document.compatMode != 'BackCompat') ||
document.documentMode == 11)
{
var elt = mxLog.window.getElement();
var resizeHandler = function(sender, evt)
{
mxLog.textarea.style.height = Math.max(0, elt.offsetHeight - 70) + 'px';
};
mxLog.window.addListener(mxEvent.RESIZE_END, resizeHandler);
mxLog.window.addListener(mxEvent.MAXIMIZE, resizeHandler);
mxLog.window.addListener(mxEvent.NORMALIZE, resizeHandler);
mxLog.textarea.style.height = '92px';
}
}
},
info: function()
{
mxLog.writeln(mxUtils.toString(navigator));
},
addButton: function(lab, funct)
{
var button = document.createElement('button');
mxUtils.write(button, lab);
mxEvent.addListener(button, 'click', funct);
mxLog.td.appendChild(button);
},
isVisible: function()
{
if (mxLog.window != null)
{
return mxLog.window.isVisible();
}
return false;
},
show: function()
{
mxLog.setVisible(true);
},
setVisible: function(visible)
{
if (mxLog.window == null)
{
mxLog.init();
}
if (mxLog.window != null)
{
mxLog.window.setVisible(visible);
}
},
enter: function(string)
{
if (mxLog.TRACE)
{
mxLog.writeln('Entering '+string);
return new Date().getTime();
}
},
leave: function(string, t0)
{
if (mxLog.TRACE)
{
var dt = (t0 != 0) ? ' ('+(new Date().getTime() - t0)+' ms)' : '';
mxLog.writeln('Leaving '+string+dt);
}
},
debug: function()
{
if (mxLog.DEBUG)
{
mxLog.writeln.apply(this, arguments);
}
},
warn: function()
{
if (mxLog.WARN)
{
mxLog.writeln.apply(this, arguments);
}
},
write: function()
{
var string = '';
for (var i = 0; i < arguments.length; i++)
{
string += arguments[i];
if (i < arguments.length - 1)
{
string += ' ';
}
}
if (mxLog.textarea != null)
{
mxLog.textarea.value = mxLog.textarea.value + string;
if (navigator.userAgent != null &&
navigator.userAgent.indexOf('Presto/2.5') >= 0)
{
mxLog.textarea.style.visibility = 'hidden';
mxLog.textarea.style.visibility = 'visible';
}
mxLog.textarea.scrollTop = mxLog.textarea.scrollHeight;
}
else
{
mxLog.buffer += string;
}
},
writeln: function()
{
var string = '';
for (var i = 0; i < arguments.length; i++)
{
string += arguments[i];
if (i < arguments.length - 1)
{
string += ' ';
}
}
mxLog.write(string + '\n');
}
};
__mxOutput.mxLog = typeof mxLog !== 'undefined' ? mxLog : undefined;
var mxObjectIdentity =
{
FIELD_NAME: 'mxObjectId',
counter: 0,
get: function(obj)
{
if (obj != null)
{
if (obj[mxObjectIdentity.FIELD_NAME] == null)
{
if (typeof obj === 'object')
{
var ctor = mxUtils.getFunctionName(obj.constructor);
obj[mxObjectIdentity.FIELD_NAME] = ctor + '#' + mxObjectIdentity.counter++;
}
else if (typeof obj === 'function')
{
obj[mxObjectIdentity.FIELD_NAME] = 'Function#' + mxObjectIdentity.counter++;
}
}
return obj[mxObjectIdentity.FIELD_NAME];
}
return null;
},
clear: function(obj)
{
if (typeof(obj) === 'object' || typeof obj === 'function')
{
delete obj[mxObjectIdentity.FIELD_NAME];
}
}
};
__mxOutput.mxObjectIdentity = typeof mxObjectIdentity !== 'undefined' ? mxObjectIdentity : undefined;
function mxDictionary()
{
this.clear();
} mxDictionary.prototype.map = null;
mxDictionary.prototype.clear = function()
{
this.map = {};
};
mxDictionary.prototype.get = function(key)
{
var id = mxObjectIdentity.get(key);
return this.map[id];
};
mxDictionary.prototype.put = function(key, value)
{
var id = mxObjectIdentity.get(key);
var previous = this.map[id];
this.map[id] = value;
return previous;
};
mxDictionary.prototype.remove = function(key)
{
var id = mxObjectIdentity.get(key);
var previous = this.map[id];
delete this.map[id];
return previous;
};
mxDictionary.prototype.getKeys = function()
{
var result = [];
for (var key in this.map)
{
result.push(key);
}
return result;
};
mxDictionary.prototype.getValues = function()
{
var result = [];
for (var key in this.map)
{
result.push(this.map[key]);
}
return result;
};
mxDictionary.prototype.visit = function(visitor)
{
for (var key in this.map)
{
visitor(key, this.map[key]);
}
};
__mxOutput.mxDictionary = typeof mxDictionary !== 'undefined' ? mxDictionary : undefined;
var mxResources =
{
resources: {},
extension: mxResourceExtension,
resourcesEncoded: false,
loadDefaultBundle: true,
loadSpecialBundle: true,
isLanguageSupported: function(lan)
{
if (mxClient.languages != null)
{
return mxUtils.indexOf(mxClient.languages, lan) >= 0;
}
return true;
},
getDefaultBundle: function(basename, lan)
{
if (mxResources.loadDefaultBundle || !mxResources.isLanguageSupported(lan))
{
return basename + mxResources.extension;
}
else
{
return null;
}
},
getSpecialBundle: function(basename, lan)
{
if (mxClient.languages == null || !this.isLanguageSupported(lan))
{
var dash = lan.indexOf('-');
if (dash > 0)
{
lan = lan.substring(0, dash);
}
}
if (mxResources.loadSpecialBundle && mxResources.isLanguageSupported(lan) && lan != mxClient.defaultLanguage)
{
return basename + '_' + lan + mxResources.extension;
}
else
{
return null;
}
},
add: function(basename, lan, callback)
{
lan = (lan != null) ? lan : ((mxClient.language != null) ?
mxClient.language.toLowerCase() : mxConstants.NONE);
if (lan != mxConstants.NONE)
{
var defaultBundle = mxResources.getDefaultBundle(basename, lan);
var specialBundle = mxResources.getSpecialBundle(basename, lan);
var loadSpecialBundle = function()
{
if (specialBundle != null)
{
if (callback)
{
mxUtils.get(specialBundle, function(req)
{
mxResources.parse(req.getText());
callback();
}, function()
{
callback();
});
}
else
{
try
{
var req = mxUtils.load(specialBundle);
if (req.isReady())
{
mxResources.parse(req.getText());
}
}
catch (e)
{
}
}
}
else if (callback != null)
{
callback();
}
};
if (defaultBundle != null)
{
if (callback)
{
mxUtils.get(defaultBundle, function(req)
{
mxResources.parse(req.getText());
loadSpecialBundle();
}, function()
{
loadSpecialBundle();
});
}
else
{
try
{
var req = mxUtils.load(defaultBundle);
if (req.isReady())
{
mxResources.parse(req.getText());
}
loadSpecialBundle();
}
catch (e)
{
}
}
}
else
{
loadSpecialBundle();
}
}
},
parse: function(text)
{
if (text != null)
{
var lines = text.split('\n');
for (var i = 0; i < lines.length; i++)
{
if (lines[i].charAt(0) != '#')
{
var index = lines[i].indexOf('=');
if (index > 0)
{
var key = lines[i].substring(0, index);
var idx = lines[i].length;
if (lines[i].charCodeAt(idx - 1) == 13)
{
idx--;
}
var value = lines[i].substring(index + 1, idx);
if (this.resourcesEncoded)
{
value = value.replace(/\\(?=u[a-fA-F\d]{4})/g,"%");
mxResources.resources[key] = unescape(value);
}
else
{
mxResources.resources[key] = value;
}
}
}
}
}
},
get: function(key, params, defaultValue)
{
var value = mxResources.resources[key];
if (value == null)
{
value = defaultValue;
}
if (value != null && params != null)
{
value = mxResources.replacePlaceholders(value, params);
}
return value;
},
replacePlaceholders: function(value, params)
{
var result = [];
var index = null;
for (var i = 0; i < value.length; i++)
{
var c = value.charAt(i);
if (c == '{')
{
index = '';
}
else if (index != null && c == '}')
{
index = parseInt(index)-1;
if (index >= 0 && index < params.length)
{
result.push(params[index]);
}
index = null;
}
else if (index != null)
{
index += c;
}
else
{
result.push(c);
}
}
return result.join('');
},
loadResources: function(callback)
{
mxResources.add(mxClient.basePath+'/resources/editor', null, function()
{
mxResources.add(mxClient.basePath+'/resources/graph', null, callback);
});
}
};
__mxOutput.mxResources = typeof mxResources !== 'undefined' ? mxResources : undefined;
function mxPoint(x, y)
{
this.x = (x != null) ? x : 0;
this.y = (y != null) ? y : 0;
} mxPoint.prototype.x = null;
mxPoint.prototype.y = null;
mxPoint.prototype.equals = function(obj)
{
return obj != null && obj.x == this.x && obj.y == this.y;
};
mxPoint.prototype.clone = function()
{
return mxUtils.clone(this);
};
__mxOutput.mxPoint = typeof mxPoint !== 'undefined' ? mxPoint : undefined;
function mxRectangle(x, y, width, height)
{
mxPoint.call(this, x, y);
this.width = (width != null) ? width : 0;
this.height = (height != null) ? height : 0;
} mxRectangle.prototype = new mxPoint();
mxRectangle.prototype.constructor = mxRectangle;
mxRectangle.prototype.width = null;
mxRectangle.prototype.height = null;
mxRectangle.prototype.setRect = function(x, y, w, h)
{
this.x = x;
this.y = y;
this.width = w;
this.height = h;
};
mxRectangle.prototype.getCenterX = function ()
{
return this.x + this.width/2;
};
mxRectangle.prototype.getCenterY = function ()
{
return this.y + this.height/2;
};
mxRectangle.prototype.add = function(rect)
{
if (rect != null)
{
var minX = Math.min(this.x, rect.x);
var minY = Math.min(this.y, rect.y);
var maxX = Math.max(this.x + this.width, rect.x + rect.width);
var maxY = Math.max(this.y + this.height, rect.y + rect.height);
this.x = minX;
this.y = minY;
this.width = maxX - minX;
this.height = maxY - minY;
}
};
mxRectangle.prototype.intersect = function(rect)
{
if (rect != null)
{
var r1 = this.x + this.width;
var r2 = rect.x + rect.width;
var b1 = this.y + this.height;
var b2 = rect.y + rect.height;
this.x = Math.max(this.x, rect.x);
this.y = Math.max(this.y, rect.y);
this.width = Math.min(r1, r2) - this.x;
this.height = Math.min(b1, b2) - this.y;
}
};
mxRectangle.prototype.grow = function(amount)
{
this.x -= amount;
this.y -= amount;
this.width += 2 * amount;
this.height += 2 * amount;
return this;
};
mxRectangle.prototype.getPoint = function()
{
return new mxPoint(this.x, this.y);
};
mxRectangle.prototype.rotate90 = function()
{
var t = (this.width - this.height) / 2;
this.x += t;
this.y -= t;
var tmp = this.width;
this.width = this.height;
this.height = tmp;
};
mxRectangle.prototype.equals = function(obj)
{
return obj != null && obj.x == this.x && obj.y == this.y &&
obj.width == this.width && obj.height == this.height;
};
mxRectangle.fromRectangle = function(rect)
{
return new mxRectangle(rect.x, rect.y, rect.width, rect.height);
};
__mxOutput.mxRectangle = typeof mxRectangle !== 'undefined' ? mxRectangle : undefined;
var mxEffects =
{
animateChanges: function(graph, changes, done)
{
var maxStep = 10;
var step = 0;
var animate = function()
{
var isRequired = false;
for (var i = 0; i < changes.length; i++)
{
var change = changes[i];
if (change instanceof mxGeometryChange ||
change instanceof mxTerminalChange ||
change instanceof mxValueChange ||
change instanceof mxChildChange ||
change instanceof mxStyleChange)
{
var state = graph.getView().getState(change.cell || change.child, false);
if (state != null)
{
isRequired = true;
if (change.constructor != mxGeometryChange || graph.model.isEdge(change.cell))
{
mxUtils.setOpacity(state.shape.node, 100 * step / maxStep);
}
else
{
var scale = graph.getView().scale;
var dx = (change.geometry.x - change.previous.x) * scale;
var dy = (change.geometry.y - change.previous.y) * scale;
var sx = (change.geometry.width - change.previous.width) * scale;
var sy = (change.geometry.height - change.previous.height) * scale;
if (step == 0)
{
state.x -= dx;
state.y -= dy;
state.width -= sx;
state.height -= sy;
}
else
{
state.x += dx / maxStep;
state.y += dy / maxStep;
state.width += sx / maxStep;
state.height += sy / maxStep;
}
graph.cellRenderer.redraw(state);
mxEffects.cascadeOpacity(graph, change.cell, 100 * step / maxStep);
}
}
}
}
if (step < maxStep && isRequired)
{
step++;
window.setTimeout(animate, delay);
}
else if (done != null)
{
done();
}
};
var delay = 30;
animate();
},
cascadeOpacity: function(graph, cell, opacity)
{
var childCount = graph.model.getChildCount(cell);
for (var i=0; i<childCount; i++)
{
var child = graph.model.getChildAt(cell, i);
var childState = graph.getView().getState(child);
if (childState != null)
{
mxUtils.setOpacity(childState.shape.node, opacity);
mxEffects.cascadeOpacity(graph, child, opacity);
}
}
var edges = graph.model.getEdges(cell);
if (edges != null)
{
for (var i=0; i<edges.length; i++)
{
var edgeState = graph.getView().getState(edges[i]);
if (edgeState != null)
{
mxUtils.setOpacity(edgeState.shape.node, opacity);
}
}
}
},
fadeOut: function(node, from, remove, step, delay, isEnabled)
{
step = step || 40;
delay = delay || 30;
var opacity = from || 100;
mxUtils.setOpacity(node, opacity);
if (isEnabled || isEnabled == null)
{
var f = function()
{
opacity = Math.max(opacity-step, 0);
mxUtils.setOpacity(node, opacity);
if (opacity > 0)
{
window.setTimeout(f, delay);
}
else
{
node.style.visibility = 'hidden';
if (remove && node.parentNode)
{
node.parentNode.removeChild(node);
}
}
};
window.setTimeout(f, delay);
}
else
{
node.style.visibility = 'hidden';
if (remove && node.parentNode)
{
node.parentNode.removeChild(node);
}
}
}
};
__mxOutput.mxEffects = typeof mxEffects !== 'undefined' ? mxEffects : undefined;
var mxUtils =
{
errorResource: (mxClient.language != 'none') ? 'error' : '',
closeResource: (mxClient.language != 'none') ? 'close' : '',
errorImage: mxClient.imageBasePath + '/error.gif',
removeCursors: function(element)
{
if (element.style != null)
{
element.style.cursor = '';
}
var children = element.childNodes;
if (children != null)
{
var childCount = children.length;
for (var i = 0; i < childCount; i += 1)
{
mxUtils.removeCursors(children[i]);
}
}
},
getCurrentStyle: function()
{
if (mxClient.IS_IE && (document.documentMode == null || document.documentMode < 9))
{
return function(element)
{
return (element != null) ? element.currentStyle : null;
};
}
else
{
return function(element)
{
return (element != null) ?
window.getComputedStyle(element, '') :
null;
};
}
}(),
parseCssNumber: function(value)
{
if (value == 'thin')
{
value = '2';
}
else if (value == 'medium')
{
value = '4';
}
else if (value == 'thick')
{
value = '6';
}
value = parseFloat(value);
if (isNaN(value))
{
value = 0;
}
return value;
},
setPrefixedStyle: function()
{
var prefix = null;
if (mxClient.IS_OT)
{
prefix = 'O';
}
else if (mxClient.IS_SF || mxClient.IS_GC)
{
prefix = 'Webkit';
}
else if (mxClient.IS_MT)
{
prefix = 'Moz';
}
else if (mxClient.IS_IE && document.documentMode >= 9 && document.documentMode < 10)
{
prefix = 'ms';
}
return function(style, name, value)
{
style[name] = value;
if (prefix != null && name.length > 0)
{
name = prefix + name.substring(0, 1).toUpperCase() + name.substring(1);
style[name] = value;
}
};
}(),
hasScrollbars: function(node)
{
var style = mxUtils.getCurrentStyle(node);
return style != null && (style.overflow == 'scroll' || style.overflow == 'auto');
},
bind: function(scope, funct)
{
return function()
{
return funct.apply(scope, arguments);
};
},
eval: function(expr)
{
var result = null;
if (expr.indexOf('function') >= 0)
{
try
{
eval('var _mxJavaScriptExpression='+expr);
result = _mxJavaScriptExpression;
_mxJavaScriptExpression = null;
}
catch (e)
{
mxLog.warn(e.message + ' while evaluating ' + expr);
}
}
else
{
try
{
result = eval(expr);
}
catch (e)
{
mxLog.warn(e.message + ' while evaluating ' + expr);
}
}
return result;
},
findNode: function(node, attr, value)
{
if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
{
var tmp = node.getAttribute(attr);
if (tmp != null && tmp == value)
{
return node;
}
}
node = node.firstChild;
while (node != null)
{
var result = mxUtils.findNode(node, attr, value);
if (result != null)
{
return result;
}
node = node.nextSibling;
}
return null;
},
getFunctionName: function(f)
{
var str = null;
if (f != null)
{
if (f.name != null)
{
str = f.name;
}
else
{
str = mxUtils.trim(f.toString());
if (/^function\s/.test(str))
{
str = mxUtils.ltrim(str.substring(9));
var idx2 = str.indexOf('(');
if (idx2 > 0)
{
str = str.substring(0, idx2);
}
}
}
}
return str;
},
indexOf: function(array, obj)
{
if (array != null && obj != null)
{
for (var i = 0; i < array.length; i++)
{
if (array[i] == obj)
{
return i;
}
}
}
return -1;
},
forEach: function(array, fn)
{
if (array != null && fn != null)
{
for (var i = 0; i < array.length; i++)
{
fn(array[i]);
}
}
return array;
},
remove: function(obj, array)
{
var result = null;
if (typeof(array) == 'object')
{
var index = mxUtils.indexOf(array, obj);
while (index >= 0)
{
array.splice(index, 1);
result = obj;
index = mxUtils.indexOf(array, obj);
}
}
for (var key in array)
{
if (array[key] == obj)
{
delete array[key];
result = obj;
}
}
return result;
},
isNode: function(value, nodeName, attributeName, attributeValue)
{
if (value != null && !isNaN(value.nodeType) && (nodeName == null ||
value.nodeName.toLowerCase() == nodeName.toLowerCase()))
{
return attributeName == null ||
value.getAttribute(attributeName) == attributeValue;
}
return false;
},
isAncestorNode: function(ancestor, child)
{
var parent = child;
while (parent != null)
{
if (parent == ancestor)
{
return true;
}
parent = parent.parentNode;
}
return false;
},
getChildNodes: function(node, nodeType)
{
nodeType = nodeType || mxConstants.NODETYPE_ELEMENT;
var children = [];
var tmp = node.firstChild;
while (tmp != null)
{
if (tmp.nodeType == nodeType)
{
children.push(tmp);
}
tmp = tmp.nextSibling;
}
return children;
},
importNode: function(doc, node, allChildren)
{
if (mxClient.IS_IE && (document.documentMode == null || document.documentMode < 10))
{
return mxUtils.importNodeImplementation(doc, node, allChildren);
}
else
{
return doc.importNode(node, allChildren);
}
},
importNodeImplementation: function(doc, node, allChildren)
{
switch (node.nodeType)
{
case 1:
{
var newNode = doc.createElement(node.nodeName);
if (node.attributes && node.attributes.length > 0)
{
for (var i = 0; i < node.attributes.length; i++)
{
newNode.setAttribute(node.attributes[i].nodeName,
node.getAttribute(node.attributes[i].nodeName));
}
}
if (allChildren && node.childNodes && node.childNodes.length > 0)
{
for (var i = 0; i < node.childNodes.length; i++)
{
newNode.appendChild(mxUtils.importNodeImplementation(doc, node.childNodes[i], allChildren));
}
}
return newNode;
}
case 3:
case 4:
case 8:
{
return doc.createTextNode((node.nodeValue != null) ? node.nodeValue : node.value);
}
} },
createXmlDocument: function()
{
var doc = null;
if (document.implementation && document.implementation.createDocument)
{
doc = document.implementation.createDocument('', '', null);
}
else if ("ActiveXObject" in window)
{
doc = mxUtils.createMsXmlDocument();
}
return doc;
},
createMsXmlDocument: function()
{
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = false;
doc.validateOnParse = false;
doc.resolveExternals = false;
return doc;
},
parseXml: function()
{
if (window.DOMParser)
{
return function(xml)
{
var parser = new DOMParser();
return parser.parseFromString(xml, 'text/xml');
};
}
else
{
return function(xml)
{
var doc = mxUtils.createMsXmlDocument();
doc.loadXML(xml);
return doc;
};
}
}(),
clearSelection: function()
{
if (document.selection)
{
return function()
{
document.selection.empty();
};
}
else if (window.getSelection)
{
return function()
{
if (window.getSelection().empty)
{
window.getSelection().empty();
}
else if (window.getSelection().removeAllRanges)
{
window.getSelection().removeAllRanges();
}
};
}
else
{
return function() { };
}
}(),
removeWhitespace: function(node, before)
{
var tmp = (before) ? node.previousSibling : node.nextSibling;
while (tmp != null && tmp.nodeType == mxConstants.NODETYPE_TEXT)
{
var next = (before) ? tmp.previousSibling : tmp.nextSibling;
var text = mxUtils.getTextContent(tmp);
if (mxUtils.trim(text).length == 0)
{
tmp.parentNode.removeChild(tmp);
}
tmp = next;
}
},
htmlEntities: function(s, newline)
{
s = String(s || '');
s = s.replace(/&/g,'&');
s = s.replace(/"/g,'"');
s = s.replace(/\'/g,''');
s = s.replace(/</g,'<');
s = s.replace(/>/g,'>');
if (newline == null || newline)
{
s = s.replace(/\n/g, '
');
}
return s;
},
isVml: function(node)
{
return node != null && node.tagUrn == 'urn:schemas-microsoft-com:vml';
},
getXml: function(node, linefeed)
{
var xml = '';
if (mxClient.IS_IE || mxClient.IS_IE11)
{
xml = mxUtils.getPrettyXml(node, '', '', '');
}
else if (window.XMLSerializer != null)
{
var xmlSerializer = new XMLSerializer();
xml = xmlSerializer.serializeToString(node);
}
else if (node.xml != null)
{
xml = node.xml.replace(/\r\n\t[\t]*/g, '').
replace(/>\r\n/g, '>').
replace(/\r\n/g, '\n');
}
linefeed = linefeed || '
';
xml = xml.replace(/\n/g, linefeed);
return xml;
},
getPrettyXml: function(node, tab, indent, newline, ns)
{
var result = [];
if (node != null)
{
tab = (tab != null) ? tab : ' ';
indent = (indent != null) ? indent : '';
newline = (newline != null) ? newline : '\n';
if (node.namespaceURI != null && node.namespaceURI != ns)
{
ns = node.namespaceURI;
if (node.getAttribute('xmlns') == null)
{
node.setAttribute('xmlns', node.namespaceURI);
}
}
if (node.nodeType == mxConstants.NODETYPE_DOCUMENT)
{
result.push(mxUtils.getPrettyXml(node.documentElement, tab, indent, newline, ns));
}
else if (node.nodeType == mxConstants.NODETYPE_DOCUMENT_FRAGMENT)
{
var tmp = node.firstChild;
if (tmp != null)
{
while (tmp != null)
{
result.push(mxUtils.getPrettyXml(tmp, tab, indent, newline, ns));
tmp = tmp.nextSibling;
}
}
}
else if (node.nodeType == mxConstants.NODETYPE_COMMENT)
{
var value = mxUtils.getTextContent(node);
if (value.length > 0)
{
result.push(indent + '<!--' + value + '-->' + newline);
}
}
else if (node.nodeType == mxConstants.NODETYPE_TEXT)
{
var value = mxUtils.trim(mxUtils.getTextContent(node));
if (value.length > 0)
{
result.push(indent + mxUtils.htmlEntities(value, false) + newline);
}
}
else if (node.nodeType == mxConstants.NODETYPE_CDATA)
{
var value = mxUtils.getTextContent(node);
if (value.length > 0)
{
result.push(indent + '<![CDATA[' + value + ']]' + newline);
}
}
else
{
result.push(indent + '<' + node.nodeName);
var attrs = node.attributes;
if (attrs != null)
{
for (var i = 0; i < attrs.length; i++)
{
var val = mxUtils.htmlEntities(attrs[i].value);
result.push(' ' + attrs[i].nodeName + '="' + val + '"');
}
}
var tmp = node.firstChild;
if (tmp != null)
{
result.push('>' + newline);
while (tmp != null)
{
result.push(mxUtils.getPrettyXml(tmp, tab, indent + tab, newline, ns));
tmp = tmp.nextSibling;
}
result.push(indent + '</'+ node.nodeName + '>' + newline);
}
else
{
result.push(' />' + newline);
}
}
}
return result.join('');
},
extractTextWithWhitespace: function(elems)
{
var blocks = ['BLOCKQUOTE', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'OL', 'P', 'PRE', 'TABLE', 'UL'];
var ret = [];
function doExtract(elts)
{
if (elts.length == 1 && (elts[0].nodeName == 'BR' ||
elts[0].innerHTML == '\n'))
{
return;
}
for (var i = 0; i < elts.length; i++)
{
var elem = elts[i];
if (elem.nodeName == 'BR' || elem.innerHTML == '\n' ||
((elts.length == 1 || i == 0) && (elem.nodeName == 'DIV' &&
elem.innerHTML.toLowerCase() == '<br>')))
{
ret.push('\n');
}
else
{
if (elem.nodeType === 3 || elem.nodeType === 4)
{
if (elem.nodeValue.length > 0)
{
ret.push(elem.nodeValue);
}
}
else if (elem.nodeType !== 8 && elem.childNodes.length > 0)
{
doExtract(elem.childNodes);
}
if (i < elts.length - 1 && mxUtils.indexOf(blocks, elts[i + 1].nodeName) >= 0)
{
ret.push('\n');
}
}
}
} doExtract(elems);
return ret.join('');
},
replaceTrailingNewlines: function(str, pattern)
{
var postfix = '';
while (str.length > 0 && str.charAt(str.length - 1) == '\n')
{
str = str.substring(0, str.length - 1);
postfix += pattern;
}
return str + postfix;
},
getTextContent: function(node)
{
if (mxClient.IS_IE && node.innerText !== undefined)
{
return node.innerText;
}
else
{
return (node != null) ? node[(node.textContent === undefined) ? 'text' : 'textContent'] : '';
}
},
setTextContent: function(node, text)
{
if (node.innerText !== undefined)
{
node.innerText = text;
}
else
{
node[(node.textContent === undefined) ? 'text' : 'textContent'] = text;
}
},
getInnerHtml: function()
{
if (mxClient.IS_IE)
{
return function(node)
{
if (node != null)
{
return node.innerHTML;
}
return '';
};
}
else
{
return function(node)
{
if (node != null)
{
var serializer = new XMLSerializer();
return serializer.serializeToString(node);
}
return '';
};
}
}(),
getOuterHtml: function()
{
if (mxClient.IS_IE)
{
return function(node)
{
if (node != null)
{
if (node.outerHTML != null)
{
return node.outerHTML;
}
else
{
var tmp = [];
tmp.push('<'+node.nodeName);
var attrs = node.attributes;
if (attrs != null)
{
for (var i = 0; i < attrs.length; i++)
{
var value = attrs[i].value;
if (value != null && value.length > 0)
{
tmp.push(' ');
tmp.push(attrs[i].nodeName);
tmp.push('="');
tmp.push(value);
tmp.push('"');
}
}
}
if (node.innerHTML.length == 0)
{
tmp.push('/>');
}
else
{
tmp.push('>');
tmp.push(node.innerHTML);
tmp.push('</'+node.nodeName+'>');
}
return tmp.join('');
}
}
return '';
};
}
else
{
return function(node)
{
if (node != null)
{
var serializer = new XMLSerializer();
return serializer.serializeToString(node);
}
return '';
};
}
}(),
write: function(parent, text)
{
var doc = parent.ownerDocument;
var node = doc.createTextNode(text);
if (parent != null)
{
parent.appendChild(node);
}
return node;
},
writeln: function(parent, text)
{
var doc = parent.ownerDocument;
var node = doc.createTextNode(text);
if (parent != null)
{
parent.appendChild(node);
parent.appendChild(document.createElement('br'));
}
return node;
},
br: function(parent, count)
{
count = count || 1;
var br = null;
for (var i = 0; i < count; i++)
{
if (parent != null)
{
br = parent.ownerDocument.createElement('br');
parent.appendChild(br);
}
}
return br;
},
button: function(label, funct, doc)
{
doc = (doc != null) ? doc : document;
var button = doc.createElement('button');
mxUtils.write(button, label);
mxEvent.addListener(button, 'click', function(evt)
{
funct(evt);
});
return button;
},
para: function(parent, text)
{
var p = document.createElement('p');
mxUtils.write(p, text);
if (parent != null)
{
parent.appendChild(p);
}
return p;
},
addTransparentBackgroundFilter: function(node)
{
node.style.filter += 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' +
mxClient.imageBasePath + '/transparent.gif\', sizingMethod=\'scale\')';
},
linkAction: function(parent, text, editor, action, pad)
{
return mxUtils.link(parent, text, function()
{
editor.execute(action);
}, pad);
},
linkInvoke: function(parent, text, editor, functName, arg, pad)
{
return mxUtils.link(parent, text, function()
{
editor[functName](arg);
}, pad);
},
link: function(parent, text, funct, pad)
{
var a = document.createElement('span');
a.style.color = 'blue';
a.style.textDecoration = 'underline';
a.style.cursor = 'pointer';
if (pad != null)
{
a.style.paddingLeft = pad+'px';
}
mxEvent.addListener(a, 'click', funct);
mxUtils.write(a, text);
if (parent != null)
{
parent.appendChild(a);
}
return a;
},
getDocumentSize: function()
{
var b = document.body;
var d = document.documentElement;
try
{
return new mxRectangle(0, 0, b.clientWidth || d.clientWidth, Math.max(b.clientHeight || 0, d.clientHeight));
}
catch (e)
{
return new mxRectangle();
}
},
fit: function(node)
{
var ds = mxUtils.getDocumentSize();
var left = parseInt(node.offsetLeft);
var width = parseInt(node.offsetWidth);
var offset = mxUtils.getDocumentScrollOrigin(node.ownerDocument);
var sl = offset.x;
var st = offset.y;
var right = (sl) + ds.width;
if (left + width > right)
{
node.style.left = Math.max(sl, right - width) + 'px';
}
var top = parseInt(node.offsetTop);
var height = parseInt(node.offsetHeight);
var bottom = st + ds.height;
if (top + height > bottom)
{
node.style.top = Math.max(st, bottom - height) + 'px';
}
},
load: function(url)
{
var req = new mxXmlRequest(url, null, 'GET', false);
req.send();
return req;
},
get: function(url, onload, onerror, binary, timeout, ontimeout, headers)
{
var req = new mxXmlRequest(url, null, 'GET');
var setRequestHeaders = req.setRequestHeaders;
if (headers)
{
req.setRequestHeaders = function(request, params)
{
setRequestHeaders.apply(this, arguments);
for (var key in headers)
{
request.setRequestHeader(key, headers[key]);
}
};
}
if (binary != null)
{
req.setBinary(binary);
}
req.send(onload, onerror, timeout, ontimeout);
return req;
},
getAll: function(urls, onload, onerror)
{
var remain = urls.length;
var result = [];
var errors = 0;
var err = function()
{
if (errors == 0 && onerror != null)
{
onerror();
}
errors++;
};
for (var i = 0; i < urls.length; i++)
{
(function(url, index)
{
mxUtils.get(url, function(req)
{
var status = req.getStatus();
if (status < 200 || status > 299)
{
err();
}
else
{
result[index] = req;
remain--;
if (remain == 0)
{
onload(result);
}
}
}, err);
})(urls[i], i);
}
if (remain == 0)
{
onload(result);
}
},
post: function(url, params, onload, onerror)
{
return new mxXmlRequest(url, params).send(onload, onerror);
},
submit: function(url, params, doc, target)
{
return new mxXmlRequest(url, params).simulate(doc, target);
},
loadInto: function(url, doc, onload)
{
if (mxClient.IS_IE)
{
doc.onreadystatechange = function ()
{
if (doc.readyState == 4)
{
onload();
}
};
}
else
{
doc.addEventListener('load', onload, false);
}
doc.load(url);
},
getValue: function(array, key, defaultValue)
{
var value = (array != null) ? array[key] : null;
if (value == null)
{
value = defaultValue;
}
return value;
},
getNumber: function(array, key, defaultValue)
{
var value = (array != null) ? array[key] : null;
if (value == null)
{
value = defaultValue || 0;
}
return Number(value);
},
getColor: function(array, key, defaultValue)
{
var value = (array != null) ? array[key] : null;
if (value == null)
{
value = defaultValue;
}
else if (value == mxConstants.NONE)
{
value = null;
}
return value;
},
clone: function(obj, transients, shallow)
{
shallow = (shallow != null) ? shallow : false;
var clone = null;
if (obj != null && typeof(obj.constructor) == 'function')
{
clone = new obj.constructor();
for (var i in obj)
{
if (i != mxObjectIdentity.FIELD_NAME && (transients == null ||
mxUtils.indexOf(transients, i) < 0))
{
if (!shallow && typeof(obj[i]) == 'object')
{
clone[i] = mxUtils.clone(obj[i]);
}
else
{
clone[i] = obj[i];
}
}
}
}
return clone;
},
equalPoints: function(a, b)
{
if ((a == null && b != null) || (a != null && b == null) ||
(a != null && b != null && a.length != b.length))
{
return false;
}
else if (a != null && b != null)
{
for (var i = 0; i < a.length; i++)
{
if ((a[i] != null && b[i] == null) ||
(a[i] == null && b[i] != null) ||
(a[i] != null && b[i] != null &&
(a[i].x != b[i].x || a[i].y != b[i].y)))
{
return false;
}
}
}
return true;
},
equalEntries: function(a, b)
{
var count = 0;
if ((a == null && b != null) || (a != null && b == null) ||
(a != null && b != null && a.length != b.length))
{
return false;
}
else if (a != null && b != null)
{
for (var key in b)
{
count++;
}
for (var key in a)
{
count--;
if ((!mxUtils.isNaN(a[key]) || !mxUtils.isNaN(b[key])) && a[key] != b[key])
{
return false;
}
}
}
return count == 0;
},
removeDuplicates: function(arr)
{
var dict = new mxDictionary();
var result = [];
for (var i = 0; i < arr.length; i++)
{
if (!dict.get(arr[i]))
{
result.push(arr[i]);
dict.put(arr[i], true);
}
}
return result;
},
isNaN: function(value)
{
return typeof(value) == 'number' && isNaN(value);
},
extend: function(ctor, superCtor)
{
var f = function() {};
f.prototype = superCtor.prototype;
ctor.prototype = new f();
ctor.prototype.constructor = ctor;
},
toString: function(obj)
{
var output = '';
for (var i in obj)
{
try
{
if (obj[i] == null)
{
output += i + ' = [null]\n';
}
else if (typeof(obj[i]) == 'function')
{
output += i + ' => [Function]\n';
}
else if (typeof(obj[i]) == 'object')
{
var ctor = mxUtils.getFunctionName(obj[i].constructor);
output += i + ' => [' + ctor + ']\n';
}
else
{
output += i + ' = ' + obj[i] + '\n';
}
}
catch (e)
{
output += i + '=' + e.message;
}
}
return output;
},
toRadians: function(deg)
{
return Math.PI * deg / 180;
},
toDegree: function(rad)
{
return rad * 180 / Math.PI;
},
arcToCurves: function(x0, y0, r1, r2, angle, largeArcFlag, sweepFlag, x, y)
{
x -= x0;
y -= y0;
if (r1 === 0 || r2 === 0)
{
return result;
}
var fS = sweepFlag;
var psai = angle;
r1 = Math.abs(r1);
r2 = Math.abs(r2);
var ctx = -x / 2;
var cty = -y / 2;
var cpsi = Math.cos(psai * Math.PI / 180);
var spsi = Math.sin(psai * Math.PI / 180);
var rxd = cpsi * ctx + spsi * cty;
var ryd = -1 * spsi * ctx + cpsi * cty;
var rxdd = rxd * rxd;
var rydd = ryd * ryd;
var r1x = r1 * r1;
var r2y = r2 * r2;
var lamda = rxdd / r1x + rydd / r2y;
var sds;
if (lamda > 1)
{
r1 = Math.sqrt(lamda) * r1;
r2 = Math.sqrt(lamda) * r2;
sds = 0;
}
else
{
var seif = 1;
if (largeArcFlag === fS)
{
seif = -1;
}
sds = seif * Math.sqrt((r1x * r2y - r1x * rydd - r2y * rxdd) / (r1x * rydd + r2y * rxdd));
}
var txd = sds * r1 * ryd / r2;
var tyd = -1 * sds * r2 * rxd / r1;
var tx = cpsi * txd - spsi * tyd + x / 2;
var ty = spsi * txd + cpsi * tyd + y / 2;
var rad = Math.atan2((ryd - tyd) / r2, (rxd - txd) / r1) - Math.atan2(0, 1);
var s1 = (rad >= 0) ? rad : 2 * Math.PI + rad;
rad = Math.atan2((-ryd - tyd) / r2, (-rxd - txd) / r1) - Math.atan2((ryd - tyd) / r2, (rxd - txd) / r1);
var dr = (rad >= 0) ? rad : 2 * Math.PI + rad;
if (fS == 0 && dr > 0)
{
dr -= 2 * Math.PI;
}
else if (fS != 0 && dr < 0)
{
dr += 2 * Math.PI;
}
var sse = dr * 2 / Math.PI;
var seg = Math.ceil(sse < 0 ? -1 * sse : sse);
var segr = dr / seg;
var t = 8/3 * Math.sin(segr / 4) * Math.sin(segr / 4) / Math.sin(segr / 2);
var cpsir1 = cpsi * r1;
var cpsir2 = cpsi * r2;
var spsir1 = spsi * r1;
var spsir2 = spsi * r2;
var mc = Math.cos(s1);
var ms = Math.sin(s1);
var x2 = -t * (cpsir1 * ms + spsir2 * mc);
var y2 = -t * (spsir1 * ms - cpsir2 * mc);
var x3 = 0;
var y3 = 0;
var result = [];
for (var n = 0; n < seg; ++n)
{
s1 += segr;
mc = Math.cos(s1);
ms = Math.sin(s1);
x3 = cpsir1 * mc - spsir2 * ms + tx;
y3 = spsir1 * mc + cpsir2 * ms + ty;
var dx = -t * (cpsir1 * ms + spsir2 * mc);
var dy = -t * (spsir1 * ms - cpsir2 * mc);
var index = n * 6;
result[index] = Number(x2 + x0);
result[index + 1] = Number(y2 + y0);
result[index + 2] = Number(x3 - dx + x0);
result[index + 3] = Number(y3 - dy + y0);
result[index + 4] = Number(x3 + x0);
result[index + 5] = Number(y3 + y0);
x2 = x3 + dx;
y2 = y3 + dy;
}
return result;
},
getBoundingBox: function(rect, rotation, cx)
{
var result = null;
if (rect != null && rotation != null && rotation != 0)
{
var rad = mxUtils.toRadians(rotation);
var cos = Math.cos(rad);
var sin = Math.sin(rad);
cx = (cx != null) ? cx : new mxPoint(rect.x + rect.width / 2, rect.y + rect.height / 2);
var p1 = new mxPoint(rect.x, rect.y);
var p2 = new mxPoint(rect.x + rect.width, rect.y);
var p3 = new mxPoint(p2.x, rect.y + rect.height);
var p4 = new mxPoint(rect.x, p3.y);
p1 = mxUtils.getRotatedPoint(p1, cos, sin, cx);
p2 = mxUtils.getRotatedPoint(p2, cos, sin, cx);
p3 = mxUtils.getRotatedPoint(p3, cos, sin, cx);
p4 = mxUtils.getRotatedPoint(p4, cos, sin, cx);
result = new mxRectangle(p1.x, p1.y, 0, 0);
result.add(new mxRectangle(p2.x, p2.y, 0, 0));
result.add(new mxRectangle(p3.x, p3.y, 0, 0));
result.add(new mxRectangle(p4.x, p4.y, 0, 0));
}
return result;
},
getRotatedPoint: function(pt, cos, sin, c)
{
c = (c != null) ? c : new mxPoint();
var x = pt.x - c.x;
var y = pt.y - c.y;
var x1 = x * cos - y * sin;
var y1 = y * cos + x * sin;
return new mxPoint(x1 + c.x, y1 + c.y);
},
getPortConstraints: function(terminal, edge, source, defaultValue)
{
var value = mxUtils.getValue(terminal.style, mxConstants.STYLE_PORT_CONSTRAINT,
mxUtils.getValue(edge.style, (source) ? mxConstants.STYLE_SOURCE_PORT_CONSTRAINT :
mxConstants.STYLE_TARGET_PORT_CONSTRAINT, null));
if (value == null)
{
return defaultValue;
}
else
{
var directions = value.toString();
var returnValue = mxConstants.DIRECTION_MASK_NONE;
var constraintRotationEnabled = mxUtils.getValue(terminal.style, mxConstants.STYLE_PORT_CONSTRAINT_ROTATION, 0);
var rotation = 0;
if (constraintRotationEnabled == 1)
{
rotation = mxUtils.getValue(terminal.style, mxConstants.STYLE_ROTATION, 0);
}
var quad = 0;
if (rotation > 45)
{
quad = 1;
if (rotation >= 135)
{
quad = 2;
}
}
else if (rotation < -45)
{
quad = 3;
if (rotation <= -135)
{
quad = 2;
}
}
if (directions.indexOf(mxConstants.DIRECTION_NORTH) >= 0)
{
switch (quad)
{
case 0:
returnValue |= mxConstants.DIRECTION_MASK_NORTH;
break;
case 1:
returnValue |= mxConstants.DIRECTION_MASK_EAST;
break;
case 2:
returnValue |= mxConstants.DIRECTION_MASK_SOUTH;
break;
case 3:
returnValue |= mxConstants.DIRECTION_MASK_WEST;
break;
}
}
if (directions.indexOf(mxConstants.DIRECTION_WEST) >= 0)
{
switch (quad)
{
case 0:
returnValue |= mxConstants.DIRECTION_MASK_WEST;
break;
case 1:
returnValue |= mxConstants.DIRECTION_MASK_NORTH;
break;
case 2:
returnValue |= mxConstants.DIRECTION_MASK_EAST;
break;
case 3:
returnValue |= mxConstants.DIRECTION_MASK_SOUTH;
break;
}
}
if (directions.indexOf(mxConstants.DIRECTION_SOUTH) >= 0)
{
switch (quad)
{
case 0:
returnValue |= mxConstants.DIRECTION_MASK_SOUTH;
break;
case 1:
returnValue |= mxConstants.DIRECTION_MASK_WEST;
break;
case 2:
returnValue |= mxConstants.DIRECTION_MASK_NORTH;
break;
case 3:
returnValue |= mxConstants.DIRECTION_MASK_EAST;
break;
}
}
if (directions.indexOf(mxConstants.DIRECTION_EAST) >= 0)
{
switch (quad)
{
case 0:
returnValue |= mxConstants.DIRECTION_MASK_EAST;
break;
case 1:
returnValue |= mxConstants.DIRECTION_MASK_SOUTH;
break;
case 2:
returnValue |= mxConstants.DIRECTION_MASK_WEST;
break;
case 3:
returnValue |= mxConstants.DIRECTION_MASK_NORTH;
break;
}
}
return returnValue;
}
},
reversePortConstraints: function(constraint)
{
var result = 0;
result = (constraint & mxConstants.DIRECTION_MASK_WEST) << 3;
result |= (constraint & mxConstants.DIRECTION_MASK_NORTH) << 1;
result |= (constraint & mxConstants.DIRECTION_MASK_SOUTH) >> 1;
result |= (constraint & mxConstants.DIRECTION_MASK_EAST) >> 3;
return result;
},
findNearestSegment: function(state, x, y)
{
var index = -1;
if (state.absolutePoints.length > 0)
{
var last = state.absolutePoints[0];
var min = null;
for (var i = 1; i < state.absolutePoints.length; i++)
{
var current = state.absolutePoints[i];
var dist = mxUtils.ptSegDistSq(last.x, last.y,
current.x, current.y, x, y);
if (min == null || dist < min)
{
min = dist;
index = i - 1;
}
last = current;
}
}
return index;
},
getDirectedBounds: function (rect, m, style, flipH, flipV)
{
var d = mxUtils.getValue(style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
flipH = (flipH != null) ? flipH : mxUtils.getValue(style, mxConstants.STYLE_FLIPH, false);
flipV = (flipV != null) ? flipV : mxUtils.getValue(style, mxConstants.STYLE_FLIPV, false);
m.x = Math.round(Math.max(0, Math.min(rect.width, m.x)));
m.y = Math.round(Math.max(0, Math.min(rect.height, m.y)));
m.width = Math.round(Math.max(0, Math.min(rect.width, m.width)));
m.height = Math.round(Math.max(0, Math.min(rect.height, m.height)));
if ((flipV && (d == mxConstants.DIRECTION_SOUTH || d == mxConstants.DIRECTION_NORTH)) ||
(flipH && (d == mxConstants.DIRECTION_EAST || d == mxConstants.DIRECTION_WEST)))
{
var tmp = m.x;
m.x = m.width;
m.width = tmp;
}
if ((flipH && (d == mxConstants.DIRECTION_SOUTH || d == mxConstants.DIRECTION_NORTH)) ||
(flipV && (d == mxConstants.DIRECTION_EAST || d == mxConstants.DIRECTION_WEST)))
{
var tmp = m.y;
m.y = m.height;
m.height = tmp;
}
var m2 = mxRectangle.fromRectangle(m);
if (d == mxConstants.DIRECTION_SOUTH)
{
m2.y = m.x;
m2.x = m.height;
m2.width = m.y;
m2.height = m.width;
}
else if (d == mxConstants.DIRECTION_WEST)
{
m2.y = m.height;
m2.x = m.width;
m2.width = m.x;
m2.height = m.y;
}
else if (d == mxConstants.DIRECTION_NORTH)
{
m2.y = m.width;
m2.x = m.y;
m2.width = m.height;
m2.height = m.x;
}
return new mxRectangle(rect.x + m2.x, rect.y + m2.y, rect.width - m2.width - m2.x, rect.height - m2.height - m2.y);
},
getPerimeterPoint: function (pts, center, point)
{
var min = null;
for (var i = 0; i < pts.length - 1; i++)
{
var pt = mxUtils.intersection(pts[i].x, pts[i].y, pts[i + 1].x, pts[i + 1].y,
center.x, center.y, point.x, point.y);
if (pt != null)
{
var dx = point.x - pt.x;
var dy = point.y - pt.y;
var ip = {p: pt, distSq: dy * dy + dx * dx};
if (ip != null && (min == null || min.distSq > ip.distSq))
{
min = ip;
}
}
}
return (min != null) ? min.p : null;
},
rectangleIntersectsSegment: function(bounds, p1, p2)
{
var top = bounds.y;
var left = bounds.x;
var bottom = top + bounds.height;
var right = left + bounds.width;
var minX = p1.x;
var maxX = p2.x;
if (p1.x > p2.x)
{
minX = p2.x;
maxX = p1.x;
}
if (maxX > right)
{
maxX = right;
}
if (minX < left)
{
minX = left;
}
if (minX > maxX)
{
return false;
}
var minY = p1.y;
var maxY = p2.y;
var dx = p2.x - p1.x;
if (Math.abs(dx) > 0.0000001)
{
var a = (p2.y - p1.y) / dx;
var b = p1.y - a * p1.x;
minY = a * minX + b;
maxY = a * maxX + b;
}
if (minY > maxY)
{
var tmp = maxY;
maxY = minY;
minY = tmp;
}
if (maxY > bottom)
{
maxY = bottom;
}
if (minY < top)
{
minY = top;
}
if (minY > maxY)
{
return false;
}
return true;
},
contains: function(bounds, x, y)
{
return (bounds.x <= x && bounds.x + bounds.width >= x &&
bounds.y <= y && bounds.y + bounds.height >= y);
},
intersects: function(a, b)
{
var tw = a.width;
var th = a.height;
var rw = b.width;
var rh = b.height;
if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0)
{
return false;
}
var tx = a.x;
var ty = a.y;
var rx = b.x;
var ry = b.y;
rw += rx;
rh += ry;
tw += tx;
th += ty;
return ((rw < rx || rw > tx) &&
(rh < ry || rh > ty) &&
(tw < tx || tw > rx) &&
(th < ty || th > ry));
},
intersectsHotspot: function(state, x, y, hotspot, min, max)
{
hotspot = (hotspot != null) ? hotspot : 1;
min = (min != null) ? min : 0;
max = (max != null) ? max : 0;
if (hotspot > 0)
{
var cx = state.getCenterX();
var cy = state.getCenterY();
var w = state.width;
var h = state.height;
var start = mxUtils.getValue(state.style, mxConstants.STYLE_STARTSIZE) * state.view.scale;
if (start > 0)
{
if (mxUtils.getValue(state.style, mxConstants.STYLE_HORIZONTAL, true))
{
cy = state.y + start / 2;
h = start;
}
else
{
cx = state.x + start / 2;
w = start;
}
}
w = Math.max(min, w * hotspot);
h = Math.max(min, h * hotspot);
if (max > 0)
{
w = Math.min(w, max);
h = Math.min(h, max);
}
var rect = new mxRectangle(cx - w / 2, cy - h / 2, w, h);
var alpha = mxUtils.toRadians(mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0);
if (alpha != 0)
{
var cos = Math.cos(-alpha);
var sin = Math.sin(-alpha);
var cx = new mxPoint(state.getCenterX(), state.getCenterY());
var pt = mxUtils.getRotatedPoint(new mxPoint(x, y), cos, sin, cx);
x = pt.x;
y = pt.y;
}
return mxUtils.contains(rect, x, y);
}
return true;
},
getOffset: function(container, scrollOffset)
{
var offsetLeft = 0;
var offsetTop = 0;
var fixed = false;
var node = container;
var b = document.body;
var d = document.documentElement;
while (node != null && node != b && node != d && !fixed)
{
var style = mxUtils.getCurrentStyle(node);
if (style != null)
{
fixed = fixed || style.position == 'fixed';
}
node = node.parentNode;
}
if (!scrollOffset && !fixed)
{
var offset = mxUtils.getDocumentScrollOrigin(container.ownerDocument);
offsetLeft += offset.x;
offsetTop += offset.y;
}
var r = container.getBoundingClientRect();
if (r != null)
{
offsetLeft += r.left;
offsetTop += r.top;
}
return new mxPoint(offsetLeft, offsetTop);
},
getDocumentScrollOrigin: function(doc)
{
if (mxClient.IS_QUIRKS)
{
return new mxPoint(doc.body.scrollLeft, doc.body.scrollTop);
}
else
{
var wnd = doc.defaultView || doc.parentWindow;
var x = (wnd != null && window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
var y = (wnd != null && window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
return new mxPoint(x, y);
}
},
getScrollOrigin: function(node, includeAncestors, includeDocument)
{
includeAncestors = (includeAncestors != null) ? includeAncestors : false;
includeDocument = (includeDocument != null) ? includeDocument : true;
var doc = (node != null) ? node.ownerDocument : document;
var b = doc.body;
var d = doc.documentElement;
var result = new mxPoint();
var fixed = false;
while (node != null && node != b && node != d)
{
if (!isNaN(node.scrollLeft) && !isNaN(node.scrollTop))
{
result.x += node.scrollLeft;
result.y += node.scrollTop;
}
var style = mxUtils.getCurrentStyle(node);
if (style != null)
{
fixed = fixed || style.position == 'fixed';
}
node = (includeAncestors) ? node.parentNode : null;
}
if (!fixed && includeDocument)
{
var origin = mxUtils.getDocumentScrollOrigin(doc);
result.x += origin.x;
result.y += origin.y;
}
return result;
},
convertPoint: function(container, x, y)
{
var origin = mxUtils.getScrollOrigin(container, false);
var offset = mxUtils.getOffset(container);
offset.x -= origin.x;
offset.y -= origin.y;
return new mxPoint(x - offset.x, y - offset.y);
},
ltrim: function(str, chars)
{
chars = chars || "\\s";
return (str != null) ? str.replace(new RegExp("^[" + chars + "]+", "g"), "") : null;
},
rtrim: function(str, chars)
{
chars = chars || "\\s";
return (str != null) ? str.replace(new RegExp("[" + chars + "]+$", "g"), "") : null;
},
trim: function(str, chars)
{
return mxUtils.ltrim(mxUtils.rtrim(str, chars), chars);
},
isNumeric: function(n)
{
return !isNaN(parseFloat(n)) && isFinite(n) && (typeof(n) != 'string' || n.toLowerCase().indexOf('0x') < 0);
},
isInteger: function(n)
{
return String(parseInt(n)) === String(n);
},
mod: function(n, m)
{
return ((n % m) + m) % m;
},
intersection: function (x0, y0, x1, y1, x2, y2, x3, y3)
{
var denom = ((y3 - y2) * (x1 - x0)) - ((x3 - x2) * (y1 - y0));
var nume_a = ((x3 - x2) * (y0 - y2)) - ((y3 - y2) * (x0 - x2));
var nume_b = ((x1 - x0) * (y0 - y2)) - ((y1 - y0) * (x0 - x2));
var ua = nume_a / denom;
var ub = nume_b / denom;
if(ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0)
{
var x = x0 + ua * (x1 - x0);
var y = y0 + ua * (y1 - y0);
return new mxPoint(x, y);
}
return null;
},
ptSegDistSq: function(x1, y1, x2, y2, px, py)
{
x2 -= x1;
y2 -= y1;
px -= x1;
py -= y1;
var dotprod = px * x2 + py * y2;
var projlenSq;
if (dotprod <= 0.0)
{
projlenSq = 0.0;
}
else
{
px = x2 - px;
py = y2 - py;
dotprod = px * x2 + py * y2;
if (dotprod <= 0.0)
{
projlenSq = 0.0;
}
else
{
projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2);
}
}
var lenSq = px * px + py * py - projlenSq;
if (lenSq < 0)
{
lenSq = 0;
}
return lenSq;
},
ptLineDist: function(x1, y1, x2, y2, px, py)
{
return Math.abs((y2 - y1) * px - (x2 - x1) * py + x2 * y1 - y2 * x1) /
Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
},
relativeCcw: function(x1, y1, x2, y2, px, py)
{
x2 -= x1;
y2 -= y1;
px -= x1;
py -= y1;
var ccw = px * y2 - py * x2;
if (ccw == 0.0)
{
ccw = px * x2 + py * y2;
if (ccw > 0.0)
{
px -= x2;
py -= y2;
ccw = px * x2 + py * y2;
if (ccw < 0.0)
{
ccw = 0.0;
}
}
}
return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
},
animateChanges: function(graph, changes)
{
mxEffects.animateChanges.apply(this, arguments);
},
cascadeOpacity: function(graph, cell, opacity)
{
mxEffects.cascadeOpacity.apply(this, arguments);
},
fadeOut: function(node, from, remove, step, delay, isEnabled)
{
mxEffects.fadeOut.apply(this, arguments);
},
setOpacity: function(node, value)
{
if (mxUtils.isVml(node))
{
if (value >= 100)
{
node.style.filter = '';
}
else
{
node.style.filter = 'alpha(opacity=' + (value/5) + ')';
}
}
else if (mxClient.IS_IE && (typeof(document.documentMode) === 'undefined' || document.documentMode < 9))
{
if (value >= 100)
{
node.style.filter = '';
}
else
{
node.style.filter = 'alpha(opacity=' + value + ')';
}
}
else
{
node.style.opacity = (value / 100);
}
},
createImage: function(src)
{
var imageNode = null;
if (mxClient.IS_IE6 && document.compatMode != 'CSS1Compat')
{
imageNode = document.createElement(mxClient.VML_PREFIX + ':image');
imageNode.setAttribute('src', src);
imageNode.style.borderStyle = 'none';
}
else
{
imageNode = document.createElement('img');
imageNode.setAttribute('src', src);
imageNode.setAttribute('border', '0');
}
return imageNode;
},
sortCells: function(cells, ascending)
{
ascending = (ascending != null) ? ascending : true;
var lookup = new mxDictionary();
cells.sort(function(o1, o2)
{
var p1 = lookup.get(o1);
if (p1 == null)
{
p1 = mxCellPath.create(o1).split(mxCellPath.PATH_SEPARATOR);
lookup.put(o1, p1);
}
var p2 = lookup.get(o2);
if (p2 == null)
{
p2 = mxCellPath.create(o2).split(mxCellPath.PATH_SEPARATOR);
lookup.put(o2, p2);
}
var comp = mxCellPath.compare(p1, p2);
return (comp == 0) ? 0 : (((comp > 0) == ascending) ? 1 : -1);
});
return cells;
},
getStylename: function(style)
{
if (style != null)
{
var pairs = style.split(';');
var stylename = pairs[0];
if (stylename.indexOf('=') < 0)
{
return stylename;
}
}
return '';
},
getStylenames: function(style)
{
var result = [];
if (style != null)
{
var pairs = style.split(';');
for (var i = 0; i < pairs.length; i++)
{
if (pairs[i].indexOf('=') < 0)
{
result.push(pairs[i]);
}
}
}
return result;
},
indexOfStylename: function(style, stylename)
{
if (style != null && stylename != null)
{
var tokens = style.split(';');
var pos = 0;
for (var i = 0; i < tokens.length; i++)
{
if (tokens[i] == stylename)
{
return pos;
}
pos += tokens[i].length + 1;
}
}
return -1;
},
addStylename: function(style, stylename)
{
if (mxUtils.indexOfStylename(style, stylename) < 0)
{
if (style == null)
{
style = '';
}
else if (style.length > 0 && style.charAt(style.length - 1) != ';')
{
style += ';';
}
style += stylename;
}
return style;
},
removeStylename: function(style, stylename)
{
var result = [];
if (style != null)
{
var tokens = style.split(';');
for (var i = 0; i < tokens.length; i++)
{
if (tokens[i] != stylename)
{
result.push(tokens[i]);
}
}
}
return result.join(';');
},
removeAllStylenames: function(style)
{
var result = [];
if (style != null)
{
var tokens = style.split(';');
for (var i = 0; i < tokens.length; i++)
{
if (tokens[i].indexOf('=') >= 0)
{
result.push(tokens[i]);
}
}
}
return result.join(';');
},
setCellStyles: function(model, cells, key, value)
{
if (cells != null && cells.length > 0)
{
model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
if (cells[i] != null)
{
var style = mxUtils.setStyle(model.getStyle(cells[i]), key, value);
model.setStyle(cells[i], style);
}
}
}
finally
{
model.endUpdate();
}
}
},
setStyle: function(style, key, value)
{
var isValue = value != null && (typeof(value.length) == 'undefined' || value.length > 0);
if (style == null || style.length == 0)
{
if (isValue)
{
style = key + '=' + value + ';';
}
}
else
{
if (style.substring(0, key.length + 1) == key + '=')
{
var next = style.indexOf(';');
if (isValue)
{
style = key + '=' + value + ((next < 0) ? ';' : style.substring(next));
}
else
{
style = (next < 0 || next == style.length - 1) ? '' : style.substring(next + 1);
}
}
else
{
var index = style.indexOf(';' + key + '=');
if (index < 0)
{
if (isValue)
{
var sep = (style.charAt(style.length - 1) == ';') ? '' : ';';
style = style + sep + key + '=' + value + ';';
}
}
else
{
var next = style.indexOf(';', index + 1);
if (isValue)
{
style = style.substring(0, index + 1) + key + '=' + value + ((next < 0) ? ';' : style.substring(next));
}
else
{
style = style.substring(0, index) + ((next < 0) ? ';' : style.substring(next));
}
}
}
}
return style;
},
setCellStyleFlags: function(model, cells, key, flag, value)
{
if (cells != null && cells.length > 0)
{
model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
if (cells[i] != null)
{
var style = mxUtils.setStyleFlag(
model.getStyle(cells[i]),
key, flag, value);
model.setStyle(cells[i], style);
}
}
}
finally
{
model.endUpdate();
}
}
},
setStyleFlag: function(style, key, flag, value)
{
if (style == null || style.length == 0)
{
if (value || value == null)
{
style = key+'='+flag;
}
else
{
style = key+'=0';
}
}
else
{
var index = style.indexOf(key+'=');
if (index < 0)
{
var sep = (style.charAt(style.length-1) == ';') ? '' : ';';
if (value || value == null)
{
style = style + sep + key + '=' + flag;
}
else
{
style = style + sep + key + '=0';
}
}
else
{
var cont = style.indexOf(';', index);
var tmp = '';
if (cont < 0)
{
tmp = style.substring(index+key.length+1);
}
else
{
tmp = style.substring(index+key.length+1, cont);
}
if (value == null)
{
tmp = parseInt(tmp) ^ flag;
}
else if (value)
{
tmp = parseInt(tmp) | flag;
}
else
{
tmp = parseInt(tmp) & ~flag;
}
style = style.substring(0, index) + key + '=' + tmp +
((cont >= 0) ? style.substring(cont) : '');
}
}
return style;
},
getAlignmentAsPoint: function(align, valign)
{
var dx = -0.5;
var dy = -0.5;
if (align == mxConstants.ALIGN_LEFT)
{
dx = 0;
}
else if (align == mxConstants.ALIGN_RIGHT)
{
dx = -1;
}
if (valign == mxConstants.ALIGN_TOP)
{
dy = 0;
}
else if (valign == mxConstants.ALIGN_BOTTOM)
{
dy = -1;
}
return new mxPoint(dx, dy);
},
getSizeForString: function(text, fontSize, fontFamily, textWidth, fontStyle)
{
fontSize = (fontSize != null) ? fontSize : mxConstants.DEFAULT_FONTSIZE;
fontFamily = (fontFamily != null) ? fontFamily : mxConstants.DEFAULT_FONTFAMILY;
var div = document.createElement('div');
div.style.fontFamily = fontFamily;
div.style.fontSize = Math.round(fontSize) + 'px';
div.style.lineHeight = Math.round(fontSize * mxConstants.LINE_HEIGHT) + 'px';
if (fontStyle != null)
{
if ((fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
{
div.style.fontWeight = 'bold';
}
if ((fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
{
div.style.fontStyle = 'italic';
}
var txtDecor = [];
if ((fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
{
txtDecor.push('underline');
}
if ((fontStyle & mxConstants.FONT_STRIKETHROUGH) == mxConstants.FONT_STRIKETHROUGH)
{
txtDecor.push('line-through');
}
if (txtDecor.length > 0)
{
div.style.textDecoration = txtDecor.join(' ');
}
}
div.style.position = 'absolute';
div.style.visibility = 'hidden';
div.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
div.style.zoom = '1';
if (textWidth != null)
{
div.style.width = textWidth + 'px';
div.style.whiteSpace = 'normal';
}
else
{
div.style.whiteSpace = 'nowrap';
}
div.innerHTML = text;
document.body.appendChild(div);
var size = new mxRectangle(0, 0, div.offsetWidth, div.offsetHeight);
document.body.removeChild(div);
return size;
},
getViewXml: function(graph, scale, cells, x0, y0)
{
x0 = (x0 != null) ? x0 : 0;
y0 = (y0 != null) ? y0 : 0;
scale = (scale != null) ? scale : 1;
if (cells == null)
{
var model = graph.getModel();
cells = [model.getRoot()];
}
var view = graph.getView();
var result = null;
var eventsEnabled = view.isEventsEnabled();
view.setEventsEnabled(false);
var drawPane = view.drawPane;
var overlayPane = view.overlayPane;
if (graph.dialect == mxConstants.DIALECT_SVG)
{
view.drawPane = document.createElementNS(mxConstants.NS_SVG, 'g');
view.canvas.appendChild(view.drawPane);
view.overlayPane = document.createElementNS(mxConstants.NS_SVG, 'g');
view.canvas.appendChild(view.overlayPane);
}
else
{
view.drawPane = view.drawPane.cloneNode(false);
view.canvas.appendChild(view.drawPane);
view.overlayPane = view.overlayPane.cloneNode(false);
view.canvas.appendChild(view.overlayPane);
}
var translate = view.getTranslate();
view.translate = new mxPoint(x0, y0);
var temp = new mxTemporaryCellStates(graph.getView(), scale, cells);
try
{
var enc = new mxCodec();
result = enc.encode(graph.getView());
}
finally
{
temp.destroy();
view.translate = translate;
view.canvas.removeChild(view.drawPane);
view.canvas.removeChild(view.overlayPane);
view.drawPane = drawPane;
view.overlayPane = overlayPane;
view.setEventsEnabled(eventsEnabled);
}
return result;
},
getScaleForPageCount: function(pageCount, graph, pageFormat, border)
{
if (pageCount < 1)
{
return 1;
}
pageFormat = (pageFormat != null) ? pageFormat : mxConstants.PAGE_FORMAT_A4_PORTRAIT;
border = (border != null) ? border : 0;
var availablePageWidth = pageFormat.width - (border * 2);
var availablePageHeight = pageFormat.height - (border * 2);
var graphBounds = graph.getGraphBounds().clone();
var sc = graph.getView().getScale();
graphBounds.width /= sc;
graphBounds.height /= sc;
var graphWidth = graphBounds.width;
var graphHeight = graphBounds.height;
var scale = 1;
var pageFormatAspectRatio = availablePageWidth / availablePageHeight;
var graphAspectRatio = graphWidth / graphHeight;
var pagesAspectRatio = graphAspectRatio / pageFormatAspectRatio;
var pageRoot = Math.sqrt(pageCount);
var pagesAspectRatioSqrt = Math.sqrt(pagesAspectRatio);
var numRowPages = pageRoot * pagesAspectRatioSqrt;
var numColumnPages = pageRoot / pagesAspectRatioSqrt;
if (numRowPages < 1 && numColumnPages > pageCount)
{
var scaleChange = numColumnPages / pageCount;
numColumnPages = pageCount;
numRowPages /= scaleChange;
}
if (numColumnPages < 1 && numRowPages > pageCount)
{
var scaleChange = numRowPages / pageCount;
numRowPages = pageCount;
numColumnPages /= scaleChange;
}
var currentTotalPages = Math.ceil(numRowPages) * Math.ceil(numColumnPages);
var numLoops = 0;
while (currentTotalPages > pageCount)
{
var roundRowDownProportion = Math.floor(numRowPages) / numRowPages;
var roundColumnDownProportion = Math.floor(numColumnPages) / numColumnPages;
if (roundRowDownProportion == 1)
{
roundRowDownProportion = Math.floor(numRowPages-1) / numRowPages;
}
if (roundColumnDownProportion == 1)
{
roundColumnDownProportion = Math.floor(numColumnPages-1) / numColumnPages;
}
var scaleChange = 1;
if (roundRowDownProportion > roundColumnDownProportion)
{
scaleChange = roundRowDownProportion;
}
else
{
scaleChange = roundColumnDownProportion;
}
numRowPages = numRowPages * scaleChange;
numColumnPages = numColumnPages * scaleChange;
currentTotalPages = Math.ceil(numRowPages) * Math.ceil(numColumnPages);
numLoops++;
if (numLoops > 10)
{
break;
}
}
var posterWidth = availablePageWidth * numRowPages;
scale = posterWidth / graphWidth;
return scale * 0.99999;
},
show: function(graph, doc, x0, y0, w, h)
{
x0 = (x0 != null) ? x0 : 0;
y0 = (y0 != null) ? y0 : 0;
if (doc == null)
{
var wnd = window.open();
doc = wnd.document;
}
else
{
doc.open();
}
if (document.documentMode == 9)
{
doc.writeln('<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=9"><![endif]-->');
}
var bounds = graph.getGraphBounds();
var dx = Math.ceil(x0 - bounds.x);
var dy = Math.ceil(y0 - bounds.y);
if (w == null)
{
w = Math.ceil(bounds.width + x0) + Math.ceil(Math.ceil(bounds.x) - bounds.x);
}
if (h == null)
{
h = Math.ceil(bounds.height + y0) + Math.ceil(Math.ceil(bounds.y) - bounds.y);
}
if (mxClient.IS_IE || document.documentMode == 11)
{
var html = '<html><head>';
var base = document.getElementsByTagName('base');
for (var i = 0; i < base.length; i++)
{
html += base[i].outerHTML;
}
html += '<style>';
for (var i = 0; i < document.styleSheets.length; i++)
{
try
{
html += document.styleSheets[i].cssText;
}
catch (e)
{
}
}
html += '</style></head><body style="margin:0px;">';
html += '<div style="position:absolute;overflow:hidden;width:' + w + 'px;height:' + h + 'px;"><div style="position:relative;left:' + dx + 'px;top:' + dy + 'px;">';
html += graph.container.innerHTML;
html += '</div></div></body><html>';
doc.writeln(html);
doc.close();
}
else
{
doc.writeln('<html><head>');
var base = document.getElementsByTagName('base');
for (var i = 0; i < base.length; i++)
{
doc.writeln(mxUtils.getOuterHtml(base[i]));
}
var links = document.getElementsByTagName('link');
for (var i = 0; i < links.length; i++)
{
doc.writeln(mxUtils.getOuterHtml(links[i]));
}
var styles = document.getElementsByTagName('style');
for (var i = 0; i < styles.length; i++)
{
doc.writeln(mxUtils.getOuterHtml(styles[i]));
}
doc.writeln('</head><body style="margin:0px;"></body></html>');
doc.close();
var outer = doc.createElement('div');
outer.position = 'absolute';
outer.overflow = 'hidden';
outer.style.width = w + 'px';
outer.style.height = h + 'px';
var div = doc.createElement('div');
div.style.position = 'absolute';
div.style.left = dx + 'px';
div.style.top = dy + 'px';
var node = graph.container.firstChild;
var svg = null;
while (node != null)
{
var clone = node.cloneNode(true);
if (node == graph.view.drawPane.ownerSVGElement)
{
outer.appendChild(clone);
svg = clone;
}
else
{
div.appendChild(clone);
}
node = node.nextSibling;
}
doc.body.appendChild(outer);
if (div.firstChild != null)
{
doc.body.appendChild(div);
}
if (svg != null)
{
svg.style.minWidth = '';
svg.style.minHeight = '';
svg.firstChild.setAttribute('transform', 'translate(' + dx + ',' + dy + ')');
}
}
mxUtils.removeCursors(doc.body);
return doc;
},
printScreen: function(graph)
{
var wnd = window.open();
graph.getGraphBounds();
mxUtils.show(graph, wnd.document);
var print = function()
{
wnd.focus();
wnd.print();
wnd.close();
};
if (mxClient.IS_GC)
{
wnd.setTimeout(print, 500);
}
else
{
print();
}
},
popup: function(content, isInternalWindow)
{
if (isInternalWindow)
{
var div = document.createElement('div');
div.style.overflow = 'scroll';
div.style.width = '636px';
div.style.height = '460px';
var pre = document.createElement('pre');
pre.innerHTML = mxUtils.htmlEntities(content, false).
replace(/\n/g,'<br>').replace(/ /g, ' ');
div.appendChild(pre);
var w = document.body.clientWidth;
var h = Math.max(document.body.clientHeight || 0, document.documentElement.clientHeight);
var wnd = new mxWindow('Popup Window', div,
w/2-320, h/2-240, 640, 480, false, true);
wnd.setClosable(true);
wnd.setVisible(true);
}
else
{
if (mxClient.IS_NS)
{
var wnd = window.open();
wnd.document.writeln('<pre>'+mxUtils.htmlEntities(content)+'</pre');
wnd.document.close();
}
else
{
var wnd = window.open();
var pre = wnd.document.createElement('pre');
pre.innerHTML = mxUtils.htmlEntities(content, false).
replace(/\n/g,'<br>').replace(/ /g, ' ');
wnd.document.body.appendChild(pre);
}
}
},
alert: function(message)
{
alert(message);
},
prompt: function(message, defaultValue)
{
return prompt(message, (defaultValue != null) ? defaultValue : '');
},
confirm: function(message)
{
return confirm(message);
},
error: function(message, width, close, icon)
{
var div = document.createElement('div');
div.style.padding = '20px';
var img = document.createElement('img');
img.setAttribute('src', icon || mxUtils.errorImage);
img.setAttribute('valign', 'bottom');
img.style.verticalAlign = 'middle';
div.appendChild(img);
div.appendChild(document.createTextNode('\u00a0'));
div.appendChild(document.createTextNode('\u00a0'));
div.appendChild(document.createTextNode('\u00a0'));
mxUtils.write(div, message);
var w = document.body.clientWidth;
var h = (document.body.clientHeight || document.documentElement.clientHeight);
var warn = new mxWindow(mxResources.get(mxUtils.errorResource) ||
mxUtils.errorResource, div, (w-width)/2, h/4, width, null,
false, true);
if (close)
{
mxUtils.br(div);
var tmp = document.createElement('p');
var button = document.createElement('button');
if (mxClient.IS_IE)
{
button.style.cssText = 'float:right';
}
else
{
button.setAttribute('style', 'float:right');
}
mxEvent.addListener(button, 'click', function(evt)
{
warn.destroy();
});
mxUtils.write(button, mxResources.get(mxUtils.closeResource) ||
mxUtils.closeResource);
tmp.appendChild(button);
div.appendChild(tmp);
mxUtils.br(div);
warn.setClosable(true);
}
warn.setVisible(true);
return warn;
},
makeDraggable: function(element, graphF, funct, dragElement, dx, dy, autoscroll,
scalePreview, highlightDropTargets, getDropTarget)
{
var dragSource = new mxDragSource(element, funct);
dragSource.dragOffset = new mxPoint((dx != null) ? dx : 0,
(dy != null) ? dy : mxConstants.TOOLTIP_VERTICAL_OFFSET);
dragSource.autoscroll = autoscroll;
dragSource.setGuidesEnabled(false);
if (highlightDropTargets != null)
{
dragSource.highlightDropTargets = highlightDropTargets;
}
if (getDropTarget != null)
{
dragSource.getDropTarget = getDropTarget;
}
dragSource.getGraphForEvent = function(evt)
{
return (typeof(graphF) == 'function') ? graphF(evt) : graphF;
};
if (dragElement != null)
{
dragSource.createDragElement = function()
{
return dragElement.cloneNode(true);
};
if (scalePreview)
{
dragSource.createPreviewElement = function(graph)
{
var elt = dragElement.cloneNode(true);
var w = parseInt(elt.style.width);
var h = parseInt(elt.style.height);
elt.style.width = Math.round(w * graph.view.scale) + 'px';
elt.style.height = Math.round(h * graph.view.scale) + 'px';
return elt;
};
}
}
return dragSource;
}
};
__mxOutput.mxUtils = typeof mxUtils !== 'undefined' ? mxUtils : undefined;
var mxConstants =
{
DEFAULT_HOTSPOT: 0.3,
MIN_HOTSPOT_SIZE: 8,
MAX_HOTSPOT_SIZE: 0,
RENDERING_HINT_EXACT: 'exact',
RENDERING_HINT_FASTER: 'faster',
RENDERING_HINT_FASTEST: 'fastest',
DIALECT_SVG: 'svg',
DIALECT_VML: 'vml',
DIALECT_MIXEDHTML: 'mixedHtml',
DIALECT_PREFERHTML: 'preferHtml',
DIALECT_STRICTHTML: 'strictHtml',
NS_SVG: 'http://www.w3.org/2000/svg',
NS_XHTML: 'http://www.w3.org/1999/xhtml',
NS_XLINK: 'http://www.w3.org/1999/xlink',
SHADOWCOLOR: 'gray',
VML_SHADOWCOLOR: 'gray',
SHADOW_OFFSET_X: 2,
SHADOW_OFFSET_Y: 3,
SHADOW_OPACITY: 1,
NODETYPE_ELEMENT: 1,
NODETYPE_ATTRIBUTE: 2,
NODETYPE_TEXT: 3,
NODETYPE_CDATA: 4,
NODETYPE_ENTITY_REFERENCE: 5,
NODETYPE_ENTITY: 6,
NODETYPE_PROCESSING_INSTRUCTION: 7,
NODETYPE_COMMENT: 8,
NODETYPE_DOCUMENT: 9,
NODETYPE_DOCUMENTTYPE: 10,
NODETYPE_DOCUMENT_FRAGMENT: 11,
NODETYPE_NOTATION: 12,
TOOLTIP_VERTICAL_OFFSET: 16,
DEFAULT_VALID_COLOR: '#00FF00',
DEFAULT_INVALID_COLOR: '#FF0000',
OUTLINE_HIGHLIGHT_COLOR: '#00FF00',
OUTLINE_HIGHLIGHT_STROKEWIDTH: 5,
HIGHLIGHT_STROKEWIDTH: 3,
HIGHLIGHT_SIZE: 2,
HIGHLIGHT_OPACITY: 100,
CURSOR_MOVABLE_VERTEX: 'move',
CURSOR_MOVABLE_EDGE: 'move',
CURSOR_LABEL_HANDLE: 'default',
CURSOR_TERMINAL_HANDLE: 'pointer',
CURSOR_BEND_HANDLE: 'crosshair',
CURSOR_VIRTUAL_BEND_HANDLE: 'crosshair',
CURSOR_CONNECT: 'pointer',
HIGHLIGHT_COLOR: '#00FF00',
CONNECT_TARGET_COLOR: '#0000FF',
INVALID_CONNECT_TARGET_COLOR: '#FF0000',
DROP_TARGET_COLOR: '#0000FF',
VALID_COLOR: '#00FF00',
INVALID_COLOR: '#FF0000',
EDGE_SELECTION_COLOR: '#00FF00',
VERTEX_SELECTION_COLOR: '#00FF00',
VERTEX_SELECTION_STROKEWIDTH: 1,
EDGE_SELECTION_STROKEWIDTH: 1,
VERTEX_SELECTION_DASHED: true,
EDGE_SELECTION_DASHED: true,
GUIDE_COLOR: '#FF0000',
GUIDE_STROKEWIDTH: 1,
OUTLINE_COLOR: '#0099FF',
OUTLINE_STROKEWIDTH: (mxClient.IS_IE) ? 2 : 3,
HANDLE_SIZE: 6,
LABEL_HANDLE_SIZE: 4,
HANDLE_FILLCOLOR: '#00FF00',
HANDLE_STROKECOLOR: 'black',
LABEL_HANDLE_FILLCOLOR: 'yellow',
CONNECT_HANDLE_FILLCOLOR: '#0000FF',
LOCKED_HANDLE_FILLCOLOR: '#FF0000',
OUTLINE_HANDLE_FILLCOLOR: '#00FFFF',
OUTLINE_HANDLE_STROKECOLOR: '#0033FF',
DEFAULT_FONTFAMILY: 'Arial,Helvetica',
DEFAULT_FONTSIZE: 11,
DEFAULT_TEXT_DIRECTION: '',
LINE_HEIGHT: 1.2,
WORD_WRAP: 'normal',
ABSOLUTE_LINE_HEIGHT: false,
DEFAULT_FONTSTYLE: 0,
DEFAULT_STARTSIZE: 40,
DEFAULT_MARKERSIZE: 6,
DEFAULT_IMAGESIZE: 24,
ENTITY_SEGMENT: 30,
RECTANGLE_ROUNDING_FACTOR: 0.15,
LINE_ARCSIZE: 20,
ARROW_SPACING: 0,
ARROW_WIDTH: 30,
ARROW_SIZE: 30,
PAGE_FORMAT_A4_PORTRAIT: new mxRectangle(0, 0, 827, 1169),
PAGE_FORMAT_A4_LANDSCAPE: new mxRectangle(0, 0, 1169, 827),
PAGE_FORMAT_LETTER_PORTRAIT: new mxRectangle(0, 0, 850, 1100),
PAGE_FORMAT_LETTER_LANDSCAPE: new mxRectangle(0, 0, 1100, 850),
NONE: 'none',
STYLE_PERIMETER: 'perimeter',
STYLE_SOURCE_PORT: 'sourcePort',
STYLE_TARGET_PORT: 'targetPort',
STYLE_PORT_CONSTRAINT: 'portConstraint',
STYLE_PORT_CONSTRAINT_ROTATION: 'portConstraintRotation',
STYLE_SOURCE_PORT_CONSTRAINT: 'sourcePortConstraint',
STYLE_TARGET_PORT_CONSTRAINT: 'targetPortConstraint',
STYLE_OPACITY: 'opacity',
STYLE_FILL_OPACITY: 'fillOpacity',
STYLE_STROKE_OPACITY: 'strokeOpacity',
STYLE_TEXT_OPACITY: 'textOpacity',
STYLE_TEXT_DIRECTION: 'textDirection',
STYLE_OVERFLOW: 'overflow',
STYLE_ORTHOGONAL: 'orthogonal',
STYLE_EXIT_X: 'exitX',
STYLE_EXIT_Y: 'exitY',
STYLE_EXIT_DX: 'exitDx',
STYLE_EXIT_DY: 'exitDy',
STYLE_EXIT_PERIMETER: 'exitPerimeter',
STYLE_ENTRY_X: 'entryX',
STYLE_ENTRY_Y: 'entryY',
STYLE_ENTRY_DX: 'entryDx',
STYLE_ENTRY_DY: 'entryDy',
STYLE_ENTRY_PERIMETER: 'entryPerimeter',
STYLE_WHITE_SPACE: 'whiteSpace',
STYLE_ROTATION: 'rotation',
STYLE_FILLCOLOR: 'fillColor',
STYLE_POINTER_EVENTS: 'pointerEvents',
STYLE_SWIMLANE_FILLCOLOR: 'swimlaneFillColor',
STYLE_MARGIN: 'margin',
STYLE_GRADIENTCOLOR: 'gradientColor',
STYLE_GRADIENT_DIRECTION: 'gradientDirection',
STYLE_STROKECOLOR: 'strokeColor',
STYLE_SEPARATORCOLOR: 'separatorColor',
STYLE_STROKEWIDTH: 'strokeWidth',
STYLE_ALIGN: 'align',
STYLE_VERTICAL_ALIGN: 'verticalAlign',
STYLE_LABEL_WIDTH: 'labelWidth',
STYLE_LABEL_POSITION: 'labelPosition',
STYLE_VERTICAL_LABEL_POSITION: 'verticalLabelPosition',
STYLE_IMAGE_ASPECT: 'imageAspect',
STYLE_IMAGE_ALIGN: 'imageAlign',
STYLE_IMAGE_VERTICAL_ALIGN: 'imageVerticalAlign',
STYLE_GLASS: 'glass',
STYLE_IMAGE: 'image',
STYLE_IMAGE_WIDTH: 'imageWidth',
STYLE_IMAGE_HEIGHT: 'imageHeight',
STYLE_IMAGE_BACKGROUND: 'imageBackground',
STYLE_IMAGE_BORDER: 'imageBorder',
STYLE_FLIPH: 'flipH',
STYLE_FLIPV: 'flipV',
STYLE_NOLABEL: 'noLabel',
STYLE_NOEDGESTYLE: 'noEdgeStyle',
STYLE_LABEL_BACKGROUNDCOLOR: 'labelBackgroundColor',
STYLE_LABEL_BORDERCOLOR: 'labelBorderColor',
STYLE_LABEL_PADDING: 'labelPadding',
STYLE_INDICATOR_SHAPE: 'indicatorShape',
STYLE_INDICATOR_IMAGE: 'indicatorImage',
STYLE_INDICATOR_COLOR: 'indicatorColor',
STYLE_INDICATOR_STROKECOLOR: 'indicatorStrokeColor',
STYLE_INDICATOR_GRADIENTCOLOR: 'indicatorGradientColor',
STYLE_INDICATOR_SPACING: 'indicatorSpacing',
STYLE_INDICATOR_WIDTH: 'indicatorWidth',
STYLE_INDICATOR_HEIGHT: 'indicatorHeight',
STYLE_INDICATOR_DIRECTION: 'indicatorDirection',
STYLE_SHADOW: 'shadow',
STYLE_SEGMENT: 'segment',
STYLE_ENDARROW: 'endArrow',
STYLE_STARTARROW: 'startArrow',
STYLE_ENDSIZE: 'endSize',
STYLE_STARTSIZE: 'startSize',
STYLE_SWIMLANE_LINE: 'swimlaneLine',
STYLE_ENDFILL: 'endFill',
STYLE_STARTFILL: 'startFill',
STYLE_DASHED: 'dashed',
STYLE_DASH_PATTERN: 'dashPattern',
STYLE_FIX_DASH: 'fixDash',
STYLE_ROUNDED: 'rounded',
STYLE_CURVED: 'curved',
STYLE_ARCSIZE: 'arcSize',
STYLE_ABSOLUTE_ARCSIZE: 'absoluteArcSize',
STYLE_SOURCE_PERIMETER_SPACING: 'sourcePerimeterSpacing',
STYLE_TARGET_PERIMETER_SPACING: 'targetPerimeterSpacing',
STYLE_PERIMETER_SPACING: 'perimeterSpacing',
STYLE_SPACING: 'spacing',
STYLE_SPACING_TOP: 'spacingTop',
STYLE_SPACING_LEFT: 'spacingLeft',
STYLE_SPACING_BOTTOM: 'spacingBottom',
STYLE_SPACING_RIGHT: 'spacingRight',
STYLE_HORIZONTAL: 'horizontal',
STYLE_DIRECTION: 'direction',
STYLE_ANCHOR_POINT_DIRECTION: 'anchorPointDirection',
STYLE_ELBOW: 'elbow',
STYLE_FONTCOLOR: 'fontColor',
STYLE_FONTFAMILY: 'fontFamily',
STYLE_FONTSIZE: 'fontSize',
STYLE_FONTSTYLE: 'fontStyle',
STYLE_ASPECT: 'aspect',
STYLE_AUTOSIZE: 'autosize',
STYLE_FOLDABLE: 'foldable',
STYLE_EDITABLE: 'editable',
STYLE_BACKGROUND_OUTLINE: 'backgroundOutline',
STYLE_BENDABLE: 'bendable',
STYLE_MOVABLE: 'movable',
STYLE_RESIZABLE: 'resizable',
STYLE_RESIZE_WIDTH: 'resizeWidth',
STYLE_RESIZE_HEIGHT: 'resizeHeight',
STYLE_ROTATABLE: 'rotatable',
STYLE_CLONEABLE: 'cloneable',
STYLE_DELETABLE: 'deletable',
STYLE_SHAPE: 'shape',
STYLE_EDGE: 'edgeStyle',
STYLE_JETTY_SIZE: 'jettySize',
STYLE_SOURCE_JETTY_SIZE: 'sourceJettySize',
STYLE_TARGET_JETTY_SIZE: 'targetJettySize',
STYLE_LOOP: 'loopStyle',
STYLE_ORTHOGONAL_LOOP: 'orthogonalLoop',
STYLE_ROUTING_CENTER_X: 'routingCenterX',
STYLE_ROUTING_CENTER_Y: 'routingCenterY',
FONT_BOLD: 1,
FONT_ITALIC: 2,
FONT_UNDERLINE: 4,
FONT_STRIKETHROUGH: 8,
SHAPE_RECTANGLE: 'rectangle',
SHAPE_ELLIPSE: 'ellipse',
SHAPE_DOUBLE_ELLIPSE: 'doubleEllipse',
SHAPE_RHOMBUS: 'rhombus',
SHAPE_LINE: 'line',
SHAPE_IMAGE: 'image',
SHAPE_ARROW: 'arrow',
SHAPE_ARROW_CONNECTOR: 'arrowConnector',
SHAPE_LABEL: 'label',
SHAPE_CYLINDER: 'cylinder',
SHAPE_SWIMLANE: 'swimlane',
SHAPE_CONNECTOR: 'connector',
SHAPE_ACTOR: 'actor',
SHAPE_CLOUD: 'cloud',
SHAPE_TRIANGLE: 'triangle',
SHAPE_HEXAGON: 'hexagon',
ARROW_CLASSIC: 'classic',
ARROW_CLASSIC_THIN: 'classicThin',
ARROW_BLOCK: 'block',
ARROW_BLOCK_THIN: 'blockThin',
ARROW_OPEN: 'open',
ARROW_OPEN_THIN: 'openThin',
ARROW_OVAL: 'oval',
ARROW_DIAMOND: 'diamond',
ARROW_DIAMOND_THIN: 'diamondThin',
ALIGN_LEFT: 'left',
ALIGN_CENTER: 'center',
ALIGN_RIGHT: 'right',
ALIGN_TOP: 'top',
ALIGN_MIDDLE: 'middle',
ALIGN_BOTTOM: 'bottom',
DIRECTION_NORTH: 'north',
DIRECTION_SOUTH: 'south',
DIRECTION_EAST: 'east',
DIRECTION_WEST: 'west',
TEXT_DIRECTION_DEFAULT: '',
TEXT_DIRECTION_AUTO: 'auto',
TEXT_DIRECTION_LTR: 'ltr',
TEXT_DIRECTION_RTL: 'rtl',
DIRECTION_MASK_NONE: 0,
DIRECTION_MASK_WEST: 1,
DIRECTION_MASK_NORTH: 2,
DIRECTION_MASK_SOUTH: 4,
DIRECTION_MASK_EAST: 8,
DIRECTION_MASK_ALL: 15,
ELBOW_VERTICAL: 'vertical',
ELBOW_HORIZONTAL: 'horizontal',
EDGESTYLE_ELBOW: 'elbowEdgeStyle',
EDGESTYLE_ENTITY_RELATION: 'entityRelationEdgeStyle',
EDGESTYLE_LOOP: 'loopEdgeStyle',
EDGESTYLE_SIDETOSIDE: 'sideToSideEdgeStyle',
EDGESTYLE_TOPTOBOTTOM: 'topToBottomEdgeStyle',
EDGESTYLE_ORTHOGONAL: 'orthogonalEdgeStyle',
EDGESTYLE_SEGMENT: 'segmentEdgeStyle',
PERIMETER_ELLIPSE: 'ellipsePerimeter',
PERIMETER_RECTANGLE: 'rectanglePerimeter',
PERIMETER_RHOMBUS: 'rhombusPerimeter',
PERIMETER_HEXAGON: 'hexagonPerimeter',
PERIMETER_TRIANGLE: 'trianglePerimeter'
};
__mxOutput.mxConstants = typeof mxConstants !== 'undefined' ? mxConstants : undefined;
function mxEventObject(name)
{
this.name = name;
this.properties = [];
for (var i = 1; i < arguments.length; i += 2)
{
if (arguments[i + 1] != null)
{
this.properties[arguments[i]] = arguments[i + 1];
}
}
} mxEventObject.prototype.name = null;
mxEventObject.prototype.properties = null;
mxEventObject.prototype.consumed = false;
mxEventObject.prototype.getName = function()
{
return this.name;
};
mxEventObject.prototype.getProperties = function()
{
return this.properties;
};
mxEventObject.prototype.getProperty = function(key)
{
return this.properties[key];
};
mxEventObject.prototype.isConsumed = function()
{
return this.consumed;
};
mxEventObject.prototype.consume = function()
{
this.consumed = true;
};
__mxOutput.mxEventObject = typeof mxEventObject !== 'undefined' ? mxEventObject : undefined;
function mxMouseEvent(evt, state)
{
this.evt = evt;
this.state = state;
this.sourceState = state;
} mxMouseEvent.prototype.consumed = false;
mxMouseEvent.prototype.evt = null;
mxMouseEvent.prototype.graphX = null;
mxMouseEvent.prototype.graphY = null;
mxMouseEvent.prototype.state = null;
mxMouseEvent.prototype.sourceState = null;
mxMouseEvent.prototype.getEvent = function()
{
return this.evt;
};
mxMouseEvent.prototype.getSource = function()
{
return mxEvent.getSource(this.evt);
};
mxMouseEvent.prototype.isSource = function(shape)
{
if (shape != null)
{
return mxUtils.isAncestorNode(shape.node, this.getSource());
}
return false;
};
mxMouseEvent.prototype.getX = function()
{
return mxEvent.getClientX(this.getEvent());
};
mxMouseEvent.prototype.getY = function()
{
return mxEvent.getClientY(this.getEvent());
};
mxMouseEvent.prototype.getGraphX = function()
{
return this.graphX;
};
mxMouseEvent.prototype.getGraphY = function()
{
return this.graphY;
};
mxMouseEvent.prototype.getState = function()
{
return this.state;
};
mxMouseEvent.prototype.getCell = function()
{
var state = this.getState();
if (state != null)
{
return state.cell;
}
return null;
};
mxMouseEvent.prototype.isPopupTrigger = function()
{
return mxEvent.isPopupTrigger(this.getEvent());
};
mxMouseEvent.prototype.isConsumed = function()
{
return this.consumed;
};
mxMouseEvent.prototype.consume = function(preventDefault)
{
preventDefault = (preventDefault != null) ? preventDefault :
(this.evt.touches != null || mxEvent.isMouseEvent(this.evt));
if (preventDefault && this.evt.preventDefault)
{
this.evt.preventDefault();
}
if (mxClient.IS_IE)
{
this.evt.returnValue = true;
}
this.consumed = true;
};
__mxOutput.mxMouseEvent = typeof mxMouseEvent !== 'undefined' ? mxMouseEvent : undefined;
function mxEventSource(eventSource)
{
this.setEventSource(eventSource);
} mxEventSource.prototype.eventListeners = null;
mxEventSource.prototype.eventsEnabled = true;
mxEventSource.prototype.eventSource = null;
mxEventSource.prototype.isEventsEnabled = function()
{
return this.eventsEnabled;
};
mxEventSource.prototype.setEventsEnabled = function(value)
{
this.eventsEnabled = value;
};
mxEventSource.prototype.getEventSource = function()
{
return this.eventSource;
};
mxEventSource.prototype.setEventSource = function(value)
{
this.eventSource = value;
};
mxEventSource.prototype.addListener = function(name, funct)
{
if (this.eventListeners == null)
{
this.eventListeners = [];
}
this.eventListeners.push(name);
this.eventListeners.push(funct);
};
mxEventSource.prototype.removeListener = function(funct)
{
if (this.eventListeners != null)
{
var i = 0;
while (i < this.eventListeners.length)
{
if (this.eventListeners[i+1] == funct)
{
this.eventListeners.splice(i, 2);
}
else
{
i += 2;
}
}
}
};
mxEventSource.prototype.fireEvent = function(evt, sender)
{
if (this.eventListeners != null && this.isEventsEnabled())
{
if (evt == null)
{
evt = new mxEventObject();
}
if (sender == null)
{
sender = this.getEventSource();
}
if (sender == null)
{
sender = this;
}
var args = [sender, evt];
for (var i = 0; i < this.eventListeners.length; i += 2)
{
var listen = this.eventListeners[i];
if (listen == null || listen == evt.getName())
{
this.eventListeners[i+1].apply(this, args);
}
}
}
};
__mxOutput.mxEventSource = typeof mxEventSource !== 'undefined' ? mxEventSource : undefined;
var mxEvent =
{
addListener: function()
{
var updateListenerList = function(element, eventName, funct)
{
if (element.mxListenerList == null)
{
element.mxListenerList = [];
}
var entry = {name: eventName, f: funct};
element.mxListenerList.push(entry);
};
if (window.addEventListener)
{
return function(element, eventName, funct)
{
element.addEventListener(eventName, funct, false);
updateListenerList(element, eventName, funct);
};
}
else
{
return function(element, eventName, funct)
{
element.attachEvent('on' + eventName, funct);
updateListenerList(element, eventName, funct);
};
}
}(),
removeListener: function()
{
var updateListener = function(element, eventName, funct)
{
if (element.mxListenerList != null)
{
var listenerCount = element.mxListenerList.length;
for (var i = 0; i < listenerCount; i++)
{
var entry = element.mxListenerList[i];
if (entry.f == funct)
{
element.mxListenerList.splice(i, 1);
break;
}
}
if (element.mxListenerList.length == 0)
{
element.mxListenerList = null;
}
}
};
if (window.removeEventListener)
{
return function(element, eventName, funct)
{
element.removeEventListener(eventName, funct, false);
updateListener(element, eventName, funct);
};
}
else
{
return function(element, eventName, funct)
{
element.detachEvent('on' + eventName, funct);
updateListener(element, eventName, funct);
};
}
}(),
removeAllListeners: function(element)
{
var list = element.mxListenerList;
if (list != null)
{
while (list.length > 0)
{
var entry = list[0];
mxEvent.removeListener(element, entry.name, entry.f);
}
}
},
addGestureListeners: function(node, startListener, moveListener, endListener)
{
if (startListener != null)
{
mxEvent.addListener(node, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', startListener);
}
if (moveListener != null)
{
mxEvent.addListener(node, (mxClient.IS_POINTER) ? 'pointermove' : 'mousemove', moveListener);
}
if (endListener != null)
{
mxEvent.addListener(node, (mxClient.IS_POINTER) ? 'pointerup' : 'mouseup', endListener);
}
if (!mxClient.IS_POINTER && mxClient.IS_TOUCH)
{
if (startListener != null)
{
mxEvent.addListener(node, 'touchstart', startListener);
}
if (moveListener != null)
{
mxEvent.addListener(node, 'touchmove', moveListener);
}
if (endListener != null)
{
mxEvent.addListener(node, 'touchend', endListener);
}
}
},
removeGestureListeners: function(node, startListener, moveListener, endListener)
{
if (startListener != null)
{
mxEvent.removeListener(node, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', startListener);
}
if (moveListener != null)
{
mxEvent.removeListener(node, (mxClient.IS_POINTER) ? 'pointermove' : 'mousemove', moveListener);
}
if (endListener != null)
{
mxEvent.removeListener(node, (mxClient.IS_POINTER) ? 'pointerup' : 'mouseup', endListener);
}
if (!mxClient.IS_POINTER && mxClient.IS_TOUCH)
{
if (startListener != null)
{
mxEvent.removeListener(node, 'touchstart', startListener);
}
if (moveListener != null)
{
mxEvent.removeListener(node, 'touchmove', moveListener);
}
if (endListener != null)
{
mxEvent.removeListener(node, 'touchend', endListener);
}
}
},
redirectMouseEvents: function(node, graph, state, down, move, up, dblClick)
{
var getState = function(evt)
{
return (typeof(state) == 'function') ? state(evt) : state;
};
mxEvent.addGestureListeners(node, function (evt)
{
if (down != null)
{
down(evt);
}
else if (!mxEvent.isConsumed(evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, getState(evt)));
}
},
function (evt)
{
if (move != null)
{
move(evt);
}
else if (!mxEvent.isConsumed(evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, getState(evt)));
}
},
function (evt)
{
if (up != null)
{
up(evt);
}
else if (!mxEvent.isConsumed(evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, getState(evt)));
}
});
mxEvent.addListener(node, 'dblclick', function (evt)
{
if (dblClick != null)
{
dblClick(evt);
}
else if (!mxEvent.isConsumed(evt))
{
var tmp = getState(evt);
graph.dblClick(evt, (tmp != null) ? tmp.cell : null);
}
});
},
release: function(element)
{
try
{
if (element != null)
{
mxEvent.removeAllListeners(element);
var children = element.childNodes;
if (children != null)
{
var childCount = children.length;
for (var i = 0; i < childCount; i += 1)
{
mxEvent.release(children[i]);
}
}
}
}
catch (e)
{
}
},
addMouseWheelListener: function(funct, target)
{
if (funct != null)
{
var wheelHandler = function(evt)
{
if (evt == null)
{
evt = window.event;
}
if (evt.ctrlKey)
{
evt.preventDefault();
}
-evt.deltaY;
if (Math.abs(evt.deltaX) > 0.5 || Math.abs(evt.deltaY) > 0.5)
{
funct(evt, (evt.deltaY == 0) ? -evt.deltaX > 0 : -evt.deltaY > 0);
}
};
target = target != null ? target : window;
if (mxClient.IS_SF && !mxClient.IS_TOUCH)
{
var scale = 1;
mxEvent.addListener(target, 'gesturestart', function(evt)
{
mxEvent.consume(evt);
scale = 1;
});
mxEvent.addListener(target, 'gesturechange', function(evt)
{
mxEvent.consume(evt);
var diff = scale - evt.scale;
if (Math.abs(diff) > 0.2)
{
funct(evt, diff < 0, true);
scale = evt.scale;
}
});
mxEvent.addListener(target, 'gestureend', function(evt)
{
mxEvent.consume(evt);
});
}
else
{
var evtCache = [];
var dx0 = 0;
var dy0 = 0;
mxEvent.addGestureListeners(target, mxUtils.bind(this, function(evt)
{
if (!mxEvent.isMouseEvent(evt) && evt.pointerId != null)
{
evtCache.push(evt);
}
}),
mxUtils.bind(this, function(evt)
{
if (!mxEvent.isMouseEvent(evt) && evtCache.length == 2)
{
for (var i = 0; i < evtCache.length; i++)
{
if (evt.pointerId == evtCache[i].pointerId)
{
evtCache[i] = evt;
break;
}
}
var dx = Math.abs(evtCache[0].clientX - evtCache[1].clientX);
var dy = Math.abs(evtCache[0].clientY - evtCache[1].clientY);
var tx = Math.abs(dx - dx0);
var ty = Math.abs(dy - dy0);
if (tx > mxEvent.PINCH_THRESHOLD || ty > mxEvent.PINCH_THRESHOLD)
{
var cx = evtCache[0].clientX + (evtCache[1].clientX - evtCache[0].clientX) / 2;
var cy = evtCache[0].clientY + (evtCache[1].clientY - evtCache[0].clientY) / 2;
funct(evtCache[0], (tx > ty) ? dx > dx0 : dy > dy0, true, cx, cy);
dx0 = dx;
dy0 = dy;
}
}
}),
mxUtils.bind(this, function(evt)
{
evtCache = [];
dx0 = 0;
dy0 = 0;
}));
}
mxEvent.addListener(target, 'wheel', wheelHandler);
}
},
disableContextMenu: function(element)
{
mxEvent.addListener(element, 'contextmenu', function(evt)
{
if (evt.preventDefault)
{
evt.preventDefault();
}
return false;
});
},
getSource: function(evt)
{
return (evt.srcElement != null) ? evt.srcElement : evt.target;
},
isConsumed: function(evt)
{
return evt.isConsumed != null && evt.isConsumed;
},
isTouchEvent: function(evt)
{
return (evt.pointerType != null) ? (evt.pointerType == 'touch' || evt.pointerType ===
evt.MSPOINTER_TYPE_TOUCH) : ((evt.mozInputSource != null) ?
evt.mozInputSource == 5 : evt.type.indexOf('touch') == 0);
},
isPenEvent: function(evt)
{
return (evt.pointerType != null) ? (evt.pointerType == 'pen' || evt.pointerType ===
evt.MSPOINTER_TYPE_PEN) : ((evt.mozInputSource != null) ?
evt.mozInputSource == 2 : evt.type.indexOf('pen') == 0);
},
isMultiTouchEvent: function(evt)
{
return (evt.type != null && evt.type.indexOf('touch') == 0 && evt.touches != null && evt.touches.length > 1);
},
isMouseEvent: function(evt)
{
return (evt.pointerType != null) ? (evt.pointerType == 'mouse' || evt.pointerType ===
evt.MSPOINTER_TYPE_MOUSE) : ((evt.mozInputSource != null) ?
evt.mozInputSource == 1 : evt.type.indexOf('mouse') == 0);
},
isLeftMouseButton: function(evt)
{
if ('buttons' in evt && (evt.type == 'mousedown' || evt.type == 'mousemove'))
{
return evt.buttons == 1;
}
else if ('which' in evt)
{
return evt.which === 1;
}
else
{
return evt.button === 1;
}
},
isMiddleMouseButton: function(evt)
{
if ('which' in evt)
{
return evt.which === 2;
}
else
{
return evt.button === 4;
}
},
isRightMouseButton: function(evt)
{
if ('which' in evt)
{
return evt.which === 3;
}
else
{
return evt.button === 2;
}
},
isPopupTrigger: function(evt)
{
return mxEvent.isRightMouseButton(evt) || (mxClient.IS_MAC && mxEvent.isControlDown(evt) &&
!mxEvent.isShiftDown(evt) && !mxEvent.isMetaDown(evt) && !mxEvent.isAltDown(evt));
},
isShiftDown: function(evt)
{
return (evt != null) ? evt.shiftKey : false;
},
isAltDown: function(evt)
{
return (evt != null) ? evt.altKey : false;
},
isControlDown: function(evt)
{
return (evt != null) ? evt.ctrlKey : false;
},
isMetaDown: function(evt)
{
return (evt != null) ? evt.metaKey : false;
},
getMainEvent: function(e)
{
if ((e.type == 'touchstart' || e.type == 'touchmove') && e.touches != null && e.touches[0] != null)
{
e = e.touches[0];
}
else if (e.type == 'touchend' && e.changedTouches != null && e.changedTouches[0] != null)
{
e = e.changedTouches[0];
}
return e;
},
getClientX: function(e)
{
return mxEvent.getMainEvent(e).clientX;
},
getClientY: function(e)
{
return mxEvent.getMainEvent(e).clientY;
},
consume: function(evt, preventDefault, stopPropagation)
{
preventDefault = (preventDefault != null) ? preventDefault : true;
stopPropagation = (stopPropagation != null) ? stopPropagation : true;
if (preventDefault)
{
if (evt.preventDefault)
{
if (stopPropagation)
{
evt.stopPropagation();
}
evt.preventDefault();
}
else if (stopPropagation)
{
evt.cancelBubble = true;
}
}
evt.isConsumed = true;
if (!evt.preventDefault)
{
evt.returnValue = false;
}
},
LABEL_HANDLE: -1,
ROTATION_HANDLE: -2,
CUSTOM_HANDLE: -100,
VIRTUAL_HANDLE: -1e5,
MOUSE_DOWN: 'mouseDown',
MOUSE_MOVE: 'mouseMove',
MOUSE_UP: 'mouseUp',
ACTIVATE: 'activate',
RESIZE_START: 'resizeStart',
RESIZE: 'resize',
RESIZE_END: 'resizeEnd',
MOVE_START: 'moveStart',
MOVE: 'move',
MOVE_END: 'moveEnd',
PAN_START: 'panStart',
PAN: 'pan',
PAN_END: 'panEnd',
MINIMIZE: 'minimize',
NORMALIZE: 'normalize',
MAXIMIZE: 'maximize',
HIDE: 'hide',
SHOW: 'show',
CLOSE: 'close',
DESTROY: 'destroy',
REFRESH: 'refresh',
SIZE: 'size',
SELECT: 'select',
FIRED: 'fired',
FIRE_MOUSE_EVENT: 'fireMouseEvent',
GESTURE: 'gesture',
TAP_AND_HOLD: 'tapAndHold',
GET: 'get',
RECEIVE: 'receive',
CONNECT: 'connect',
DISCONNECT: 'disconnect',
SUSPEND: 'suspend',
RESUME: 'resume',
MARK: 'mark',
ROOT: 'root',
POST: 'post',
OPEN: 'open',
SAVE: 'save',
BEFORE_ADD_VERTEX: 'beforeAddVertex',
ADD_VERTEX: 'addVertex',
AFTER_ADD_VERTEX: 'afterAddVertex',
DONE: 'done',
EXECUTE: 'execute',
EXECUTED: 'executed',
BEGIN_UPDATE: 'beginUpdate',
START_EDIT: 'startEdit',
END_UPDATE: 'endUpdate',
END_EDIT: 'endEdit',
BEFORE_UNDO: 'beforeUndo',
UNDO: 'undo',
REDO: 'redo',
CHANGE: 'change',
NOTIFY: 'notify',
LAYOUT_CELLS: 'layoutCells',
CLICK: 'click',
SCALE: 'scale',
TRANSLATE: 'translate',
SCALE_AND_TRANSLATE: 'scaleAndTranslate',
UP: 'up',
DOWN: 'down',
ADD: 'add',
REMOVE: 'remove',
CLEAR: 'clear',
ADD_CELLS: 'addCells',
CELLS_ADDED: 'cellsAdded',
MOVE_CELLS: 'moveCells',
CELLS_MOVED: 'cellsMoved',
RESIZE_CELLS: 'resizeCells',
CELLS_RESIZED: 'cellsResized',
TOGGLE_CELLS: 'toggleCells',
CELLS_TOGGLED: 'cellsToggled',
ORDER_CELLS: 'orderCells',
CELLS_ORDERED: 'cellsOrdered',
REMOVE_CELLS: 'removeCells',
CELLS_REMOVED: 'cellsRemoved',
GROUP_CELLS: 'groupCells',
UNGROUP_CELLS: 'ungroupCells',
REMOVE_CELLS_FROM_PARENT: 'removeCellsFromParent',
FOLD_CELLS: 'foldCells',
CELLS_FOLDED: 'cellsFolded',
ALIGN_CELLS: 'alignCells',
LABEL_CHANGED: 'labelChanged',
CONNECT_CELL: 'connectCell',
CELL_CONNECTED: 'cellConnected',
SPLIT_EDGE: 'splitEdge',
FLIP_EDGE: 'flipEdge',
START_EDITING: 'startEditing',
EDITING_STARTED: 'editingStarted',
EDITING_STOPPED: 'editingStopped',
ADD_OVERLAY: 'addOverlay',
REMOVE_OVERLAY: 'removeOverlay',
UPDATE_CELL_SIZE: 'updateCellSize',
ESCAPE: 'escape',
DOUBLE_CLICK: 'doubleClick',
START: 'start',
RESET: 'reset',
PINCH_THRESHOLD: 10
};
__mxOutput.mxEvent = typeof mxEvent !== 'undefined' ? mxEvent : undefined;
function mxXmlRequest(url, params, method, async, username, password)
{
this.url = url;
this.params = params;
this.method = method || 'POST';
this.async = (async != null) ? async : true;
this.username = username;
this.password = password;
} mxXmlRequest.prototype.url = null;
mxXmlRequest.prototype.params = null;
mxXmlRequest.prototype.method = null;
mxXmlRequest.prototype.async = null;
mxXmlRequest.prototype.binary = false;
mxXmlRequest.prototype.withCredentials = false;
mxXmlRequest.prototype.username = null;
mxXmlRequest.prototype.password = null;
mxXmlRequest.prototype.request = null;
mxXmlRequest.prototype.decodeSimulateValues = false;
mxXmlRequest.prototype.isBinary = function()
{
return this.binary;
};
mxXmlRequest.prototype.setBinary = function(value)
{
this.binary = value;
};
mxXmlRequest.prototype.getText = function()
{
return this.request.responseText;
};
mxXmlRequest.prototype.isReady = function()
{
return this.request.readyState == 4;
};
mxXmlRequest.prototype.getDocumentElement = function()
{
var doc = this.getXml();
if (doc != null)
{
return doc.documentElement;
}
return null;
};
mxXmlRequest.prototype.getXml = function()
{
var xml = this.request.responseXML;
if (document.documentMode >= 9 || xml == null || xml.documentElement == null)
{
xml = mxUtils.parseXml(this.request.responseText);
}
return xml;
};
mxXmlRequest.prototype.getStatus = function()
{
return (this.request != null) ? this.request.status : null;
};
mxXmlRequest.prototype.create = function()
{
if (window.XMLHttpRequest)
{
return function()
{
var req = new XMLHttpRequest();
if (this.isBinary() && req.overrideMimeType)
{
req.overrideMimeType('text/plain; charset=x-user-defined');
}
return req;
};
}
else if (typeof(ActiveXObject) != 'undefined')
{
return function()
{
return new ActiveXObject('Microsoft.XMLHTTP');
};
}
}();
mxXmlRequest.prototype.send = function(onload, onerror, timeout, ontimeout)
{
this.request = this.create();
if (this.request != null)
{
if (onload != null)
{
this.request.onreadystatechange = mxUtils.bind(this, function()
{
if (this.isReady())
{
onload(this);
this.request.onreadystatechange = null;
}
});
}
this.request.open(this.method, this.url, this.async,
this.username, this.password);
this.setRequestHeaders(this.request, this.params);
if (window.XMLHttpRequest && this.withCredentials)
{
this.request.withCredentials = 'true';
}
if (!mxClient.IS_QUIRKS && (document.documentMode == null || document.documentMode > 9) &&
window.XMLHttpRequest && timeout != null && ontimeout != null)
{
this.request.timeout = timeout;
this.request.ontimeout = ontimeout;
}
this.request.send(this.params);
}
};
mxXmlRequest.prototype.setRequestHeaders = function(request, params)
{
if (params != null)
{
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
};
mxXmlRequest.prototype.simulate = function(doc, target)
{
doc = doc || document;
var old = null;
if (doc == document)
{
old = window.onbeforeunload;
window.onbeforeunload = null;
}
var form = doc.createElement('form');
form.setAttribute('method', this.method);
form.setAttribute('action', this.url);
if (target != null)
{
form.setAttribute('target', target);
}
form.style.display = 'none';
form.style.visibility = 'hidden';
var pars = (this.params.indexOf('&') > 0) ?
this.params.split('&') :
this.params.split();
for (var i=0; i<pars.length; i++)
{
var pos = pars[i].indexOf('=');
if (pos > 0)
{
var name = pars[i].substring(0, pos);
var value = pars[i].substring(pos+1);
if (this.decodeSimulateValues)
{
value = decodeURIComponent(value);
}
var textarea = doc.createElement('textarea');
textarea.setAttribute('wrap', 'off');
textarea.setAttribute('name', name);
mxUtils.write(textarea, value);
form.appendChild(textarea);
}
}
doc.body.appendChild(form);
form.submit();
if (form.parentNode != null)
{
form.parentNode.removeChild(form);
}
if (old != null)
{
window.onbeforeunload = old;
}
};
__mxOutput.mxXmlRequest = typeof mxXmlRequest !== 'undefined' ? mxXmlRequest : undefined;
var mxClipboard =
{
STEPSIZE: 10,
insertCount: 1,
cells: null,
setCells: function(cells)
{
mxClipboard.cells = cells;
},
getCells: function()
{
return mxClipboard.cells;
},
isEmpty: function()
{
return mxClipboard.getCells() == null;
},
cut: function(graph, cells)
{
cells = mxClipboard.copy(graph, cells);
mxClipboard.insertCount = 0;
mxClipboard.removeCells(graph, cells);
return cells;
},
removeCells: function(graph, cells)
{
graph.removeCells(cells);
},
copy: function(graph, cells)
{
cells = cells || graph.getSelectionCells();
var result = graph.getExportableCells(graph.model.getTopmostCells(cells));
mxClipboard.insertCount = 1;
mxClipboard.setCells(graph.cloneCells(result));
return result;
},
paste: function(graph)
{
var cells = null;
if (!mxClipboard.isEmpty())
{
cells = graph.getImportableCells(mxClipboard.getCells());
var delta = mxClipboard.insertCount * mxClipboard.STEPSIZE;
var parent = graph.getDefaultParent();
cells = graph.importCells(cells, delta, delta, parent);
mxClipboard.insertCount++;
graph.setSelectionCells(cells);
}
return cells;
}
};
__mxOutput.mxClipboard = typeof mxClipboard !== 'undefined' ? mxClipboard : undefined;
function mxWindow(title, content, x, y, width, height, minimizable, movable, replaceNode, style)
{
if (content != null)
{
minimizable = (minimizable != null) ? minimizable : true;
this.content = content;
this.init(x, y, width, height, style);
this.installMaximizeHandler();
this.installMinimizeHandler();
this.installCloseHandler();
this.setMinimizable(minimizable);
this.setTitle(title);
if (movable == null || movable)
{
this.installMoveHandler();
}
if (replaceNode != null && replaceNode.parentNode != null)
{
replaceNode.parentNode.replaceChild(this.div, replaceNode);
}
else
{
document.body.appendChild(this.div);
}
}
} mxWindow.prototype = new mxEventSource();
mxWindow.prototype.constructor = mxWindow;
mxWindow.prototype.closeImage = mxClient.imageBasePath + '/close.gif';
mxWindow.prototype.minimizeImage = mxClient.imageBasePath + '/minimize.gif';
mxWindow.prototype.normalizeImage = mxClient.imageBasePath + '/normalize.gif';
mxWindow.prototype.maximizeImage = mxClient.imageBasePath + '/maximize.gif';
mxWindow.prototype.resizeImage = mxClient.imageBasePath + '/resize.gif';
mxWindow.prototype.visible = false;
mxWindow.prototype.minimumSize = new mxRectangle(0, 0, 50, 40);
mxWindow.prototype.destroyOnClose = true;
mxWindow.prototype.contentHeightCorrection = (document.documentMode == 8 || document.documentMode == 7) ? 6 : 2;
mxWindow.prototype.title = null;
mxWindow.prototype.content = null;
mxWindow.prototype.init = function(x, y, width, height, style)
{
style = (style != null) ? style : 'mxWindow';
this.div = document.createElement('div');
this.div.className = style;
this.div.style.left = x + 'px';
this.div.style.top = y + 'px';
this.table = document.createElement('table');
this.table.className = style;
if (mxClient.IS_POINTER)
{
this.div.style.touchAction = 'none';
}
if (width != null)
{
if (!mxClient.IS_QUIRKS)
{
this.div.style.width = width + 'px';
}
this.table.style.width = width + 'px';
}
if (height != null)
{
if (!mxClient.IS_QUIRKS)
{
this.div.style.height = height + 'px';
}
this.table.style.height = height + 'px';
}
var tbody = document.createElement('tbody');
var tr = document.createElement('tr');
this.title = document.createElement('td');
this.title.className = style + 'Title';
this.buttons = document.createElement('div');
this.buttons.style.position = 'absolute';
this.buttons.style.display = 'inline-block';
this.buttons.style.right = '4px';
this.buttons.style.top = '5px';
this.title.appendChild(this.buttons);
tr.appendChild(this.title);
tbody.appendChild(tr);
tr = document.createElement('tr');
this.td = document.createElement('td');
this.td.className = style + 'Pane';
if (document.documentMode == 7)
{
this.td.style.height = '100%';
}
this.contentWrapper = document.createElement('div');
this.contentWrapper.className = style + 'Pane';
this.contentWrapper.style.width = '100%';
this.contentWrapper.appendChild(this.content);
if (mxClient.IS_QUIRKS || this.content.nodeName.toUpperCase() != 'DIV')
{
this.contentWrapper.style.height = '100%';
}
this.td.appendChild(this.contentWrapper);
tr.appendChild(this.td);
tbody.appendChild(tr);
this.table.appendChild(tbody);
this.div.appendChild(this.table);
var activator = mxUtils.bind(this, function(evt)
{
this.activate();
});
mxEvent.addGestureListeners(this.title, activator);
mxEvent.addGestureListeners(this.table, activator);
this.hide();
};
mxWindow.prototype.setTitle = function(title)
{
var child = this.title.firstChild;
while (child != null)
{
var next = child.nextSibling;
if (child.nodeType == mxConstants.NODETYPE_TEXT)
{
child.parentNode.removeChild(child);
}
child = next;
}
mxUtils.write(this.title, title || '');
this.title.appendChild(this.buttons);
};
mxWindow.prototype.setScrollable = function(scrollable)
{
if (navigator.userAgent == null ||
navigator.userAgent.indexOf('Presto/2.5') < 0)
{
if (scrollable)
{
this.contentWrapper.style.overflow = 'auto';
}
else
{
this.contentWrapper.style.overflow = 'hidden';
}
}
};
mxWindow.prototype.activate = function()
{
if (mxWindow.activeWindow != this)
{
var style = mxUtils.getCurrentStyle(this.getElement());
var index = (style != null) ? style.zIndex : 3;
if (mxWindow.activeWindow)
{
var elt = mxWindow.activeWindow.getElement();
if (elt != null && elt.style != null)
{
elt.style.zIndex = index;
}
}
var previousWindow = mxWindow.activeWindow;
this.getElement().style.zIndex = parseInt(index) + 1;
mxWindow.activeWindow = this;
this.fireEvent(new mxEventObject(mxEvent.ACTIVATE, 'previousWindow', previousWindow));
}
};
mxWindow.prototype.getElement = function()
{
return this.div;
};
mxWindow.prototype.fit = function()
{
mxUtils.fit(this.div);
};
mxWindow.prototype.isResizable = function()
{
if (this.resize != null)
{
return this.resize.style.display != 'none';
}
return false;
};
mxWindow.prototype.setResizable = function(resizable)
{
if (resizable)
{
if (this.resize == null)
{
this.resize = document.createElement('img');
this.resize.style.position = 'absolute';
this.resize.style.bottom = '2px';
this.resize.style.right = '2px';
this.resize.setAttribute('src', this.resizeImage);
this.resize.style.cursor = 'nw-resize';
var startX = null;
var startY = null;
var width = null;
var height = null;
var start = mxUtils.bind(this, function(evt)
{
this.activate();
startX = mxEvent.getClientX(evt);
startY = mxEvent.getClientY(evt);
width = this.div.offsetWidth;
height = this.div.offsetHeight;
mxEvent.addGestureListeners(document, null, dragHandler, dropHandler);
this.fireEvent(new mxEventObject(mxEvent.RESIZE_START, 'event', evt));
mxEvent.consume(evt);
});
var dragHandler = mxUtils.bind(this, function(evt)
{
if (startX != null && startY != null)
{
var dx = mxEvent.getClientX(evt) - startX;
var dy = mxEvent.getClientY(evt) - startY;
this.setSize(width + dx, height + dy);
this.fireEvent(new mxEventObject(mxEvent.RESIZE, 'event', evt));
mxEvent.consume(evt);
}
});
var dropHandler = mxUtils.bind(this, function(evt)
{
if (startX != null && startY != null)
{
startX = null;
startY = null;
mxEvent.removeGestureListeners(document, null, dragHandler, dropHandler);
this.fireEvent(new mxEventObject(mxEvent.RESIZE_END, 'event', evt));
mxEvent.consume(evt);
}
});
mxEvent.addGestureListeners(this.resize, start, dragHandler, dropHandler);
this.div.appendChild(this.resize);
}
else
{
this.resize.style.display = 'inline';
}
}
else if (this.resize != null)
{
this.resize.style.display = 'none';
}
};
mxWindow.prototype.setSize = function(width, height)
{
width = Math.max(this.minimumSize.width, width);
height = Math.max(this.minimumSize.height, height);
if (!mxClient.IS_QUIRKS)
{
this.div.style.width = width + 'px';
this.div.style.height = height + 'px';
}
this.table.style.width = width + 'px';
this.table.style.height = height + 'px';
if (!mxClient.IS_QUIRKS)
{
this.contentWrapper.style.height = (this.div.offsetHeight -
this.title.offsetHeight - this.contentHeightCorrection) + 'px';
}
};
mxWindow.prototype.setMinimizable = function(minimizable)
{
this.minimize.style.display = (minimizable) ? '' : 'none';
};
mxWindow.prototype.getMinimumSize = function()
{
return new mxRectangle(0, 0, 0, this.title.offsetHeight);
};
mxWindow.prototype.installMinimizeHandler = function()
{
this.minimize = document.createElement('img');
this.minimize.setAttribute('src', this.minimizeImage);
this.minimize.setAttribute('title', 'Minimize');
this.minimize.style.cursor = 'pointer';
this.minimize.style.marginLeft = '2px';
this.minimize.style.display = 'none';
this.buttons.appendChild(this.minimize);
var minimized = false;
var maxDisplay = null;
var height = null;
var funct = mxUtils.bind(this, function(evt)
{
this.activate();
if (!minimized)
{
minimized = true;
this.minimize.setAttribute('src', this.normalizeImage);
this.minimize.setAttribute('title', 'Normalize');
this.contentWrapper.style.display = 'none';
maxDisplay = this.maximize.style.display;
this.maximize.style.display = 'none';
height = this.table.style.height;
var minSize = this.getMinimumSize();
if (minSize.height > 0)
{
if (!mxClient.IS_QUIRKS)
{
this.div.style.height = minSize.height + 'px';
}
this.table.style.height = minSize.height + 'px';
}
if (minSize.width > 0)
{
if (!mxClient.IS_QUIRKS)
{
this.div.style.width = minSize.width + 'px';
}
this.table.style.width = minSize.width + 'px';
}
if (this.resize != null)
{
this.resize.style.visibility = 'hidden';
}
this.fireEvent(new mxEventObject(mxEvent.MINIMIZE, 'event', evt));
}
else
{
minimized = false;
this.minimize.setAttribute('src', this.minimizeImage);
this.minimize.setAttribute('title', 'Minimize');
this.contentWrapper.style.display = '';
this.maximize.style.display = maxDisplay;
if (!mxClient.IS_QUIRKS)
{
this.div.style.height = height;
}
this.table.style.height = height;
if (this.resize != null)
{
this.resize.style.visibility = '';
}
this.fireEvent(new mxEventObject(mxEvent.NORMALIZE, 'event', evt));
}
mxEvent.consume(evt);
});
mxEvent.addGestureListeners(this.minimize, funct);
};
mxWindow.prototype.setMaximizable = function(maximizable)
{
this.maximize.style.display = (maximizable) ? '' : 'none';
};
mxWindow.prototype.installMaximizeHandler = function()
{
this.maximize = document.createElement('img');
this.maximize.setAttribute('src', this.maximizeImage);
this.maximize.setAttribute('title', 'Maximize');
this.maximize.style.cursor = 'default';
this.maximize.style.marginLeft = '2px';
this.maximize.style.cursor = 'pointer';
this.maximize.style.display = 'none';
this.buttons.appendChild(this.maximize);
var maximized = false;
var x = null;
var y = null;
var height = null;
var width = null;
var minDisplay = null;
var funct = mxUtils.bind(this, function(evt)
{
this.activate();
if (this.maximize.style.display != 'none')
{
if (!maximized)
{
maximized = true;
this.maximize.setAttribute('src', this.normalizeImage);
this.maximize.setAttribute('title', 'Normalize');
this.contentWrapper.style.display = '';
minDisplay = this.minimize.style.display;
this.minimize.style.display = 'none';
x = parseInt(this.div.style.left);
y = parseInt(this.div.style.top);
height = this.table.style.height;
width = this.table.style.width;
this.div.style.left = '0px';
this.div.style.top = '0px';
var docHeight = Math.max(document.body.clientHeight || 0, document.documentElement.clientHeight || 0);
if (!mxClient.IS_QUIRKS)
{
this.div.style.width = (document.body.clientWidth - 2) + 'px';
this.div.style.height = (docHeight - 2) + 'px';
}
this.table.style.width = (document.body.clientWidth - 2) + 'px';
this.table.style.height = (docHeight - 2) + 'px';
if (this.resize != null)
{
this.resize.style.visibility = 'hidden';
}
if (!mxClient.IS_QUIRKS)
{
var style = mxUtils.getCurrentStyle(this.contentWrapper);
if (style.overflow == 'auto' || this.resize != null)
{
this.contentWrapper.style.height = (this.div.offsetHeight -
this.title.offsetHeight - this.contentHeightCorrection) + 'px';
}
}
this.fireEvent(new mxEventObject(mxEvent.MAXIMIZE, 'event', evt));
}
else
{
maximized = false;
this.maximize.setAttribute('src', this.maximizeImage);
this.maximize.setAttribute('title', 'Maximize');
this.contentWrapper.style.display = '';
this.minimize.style.display = minDisplay;
this.div.style.left = x+'px';
this.div.style.top = y+'px';
if (!mxClient.IS_QUIRKS)
{
this.div.style.height = height;
this.div.style.width = width;
var style = mxUtils.getCurrentStyle(this.contentWrapper);
if (style.overflow == 'auto' || this.resize != null)
{
this.contentWrapper.style.height = (this.div.offsetHeight -
this.title.offsetHeight - this.contentHeightCorrection) + 'px';
}
}
this.table.style.height = height;
this.table.style.width = width;
if (this.resize != null)
{
this.resize.style.visibility = '';
}
this.fireEvent(new mxEventObject(mxEvent.NORMALIZE, 'event', evt));
}
mxEvent.consume(evt);
}
});
mxEvent.addGestureListeners(this.maximize, funct);
mxEvent.addListener(this.title, 'dblclick', funct);
};
mxWindow.prototype.installMoveHandler = function()
{
this.title.style.cursor = 'move';
mxEvent.addGestureListeners(this.title,
mxUtils.bind(this, function(evt)
{
var startX = mxEvent.getClientX(evt);
var startY = mxEvent.getClientY(evt);
var x = this.getX();
var y = this.getY();
var dragHandler = mxUtils.bind(this, function(evt)
{
var dx = mxEvent.getClientX(evt) - startX;
var dy = mxEvent.getClientY(evt) - startY;
this.setLocation(x + dx, y + dy);
this.fireEvent(new mxEventObject(mxEvent.MOVE, 'event', evt));
mxEvent.consume(evt);
});
var dropHandler = mxUtils.bind(this, function(evt)
{
mxEvent.removeGestureListeners(document, null, dragHandler, dropHandler);
this.fireEvent(new mxEventObject(mxEvent.MOVE_END, 'event', evt));
mxEvent.consume(evt);
});
mxEvent.addGestureListeners(document, null, dragHandler, dropHandler);
this.fireEvent(new mxEventObject(mxEvent.MOVE_START, 'event', evt));
mxEvent.consume(evt);
}));
if (mxClient.IS_POINTER)
{
this.title.style.touchAction = 'none';
}
};
mxWindow.prototype.setLocation = function(x, y)
{
this.div.style.left = x + 'px';
this.div.style.top = y + 'px';
};
mxWindow.prototype.getX = function()
{
return parseInt(this.div.style.left);
};
mxWindow.prototype.getY = function()
{
return parseInt(this.div.style.top);
};
mxWindow.prototype.installCloseHandler = function()
{
this.closeImg = document.createElement('img');
this.closeImg.setAttribute('src', this.closeImage);
this.closeImg.setAttribute('title', 'Close');
this.closeImg.style.marginLeft = '2px';
this.closeImg.style.cursor = 'pointer';
this.closeImg.style.display = 'none';
this.buttons.appendChild(this.closeImg);
mxEvent.addGestureListeners(this.closeImg,
mxUtils.bind(this, function(evt)
{
this.fireEvent(new mxEventObject(mxEvent.CLOSE, 'event', evt));
if (this.destroyOnClose)
{
this.destroy();
}
else
{
this.setVisible(false);
}
mxEvent.consume(evt);
}));
};
mxWindow.prototype.setImage = function(image)
{
this.image = document.createElement('img');
this.image.setAttribute('src', image);
this.image.setAttribute('align', 'left');
this.image.style.marginRight = '4px';
this.image.style.marginLeft = '0px';
this.image.style.marginTop = '-2px';
this.title.insertBefore(this.image, this.title.firstChild);
};
mxWindow.prototype.setClosable = function(closable)
{
this.closeImg.style.display = (closable) ? '' : 'none';
};
mxWindow.prototype.isVisible = function()
{
if (this.div != null)
{
return this.div.style.display != 'none';
}
return false;
};
mxWindow.prototype.setVisible = function(visible)
{
if (this.div != null && this.isVisible() != visible)
{
if (visible)
{
this.show();
}
else
{
this.hide();
}
}
};
mxWindow.prototype.show = function()
{
this.div.style.display = '';
this.activate();
var style = mxUtils.getCurrentStyle(this.contentWrapper);
if (!mxClient.IS_QUIRKS && (style.overflow == 'auto' || this.resize != null) &&
this.contentWrapper.style.display != 'none')
{
this.contentWrapper.style.height = (this.div.offsetHeight -
this.title.offsetHeight - this.contentHeightCorrection) + 'px';
}
this.fireEvent(new mxEventObject(mxEvent.SHOW));
};
mxWindow.prototype.hide = function()
{
this.div.style.display = 'none';
this.fireEvent(new mxEventObject(mxEvent.HIDE));
};
mxWindow.prototype.destroy = function()
{
this.fireEvent(new mxEventObject(mxEvent.DESTROY));
if (this.div != null)
{
mxEvent.release(this.div);
this.div.parentNode.removeChild(this.div);
this.div = null;
}
this.title = null;
this.content = null;
this.contentWrapper = null;
};
__mxOutput.mxWindow = typeof mxWindow !== 'undefined' ? mxWindow : undefined;
function mxForm(className)
{
this.table = document.createElement('table');
this.table.className = className;
this.body = document.createElement('tbody');
this.table.appendChild(this.body);
} mxForm.prototype.table = null;
mxForm.prototype.body = false;
mxForm.prototype.getTable = function()
{
return this.table;
};
mxForm.prototype.addButtons = function(okFunct, cancelFunct)
{
var tr = document.createElement('tr');
var td = document.createElement('td');
tr.appendChild(td);
td = document.createElement('td');
var button = document.createElement('button');
mxUtils.write(button, mxResources.get('ok') || 'OK');
td.appendChild(button);
mxEvent.addListener(button, 'click', function()
{
okFunct();
});
button = document.createElement('button');
mxUtils.write(button, mxResources.get('cancel') || 'Cancel');
td.appendChild(button);
mxEvent.addListener(button, 'click', function()
{
cancelFunct();
});
tr.appendChild(td);
this.body.appendChild(tr);
};
mxForm.prototype.addText = function(name, value, type)
{
var input = document.createElement('input');
input.setAttribute('type', type || 'text');
input.value = value;
return this.addField(name, input);
};
mxForm.prototype.addCheckbox = function(name, value)
{
var input = document.createElement('input');
input.setAttribute('type', 'checkbox');
this.addField(name, input);
if (value)
{
input.checked = true;
}
return input;
};
mxForm.prototype.addTextarea = function(name, value, rows)
{
var input = document.createElement('textarea');
if (mxClient.IS_NS)
{
rows--;
}
input.setAttribute('rows', rows || 2);
input.value = value;
return this.addField(name, input);
};
mxForm.prototype.addCombo = function(name, isMultiSelect, size)
{
var select = document.createElement('select');
if (size != null)
{
select.setAttribute('size', size);
}
if (isMultiSelect)
{
select.setAttribute('multiple', 'true');
}
return this.addField(name, select);
};
mxForm.prototype.addOption = function(combo, label, value, isSelected)
{
var option = document.createElement('option');
mxUtils.writeln(option, label);
option.setAttribute('value', value);
if (isSelected)
{
option.setAttribute('selected', isSelected);
}
combo.appendChild(option);
};
mxForm.prototype.addField = function(name, input)
{
var tr = document.createElement('tr');
var td = document.createElement('td');
mxUtils.write(td, name);
tr.appendChild(td);
td = document.createElement('td');
td.appendChild(input);
tr.appendChild(td);
this.body.appendChild(tr);
return input;
};
__mxOutput.mxForm = typeof mxForm !== 'undefined' ? mxForm : undefined;
function mxImage(src, width, height)
{
this.src = src;
this.width = width;
this.height = height;
} mxImage.prototype.src = null;
mxImage.prototype.width = null;
mxImage.prototype.height = null;
__mxOutput.mxImage = typeof mxImage !== 'undefined' ? mxImage : undefined;
function mxDivResizer(div, container)
{
if (div.nodeName.toLowerCase() == 'div')
{
if (container == null)
{
container = window;
}
this.div = div;
var style = mxUtils.getCurrentStyle(div);
if (style != null)
{
this.resizeWidth = style.width == 'auto';
this.resizeHeight = style.height == 'auto';
}
mxEvent.addListener(container, 'resize',
mxUtils.bind(this, function(evt)
{
if (!this.handlingResize)
{
this.handlingResize = true;
this.resize();
this.handlingResize = false;
}
})
);
this.resize();
}
} mxDivResizer.prototype.resizeWidth = true;
mxDivResizer.prototype.resizeHeight = true;
mxDivResizer.prototype.handlingResize = false;
mxDivResizer.prototype.resize = function()
{
var w = this.getDocumentWidth();
var h = this.getDocumentHeight();
var l = parseInt(this.div.style.left);
var r = parseInt(this.div.style.right);
var t = parseInt(this.div.style.top);
var b = parseInt(this.div.style.bottom);
if (this.resizeWidth &&
!isNaN(l) &&
!isNaN(r) &&
l >= 0 &&
r >= 0 &&
w - r - l > 0)
{
this.div.style.width = (w - r - l)+'px';
}
if (this.resizeHeight &&
!isNaN(t) &&
!isNaN(b) &&
t >= 0 &&
b >= 0 &&
h - t - b > 0)
{
this.div.style.height = (h - t - b)+'px';
}
};
mxDivResizer.prototype.getDocumentWidth = function()
{
return document.body.clientWidth;
};
mxDivResizer.prototype.getDocumentHeight = function()
{
return document.body.clientHeight;
};
__mxOutput.mxDivResizer = typeof mxDivResizer !== 'undefined' ? mxDivResizer : undefined;
function mxDragSource(element, dropHandler)
{
this.element = element;
this.dropHandler = dropHandler;
mxEvent.addGestureListeners(element, mxUtils.bind(this, function(evt)
{
this.mouseDown(evt);
}));
mxEvent.addListener(element, 'dragstart', function(evt)
{
mxEvent.consume(evt);
});
this.eventConsumer = function(sender, evt)
{
var evtName = evt.getProperty('eventName');
var me = evt.getProperty('event');
if (evtName != mxEvent.MOUSE_DOWN)
{
me.consume();
}
};
} mxDragSource.prototype.element = null;
mxDragSource.prototype.dropHandler = null;
mxDragSource.prototype.dragOffset = null;
mxDragSource.prototype.dragElement = null;
mxDragSource.prototype.previewElement = null;
mxDragSource.prototype.previewOffset = null;
mxDragSource.prototype.enabled = true;
mxDragSource.prototype.currentGraph = null;
mxDragSource.prototype.currentDropTarget = null;
mxDragSource.prototype.currentPoint = null;
mxDragSource.prototype.currentGuide = null;
mxDragSource.prototype.currentHighlight = null;
mxDragSource.prototype.autoscroll = true;
mxDragSource.prototype.guidesEnabled = true;
mxDragSource.prototype.gridEnabled = true;
mxDragSource.prototype.highlightDropTargets = true;
mxDragSource.prototype.dragElementZIndex = 100;
mxDragSource.prototype.dragElementOpacity = 70;
mxDragSource.prototype.checkEventSource = true;
mxDragSource.prototype.isEnabled = function()
{
return this.enabled;
};
mxDragSource.prototype.setEnabled = function(value)
{
this.enabled = value;
};
mxDragSource.prototype.isGuidesEnabled = function()
{
return this.guidesEnabled;
};
mxDragSource.prototype.setGuidesEnabled = function(value)
{
this.guidesEnabled = value;
};
mxDragSource.prototype.isGridEnabled = function()
{
return this.gridEnabled;
};
mxDragSource.prototype.setGridEnabled = function(value)
{
this.gridEnabled = value;
};
mxDragSource.prototype.getGraphForEvent = function(evt)
{
return null;
};
mxDragSource.prototype.getDropTarget = function(graph, x, y, evt)
{
return graph.getCellAt(x, y);
};
mxDragSource.prototype.createDragElement = function(evt)
{
return this.element.cloneNode(true);
};
mxDragSource.prototype.createPreviewElement = function(graph)
{
return null;
};
mxDragSource.prototype.isActive = function()
{
return this.mouseMoveHandler != null;
};
mxDragSource.prototype.reset = function()
{
if (this.currentGraph != null)
{
this.dragExit(this.currentGraph);
this.currentGraph = null;
}
this.removeDragElement();
this.removeListeners();
this.stopDrag();
};
mxDragSource.prototype.mouseDown = function(evt)
{
if (this.enabled && !mxEvent.isConsumed(evt) && this.mouseMoveHandler == null)
{
this.startDrag(evt);
this.mouseMoveHandler = mxUtils.bind(this, this.mouseMove);
this.mouseUpHandler = mxUtils.bind(this, this.mouseUp);
mxEvent.addGestureListeners(document, null, this.mouseMoveHandler, this.mouseUpHandler);
if (mxClient.IS_TOUCH && !mxEvent.isMouseEvent(evt))
{
this.eventSource = mxEvent.getSource(evt);
mxEvent.addGestureListeners(this.eventSource, null, this.mouseMoveHandler, this.mouseUpHandler);
}
}
};
mxDragSource.prototype.startDrag = function(evt)
{
this.dragElement = this.createDragElement(evt);
this.dragElement.style.position = 'absolute';
this.dragElement.style.zIndex = this.dragElementZIndex;
mxUtils.setOpacity(this.dragElement, this.dragElementOpacity);
if (this.checkEventSource && mxClient.IS_SVG)
{
this.dragElement.style.pointerEvents = 'none';
}
};
mxDragSource.prototype.stopDrag = function()
{
this.removeDragElement();
};
mxDragSource.prototype.removeDragElement = function()
{
if (this.dragElement != null)
{
if (this.dragElement.parentNode != null)
{
this.dragElement.parentNode.removeChild(this.dragElement);
}
this.dragElement = null;
}
};
mxDragSource.prototype.getElementForEvent = function(evt)
{
return ((mxEvent.isTouchEvent(evt) || mxEvent.isPenEvent(evt)) ?
document.elementFromPoint(mxEvent.getClientX(evt), mxEvent.getClientY(evt)) :
mxEvent.getSource(evt));
};
mxDragSource.prototype.graphContainsEvent = function(graph, evt)
{
var x = mxEvent.getClientX(evt);
var y = mxEvent.getClientY(evt);
var offset = mxUtils.getOffset(graph.container);
var origin = mxUtils.getScrollOrigin();
var elt = this.getElementForEvent(evt);
if (this.checkEventSource)
{
while (elt != null && elt != graph.container)
{
elt = elt.parentNode;
}
}
return elt != null && x >= offset.x - origin.x && y >= offset.y - origin.y &&
x <= offset.x - origin.x + graph.container.offsetWidth &&
y <= offset.y - origin.y + graph.container.offsetHeight;
};
mxDragSource.prototype.mouseMove = function(evt)
{
var graph = this.getGraphForEvent(evt);
if (graph != null && !this.graphContainsEvent(graph, evt))
{
graph = null;
}
if (graph != this.currentGraph)
{
if (this.currentGraph != null)
{
this.dragExit(this.currentGraph, evt);
}
this.currentGraph = graph;
if (this.currentGraph != null)
{
this.dragEnter(this.currentGraph, evt);
}
}
if (this.currentGraph != null)
{
this.dragOver(this.currentGraph, evt);
}
if (this.dragElement != null && (this.previewElement == null || this.previewElement.style.visibility != 'visible'))
{
var x = mxEvent.getClientX(evt);
var y = mxEvent.getClientY(evt);
if (this.dragElement.parentNode == null)
{
document.body.appendChild(this.dragElement);
}
this.dragElement.style.visibility = 'visible';
if (this.dragOffset != null)
{
x += this.dragOffset.x;
y += this.dragOffset.y;
}
var offset = mxUtils.getDocumentScrollOrigin(document);
this.dragElement.style.left = (x + offset.x) + 'px';
this.dragElement.style.top = (y + offset.y) + 'px';
}
else if (this.dragElement != null)
{
this.dragElement.style.visibility = 'hidden';
}
mxEvent.consume(evt);
};
mxDragSource.prototype.mouseUp = function(evt)
{
if (this.currentGraph != null)
{
if (this.currentPoint != null && (this.previewElement == null ||
this.previewElement.style.visibility != 'hidden'))
{
var scale = this.currentGraph.view.scale;
var tr = this.currentGraph.view.translate;
var x = this.currentPoint.x / scale - tr.x;
var y = this.currentPoint.y / scale - tr.y;
this.drop(this.currentGraph, evt, this.currentDropTarget, x, y);
}
this.dragExit(this.currentGraph);
this.currentGraph = null;
}
this.stopDrag();
this.removeListeners();
mxEvent.consume(evt);
};
mxDragSource.prototype.removeListeners = function()
{
if (this.eventSource != null)
{
mxEvent.removeGestureListeners(this.eventSource, null, this.mouseMoveHandler, this.mouseUpHandler);
this.eventSource = null;
}
mxEvent.removeGestureListeners(document, null, this.mouseMoveHandler, this.mouseUpHandler);
this.mouseMoveHandler = null;
this.mouseUpHandler = null;
};
mxDragSource.prototype.dragEnter = function(graph, evt)
{
graph.isMouseDown = true;
graph.isMouseTrigger = mxEvent.isMouseEvent(evt);
this.previewElement = this.createPreviewElement(graph);
if (this.previewElement != null && this.checkEventSource && mxClient.IS_SVG)
{
this.previewElement.style.pointerEvents = 'none';
}
if (this.isGuidesEnabled() && this.previewElement != null)
{
this.currentGuide = new mxGuide(graph, graph.graphHandler.getGuideStates());
}
if (this.highlightDropTargets)
{
this.currentHighlight = new mxCellHighlight(graph, mxConstants.DROP_TARGET_COLOR);
}
graph.addListener(mxEvent.FIRE_MOUSE_EVENT, this.eventConsumer);
};
mxDragSource.prototype.dragExit = function(graph, evt)
{
this.currentDropTarget = null;
this.currentPoint = null;
graph.isMouseDown = false;
graph.removeListener(this.eventConsumer);
if (this.previewElement != null)
{
if (this.previewElement.parentNode != null)
{
this.previewElement.parentNode.removeChild(this.previewElement);
}
this.previewElement = null;
}
if (this.currentGuide != null)
{
this.currentGuide.destroy();
this.currentGuide = null;
}
if (this.currentHighlight != null)
{
this.currentHighlight.destroy();
this.currentHighlight = null;
}
};
mxDragSource.prototype.dragOver = function(graph, evt)
{
var offset = mxUtils.getOffset(graph.container);
var origin = mxUtils.getScrollOrigin(graph.container);
var x = mxEvent.getClientX(evt) - offset.x + origin.x - graph.panDx;
var y = mxEvent.getClientY(evt) - offset.y + origin.y - graph.panDy;
if (graph.autoScroll && (this.autoscroll == null || this.autoscroll))
{
graph.scrollPointToVisible(x, y, graph.autoExtend);
}
if (this.currentHighlight != null && graph.isDropEnabled())
{
this.currentDropTarget = this.getDropTarget(graph, x, y, evt);
var state = graph.getView().getState(this.currentDropTarget);
this.currentHighlight.highlight(state);
}
if (this.previewElement != null)
{
if (this.previewElement.parentNode == null)
{
graph.container.appendChild(this.previewElement);
this.previewElement.style.zIndex = '3';
this.previewElement.style.position = 'absolute';
}
var gridEnabled = this.isGridEnabled() && graph.isGridEnabledEvent(evt);
var hideGuide = true;
if (this.currentGuide != null && this.currentGuide.isEnabledForEvent(evt))
{
var w = parseInt(this.previewElement.style.width);
var h = parseInt(this.previewElement.style.height);
var bounds = new mxRectangle(0, 0, w, h);
var delta = new mxPoint(x, y);
delta = this.currentGuide.move(bounds, delta, gridEnabled, true);
hideGuide = false;
x = delta.x;
y = delta.y;
}
else if (gridEnabled)
{
var scale = graph.view.scale;
var tr = graph.view.translate;
var off = graph.gridSize / 2;
x = (graph.snap(x / scale - tr.x - off) + tr.x) * scale;
y = (graph.snap(y / scale - tr.y - off) + tr.y) * scale;
}
if (this.currentGuide != null && hideGuide)
{
this.currentGuide.hide();
}
if (this.previewOffset != null)
{
x += this.previewOffset.x;
y += this.previewOffset.y;
}
this.previewElement.style.left = Math.round(x) + 'px';
this.previewElement.style.top = Math.round(y) + 'px';
this.previewElement.style.visibility = 'visible';
}
this.currentPoint = new mxPoint(x, y);
};
mxDragSource.prototype.drop = function(graph, evt, dropTarget, x, y)
{
this.dropHandler.apply(this, arguments);
if (graph.container.style.visibility != 'hidden')
{
graph.container.focus();
}
};
__mxOutput.mxDragSource = typeof mxDragSource !== 'undefined' ? mxDragSource : undefined;
function mxToolbar(container)
{
this.container = container;
} mxToolbar.prototype = new mxEventSource();
mxToolbar.prototype.constructor = mxToolbar;
mxToolbar.prototype.container = null;
mxToolbar.prototype.enabled = true;
mxToolbar.prototype.noReset = false;
mxToolbar.prototype.updateDefaultMode = true;
mxToolbar.prototype.addItem = function(title, icon, funct, pressedIcon, style, factoryMethod)
{
var img = document.createElement((icon != null) ? 'img' : 'button');
var initialClassName = style || ((factoryMethod != null) ?
'mxToolbarMode' : 'mxToolbarItem');
img.className = initialClassName;
img.setAttribute('src', icon);
if (title != null)
{
if (icon != null)
{
img.setAttribute('title', title);
}
else
{
mxUtils.write(img, title);
}
}
this.container.appendChild(img);
if (funct != null)
{
mxEvent.addListener(img, 'click', funct);
if (mxClient.IS_TOUCH)
{
mxEvent.addListener(img, 'touchend', funct);
}
}
var mouseHandler = mxUtils.bind(this, function(evt)
{
if (pressedIcon != null)
{
img.setAttribute('src', icon);
}
else
{
img.style.backgroundColor = '';
}
});
mxEvent.addGestureListeners(img, mxUtils.bind(this, function(evt)
{
if (pressedIcon != null)
{
img.setAttribute('src', pressedIcon);
}
else
{
img.style.backgroundColor = 'gray';
}
if (factoryMethod != null)
{
if (this.menu == null)
{
this.menu = new mxPopupMenu();
this.menu.init();
}
var last = this.currentImg;
if (this.menu.isMenuShowing())
{
this.menu.hideMenu();
}
if (last != img)
{
this.currentImg = img;
this.menu.factoryMethod = factoryMethod;
var point = new mxPoint(
img.offsetLeft,
img.offsetTop + img.offsetHeight);
this.menu.popup(point.x, point.y, null, evt);
if (this.menu.isMenuShowing())
{
img.className = initialClassName + 'Selected';
this.menu.hideMenu = function()
{
mxPopupMenu.prototype.hideMenu.apply(this);
img.className = initialClassName;
this.currentImg = null;
};
}
}
}
}), null, mouseHandler);
mxEvent.addListener(img, 'mouseout', mouseHandler);
return img;
};
mxToolbar.prototype.addCombo = function(style)
{
var div = document.createElement('div');
div.style.display = 'inline';
div.className = 'mxToolbarComboContainer';
var select = document.createElement('select');
select.className = style || 'mxToolbarCombo';
div.appendChild(select);
this.container.appendChild(div);
return select;
};
mxToolbar.prototype.addActionCombo = function(title, style)
{
var select = document.createElement('select');
select.className = style || 'mxToolbarCombo';
this.addOption(select, title, null);
mxEvent.addListener(select, 'change', function(evt)
{
var value = select.options[select.selectedIndex];
select.selectedIndex = 0;
if (value.funct != null)
{
value.funct(evt);
}
});
this.container.appendChild(select);
return select;
};
mxToolbar.prototype.addOption = function(combo, title, value)
{
var option = document.createElement('option');
mxUtils.writeln(option, title);
if (typeof(value) == 'function')
{
option.funct = value;
}
else
{
option.setAttribute('value', value);
}
combo.appendChild(option);
return option;
};
mxToolbar.prototype.addSwitchMode = function(title, icon, funct, pressedIcon, style)
{
var img = document.createElement('img');
img.initialClassName = style || 'mxToolbarMode';
img.className = img.initialClassName;
img.setAttribute('src', icon);
img.altIcon = pressedIcon;
if (title != null)
{
img.setAttribute('title', title);
}
mxEvent.addListener(img, 'click', mxUtils.bind(this, function(evt)
{
var tmp = this.selectedMode.altIcon;
if (tmp != null)
{
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
this.selectedMode.setAttribute('src', tmp);
}
else
{
this.selectedMode.className = this.selectedMode.initialClassName;
}
if (this.updateDefaultMode)
{
this.defaultMode = img;
}
this.selectedMode = img;
var tmp = img.altIcon;
if (tmp != null)
{
img.altIcon = img.getAttribute('src');
img.setAttribute('src', tmp);
}
else
{
img.className = img.initialClassName+'Selected';
}
this.fireEvent(new mxEventObject(mxEvent.SELECT));
funct();
}));
this.container.appendChild(img);
if (this.defaultMode == null)
{
this.defaultMode = img;
this.selectMode(img);
funct();
}
return img;
};
mxToolbar.prototype.addMode = function(title, icon, funct, pressedIcon, style, toggle)
{
toggle = (toggle != null) ? toggle : true;
var img = document.createElement((icon != null) ? 'img' : 'button');
img.initialClassName = style || 'mxToolbarMode';
img.className = img.initialClassName;
img.setAttribute('src', icon);
img.altIcon = pressedIcon;
if (title != null)
{
img.setAttribute('title', title);
}
if (this.enabled && toggle)
{
mxEvent.addListener(img, 'click', mxUtils.bind(this, function(evt)
{
this.selectMode(img, funct);
this.noReset = false;
}));
mxEvent.addListener(img, 'dblclick', mxUtils.bind(this, function(evt)
{
this.selectMode(img, funct);
this.noReset = true;
}));
if (this.defaultMode == null)
{
this.defaultMode = img;
this.defaultFunction = funct;
this.selectMode(img, funct);
}
}
this.container.appendChild(img);
return img;
};
mxToolbar.prototype.selectMode = function(domNode, funct)
{
if (this.selectedMode != domNode)
{
if (this.selectedMode != null)
{
var tmp = this.selectedMode.altIcon;
if (tmp != null)
{
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
this.selectedMode.setAttribute('src', tmp);
}
else
{
this.selectedMode.className = this.selectedMode.initialClassName;
}
}
this.selectedMode = domNode;
var tmp = this.selectedMode.altIcon;
if (tmp != null)
{
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
this.selectedMode.setAttribute('src', tmp);
}
else
{
this.selectedMode.className = this.selectedMode.initialClassName+'Selected';
}
this.fireEvent(new mxEventObject(mxEvent.SELECT, "function", funct));
}
};
mxToolbar.prototype.resetMode = function(forced)
{
if ((forced || !this.noReset) && this.selectedMode != this.defaultMode)
{
this.selectMode(this.defaultMode, this.defaultFunction);
}
};
mxToolbar.prototype.addSeparator = function(icon)
{
return this.addItem(null, icon, null);
};
mxToolbar.prototype.addBreak = function()
{
mxUtils.br(this.container);
};
mxToolbar.prototype.addLine = function()
{
var hr = document.createElement('hr');
hr.style.marginRight = '6px';
hr.setAttribute('size', '1');
this.container.appendChild(hr);
};
mxToolbar.prototype.destroy = function ()
{
mxEvent.release(this.container);
this.container = null;
this.defaultMode = null;
this.defaultFunction = null;
this.selectedMode = null;
if (this.menu != null)
{
this.menu.destroy();
}
};
__mxOutput.mxToolbar = typeof mxToolbar !== 'undefined' ? mxToolbar : undefined;
function mxUndoableEdit(source, significant)
{
this.source = source;
this.changes = [];
this.significant = (significant != null) ? significant : true;
} mxUndoableEdit.prototype.source = null;
mxUndoableEdit.prototype.changes = null;
mxUndoableEdit.prototype.significant = null;
mxUndoableEdit.prototype.undone = false;
mxUndoableEdit.prototype.redone = false;
mxUndoableEdit.prototype.isEmpty = function()
{
return this.changes.length == 0;
};
mxUndoableEdit.prototype.isSignificant = function()
{
return this.significant;
};
mxUndoableEdit.prototype.add = function(change)
{
this.changes.push(change);
};
mxUndoableEdit.prototype.notify = function() { };
mxUndoableEdit.prototype.die = function() { };
mxUndoableEdit.prototype.undo = function()
{
if (!this.undone)
{
this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
var count = this.changes.length;
for (var i = count - 1; i >= 0; i--)
{
var change = this.changes[i];
if (change.execute != null)
{
change.execute();
}
else if (change.undo != null)
{
change.undo();
}
this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
}
this.undone = true;
this.redone = false;
this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
}
this.notify();
};
mxUndoableEdit.prototype.redo = function()
{
if (!this.redone)
{
this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
var count = this.changes.length;
for (var i = 0; i < count; i++)
{
var change = this.changes[i];
if (change.execute != null)
{
change.execute();
}
else if (change.redo != null)
{
change.redo();
}
this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
}
this.undone = false;
this.redone = true;
this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
}
this.notify();
};
__mxOutput.mxUndoableEdit = typeof mxUndoableEdit !== 'undefined' ? mxUndoableEdit : undefined;
function mxUndoManager(size)
{
this.size = (size != null) ? size : 100;
this.clear();
} mxUndoManager.prototype = new mxEventSource();
mxUndoManager.prototype.constructor = mxUndoManager;
mxUndoManager.prototype.size = null;
mxUndoManager.prototype.history = null;
mxUndoManager.prototype.indexOfNextAdd = 0;
mxUndoManager.prototype.isEmpty = function()
{
return this.history.length == 0;
};
mxUndoManager.prototype.clear = function()
{
this.history = [];
this.indexOfNextAdd = 0;
this.fireEvent(new mxEventObject(mxEvent.CLEAR));
};
mxUndoManager.prototype.canUndo = function()
{
return this.indexOfNextAdd > 0;
};
mxUndoManager.prototype.undo = function()
{
while (this.indexOfNextAdd > 0)
{
var edit = this.history[--this.indexOfNextAdd];
edit.undo();
if (edit.isSignificant())
{
this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
break;
}
}
};
mxUndoManager.prototype.canRedo = function()
{
return this.indexOfNextAdd < this.history.length;
};
mxUndoManager.prototype.redo = function()
{
var n = this.history.length;
while (this.indexOfNextAdd < n)
{
var edit = this.history[this.indexOfNextAdd++];
edit.redo();
if (edit.isSignificant())
{
this.fireEvent(new mxEventObject(mxEvent.REDO, 'edit', edit));
break;
}
}
};
mxUndoManager.prototype.undoableEditHappened = function(undoableEdit)
{
this.trim();
if (this.size > 0 &&
this.size == this.history.length)
{
this.history.shift();
}
this.history.push(undoableEdit);
this.indexOfNextAdd = this.history.length;
this.fireEvent(new mxEventObject(mxEvent.ADD, 'edit', undoableEdit));
};
mxUndoManager.prototype.trim = function()
{
if (this.history.length > this.indexOfNextAdd)
{
var edits = this.history.splice(this.indexOfNextAdd,
this.history.length - this.indexOfNextAdd);
for (var i = 0; i < edits.length; i++)
{
edits[i].die();
}
}
};
__mxOutput.mxUndoManager = typeof mxUndoManager !== 'undefined' ? mxUndoManager : undefined;
var mxUrlConverter = function()
{
};
mxUrlConverter.prototype.enabled = true;
mxUrlConverter.prototype.baseUrl = null;
mxUrlConverter.prototype.baseDomain = null;
mxUrlConverter.prototype.updateBaseUrl = function()
{
this.baseDomain = location.protocol + '//' + location.host;
this.baseUrl = this.baseDomain + location.pathname;
var tmp = this.baseUrl.lastIndexOf('/');
if (tmp > 0)
{
this.baseUrl = this.baseUrl.substring(0, tmp + 1);
}
};
mxUrlConverter.prototype.isEnabled = function()
{
return this.enabled;
};
mxUrlConverter.prototype.setEnabled = function(value)
{
this.enabled = value;
};
mxUrlConverter.prototype.getBaseUrl = function()
{
return this.baseUrl;
};
mxUrlConverter.prototype.setBaseUrl = function(value)
{
this.baseUrl = value;
};
mxUrlConverter.prototype.getBaseDomain = function()
{
return this.baseDomain;
};
mxUrlConverter.prototype.setBaseDomain = function(value)
{
this.baseDomain = value;
};
mxUrlConverter.prototype.isRelativeUrl = function(url)
{
return url != null && url.substring(0, 2) != '//' && url.substring(0, 7) != 'http://' &&
url.substring(0, 8) != 'https://' && url.substring(0, 10) != 'data:image' &&
url.substring(0, 7) != 'file://';
};
mxUrlConverter.prototype.convert = function(url)
{
if (this.isEnabled() && this.isRelativeUrl(url))
{
if (this.getBaseUrl() == null)
{
this.updateBaseUrl();
}
if (url.charAt(0) == '/')
{
url = this.getBaseDomain() + url;
}
else
{
url = this.getBaseUrl() + url;
}
}
return url;
};
__mxOutput.mxUrlConverter = typeof mxUrlConverter !== 'undefined' ? mxUrlConverter : undefined;
function mxPanningManager(graph)
{
this.thread = null;
this.active = false;
this.tdx = 0;
this.tdy = 0;
this.t0x = 0;
this.t0y = 0;
this.dx = 0;
this.dy = 0;
this.scrollbars = false;
this.scrollLeft = 0;
this.scrollTop = 0;
this.mouseListener =
{
mouseDown: function(sender, me) { },
mouseMove: function(sender, me) { },
mouseUp: mxUtils.bind(this, function(sender, me)
{
if (this.active)
{
this.stop();
}
})
};
graph.addMouseListener(this.mouseListener);
this.mouseUpListener = mxUtils.bind(this, function()
{
if (this.active)
{
this.stop();
}
});
mxEvent.addListener(document, 'mouseup', this.mouseUpListener);
var createThread = mxUtils.bind(this, function()
{
this.scrollbars = mxUtils.hasScrollbars(graph.container);
this.scrollLeft = graph.container.scrollLeft;
this.scrollTop = graph.container.scrollTop;
return window.setInterval(mxUtils.bind(this, function()
{
this.tdx -= this.dx;
this.tdy -= this.dy;
if (this.scrollbars)
{
var left = -graph.container.scrollLeft - Math.ceil(this.dx);
var top = -graph.container.scrollTop - Math.ceil(this.dy);
graph.panGraph(left, top);
graph.panDx = this.scrollLeft - graph.container.scrollLeft;
graph.panDy = this.scrollTop - graph.container.scrollTop;
graph.fireEvent(new mxEventObject(mxEvent.PAN));
}
else
{
graph.panGraph(this.getDx(), this.getDy());
}
}), this.delay);
});
this.isActive = function()
{
return active;
};
this.getDx = function()
{
return Math.round(this.tdx);
};
this.getDy = function()
{
return Math.round(this.tdy);
};
this.start = function()
{
this.t0x = graph.view.translate.x;
this.t0y = graph.view.translate.y;
this.active = true;
};
this.panTo = function(x, y, w, h)
{
if (!this.active)
{
this.start();
}
this.scrollLeft = graph.container.scrollLeft;
this.scrollTop = graph.container.scrollTop;
w = (w != null) ? w : 0;
h = (h != null) ? h : 0;
var c = graph.container;
this.dx = x + w - c.scrollLeft - c.clientWidth;
if (this.dx < 0 && Math.abs(this.dx) < this.border)
{
this.dx = this.border + this.dx;
}
else if (this.handleMouseOut)
{
this.dx = Math.max(this.dx, 0);
}
else
{
this.dx = 0;
}
if (this.dx == 0)
{
this.dx = x - c.scrollLeft;
if (this.dx > 0 && this.dx < this.border)
{
this.dx = this.dx - this.border;
}
else if (this.handleMouseOut)
{
this.dx = Math.min(0, this.dx);
}
else
{
this.dx = 0;
}
}
this.dy = y + h - c.scrollTop - c.clientHeight;
if (this.dy < 0 && Math.abs(this.dy) < this.border)
{
this.dy = this.border + this.dy;
}
else if (this.handleMouseOut)
{
this.dy = Math.max(this.dy, 0);
}
else
{
this.dy = 0;
}
if (this.dy == 0)
{
this.dy = y - c.scrollTop;
if (this.dy > 0 && this.dy < this.border)
{
this.dy = this.dy - this.border;
}
else if (this.handleMouseOut)
{
this.dy = Math.min(0, this.dy);
}
else
{
this.dy = 0;
}
}
if (this.dx != 0 || this.dy != 0)
{
this.dx *= this.damper;
this.dy *= this.damper;
if (this.thread == null)
{
this.thread = createThread();
}
}
else if (this.thread != null)
{
window.clearInterval(this.thread);
this.thread = null;
}
};
this.stop = function()
{
if (this.active)
{
this.active = false;
if (this.thread != null)
{
window.clearInterval(this.thread);
this.thread = null;
}
this.tdx = 0;
this.tdy = 0;
if (!this.scrollbars)
{
var px = graph.panDx;
var py = graph.panDy;
if (px != 0 || py != 0)
{
graph.panGraph(0, 0);
graph.view.setTranslate(this.t0x + px / graph.view.scale, this.t0y + py / graph.view.scale);
}
}
else
{
graph.panDx = 0;
graph.panDy = 0;
graph.fireEvent(new mxEventObject(mxEvent.PAN));
}
}
};
this.destroy = function()
{
graph.removeMouseListener(this.mouseListener);
mxEvent.removeListener(document, 'mouseup', this.mouseUpListener);
};
} mxPanningManager.prototype.damper = 1/6;
mxPanningManager.prototype.delay = 10;
mxPanningManager.prototype.handleMouseOut = true;
mxPanningManager.prototype.border = 0;
__mxOutput.mxPanningManager = typeof mxPanningManager !== 'undefined' ? mxPanningManager : undefined;
function mxPopupMenu(factoryMethod)
{
this.factoryMethod = factoryMethod;
if (factoryMethod != null)
{
this.init();
}
} mxPopupMenu.prototype = new mxEventSource();
mxPopupMenu.prototype.constructor = mxPopupMenu;
mxPopupMenu.prototype.submenuImage = mxClient.imageBasePath + '/submenu.gif';
mxPopupMenu.prototype.zIndex = 10006;
mxPopupMenu.prototype.factoryMethod = null;
mxPopupMenu.prototype.useLeftButtonForPopup = false;
mxPopupMenu.prototype.enabled = true;
mxPopupMenu.prototype.itemCount = 0;
mxPopupMenu.prototype.autoExpand = false;
mxPopupMenu.prototype.smartSeparators = false;
mxPopupMenu.prototype.labels = true;
mxPopupMenu.prototype.init = function()
{
this.table = document.createElement('table');
this.table.className = 'mxPopupMenu';
this.tbody = document.createElement('tbody');
this.table.appendChild(this.tbody);
this.div = document.createElement('div');
this.div.className = 'mxPopupMenu';
this.div.style.display = 'inline';
this.div.style.zIndex = this.zIndex;
this.div.appendChild(this.table);
mxEvent.disableContextMenu(this.div);
};
mxPopupMenu.prototype.isEnabled = function()
{
return this.enabled;
};
mxPopupMenu.prototype.setEnabled = function(enabled)
{
this.enabled = enabled;
};
mxPopupMenu.prototype.isPopupTrigger = function(me)
{
return me.isPopupTrigger() || (this.useLeftButtonForPopup && mxEvent.isLeftMouseButton(me.getEvent()));
};
mxPopupMenu.prototype.addItem = function(title, image, funct, parent, iconCls, enabled, active, noHover)
{
parent = parent || this;
this.itemCount++;
if (parent.willAddSeparator)
{
if (parent.containsItems)
{
this.addSeparator(parent, true);
}
parent.willAddSeparator = false;
}
parent.containsItems = true;
var tr = document.createElement('tr');
tr.className = 'mxPopupMenuItem';
var col1 = document.createElement('td');
col1.className = 'mxPopupMenuIcon';
if (image != null)
{
var img = document.createElement('img');
img.src = image;
col1.appendChild(img);
}
else if (iconCls != null)
{
var div = document.createElement('div');
div.className = iconCls;
col1.appendChild(div);
}
tr.appendChild(col1);
if (this.labels)
{
var col2 = document.createElement('td');
col2.className = 'mxPopupMenuItem' +
((enabled != null && !enabled) ? ' mxDisabled' : '');
mxUtils.write(col2, title);
col2.align = 'left';
tr.appendChild(col2);
var col3 = document.createElement('td');
col3.className = 'mxPopupMenuItem' +
((enabled != null && !enabled) ? ' mxDisabled' : '');
col3.style.paddingRight = '6px';
col3.style.textAlign = 'right';
tr.appendChild(col3);
if (parent.div == null)
{
this.createSubmenu(parent);
}
}
parent.tbody.appendChild(tr);
if (active != false && enabled != false)
{
var currentSelection = null;
mxEvent.addGestureListeners(tr,
mxUtils.bind(this, function(evt)
{
this.eventReceiver = tr;
if (parent.activeRow != tr && parent.activeRow != parent)
{
if (parent.activeRow != null && parent.activeRow.div.parentNode != null)
{
this.hideSubmenu(parent);
}
if (tr.div != null)
{
this.showSubmenu(parent, tr);
parent.activeRow = tr;
}
}
if (document.selection != null && (mxClient.IS_QUIRKS || document.documentMode == 8))
{
currentSelection = document.selection.createRange();
}
mxEvent.consume(evt);
}),
mxUtils.bind(this, function(evt)
{
if (parent.activeRow != tr && parent.activeRow != parent)
{
if (parent.activeRow != null && parent.activeRow.div.parentNode != null)
{
this.hideSubmenu(parent);
}
if (this.autoExpand && tr.div != null)
{
this.showSubmenu(parent, tr);
parent.activeRow = tr;
}
}
if (!noHover)
{
tr.className = 'mxPopupMenuItemHover';
}
}),
mxUtils.bind(this, function(evt)
{
if (this.eventReceiver == tr)
{
if (parent.activeRow != tr)
{
this.hideMenu();
}
if (currentSelection != null)
{
try
{
currentSelection.select();
}
catch (e)
{
}
currentSelection = null;
}
if (funct != null)
{
funct(evt);
}
}
this.eventReceiver = null;
mxEvent.consume(evt);
})
);
if (!noHover)
{
mxEvent.addListener(tr, 'mouseout',
mxUtils.bind(this, function(evt)
{
tr.className = 'mxPopupMenuItem';
})
);
}
}
return tr;
};
mxPopupMenu.prototype.addCheckmark = function(item, img)
{
var td = item.firstChild.nextSibling;
td.style.backgroundImage = 'url(\'' + img + '\')';
td.style.backgroundRepeat = 'no-repeat';
td.style.backgroundPosition = '2px 50%';
};
mxPopupMenu.prototype.createSubmenu = function(parent)
{
parent.table = document.createElement('table');
parent.table.className = 'mxPopupMenu';
parent.tbody = document.createElement('tbody');
parent.table.appendChild(parent.tbody);
parent.div = document.createElement('div');
parent.div.className = 'mxPopupMenu';
parent.div.style.position = 'absolute';
parent.div.style.display = 'inline';
parent.div.style.zIndex = this.zIndex;
parent.div.appendChild(parent.table);
var img = document.createElement('img');
img.setAttribute('src', this.submenuImage);
td = parent.firstChild.nextSibling.nextSibling;
td.appendChild(img);
};
mxPopupMenu.prototype.showSubmenu = function(parent, row)
{
if (row.div != null)
{
row.div.style.left = (parent.div.offsetLeft +
row.offsetLeft+row.offsetWidth - 1) + 'px';
row.div.style.top = (parent.div.offsetTop+row.offsetTop) + 'px';
document.body.appendChild(row.div);
var left = parseInt(row.div.offsetLeft);
var width = parseInt(row.div.offsetWidth);
var offset = mxUtils.getDocumentScrollOrigin(document);
var b = document.body;
var d = document.documentElement;
var right = offset.x + (b.clientWidth || d.clientWidth);
if (left + width > right)
{
row.div.style.left = Math.max(0, (parent.div.offsetLeft - width + ((mxClient.IS_IE) ? 6 : -6))) + 'px';
}
mxUtils.fit(row.div);
}
};
mxPopupMenu.prototype.addSeparator = function(parent, force)
{
parent = parent || this;
if (this.smartSeparators && !force)
{
parent.willAddSeparator = true;
}
else if (parent.tbody != null)
{
parent.willAddSeparator = false;
var tr = document.createElement('tr');
var col1 = document.createElement('td');
col1.className = 'mxPopupMenuIcon';
col1.style.padding = '0 0 0 0px';
tr.appendChild(col1);
var col2 = document.createElement('td');
col2.style.padding = '0 0 0 0px';
col2.setAttribute('colSpan', '2');
var hr = document.createElement('hr');
hr.setAttribute('size', '1');
col2.appendChild(hr);
tr.appendChild(col2);
parent.tbody.appendChild(tr);
}
};
mxPopupMenu.prototype.popup = function(x, y, cell, evt)
{
if (this.div != null && this.tbody != null && this.factoryMethod != null)
{
this.div.style.left = x + 'px';
this.div.style.top = y + 'px';
while (this.tbody.firstChild != null)
{
mxEvent.release(this.tbody.firstChild);
this.tbody.removeChild(this.tbody.firstChild);
}
this.itemCount = 0;
this.factoryMethod(this, cell, evt);
if (this.itemCount > 0)
{
this.showMenu();
this.fireEvent(new mxEventObject(mxEvent.SHOW));
}
}
};
mxPopupMenu.prototype.isMenuShowing = function()
{
return this.div != null && this.div.parentNode == document.body;
};
mxPopupMenu.prototype.showMenu = function()
{
if (document.documentMode >= 9)
{
this.div.style.filter = 'none';
}
document.body.appendChild(this.div);
mxUtils.fit(this.div);
};
mxPopupMenu.prototype.hideMenu = function()
{
if (this.div != null)
{
if (this.div.parentNode != null)
{
this.div.parentNode.removeChild(this.div);
}
this.hideSubmenu(this);
this.containsItems = false;
this.fireEvent(new mxEventObject(mxEvent.HIDE));
}
};
mxPopupMenu.prototype.hideSubmenu = function(parent)
{
if (parent.activeRow != null)
{
this.hideSubmenu(parent.activeRow);
if (parent.activeRow.div.parentNode != null)
{
parent.activeRow.div.parentNode.removeChild(parent.activeRow.div);
}
parent.activeRow = null;
}
};
mxPopupMenu.prototype.destroy = function()
{
if (this.div != null)
{
mxEvent.release(this.div);
if (this.div.parentNode != null)
{
this.div.parentNode.removeChild(this.div);
}
this.div = null;
}
};
__mxOutput.mxPopupMenu = typeof mxPopupMenu !== 'undefined' ? mxPopupMenu : undefined;
function mxAutoSaveManager(graph)
{
this.changeHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.isEnabled())
{
this.graphModelChanged(evt.getProperty('edit').changes);
}
});
this.setGraph(graph);
} mxAutoSaveManager.prototype = new mxEventSource();
mxAutoSaveManager.prototype.constructor = mxAutoSaveManager;
mxAutoSaveManager.prototype.graph = null;
mxAutoSaveManager.prototype.autoSaveDelay = 10;
mxAutoSaveManager.prototype.autoSaveThrottle = 2;
mxAutoSaveManager.prototype.autoSaveThreshold = 5;
mxAutoSaveManager.prototype.ignoredChanges = 0;
mxAutoSaveManager.prototype.lastSnapshot = 0;
mxAutoSaveManager.prototype.enabled = true;
mxAutoSaveManager.prototype.changeHandler = null;
mxAutoSaveManager.prototype.isEnabled = function()
{
return this.enabled;
};
mxAutoSaveManager.prototype.setEnabled = function(value)
{
this.enabled = value;
};
mxAutoSaveManager.prototype.setGraph = function(graph)
{
if (this.graph != null)
{
this.graph.getModel().removeListener(this.changeHandler);
}
this.graph = graph;
if (this.graph != null)
{
this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
}
};
mxAutoSaveManager.prototype.save = function()
{
};
mxAutoSaveManager.prototype.graphModelChanged = function(changes)
{
var now = new Date().getTime();
var dt = (now - this.lastSnapshot) / 1000;
if (dt > this.autoSaveDelay ||
(this.ignoredChanges >= this.autoSaveThreshold &&
dt > this.autoSaveThrottle))
{
this.save();
this.reset();
}
else
{
this.ignoredChanges++;
}
};
mxAutoSaveManager.prototype.reset = function()
{
this.lastSnapshot = new Date().getTime();
this.ignoredChanges = 0;
};
mxAutoSaveManager.prototype.destroy = function()
{
this.setGraph(null);
};
__mxOutput.mxAutoSaveManager = typeof mxAutoSaveManager !== 'undefined' ? mxAutoSaveManager : undefined;
function mxAnimation(delay)
{
this.delay = (delay != null) ? delay : 20;
} mxAnimation.prototype = new mxEventSource();
mxAnimation.prototype.constructor = mxAnimation;
mxAnimation.prototype.delay = null;
mxAnimation.prototype.thread = null;
mxAnimation.prototype.isRunning = function()
{
return this.thread != null;
};
mxAnimation.prototype.startAnimation = function()
{
if (this.thread == null)
{
this.thread = window.setInterval(mxUtils.bind(this, this.updateAnimation), this.delay);
}
};
mxAnimation.prototype.updateAnimation = function()
{
this.fireEvent(new mxEventObject(mxEvent.EXECUTE));
};
mxAnimation.prototype.stopAnimation = function()
{
if (this.thread != null)
{
window.clearInterval(this.thread);
this.thread = null;
this.fireEvent(new mxEventObject(mxEvent.DONE));
}
};
__mxOutput.mxAnimation = typeof mxAnimation !== 'undefined' ? mxAnimation : undefined;
function mxMorphing(graph, steps, ease, delay)
{
mxAnimation.call(this, delay);
this.graph = graph;
this.steps = (steps != null) ? steps : 6;
this.ease = (ease != null) ? ease : 1.5;
} mxMorphing.prototype = new mxAnimation();
mxMorphing.prototype.constructor = mxMorphing;
mxMorphing.prototype.graph = null;
mxMorphing.prototype.steps = null;
mxMorphing.prototype.step = 0;
mxMorphing.prototype.ease = null;
mxMorphing.prototype.cells = null;
mxMorphing.prototype.updateAnimation = function()
{
mxAnimation.prototype.updateAnimation.apply(this, arguments);
var move = new mxCellStatePreview(this.graph);
if (this.cells != null)
{
for (var i = 0; i < this.cells.length; i++)
{
this.animateCell(this.cells[i], move, false);
}
}
else
{
this.animateCell(this.graph.getModel().getRoot(), move, true);
}
this.show(move);
if (move.isEmpty() || this.step++ >= this.steps)
{
this.stopAnimation();
}
};
mxMorphing.prototype.show = function(move)
{
move.show();
};
mxMorphing.prototype.animateCell = function(cell, move, recurse)
{
var state = this.graph.getView().getState(cell);
var delta = null;
if (state != null)
{
delta = this.getDelta(state);
if (this.graph.getModel().isVertex(cell) && (delta.x != 0 || delta.y != 0))
{
var translate = this.graph.view.getTranslate();
var scale = this.graph.view.getScale();
delta.x += translate.x * scale;
delta.y += translate.y * scale;
move.moveState(state, -delta.x / this.ease, -delta.y / this.ease);
}
}
if (recurse && !this.stopRecursion(state, delta))
{
var childCount = this.graph.getModel().getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
this.animateCell(this.graph.getModel().getChildAt(cell, i), move, recurse);
}
}
};
mxMorphing.prototype.stopRecursion = function(state, delta)
{
return delta != null && (delta.x != 0 || delta.y != 0);
};
mxMorphing.prototype.getDelta = function(state)
{
var origin = this.getOriginForCell(state.cell);
var translate = this.graph.getView().getTranslate();
var scale = this.graph.getView().getScale();
var x = state.x / scale - translate.x;
var y = state.y / scale - translate.y;
return new mxPoint((origin.x - x) * scale, (origin.y - y) * scale);
};
mxMorphing.prototype.getOriginForCell = function(cell)
{
var result = null;
if (cell != null)
{
var parent = this.graph.getModel().getParent(cell);
var geo = this.graph.getCellGeometry(cell);
result = this.getOriginForCell(parent);
if (geo != null)
{
if (geo.relative)
{
var pgeo = this.graph.getCellGeometry(parent);
if (pgeo != null)
{
result.x += geo.x * pgeo.width;
result.y += geo.y * pgeo.height;
}
}
else
{
result.x += geo.x;
result.y += geo.y;
}
}
}
if (result == null)
{
var t = this.graph.view.getTranslate();
result = new mxPoint(-t.x, -t.y);
}
return result;
};
__mxOutput.mxMorphing = typeof mxMorphing !== 'undefined' ? mxMorphing : undefined;
function mxImageBundle(alt)
{
this.images = [];
this.alt = (alt != null) ? alt : false;
} mxImageBundle.prototype.images = null;
mxImageBundle.prototype.alt = null;
mxImageBundle.prototype.putImage = function(key, value, fallback)
{
this.images[key] = {value: value, fallback: fallback};
};
mxImageBundle.prototype.getImage = function(key)
{
var result = null;
if (key != null)
{
var img = this.images[key];
if (img != null)
{
result = (this.alt) ? img.fallback : img.value;
}
}
return result;
};
__mxOutput.mxImageBundle = typeof mxImageBundle !== 'undefined' ? mxImageBundle : undefined;
function mxImageExport() { } mxImageExport.prototype.includeOverlays = false;
mxImageExport.prototype.drawState = function(state, canvas)
{
if (state != null)
{
this.visitStatesRecursive(state, canvas, mxUtils.bind(this, function()
{
this.drawCellState.apply(this, arguments);
}));
if (this.includeOverlays)
{
this.visitStatesRecursive(state, canvas, mxUtils.bind(this, function()
{
this.drawOverlays.apply(this, arguments);
}));
}
}
};
mxImageExport.prototype.visitStatesRecursive = function(state, canvas, visitor)
{
if (state != null)
{
visitor(state, canvas);
var graph = state.view.graph;
var childCount = graph.model.getChildCount(state.cell);
for (var i = 0; i < childCount; i++)
{
var childState = graph.view.getState(graph.model.getChildAt(state.cell, i));
this.visitStatesRecursive(childState, canvas, visitor);
}
}
};
mxImageExport.prototype.getLinkForCellState = function(state, canvas)
{
return null;
};
mxImageExport.prototype.drawCellState = function(state, canvas)
{
var link = this.getLinkForCellState(state, canvas);
if (link != null)
{
canvas.setLink(link);
}
this.drawShape(state, canvas);
this.drawText(state, canvas);
if (link != null)
{
canvas.setLink(null);
}
};
mxImageExport.prototype.drawShape = function(state, canvas)
{
if (state.shape instanceof mxShape && state.shape.checkBounds())
{
canvas.save();
state.shape.beforePaint(canvas);
state.shape.paint(canvas);
state.shape.afterPaint(canvas);
canvas.restore();
}
};
mxImageExport.prototype.drawText = function(state, canvas)
{
if (state.text != null && state.text.checkBounds())
{
canvas.save();
state.text.beforePaint(canvas);
state.text.paint(canvas);
state.text.afterPaint(canvas);
canvas.restore();
}
};
mxImageExport.prototype.drawOverlays = function(state, canvas)
{
if (state.overlays != null)
{
state.overlays.visit(function(id, shape)
{
if (shape instanceof mxShape)
{
shape.paint(canvas);
}
});
}
};
__mxOutput.mxImageExport = typeof mxImageExport !== 'undefined' ? mxImageExport : undefined;
function mxAbstractCanvas2D()
{
this.converter = this.createUrlConverter();
this.reset();
} mxAbstractCanvas2D.prototype.state = null;
mxAbstractCanvas2D.prototype.states = null;
mxAbstractCanvas2D.prototype.path = null;
mxAbstractCanvas2D.prototype.rotateHtml = true;
mxAbstractCanvas2D.prototype.lastX = 0;
mxAbstractCanvas2D.prototype.lastY = 0;
mxAbstractCanvas2D.prototype.moveOp = 'M';
mxAbstractCanvas2D.prototype.lineOp = 'L';
mxAbstractCanvas2D.prototype.quadOp = 'Q';
mxAbstractCanvas2D.prototype.curveOp = 'C';
mxAbstractCanvas2D.prototype.closeOp = 'Z';
mxAbstractCanvas2D.prototype.pointerEvents = false;
mxAbstractCanvas2D.prototype.createUrlConverter = function()
{
return new mxUrlConverter();
};
mxAbstractCanvas2D.prototype.reset = function()
{
this.state = this.createState();
this.states = [];
};
mxAbstractCanvas2D.prototype.createState = function()
{
return {
dx: 0,
dy: 0,
scale: 1,
alpha: 1,
fillAlpha: 1,
strokeAlpha: 1,
fillColor: null,
gradientFillAlpha: 1,
gradientColor: null,
gradientAlpha: 1,
gradientDirection: null,
strokeColor: null,
strokeWidth: 1,
dashed: false,
dashPattern: '3 3',
fixDash: false,
lineCap: 'flat',
lineJoin: 'miter',
miterLimit: 10,
fontColor: '#000000',
fontBackgroundColor: null,
fontBorderColor: null,
fontSize: mxConstants.DEFAULT_FONTSIZE,
fontFamily: mxConstants.DEFAULT_FONTFAMILY,
fontStyle: 0,
shadow: false,
shadowColor: mxConstants.SHADOWCOLOR,
shadowAlpha: mxConstants.SHADOW_OPACITY,
shadowDx: mxConstants.SHADOW_OFFSET_X,
shadowDy: mxConstants.SHADOW_OFFSET_Y,
rotation: 0,
rotationCx: 0,
rotationCy: 0
};
};
mxAbstractCanvas2D.prototype.format = function(value)
{
return Math.round(parseFloat(value));
};
mxAbstractCanvas2D.prototype.addOp = function()
{
if (this.path != null)
{
this.path.push(arguments[0]);
if (arguments.length > 2)
{
var s = this.state;
for (var i = 2; i < arguments.length; i += 2)
{
this.lastX = arguments[i - 1];
this.lastY = arguments[i];
this.path.push(this.format((this.lastX + s.dx) * s.scale));
this.path.push(this.format((this.lastY + s.dy) * s.scale));
}
}
}
};
mxAbstractCanvas2D.prototype.rotatePoint = function(x, y, theta, cx, cy)
{
var rad = theta * (Math.PI / 180);
return mxUtils.getRotatedPoint(new mxPoint(x, y), Math.cos(rad),
Math.sin(rad), new mxPoint(cx, cy));
};
mxAbstractCanvas2D.prototype.save = function()
{
this.states.push(this.state);
this.state = mxUtils.clone(this.state);
};
mxAbstractCanvas2D.prototype.restore = function()
{
if (this.states.length > 0)
{
this.state = this.states.pop();
}
};
mxAbstractCanvas2D.prototype.setLink = function(link)
{
};
mxAbstractCanvas2D.prototype.scale = function(value)
{
this.state.scale *= value;
this.state.strokeWidth *= value;
};
mxAbstractCanvas2D.prototype.translate = function(dx, dy)
{
this.state.dx += dx;
this.state.dy += dy;
};
mxAbstractCanvas2D.prototype.rotate = function(theta, flipH, flipV, cx, cy)
{
};
mxAbstractCanvas2D.prototype.setAlpha = function(value)
{
this.state.alpha = value;
};
mxAbstractCanvas2D.prototype.setFillAlpha = function(value)
{
this.state.fillAlpha = value;
};
mxAbstractCanvas2D.prototype.setStrokeAlpha = function(value)
{
this.state.strokeAlpha = value;
};
mxAbstractCanvas2D.prototype.setFillColor = function(value)
{
if (value == mxConstants.NONE)
{
value = null;
}
this.state.fillColor = value;
this.state.gradientColor = null;
};
mxAbstractCanvas2D.prototype.setGradient = function(color1, color2, x, y, w, h, direction, alpha1, alpha2)
{
var s = this.state;
s.fillColor = color1;
s.gradientFillAlpha = (alpha1 != null) ? alpha1 : 1;
s.gradientColor = color2;
s.gradientAlpha = (alpha2 != null) ? alpha2 : 1;
s.gradientDirection = direction;
};
mxAbstractCanvas2D.prototype.setStrokeColor = function(value)
{
if (value == mxConstants.NONE)
{
value = null;
}
this.state.strokeColor = value;
};
mxAbstractCanvas2D.prototype.setStrokeWidth = function(value)
{
this.state.strokeWidth = value;
};
mxAbstractCanvas2D.prototype.setDashed = function(value, fixDash)
{
this.state.dashed = value;
this.state.fixDash = fixDash;
};
mxAbstractCanvas2D.prototype.setDashPattern = function(value)
{
this.state.dashPattern = value;
};
mxAbstractCanvas2D.prototype.setLineCap = function(value)
{
this.state.lineCap = value;
};
mxAbstractCanvas2D.prototype.setLineJoin = function(value)
{
this.state.lineJoin = value;
};
mxAbstractCanvas2D.prototype.setMiterLimit = function(value)
{
this.state.miterLimit = value;
};
mxAbstractCanvas2D.prototype.setFontColor = function(value)
{
if (value == mxConstants.NONE)
{
value = null;
}
this.state.fontColor = value;
};
mxAbstractCanvas2D.prototype.setFontBackgroundColor = function(value)
{
if (value == mxConstants.NONE)
{
value = null;
}
this.state.fontBackgroundColor = value;
};
mxAbstractCanvas2D.prototype.setFontBorderColor = function(value)
{
if (value == mxConstants.NONE)
{
value = null;
}
this.state.fontBorderColor = value;
};
mxAbstractCanvas2D.prototype.setFontSize = function(value)
{
this.state.fontSize = parseFloat(value);
};
mxAbstractCanvas2D.prototype.setFontFamily = function(value)
{
this.state.fontFamily = value;
};
mxAbstractCanvas2D.prototype.setFontStyle = function(value)
{
if (value == null)
{
value = 0;
}
this.state.fontStyle = value;
};
mxAbstractCanvas2D.prototype.setShadow = function(enabled)
{
this.state.shadow = enabled;
};
mxAbstractCanvas2D.prototype.setShadowColor = function(value)
{
if (value == mxConstants.NONE)
{
value = null;
}
this.state.shadowColor = value;
};
mxAbstractCanvas2D.prototype.setShadowAlpha = function(value)
{
this.state.shadowAlpha = value;
};
mxAbstractCanvas2D.prototype.setShadowOffset = function(dx, dy)
{
this.state.shadowDx = dx;
this.state.shadowDy = dy;
};
mxAbstractCanvas2D.prototype.begin = function()
{
this.lastX = 0;
this.lastY = 0;
this.path = [];
};
mxAbstractCanvas2D.prototype.moveTo = function(x, y)
{
this.addOp(this.moveOp, x, y);
};
mxAbstractCanvas2D.prototype.lineTo = function(x, y)
{
this.addOp(this.lineOp, x, y);
};
mxAbstractCanvas2D.prototype.quadTo = function(x1, y1, x2, y2)
{
this.addOp(this.quadOp, x1, y1, x2, y2);
};
mxAbstractCanvas2D.prototype.curveTo = function(x1, y1, x2, y2, x3, y3)
{
this.addOp(this.curveOp, x1, y1, x2, y2, x3, y3);
};
mxAbstractCanvas2D.prototype.arcTo = function(rx, ry, angle, largeArcFlag, sweepFlag, x, y)
{
var curves = mxUtils.arcToCurves(this.lastX, this.lastY, rx, ry, angle, largeArcFlag, sweepFlag, x, y);
if (curves != null)
{
for (var i = 0; i < curves.length; i += 6)
{
this.curveTo(curves[i], curves[i + 1], curves[i + 2],
curves[i + 3], curves[i + 4], curves[i + 5]);
}
}
};
mxAbstractCanvas2D.prototype.close = function(x1, y1, x2, y2, x3, y3)
{
this.addOp(this.closeOp);
};
mxAbstractCanvas2D.prototype.end = function() { };
__mxOutput.mxAbstractCanvas2D = typeof mxAbstractCanvas2D !== 'undefined' ? mxAbstractCanvas2D : undefined;
function mxXmlCanvas2D(root)
{
mxAbstractCanvas2D.call(this);
this.root = root;
this.writeDefaults();
} mxUtils.extend(mxXmlCanvas2D, mxAbstractCanvas2D);
mxXmlCanvas2D.prototype.textEnabled = true;
mxXmlCanvas2D.prototype.compressed = true;
mxXmlCanvas2D.prototype.writeDefaults = function()
{
var elem;
elem = this.createElement('fontfamily');
elem.setAttribute('family', mxConstants.DEFAULT_FONTFAMILY);
this.root.appendChild(elem);
elem = this.createElement('fontsize');
elem.setAttribute('size', mxConstants.DEFAULT_FONTSIZE);
this.root.appendChild(elem);
elem = this.createElement('shadowcolor');
elem.setAttribute('color', mxConstants.SHADOWCOLOR);
this.root.appendChild(elem);
elem = this.createElement('shadowalpha');
elem.setAttribute('alpha', mxConstants.SHADOW_OPACITY);
this.root.appendChild(elem);
elem = this.createElement('shadowoffset');
elem.setAttribute('dx', mxConstants.SHADOW_OFFSET_X);
elem.setAttribute('dy', mxConstants.SHADOW_OFFSET_Y);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.format = function(value)
{
return parseFloat(parseFloat(value).toFixed(2));
};
mxXmlCanvas2D.prototype.createElement = function(name)
{
return this.root.ownerDocument.createElement(name);
};
mxXmlCanvas2D.prototype.save = function()
{
if (this.compressed)
{
mxAbstractCanvas2D.prototype.save.apply(this, arguments);
}
this.root.appendChild(this.createElement('save'));
};
mxXmlCanvas2D.prototype.restore = function()
{
if (this.compressed)
{
mxAbstractCanvas2D.prototype.restore.apply(this, arguments);
}
this.root.appendChild(this.createElement('restore'));
};
mxXmlCanvas2D.prototype.scale = function(value)
{
var elem = this.createElement('scale');
elem.setAttribute('scale', value);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.translate = function(dx, dy)
{
var elem = this.createElement('translate');
elem.setAttribute('dx', this.format(dx));
elem.setAttribute('dy', this.format(dy));
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.rotate = function(theta, flipH, flipV, cx, cy)
{
var elem = this.createElement('rotate');
if (theta != 0 || flipH || flipV)
{
elem.setAttribute('theta', this.format(theta));
elem.setAttribute('flipH', (flipH) ? '1' : '0');
elem.setAttribute('flipV', (flipV) ? '1' : '0');
elem.setAttribute('cx', this.format(cx));
elem.setAttribute('cy', this.format(cy));
this.root.appendChild(elem);
}
};
mxXmlCanvas2D.prototype.setAlpha = function(value)
{
if (this.compressed)
{
if (this.state.alpha == value)
{
return;
}
mxAbstractCanvas2D.prototype.setAlpha.apply(this, arguments);
}
var elem = this.createElement('alpha');
elem.setAttribute('alpha', this.format(value));
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setFillAlpha = function(value)
{
if (this.compressed)
{
if (this.state.fillAlpha == value)
{
return;
}
mxAbstractCanvas2D.prototype.setFillAlpha.apply(this, arguments);
}
var elem = this.createElement('fillalpha');
elem.setAttribute('alpha', this.format(value));
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setStrokeAlpha = function(value)
{
if (this.compressed)
{
if (this.state.strokeAlpha == value)
{
return;
}
mxAbstractCanvas2D.prototype.setStrokeAlpha.apply(this, arguments);
}
var elem = this.createElement('strokealpha');
elem.setAttribute('alpha', this.format(value));
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setFillColor = function(value)
{
if (value == mxConstants.NONE)
{
value = null;
}
if (this.compressed)
{
if (this.state.fillColor == value)
{
return;
}
mxAbstractCanvas2D.prototype.setFillColor.apply(this, arguments);
}
var elem = this.createElement('fillcolor');
elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setGradient = function(color1, color2, x, y, w, h, direction, alpha1, alpha2)
{
if (color1 != null && color2 != null)
{
mxAbstractCanvas2D.prototype.setGradient.apply(this, arguments);
var elem = this.createElement('gradient');
elem.setAttribute('c1', color1);
elem.setAttribute('c2', color2);
elem.setAttribute('x', this.format(x));
elem.setAttribute('y', this.format(y));
elem.setAttribute('w', this.format(w));
elem.setAttribute('h', this.format(h));
if (direction != null)
{
elem.setAttribute('direction', direction);
}
if (alpha1 != null)
{
elem.setAttribute('alpha1', alpha1);
}
if (alpha2 != null)
{
elem.setAttribute('alpha2', alpha2);
}
this.root.appendChild(elem);
}
};
mxXmlCanvas2D.prototype.setStrokeColor = function(value)
{
if (value == mxConstants.NONE)
{
value = null;
}
if (this.compressed)
{
if (this.state.strokeColor == value)
{
return;
}
mxAbstractCanvas2D.prototype.setStrokeColor.apply(this, arguments);
}
var elem = this.createElement('strokecolor');
elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setStrokeWidth = function(value)
{
if (this.compressed)
{
if (this.state.strokeWidth == value)
{
return;
}
mxAbstractCanvas2D.prototype.setStrokeWidth.apply(this, arguments);
}
var elem = this.createElement('strokewidth');
elem.setAttribute('width', this.format(value));
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setDashed = function(value, fixDash)
{
if (this.compressed)
{
if (this.state.dashed == value)
{
return;
}
mxAbstractCanvas2D.prototype.setDashed.apply(this, arguments);
}
var elem = this.createElement('dashed');
elem.setAttribute('dashed', (value) ? '1' : '0');
if (fixDash != null)
{
elem.setAttribute('fixDash', (fixDash) ? '1' : '0');
}
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setDashPattern = function(value)
{
if (this.compressed)
{
if (this.state.dashPattern == value)
{
return;
}
mxAbstractCanvas2D.prototype.setDashPattern.apply(this, arguments);
}
var elem = this.createElement('dashpattern');
elem.setAttribute('pattern', value);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setLineCap = function(value)
{
if (this.compressed)
{
if (this.state.lineCap == value)
{
return;
}
mxAbstractCanvas2D.prototype.setLineCap.apply(this, arguments);
}
var elem = this.createElement('linecap');
elem.setAttribute('cap', value);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setLineJoin = function(value)
{
if (this.compressed)
{
if (this.state.lineJoin == value)
{
return;
}
mxAbstractCanvas2D.prototype.setLineJoin.apply(this, arguments);
}
var elem = this.createElement('linejoin');
elem.setAttribute('join', value);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setMiterLimit = function(value)
{
if (this.compressed)
{
if (this.state.miterLimit == value)
{
return;
}
mxAbstractCanvas2D.prototype.setMiterLimit.apply(this, arguments);
}
var elem = this.createElement('miterlimit');
elem.setAttribute('limit', value);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setFontColor = function(value)
{
if (this.textEnabled)
{
if (value == mxConstants.NONE)
{
value = null;
}
if (this.compressed)
{
if (this.state.fontColor == value)
{
return;
}
mxAbstractCanvas2D.prototype.setFontColor.apply(this, arguments);
}
var elem = this.createElement('fontcolor');
elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
this.root.appendChild(elem);
}
};
mxXmlCanvas2D.prototype.setFontBackgroundColor = function(value)
{
if (this.textEnabled)
{
if (value == mxConstants.NONE)
{
value = null;
}
if (this.compressed)
{
if (this.state.fontBackgroundColor == value)
{
return;
}
mxAbstractCanvas2D.prototype.setFontBackgroundColor.apply(this, arguments);
}
var elem = this.createElement('fontbackgroundcolor');
elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
this.root.appendChild(elem);
}
};
mxXmlCanvas2D.prototype.setFontBorderColor = function(value)
{
if (this.textEnabled)
{
if (value == mxConstants.NONE)
{
value = null;
}
if (this.compressed)
{
if (this.state.fontBorderColor == value)
{
return;
}
mxAbstractCanvas2D.prototype.setFontBorderColor.apply(this, arguments);
}
var elem = this.createElement('fontbordercolor');
elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
this.root.appendChild(elem);
}
};
mxXmlCanvas2D.prototype.setFontSize = function(value)
{
if (this.textEnabled)
{
if (this.compressed)
{
if (this.state.fontSize == value)
{
return;
}
mxAbstractCanvas2D.prototype.setFontSize.apply(this, arguments);
}
var elem = this.createElement('fontsize');
elem.setAttribute('size', value);
this.root.appendChild(elem);
}
};
mxXmlCanvas2D.prototype.setFontFamily = function(value)
{
if (this.textEnabled)
{
if (this.compressed)
{
if (this.state.fontFamily == value)
{
return;
}
mxAbstractCanvas2D.prototype.setFontFamily.apply(this, arguments);
}
var elem = this.createElement('fontfamily');
elem.setAttribute('family', value);
this.root.appendChild(elem);
}
};
mxXmlCanvas2D.prototype.setFontStyle = function(value)
{
if (this.textEnabled)
{
if (value == null)
{
value = 0;
}
if (this.compressed)
{
if (this.state.fontStyle == value)
{
return;
}
mxAbstractCanvas2D.prototype.setFontStyle.apply(this, arguments);
}
var elem = this.createElement('fontstyle');
elem.setAttribute('style', value);
this.root.appendChild(elem);
}
};
mxXmlCanvas2D.prototype.setShadow = function(value)
{
if (this.compressed)
{
if (this.state.shadow == value)
{
return;
}
mxAbstractCanvas2D.prototype.setShadow.apply(this, arguments);
}
var elem = this.createElement('shadow');
elem.setAttribute('enabled', (value) ? '1' : '0');
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setShadowColor = function(value)
{
if (this.compressed)
{
if (value == mxConstants.NONE)
{
value = null;
}
if (this.state.shadowColor == value)
{
return;
}
mxAbstractCanvas2D.prototype.setShadowColor.apply(this, arguments);
}
var elem = this.createElement('shadowcolor');
elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setShadowAlpha = function(value)
{
if (this.compressed)
{
if (this.state.shadowAlpha == value)
{
return;
}
mxAbstractCanvas2D.prototype.setShadowAlpha.apply(this, arguments);
}
var elem = this.createElement('shadowalpha');
elem.setAttribute('alpha', value);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.setShadowOffset = function(dx, dy)
{
if (this.compressed)
{
if (this.state.shadowDx == dx && this.state.shadowDy == dy)
{
return;
}
mxAbstractCanvas2D.prototype.setShadowOffset.apply(this, arguments);
}
var elem = this.createElement('shadowoffset');
elem.setAttribute('dx', dx);
elem.setAttribute('dy', dy);
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.rect = function(x, y, w, h)
{
var elem = this.createElement('rect');
elem.setAttribute('x', this.format(x));
elem.setAttribute('y', this.format(y));
elem.setAttribute('w', this.format(w));
elem.setAttribute('h', this.format(h));
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.roundrect = function(x, y, w, h, dx, dy)
{
var elem = this.createElement('roundrect');
elem.setAttribute('x', this.format(x));
elem.setAttribute('y', this.format(y));
elem.setAttribute('w', this.format(w));
elem.setAttribute('h', this.format(h));
elem.setAttribute('dx', this.format(dx));
elem.setAttribute('dy', this.format(dy));
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.ellipse = function(x, y, w, h)
{
var elem = this.createElement('ellipse');
elem.setAttribute('x', this.format(x));
elem.setAttribute('y', this.format(y));
elem.setAttribute('w', this.format(w));
elem.setAttribute('h', this.format(h));
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.image = function(x, y, w, h, src, aspect, flipH, flipV)
{
src = this.converter.convert(src);
var elem = this.createElement('image');
elem.setAttribute('x', this.format(x));
elem.setAttribute('y', this.format(y));
elem.setAttribute('w', this.format(w));
elem.setAttribute('h', this.format(h));
elem.setAttribute('src', src);
elem.setAttribute('aspect', (aspect) ? '1' : '0');
elem.setAttribute('flipH', (flipH) ? '1' : '0');
elem.setAttribute('flipV', (flipV) ? '1' : '0');
this.root.appendChild(elem);
};
mxXmlCanvas2D.prototype.begin = function()
{
this.root.appendChild(this.createElement('begin'));
this.lastX = 0;
this.lastY = 0;
};
mxXmlCanvas2D.prototype.moveTo = function(x, y)
{
var elem = this.createElement('move');
elem.setAttribute('x', this.format(x));
elem.setAttribute('y', this.format(y));
this.root.appendChild(elem);
this.lastX = x;
this.lastY = y;
};
mxXmlCanvas2D.prototype.lineTo = function(x, y)
{
var elem = this.createElement('line');
elem.setAttribute('x', this.format(x));
elem.setAttribute('y', this.format(y));
this.root.appendChild(elem);
this.lastX = x;
this.lastY = y;
};
mxXmlCanvas2D.prototype.quadTo = function(x1, y1, x2, y2)
{
var elem = this.createElement('quad');
elem.setAttribute('x1', this.format(x1));
elem.setAttribute('y1', this.format(y1));
elem.setAttribute('x2', this.format(x2));
elem.setAttribute('y2', this.format(y2));
this.root.appendChild(elem);
this.lastX = x2;
this.lastY = y2;
};
mxXmlCanvas2D.prototype.curveTo = function(x1, y1, x2, y2, x3, y3)
{
var elem = this.createElement('curve');
elem.setAttribute('x1', this.format(x1));
elem.setAttribute('y1', this.format(y1));
elem.setAttribute('x2', this.format(x2));
elem.setAttribute('y2', this.format(y2));
elem.setAttribute('x3', this.format(x3));
elem.setAttribute('y3', this.format(y3));
this.root.appendChild(elem);
this.lastX = x3;
this.lastY = y3;
};
mxXmlCanvas2D.prototype.close = function()
{
this.root.appendChild(this.createElement('close'));
};
mxXmlCanvas2D.prototype.text = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir)
{
if (this.textEnabled && str != null)
{
if (mxUtils.isNode(str))
{
str = mxUtils.getOuterHtml(str);
}
var elem = this.createElement('text');
elem.setAttribute('x', this.format(x));
elem.setAttribute('y', this.format(y));
elem.setAttribute('w', this.format(w));
elem.setAttribute('h', this.format(h));
elem.setAttribute('str', str);
if (align != null)
{
elem.setAttribute('align', align);
}
if (valign != null)
{
elem.setAttribute('valign', valign);
}
elem.setAttribute('wrap', (wrap) ? '1' : '0');
if (format == null)
{
format = '';
}
elem.setAttribute('format', format);
if (overflow != null)
{
elem.setAttribute('overflow', overflow);
}
if (clip != null)
{
elem.setAttribute('clip', (clip) ? '1' : '0');
}
if (rotation != null)
{
elem.setAttribute('rotation', rotation);
}
if (dir != null)
{
elem.setAttribute('dir', dir);
}
this.root.appendChild(elem);
}
};
mxXmlCanvas2D.prototype.stroke = function()
{
this.root.appendChild(this.createElement('stroke'));
};
mxXmlCanvas2D.prototype.fill = function()
{
this.root.appendChild(this.createElement('fill'));
};
mxXmlCanvas2D.prototype.fillAndStroke = function()
{
this.root.appendChild(this.createElement('fillstroke'));
};
__mxOutput.mxXmlCanvas2D = typeof mxXmlCanvas2D !== 'undefined' ? mxXmlCanvas2D : undefined;
function mxSvgCanvas2D(root, styleEnabled)
{
mxAbstractCanvas2D.call(this);
this.root = root;
this.gradients = [];
this.defs = null;
this.styleEnabled = (styleEnabled != null) ? styleEnabled : false;
var svg = null;
if (root.ownerDocument != document)
{
var node = root;
while (node != null && node.nodeName != 'svg')
{
node = node.parentNode;
}
svg = node;
}
if (svg != null)
{
var tmp = svg.getElementsByTagName('defs');
if (tmp.length > 0)
{
this.defs = svg.getElementsByTagName('defs')[0];
}
if (this.defs == null)
{
this.defs = this.createElement('defs');
if (svg.firstChild != null)
{
svg.insertBefore(this.defs, svg.firstChild);
}
else
{
svg.appendChild(this.defs);
}
}
if (this.styleEnabled)
{
this.defs.appendChild(this.createStyle());
}
}
} mxUtils.extend(mxSvgCanvas2D, mxAbstractCanvas2D);
(function()
{
mxSvgCanvas2D.prototype.useDomParser = !mxClient.IS_IE && typeof DOMParser === 'function' && typeof XMLSerializer === 'function';
if (mxSvgCanvas2D.prototype.useDomParser)
{
try
{
var doc = new DOMParser().parseFromString('test text', 'text/html');
mxSvgCanvas2D.prototype.useDomParser = doc != null;
}
catch (e)
{
mxSvgCanvas2D.prototype.useDomParser = false;
}
}
mxSvgCanvas2D.prototype.useAbsoluteIds = !mxClient.IS_CHROMEAPP && !mxClient.IS_IE && !mxClient.IS_IE11 &&
!mxClient.IS_EDGE && document.getElementsByTagName('base').length > 0;
})();
mxSvgCanvas2D.prototype.node = null;
mxSvgCanvas2D.prototype.matchHtmlAlignment = true;
mxSvgCanvas2D.prototype.textEnabled = true;
mxSvgCanvas2D.prototype.foEnabled = true;
mxSvgCanvas2D.prototype.foAltText = '[Object]';
mxSvgCanvas2D.prototype.foOffset = 0;
mxSvgCanvas2D.prototype.textOffset = 0;
mxSvgCanvas2D.prototype.imageOffset = 0;
mxSvgCanvas2D.prototype.strokeTolerance = 0;
mxSvgCanvas2D.prototype.minStrokeWidth = 1;
mxSvgCanvas2D.prototype.refCount = 0;
mxSvgCanvas2D.prototype.lineHeightCorrection = 1;
mxSvgCanvas2D.prototype.pointerEventsValue = 'all';
mxSvgCanvas2D.prototype.fontMetricsPadding = 10;
mxSvgCanvas2D.prototype.cacheOffsetSize = true;
mxSvgCanvas2D.prototype.format = function(value)
{
return parseFloat(parseFloat(value).toFixed(2));
};
mxSvgCanvas2D.prototype.getBaseUrl = function()
{
var href = window.location.href;
var hash = href.lastIndexOf('#');
if (hash > 0)
{
href = href.substring(0, hash);
}
return href;
};
mxSvgCanvas2D.prototype.reset = function()
{
mxAbstractCanvas2D.prototype.reset.apply(this, arguments);
this.gradients = [];
};
mxSvgCanvas2D.prototype.createStyle = function(x)
{
var style = this.createElement('style');
style.setAttribute('type', 'text/css');
mxUtils.write(style, 'svg{font-family:' + mxConstants.DEFAULT_FONTFAMILY +
';font-size:' + mxConstants.DEFAULT_FONTSIZE +
';fill:none;stroke-miterlimit:10}');
return style;
};
mxSvgCanvas2D.prototype.createElement = function(tagName, namespace)
{
if (this.root.ownerDocument.createElementNS != null)
{
return this.root.ownerDocument.createElementNS(namespace || mxConstants.NS_SVG, tagName);
}
else
{
var elt = this.root.ownerDocument.createElement(tagName);
if (namespace != null)
{
elt.setAttribute('xmlns', namespace);
}
return elt;
}
};
mxSvgCanvas2D.prototype.getAlternateText = function(fo, x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation)
{
return (str != null) ? this.foAltText : null;
};
mxSvgCanvas2D.prototype.createAlternateContent = function(fo, x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation)
{
var text = this.getAlternateText(fo, x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation);
var s = this.state;
if (text != null && s.fontSize > 0)
{
var dy = (valign == mxConstants.ALIGN_TOP) ? 1 :
(valign == mxConstants.ALIGN_BOTTOM) ? 0 : 0.3;
var anchor = (align == mxConstants.ALIGN_RIGHT) ? 'end' :
(align == mxConstants.ALIGN_LEFT) ? 'start' :
'middle';
var alt = this.createElement('text');
alt.setAttribute('x', Math.round(x + s.dx));
alt.setAttribute('y', Math.round(y + s.dy + dy * s.fontSize));
alt.setAttribute('fill', s.fontColor || 'black');
alt.setAttribute('font-family', s.fontFamily);
alt.setAttribute('font-size', Math.round(s.fontSize) + 'px');
if (anchor != 'start')
{
alt.setAttribute('text-anchor', anchor);
}
if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
{
alt.setAttribute('font-weight', 'bold');
}
if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
{
alt.setAttribute('font-style', 'italic');
}
var txtDecor = [];
if ((s.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
{
txtDecor.push('underline');
}
if ((s.fontStyle & mxConstants.FONT_STRIKETHROUGH) == mxConstants.FONT_STRIKETHROUGH)
{
txtDecor.push('line-through');
}
if (txtDecor.length > 0)
{
alt.setAttribute('text-decoration', txtDecor.join(' '));
}
mxUtils.write(alt, text);
return alt;
}
else
{
return null;
}
};
mxSvgCanvas2D.prototype.createGradientId = function(start, end, alpha1, alpha2, direction)
{
if (start.charAt(0) == '#')
{
start = start.substring(1);
}
if (end.charAt(0) == '#')
{
end = end.substring(1);
}
start = start.toLowerCase() + '-' + alpha1;
end = end.toLowerCase() + '-' + alpha2;
var dir = null;
if (direction == null || direction == mxConstants.DIRECTION_SOUTH)
{
dir = 's';
}
else if (direction == mxConstants.DIRECTION_EAST)
{
dir = 'e';
}
else
{
var tmp = start;
start = end;
end = tmp;
if (direction == mxConstants.DIRECTION_NORTH)
{
dir = 's';
}
else if (direction == mxConstants.DIRECTION_WEST)
{
dir = 'e';
}
}
return 'mx-gradient-' + start + '-' + end + '-' + dir;
};
mxSvgCanvas2D.prototype.getSvgGradient = function(start, end, alpha1, alpha2, direction)
{
var id = this.createGradientId(start, end, alpha1, alpha2, direction);
var gradient = this.gradients[id];
if (gradient == null)
{
var svg = this.root.ownerSVGElement;
var counter = 0;
var tmpId = id + '-' + counter;
if (svg != null)
{
gradient = svg.ownerDocument.getElementById(tmpId);
while (gradient != null && gradient.ownerSVGElement != svg)
{
tmpId = id + '-' + counter++;
gradient = svg.ownerDocument.getElementById(tmpId);
}
}
else
{
tmpId = 'id' + (++this.refCount);
}
if (gradient == null)
{
gradient = this.createSvgGradient(start, end, alpha1, alpha2, direction);
gradient.setAttribute('id', tmpId);
if (this.defs != null)
{
this.defs.appendChild(gradient);
}
else
{
svg.appendChild(gradient);
}
}
this.gradients[id] = gradient;
}
return gradient.getAttribute('id');
};
mxSvgCanvas2D.prototype.createSvgGradient = function(start, end, alpha1, alpha2, direction)
{
var gradient = this.createElement('linearGradient');
gradient.setAttribute('x1', '0%');
gradient.setAttribute('y1', '0%');
gradient.setAttribute('x2', '0%');
gradient.setAttribute('y2', '0%');
if (direction == null || direction == mxConstants.DIRECTION_SOUTH)
{
gradient.setAttribute('y2', '100%');
}
else if (direction == mxConstants.DIRECTION_EAST)
{
gradient.setAttribute('x2', '100%');
}
else if (direction == mxConstants.DIRECTION_NORTH)
{
gradient.setAttribute('y1', '100%');
}
else if (direction == mxConstants.DIRECTION_WEST)
{
gradient.setAttribute('x1', '100%');
}
var op = (alpha1 < 1) ? ';stop-opacity:' + alpha1 : '';
var stop = this.createElement('stop');
stop.setAttribute('offset', '0%');
stop.setAttribute('style', 'stop-color:' + start + op);
gradient.appendChild(stop);
op = (alpha2 < 1) ? ';stop-opacity:' + alpha2 : '';
stop = this.createElement('stop');
stop.setAttribute('offset', '100%');
stop.setAttribute('style', 'stop-color:' + end + op);
gradient.appendChild(stop);
return gradient;
};
mxSvgCanvas2D.prototype.addNode = function(filled, stroked)
{
var node = this.node;
var s = this.state;
if (node != null)
{
if (node.nodeName == 'path')
{
if (this.path != null && this.path.length > 0)
{
node.setAttribute('d', this.path.join(' '));
}
else
{
return;
}
}
if (filled && s.fillColor != null)
{
this.updateFill();
}
else if (!this.styleEnabled)
{
if (node.nodeName == 'ellipse' && mxClient.IS_FF)
{
node.setAttribute('fill', 'transparent');
}
else
{
node.setAttribute('fill', 'none');
}
filled = false;
}
if (stroked && s.strokeColor != null)
{
this.updateStroke();
}
else if (!this.styleEnabled)
{
node.setAttribute('stroke', 'none');
}
if (s.transform != null && s.transform.length > 0)
{
node.setAttribute('transform', s.transform);
}
if (s.shadow)
{
this.root.appendChild(this.createShadow(node));
}
if (this.strokeTolerance > 0 && !filled)
{
this.root.appendChild(this.createTolerance(node));
}
if (this.pointerEvents)
{
node.setAttribute('pointer-events', this.pointerEventsValue);
}
else if (!this.pointerEvents && this.originalRoot == null)
{
node.setAttribute('pointer-events', 'none');
}
if ((node.nodeName != 'rect' && node.nodeName != 'path' && node.nodeName != 'ellipse') ||
(node.getAttribute('fill') != 'none' && node.getAttribute('fill') != 'transparent') ||
node.getAttribute('stroke') != 'none' || node.getAttribute('pointer-events') != 'none')
{
this.root.appendChild(node);
}
this.node = null;
}
};
mxSvgCanvas2D.prototype.updateFill = function()
{
var s = this.state;
if (s.alpha < 1 || s.fillAlpha < 1)
{
this.node.setAttribute('fill-opacity', s.alpha * s.fillAlpha);
}
if (s.fillColor != null)
{
if (s.gradientColor != null)
{
var id = this.getSvgGradient(String(s.fillColor), String(s.gradientColor),
s.gradientFillAlpha, s.gradientAlpha, s.gradientDirection);
if (this.root.ownerDocument == document && this.useAbsoluteIds)
{
var base = this.getBaseUrl().replace(/([\(\)])/g, '\\$1');
this.node.setAttribute('fill', 'url(' + base + '#' + id + ')');
}
else
{
this.node.setAttribute('fill', 'url(#' + id + ')');
}
}
else
{
this.node.setAttribute('fill', String(s.fillColor).toLowerCase());
}
}
};
mxSvgCanvas2D.prototype.getCurrentStrokeWidth = function()
{
return Math.max(this.minStrokeWidth, Math.max(0.01, this.format(this.state.strokeWidth * this.state.scale)));
};
mxSvgCanvas2D.prototype.updateStroke = function()
{
var s = this.state;
this.node.setAttribute('stroke', String(s.strokeColor).toLowerCase());
if (s.alpha < 1 || s.strokeAlpha < 1)
{
this.node.setAttribute('stroke-opacity', s.alpha * s.strokeAlpha);
}
var sw = this.getCurrentStrokeWidth();
if (sw != 1)
{
this.node.setAttribute('stroke-width', sw);
}
if (this.node.nodeName == 'path')
{
this.updateStrokeAttributes();
}
if (s.dashed)
{
this.node.setAttribute('stroke-dasharray', this.createDashPattern(
((s.fixDash) ? 1 : s.strokeWidth) * s.scale));
}
};
mxSvgCanvas2D.prototype.updateStrokeAttributes = function()
{
var s = this.state;
if (s.lineJoin != null && s.lineJoin != 'miter')
{
this.node.setAttribute('stroke-linejoin', s.lineJoin);
}
if (s.lineCap != null)
{
var value = s.lineCap;
if (value == 'flat')
{
value = 'butt';
}
if (value != 'butt')
{
this.node.setAttribute('stroke-linecap', value);
}
}
if (s.miterLimit != null && (!this.styleEnabled || s.miterLimit != 10))
{
this.node.setAttribute('stroke-miterlimit', s.miterLimit);
}
};
mxSvgCanvas2D.prototype.createDashPattern = function(scale)
{
var pat = [];
if (typeof(this.state.dashPattern) === 'string')
{
var dash = this.state.dashPattern.split(' ');
if (dash.length > 0)
{
for (var i = 0; i < dash.length; i++)
{
pat[i] = Number(dash[i]) * scale;
}
}
}
return pat.join(' ');
};
mxSvgCanvas2D.prototype.createTolerance = function(node)
{
var tol = node.cloneNode(true);
var sw = parseFloat(tol.getAttribute('stroke-width') || 1) + this.strokeTolerance;
tol.setAttribute('pointer-events', 'stroke');
tol.setAttribute('visibility', 'hidden');
tol.removeAttribute('stroke-dasharray');
tol.setAttribute('stroke-width', sw);
tol.setAttribute('fill', 'none');
tol.setAttribute('stroke', (mxClient.IS_OT) ? 'none' : 'white');
return tol;
};
mxSvgCanvas2D.prototype.createShadow = function(node)
{
var shadow = node.cloneNode(true);
var s = this.state;
if (shadow.getAttribute('fill') != 'none' && (!mxClient.IS_FF || shadow.getAttribute('fill') != 'transparent'))
{
shadow.setAttribute('fill', s.shadowColor);
}
if (shadow.getAttribute('stroke') != 'none')
{
shadow.setAttribute('stroke', s.shadowColor);
}
shadow.setAttribute('transform', 'translate(' + this.format(s.shadowDx * s.scale) +
',' + this.format(s.shadowDy * s.scale) + ')' + (s.transform || ''));
shadow.setAttribute('opacity', s.shadowAlpha);
return shadow;
};
mxSvgCanvas2D.prototype.setLink = function(link)
{
if (link == null)
{
this.root = this.originalRoot;
}
else
{
this.originalRoot = this.root;
var node = this.createElement('a');
if (node.setAttributeNS == null || (this.root.ownerDocument != document && document.documentMode == null))
{
node.setAttribute('xlink:href', link);
}
else
{
node.setAttributeNS(mxConstants.NS_XLINK, 'xlink:href', link);
}
this.root.appendChild(node);
this.root = node;
}
};
mxSvgCanvas2D.prototype.rotate = function(theta, flipH, flipV, cx, cy)
{
if (theta != 0 || flipH || flipV)
{
var s = this.state;
cx += s.dx;
cy += s.dy;
cx *= s.scale;
cy *= s.scale;
s.transform = s.transform || '';
if (flipH && flipV)
{
theta += 180;
}
else if (flipH != flipV)
{
var tx = (flipH) ? cx : 0;
var sx = (flipH) ? -1 : 1;
var ty = (flipV) ? cy : 0;
var sy = (flipV) ? -1 : 1;
s.transform += 'translate(' + this.format(tx) + ',' + this.format(ty) + ')' +
'scale(' + this.format(sx) + ',' + this.format(sy) + ')' +
'translate(' + this.format(-tx) + ',' + this.format(-ty) + ')';
}
if (flipH ? !flipV : flipV)
{
theta *= -1;
}
if (theta != 0)
{
s.transform += 'rotate(' + this.format(theta) + ',' + this.format(cx) + ',' + this.format(cy) + ')';
}
s.rotation = s.rotation + theta;
s.rotationCx = cx;
s.rotationCy = cy;
}
};
mxSvgCanvas2D.prototype.begin = function()
{
mxAbstractCanvas2D.prototype.begin.apply(this, arguments);
this.node = this.createElement('path');
};
mxSvgCanvas2D.prototype.rect = function(x, y, w, h)
{
var s = this.state;
var n = this.createElement('rect');
n.setAttribute('x', this.format((x + s.dx) * s.scale));
n.setAttribute('y', this.format((y + s.dy) * s.scale));
n.setAttribute('width', this.format(w * s.scale));
n.setAttribute('height', this.format(h * s.scale));
this.node = n;
};
mxSvgCanvas2D.prototype.roundrect = function(x, y, w, h, dx, dy)
{
this.rect(x, y, w, h);
if (dx > 0)
{
this.node.setAttribute('rx', this.format(dx * this.state.scale));
}
if (dy > 0)
{
this.node.setAttribute('ry', this.format(dy * this.state.scale));
}
};
mxSvgCanvas2D.prototype.ellipse = function(x, y, w, h)
{
var s = this.state;
var n = this.createElement('ellipse');
n.setAttribute('cx', this.format((x + w / 2 + s.dx) * s.scale));
n.setAttribute('cy', this.format((y + h / 2 + s.dy) * s.scale));
n.setAttribute('rx', w / 2 * s.scale);
n.setAttribute('ry', h / 2 * s.scale);
this.node = n;
};
mxSvgCanvas2D.prototype.image = function(x, y, w, h, src, aspect, flipH, flipV)
{
src = this.converter.convert(src);
aspect = (aspect != null) ? aspect : true;
flipH = (flipH != null) ? flipH : false;
flipV = (flipV != null) ? flipV : false;
var s = this.state;
x += s.dx;
y += s.dy;
var node = this.createElement('image');
node.setAttribute('x', this.format(x * s.scale) + this.imageOffset);
node.setAttribute('y', this.format(y * s.scale) + this.imageOffset);
node.setAttribute('width', this.format(w * s.scale));
node.setAttribute('height', this.format(h * s.scale));
if (node.setAttributeNS == null)
{
node.setAttribute('xlink:href', src);
}
else
{
node.setAttributeNS(mxConstants.NS_XLINK, 'xlink:href', src);
}
if (!aspect)
{
node.setAttribute('preserveAspectRatio', 'none');
}
if (s.alpha < 1 || s.fillAlpha < 1)
{
node.setAttribute('opacity', s.alpha * s.fillAlpha);
}
var tr = this.state.transform || '';
if (flipH || flipV)
{
var sx = 1;
var sy = 1;
var dx = 0;
var dy = 0;
if (flipH)
{
sx = -1;
dx = -w - 2 * x;
}
if (flipV)
{
sy = -1;
dy = -h - 2 * y;
}
tr += 'scale(' + sx + ',' + sy + ')translate(' + (dx * s.scale) + ',' + (dy * s.scale) + ')';
}
if (tr.length > 0)
{
node.setAttribute('transform', tr);
}
if (!this.pointerEvents)
{
node.setAttribute('pointer-events', 'none');
}
this.root.appendChild(node);
};
mxSvgCanvas2D.prototype.convertHtml = function(val)
{
if (this.useDomParser)
{
var doc = new DOMParser().parseFromString(val, 'text/html');
if (doc != null)
{
val = new XMLSerializer().serializeToString(doc.body);
if (val.substring(0, 5) == '<body')
{
val = val.substring(val.indexOf('>', 5) + 1);
}
if (val.substring(val.length - 7, val.length) == '</body>')
{
val = val.substring(0, val.length - 7);
}
}
}
else if (document.implementation != null && document.implementation.createDocument != null)
{
var xd = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
var xb = xd.createElement('body');
xd.documentElement.appendChild(xb);
var div = document.createElement('div');
div.innerHTML = val;
var child = div.firstChild;
while (child != null)
{
var next = child.nextSibling;
xb.appendChild(xd.adoptNode(child));
child = next;
}
return xb.innerHTML;
}
else
{
var ta = document.createElement('textarea');
ta.innerHTML = val.replace(/&/g, '&amp;').
replace(/</g, '&lt;').replace(/>/g, '&gt;').
replace(/</g, '&lt;').replace(/>/g, '&gt;').
replace(/</g, '<').replace(/>/g, '>');
val = ta.value.replace(/&/g, '&').replace(/&lt;/g, '<').
replace(/&gt;/g, '>').replace(/&amp;/g, '&').
replace(/<br>/g, '<br />').replace(/<hr>/g, '<hr />').
replace(/(<img[^>]+)>/gm, "$1 />");
}
return val;
};
mxSvgCanvas2D.prototype.createDiv = function(str)
{
var val = str;
if (!mxUtils.isNode(val))
{
val = '<div><div>' + this.convertHtml(val) + '</div></div>';
}
if (!mxClient.IS_IE && !mxClient.IS_IE11 && document.createElementNS)
{
var div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
if (mxUtils.isNode(val))
{
var div2 = document.createElement('div');
var div3 = div2.cloneNode(false);
if (this.root.ownerDocument != document)
{
div2.appendChild(val.cloneNode(true));
}
else
{
div2.appendChild(val);
}
div3.appendChild(div2);
div.appendChild(div3);
}
else
{
div.innerHTML = val;
}
return div;
}
else
{
if (mxUtils.isNode(val))
{
val = '<div><div>' + mxUtils.getXml(val) + '</div></div>';
}
val = '<div xmlns="http://www.w3.org/1999/xhtml">' + val + '</div>';
return mxUtils.parseXml(val).documentElement;
}
};
mxSvgCanvas2D.prototype.updateText = function(x, y, w, h, align, valign, wrap, overflow, clip, rotation, node)
{
if (node != null && node.firstChild != null && node.firstChild.firstChild != null)
{
this.updateTextNodes(x, y, w, h, align, valign, wrap, overflow, clip, rotation, node.firstChild);
}
};
mxSvgCanvas2D.prototype.addForeignObject = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir, div, root)
{
var group = this.createElement('g');
var fo = this.createElement('foreignObject');
fo.setAttribute('style', 'overflow: visible; text-align: left;');
fo.setAttribute('pointer-events', 'none');
if (div.ownerDocument != document)
{
div = mxUtils.importNodeImplementation(fo.ownerDocument, div, true);
}
fo.appendChild(div);
group.appendChild(fo);
this.updateTextNodes(x, y, w, h, align, valign, wrap, overflow, clip, rotation, group);
if (this.root.ownerDocument != document)
{
var alt = this.createAlternateContent(fo, x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation);
if (alt != null)
{
fo.setAttribute('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility');
var sw = this.createElement('switch');
sw.appendChild(fo);
sw.appendChild(alt);
group.appendChild(sw);
}
}
root.appendChild(group);
};
mxSvgCanvas2D.prototype.updateTextNodes = function(x, y, w, h, align, valign, wrap, overflow, clip, rotation, g)
{
var s = this.state.scale;
mxSvgCanvas2D.createCss(w + 2, h, align, valign, wrap, overflow, clip,
(this.state.fontBackgroundColor != null) ? this.state.fontBackgroundColor : null,
(this.state.fontBorderColor != null) ? this.state.fontBorderColor : null,
'display: flex; align-items: unsafe ' +
((valign == mxConstants.ALIGN_TOP) ? 'flex-start' :
((valign == mxConstants.ALIGN_BOTTOM) ? 'flex-end' : 'center')) + '; ' +
'justify-content: unsafe ' + ((align == mxConstants.ALIGN_LEFT) ? 'flex-start' :
((align == mxConstants.ALIGN_RIGHT) ? 'flex-end' : 'center')) + '; ',
this.getTextCss(), s, mxUtils.bind(this, function(dx, dy, flex, item, block)
{
x += this.state.dx;
y += this.state.dy;
var fo = g.firstChild;
var div = fo.firstChild;
var box = div.firstChild;
var text = box.firstChild;
var r = ((this.rotateHtml) ? this.state.rotation : 0) + ((rotation != null) ? rotation : 0);
var t = ((this.foOffset != 0) ? 'translate(' + this.foOffset + ' ' + this.foOffset + ')' : '') +
((s != 1) ? 'scale(' + s + ')' : '');
text.setAttribute('style', block);
box.setAttribute('style', item);
fo.setAttribute('width', Math.ceil(1 / Math.min(1, s) * 100) + '%');
fo.setAttribute('height', Math.ceil(1 / Math.min(1, s) * 100) + '%');
var yp = Math.round(y + dy);
if (yp < 0)
{
fo.setAttribute('y', yp);
}
else
{
fo.removeAttribute('y');
flex += 'padding-top: ' + yp + 'px; ';
}
div.setAttribute('style', flex + 'margin-left: ' + Math.round(x + dx) + 'px;');
t += ((r != 0) ? ('rotate(' + r + ' ' + x + ' ' + y + ')') : '');
if (t != '')
{
g.setAttribute('transform', t);
}
else
{
g.removeAttribute('transform');
}
if (this.state.alpha != 1)
{
g.setAttribute('opacity', this.state.alpha);
}
else
{
g.removeAttribute('opacity');
}
}));
};
mxSvgCanvas2D.createCss = function(w, h, align, valign, wrap, overflow, clip, bg, border, flex, block, s, callback)
{
var item = 'box-sizing: border-box; font-size: 0; text-align: ' + ((align == mxConstants.ALIGN_LEFT) ? 'left' :
((align == mxConstants.ALIGN_RIGHT) ? 'right' : 'center')) + '; ';
var pt = mxUtils.getAlignmentAsPoint(align, valign);
var ofl = 'overflow: hidden; ';
var fw = 'width: 1px; ';
var fh = 'height: 1px; ';
var dx = pt.x * w;
var dy = pt.y * h;
if (clip)
{
fw = 'width: ' + Math.round(w) + 'px; ';
item += 'max-height: ' + Math.round(h) + 'px; ';
dy = 0;
}
else if (overflow == 'fill')
{
fw = 'width: ' + Math.round(w) + 'px; ';
fh = 'height: ' + Math.round(h) + 'px; ';
block += 'width: 100%; height: 100%; ';
item += fw + fh;
}
else if (overflow == 'width')
{
fw = 'width: ' + Math.round(w) + 'px; ';
block += 'width: 100%; ';
item += fw;
dy = 0;
if (h > 0)
{
item += 'max-height: ' + Math.round(h) + 'px; ';
}
}
else
{
ofl = '';
dy = 0;
}
var bgc = '';
if (bg != null)
{
bgc += 'background-color: ' + bg + '; ';
}
if (border != null)
{
bgc += 'border: 1px solid ' + border + '; ';
}
if (ofl == '' || clip)
{
block += bgc;
}
else
{
item += bgc;
}
if (wrap && w > 0)
{
block += 'white-space: normal; word-wrap: ' + mxConstants.WORD_WRAP + '; ';
fw = 'width: ' + Math.round(w) + 'px; ';
if (ofl != '' && overflow != 'fill')
{
dy = 0;
}
}
else
{
block += 'white-space: nowrap; ';
if (ofl == '')
{
dx = 0;
}
}
callback(dx, dy, flex + fw + fh, item + ofl, block, ofl);
};
mxSvgCanvas2D.prototype.getTextCss = function()
{
var s = this.state;
var lh = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (s.fontSize * mxConstants.LINE_HEIGHT) + 'px' :
(mxConstants.LINE_HEIGHT * this.lineHeightCorrection);
var css = 'display: inline-block; font-size: ' + s.fontSize + 'px; ' +
'font-family: ' + s.fontFamily + '; color: ' + s.fontColor + '; line-height: ' + lh +
'; pointer-events: ' + ((this.pointerEvents) ? this.pointerEventsValue : 'none') + '; ';
if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
{
css += 'font-weight: bold; ';
}
if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
{
css += 'font-style: italic; ';
}
var deco = [];
if ((s.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
{
deco.push('underline');
}
if ((s.fontStyle & mxConstants.FONT_STRIKETHROUGH) == mxConstants.FONT_STRIKETHROUGH)
{
deco.push('line-through');
}
if (deco.length > 0)
{
css += 'text-decoration: ' + deco.join(' ') + '; ';
}
return css;
};
mxSvgCanvas2D.prototype.text = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir)
{
if (this.textEnabled && str != null)
{
rotation = (rotation != null) ? rotation : 0;
if (this.foEnabled && format == 'html')
{
var div = this.createDiv(str);
if (div != null)
{
if (dir != null)
{
div.setAttribute('dir', dir);
}
this.addForeignObject(x, y, w, h, str, align, valign, wrap,
format, overflow, clip, rotation, dir, div, this.root);
}
}
else
{
this.plainText(x + this.state.dx, y + this.state.dy, w, h, str,
align, valign, wrap, overflow, clip, rotation, dir);
}
}
};
mxSvgCanvas2D.prototype.createClip = function(x, y, w, h)
{
x = Math.round(x);
y = Math.round(y);
w = Math.round(w);
h = Math.round(h);
var id = 'mx-clip-' + x + '-' + y + '-' + w + '-' + h;
var counter = 0;
var tmp = id + '-' + counter;
while (document.getElementById(tmp) != null)
{
tmp = id + '-' + (++counter);
}
clip = this.createElement('clipPath');
clip.setAttribute('id', tmp);
var rect = this.createElement('rect');
rect.setAttribute('x', x);
rect.setAttribute('y', y);
rect.setAttribute('width', w);
rect.setAttribute('height', h);
clip.appendChild(rect);
return clip;
};
mxSvgCanvas2D.prototype.plainText = function(x, y, w, h, str, align, valign, wrap, overflow, clip, rotation, dir)
{
rotation = (rotation != null) ? rotation : 0;
var s = this.state;
var size = s.fontSize;
var node = this.createElement('g');
var tr = s.transform || '';
this.updateFont(node);
if (!this.pointerEvents && this.originalRoot == null)
{
node.setAttribute('pointer-events', 'none');
}
if (rotation != 0)
{
tr += 'rotate(' + rotation + ',' + this.format(x * s.scale) + ',' + this.format(y * s.scale) + ')';
}
if (dir != null)
{
node.setAttribute('direction', dir);
}
if (clip && w > 0 && h > 0)
{
var cx = x;
var cy = y;
if (align == mxConstants.ALIGN_CENTER)
{
cx -= w / 2;
}
else if (align == mxConstants.ALIGN_RIGHT)
{
cx -= w;
}
if (overflow != 'fill')
{
if (valign == mxConstants.ALIGN_MIDDLE)
{
cy -= h / 2;
}
else if (valign == mxConstants.ALIGN_BOTTOM)
{
cy -= h;
}
}
var c = this.createClip(cx * s.scale - 2, cy * s.scale - 2, w * s.scale + 4, h * s.scale + 4);
if (this.defs != null)
{
this.defs.appendChild(c);
}
else
{
this.root.appendChild(c);
}
if (!mxClient.IS_CHROMEAPP && !mxClient.IS_IE && !mxClient.IS_IE11 &&
!mxClient.IS_EDGE && this.root.ownerDocument == document)
{
var base = this.getBaseUrl().replace(/([\(\)])/g, '\\$1');
node.setAttribute('clip-path', 'url(' + base + '#' + c.getAttribute('id') + ')');
}
else
{
node.setAttribute('clip-path', 'url(#' + c.getAttribute('id') + ')');
}
}
var anchor = (align == mxConstants.ALIGN_RIGHT) ? 'end' :
(align == mxConstants.ALIGN_CENTER) ? 'middle' :
'start';
if (anchor != 'start')
{
node.setAttribute('text-anchor', anchor);
}
if (!this.styleEnabled || size != mxConstants.DEFAULT_FONTSIZE)
{
node.setAttribute('font-size', (size * s.scale) + 'px');
}
if (tr.length > 0)
{
node.setAttribute('transform', tr);
}
if (s.alpha < 1)
{
node.setAttribute('opacity', s.alpha);
}
var lines = str.split('\n');
var lh = Math.round(size * mxConstants.LINE_HEIGHT);
var textHeight = size + (lines.length - 1) * lh;
var cy = y + size - 1;
if (valign == mxConstants.ALIGN_MIDDLE)
{
if (overflow == 'fill')
{
cy -= h / 2;
}
else
{
var dy = ((this.matchHtmlAlignment && clip && h > 0) ? Math.min(textHeight, h) : textHeight) / 2;
cy -= dy;
}
}
else if (valign == mxConstants.ALIGN_BOTTOM)
{
if (overflow == 'fill')
{
cy -= h;
}
else
{
var dy = (this.matchHtmlAlignment && clip && h > 0) ? Math.min(textHeight, h) : textHeight;
cy -= dy + 1;
}
}
for (var i = 0; i < lines.length; i++)
{
if (lines[i].length > 0 && mxUtils.trim(lines[i]).length > 0)
{
var text = this.createElement('text');
text.setAttribute('x', this.format(x * s.scale) + this.textOffset);
text.setAttribute('y', this.format(cy * s.scale) + this.textOffset);
mxUtils.write(text, lines[i]);
node.appendChild(text);
}
cy += lh;
}
this.root.appendChild(node);
this.addTextBackground(node, str, x, y, w, (overflow == 'fill') ? h : textHeight, align, valign, overflow);
};
mxSvgCanvas2D.prototype.updateFont = function(node)
{
var s = this.state;
node.setAttribute('fill', s.fontColor);
if (!this.styleEnabled || s.fontFamily != mxConstants.DEFAULT_FONTFAMILY)
{
node.setAttribute('font-family', s.fontFamily);
}
if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
{
node.setAttribute('font-weight', 'bold');
}
if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
{
node.setAttribute('font-style', 'italic');
}
var txtDecor = [];
if ((s.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
{
txtDecor.push('underline');
}
if ((s.fontStyle & mxConstants.FONT_STRIKETHROUGH) == mxConstants.FONT_STRIKETHROUGH)
{
txtDecor.push('line-through');
}
if (txtDecor.length > 0)
{
node.setAttribute('text-decoration', txtDecor.join(' '));
}
};
mxSvgCanvas2D.prototype.addTextBackground = function(node, str, x, y, w, h, align, valign, overflow)
{
var s = this.state;
if (s.fontBackgroundColor != null || s.fontBorderColor != null)
{
var bbox = null;
if (overflow == 'fill' || overflow == 'width')
{
if (align == mxConstants.ALIGN_CENTER)
{
x -= w / 2;
}
else if (align == mxConstants.ALIGN_RIGHT)
{
x -= w;
}
if (valign == mxConstants.ALIGN_MIDDLE)
{
y -= h / 2;
}
else if (valign == mxConstants.ALIGN_BOTTOM)
{
y -= h;
}
bbox = new mxRectangle((x + 1) * s.scale, y * s.scale, (w - 2) * s.scale, (h + 2) * s.scale);
}
else if (node.getBBox != null && this.root.ownerDocument == document)
{
try
{
bbox = node.getBBox();
var ie = mxClient.IS_IE && mxClient.IS_SVG;
bbox = new mxRectangle(bbox.x, bbox.y + ((ie) ? 0 : 1), bbox.width, bbox.height + ((ie) ? 1 : 0));
}
catch (e)
{
}
}
if (bbox == null || bbox.width == 0 || bbox.height == 0)
{
var div = document.createElement('div');
div.style.lineHeight = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (s.fontSize * mxConstants.LINE_HEIGHT) + 'px' : mxConstants.LINE_HEIGHT;
div.style.fontSize = s.fontSize + 'px';
div.style.fontFamily = s.fontFamily;
div.style.whiteSpace = 'nowrap';
div.style.position = 'absolute';
div.style.visibility = 'hidden';
div.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
div.style.zoom = '1';
if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
{
div.style.fontWeight = 'bold';
}
if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
{
div.style.fontStyle = 'italic';
}
str = mxUtils.htmlEntities(str, false);
div.innerHTML = str.replace(/\n/g, '<br/>');
document.body.appendChild(div);
var w = div.offsetWidth;
var h = div.offsetHeight;
div.parentNode.removeChild(div);
if (align == mxConstants.ALIGN_CENTER)
{
x -= w / 2;
}
else if (align == mxConstants.ALIGN_RIGHT)
{
x -= w;
}
if (valign == mxConstants.ALIGN_MIDDLE)
{
y -= h / 2;
}
else if (valign == mxConstants.ALIGN_BOTTOM)
{
y -= h;
}
bbox = new mxRectangle((x + 1) * s.scale, (y + 2) * s.scale, w * s.scale, (h + 1) * s.scale);
}
if (bbox != null)
{
var n = this.createElement('rect');
n.setAttribute('fill', s.fontBackgroundColor || 'none');
n.setAttribute('stroke', s.fontBorderColor || 'none');
n.setAttribute('x', Math.floor(bbox.x - 1));
n.setAttribute('y', Math.floor(bbox.y - 1));
n.setAttribute('width', Math.ceil(bbox.width + 2));
n.setAttribute('height', Math.ceil(bbox.height));
var sw = (s.fontBorderColor != null) ? Math.max(1, this.format(s.scale)) : 0;
n.setAttribute('stroke-width', sw);
if (this.root.ownerDocument == document && mxUtils.mod(sw, 2) == 1)
{
n.setAttribute('transform', 'translate(0.5, 0.5)');
}
node.insertBefore(n, node.firstChild);
}
}
};
mxSvgCanvas2D.prototype.stroke = function()
{
this.addNode(false, true);
};
mxSvgCanvas2D.prototype.fill = function()
{
this.addNode(true, false);
};
mxSvgCanvas2D.prototype.fillAndStroke = function()
{
this.addNode(true, true);
};
__mxOutput.mxSvgCanvas2D = typeof mxSvgCanvas2D !== 'undefined' ? mxSvgCanvas2D : undefined;
var mxVmlCanvas2D = function(root)
{
mxAbstractCanvas2D.call(this);
this.root = root;
};
mxUtils.extend(mxVmlCanvas2D, mxAbstractCanvas2D);
mxVmlCanvas2D.prototype.node = null;
mxVmlCanvas2D.prototype.textEnabled = true;
mxVmlCanvas2D.prototype.moveOp = 'm';
mxVmlCanvas2D.prototype.lineOp = 'l';
mxVmlCanvas2D.prototype.curveOp = 'c';
mxVmlCanvas2D.prototype.closeOp = 'x';
mxVmlCanvas2D.prototype.rotatedHtmlBackground = '';
mxVmlCanvas2D.prototype.vmlScale = 1;
mxVmlCanvas2D.prototype.createElement = function(name)
{
return document.createElement(name);
};
mxVmlCanvas2D.prototype.createVmlElement = function(name)
{
return this.createElement(mxClient.VML_PREFIX + ':' + name);
};
mxVmlCanvas2D.prototype.addNode = function(filled, stroked)
{
var node = this.node;
var s = this.state;
if (node != null)
{
if (node.nodeName == 'shape')
{
if (this.path != null && this.path.length > 0)
{
node.path = this.path.join(' ') + ' e';
node.style.width = this.root.style.width;
node.style.height = this.root.style.height;
node.coordsize = parseInt(node.style.width) + ' ' + parseInt(node.style.height);
}
else
{
return;
}
}
node.strokeweight = this.format(Math.max(1, s.strokeWidth * s.scale / this.vmlScale)) + 'px';
if (s.shadow)
{
this.root.appendChild(this.createShadow(node,
filled && s.fillColor != null,
stroked && s.strokeColor != null));
}
if (stroked && s.strokeColor != null)
{
node.stroked = 'true';
node.strokecolor = s.strokeColor;
}
else
{
node.stroked = 'false';
}
node.appendChild(this.createStroke());
if (filled && s.fillColor != null)
{
node.appendChild(this.createFill());
}
else if (this.pointerEvents && (node.nodeName != 'shape' ||
this.path[this.path.length - 1] == this.closeOp))
{
node.appendChild(this.createTransparentFill());
}
else
{
node.filled = 'false';
}
this.root.appendChild(node);
}
};
mxVmlCanvas2D.prototype.createTransparentFill = function()
{
var fill = this.createVmlElement('fill');
fill.src = mxClient.imageBasePath + '/transparent.gif';
fill.type = 'tile';
return fill;
};
mxVmlCanvas2D.prototype.createFill = function()
{
var s = this.state;
var fill = this.createVmlElement('fill');
fill.color = s.fillColor;
if (s.gradientColor != null)
{
fill.type = 'gradient';
fill.method = 'none';
fill.color2 = s.gradientColor;
var angle = 180 - s.rotation;
if (s.gradientDirection == mxConstants.DIRECTION_WEST)
{
angle -= 90 + ((this.root.style.flip == 'x') ? 180 : 0);
}
else if (s.gradientDirection == mxConstants.DIRECTION_EAST)
{
angle += 90 + ((this.root.style.flip == 'x') ? 180 : 0);
}
else if (s.gradientDirection == mxConstants.DIRECTION_NORTH)
{
angle -= 180 + ((this.root.style.flip == 'y') ? -180 : 0);
}
else
{
angle += ((this.root.style.flip == 'y') ? -180 : 0);
}
if (this.root.style.flip == 'x' || this.root.style.flip == 'y')
{
angle *= -1;
}
fill.angle = mxUtils.mod(angle, 360);
fill.opacity = (s.alpha * s.gradientFillAlpha * 100) + '%';
fill.setAttribute(mxClient.OFFICE_PREFIX + ':opacity2', (s.alpha * s.gradientAlpha * 100) + '%');
}
else if (s.alpha < 1 || s.fillAlpha < 1)
{
fill.opacity = (s.alpha * s.fillAlpha * 100) + '%';
}
return fill;
};
mxVmlCanvas2D.prototype.createStroke = function()
{
var s = this.state;
var stroke = this.createVmlElement('stroke');
stroke.endcap = s.lineCap || 'flat';
stroke.joinstyle = s.lineJoin || 'miter';
stroke.miterlimit = s.miterLimit || '10';
if (s.alpha < 1 || s.strokeAlpha < 1)
{
stroke.opacity = (s.alpha * s.strokeAlpha * 100) + '%';
}
if (s.dashed)
{
stroke.dashstyle = this.getVmlDashStyle();
}
return stroke;
};
mxVmlCanvas2D.prototype.getVmlDashStyle = function()
{
var result = 'dash';
if (typeof(this.state.dashPattern) === 'string')
{
var tok = this.state.dashPattern.split(' ');
if (tok.length > 0 && tok[0] == 1)
{
result = '0 2';
}
}
return result;
};
mxVmlCanvas2D.prototype.createShadow = function(node, filled, stroked)
{
var s = this.state;
var rad = -s.rotation * (Math.PI / 180);
var cos = Math.cos(rad);
var sin = Math.sin(rad);
var dx = s.shadowDx * s.scale;
var dy = s.shadowDy * s.scale;
if (this.root.style.flip == 'x')
{
dx *= -1;
}
else if (this.root.style.flip == 'y')
{
dy *= -1;
}
var shadow = node.cloneNode(true);
shadow.style.marginLeft = Math.round(dx * cos - dy * sin) + 'px';
shadow.style.marginTop = Math.round(dx * sin + dy * cos) + 'px';
if (document.documentMode == 8)
{
shadow.strokeweight = node.strokeweight;
if (node.nodeName == 'shape')
{
shadow.path = this.path.join(' ') + ' e';
shadow.style.width = this.root.style.width;
shadow.style.height = this.root.style.height;
shadow.coordsize = parseInt(node.style.width) + ' ' + parseInt(node.style.height);
}
}
if (stroked)
{
shadow.strokecolor = s.shadowColor;
shadow.appendChild(this.createShadowStroke());
}
else
{
shadow.stroked = 'false';
}
if (filled)
{
shadow.appendChild(this.createShadowFill());
}
else
{
shadow.filled = 'false';
}
return shadow;
};
mxVmlCanvas2D.prototype.createShadowFill = function()
{
var fill = this.createVmlElement('fill');
fill.color = this.state.shadowColor;
fill.opacity = (this.state.alpha * this.state.shadowAlpha * 100) + '%';
return fill;
};
mxVmlCanvas2D.prototype.createShadowStroke = function()
{
var stroke = this.createStroke();
stroke.opacity = (this.state.alpha * this.state.shadowAlpha * 100) + '%';
return stroke;
};
mxVmlCanvas2D.prototype.rotate = function(theta, flipH, flipV, cx, cy)
{
if (flipH && flipV)
{
theta += 180;
}
else if (flipH)
{
this.root.style.flip = 'x';
}
else if (flipV)
{
this.root.style.flip = 'y';
}
if (flipH ? !flipV : flipV)
{
theta *= -1;
}
this.root.style.rotation = theta;
this.state.rotation = this.state.rotation + theta;
this.state.rotationCx = cx;
this.state.rotationCy = cy;
};
mxVmlCanvas2D.prototype.begin = function()
{
mxAbstractCanvas2D.prototype.begin.apply(this, arguments);
this.node = this.createVmlElement('shape');
this.node.style.position = 'absolute';
};
mxVmlCanvas2D.prototype.quadTo = function(x1, y1, x2, y2)
{
var s = this.state;
var cpx0 = (this.lastX + s.dx) * s.scale;
var cpy0 = (this.lastY + s.dy) * s.scale;
var qpx1 = (x1 + s.dx) * s.scale;
var qpy1 = (y1 + s.dy) * s.scale;
var cpx3 = (x2 + s.dx) * s.scale;
var cpy3 = (y2 + s.dy) * s.scale;
var cpx1 = cpx0 + 2/3 * (qpx1 - cpx0);
var cpy1 = cpy0 + 2/3 * (qpy1 - cpy0);
var cpx2 = cpx3 + 2/3 * (qpx1 - cpx3);
var cpy2 = cpy3 + 2/3 * (qpy1 - cpy3);
this.path.push('c ' + this.format(cpx1) + ' ' + this.format(cpy1) +
' ' + this.format(cpx2) + ' ' + this.format(cpy2) +
' ' + this.format(cpx3) + ' ' + this.format(cpy3));
this.lastX = (cpx3 / s.scale) - s.dx;
this.lastY = (cpy3 / s.scale) - s.dy;
};
mxVmlCanvas2D.prototype.createRect = function(nodeName, x, y, w, h)
{
var s = this.state;
var n = this.createVmlElement(nodeName);
n.style.position = 'absolute';
n.style.left = this.format((x + s.dx) * s.scale) + 'px';
n.style.top = this.format((y + s.dy) * s.scale) + 'px';
n.style.width = this.format(w * s.scale) + 'px';
n.style.height = this.format(h * s.scale) + 'px';
return n;
};
mxVmlCanvas2D.prototype.rect = function(x, y, w, h)
{
this.node = this.createRect('rect', x, y, w, h);
};
mxVmlCanvas2D.prototype.roundrect = function(x, y, w, h, dx, dy)
{
this.node = this.createRect('roundrect', x, y, w, h);
this.node.setAttribute('arcsize', Math.max(dx * 100 / w, dy * 100 / h) + '%');
};
mxVmlCanvas2D.prototype.ellipse = function(x, y, w, h)
{
this.node = this.createRect('oval', x, y, w, h);
};
mxVmlCanvas2D.prototype.image = function(x, y, w, h, src, aspect, flipH, flipV)
{
var node = null;
if (!aspect)
{
node = this.createRect('image', x, y, w, h);
node.src = src;
}
else
{
node = this.createRect('rect', x, y, w, h);
node.stroked = 'false';
var fill = this.createVmlElement('fill');
fill.aspect = (aspect) ? 'atmost' : 'ignore';
fill.rotate = 'true';
fill.type = 'frame';
fill.src = src;
node.appendChild(fill);
}
if (flipH && flipV)
{
node.style.rotation = '180';
}
else if (flipH)
{
node.style.flip = 'x';
}
else if (flipV)
{
node.style.flip = 'y';
}
if (this.state.alpha < 1 || this.state.fillAlpha < 1)
{
node.style.filter += 'alpha(opacity=' + (this.state.alpha * this.state.fillAlpha * 100) + ')';
}
this.root.appendChild(node);
};
mxVmlCanvas2D.prototype.createDiv = function(str, align, valign, overflow)
{
var div = this.createElement('div');
var state = this.state;
var css = '';
if (state.fontBackgroundColor != null)
{
css += 'background-color:' + mxUtils.htmlEntities(state.fontBackgroundColor) + ';';
}
if (state.fontBorderColor != null)
{
css += 'border:1px solid ' + mxUtils.htmlEntities(state.fontBorderColor) + ';';
}
if (mxUtils.isNode(str))
{
div.appendChild(str);
}
else
{
if (overflow != 'fill' && overflow != 'width')
{
var div2 = this.createElement('div');
div2.style.cssText = css;
div2.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
div2.style.zoom = '1';
div2.style.textDecoration = 'inherit';
div2.innerHTML = str;
div.appendChild(div2);
}
else
{
div.style.cssText = css;
div.innerHTML = str;
}
}
var style = div.style;
style.fontSize = (state.fontSize / this.vmlScale) + 'px';
style.fontFamily = state.fontFamily;
style.color = state.fontColor;
style.verticalAlign = 'top';
style.textAlign = align || 'left';
style.lineHeight = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (state.fontSize * mxConstants.LINE_HEIGHT / this.vmlScale) + 'px' : mxConstants.LINE_HEIGHT;
if ((state.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
{
style.fontWeight = 'bold';
}
if ((state.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
{
style.fontStyle = 'italic';
}
if ((state.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
{
style.textDecoration = 'underline';
}
return div;
};
mxVmlCanvas2D.prototype.text = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir)
{
if (this.textEnabled && str != null)
{
var s = this.state;
if (format == 'html')
{
if (s.rotation != null)
{
var pt = this.rotatePoint(x, y, s.rotation, s.rotationCx, s.rotationCy);
x = pt.x;
y = pt.y;
}
if (document.documentMode == 8 && !mxClient.IS_EM)
{
x += s.dx;
y += s.dy;
if (overflow != 'fill' && valign == mxConstants.ALIGN_TOP)
{
y -= 1;
}
}
else
{
x *= s.scale;
y *= s.scale;
}
var abs = (document.documentMode == 8 && !mxClient.IS_EM) ? this.createVmlElement('group') : this.createElement('div');
abs.style.position = 'absolute';
abs.style.display = 'inline';
abs.style.left = this.format(x) + 'px';
abs.style.top = this.format(y) + 'px';
abs.style.zoom = s.scale;
var box = this.createElement('div');
box.style.position = 'relative';
box.style.display = 'inline';
var margin = mxUtils.getAlignmentAsPoint(align, valign);
var dx = margin.x;
var dy = margin.y;
var div = this.createDiv(str, align, valign, overflow);
var inner = this.createElement('div');
if (dir != null)
{
div.setAttribute('dir', dir);
}
if (wrap && w > 0)
{
if (!clip)
{
div.style.width = Math.round(w) + 'px';
}
div.style.wordWrap = mxConstants.WORD_WRAP;
div.style.whiteSpace = 'normal';
if (div.style.wordWrap == 'break-word')
{
var tmp = div;
if (tmp.firstChild != null && tmp.firstChild.nodeName == 'DIV')
{
tmp.firstChild.style.width = '100%';
}
}
}
else
{
div.style.whiteSpace = 'nowrap';
}
var rot = s.rotation + (rotation || 0);
if (this.rotateHtml && rot != 0)
{
inner.style.display = 'inline';
inner.style.zoom = '1';
inner.appendChild(div);
if (document.documentMode == 8 && !mxClient.IS_EM && this.root.nodeName != 'DIV')
{
box.appendChild(inner);
abs.appendChild(box);
}
else
{
abs.appendChild(inner);
}
}
else if (document.documentMode == 8 && !mxClient.IS_EM)
{
box.appendChild(div);
abs.appendChild(box);
}
else
{
div.style.display = 'inline';
abs.appendChild(div);
}
if (this.root.nodeName != 'DIV')
{
var rect = this.createVmlElement('rect');
rect.stroked = 'false';
rect.filled = 'false';
rect.appendChild(abs);
this.root.appendChild(rect);
}
else
{
this.root.appendChild(abs);
}
if (clip)
{
div.style.overflow = 'hidden';
div.style.width = Math.round(w) + 'px';
if (!mxClient.IS_QUIRKS)
{
div.style.maxHeight = Math.round(h) + 'px';
}
}
else if (overflow == 'fill')
{
div.style.overflow = 'hidden';
div.style.width = (Math.max(0, w) + 1) + 'px';
div.style.height = (Math.max(0, h) + 1) + 'px';
}
else if (overflow == 'width')
{
div.style.overflow = 'hidden';
div.style.width = (Math.max(0, w) + 1) + 'px';
div.style.maxHeight = (Math.max(0, h) + 1) + 'px';
}
if (this.rotateHtml && rot != 0)
{
var rad = rot * (Math.PI / 180);
var real_cos = parseFloat(parseFloat(Math.cos(rad)).toFixed(8));
var real_sin = parseFloat(parseFloat(Math.sin(-rad)).toFixed(8));
rad %= 2 * Math.PI;
if (rad < 0) rad += 2 * Math.PI;
rad %= Math.PI;
if (rad > Math.PI / 2) rad = Math.PI - rad;
var cos = Math.cos(rad);
var sin = Math.sin(rad);
if (document.documentMode == 8 && !mxClient.IS_EM)
{
div.style.display = 'inline-block';
inner.style.display = 'inline-block';
box.style.display = 'inline-block';
}
div.style.visibility = 'hidden';
div.style.position = 'absolute';
document.body.appendChild(div);
var sizeDiv = div;
if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
{
sizeDiv = sizeDiv.firstChild;
}
var tmp = sizeDiv.offsetWidth + 3;
var oh = sizeDiv.offsetHeight;
if (clip)
{
w = Math.min(w, tmp);
oh = Math.min(oh, h);
}
else
{
w = tmp;
}
if (wrap)
{
div.style.width = w + 'px';
}
if (mxClient.IS_QUIRKS && (clip || overflow == 'width') && oh > h)
{
oh = h;
div.style.height = oh + 'px';
}
h = oh;
var top_fix = (h - h * cos + w * -sin) / 2 - real_sin * w * (dx + 0.5) + real_cos * h * (dy + 0.5);
var left_fix = (w - w * cos + h * -sin) / 2 + real_cos * w * (dx + 0.5) + real_sin * h * (dy + 0.5);
if (abs.nodeName == 'group' && this.root.nodeName == 'DIV')
{
var pos = this.createElement('div');
pos.style.display = 'inline-block';
pos.style.position = 'absolute';
pos.style.left = this.format(x + (left_fix - w / 2) * s.scale) + 'px';
pos.style.top = this.format(y + (top_fix - h / 2) * s.scale) + 'px';
abs.parentNode.appendChild(pos);
pos.appendChild(abs);
}
else
{
var sc = (document.documentMode == 8 && !mxClient.IS_EM) ? 1 : s.scale;
abs.style.left = this.format(x + (left_fix - w / 2) * sc) + 'px';
abs.style.top = this.format(y + (top_fix - h / 2) * sc) + 'px';
}
inner.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11="+real_cos+", M12="+
real_sin+", M21="+(-real_sin)+", M22="+real_cos+", sizingMethod='auto expand')";
inner.style.backgroundColor = this.rotatedHtmlBackground;
if (this.state.alpha < 1)
{
inner.style.filter += 'alpha(opacity=' + (this.state.alpha * 100) + ')';
}
inner.appendChild(div);
div.style.position = '';
div.style.visibility = '';
}
else if (document.documentMode != 8 || mxClient.IS_EM)
{
div.style.verticalAlign = 'top';
if (this.state.alpha < 1)
{
abs.style.filter = 'alpha(opacity=' + (this.state.alpha * 100) + ')';
}
var divParent = div.parentNode;
div.style.visibility = 'hidden';
document.body.appendChild(div);
w = div.offsetWidth;
var oh = div.offsetHeight;
if (mxClient.IS_QUIRKS && clip && oh > h)
{
oh = h;
div.style.height = oh + 'px';
}
h = oh;
div.style.visibility = '';
divParent.appendChild(div);
abs.style.left = this.format(x + w * dx * this.state.scale) + 'px';
abs.style.top = this.format(y + h * dy * this.state.scale) + 'px';
}
else
{
if (this.state.alpha < 1)
{
div.style.filter = 'alpha(opacity=' + (this.state.alpha * 100) + ')';
}
box.style.left = (dx * 100) + '%';
box.style.top = (dy * 100) + '%';
}
}
else
{
this.plainText(x, y, w, h, mxUtils.htmlEntities(str, false), align, valign, wrap, format, overflow, clip, rotation, dir);
}
}
};
mxVmlCanvas2D.prototype.plainText = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir)
{
var s = this.state;
x = (x + s.dx) * s.scale;
y = (y + s.dy) * s.scale;
var node = this.createVmlElement('shape');
node.style.width = '1px';
node.style.height = '1px';
node.stroked = 'false';
var fill = this.createVmlElement('fill');
fill.color = s.fontColor;
fill.opacity = (s.alpha * 100) + '%';
node.appendChild(fill);
var path = this.createVmlElement('path');
path.textpathok = 'true';
path.v = 'm ' + this.format(0) + ' ' + this.format(0) + ' l ' + this.format(1) + ' ' + this.format(0);
node.appendChild(path);
var tp = this.createVmlElement('textpath');
tp.style.cssText = 'v-text-align:' + align;
tp.style.align = align;
tp.style.fontFamily = s.fontFamily;
tp.string = str;
tp.on = 'true';
var size = s.fontSize * s.scale / this.vmlScale;
tp.style.fontSize = size + 'px';
if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
{
tp.style.fontWeight = 'bold';
}
if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
{
tp.style.fontStyle = 'italic';
}
if ((s.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
{
tp.style.textDecoration = 'underline';
}
var lines = str.split('\n');
var textHeight = size + (lines.length - 1) * size * mxConstants.LINE_HEIGHT;
var dx = 0;
var dy = 0;
if (valign == mxConstants.ALIGN_BOTTOM)
{
dy = - textHeight / 2;
}
else if (valign != mxConstants.ALIGN_MIDDLE)
{
dy = textHeight / 2;
}
if (rotation != null)
{
node.style.rotation = rotation;
var rad = rotation * (Math.PI / 180);
dx = Math.sin(rad) * dy;
dy = Math.cos(rad) * dy;
}
node.appendChild(tp);
node.style.left = this.format(x - dx) + 'px';
node.style.top = this.format(y + dy) + 'px';
this.root.appendChild(node);
};
mxVmlCanvas2D.prototype.stroke = function()
{
this.addNode(false, true);
};
mxVmlCanvas2D.prototype.fill = function()
{
this.addNode(true, false);
};
mxVmlCanvas2D.prototype.fillAndStroke = function()
{
this.addNode(true, true);
};
__mxOutput.mxVmlCanvas2D = typeof mxVmlCanvas2D !== 'undefined' ? mxVmlCanvas2D : undefined;
function mxGuide(graph, states)
{
this.graph = graph;
this.setStates(states);
} mxGuide.prototype.graph = null;
mxGuide.prototype.states = null;
mxGuide.prototype.horizontal = true;
mxGuide.prototype.vertical = true;
mxGuide.prototype.guideX = null;
mxGuide.prototype.guideY = null;
mxGuide.prototype.rounded = false;
mxGuide.prototype.tolerance = 2;
mxGuide.prototype.setStates = function(states)
{
this.states = states;
};
mxGuide.prototype.isEnabledForEvent = function(evt)
{
return true;
};
mxGuide.prototype.getGuideTolerance = function(gridEnabled)
{
return (gridEnabled && this.graph.gridEnabled) ? this.graph.gridSize / 2 : this.tolerance;
};
mxGuide.prototype.createGuideShape = function(horizontal)
{
var guide = new mxPolyline([], mxConstants.GUIDE_COLOR, mxConstants.GUIDE_STROKEWIDTH);
guide.isDashed = true;
return guide;
};
mxGuide.prototype.isStateIgnored = function(state)
{
return false;
};
mxGuide.prototype.move = function(bounds, delta, gridEnabled, clone)
{
if (this.states != null && (this.horizontal || this.vertical) && bounds != null && delta != null)
{
var scale = this.graph.getView().scale;
var tt = this.getGuideTolerance(gridEnabled) * scale;
var b = bounds.clone();
b.x += delta.x;
b.y += delta.y;
var overrideX = false;
var stateX = null;
var valueX = null;
var overrideY = false;
var stateY = null;
var valueY = null;
var ttX = tt;
var ttY = tt;
var left = b.x;
var right = b.x + b.width;
var center = b.getCenterX();
var top = b.y;
var bottom = b.y + b.height;
var middle = b.getCenterY();
function snapX(x, state, centerAlign)
{
var override = false;
if (centerAlign && Math.abs(x - center) < ttX)
{
delta.x = x - bounds.getCenterX();
ttX = Math.abs(x - center);
override = true;
}
else if (!centerAlign)
{
if (Math.abs(x - left) < ttX)
{
delta.x = x - bounds.x;
ttX = Math.abs(x - left);
override = true;
}
else if (Math.abs(x - right) < ttX)
{
delta.x = x - bounds.x - bounds.width;
ttX = Math.abs(x - right);
override = true;
}
}
if (override)
{
stateX = state;
valueX = x;
if (this.guideX == null)
{
this.guideX = this.createGuideShape(true);
this.guideX.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
this.guideX.pointerEvents = false;
this.guideX.init(this.graph.getView().getOverlayPane());
}
}
overrideX = overrideX || override;
} function snapY(y, state, centerAlign)
{
var override = false;
if (centerAlign && Math.abs(y - middle) < ttY)
{
delta.y = y - bounds.getCenterY();
ttY = Math.abs(y - middle);
override = true;
}
else if (!centerAlign)
{
if (Math.abs(y - top) < ttY)
{
delta.y = y - bounds.y;
ttY = Math.abs(y - top);
override = true;
}
else if (Math.abs(y - bottom) < ttY)
{
delta.y = y - bounds.y - bounds.height;
ttY = Math.abs(y - bottom);
override = true;
}
}
if (override)
{
stateY = state;
valueY = y;
if (this.guideY == null)
{
this.guideY = this.createGuideShape(false);
this.guideY.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
this.guideY.pointerEvents = false;
this.guideY.init(this.graph.getView().getOverlayPane());
}
}
overrideY = overrideY || override;
} for (var i = 0; i < this.states.length; i++)
{
var state = this.states[i];
if (state != null && !this.isStateIgnored(state))
{
if (this.horizontal)
{
snapX.call(this, state.getCenterX(), state, true);
snapX.call(this, state.x, state, false);
snapX.call(this, state.x + state.width, state, false);
if (state.cell == null)
{
snapX.call(this, state.getCenterX(), state, false);
}
}
if (this.vertical)
{
snapY.call(this, state.getCenterY(), state, true);
snapY.call(this, state.y, state, false);
snapY.call(this, state.y + state.height, state, false);
if (state.cell == null)
{
snapY.call(this, state.getCenterY(), state, false);
}
}
}
}
this.graph.snapDelta(delta, bounds, !gridEnabled, overrideX, overrideY);
delta = this.getDelta(bounds, stateX, delta.x, stateY, delta.y);
var c = this.graph.container;
if (!overrideX && this.guideX != null)
{
this.guideX.node.style.visibility = 'hidden';
}
else if (this.guideX != null)
{
var minY = null;
var maxY = null;
if (stateX != null && bounds != null)
{
minY = Math.min(bounds.y + delta.y - this.graph.panDy, stateX.y);
maxY = Math.max(bounds.y + bounds.height + delta.y - this.graph.panDy, stateX.y + stateX.height);
}
if (minY != null && maxY != null)
{
this.guideX.points = [new mxPoint(valueX, minY), new mxPoint(valueX, maxY)];
}
else
{
this.guideX.points = [new mxPoint(valueX, -this.graph.panDy),
new mxPoint(valueX, c.scrollHeight - 3 - this.graph.panDy)];
}
this.guideX.stroke = this.getGuideColor(stateX, true);
this.guideX.node.style.visibility = 'visible';
this.guideX.redraw();
}
if (!overrideY && this.guideY != null)
{
this.guideY.node.style.visibility = 'hidden';
}
else if (this.guideY != null)
{
var minX = null;
var maxX = null;
if (stateY != null && bounds != null)
{
minX = Math.min(bounds.x + delta.x - this.graph.panDx, stateY.x);
maxX = Math.max(bounds.x + bounds.width + delta.x - this.graph.panDx, stateY.x + stateY.width);
}
if (minX != null && maxX != null)
{
this.guideY.points = [new mxPoint(minX, valueY), new mxPoint(maxX, valueY)];
}
else
{
this.guideY.points = [new mxPoint(-this.graph.panDx, valueY),
new mxPoint(c.scrollWidth - 3 - this.graph.panDx, valueY)];
}
this.guideY.stroke = this.getGuideColor(stateY, false);
this.guideY.node.style.visibility = 'visible';
this.guideY.redraw();
}
}
return delta;
};
mxGuide.prototype.getDelta = function(bounds, stateX, dx, stateY, dy)
{
var s = this.graph.view.scale;
if (this.rounded || (stateX != null && stateX.cell == null))
{
dx = Math.round((bounds.x + dx) / s) * s - bounds.x;
}
if (this.rounded || (stateY != null && stateY.cell == null))
{
dy = Math.round((bounds.y + dy) / s) * s - bounds.y;
}
return new mxPoint(dx, dy);
};
mxGuide.prototype.getGuideColor = function(state, horizontal)
{
return mxConstants.GUIDE_COLOR;
};
mxGuide.prototype.hide = function()
{
this.setVisible(false);
};
mxGuide.prototype.setVisible = function(visible)
{
if (this.guideX != null)
{
this.guideX.node.style.visibility = (visible) ? 'visible' : 'hidden';
}
if (this.guideY != null)
{
this.guideY.node.style.visibility = (visible) ? 'visible' : 'hidden';
}
};
mxGuide.prototype.destroy = function()
{
if (this.guideX != null)
{
this.guideX.destroy();
this.guideX = null;
}
if (this.guideY != null)
{
this.guideY.destroy();
this.guideY = null;
}
};
__mxOutput.mxGuide = typeof mxGuide !== 'undefined' ? mxGuide : undefined;
function mxShape(stencil)
{
this.stencil = stencil;
this.initStyles();
} mxShape.prototype.dialect = null;
mxShape.prototype.scale = 1;
mxShape.prototype.antiAlias = true;
mxShape.prototype.minSvgStrokeWidth = 1;
mxShape.prototype.bounds = null;
mxShape.prototype.points = null;
mxShape.prototype.node = null;
mxShape.prototype.state = null;
mxShape.prototype.style = null;
mxShape.prototype.boundingBox = null;
mxShape.prototype.stencil = null;
mxShape.prototype.svgStrokeTolerance = 8;
mxShape.prototype.pointerEvents = true;
mxShape.prototype.svgPointerEvents = 'all';
mxShape.prototype.shapePointerEvents = false;
mxShape.prototype.stencilPointerEvents = false;
mxShape.prototype.vmlScale = 1;
mxShape.prototype.outline = false;
mxShape.prototype.visible = true;
mxShape.prototype.useSvgBoundingBox = false;
mxShape.prototype.init = function(container)
{
if (this.node == null)
{
this.node = this.create(container);
if (container != null)
{
container.appendChild(this.node);
}
}
};
mxShape.prototype.initStyles = function(container)
{
this.strokewidth = 1;
this.rotation = 0;
this.opacity = 100;
this.fillOpacity = 100;
this.strokeOpacity = 100;
this.flipH = false;
this.flipV = false;
};
mxShape.prototype.isParseVml = function()
{
return true;
};
mxShape.prototype.isHtmlAllowed = function()
{
return false;
};
mxShape.prototype.getSvgScreenOffset = function()
{
var sw = this.stencil && this.stencil.strokewidth != 'inherit' ? Number(this.stencil.strokewidth) : this.strokewidth;
return (mxUtils.mod(Math.max(1, Math.round(sw * this.scale)), 2) == 1) ? 0.5 : 0;
};
mxShape.prototype.create = function(container)
{
var node = null;
if (container != null && container.ownerSVGElement != null)
{
node = this.createSvg(container);
}
else if (document.documentMode == 8 || !mxClient.IS_VML ||
(this.dialect != mxConstants.DIALECT_VML && this.isHtmlAllowed()))
{
node = this.createHtml(container);
}
else
{
node = this.createVml(container);
}
return node;
};
mxShape.prototype.createSvg = function()
{
return document.createElementNS(mxConstants.NS_SVG, 'g');
};
mxShape.prototype.createVml = function()
{
var node = document.createElement(mxClient.VML_PREFIX + ':group');
node.style.position = 'absolute';
return node;
};
mxShape.prototype.createHtml = function()
{
var node = document.createElement('div');
node.style.position = 'absolute';
return node;
};
mxShape.prototype.reconfigure = function()
{
this.redraw();
};
mxShape.prototype.redraw = function()
{
this.updateBoundsFromPoints();
if (this.visible && this.checkBounds())
{
this.node.style.visibility = 'visible';
this.clear();
if (this.node.nodeName == 'DIV' && (this.isHtmlAllowed() || !mxClient.IS_VML))
{
this.redrawHtmlShape();
}
else
{
this.redrawShape();
}
this.updateBoundingBox();
}
else
{
this.node.style.visibility = 'hidden';
this.boundingBox = null;
}
};
mxShape.prototype.clear = function()
{
if (this.node.ownerSVGElement != null)
{
while (this.node.lastChild != null)
{
this.node.removeChild(this.node.lastChild);
}
}
else
{
this.node.style.cssText = 'position:absolute;' + ((this.cursor != null) ?
('cursor:' + this.cursor + ';') : '');
this.node.innerHTML = '';
}
};
mxShape.prototype.updateBoundsFromPoints = function()
{
var pts = this.points;
if (pts != null && pts.length > 0 && pts[0] != null)
{
this.bounds = new mxRectangle(Number(pts[0].x), Number(pts[0].y), 1, 1);
for (var i = 1; i < this.points.length; i++)
{
if (pts[i] != null)
{
this.bounds.add(new mxRectangle(Number(pts[i].x), Number(pts[i].y), 1, 1));
}
}
}
};
mxShape.prototype.getLabelBounds = function(rect)
{
var d = mxUtils.getValue(this.style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
var bounds = rect;
if (d != mxConstants.DIRECTION_SOUTH && d != mxConstants.DIRECTION_NORTH &&
this.state != null && this.state.text != null &&
this.state.text.isPaintBoundsInverted())
{
bounds = bounds.clone();
var tmp = bounds.width;
bounds.width = bounds.height;
bounds.height = tmp;
}
var m = this.getLabelMargins(bounds);
if (m != null)
{
var flipH = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPH, false) == '1';
var flipV = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPV, false) == '1';
if (this.state != null && this.state.text != null &&
this.state.text.isPaintBoundsInverted())
{
var tmp = m.x;
m.x = m.height;
m.height = m.width;
m.width = m.y;
m.y = tmp;
tmp = flipH;
flipH = flipV;
flipV = tmp;
}
return mxUtils.getDirectedBounds(rect, m, this.style, flipH, flipV);
}
return rect;
};
mxShape.prototype.getLabelMargins= function(rect)
{
return null;
};
mxShape.prototype.checkBounds = function()
{
return (!isNaN(this.scale) && isFinite(this.scale) && this.scale > 0 &&
this.bounds != null && !isNaN(this.bounds.x) && !isNaN(this.bounds.y) &&
!isNaN(this.bounds.width) && !isNaN(this.bounds.height) &&
this.bounds.width > 0 && this.bounds.height > 0);
};
mxShape.prototype.createVmlGroup = function()
{
var node = document.createElement(mxClient.VML_PREFIX + ':group');
node.style.position = 'absolute';
node.style.width = this.node.style.width;
node.style.height = this.node.style.height;
return node;
};
mxShape.prototype.redrawShape = function()
{
var canvas = this.createCanvas();
if (canvas != null)
{
canvas.pointerEvents = this.pointerEvents;
this.beforePaint(canvas);
this.paint(canvas);
this.afterPaint(canvas);
if (this.node != canvas.root)
{
this.node.insertAdjacentHTML('beforeend', canvas.root.outerHTML);
}
if (this.node.nodeName == 'DIV' && document.documentMode == 8)
{
this.node.style.filter = '';
mxUtils.addTransparentBackgroundFilter(this.node);
}
this.destroyCanvas(canvas);
}
};
mxShape.prototype.createCanvas = function()
{
var canvas = null;
if (this.node.ownerSVGElement != null)
{
canvas = this.createSvgCanvas();
}
else if (mxClient.IS_VML)
{
this.updateVmlContainer();
canvas = this.createVmlCanvas();
}
if (canvas != null && this.outline)
{
canvas.setStrokeWidth(this.strokewidth);
canvas.setStrokeColor(this.stroke);
if (this.isDashed != null)
{
canvas.setDashed(this.isDashed);
}
canvas.setStrokeWidth = function() {};
canvas.setStrokeColor = function() {};
canvas.setFillColor = function() {};
canvas.setGradient = function() {};
canvas.setDashed = function() {};
canvas.text = function() {};
}
return canvas;
};
mxShape.prototype.createSvgCanvas = function()
{
var canvas = new mxSvgCanvas2D(this.node, false);
canvas.strokeTolerance = (this.pointerEvents) ? this.svgStrokeTolerance : 0;
canvas.pointerEventsValue = this.svgPointerEvents;
var off = this.getSvgScreenOffset();
if (off != 0)
{
this.node.setAttribute('transform', 'translate(' + off + ',' + off + ')');
}
else
{
this.node.removeAttribute('transform');
}
canvas.minStrokeWidth = this.minSvgStrokeWidth;
if (!this.antiAlias)
{
canvas.format = function(value)
{
return Math.round(parseFloat(value));
};
}
return canvas;
};
mxShape.prototype.createVmlCanvas = function()
{
var node = (document.documentMode == 8 && this.isParseVml()) ? this.createVmlGroup() : this.node;
var canvas = new mxVmlCanvas2D(node);
if (node.tagUrn != '')
{
var w = Math.max(1, Math.round(this.bounds.width));
var h = Math.max(1, Math.round(this.bounds.height));
node.coordsize = (w * this.vmlScale) + ',' + (h * this.vmlScale);
canvas.scale(this.vmlScale);
canvas.vmlScale = this.vmlScale;
}
var s = this.scale;
canvas.translate(-Math.round(this.bounds.x / s), -Math.round(this.bounds.y / s));
return canvas;
};
mxShape.prototype.updateVmlContainer = function()
{
this.node.style.left = Math.round(this.bounds.x) + 'px';
this.node.style.top = Math.round(this.bounds.y) + 'px';
var w = Math.max(1, Math.round(this.bounds.width));
var h = Math.max(1, Math.round(this.bounds.height));
this.node.style.width = w + 'px';
this.node.style.height = h + 'px';
this.node.style.overflow = 'visible';
};
mxShape.prototype.redrawHtmlShape = function()
{
this.updateHtmlBounds(this.node);
this.updateHtmlFilters(this.node);
this.updateHtmlColors(this.node);
};
mxShape.prototype.updateHtmlFilters = function(node)
{
var f = '';
if (this.opacity < 100)
{
f += 'alpha(opacity=' + (this.opacity) + ')';
}
if (this.isShadow)
{
f += 'progid:DXImageTransform.Microsoft.dropShadow (' +
'OffX=\'' + Math.round(mxConstants.SHADOW_OFFSET_X * this.scale) + '\', ' +
'OffY=\'' + Math.round(mxConstants.SHADOW_OFFSET_Y * this.scale) + '\', ' +
'Color=\'' + mxConstants.VML_SHADOWCOLOR + '\')';
}
if (this.fill != null && this.fill != mxConstants.NONE && this.gradient && this.gradient != mxConstants.NONE)
{
var start = this.fill;
var end = this.gradient;
var type = '0';
var lookup = {east:0,south:1,west:2,north:3};
var dir = (this.direction != null) ? lookup[this.direction] : 0;
if (this.gradientDirection != null)
{
dir = mxUtils.mod(dir + lookup[this.gradientDirection] - 1, 4);
}
if (dir == 1)
{
type = '1';
var tmp = start;
start = end;
end = tmp;
}
else if (dir == 2)
{
var tmp = start;
start = end;
end = tmp;
}
else if (dir == 3)
{
type = '1';
}
f += 'progid:DXImageTransform.Microsoft.gradient(' +
'startColorStr=\'' + start + '\', endColorStr=\'' + end +
'\', gradientType=\'' + type + '\')';
}
node.style.filter = f;
};
mxShape.prototype.updateHtmlColors = function(node)
{
var color = this.stroke;
if (color != null && color != mxConstants.NONE)
{
node.style.borderColor = color;
if (this.isDashed)
{
node.style.borderStyle = 'dashed';
}
else if (this.strokewidth > 0)
{
node.style.borderStyle = 'solid';
}
node.style.borderWidth = Math.max(1, Math.ceil(this.strokewidth * this.scale)) + 'px';
}
else
{
node.style.borderWidth = '0px';
}
color = (this.outline) ? null : this.fill;
if (color != null && color != mxConstants.NONE)
{
node.style.backgroundColor = color;
node.style.backgroundImage = 'none';
}
else if (this.pointerEvents)
{
node.style.backgroundColor = 'transparent';
}
else if (document.documentMode == 8)
{
mxUtils.addTransparentBackgroundFilter(node);
}
else
{
this.setTransparentBackgroundImage(node);
}
};
mxShape.prototype.updateHtmlBounds = function(node)
{
var sw = (document.documentMode >= 9) ? 0 : Math.ceil(this.strokewidth * this.scale);
node.style.borderWidth = Math.max(1, sw) + 'px';
node.style.overflow = 'hidden';
node.style.left = Math.round(this.bounds.x - sw / 2) + 'px';
node.style.top = Math.round(this.bounds.y - sw / 2) + 'px';
if (document.compatMode == 'CSS1Compat')
{
sw = -sw;
}
node.style.width = Math.round(Math.max(0, this.bounds.width + sw)) + 'px';
node.style.height = Math.round(Math.max(0, this.bounds.height + sw)) + 'px';
};
mxShape.prototype.destroyCanvas = function(canvas)
{
if (canvas instanceof mxSvgCanvas2D)
{
for (var key in canvas.gradients)
{
var gradient = canvas.gradients[key];
if (gradient != null)
{
gradient.mxRefCount = (gradient.mxRefCount || 0) + 1;
}
}
this.releaseSvgGradients(this.oldGradients);
this.oldGradients = canvas.gradients;
}
};
mxShape.prototype.beforePaint = function(c) { };
mxShape.prototype.afterPaint = function(c) { };
mxShape.prototype.paint = function(c)
{
var strokeDrawn = false;
if (c != null && this.outline)
{
var stroke = c.stroke;
c.stroke = function()
{
strokeDrawn = true;
stroke.apply(this, arguments);
};
var fillAndStroke = c.fillAndStroke;
c.fillAndStroke = function()
{
strokeDrawn = true;
fillAndStroke.apply(this, arguments);
};
}
var s = this.scale;
var x = this.bounds.x / s;
var y = this.bounds.y / s;
var w = this.bounds.width / s;
var h = this.bounds.height / s;
if (this.isPaintBoundsInverted())
{
var t = (w - h) / 2;
x += t;
y -= t;
var tmp = w;
w = h;
h = tmp;
}
this.updateTransform(c, x, y, w, h);
this.configureCanvas(c, x, y, w, h);
var bg = null;
if ((this.stencil == null && this.points == null && this.shapePointerEvents) ||
(this.stencil != null && this.stencilPointerEvents))
{
var bb = this.createBoundingBox();
if (this.dialect == mxConstants.DIALECT_SVG)
{
bg = this.createTransparentSvgRectangle(bb.x, bb.y, bb.width, bb.height);
this.node.appendChild(bg);
}
else
{
var rect = c.createRect('rect', bb.x / s, bb.y / s, bb.width / s, bb.height / s);
rect.appendChild(c.createTransparentFill());
rect.stroked = 'false';
c.root.appendChild(rect);
}
}
if (this.stencil != null)
{
this.stencil.drawShape(c, this, x, y, w, h);
}
else
{
c.setStrokeWidth(this.strokewidth);
if (this.points != null)
{
var pts = [];
for (var i = 0; i < this.points.length; i++)
{
if (this.points[i] != null)
{
pts.push(new mxPoint(this.points[i].x / s, this.points[i].y / s));
}
}
this.paintEdgeShape(c, pts);
}
else
{
this.paintVertexShape(c, x, y, w, h);
}
}
if (bg != null && c.state != null && c.state.transform != null)
{
bg.setAttribute('transform', c.state.transform);
}
if (c != null && this.outline && !strokeDrawn)
{
c.rect(x, y, w, h);
c.stroke();
}
};
mxShape.prototype.configureCanvas = function(c, x, y, w, h)
{
var dash = null;
if (this.style != null)
{
dash = this.style['dashPattern'];
}
c.setAlpha(this.opacity / 100);
c.setFillAlpha(this.fillOpacity / 100);
c.setStrokeAlpha(this.strokeOpacity / 100);
if (this.isShadow != null)
{
c.setShadow(this.isShadow);
}
if (this.isDashed != null)
{
c.setDashed(this.isDashed, (this.style != null) ?
mxUtils.getValue(this.style, mxConstants.STYLE_FIX_DASH, false) == 1 : false);
}
if (dash != null)
{
c.setDashPattern(dash);
}
if (this.fill != null && this.fill != mxConstants.NONE && this.gradient && this.gradient != mxConstants.NONE)
{
var b = this.getGradientBounds(c, x, y, w, h);
c.setGradient(this.fill, this.gradient, b.x, b.y, b.width, b.height, this.gradientDirection);
}
else
{
c.setFillColor(this.fill);
}
c.setStrokeColor(this.stroke);
};
mxShape.prototype.getGradientBounds = function(c, x, y, w, h)
{
return new mxRectangle(x, y, w, h);
};
mxShape.prototype.updateTransform = function(c, x, y, w, h)
{
c.scale(this.scale);
c.rotate(this.getShapeRotation(), this.flipH, this.flipV, x + w / 2, y + h / 2);
};
mxShape.prototype.paintVertexShape = function(c, x, y, w, h)
{
this.paintBackground(c, x, y, w, h);
if (!this.outline || this.style == null || mxUtils.getValue(
this.style, mxConstants.STYLE_BACKGROUND_OUTLINE, 0) == 0)
{
c.setShadow(false);
this.paintForeground(c, x, y, w, h);
}
};
mxShape.prototype.paintBackground = function(c, x, y, w, h) { };
mxShape.prototype.paintForeground = function(c, x, y, w, h) { };
mxShape.prototype.paintEdgeShape = function(c, pts) { };
mxShape.prototype.getArcSize = function(w, h)
{
var r = 0;
if (mxUtils.getValue(this.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1')
{
r = Math.min(w / 2, Math.min(h / 2, mxUtils.getValue(this.style,
mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2));
}
else
{
var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE,
mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;
r = Math.min(w * f, h * f);
}
return r;
};
mxShape.prototype.paintGlassEffect = function(c, x, y, w, h, arc)
{
var sw = Math.ceil(this.strokewidth / 2);
var size = 0.4;
c.setGradient('#ffffff', '#ffffff', x, y, w, h * 0.6, 'south', 0.9, 0.1);
c.begin();
arc += 2 * sw;
if (this.isRounded)
{
c.moveTo(x - sw + arc, y - sw);
c.quadTo(x - sw, y - sw, x - sw, y - sw + arc);
c.lineTo(x - sw, y + h * size);
c.quadTo(x + w * 0.5, y + h * 0.7, x + w + sw, y + h * size);
c.lineTo(x + w + sw, y - sw + arc);
c.quadTo(x + w + sw, y - sw, x + w + sw - arc, y - sw);
}
else
{
c.moveTo(x - sw, y - sw);
c.lineTo(x - sw, y + h * size);
c.quadTo(x + w * 0.5, y + h * 0.7, x + w + sw, y + h * size);
c.lineTo(x + w + sw, y - sw);
}
c.close();
c.fill();
};
mxShape.prototype.addPoints = function(c, pts, rounded, arcSize, close, exclude, initialMove)
{
if (pts != null && pts.length > 0)
{
initialMove = (initialMove != null) ? initialMove : true;
var pe = pts[pts.length - 1];
if (close && rounded)
{
pts = pts.slice();
var p0 = pts[0];
var wp = new mxPoint(pe.x + (p0.x - pe.x) / 2, pe.y + (p0.y - pe.y) / 2);
pts.splice(0, 0, wp);
}
var pt = pts[0];
var i = 1;
if (initialMove)
{
c.moveTo(pt.x, pt.y);
}
else
{
c.lineTo(pt.x, pt.y);
}
while (i < ((close) ? pts.length : pts.length - 1))
{
var tmp = pts[mxUtils.mod(i, pts.length)];
var dx = pt.x - tmp.x;
var dy = pt.y - tmp.y;
if (rounded && (dx != 0 || dy != 0) && (exclude == null || mxUtils.indexOf(exclude, i - 1) < 0))
{
var dist = Math.sqrt(dx * dx + dy * dy);
var nx1 = dx * Math.min(arcSize, dist / 2) / dist;
var ny1 = dy * Math.min(arcSize, dist / 2) / dist;
var x1 = tmp.x + nx1;
var y1 = tmp.y + ny1;
c.lineTo(x1, y1);
var next = pts[mxUtils.mod(i + 1, pts.length)];
while (i < pts.length - 2 && Math.round(next.x - tmp.x) == 0 && Math.round(next.y - tmp.y) == 0)
{
next = pts[mxUtils.mod(i + 2, pts.length)];
i++;
}
dx = next.x - tmp.x;
dy = next.y - tmp.y;
dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
var nx2 = dx * Math.min(arcSize, dist / 2) / dist;
var ny2 = dy * Math.min(arcSize, dist / 2) / dist;
var x2 = tmp.x + nx2;
var y2 = tmp.y + ny2;
c.quadTo(tmp.x, tmp.y, x2, y2);
tmp = new mxPoint(x2, y2);
}
else
{
c.lineTo(tmp.x, tmp.y);
}
pt = tmp;
i++;
}
if (close)
{
c.close();
}
else
{
c.lineTo(pe.x, pe.y);
}
}
};
mxShape.prototype.resetStyles = function()
{
this.initStyles();
this.spacing = 0;
delete this.fill;
delete this.gradient;
delete this.gradientDirection;
delete this.stroke;
delete this.startSize;
delete this.endSize;
delete this.startArrow;
delete this.endArrow;
delete this.direction;
delete this.isShadow;
delete this.isDashed;
delete this.isRounded;
delete this.glass;
};
mxShape.prototype.apply = function(state)
{
this.state = state;
this.style = state.style;
if (this.style != null)
{
this.fill = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, this.fill);
this.gradient = mxUtils.getValue(this.style, mxConstants.STYLE_GRADIENTCOLOR, this.gradient);
this.gradientDirection = mxUtils.getValue(this.style, mxConstants.STYLE_GRADIENT_DIRECTION, this.gradientDirection);
this.opacity = mxUtils.getValue(this.style, mxConstants.STYLE_OPACITY, this.opacity);
this.fillOpacity = mxUtils.getValue(this.style, mxConstants.STYLE_FILL_OPACITY, this.fillOpacity);
this.strokeOpacity = mxUtils.getValue(this.style, mxConstants.STYLE_STROKE_OPACITY, this.strokeOpacity);
this.stroke = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, this.stroke);
this.strokewidth = mxUtils.getNumber(this.style, mxConstants.STYLE_STROKEWIDTH, this.strokewidth);
this.spacing = mxUtils.getValue(this.style, mxConstants.STYLE_SPACING, this.spacing);
this.startSize = mxUtils.getNumber(this.style, mxConstants.STYLE_STARTSIZE, this.startSize);
this.endSize = mxUtils.getNumber(this.style, mxConstants.STYLE_ENDSIZE, this.endSize);
this.startArrow = mxUtils.getValue(this.style, mxConstants.STYLE_STARTARROW, this.startArrow);
this.endArrow = mxUtils.getValue(this.style, mxConstants.STYLE_ENDARROW, this.endArrow);
this.rotation = mxUtils.getValue(this.style, mxConstants.STYLE_ROTATION, this.rotation);
this.direction = mxUtils.getValue(this.style, mxConstants.STYLE_DIRECTION, this.direction);
this.flipH = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPH, 0) == 1;
this.flipV = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPV, 0) == 1;
if (this.stencil != null)
{
this.flipH = mxUtils.getValue(this.style, 'stencilFlipH', 0) == 1 || this.flipH;
this.flipV = mxUtils.getValue(this.style, 'stencilFlipV', 0) == 1 || this.flipV;
}
if (this.direction == mxConstants.DIRECTION_NORTH || this.direction == mxConstants.DIRECTION_SOUTH)
{
var tmp = this.flipH;
this.flipH = this.flipV;
this.flipV = tmp;
}
this.isShadow = mxUtils.getValue(this.style, mxConstants.STYLE_SHADOW, this.isShadow) == 1;
this.isDashed = mxUtils.getValue(this.style, mxConstants.STYLE_DASHED, this.isDashed) == 1;
this.isRounded = mxUtils.getValue(this.style, mxConstants.STYLE_ROUNDED, this.isRounded) == 1;
this.glass = mxUtils.getValue(this.style, mxConstants.STYLE_GLASS, this.glass) == 1;
if (this.fill == mxConstants.NONE)
{
this.fill = null;
}
if (this.gradient == mxConstants.NONE)
{
this.gradient = null;
}
if (this.stroke == mxConstants.NONE)
{
this.stroke = null;
}
}
};
mxShape.prototype.setCursor = function(cursor)
{
if (cursor == null)
{
cursor = '';
}
this.cursor = cursor;
if (this.node != null)
{
this.node.style.cursor = cursor;
}
};
mxShape.prototype.getCursor = function()
{
return this.cursor;
};
mxShape.prototype.isRoundable = function()
{
return false;
};
mxShape.prototype.updateBoundingBox = function()
{
if (this.useSvgBoundingBox && this.node != null && this.node.ownerSVGElement != null)
{
try
{
var b = this.node.getBBox();
if (b.width > 0 && b.height > 0)
{
this.boundingBox = new mxRectangle(b.x, b.y, b.width, b.height);
this.boundingBox.grow(this.strokewidth * this.scale / 2);
return;
}
}
catch(e)
{
}
}
if (this.bounds != null)
{
var bbox = this.createBoundingBox();
if (bbox != null)
{
this.augmentBoundingBox(bbox);
var rot = this.getShapeRotation();
if (rot != 0)
{
bbox = mxUtils.getBoundingBox(bbox, rot);
}
}
this.boundingBox = bbox;
}
};
mxShape.prototype.createBoundingBox = function()
{
var bb = this.bounds.clone();
if ((this.stencil != null && (this.direction == mxConstants.DIRECTION_NORTH ||
this.direction == mxConstants.DIRECTION_SOUTH)) || this.isPaintBoundsInverted())
{
bb.rotate90();
}
return bb;
};
mxShape.prototype.augmentBoundingBox = function(bbox)
{
if (this.isShadow)
{
bbox.width += Math.ceil(mxConstants.SHADOW_OFFSET_X * this.scale);
bbox.height += Math.ceil(mxConstants.SHADOW_OFFSET_Y * this.scale);
}
bbox.grow(this.strokewidth * this.scale / 2);
};
mxShape.prototype.isPaintBoundsInverted = function()
{
return this.stencil == null && (this.direction == mxConstants.DIRECTION_NORTH ||
this.direction == mxConstants.DIRECTION_SOUTH);
};
mxShape.prototype.getRotation = function()
{
return (this.rotation != null) ? this.rotation : 0;
};
mxShape.prototype.getTextRotation = function()
{
var rot = this.getRotation();
if (mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, 1) != 1)
{
rot += mxText.prototype.verticalTextRotation;
}
return rot;
};
mxShape.prototype.getShapeRotation = function()
{
var rot = this.getRotation();
if (this.direction != null)
{
if (this.direction == mxConstants.DIRECTION_NORTH)
{
rot += 270;
}
else if (this.direction == mxConstants.DIRECTION_WEST)
{
rot += 180;
}
else if (this.direction == mxConstants.DIRECTION_SOUTH)
{
rot += 90;
}
}
return rot;
};
mxShape.prototype.createTransparentSvgRectangle = function(x, y, w, h)
{
var rect = document.createElementNS(mxConstants.NS_SVG, 'rect');
rect.setAttribute('x', x);
rect.setAttribute('y', y);
rect.setAttribute('width', w);
rect.setAttribute('height', h);
rect.setAttribute('fill', 'none');
rect.setAttribute('stroke', 'none');
rect.setAttribute('pointer-events', 'all');
return rect;
};
mxShape.prototype.setTransparentBackgroundImage = function(node)
{
node.style.backgroundImage = 'url(\'' + mxClient.imageBasePath + '/transparent.gif\')';
};
mxShape.prototype.releaseSvgGradients = function(grads)
{
if (grads != null)
{
for (var key in grads)
{
var gradient = grads[key];
if (gradient != null)
{
gradient.mxRefCount = (gradient.mxRefCount || 0) - 1;
if (gradient.mxRefCount == 0 && gradient.parentNode != null)
{
gradient.parentNode.removeChild(gradient);
}
}
}
}
};
mxShape.prototype.destroy = function()
{
if (this.node != null)
{
mxEvent.release(this.node);
if (this.node.parentNode != null)
{
this.node.parentNode.removeChild(this.node);
}
this.node = null;
}
this.releaseSvgGradients(this.oldGradients);
this.oldGradients = null;
};
__mxOutput.mxShape = typeof mxShape !== 'undefined' ? mxShape : undefined;
function mxStencil(desc)
{
this.desc = desc;
this.parseDescription();
this.parseConstraints();
} mxUtils.extend(mxStencil, mxShape);
mxStencil.defaultLocalized = false;
mxStencil.allowEval = false;
mxStencil.prototype.desc = null;
mxStencil.prototype.constraints = null;
mxStencil.prototype.aspect = null;
mxStencil.prototype.w0 = null;
mxStencil.prototype.h0 = null;
mxStencil.prototype.bgNode = null;
mxStencil.prototype.fgNode = null;
mxStencil.prototype.strokewidth = null;
mxStencil.prototype.parseDescription = function()
{
this.fgNode = this.desc.getElementsByTagName('foreground')[0];
this.bgNode = this.desc.getElementsByTagName('background')[0];
this.w0 = Number(this.desc.getAttribute('w') || 100);
this.h0 = Number(this.desc.getAttribute('h') || 100);
var aspect = this.desc.getAttribute('aspect');
this.aspect = (aspect != null) ? aspect : 'variable';
var sw = this.desc.getAttribute('strokewidth');
this.strokewidth = (sw != null) ? sw : '1';
};
mxStencil.prototype.parseConstraints = function()
{
var conns = this.desc.getElementsByTagName('connections')[0];
if (conns != null)
{
var tmp = mxUtils.getChildNodes(conns);
if (tmp != null && tmp.length > 0)
{
this.constraints = [];
for (var i = 0; i < tmp.length; i++)
{
this.constraints.push(this.parseConstraint(tmp[i]));
}
}
}
};
mxStencil.prototype.parseConstraint = function(node)
{
var x = Number(node.getAttribute('x'));
var y = Number(node.getAttribute('y'));
var perimeter = node.getAttribute('perimeter') == '1';
var name = node.getAttribute('name');
return new mxConnectionConstraint(new mxPoint(x, y), perimeter, name);
};
mxStencil.prototype.evaluateTextAttribute = function(node, attribute, shape)
{
var result = this.evaluateAttribute(node, attribute, shape);
var loc = node.getAttribute('localized');
if ((mxStencil.defaultLocalized && loc == null) || loc == '1')
{
result = mxResources.get(result);
}
return result;
};
mxStencil.prototype.evaluateAttribute = function(node, attribute, shape)
{
var result = node.getAttribute(attribute);
if (result == null)
{
var text = mxUtils.getTextContent(node);
if (text != null && mxStencil.allowEval)
{
var funct = mxUtils.eval(text);
if (typeof(funct) == 'function')
{
result = funct(shape);
}
}
}
return result;
};
mxStencil.prototype.drawShape = function(canvas, shape, x, y, w, h)
{
var stack = canvas.states.slice();
var direction = mxUtils.getValue(shape.style, mxConstants.STYLE_DIRECTION, null);
var aspect = this.computeAspect(shape.style, x, y, w, h, direction);
var minScale = Math.min(aspect.width, aspect.height);
var sw = (this.strokewidth == 'inherit') ?
Number(mxUtils.getNumber(shape.style, mxConstants.STYLE_STROKEWIDTH, 1)) :
Number(this.strokewidth) * minScale;
canvas.setStrokeWidth(sw);
if (shape.style != null && mxUtils.getValue(shape.style, mxConstants.STYLE_POINTER_EVENTS, '0') == '1')
{
canvas.setStrokeColor(mxConstants.NONE);
canvas.rect(x, y, w, h);
canvas.stroke();
canvas.setStrokeColor(shape.stroke);
}
this.drawChildren(canvas, shape, x, y, w, h, this.bgNode, aspect, false, true);
this.drawChildren(canvas, shape, x, y, w, h, this.fgNode, aspect, true,
!shape.outline || shape.style == null || mxUtils.getValue(
shape.style, mxConstants.STYLE_BACKGROUND_OUTLINE, 0) == 0);
if (canvas.states.length != stack.length)
{
canvas.states = stack;
}
};
mxStencil.prototype.drawChildren = function(canvas, shape, x, y, w, h, node, aspect, disableShadow, paint)
{
if (node != null && w > 0 && h > 0)
{
var tmp = node.firstChild;
while (tmp != null)
{
if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT)
{
this.drawNode(canvas, shape, tmp, aspect, disableShadow, paint);
}
tmp = tmp.nextSibling;
}
}
};
mxStencil.prototype.computeAspect = function(shape, x, y, w, h, direction)
{
var x0 = x;
var y0 = y;
var sx = w / this.w0;
var sy = h / this.h0;
var inverse = (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH);
if (inverse)
{
sy = w / this.h0;
sx = h / this.w0;
var delta = (w - h) / 2;
x0 += delta;
y0 -= delta;
}
if (this.aspect == 'fixed')
{
sy = Math.min(sx, sy);
sx = sy;
if (inverse)
{
x0 += (h - this.w0 * sx) / 2;
y0 += (w - this.h0 * sy) / 2;
}
else
{
x0 += (w - this.w0 * sx) / 2;
y0 += (h - this.h0 * sy) / 2;
}
}
return new mxRectangle(x0, y0, sx, sy);
};
mxStencil.prototype.drawNode = function(canvas, shape, node, aspect, disableShadow, paint)
{
var name = node.nodeName;
var x0 = aspect.x;
var y0 = aspect.y;
var sx = aspect.width;
var sy = aspect.height;
var minScale = Math.min(sx, sy);
if (name == 'save')
{
canvas.save();
}
else if (name == 'restore')
{
canvas.restore();
}
else if (paint)
{
if (name == 'path')
{
canvas.begin();
var parseRegularly = true;
if (node.getAttribute('rounded') == '1')
{
parseRegularly = false;
var arcSize = Number(node.getAttribute('arcSize'));
var pointCount = 0;
var segs = [];
var childNode = node.firstChild;
while (childNode != null)
{
if (childNode.nodeType == mxConstants.NODETYPE_ELEMENT)
{
var childName = childNode.nodeName;
if (childName == 'move' || childName == 'line')
{
if (childName == 'move' || segs.length == 0)
{
segs.push([]);
}
segs[segs.length - 1].push(new mxPoint(x0 + Number(childNode.getAttribute('x')) * sx,
y0 + Number(childNode.getAttribute('y')) * sy));
pointCount++;
}
else
{
parseRegularly = true;
break;
}
}
childNode = childNode.nextSibling;
}
if (!parseRegularly && pointCount > 0)
{
for (var i = 0; i < segs.length; i++)
{
var close = false, ps = segs[i][0], pe = segs[i][segs[i].length - 1];
if (ps.x == pe.x && ps.y == pe.y)
{
segs[i].pop();
close = true;
}
this.addPoints(canvas, segs[i], true, arcSize, close);
}
}
else
{
parseRegularly = true;
}
}
if (parseRegularly)
{
var childNode = node.firstChild;
while (childNode != null)
{
if (childNode.nodeType == mxConstants.NODETYPE_ELEMENT)
{
this.drawNode(canvas, shape, childNode, aspect, disableShadow, paint);
}
childNode = childNode.nextSibling;
}
}
}
else if (name == 'close')
{
canvas.close();
}
else if (name == 'move')
{
canvas.moveTo(x0 + Number(node.getAttribute('x')) * sx, y0 + Number(node.getAttribute('y')) * sy);
}
else if (name == 'line')
{
canvas.lineTo(x0 + Number(node.getAttribute('x')) * sx, y0 + Number(node.getAttribute('y')) * sy);
}
else if (name == 'quad')
{
canvas.quadTo(x0 + Number(node.getAttribute('x1')) * sx,
y0 + Number(node.getAttribute('y1')) * sy,
x0 + Number(node.getAttribute('x2')) * sx,
y0 + Number(node.getAttribute('y2')) * sy);
}
else if (name == 'curve')
{
canvas.curveTo(x0 + Number(node.getAttribute('x1')) * sx,
y0 + Number(node.getAttribute('y1')) * sy,
x0 + Number(node.getAttribute('x2')) * sx,
y0 + Number(node.getAttribute('y2')) * sy,
x0 + Number(node.getAttribute('x3')) * sx,
y0 + Number(node.getAttribute('y3')) * sy);
}
else if (name == 'arc')
{
canvas.arcTo(Number(node.getAttribute('rx')) * sx,
Number(node.getAttribute('ry')) * sy,
Number(node.getAttribute('x-axis-rotation')),
Number(node.getAttribute('large-arc-flag')),
Number(node.getAttribute('sweep-flag')),
x0 + Number(node.getAttribute('x')) * sx,
y0 + Number(node.getAttribute('y')) * sy);
}
else if (name == 'rect')
{
canvas.rect(x0 + Number(node.getAttribute('x')) * sx,
y0 + Number(node.getAttribute('y')) * sy,
Number(node.getAttribute('w')) * sx,
Number(node.getAttribute('h')) * sy);
}
else if (name == 'roundrect')
{
var arcsize = Number(node.getAttribute('arcsize'));
if (arcsize == 0)
{
arcsize = mxConstants.RECTANGLE_ROUNDING_FACTOR * 100;
}
var w = Number(node.getAttribute('w')) * sx;
var h = Number(node.getAttribute('h')) * sy;
var factor = Number(arcsize) / 100;
var r = Math.min(w * factor, h * factor);
canvas.roundrect(x0 + Number(node.getAttribute('x')) * sx,
y0 + Number(node.getAttribute('y')) * sy,
w, h, r, r);
}
else if (name == 'ellipse')
{
canvas.ellipse(x0 + Number(node.getAttribute('x')) * sx,
y0 + Number(node.getAttribute('y')) * sy,
Number(node.getAttribute('w')) * sx,
Number(node.getAttribute('h')) * sy);
}
else if (name == 'image')
{
if (!shape.outline)
{
var src = this.evaluateAttribute(node, 'src', shape);
canvas.image(x0 + Number(node.getAttribute('x')) * sx,
y0 + Number(node.getAttribute('y')) * sy,
Number(node.getAttribute('w')) * sx,
Number(node.getAttribute('h')) * sy,
src, false, node.getAttribute('flipH') == '1',
node.getAttribute('flipV') == '1');
}
}
else if (name == 'text')
{
if (!shape.outline)
{
var str = this.evaluateTextAttribute(node, 'str', shape);
var rotation = node.getAttribute('vertical') == '1' ? -90 : 0;
if (node.getAttribute('align-shape') == '0')
{
var dr = shape.rotation;
var flipH = mxUtils.getValue(shape.style, mxConstants.STYLE_FLIPH, 0) == 1;
var flipV = mxUtils.getValue(shape.style, mxConstants.STYLE_FLIPV, 0) == 1;
if (flipH && flipV)
{
rotation -= dr;
}
else if (flipH || flipV)
{
rotation += dr;
}
else
{
rotation -= dr;
}
}
rotation -= node.getAttribute('rotation');
canvas.text(x0 + Number(node.getAttribute('x')) * sx,
y0 + Number(node.getAttribute('y')) * sy,
0, 0, str, node.getAttribute('align') || 'left',
node.getAttribute('valign') || 'top', false, '',
null, false, rotation);
}
}
else if (name == 'include-shape')
{
var stencil = mxStencilRegistry.getStencil(node.getAttribute('name'));
if (stencil != null)
{
var x = x0 + Number(node.getAttribute('x')) * sx;
var y = y0 + Number(node.getAttribute('y')) * sy;
var w = Number(node.getAttribute('w')) * sx;
var h = Number(node.getAttribute('h')) * sy;
stencil.drawShape(canvas, shape, x, y, w, h);
}
}
else if (name == 'fillstroke')
{
canvas.fillAndStroke();
}
else if (name == 'fill')
{
canvas.fill();
}
else if (name == 'stroke')
{
canvas.stroke();
}
else if (name == 'strokewidth')
{
var s = (node.getAttribute('fixed') == '1') ? 1 : minScale;
canvas.setStrokeWidth(Number(node.getAttribute('width')) * s);
}
else if (name == 'dashed')
{
canvas.setDashed(node.getAttribute('dashed') == '1');
}
else if (name == 'dashpattern')
{
var value = node.getAttribute('pattern');
if (value != null)
{
var tmp = value.split(' ');
var pat = [];
for (var i = 0; i < tmp.length; i++)
{
if (tmp[i].length > 0)
{
pat.push(Number(tmp[i]) * minScale);
}
}
value = pat.join(' ');
canvas.setDashPattern(value);
}
}
else if (name == 'strokecolor')
{
canvas.setStrokeColor(node.getAttribute('color'));
}
else if (name == 'linecap')
{
canvas.setLineCap(node.getAttribute('cap'));
}
else if (name == 'linejoin')
{
canvas.setLineJoin(node.getAttribute('join'));
}
else if (name == 'miterlimit')
{
canvas.setMiterLimit(Number(node.getAttribute('limit')));
}
else if (name == 'fillcolor')
{
canvas.setFillColor(node.getAttribute('color'));
}
else if (name == 'alpha')
{
canvas.setAlpha(node.getAttribute('alpha'));
}
else if (name == 'fillalpha')
{
canvas.setAlpha(node.getAttribute('alpha'));
}
else if (name == 'strokealpha')
{
canvas.setAlpha(node.getAttribute('alpha'));
}
else if (name == 'fontcolor')
{
canvas.setFontColor(node.getAttribute('color'));
}
else if (name == 'fontstyle')
{
canvas.setFontStyle(node.getAttribute('style'));
}
else if (name == 'fontfamily')
{
canvas.setFontFamily(node.getAttribute('family'));
}
else if (name == 'fontsize')
{
canvas.setFontSize(Number(node.getAttribute('size')) * minScale);
}
if (disableShadow && (name == 'fillstroke' || name == 'fill' || name == 'stroke'))
{
disableShadow = false;
canvas.setShadow(false);
}
}
};
__mxOutput.mxStencil = typeof mxStencil !== 'undefined' ? mxStencil : undefined;
var mxStencilRegistry =
{
stencils: {},
addStencil: function(name, stencil)
{
mxStencilRegistry.stencils[name] = stencil;
},
getStencil: function(name)
{
return mxStencilRegistry.stencils[name];
}
};
__mxOutput.mxStencilRegistry = typeof mxStencilRegistry !== 'undefined' ? mxStencilRegistry : undefined;
var mxMarker =
{
markers: [],
addMarker: function(type, funct)
{
mxMarker.markers[type] = funct;
},
createMarker: function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
{
var funct = mxMarker.markers[type];
return (funct != null) ? funct(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) : null;
}
};
(function()
{
function createArrow(widthFactor)
{
widthFactor = (widthFactor != null) ? widthFactor : 2;
return function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
{
var endOffsetX = unitX * sw * 1.118;
var endOffsetY = unitY * sw * 1.118;
unitX = unitX * (size + sw);
unitY = unitY * (size + sw);
var pt = pe.clone();
pt.x -= endOffsetX;
pt.y -= endOffsetY;
var f = (type != mxConstants.ARROW_CLASSIC && type != mxConstants.ARROW_CLASSIC_THIN) ? 1 : 3 / 4;
pe.x += -unitX * f - endOffsetX;
pe.y += -unitY * f - endOffsetY;
return function()
{
canvas.begin();
canvas.moveTo(pt.x, pt.y);
canvas.lineTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor);
if (type == mxConstants.ARROW_CLASSIC || type == mxConstants.ARROW_CLASSIC_THIN)
{
canvas.lineTo(pt.x - unitX * 3 / 4, pt.y - unitY * 3 / 4);
}
canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor);
canvas.close();
if (filled)
{
canvas.fillAndStroke();
}
else
{
canvas.stroke();
}
};
}
} mxMarker.addMarker('classic', createArrow(2));
mxMarker.addMarker('classicThin', createArrow(3));
mxMarker.addMarker('block', createArrow(2));
mxMarker.addMarker('blockThin', createArrow(3));
function createOpenArrow(widthFactor)
{
widthFactor = (widthFactor != null) ? widthFactor : 2;
return function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
{
var endOffsetX = unitX * sw * 1.118;
var endOffsetY = unitY * sw * 1.118;
unitX = unitX * (size + sw);
unitY = unitY * (size + sw);
var pt = pe.clone();
pt.x -= endOffsetX;
pt.y -= endOffsetY;
pe.x += -endOffsetX * 2;
pe.y += -endOffsetY * 2;
return function()
{
canvas.begin();
canvas.moveTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor);
canvas.lineTo(pt.x, pt.y);
canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor);
canvas.stroke();
};
}
} mxMarker.addMarker('open', createOpenArrow(2));
mxMarker.addMarker('openThin', createOpenArrow(3));
mxMarker.addMarker('oval', function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
{
var a = size / 2;
var pt = pe.clone();
pe.x -= unitX * a;
pe.y -= unitY * a;
return function()
{
canvas.ellipse(pt.x - a, pt.y - a, size, size);
if (filled)
{
canvas.fillAndStroke();
}
else
{
canvas.stroke();
}
};
});
function diamond(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
{
var swFactor = (type == mxConstants.ARROW_DIAMOND) ? 0.7071 : 0.9862;
var endOffsetX = unitX * sw * swFactor;
var endOffsetY = unitY * sw * swFactor;
unitX = unitX * (size + sw);
unitY = unitY * (size + sw);
var pt = pe.clone();
pt.x -= endOffsetX;
pt.y -= endOffsetY;
pe.x += -unitX - endOffsetX;
pe.y += -unitY - endOffsetY;
var tk = ((type == mxConstants.ARROW_DIAMOND) ? 2 : 3.4);
return function()
{
canvas.begin();
canvas.moveTo(pt.x, pt.y);
canvas.lineTo(pt.x - unitX / 2 - unitY / tk, pt.y + unitX / tk - unitY / 2);
canvas.lineTo(pt.x - unitX, pt.y - unitY);
canvas.lineTo(pt.x - unitX / 2 + unitY / tk, pt.y - unitY / 2 - unitX / tk);
canvas.close();
if (filled)
{
canvas.fillAndStroke();
}
else
{
canvas.stroke();
}
};
} mxMarker.addMarker('diamond', diamond);
mxMarker.addMarker('diamondThin', diamond);
})();
__mxOutput.mxMarker = typeof mxMarker !== 'undefined' ? mxMarker : undefined;
function mxActor(bounds, fill, stroke, strokewidth)
{
mxShape.call(this);
this.bounds = bounds;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
} mxUtils.extend(mxActor, mxShape);
mxActor.prototype.paintVertexShape = function(c, x, y, w, h)
{
c.translate(x, y);
c.begin();
this.redrawPath(c, x, y, w, h);
c.fillAndStroke();
};
mxActor.prototype.redrawPath = function(c, x, y, w, h)
{
var width = w/3;
c.moveTo(0, h);
c.curveTo(0, 3 * h / 5, 0, 2 * h / 5, w / 2, 2 * h / 5);
c.curveTo(w / 2 - width, 2 * h / 5, w / 2 - width, 0, w / 2, 0);
c.curveTo(w / 2 + width, 0, w / 2 + width, 2 * h / 5, w / 2, 2 * h / 5);
c.curveTo(w, 2 * h / 5, w, 3 * h / 5, w, h);
c.close();
};
__mxOutput.mxActor = typeof mxActor !== 'undefined' ? mxActor : undefined;
function mxCloud(bounds, fill, stroke, strokewidth)
{
mxActor.call(this);
this.bounds = bounds;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
} mxUtils.extend(mxCloud, mxActor);
mxCloud.prototype.redrawPath = function(c, x, y, w, h)
{
c.moveTo(0.25 * w, 0.25 * h);
c.curveTo(0.05 * w, 0.25 * h, 0, 0.5 * h, 0.16 * w, 0.55 * h);
c.curveTo(0, 0.66 * h, 0.18 * w, 0.9 * h, 0.31 * w, 0.8 * h);
c.curveTo(0.4 * w, h, 0.7 * w, h, 0.8 * w, 0.8 * h);
c.curveTo(w, 0.8 * h, w, 0.6 * h, 0.875 * w, 0.5 * h);
c.curveTo(w, 0.3 * h, 0.8 * w, 0.1 * h, 0.625 * w, 0.2 * h);
c.curveTo(0.5 * w, 0.05 * h, 0.3 * w, 0.05 * h, 0.25 * w, 0.25 * h);
c.close();
};
__mxOutput.mxCloud = typeof mxCloud !== 'undefined' ? mxCloud : undefined;
function mxRectangleShape(bounds, fill, stroke, strokewidth)
{
mxShape.call(this);
this.bounds = bounds;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
} mxUtils.extend(mxRectangleShape, mxShape);
mxRectangleShape.prototype.isHtmlAllowed = function()
{
var events = true;
if (this.style != null)
{
events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1';
}
return !this.isRounded && !this.glass && this.rotation == 0 && (events ||
(this.fill != null && this.fill != mxConstants.NONE));
};
mxRectangleShape.prototype.paintBackground = function(c, x, y, w, h)
{
var events = true;
if (this.style != null)
{
events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1';
}
if (events || (this.fill != null && this.fill != mxConstants.NONE) ||
(this.stroke != null && this.stroke != mxConstants.NONE))
{
if (!events && (this.fill == null || this.fill == mxConstants.NONE))
{
c.pointerEvents = false;
}
if (this.isRounded)
{
var r = 0;
if (mxUtils.getValue(this.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1')
{
r = Math.min(w / 2, Math.min(h / 2, mxUtils.getValue(this.style,
mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2));
}
else
{
var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE,
mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;
r = Math.min(w * f, h * f);
}
c.roundrect(x, y, w, h, r, r);
}
else
{
c.rect(x, y, w, h);
}
c.fillAndStroke();
}
};
mxRectangleShape.prototype.isRoundable = function(c, x, y, w, h)
{
return true;
};
mxRectangleShape.prototype.paintForeground = function(c, x, y, w, h)
{
if (this.glass && !this.outline && this.fill != null && this.fill != mxConstants.NONE)
{
this.paintGlassEffect(c, x, y, w, h, this.getArcSize(w + this.strokewidth, h + this.strokewidth));
}
};
__mxOutput.mxRectangleShape = typeof mxRectangleShape !== 'undefined' ? mxRectangleShape : undefined;
function mxEllipse(bounds, fill, stroke, strokewidth)
{
mxShape.call(this);
this.bounds = bounds;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
} mxUtils.extend(mxEllipse, mxShape);
mxEllipse.prototype.paintVertexShape = function(c, x, y, w, h)
{
c.ellipse(x, y, w, h);
c.fillAndStroke();
};
__mxOutput.mxEllipse = typeof mxEllipse !== 'undefined' ? mxEllipse : undefined;
function mxDoubleEllipse(bounds, fill, stroke, strokewidth)
{
mxShape.call(this);
this.bounds = bounds;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
} mxUtils.extend(mxDoubleEllipse, mxShape);
mxDoubleEllipse.prototype.vmlScale = 10;
mxDoubleEllipse.prototype.paintBackground = function(c, x, y, w, h)
{
c.ellipse(x, y, w, h);
c.fillAndStroke();
};
mxDoubleEllipse.prototype.paintForeground = function(c, x, y, w, h)
{
if (!this.outline)
{
var margin = mxUtils.getValue(this.style, mxConstants.STYLE_MARGIN, Math.min(3 + this.strokewidth, Math.min(w / 5, h / 5)));
x += margin;
y += margin;
w -= 2 * margin;
h -= 2 * margin;
if (w > 0 && h > 0)
{
c.ellipse(x, y, w, h);
}
c.stroke();
}
};
mxDoubleEllipse.prototype.getLabelBounds = function(rect)
{
var margin = (mxUtils.getValue(this.style, mxConstants.STYLE_MARGIN, Math.min(3 + this.strokewidth,
Math.min(rect.width / 5 / this.scale, rect.height / 5 / this.scale)))) * this.scale;
return new mxRectangle(rect.x + margin, rect.y + margin, rect.width - 2 * margin, rect.height - 2 * margin);
};
__mxOutput.mxDoubleEllipse = typeof mxDoubleEllipse !== 'undefined' ? mxDoubleEllipse : undefined;
function mxRhombus(bounds, fill, stroke, strokewidth)
{
mxShape.call(this);
this.bounds = bounds;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
} mxUtils.extend(mxRhombus, mxShape);
mxRhombus.prototype.isRoundable = function()
{
return true;
};
mxRhombus.prototype.paintVertexShape = function(c, x, y, w, h)
{
var hw = w / 2;
var hh = h / 2;
var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
c.begin();
this.addPoints(c, [new mxPoint(x + hw, y), new mxPoint(x + w, y + hh), new mxPoint(x + hw, y + h),
new mxPoint(x, y + hh)], this.isRounded, arcSize, true);
c.fillAndStroke();
};
__mxOutput.mxRhombus = typeof mxRhombus !== 'undefined' ? mxRhombus : undefined;
function mxPolyline(points, stroke, strokewidth)
{
mxShape.call(this);
this.points = points;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
} mxUtils.extend(mxPolyline, mxShape);
mxPolyline.prototype.getRotation = function()
{
return 0;
};
mxPolyline.prototype.getShapeRotation = function()
{
return 0;
};
mxPolyline.prototype.isPaintBoundsInverted = function()
{
return false;
};
mxPolyline.prototype.paintEdgeShape = function(c, pts)
{
var prev = c.pointerEventsValue;
c.pointerEventsValue = 'stroke';
if (this.style == null || this.style[mxConstants.STYLE_CURVED] != 1)
{
this.paintLine(c, pts, this.isRounded);
}
else
{
this.paintCurvedLine(c, pts);
}
c.pointerEventsValue = prev;
};
mxPolyline.prototype.paintLine = function(c, pts, rounded)
{
var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
c.begin();
this.addPoints(c, pts, rounded, arcSize, false);
c.stroke();
};
mxPolyline.prototype.paintCurvedLine = function(c, pts)
{
c.begin();
var pt = pts[0];
var n = pts.length;
c.moveTo(pt.x, pt.y);
for (var i = 1; i < n - 2; i++)
{
var p0 = pts[i];
var p1 = pts[i + 1];
var ix = (p0.x + p1.x) / 2;
var iy = (p0.y + p1.y) / 2;
c.quadTo(p0.x, p0.y, ix, iy);
}
var p0 = pts[n - 2];
var p1 = pts[n - 1];
c.quadTo(p0.x, p0.y, p1.x, p1.y);
c.stroke();
};
__mxOutput.mxPolyline = typeof mxPolyline !== 'undefined' ? mxPolyline : undefined;
function mxArrow(points, fill, stroke, strokewidth, arrowWidth, spacing, endSize)
{
mxShape.call(this);
this.points = points;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
this.arrowWidth = (arrowWidth != null) ? arrowWidth : mxConstants.ARROW_WIDTH;
this.spacing = (spacing != null) ? spacing : mxConstants.ARROW_SPACING;
this.endSize = (endSize != null) ? endSize : mxConstants.ARROW_SIZE;
} mxUtils.extend(mxArrow, mxShape);
mxArrow.prototype.augmentBoundingBox = function(bbox)
{
mxShape.prototype.augmentBoundingBox.apply(this, arguments);
var w = Math.max(this.arrowWidth, this.endSize);
bbox.grow((w / 2 + this.strokewidth) * this.scale);
};
mxArrow.prototype.paintEdgeShape = function(c, pts)
{
var spacing = mxConstants.ARROW_SPACING;
var width = mxConstants.ARROW_WIDTH;
var arrow = mxConstants.ARROW_SIZE;
var p0 = pts[0];
var pe = pts[pts.length - 1];
var dx = pe.x - p0.x;
var dy = pe.y - p0.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var length = dist - 2 * spacing - arrow;
var nx = dx / dist;
var ny = dy / dist;
var basex = length * nx;
var basey = length * ny;
var floorx = width * ny/3;
var floory = -width * nx/3;
var p0x = p0.x - floorx / 2 + spacing * nx;
var p0y = p0.y - floory / 2 + spacing * ny;
var p1x = p0x + floorx;
var p1y = p0y + floory;
var p2x = p1x + basex;
var p2y = p1y + basey;
var p3x = p2x + floorx;
var p3y = p2y + floory;
var p5x = p3x - 3 * floorx;
var p5y = p3y - 3 * floory;
c.begin();
c.moveTo(p0x, p0y);
c.lineTo(p1x, p1y);
c.lineTo(p2x, p2y);
c.lineTo(p3x, p3y);
c.lineTo(pe.x - spacing * nx, pe.y - spacing * ny);
c.lineTo(p5x, p5y);
c.lineTo(p5x + floorx, p5y + floory);
c.close();
c.fillAndStroke();
};
__mxOutput.mxArrow = typeof mxArrow !== 'undefined' ? mxArrow : undefined;
function mxArrowConnector(points, fill, stroke, strokewidth, arrowWidth, spacing, endSize)
{
mxShape.call(this);
this.points = points;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
this.arrowWidth = (arrowWidth != null) ? arrowWidth : mxConstants.ARROW_WIDTH;
this.arrowSpacing = (spacing != null) ? spacing : mxConstants.ARROW_SPACING;
this.startSize = mxConstants.ARROW_SIZE / 5;
this.endSize = mxConstants.ARROW_SIZE / 5;
} mxUtils.extend(mxArrowConnector, mxShape);
mxArrowConnector.prototype.useSvgBoundingBox = true;
mxArrowConnector.prototype.isRoundable = function()
{
return true;
};
mxArrowConnector.prototype.resetStyles = function()
{
mxShape.prototype.resetStyles.apply(this, arguments);
this.arrowSpacing = mxConstants.ARROW_SPACING;
};
mxArrowConnector.prototype.apply = function(state)
{
mxShape.prototype.apply.apply(this, arguments);
if (this.style != null)
{
this.startSize = mxUtils.getNumber(this.style, mxConstants.STYLE_STARTSIZE, mxConstants.ARROW_SIZE / 5) * 3;
this.endSize = mxUtils.getNumber(this.style, mxConstants.STYLE_ENDSIZE, mxConstants.ARROW_SIZE / 5) * 3;
}
};
mxArrowConnector.prototype.augmentBoundingBox = function(bbox)
{
mxShape.prototype.augmentBoundingBox.apply(this, arguments);
var w = this.getEdgeWidth();
if (this.isMarkerStart())
{
w = Math.max(w, this.getStartArrowWidth());
}
if (this.isMarkerEnd())
{
w = Math.max(w, this.getEndArrowWidth());
}
bbox.grow((w / 2 + this.strokewidth) * this.scale);
};
mxArrowConnector.prototype.paintEdgeShape = function(c, pts)
{
var strokeWidth = this.strokewidth;
if (this.outline)
{
strokeWidth = Math.max(1, mxUtils.getNumber(this.style, mxConstants.STYLE_STROKEWIDTH, this.strokewidth));
}
var startWidth = this.getStartArrowWidth() + strokeWidth;
var endWidth = this.getEndArrowWidth() + strokeWidth;
var edgeWidth = this.outline ? this.getEdgeWidth() + strokeWidth : this.getEdgeWidth();
var openEnded = this.isOpenEnded();
var markerStart = this.isMarkerStart();
var markerEnd = this.isMarkerEnd();
var spacing = (openEnded) ? 0 : this.arrowSpacing + strokeWidth / 2;
var startSize = this.startSize + strokeWidth;
var endSize = this.endSize + strokeWidth;
var isRounded = this.isArrowRounded();
var pe = pts[pts.length - 1];
var i0 = 1;
while (i0 < pts.length - 1 && pts[i0].x == pts[0].x && pts[i0].y == pts[0].y)
{
i0++;
}
var dx = pts[i0].x - pts[0].x;
var dy = pts[i0].y - pts[0].y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist == 0)
{
return;
}
var nx = dx / dist;
var nx2, nx1 = nx;
var ny = dy / dist;
var ny2, ny1 = ny;
var orthx = edgeWidth * ny;
var orthy = -edgeWidth * nx;
var fns = [];
if (isRounded)
{
c.setLineJoin('round');
}
else if (pts.length > 2)
{
c.setMiterLimit(1.42);
}
c.begin();
var startNx = nx;
var startNy = ny;
if (markerStart && !openEnded)
{
this.paintMarker(c, pts[0].x, pts[0].y, nx, ny, startSize, startWidth, edgeWidth, spacing, true);
}
else
{
var outStartX = pts[0].x + orthx / 2 + spacing * nx;
var outStartY = pts[0].y + orthy / 2 + spacing * ny;
var inEndX = pts[0].x - orthx / 2 + spacing * nx;
var inEndY = pts[0].y - orthy / 2 + spacing * ny;
if (openEnded)
{
c.moveTo(outStartX, outStartY);
fns.push(function()
{
c.lineTo(inEndX, inEndY);
});
}
else
{
c.moveTo(inEndX, inEndY);
c.lineTo(outStartX, outStartY);
}
}
var dx1 = 0;
var dy1 = 0;
var dist1 = 0;
for (var i = 0; i < pts.length - 2; i++)
{
var pos = mxUtils.relativeCcw(pts[i].x, pts[i].y, pts[i+1].x, pts[i+1].y, pts[i+2].x, pts[i+2].y);
dx1 = pts[i+2].x - pts[i+1].x;
dy1 = pts[i+2].y - pts[i+1].y;
dist1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
if (dist1 != 0)
{
nx1 = dx1 / dist1;
ny1 = dy1 / dist1;
var tmp1 = nx * nx1 + ny * ny1;
var tmp = Math.max(Math.sqrt((tmp1 + 1) / 2), 0.04);
nx2 = (nx + nx1);
ny2 = (ny + ny1);
var dist2 = Math.sqrt(nx2 * nx2 + ny2 * ny2);
if (dist2 != 0)
{
nx2 = nx2 / dist2;
ny2 = ny2 / dist2;
var strokeWidthFactor = Math.max(tmp, Math.min(this.strokewidth / 200 + 0.04, 0.35));
var angleFactor = (pos != 0 && isRounded) ? Math.max(0.1, strokeWidthFactor) : Math.max(tmp, 0.06);
var outX = pts[i+1].x + ny2 * edgeWidth / 2 / angleFactor;
var outY = pts[i+1].y - nx2 * edgeWidth / 2 / angleFactor;
var inX = pts[i+1].x - ny2 * edgeWidth / 2 / angleFactor;
var inY = pts[i+1].y + nx2 * edgeWidth / 2 / angleFactor;
if (pos == 0 || !isRounded)
{
c.lineTo(outX, outY);
(function(x, y)
{
fns.push(function()
{
c.lineTo(x, y);
});
})(inX, inY);
}
else if (pos == -1)
{
var c1x = inX + ny * edgeWidth;
var c1y = inY - nx * edgeWidth;
var c2x = inX + ny1 * edgeWidth;
var c2y = inY - nx1 * edgeWidth;
c.lineTo(c1x, c1y);
c.quadTo(outX, outY, c2x, c2y);
(function(x, y)
{
fns.push(function()
{
c.lineTo(x, y);
});
})(inX, inY);
}
else
{
c.lineTo(outX, outY);
(function(x, y)
{
var c1x = outX - ny * edgeWidth;
var c1y = outY + nx * edgeWidth;
var c2x = outX - ny1 * edgeWidth;
var c2y = outY + nx1 * edgeWidth;
fns.push(function()
{
c.quadTo(x, y, c1x, c1y);
});
fns.push(function()
{
c.lineTo(c2x, c2y);
});
})(inX, inY);
}
nx = nx1;
ny = ny1;
}
}
}
orthx = edgeWidth * ny1;
orthy = - edgeWidth * nx1;
if (markerEnd && !openEnded)
{
this.paintMarker(c, pe.x, pe.y, -nx, -ny, endSize, endWidth, edgeWidth, spacing, false);
}
else
{
c.lineTo(pe.x - spacing * nx1 + orthx / 2, pe.y - spacing * ny1 + orthy / 2);
var inStartX = pe.x - spacing * nx1 - orthx / 2;
var inStartY = pe.y - spacing * ny1 - orthy / 2;
if (!openEnded)
{
c.lineTo(inStartX, inStartY);
}
else
{
c.moveTo(inStartX, inStartY);
fns.splice(0, 0, function()
{
c.moveTo(inStartX, inStartY);
});
}
}
for (var i = fns.length - 1; i >= 0; i--)
{
fns[i]();
}
if (openEnded)
{
c.end();
c.stroke();
}
else
{
c.close();
c.fillAndStroke();
}
c.setShadow(false);
c.setMiterLimit(4);
if (isRounded)
{
c.setLineJoin('flat');
}
if (pts.length > 2)
{
c.setMiterLimit(4);
if (markerStart && !openEnded)
{
c.begin();
this.paintMarker(c, pts[0].x, pts[0].y, startNx, startNy, startSize, startWidth, edgeWidth, spacing, true);
c.stroke();
c.end();
}
if (markerEnd && !openEnded)
{
c.begin();
this.paintMarker(c, pe.x, pe.y, -nx, -ny, endSize, endWidth, edgeWidth, spacing, true);
c.stroke();
c.end();
}
}
};
mxArrowConnector.prototype.paintMarker = function(c, ptX, ptY, nx, ny, size, arrowWidth, edgeWidth, spacing, initialMove)
{
var widthArrowRatio = edgeWidth / arrowWidth;
var orthx = edgeWidth * ny / 2;
var orthy = -edgeWidth * nx / 2;
var spaceX = (spacing + size) * nx;
var spaceY = (spacing + size) * ny;
if (initialMove)
{
c.moveTo(ptX - orthx + spaceX, ptY - orthy + spaceY);
}
else
{
c.lineTo(ptX - orthx + spaceX, ptY - orthy + spaceY);
}
c.lineTo(ptX - orthx / widthArrowRatio + spaceX, ptY - orthy / widthArrowRatio + spaceY);
c.lineTo(ptX + spacing * nx, ptY + spacing * ny);
c.lineTo(ptX + orthx / widthArrowRatio + spaceX, ptY + orthy / widthArrowRatio + spaceY);
c.lineTo(ptX + orthx + spaceX, ptY + orthy + spaceY);
};
mxArrowConnector.prototype.isArrowRounded = function()
{
return this.isRounded;
};
mxArrowConnector.prototype.getStartArrowWidth = function()
{
return mxConstants.ARROW_WIDTH;
};
mxArrowConnector.prototype.getEndArrowWidth = function()
{
return mxConstants.ARROW_WIDTH;
};
mxArrowConnector.prototype.getEdgeWidth = function()
{
return mxConstants.ARROW_WIDTH / 3;
};
mxArrowConnector.prototype.isOpenEnded = function()
{
return false;
};
mxArrowConnector.prototype.isMarkerStart = function()
{
return (mxUtils.getValue(this.style, mxConstants.STYLE_STARTARROW, mxConstants.NONE) != mxConstants.NONE);
};
mxArrowConnector.prototype.isMarkerEnd = function()
{
return (mxUtils.getValue(this.style, mxConstants.STYLE_ENDARROW, mxConstants.NONE) != mxConstants.NONE);
};
__mxOutput.mxArrowConnector = typeof mxArrowConnector !== 'undefined' ? mxArrowConnector : undefined;
function mxText(value, bounds, align, valign, color,
family, size, fontStyle, spacing, spacingTop, spacingRight,
spacingBottom, spacingLeft, horizontal, background, border,
wrap, clipped, overflow, labelPadding, textDirection)
{
mxShape.call(this);
this.value = value;
this.bounds = bounds;
this.color = (color != null) ? color : 'black';
this.align = (align != null) ? align : mxConstants.ALIGN_CENTER;
this.valign = (valign != null) ? valign : mxConstants.ALIGN_MIDDLE;
this.family = (family != null) ? family : mxConstants.DEFAULT_FONTFAMILY;
this.size = (size != null) ? size : mxConstants.DEFAULT_FONTSIZE;
this.fontStyle = (fontStyle != null) ? fontStyle : mxConstants.DEFAULT_FONTSTYLE;
this.spacing = parseInt(spacing || 2);
this.spacingTop = this.spacing + parseInt(spacingTop || 0);
this.spacingRight = this.spacing + parseInt(spacingRight || 0);
this.spacingBottom = this.spacing + parseInt(spacingBottom || 0);
this.spacingLeft = this.spacing + parseInt(spacingLeft || 0);
this.horizontal = (horizontal != null) ? horizontal : true;
this.background = background;
this.border = border;
this.wrap = (wrap != null) ? wrap : false;
this.clipped = (clipped != null) ? clipped : false;
this.overflow = (overflow != null) ? overflow : 'visible';
this.labelPadding = (labelPadding != null) ? labelPadding : 0;
this.textDirection = textDirection;
this.rotation = 0;
this.updateMargin();
} mxUtils.extend(mxText, mxShape);
mxText.prototype.baseSpacingTop = 0;
mxText.prototype.baseSpacingBottom = 0;
mxText.prototype.baseSpacingLeft = 0;
mxText.prototype.baseSpacingRight = 0;
mxText.prototype.replaceLinefeeds = true;
mxText.prototype.verticalTextRotation = -90;
mxText.prototype.ignoreClippedStringSize = true;
mxText.prototype.ignoreStringSize = false;
mxText.prototype.textWidthPadding = (document.documentMode == 8 && !mxClient.IS_EM) ? 4 : 3;
mxText.prototype.lastValue = null;
mxText.prototype.cacheEnabled = true;
mxText.prototype.isParseVml = function()
{
return false;
};
mxText.prototype.isHtmlAllowed = function()
{
return document.documentMode != 8 || mxClient.IS_EM;
};
mxText.prototype.getSvgScreenOffset = function()
{
return 0;
};
mxText.prototype.checkBounds = function()
{
return (!isNaN(this.scale) && isFinite(this.scale) && this.scale > 0 &&
this.bounds != null && !isNaN(this.bounds.x) && !isNaN(this.bounds.y) &&
!isNaN(this.bounds.width) && !isNaN(this.bounds.height));
};
mxText.prototype.paint = function(c, update)
{
var s = this.scale;
var x = this.bounds.x / s;
var y = this.bounds.y / s;
var w = this.bounds.width / s;
var h = this.bounds.height / s;
this.updateTransform(c, x, y, w, h);
this.configureCanvas(c, x, y, w, h);
if (update)
{
c.updateText(x, y, w, h, this.align, this.valign, this.wrap, this.overflow,
this.clipped, this.getTextRotation(), this.node);
}
else
{
var realHtml = mxUtils.isNode(this.value) || this.dialect == mxConstants.DIALECT_STRICTHTML;
var fmt = (realHtml || c instanceof mxVmlCanvas2D) ? 'html' : '';
var val = this.value;
if (!realHtml && fmt == 'html')
{
val = mxUtils.htmlEntities(val, false);
}
if (fmt == 'html' && !mxUtils.isNode(this.value))
{
val = mxUtils.replaceTrailingNewlines(val, '<div><br></div>');
}
val = (!mxUtils.isNode(this.value) && this.replaceLinefeeds && fmt == 'html') ?
val.replace(/\n/g, '<br/>') : val;
var dir = this.textDirection;
if (dir == mxConstants.TEXT_DIRECTION_AUTO && !realHtml)
{
dir = this.getAutoDirection();
}
if (dir != mxConstants.TEXT_DIRECTION_LTR && dir != mxConstants.TEXT_DIRECTION_RTL)
{
dir = null;
}
c.text(x, y, w, h, val, this.align, this.valign, this.wrap, fmt,
this.overflow, this.clipped, this.getTextRotation(), dir);
}
};
mxText.prototype.redraw = function()
{
if (this.visible && this.checkBounds() && this.cacheEnabled && this.lastValue == this.value &&
(mxUtils.isNode(this.value) || this.dialect == mxConstants.DIALECT_STRICTHTML))
{
if (this.node.nodeName == 'DIV' && (this.isHtmlAllowed() || !mxClient.IS_VML))
{
if (mxClient.IS_SVG)
{
this.redrawHtmlShapeWithCss3();
}
else
{
this.updateSize(this.node, (this.state == null || this.state.view.textDiv == null));
if (mxClient.IS_IE && (document.documentMode == null || document.documentMode <= 8))
{
this.updateHtmlFilter();
}
else
{
this.updateHtmlTransform();
}
}
this.updateBoundingBox();
}
else
{
var canvas = this.createCanvas();
if (canvas != null && canvas.updateText != null)
{
canvas.pointerEvents = this.pointerEvents;
this.paint(canvas, true);
this.destroyCanvas(canvas);
this.updateBoundingBox();
}
else
{
mxShape.prototype.redraw.apply(this, arguments);
}
}
}
else
{
mxShape.prototype.redraw.apply(this, arguments);
if (mxUtils.isNode(this.value) || this.dialect == mxConstants.DIALECT_STRICTHTML)
{
this.lastValue = this.value;
}
else
{
this.lastValue = null;
}
}
};
mxText.prototype.resetStyles = function()
{
mxShape.prototype.resetStyles.apply(this, arguments);
this.color = 'black';
this.align = mxConstants.ALIGN_CENTER;
this.valign = mxConstants.ALIGN_MIDDLE;
this.family = mxConstants.DEFAULT_FONTFAMILY;
this.size = mxConstants.DEFAULT_FONTSIZE;
this.fontStyle = mxConstants.DEFAULT_FONTSTYLE;
this.spacing = 2;
this.spacingTop = 2;
this.spacingRight = 2;
this.spacingBottom = 2;
this.spacingLeft = 2;
this.horizontal = true;
delete this.background;
delete this.border;
this.textDirection = mxConstants.DEFAULT_TEXT_DIRECTION;
delete this.margin;
};
mxText.prototype.apply = function(state)
{
var old = this.spacing;
mxShape.prototype.apply.apply(this, arguments);
if (this.style != null)
{
this.fontStyle = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSTYLE, this.fontStyle);
this.family = mxUtils.getValue(this.style, mxConstants.STYLE_FONTFAMILY, this.family);
this.size = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, this.size);
this.color = mxUtils.getValue(this.style, mxConstants.STYLE_FONTCOLOR, this.color);
this.align = mxUtils.getValue(this.style, mxConstants.STYLE_ALIGN, this.align);
this.valign = mxUtils.getValue(this.style, mxConstants.STYLE_VERTICAL_ALIGN, this.valign);
this.spacing = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING, this.spacing));
this.spacingTop = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING_TOP, this.spacingTop - old)) + this.spacing;
this.spacingRight = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING_RIGHT, this.spacingRight - old)) + this.spacing;
this.spacingBottom = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING_BOTTOM, this.spacingBottom - old)) + this.spacing;
this.spacingLeft = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING_LEFT, this.spacingLeft - old)) + this.spacing;
this.horizontal = mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, this.horizontal);
this.background = mxUtils.getValue(this.style, mxConstants.STYLE_LABEL_BACKGROUNDCOLOR, this.background);
this.border = mxUtils.getValue(this.style, mxConstants.STYLE_LABEL_BORDERCOLOR, this.border);
this.textDirection = mxUtils.getValue(this.style, mxConstants.STYLE_TEXT_DIRECTION, mxConstants.DEFAULT_TEXT_DIRECTION);
this.opacity = mxUtils.getValue(this.style, mxConstants.STYLE_TEXT_OPACITY, 100);
this.updateMargin();
}
this.flipV = null;
this.flipH = null;
};
mxText.prototype.getAutoDirection = function()
{
var tmp = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(this.value);
return (tmp != null && tmp.length > 0 && tmp[0] > 'z') ?
mxConstants.TEXT_DIRECTION_RTL : mxConstants.TEXT_DIRECTION_LTR;
};
mxText.prototype.getContentNode = function()
{
var result = this.node;
if (result != null)
{
if (result.ownerSVGElement == null)
{
result = this.node.firstChild.firstChild;
}
else
{
result = result.firstChild.firstChild.firstChild.firstChild.firstChild;
}
}
return result;
};
mxText.prototype.updateBoundingBox = function()
{
var node = this.node;
this.boundingBox = this.bounds.clone();
var rot = this.getTextRotation();
var h = (this.style != null) ? mxUtils.getValue(this.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER) : null;
var v = (this.style != null) ? mxUtils.getValue(this.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE) : null;
if (!this.ignoreStringSize && node != null && this.overflow != 'fill' && (!this.clipped ||
!this.ignoreClippedStringSize || h != mxConstants.ALIGN_CENTER || v != mxConstants.ALIGN_MIDDLE))
{
var ow = null;
var oh = null;
if (node.ownerSVGElement != null)
{
if (node.firstChild != null && node.firstChild.firstChild != null &&
node.firstChild.firstChild.nodeName == 'foreignObject')
{
node = node.firstChild.firstChild.firstChild.firstChild;
oh = node.offsetHeight * this.scale;
if (this.overflow == 'width')
{
ow = this.boundingBox.width;
}
else
{
ow = node.offsetWidth * this.scale;
}
}
else
{
try
{
var b = node.getBBox();
if (typeof(this.value) == 'string' && mxUtils.trim(this.value) == 0)
{
this.boundingBox = null;
}
else if (b.width == 0 && b.height == 0)
{
this.boundingBox = null;
}
else
{
this.boundingBox = new mxRectangle(b.x, b.y, b.width, b.height);
}
return;
}
catch (e)
{
}
}
}
else
{
var td = (this.state != null) ? this.state.view.textDiv : null;
if (this.offsetWidth != null && this.offsetHeight != null)
{
ow = this.offsetWidth * this.scale;
oh = this.offsetHeight * this.scale;
}
else
{
if (td != null)
{
this.updateFont(td);
this.updateSize(td, false);
this.updateInnerHtml(td);
node = td;
}
var sizeDiv = node;
if (document.documentMode == 8 && !mxClient.IS_EM)
{
var w = Math.round(this.bounds.width / this.scale);
if (this.wrap && w > 0)
{
node.style.wordWrap = mxConstants.WORD_WRAP;
node.style.whiteSpace = 'normal';
if (node.style.wordWrap != 'break-word')
{
var divs = sizeDiv.getElementsByTagName('div');
if (divs.length > 0)
{
sizeDiv = divs[divs.length - 1];
}
ow = sizeDiv.offsetWidth + 2;
divs = this.node.getElementsByTagName('div');
if (this.clipped)
{
ow = Math.min(w, ow);
}
if (divs.length > 1)
{
divs[divs.length - 2].style.width = ow + 'px';
}
}
}
else
{
node.style.whiteSpace = 'nowrap';
}
}
else if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
{
sizeDiv = sizeDiv.firstChild;
}
this.offsetWidth = sizeDiv.offsetWidth + this.textWidthPadding;
this.offsetHeight = sizeDiv.offsetHeight;
ow = this.offsetWidth * this.scale;
oh = this.offsetHeight * this.scale;
}
}
if (ow != null && oh != null)
{
this.boundingBox = new mxRectangle(this.bounds.x,
this.bounds.y, ow, oh);
}
}
if (this.boundingBox != null)
{
if (rot != 0)
{
var bbox = mxUtils.getBoundingBox(new mxRectangle(
this.margin.x * this.boundingBox.width,
this.margin.y * this.boundingBox.height,
this.boundingBox.width, this.boundingBox.height),
rot, new mxPoint(0, 0));
this.unrotatedBoundingBox = mxRectangle.fromRectangle(this.boundingBox);
this.unrotatedBoundingBox.x += this.margin.x * this.unrotatedBoundingBox.width;
this.unrotatedBoundingBox.y += this.margin.y * this.unrotatedBoundingBox.height;
this.boundingBox.x += bbox.x;
this.boundingBox.y += bbox.y;
this.boundingBox.width = bbox.width;
this.boundingBox.height = bbox.height;
}
else
{
this.boundingBox.x += this.margin.x * this.boundingBox.width;
this.boundingBox.y += this.margin.y * this.boundingBox.height;
this.unrotatedBoundingBox = null;
}
}
};
mxText.prototype.getShapeRotation = function()
{
return 0;
};
mxText.prototype.getTextRotation = function()
{
return (this.state != null && this.state.shape != null) ? this.state.shape.getTextRotation() : 0;
};
mxText.prototype.isPaintBoundsInverted = function()
{
return !this.horizontal && this.state != null && this.state.view.graph.model.isVertex(this.state.cell);
};
mxText.prototype.configureCanvas = function(c, x, y, w, h)
{
mxShape.prototype.configureCanvas.apply(this, arguments);
c.setFontColor(this.color);
c.setFontBackgroundColor(this.background);
c.setFontBorderColor(this.border);
c.setFontFamily(this.family);
c.setFontSize(this.size);
c.setFontStyle(this.fontStyle);
};
mxText.prototype.updateVmlContainer = function()
{
this.node.style.left = Math.round(this.bounds.x) + 'px';
this.node.style.top = Math.round(this.bounds.y) + 'px';
this.node.style.width = '1px';
this.node.style.height = '1px';
this.node.style.overflow = 'visible';
};
mxText.prototype.getHtmlValue = function()
{
var val = this.value;
if (this.dialect != mxConstants.DIALECT_STRICTHTML)
{
val = mxUtils.htmlEntities(val, false);
}
val = mxUtils.replaceTrailingNewlines(val, '<div><br></div>');
val = (this.replaceLinefeeds) ? val.replace(/\n/g, '<br/>') : val;
return val;
};
mxText.prototype.getTextCss = function()
{
var lh = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (this.size * mxConstants.LINE_HEIGHT) + 'px' :
mxConstants.LINE_HEIGHT;
var css = 'display: inline-block; font-size: ' + this.size + 'px; ' +
'font-family: ' + this.family + '; color: ' + this.color + '; line-height: ' + lh +
'; pointer-events: ' + ((this.pointerEvents) ? 'all' : 'none') + '; ';
if ((this.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
{
css += 'font-weight: bold; ';
}
if ((this.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
{
css += 'font-style: italic; ';
}
var deco = [];
if ((this.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
{
deco.push('underline');
}
if ((this.fontStyle & mxConstants.FONT_STRIKETHROUGH) == mxConstants.FONT_STRIKETHROUGH)
{
deco.push('line-through');
}
if (deco.length > 0)
{
css += 'text-decoration: ' + deco.join(' ') + '; ';
}
return css;
};
mxText.prototype.redrawHtmlShape = function()
{
if (mxClient.IS_SVG)
{
this.redrawHtmlShapeWithCss3();
}
else
{
var style = this.node.style;
style.whiteSpace = 'normal';
style.overflow = '';
style.width = '';
style.height = '';
this.updateValue();
this.updateFont(this.node);
this.updateSize(this.node, (this.state == null || this.state.view.textDiv == null));
this.offsetWidth = null;
this.offsetHeight = null;
if (mxClient.IS_IE && (document.documentMode == null || document.documentMode <= 8))
{
this.updateHtmlFilter();
}
else
{
this.updateHtmlTransform();
}
}
};
mxText.prototype.redrawHtmlShapeWithCss3 = function()
{
var w = Math.max(0, Math.round(this.bounds.width / this.scale));
var h = Math.max(0, Math.round(this.bounds.height / this.scale));
var flex = 'position: absolute; left: ' + Math.round(this.bounds.x) + 'px; ' +
'top: ' + Math.round(this.bounds.y) + 'px; pointer-events: none; ';
var block = this.getTextCss();
mxSvgCanvas2D.createCss(w + 2, h, this.align, this.valign, this.wrap, this.overflow, this.clipped,
(this.background != null) ? mxUtils.htmlEntities(this.background) : null,
(this.border != null) ? mxUtils.htmlEntities(this.border) : null,
flex, block, this.scale, mxUtils.bind(this, function(dx, dy, flex, item, block, ofl)
{
var r = this.getTextRotation();
var tr = ((this.scale != 1) ? 'scale(' + this.scale + ') ' : '') +
((r != 0) ? 'rotate(' + r + 'deg) ' : '') +
((this.margin.x != 0 || this.margin.y != 0) ?
'translate(' + (this.margin.x * 100) + '%,' +
(this.margin.y * 100) + '%)' : '');
if (tr != '')
{
tr = 'transform-origin: 0 0; transform: ' + tr + '; ';
}
if (ofl == '')
{
flex += item;
item = 'display:inline-block; min-width: 100%; ' + tr;
}
else
{
item += tr;
if (mxClient.IS_SF)
{
item += '-webkit-clip-path: content-box;';
}
}
if (this.opacity < 100)
{
block += 'opacity: ' + (this.opacity / 100) + '; ';
}
this.node.setAttribute('style', flex);
var html = (mxUtils.isNode(this.value)) ? this.value.outerHTML : this.getHtmlValue();
if (this.node.firstChild == null)
{
this.node.innerHTML = '<div><div>' + html +'</div></div>';
}
this.node.firstChild.firstChild.setAttribute('style', block);
this.node.firstChild.setAttribute('style', item);
}));
};
mxText.prototype.updateHtmlTransform = function()
{
var theta = this.getTextRotation();
var style = this.node.style;
var dx = this.margin.x;
var dy = this.margin.y;
if (theta != 0)
{
mxUtils.setPrefixedStyle(style, 'transformOrigin', (-dx * 100) + '%' + ' ' + (-dy * 100) + '%');
mxUtils.setPrefixedStyle(style, 'transform', 'translate(' + (dx * 100) + '%' + ',' + (dy * 100) + '%) ' +
'scale(' + this.scale + ') rotate(' + theta + 'deg)');
}
else
{
mxUtils.setPrefixedStyle(style, 'transformOrigin', '0% 0%');
mxUtils.setPrefixedStyle(style, 'transform', 'scale(' + this.scale + ') ' +
'translate(' + (dx * 100) + '%' + ',' + (dy * 100) + '%)');
}
style.left = Math.round(this.bounds.x - Math.ceil(dx * ((this.overflow != 'fill' &&
this.overflow != 'width') ? 3 : 1))) + 'px';
style.top = Math.round(this.bounds.y - dy * ((this.overflow != 'fill') ? 3 : 1)) + 'px';
if (this.opacity < 100)
{
style.opacity = this.opacity / 100;
}
else
{
style.opacity = '';
}
};
mxText.prototype.updateInnerHtml = function(elt)
{
if (mxUtils.isNode(this.value))
{
elt.innerHTML = this.value.outerHTML;
}
else
{
var val = this.value;
if (this.dialect != mxConstants.DIALECT_STRICTHTML)
{
val = mxUtils.htmlEntities(val, false);
}
val = mxUtils.replaceTrailingNewlines(val, '<div> </div>');
val = (this.replaceLinefeeds) ? val.replace(/\n/g, '<br/>') : val;
val = '<div style="display:inline-block;_display:inline;">' + val + '</div>';
elt.innerHTML = val;
}
};
mxText.prototype.updateHtmlFilter = function()
{
var style = this.node.style;
var dx = this.margin.x;
var dy = this.margin.y;
var s = this.scale;
mxUtils.setOpacity(this.node, this.opacity);
var ow = 0;
var oh = 0;
var td = (this.state != null) ? this.state.view.textDiv : null;
var sizeDiv = this.node;
if (td != null)
{
td.style.overflow = '';
td.style.height = '';
td.style.width = '';
this.updateFont(td);
this.updateSize(td, false);
this.updateInnerHtml(td);
var w = Math.round(this.bounds.width / this.scale);
if (this.wrap && w > 0)
{
td.style.whiteSpace = 'normal';
td.style.wordWrap = mxConstants.WORD_WRAP;
ow = w;
if (this.clipped)
{
ow = Math.min(ow, this.bounds.width);
}
td.style.width = ow + 'px';
}
else
{
td.style.whiteSpace = 'nowrap';
}
sizeDiv = td;
if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
{
sizeDiv = sizeDiv.firstChild;
if (this.wrap && td.style.wordWrap == 'break-word')
{
sizeDiv.style.width = '100%';
}
}
if (!this.clipped && this.wrap && w > 0)
{
ow = sizeDiv.offsetWidth + this.textWidthPadding;
td.style.width = ow + 'px';
}
oh = sizeDiv.offsetHeight + 2;
if (mxClient.IS_QUIRKS && this.border != null && this.border != mxConstants.NONE)
{
oh += 3;
}
}
else if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
{
sizeDiv = sizeDiv.firstChild;
oh = sizeDiv.offsetHeight;
}
ow = sizeDiv.offsetWidth + this.textWidthPadding;
if (this.clipped)
{
oh = Math.min(oh, this.bounds.height);
}
var w = this.bounds.width / s;
var h = this.bounds.height / s;
if (this.overflow == 'fill')
{
oh = h;
ow = w;
}
else if (this.overflow == 'width')
{
oh = sizeDiv.scrollHeight;
ow = w;
}
this.offsetWidth = ow;
this.offsetHeight = oh;
if (mxClient.IS_QUIRKS && (this.clipped || (this.overflow == 'width' && h > 0)))
{
h = Math.min(h, oh);
style.height = Math.round(h) + 'px';
}
else
{
h = oh;
}
if (this.overflow != 'fill' && this.overflow != 'width')
{
if (this.clipped)
{
ow = Math.min(w, ow);
}
w = ow;
if ((mxClient.IS_QUIRKS && this.clipped) || this.wrap)
{
style.width = Math.round(w) + 'px';
}
}
h *= s;
w *= s;
var rad = this.getTextRotation() * (Math.PI / 180);
var real_cos = parseFloat(parseFloat(Math.cos(rad)).toFixed(8));
var real_sin = parseFloat(parseFloat(Math.sin(-rad)).toFixed(8));
rad %= 2 * Math.PI;
if (rad < 0)
{
rad += 2 * Math.PI;
}
rad %= Math.PI;
if (rad > Math.PI / 2)
{
rad = Math.PI - rad;
}
var cos = Math.cos(rad);
var sin = Math.sin(-rad);
var tx = w * -(dx + 0.5);
var ty = h * -(dy + 0.5);
var top_fix = (h - h * cos + w * sin) / 2 + real_sin * tx - real_cos * ty;
var left_fix = (w - w * cos + h * sin) / 2 - real_cos * tx - real_sin * ty;
if (rad != 0)
{
var f = 'progid:DXImageTransform.Microsoft.Matrix(M11=' + real_cos + ', M12='+
real_sin + ', M21=' + (-real_sin) + ', M22=' + real_cos + ', sizingMethod=\'auto expand\')';
if (style.filter != null && style.filter.length > 0)
{
style.filter += ' ' + f;
}
else
{
style.filter = f;
}
}
var dy = 0;
if (this.overflow != 'fill' && mxClient.IS_QUIRKS)
{
if (this.valign == mxConstants.ALIGN_TOP)
{
dy -= 1;
}
else if (this.valign == mxConstants.ALIGN_BOTTOM)
{
dy += 2;
}
else
{
dy += 1;
}
}
style.zoom = s;
style.left = Math.round(this.bounds.x + left_fix - w / 2) + 'px';
style.top = Math.round(this.bounds.y + top_fix - h / 2 + dy) + 'px';
};
mxText.prototype.updateValue = function()
{
if (mxUtils.isNode(this.value))
{
this.node.innerHTML = '';
this.node.appendChild(this.value);
}
else
{
var val = this.value;
if (this.dialect != mxConstants.DIALECT_STRICTHTML)
{
val = mxUtils.htmlEntities(val, false);
}
val = mxUtils.replaceTrailingNewlines(val, '<div><br></div>');
val = (this.replaceLinefeeds) ? val.replace(/\n/g, '<br/>') : val;
var bg = (this.background != null && this.background != mxConstants.NONE) ? this.background : null;
var bd = (this.border != null && this.border != mxConstants.NONE) ? this.border : null;
if (this.overflow == 'fill' || this.overflow == 'width')
{
if (bg != null)
{
this.node.style.backgroundColor = bg;
}
if (bd != null)
{
this.node.style.border = '1px solid ' + bd;
}
}
else
{
var css = '';
if (bg != null)
{
css += 'background-color:' + mxUtils.htmlEntities(bg) + ';';
}
if (bd != null)
{
css += 'border:1px solid ' + mxUtils.htmlEntities(bd) + ';';
}
var lh = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (this.size * mxConstants.LINE_HEIGHT) + 'px' :
mxConstants.LINE_HEIGHT;
val = '<div style="zoom:1;' + css + 'display:inline-block;_display:inline;text-decoration:inherit;' +
'padding-bottom:1px;padding-right:1px;line-height:' + lh + '">' + val + '</div>';
}
this.node.innerHTML = val;
var divs = this.node.getElementsByTagName('div');
if (divs.length > 0)
{
var dir = this.textDirection;
if (dir == mxConstants.TEXT_DIRECTION_AUTO && this.dialect != mxConstants.DIALECT_STRICTHTML)
{
dir = this.getAutoDirection();
}
if (dir == mxConstants.TEXT_DIRECTION_LTR || dir == mxConstants.TEXT_DIRECTION_RTL)
{
divs[divs.length - 1].setAttribute('dir', dir);
}
else
{
divs[divs.length - 1].removeAttribute('dir');
}
}
}
};
mxText.prototype.updateFont = function(node)
{
var style = node.style;
style.lineHeight = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (this.size * mxConstants.LINE_HEIGHT) + 'px' : mxConstants.LINE_HEIGHT;
style.fontSize = this.size + 'px';
style.fontFamily = this.family;
style.verticalAlign = 'top';
style.color = this.color;
if ((this.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
{
style.fontWeight = 'bold';
}
else
{
style.fontWeight = '';
}
if ((this.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
{
style.fontStyle = 'italic';
}
else
{
style.fontStyle = '';
}
var txtDecor = [];
if ((this.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
{
txtDecor.push('underline');
}
if ((this.fontStyle & mxConstants.FONT_STRIKETHROUGH) == mxConstants.FONT_STRIKETHROUGH)
{
txtDecor.push('line-through');
}
style.textDecoration = txtDecor.join(' ');
if (this.align == mxConstants.ALIGN_CENTER)
{
style.textAlign = 'center';
}
else if (this.align == mxConstants.ALIGN_RIGHT)
{
style.textAlign = 'right';
}
else
{
style.textAlign = 'left';
}
};
mxText.prototype.updateSize = function(node, enableWrap)
{
var w = Math.max(0, Math.round(this.bounds.width / this.scale));
var h = Math.max(0, Math.round(this.bounds.height / this.scale));
var style = node.style;
if (this.clipped)
{
style.overflow = 'hidden';
if (!mxClient.IS_QUIRKS)
{
style.maxHeight = h + 'px';
style.maxWidth = w + 'px';
}
else
{
style.width = w + 'px';
}
}
else if (this.overflow == 'fill')
{
style.width = (w + 1) + 'px';
style.height = (h + 1) + 'px';
style.overflow = 'hidden';
}
else if (this.overflow == 'width')
{
style.width = (w + 1) + 'px';
style.maxHeight = (h + 1) + 'px';
style.overflow = 'hidden';
}
if (this.wrap && w > 0)
{
style.wordWrap = mxConstants.WORD_WRAP;
style.whiteSpace = 'normal';
style.width = w + 'px';
if (enableWrap && this.overflow != 'fill' && this.overflow != 'width')
{
var sizeDiv = node;
if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
{
sizeDiv = sizeDiv.firstChild;
if (node.style.wordWrap == 'break-word')
{
sizeDiv.style.width = '100%';
}
}
var tmp = sizeDiv.offsetWidth;
if (tmp == 0)
{
var prev = node.parentNode;
node.style.visibility = 'hidden';
document.body.appendChild(node);
tmp = sizeDiv.offsetWidth;
node.style.visibility = '';
prev.appendChild(node);
}
tmp += 3;
if (this.clipped)
{
tmp = Math.min(tmp, w);
}
style.width = tmp + 'px';
}
}
else
{
style.whiteSpace = 'nowrap';
}
};
mxText.prototype.updateMargin = function()
{
this.margin = mxUtils.getAlignmentAsPoint(this.align, this.valign);
};
mxText.prototype.getSpacing = function()
{
var dx = 0;
var dy = 0;
if (this.align == mxConstants.ALIGN_CENTER)
{
dx = (this.spacingLeft - this.spacingRight) / 2;
}
else if (this.align == mxConstants.ALIGN_RIGHT)
{
dx = -this.spacingRight - this.baseSpacingRight;
}
else
{
dx = this.spacingLeft + this.baseSpacingLeft;
}
if (this.valign == mxConstants.ALIGN_MIDDLE)
{
dy = (this.spacingTop - this.spacingBottom) / 2;
}
else if (this.valign == mxConstants.ALIGN_BOTTOM)
{
dy = -this.spacingBottom - this.baseSpacingBottom; }
else
{
dy = this.spacingTop + this.baseSpacingTop;
}
return new mxPoint(dx, dy);
};
__mxOutput.mxText = typeof mxText !== 'undefined' ? mxText : undefined;
function mxTriangle()
{
mxActor.call(this);
} mxUtils.extend(mxTriangle, mxActor);
mxTriangle.prototype.isRoundable = function()
{
return true;
};
mxTriangle.prototype.redrawPath = function(c, x, y, w, h)
{
var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0.5 * h), new mxPoint(0, h)], this.isRounded, arcSize, true);
};
__mxOutput.mxTriangle = typeof mxTriangle !== 'undefined' ? mxTriangle : undefined;
function mxHexagon()
{
mxActor.call(this);
} mxUtils.extend(mxHexagon, mxActor);
mxHexagon.prototype.redrawPath = function(c, x, y, w, h)
{
var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
this.addPoints(c, [new mxPoint(0.25 * w, 0), new mxPoint(0.75 * w, 0), new mxPoint(w, 0.5 * h), new mxPoint(0.75 * w, h),
new mxPoint(0.25 * w, h), new mxPoint(0, 0.5 * h)], this.isRounded, arcSize, true);
};
__mxOutput.mxHexagon = typeof mxHexagon !== 'undefined' ? mxHexagon : undefined;
function mxLine(bounds, stroke, strokewidth, vertical)
{
mxShape.call(this);
this.bounds = bounds;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
this.vertical = (vertical != null) ? vertical : this.vertical;
} mxUtils.extend(mxLine, mxShape);
mxLine.prototype.vertical = false;
mxLine.prototype.paintVertexShape = function(c, x, y, w, h)
{
c.begin();
if (this.vertical)
{
var mid = x + w / 2;
c.moveTo(mid, y);
c.lineTo(mid, y + h);
}
else
{
var mid = y + h / 2;
c.moveTo(x, mid);
c.lineTo(x + w, mid);
}
c.stroke();
};
__mxOutput.mxLine = typeof mxLine !== 'undefined' ? mxLine : undefined;
function mxImageShape(bounds, image, fill, stroke, strokewidth)
{
mxShape.call(this);
this.bounds = bounds;
this.image = image;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
this.shadow = false;
} mxUtils.extend(mxImageShape, mxRectangleShape);
mxImageShape.prototype.preserveImageAspect = true;
mxImageShape.prototype.getSvgScreenOffset = function()
{
return 0;
};
mxImageShape.prototype.apply = function(state)
{
mxShape.prototype.apply.apply(this, arguments);
this.fill = null;
this.stroke = null;
this.gradient = null;
if (this.style != null)
{
this.preserveImageAspect = mxUtils.getNumber(this.style, mxConstants.STYLE_IMAGE_ASPECT, 1) == 1;
this.flipH = this.flipH || mxUtils.getValue(this.style, 'imageFlipH', 0) == 1;
this.flipV = this.flipV || mxUtils.getValue(this.style, 'imageFlipV', 0) == 1;
}
};
mxImageShape.prototype.isHtmlAllowed = function()
{
return !this.preserveImageAspect;
};
mxImageShape.prototype.createHtml = function()
{
var node = document.createElement('div');
node.style.position = 'absolute';
return node;
};
mxImageShape.prototype.isRoundable = function(c, x, y, w, h)
{
return false;
};
mxImageShape.prototype.paintVertexShape = function(c, x, y, w, h)
{
if (this.image != null)
{
var fill = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND, null);
var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, null);
if (fill != null)
{
c.setFillColor(fill);
c.setStrokeColor(stroke);
c.rect(x, y, w, h);
c.fillAndStroke();
}
c.image(x, y, w, h, this.image, this.preserveImageAspect, false, false);
var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, null);
if (stroke != null)
{
c.setShadow(false);
c.setStrokeColor(stroke);
c.rect(x, y, w, h);
c.stroke();
}
}
else
{
mxRectangleShape.prototype.paintBackground.apply(this, arguments);
}
};
mxImageShape.prototype.redrawHtmlShape = function()
{
this.node.style.left = Math.round(this.bounds.x) + 'px';
this.node.style.top = Math.round(this.bounds.y) + 'px';
this.node.style.width = Math.max(0, Math.round(this.bounds.width)) + 'px';
this.node.style.height = Math.max(0, Math.round(this.bounds.height)) + 'px';
this.node.innerHTML = '';
if (this.image != null)
{
var fill = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND, '');
var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, '');
this.node.style.backgroundColor = fill;
this.node.style.borderColor = stroke;
var useVml = mxClient.IS_IE6 || ((document.documentMode == null || document.documentMode <= 8) && this.rotation != 0);
var img = document.createElement((useVml) ? mxClient.VML_PREFIX + ':image' : 'img');
img.setAttribute('border', '0');
img.style.position = 'absolute';
img.src = this.image;
var filter = (this.opacity < 100) ? 'alpha(opacity=' + this.opacity + ')' : '';
this.node.style.filter = filter;
if (this.flipH && this.flipV)
{
filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
}
else if (this.flipH)
{
filter += 'progid:DXImageTransform.Microsoft.BasicImage(mirror=1)';
}
else if (this.flipV)
{
filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)';
}
if (img.style.filter != filter)
{
img.style.filter = filter;
}
if (img.nodeName == 'image')
{
img.style.rotation = this.rotation;
}
else if (this.rotation != 0)
{
mxUtils.setPrefixedStyle(img.style, 'transform', 'rotate(' + this.rotation + 'deg)');
}
else
{
mxUtils.setPrefixedStyle(img.style, 'transform', '');
}
img.style.width = this.node.style.width;
img.style.height = this.node.style.height;
this.node.style.backgroundImage = '';
this.node.appendChild(img);
}
else
{
this.setTransparentBackgroundImage(this.node);
}
};
__mxOutput.mxImageShape = typeof mxImageShape !== 'undefined' ? mxImageShape : undefined;
function mxLabel(bounds, fill, stroke, strokewidth)
{
mxRectangleShape.call(this, bounds, fill, stroke, strokewidth);
} mxUtils.extend(mxLabel, mxRectangleShape);
mxLabel.prototype.imageSize = mxConstants.DEFAULT_IMAGESIZE;
mxLabel.prototype.spacing = 2;
mxLabel.prototype.indicatorSize = 10;
mxLabel.prototype.indicatorSpacing = 2;
mxLabel.prototype.init = function(container)
{
mxShape.prototype.init.apply(this, arguments);
if (this.indicatorShape != null)
{
this.indicator = new this.indicatorShape();
this.indicator.dialect = this.dialect;
this.indicator.init(this.node);
}
};
mxLabel.prototype.redraw = function()
{
if (this.indicator != null)
{
this.indicator.fill = this.indicatorColor;
this.indicator.stroke = this.indicatorStrokeColor;
this.indicator.gradient = this.indicatorGradientColor;
this.indicator.direction = this.indicatorDirection;
this.indicator.redraw();
}
mxShape.prototype.redraw.apply(this, arguments);
};
mxLabel.prototype.isHtmlAllowed = function()
{
return mxRectangleShape.prototype.isHtmlAllowed.apply(this, arguments) &&
this.indicatorColor == null && this.indicatorShape == null;
};
mxLabel.prototype.paintForeground = function(c, x, y, w, h)
{
this.paintImage(c, x, y, w, h);
this.paintIndicator(c, x, y, w, h);
mxRectangleShape.prototype.paintForeground.apply(this, arguments);
};
mxLabel.prototype.paintImage = function(c, x, y, w, h)
{
if (this.image != null)
{
var bounds = this.getImageBounds(x, y, w, h);
c.image(bounds.x, bounds.y, bounds.width, bounds.height, this.image, false, false, false);
}
};
mxLabel.prototype.getImageBounds = function(x, y, w, h)
{
var align = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_ALIGN, mxConstants.ALIGN_LEFT);
var valign = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE);
var width = mxUtils.getNumber(this.style, mxConstants.STYLE_IMAGE_WIDTH, mxConstants.DEFAULT_IMAGESIZE);
var height = mxUtils.getNumber(this.style, mxConstants.STYLE_IMAGE_HEIGHT, mxConstants.DEFAULT_IMAGESIZE);
var spacing = mxUtils.getNumber(this.style, mxConstants.STYLE_SPACING, this.spacing) + 5;
if (align == mxConstants.ALIGN_CENTER)
{
x += (w - width) / 2;
}
else if (align == mxConstants.ALIGN_RIGHT)
{
x += w - width - spacing;
}
else
{
x += spacing;
}
if (valign == mxConstants.ALIGN_TOP)
{
y += spacing;
}
else if (valign == mxConstants.ALIGN_BOTTOM)
{
y += h - height - spacing;
}
else
{
y += (h - height) / 2;
}
return new mxRectangle(x, y, width, height);
};
mxLabel.prototype.paintIndicator = function(c, x, y, w, h)
{
if (this.indicator != null)
{
this.indicator.bounds = this.getIndicatorBounds(x, y, w, h);
this.indicator.paint(c);
}
else if (this.indicatorImage != null)
{
var bounds = this.getIndicatorBounds(x, y, w, h);
c.image(bounds.x, bounds.y, bounds.width, bounds.height, this.indicatorImage, false, false, false);
}
};
mxLabel.prototype.getIndicatorBounds = function(x, y, w, h)
{
var align = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_ALIGN, mxConstants.ALIGN_LEFT);
var valign = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE);
var width = mxUtils.getNumber(this.style, mxConstants.STYLE_INDICATOR_WIDTH, this.indicatorSize);
var height = mxUtils.getNumber(this.style, mxConstants.STYLE_INDICATOR_HEIGHT, this.indicatorSize);
var spacing = this.spacing + 5;
if (align == mxConstants.ALIGN_RIGHT)
{
x += w - width - spacing;
}
else if (align == mxConstants.ALIGN_CENTER)
{
x += (w - width) / 2;
}
else
{
x += spacing;
}
if (valign == mxConstants.ALIGN_BOTTOM)
{
y += h - height - spacing;
}
else if (valign == mxConstants.ALIGN_TOP)
{
y += spacing;
}
else
{
y += (h - height) / 2;
}
return new mxRectangle(x, y, width, height);
};
mxLabel.prototype.redrawHtmlShape = function()
{
mxRectangleShape.prototype.redrawHtmlShape.apply(this, arguments);
while(this.node.hasChildNodes())
{
this.node.removeChild(this.node.lastChild);
}
if (this.image != null)
{
var node = document.createElement('img');
node.style.position = 'relative';
node.setAttribute('border', '0');
var bounds = this.getImageBounds(this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
bounds.x -= this.bounds.x;
bounds.y -= this.bounds.y;
node.style.left = Math.round(bounds.x) + 'px';
node.style.top = Math.round(bounds.y) + 'px';
node.style.width = Math.round(bounds.width) + 'px';
node.style.height = Math.round(bounds.height) + 'px';
node.src = this.image;
this.node.appendChild(node);
}
};
__mxOutput.mxLabel = typeof mxLabel !== 'undefined' ? mxLabel : undefined;
function mxCylinder(bounds, fill, stroke, strokewidth)
{
mxShape.call(this);
this.bounds = bounds;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
} mxUtils.extend(mxCylinder, mxShape);
mxCylinder.prototype.maxHeight = 40;
mxCylinder.prototype.svgStrokeTolerance = 0;
mxCylinder.prototype.paintVertexShape = function(c, x, y, w, h)
{
c.translate(x, y);
c.begin();
this.redrawPath(c, x, y, w, h, false);
c.fillAndStroke();
if (!this.outline || this.style == null || mxUtils.getValue(
this.style, mxConstants.STYLE_BACKGROUND_OUTLINE, 0) == 0)
{
c.setShadow(false);
c.begin();
this.redrawPath(c, x, y, w, h, true);
c.stroke();
}
};
mxCylinder.prototype.getCylinderSize = function(x, y, w, h)
{
return Math.min(this.maxHeight, Math.round(h / 5));
};
mxCylinder.prototype.redrawPath = function(c, x, y, w, h, isForeground)
{
var dy = this.getCylinderSize(x, y, w, h);
if ((isForeground && this.fill != null) || (!isForeground && this.fill == null))
{
c.moveTo(0, dy);
c.curveTo(0, 2 * dy, w, 2 * dy, w, dy);
if (!isForeground)
{
c.stroke();
c.begin();
}
}
if (!isForeground)
{
c.moveTo(0, dy);
c.curveTo(0, -dy / 3, w, -dy / 3, w, dy);
c.lineTo(w, h - dy);
c.curveTo(w, h + dy / 3, 0, h + dy / 3, 0, h - dy);
c.close();
}
};
__mxOutput.mxCylinder = typeof mxCylinder !== 'undefined' ? mxCylinder : undefined;
function mxConnector(points, stroke, strokewidth)
{
mxPolyline.call(this, points, stroke, strokewidth);
} mxUtils.extend(mxConnector, mxPolyline);
mxConnector.prototype.updateBoundingBox = function()
{
this.useSvgBoundingBox = this.style != null && this.style[mxConstants.STYLE_CURVED] == 1;
mxShape.prototype.updateBoundingBox.apply(this, arguments);
};
mxConnector.prototype.paintEdgeShape = function(c, pts)
{
var sourceMarker = this.createMarker(c, pts, true);
var targetMarker = this.createMarker(c, pts, false);
mxPolyline.prototype.paintEdgeShape.apply(this, arguments);
c.setFillColor(this.stroke);
c.setShadow(false);
c.setDashed(false);
if (sourceMarker != null)
{
sourceMarker();
}
if (targetMarker != null)
{
targetMarker();
}
};
mxConnector.prototype.createMarker = function(c, pts, source)
{
var result = null;
var n = pts.length;
var type = mxUtils.getValue(this.style, (source) ? mxConstants.STYLE_STARTARROW : mxConstants.STYLE_ENDARROW);
var p0 = (source) ? pts[1] : pts[n - 2];
var pe = (source) ? pts[0] : pts[n - 1];
if (type != null && p0 != null && pe != null)
{
var count = 1;
while (count < n - 1 && Math.round(p0.x - pe.x) == 0 && Math.round(p0.y - pe.y) == 0)
{
p0 = (source) ? pts[1 + count] : pts[n - 2 - count];
count++;
}
var dx = pe.x - p0.x;
var dy = pe.y - p0.y;
var dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
var unitX = dx / dist;
var unitY = dy / dist;
var size = mxUtils.getNumber(this.style, (source) ? mxConstants.STYLE_STARTSIZE : mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE);
var filled = this.style[(source) ? mxConstants.STYLE_STARTFILL : mxConstants.STYLE_ENDFILL] != 0;
result = mxMarker.createMarker(c, this, type, pe, unitX, unitY, size, source, this.strokewidth, filled);
}
return result;
};
mxConnector.prototype.augmentBoundingBox = function(bbox)
{
mxShape.prototype.augmentBoundingBox.apply(this, arguments);
var size = 0;
if (mxUtils.getValue(this.style, mxConstants.STYLE_STARTARROW, mxConstants.NONE) != mxConstants.NONE)
{
size = mxUtils.getNumber(this.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_MARKERSIZE) + 1;
}
if (mxUtils.getValue(this.style, mxConstants.STYLE_ENDARROW, mxConstants.NONE) != mxConstants.NONE)
{
size = Math.max(size, mxUtils.getNumber(this.style, mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE)) + 1;
}
bbox.grow(size * this.scale);
};
__mxOutput.mxConnector = typeof mxConnector !== 'undefined' ? mxConnector : undefined;
function mxSwimlane(bounds, fill, stroke, strokewidth)
{
mxShape.call(this);
this.bounds = bounds;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
} mxUtils.extend(mxSwimlane, mxShape);
mxSwimlane.prototype.imageSize = 16;
mxSwimlane.prototype.isRoundable = function(c, x, y, w, h)
{
return true;
};
mxSwimlane.prototype.getTitleSize = function()
{
return Math.max(0, mxUtils.getValue(this.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE));
};
mxSwimlane.prototype.getLabelBounds = function(rect)
{
var start = this.getTitleSize();
var bounds = new mxRectangle(rect.x, rect.y, rect.width, rect.height);
var horizontal = this.isHorizontal();
var flipH = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPH, 0) == 1;
var flipV = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPV, 0) == 1;
var shapeVertical = (this.direction == mxConstants.DIRECTION_NORTH ||
this.direction == mxConstants.DIRECTION_SOUTH);
var realHorizontal = horizontal == !shapeVertical;
var realFlipH = !realHorizontal && flipH != (this.direction == mxConstants.DIRECTION_SOUTH ||
this.direction == mxConstants.DIRECTION_WEST);
var realFlipV = realHorizontal && flipV != (this.direction == mxConstants.DIRECTION_SOUTH ||
this.direction == mxConstants.DIRECTION_WEST);
if (!shapeVertical)
{
var tmp = Math.min(bounds.height, start * this.scale);
if (realFlipH || realFlipV)
{
bounds.y += bounds.height - tmp;
}
bounds.height = tmp;
}
else
{
var tmp = Math.min(bounds.width, start * this.scale);
if (realFlipH || realFlipV)
{
bounds.x += bounds.width - tmp;
}
bounds.width = tmp;
}
return bounds;
};
mxSwimlane.prototype.getGradientBounds = function(c, x, y, w, h)
{
var start = this.getTitleSize();
if (this.isHorizontal())
{
start = Math.min(start, h);
return new mxRectangle(x, y, w, start);
}
else
{
start = Math.min(start, w);
return new mxRectangle(x, y, start, h);
}
};
mxSwimlane.prototype.getSwimlaneArcSize = function(w, h, start)
{
if (mxUtils.getValue(this.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1')
{
return Math.min(w / 2, Math.min(h / 2, mxUtils.getValue(this.style,
mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2));
}
else
{
var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;
return start * f * 3;
}
};
mxSwimlane.prototype.isHorizontal = function()
{
return mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, 1) == 1;
};
mxSwimlane.prototype.paintVertexShape = function(c, x, y, w, h)
{
var start = this.getTitleSize();
var fill = mxUtils.getValue(this.style, mxConstants.STYLE_SWIMLANE_FILLCOLOR, mxConstants.NONE);
var swimlaneLine = mxUtils.getValue(this.style, mxConstants.STYLE_SWIMLANE_LINE, 1) == 1;
var r = 0;
if (this.isHorizontal())
{
start = Math.min(start, h);
}
else
{
start = Math.min(start, w);
}
c.translate(x, y);
if (!this.isRounded)
{
this.paintSwimlane(c, x, y, w, h, start, fill, swimlaneLine);
}
else
{
r = this.getSwimlaneArcSize(w, h, start);
r = Math.min(((this.isHorizontal()) ? h : w) - start, Math.min(start, r));
this.paintRoundedSwimlane(c, x, y, w, h, start, r, fill, swimlaneLine);
}
var sep = mxUtils.getValue(this.style, mxConstants.STYLE_SEPARATORCOLOR, mxConstants.NONE);
this.paintSeparator(c, x, y, w, h, start, sep);
if (this.image != null)
{
var bounds = this.getImageBounds(x, y, w, h);
c.image(bounds.x - x, bounds.y - y, bounds.width, bounds.height,
this.image, false, false, false);
}
if (this.glass)
{
c.setShadow(false);
this.paintGlassEffect(c, 0, 0, w, start, r);
}
};
mxSwimlane.prototype.paintSwimlane = function(c, x, y, w, h, start, fill, swimlaneLine)
{
c.begin();
var events = true;
if (this.style != null)
{
events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1';
}
if (!events && (this.fill == null || this.fill == mxConstants.NONE))
{
c.pointerEvents = false;
}
if (this.isHorizontal())
{
c.moveTo(0, start);
c.lineTo(0, 0);
c.lineTo(w, 0);
c.lineTo(w, start);
c.fillAndStroke();
if (start < h)
{
if (fill == mxConstants.NONE || !events)
{
c.pointerEvents = false;
}
if (fill != mxConstants.NONE)
{
c.setFillColor(fill);
}
c.begin();
c.moveTo(0, start);
c.lineTo(0, h);
c.lineTo(w, h);
c.lineTo(w, start);
if (fill == mxConstants.NONE)
{
c.stroke();
}
else
{
c.fillAndStroke();
}
}
}
else
{
c.moveTo(start, 0);
c.lineTo(0, 0);
c.lineTo(0, h);
c.lineTo(start, h);
c.fillAndStroke();
if (start < w)
{
if (fill == mxConstants.NONE || !events)
{
c.pointerEvents = false;
}
if (fill != mxConstants.NONE)
{
c.setFillColor(fill);
}
c.begin();
c.moveTo(start, 0);
c.lineTo(w, 0);
c.lineTo(w, h);
c.lineTo(start, h);
if (fill == mxConstants.NONE)
{
c.stroke();
}
else
{
c.fillAndStroke();
}
}
}
if (swimlaneLine)
{
this.paintDivider(c, x, y, w, h, start, fill == mxConstants.NONE);
}
};
mxSwimlane.prototype.paintRoundedSwimlane = function(c, x, y, w, h, start, r, fill, swimlaneLine)
{
c.begin();
var events = true;
if (this.style != null)
{
events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1';
}
if (!events && (this.fill == null || this.fill == mxConstants.NONE))
{
c.pointerEvents = false;
}
if (this.isHorizontal())
{
c.moveTo(w, start);
c.lineTo(w, r);
c.quadTo(w, 0, w - Math.min(w / 2, r), 0);
c.lineTo(Math.min(w / 2, r), 0);
c.quadTo(0, 0, 0, r);
c.lineTo(0, start);
c.fillAndStroke();
if (start < h)
{
if (fill == mxConstants.NONE || !events)
{
c.pointerEvents = false;
}
if (fill != mxConstants.NONE)
{
c.setFillColor(fill);
}
c.begin();
c.moveTo(0, start);
c.lineTo(0, h - r);
c.quadTo(0, h, Math.min(w / 2, r), h);
c.lineTo(w - Math.min(w / 2, r), h);
c.quadTo(w, h, w, h - r);
c.lineTo(w, start);
if (fill == mxConstants.NONE)
{
c.stroke();
}
else
{
c.fillAndStroke();
}
}
}
else
{
c.moveTo(start, 0);
c.lineTo(r, 0);
c.quadTo(0, 0, 0, Math.min(h / 2, r));
c.lineTo(0, h - Math.min(h / 2, r));
c.quadTo(0, h, r, h);
c.lineTo(start, h);
c.fillAndStroke();
if (start < w)
{
if (fill == mxConstants.NONE || !events)
{
c.pointerEvents = false;
}
if (fill != mxConstants.NONE)
{
c.setFillColor(fill);
}
c.begin();
c.moveTo(start, h);
c.lineTo(w - r, h);
c.quadTo(w, h, w, h - Math.min(h / 2, r));
c.lineTo(w, Math.min(h / 2, r));
c.quadTo(w, 0, w - r, 0);
c.lineTo(start, 0);
if (fill == mxConstants.NONE)
{
c.stroke();
}
else
{
c.fillAndStroke();
}
}
}
if (swimlaneLine)
{
this.paintDivider(c, x, y, w, h, start, fill == mxConstants.NONE);
}
};
mxSwimlane.prototype.paintDivider = function(c, x, y, w, h, start, shadow)
{
if (!shadow)
{
c.setShadow(false);
}
c.begin();
if (this.isHorizontal())
{
c.moveTo(0, start);
c.lineTo(w, start);
}
else
{
c.moveTo(start, 0);
c.lineTo(start, h);
}
c.stroke();
};
mxSwimlane.prototype.paintSeparator = function(c, x, y, w, h, start, color)
{
if (color != mxConstants.NONE)
{
c.setStrokeColor(color);
c.setDashed(true);
c.begin();
if (this.isHorizontal())
{
c.moveTo(w, start);
c.lineTo(w, h);
}
else
{
c.moveTo(start, 0);
c.lineTo(w, 0);
}
c.stroke();
c.setDashed(false);
}
};
mxSwimlane.prototype.getImageBounds = function(x, y, w, h)
{
if (this.isHorizontal())
{
return new mxRectangle(x + w - this.imageSize, y, this.imageSize, this.imageSize);
}
else
{
return new mxRectangle(x, y, this.imageSize, this.imageSize);
}
};
__mxOutput.mxSwimlane = typeof mxSwimlane !== 'undefined' ? mxSwimlane : undefined;
function mxGraphLayout(graph)
{
this.graph = graph;
} mxGraphLayout.prototype.graph = null;
mxGraphLayout.prototype.useBoundingBox = true;
mxGraphLayout.prototype.parent = null;
mxGraphLayout.prototype.moveCell = function(cell, x, y) { };
mxGraphLayout.prototype.resizeCell = function(cell, bounds) { };
mxGraphLayout.prototype.execute = function(parent) { };
mxGraphLayout.prototype.getGraph = function()
{
return this.graph;
};
mxGraphLayout.prototype.getConstraint = function(key, cell, edge, source)
{
return this.graph.getCurrentCellStyle(cell)[key]
};
mxGraphLayout.traverse = function(vertex, directed, func, edge, visited)
{
if (func != null && vertex != null)
{
directed = (directed != null) ? directed : true;
visited = visited || new mxDictionary();
if (!visited.get(vertex))
{
visited.put(vertex, true);
var result = func(vertex, edge);
if (result == null || result)
{
var edgeCount = this.graph.model.getEdgeCount(vertex);
if (edgeCount > 0)
{
for (var i = 0; i < edgeCount; i++)
{
var e = this.graph.model.getEdgeAt(vertex, i);
var isSource = this.graph.model.getTerminal(e, true) == vertex;
if (!directed || isSource)
{
var next = this.graph.view.getVisibleTerminal(e, !isSource);
this.traverse(next, directed, func, e, visited);
}
}
}
}
}
}
};
mxGraphLayout.prototype.isAncestor = function(parent, child, traverseAncestors)
{
if (!traverseAncestors)
{
return (this.graph.model.getParent(child) == parent);
}
if (child == parent)
{
return false;
}
while (child != null && child != parent)
{
child = this.graph.model.getParent(child);
}
return child == parent;
};
mxGraphLayout.prototype.isVertexMovable = function(cell)
{
return this.graph.isCellMovable(cell);
};
mxGraphLayout.prototype.isVertexIgnored = function(vertex)
{
return !this.graph.getModel().isVertex(vertex) ||
!this.graph.isCellVisible(vertex);
};
mxGraphLayout.prototype.isEdgeIgnored = function(edge)
{
var model = this.graph.getModel();
return !model.isEdge(edge) ||
!this.graph.isCellVisible(edge) ||
model.getTerminal(edge, true) == null ||
model.getTerminal(edge, false) == null;
};
mxGraphLayout.prototype.setEdgeStyleEnabled = function(edge, value)
{
this.graph.setCellStyles(mxConstants.STYLE_NOEDGESTYLE,
(value) ? '0' : '1', [edge]);
};
mxGraphLayout.prototype.setOrthogonalEdge = function(edge, value)
{
this.graph.setCellStyles(mxConstants.STYLE_ORTHOGONAL,
(value) ? '1' : '0', [edge]);
};
mxGraphLayout.prototype.getParentOffset = function(parent)
{
var result = new mxPoint();
if (parent != null && parent != this.parent)
{
var model = this.graph.getModel();
if (model.isAncestor(this.parent, parent))
{
var parentGeo = model.getGeometry(parent);
while (parent != this.parent)
{
result.x = result.x + parentGeo.x;
result.y = result.y + parentGeo.y;
parent = model.getParent(parent); parentGeo = model.getGeometry(parent);
}
}
}
return result;
};
mxGraphLayout.prototype.setEdgePoints = function(edge, points)
{
if (edge != null)
{
var model = this.graph.model;
var geometry = model.getGeometry(edge);
if (geometry == null)
{
geometry = new mxGeometry();
geometry.setRelative(true);
}
else
{
geometry = geometry.clone();
}
if (this.parent != null && points != null)
{
var parent = model.getParent(edge);
var parentOffset = this.getParentOffset(parent);
for (var i = 0; i < points.length; i++)
{
points[i].x = points[i].x - parentOffset.x;
points[i].y = points[i].y - parentOffset.y;
}
}
geometry.points = points;
model.setGeometry(edge, geometry);
}
};
mxGraphLayout.prototype.setVertexLocation = function(cell, x, y)
{
var model = this.graph.getModel();
var geometry = model.getGeometry(cell);
var result = null;
if (geometry != null)
{
result = new mxRectangle(x, y, geometry.width, geometry.height);
if (this.useBoundingBox)
{
var state = this.graph.getView().getState(cell);
if (state != null && state.text != null && state.text.boundingBox != null)
{
var scale = this.graph.getView().scale;
var box = state.text.boundingBox;
if (state.text.boundingBox.x < state.x)
{
x += (state.x - box.x) / scale;
result.width = box.width;
}
if (state.text.boundingBox.y < state.y)
{
y += (state.y - box.y) / scale;
result.height = box.height;
}
}
}
if (this.parent != null)
{
var parent = model.getParent(cell);
if (parent != null && parent != this.parent)
{
var parentOffset = this.getParentOffset(parent);
x = x - parentOffset.x;
y = y - parentOffset.y;
}
}
if (geometry.x != x || geometry.y != y)
{
geometry = geometry.clone();
geometry.x = x;
geometry.y = y;
model.setGeometry(cell, geometry);
}
}
return result;
};
mxGraphLayout.prototype.getVertexBounds = function(cell)
{
var geo = this.graph.getModel().getGeometry(cell);
if (this.useBoundingBox)
{
var state = this.graph.getView().getState(cell);
if (state != null && state.text != null && state.text.boundingBox != null)
{
var scale = this.graph.getView().scale;
var tmp = state.text.boundingBox;
var dx0 = Math.max(state.x - tmp.x, 0) / scale;
var dy0 = Math.max(state.y - tmp.y, 0) / scale;
var dx1 = Math.max((tmp.x + tmp.width) - (state.x + state.width), 0) / scale;
var dy1 = Math.max((tmp.y + tmp.height) - (state.y + state.height), 0) / scale;
geo = new mxRectangle(geo.x - dx0, geo.y - dy0, geo.width + dx0 + dx1, geo.height + dy0 + dy1);
}
}
if (this.parent != null)
{
var parent = this.graph.getModel().getParent(cell);
geo = geo.clone();
if (parent != null && parent != this.parent)
{
var parentOffset = this.getParentOffset(parent);
geo.x = geo.x + parentOffset.x;
geo.y = geo.y + parentOffset.y;
}
}
return new mxRectangle(geo.x, geo.y, geo.width, geo.height);
};
mxGraphLayout.prototype.arrangeGroups = function(cells, border, topBorder, rightBorder, bottomBorder, leftBorder)
{
return this.graph.updateGroupBounds(cells, border, true, topBorder, rightBorder, bottomBorder, leftBorder);
};
function WeightedCellSorter(cell, weightedValue)
{
this.cell = cell;
this.weightedValue = weightedValue;
} WeightedCellSorter.prototype.weightedValue = 0;
WeightedCellSorter.prototype.nudge = false;
WeightedCellSorter.prototype.visited = false;
WeightedCellSorter.prototype.rankIndex = null;
WeightedCellSorter.prototype.cell = null;
WeightedCellSorter.prototype.compare = function(a, b)
{
if (a != null && b != null)
{
if (b.weightedValue > a.weightedValue)
{
return -1;
}
else if (b.weightedValue < a.weightedValue)
{
return 1;
}
else
{
if (b.nudge)
{
return -1;
}
else
{
return 1;
}
}
}
else
{
return 0;
}
};
__mxOutput.mxGraphLayout = typeof mxGraphLayout !== 'undefined' ? mxGraphLayout : undefined;
function mxStackLayout(graph, horizontal, spacing, x0, y0, border)
{
mxGraphLayout.call(this, graph);
this.horizontal = (horizontal != null) ? horizontal : true;
this.spacing = (spacing != null) ? spacing : 0;
this.x0 = (x0 != null) ? x0 : 0;
this.y0 = (y0 != null) ? y0 : 0;
this.border = (border != null) ? border : 0;
} mxStackLayout.prototype = new mxGraphLayout();
mxStackLayout.prototype.constructor = mxStackLayout;
mxStackLayout.prototype.horizontal = null;
mxStackLayout.prototype.spacing = null;
mxStackLayout.prototype.x0 = null;
mxStackLayout.prototype.y0 = null;
mxStackLayout.prototype.border = 0;
mxStackLayout.prototype.marginTop = 0;
mxStackLayout.prototype.marginLeft = 0;
mxStackLayout.prototype.marginRight = 0;
mxStackLayout.prototype.marginBottom = 0;
mxStackLayout.prototype.keepFirstLocation = false;
mxStackLayout.prototype.fill = false;
mxStackLayout.prototype.resizeParent = false;
mxStackLayout.prototype.resizeParentMax = false;
mxStackLayout.prototype.resizeLast = false;
mxStackLayout.prototype.wrap = null;
mxStackLayout.prototype.borderCollapse = true;
mxStackLayout.prototype.allowGaps = false;
mxStackLayout.prototype.gridSize = 0;
mxStackLayout.prototype.isHorizontal = function()
{
return this.horizontal;
};
mxStackLayout.prototype.moveCell = function(cell, x, y)
{
var model = this.graph.getModel();
var parent = model.getParent(cell);
var horizontal = this.isHorizontal();
if (cell != null && parent != null)
{
var i = 0;
var last = 0;
var childCount = model.getChildCount(parent);
var value = (horizontal) ? x : y;
var pstate = this.graph.getView().getState(parent);
if (pstate != null)
{
value -= (horizontal) ? pstate.x : pstate.y;
}
value /= this.graph.view.scale;
for (i = 0; i < childCount; i++)
{
var child = model.getChildAt(parent, i);
if (child != cell)
{
var bounds = model.getGeometry(child);
if (bounds != null)
{
var tmp = (horizontal) ?
bounds.x + bounds.width / 2 :
bounds.y + bounds.height / 2;
if (last <= value && tmp > value)
{
break;
}
last = tmp;
}
}
}
var idx = parent.getIndex(cell);
idx = Math.max(0, i - ((i > idx) ? 1 : 0));
model.add(parent, cell, idx);
}
};
mxStackLayout.prototype.getParentSize = function(parent)
{
var model = this.graph.getModel();
var pgeo = model.getGeometry(parent);
if (this.graph.container != null && ((pgeo == null &&
model.isLayer(parent)) || parent == this.graph.getView().currentRoot))
{
var width = this.graph.container.offsetWidth - 1;
var height = this.graph.container.offsetHeight - 1;
pgeo = new mxRectangle(0, 0, width, height);
}
return pgeo;
};
mxStackLayout.prototype.getLayoutCells = function(parent)
{
var model = this.graph.getModel();
var childCount = model.getChildCount(parent);
var cells = [];
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(parent, i);
if (!this.isVertexIgnored(child) && this.isVertexMovable(child))
{
cells.push(child);
}
}
if (this.allowGaps)
{
cells.sort(mxUtils.bind(this, function(c1, c2)
{
var geo1 = this.graph.getCellGeometry(c1);
var geo2 = this.graph.getCellGeometry(c2);
return (this.horizontal) ?
((geo1.x == geo2.x) ? 0 : ((geo1.x > geo2.x > 0) ? 1 : -1)) :
((geo1.y == geo2.y) ? 0 : ((geo1.y > geo2.y > 0) ? 1 : -1));
}));
}
return cells;
};
mxStackLayout.prototype.snap = function(value)
{
if (this.gridSize != null && this.gridSize > 0)
{
value = Math.max(value, this.gridSize);
if (value / this.gridSize > 1)
{
var mod = value % this.gridSize;
value += mod > this.gridSize / 2 ? (this.gridSize - mod) : -mod;
}
}
return value;
};
mxStackLayout.prototype.execute = function(parent)
{
if (parent != null)
{
var pgeo = this.getParentSize(parent);
var horizontal = this.isHorizontal();
var model = this.graph.getModel();
var fillValue = null;
if (pgeo != null)
{
fillValue = (horizontal) ? pgeo.height - this.marginTop - this.marginBottom :
pgeo.width - this.marginLeft - this.marginRight;
}
fillValue -= 2 * this.border;
var x0 = this.x0 + this.border + this.marginLeft;
var y0 = this.y0 + this.border + this.marginTop;
if (this.graph.isSwimlane(parent))
{
var style = this.graph.getCellStyle(parent);
var start = mxUtils.getNumber(style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE);
var horz = mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true) == 1;
if (pgeo != null)
{
if (horz)
{
start = Math.min(start, pgeo.height);
}
else
{
start = Math.min(start, pgeo.width);
}
}
if (horizontal == horz)
{
fillValue -= start;
}
if (horz)
{
y0 += start;
}
else
{
x0 += start;
}
}
model.beginUpdate();
try
{
var tmp = 0;
var last = null;
var lastValue = 0;
var lastChild = null;
var cells = this.getLayoutCells(parent);
for (var i = 0; i < cells.length; i++)
{
var child = cells[i];
var geo = model.getGeometry(child);
if (geo != null)
{
geo = geo.clone();
if (this.wrap != null && last != null)
{
if ((horizontal && last.x + last.width +
geo.width + 2 * this.spacing > this.wrap) ||
(!horizontal && last.y + last.height +
geo.height + 2 * this.spacing > this.wrap))
{
last = null;
if (horizontal)
{
y0 += tmp + this.spacing;
}
else
{
x0 += tmp + this.spacing;
}
tmp = 0;
}
}
tmp = Math.max(tmp, (horizontal) ? geo.height : geo.width);
var sw = 0;
if (!this.borderCollapse)
{
var childStyle = this.graph.getCellStyle(child);
sw = mxUtils.getNumber(childStyle, mxConstants.STYLE_STROKEWIDTH, 1);
}
if (last != null)
{
var temp = lastValue + this.spacing + Math.floor(sw / 2);
if (horizontal)
{
geo.x = this.snap(((this.allowGaps) ? Math.max(temp, geo.x) :
temp) - this.marginLeft) + this.marginLeft;
}
else
{
geo.y = this.snap(((this.allowGaps) ? Math.max(temp, geo.y) :
temp) - this.marginTop) + this.marginTop;
}
}
else if (!this.keepFirstLocation)
{
if (horizontal)
{
geo.x = (this.allowGaps && geo.x > x0) ? Math.max(this.snap(geo.x -
this.marginLeft) + this.marginLeft, x0) : x0;
}
else
{
geo.y = (this.allowGaps && geo.y > y0) ? Math.max(this.snap(geo.y -
this.marginTop) + this.marginTop, y0) : y0;
}
}
if (horizontal)
{
geo.y = y0;
}
else
{
geo.x = x0;
}
if (this.fill && fillValue != null)
{
if (horizontal)
{
geo.height = fillValue;
}
else
{
geo.width = fillValue;
}
}
if (horizontal)
{
geo.width = this.snap(geo.width);
}
else
{
geo.height = this.snap(geo.height);
}
this.setChildGeometry(child, geo);
lastChild = child;
last = geo;
if (horizontal)
{
lastValue = last.x + last.width + Math.floor(sw / 2);
}
else
{
lastValue = last.y + last.height + Math.floor(sw / 2);
}
}
}
if (this.resizeParent && pgeo != null && last != null && !this.graph.isCellCollapsed(parent))
{
this.updateParentGeometry(parent, pgeo, last);
}
else if (this.resizeLast && pgeo != null && last != null && lastChild != null)
{
if (horizontal)
{
last.width = pgeo.width - last.x - this.spacing - this.marginRight - this.marginLeft;
}
else
{
last.height = pgeo.height - last.y - this.spacing - this.marginBottom;
}
this.setChildGeometry(lastChild, last);
}
}
finally
{
model.endUpdate();
}
}
};
mxStackLayout.prototype.setChildGeometry = function(child, geo)
{
var geo2 = this.graph.getCellGeometry(child);
if (geo2 == null || geo.x != geo2.x || geo.y != geo2.y ||
geo.width != geo2.width || geo.height != geo2.height)
{
this.graph.getModel().setGeometry(child, geo);
}
};
mxStackLayout.prototype.updateParentGeometry = function(parent, pgeo, last)
{
var horizontal = this.isHorizontal();
var model = this.graph.getModel();
var pgeo2 = pgeo.clone();
if (horizontal)
{
var tmp = last.x + last.width + this.marginRight + this.border;
if (this.resizeParentMax)
{
pgeo2.width = Math.max(pgeo2.width, tmp);
}
else
{
pgeo2.width = tmp;
}
}
else
{
var tmp = last.y + last.height + this.marginBottom + this.border;
if (this.resizeParentMax)
{
pgeo2.height = Math.max(pgeo2.height, tmp);
}
else
{
pgeo2.height = tmp;
}
}
if (pgeo.x != pgeo2.x || pgeo.y != pgeo2.y ||
pgeo.width != pgeo2.width || pgeo.height != pgeo2.height)
{
model.setGeometry(parent, pgeo2);
}
};
__mxOutput.mxStackLayout = typeof mxStackLayout !== 'undefined' ? mxStackLayout : undefined;
function mxPartitionLayout(graph, horizontal, spacing, border)
{
mxGraphLayout.call(this, graph);
this.horizontal = (horizontal != null) ? horizontal : true;
this.spacing = spacing || 0;
this.border = border || 0;
} mxPartitionLayout.prototype = new mxGraphLayout();
mxPartitionLayout.prototype.constructor = mxPartitionLayout;
mxPartitionLayout.prototype.horizontal = null;
mxPartitionLayout.prototype.spacing = null;
mxPartitionLayout.prototype.border = null;
mxPartitionLayout.prototype.resizeVertices = true;
mxPartitionLayout.prototype.isHorizontal = function()
{
return this.horizontal;
};
mxPartitionLayout.prototype.moveCell = function(cell, x, y)
{
var model = this.graph.getModel();
var parent = model.getParent(cell);
if (cell != null &&
parent != null)
{
var i = 0;
var last = 0;
var childCount = model.getChildCount(parent);
for (i = 0; i < childCount; i++)
{
var child = model.getChildAt(parent, i);
var bounds = this.getVertexBounds(child);
if (bounds != null)
{
var tmp = bounds.x + bounds.width / 2;
if (last < x && tmp > x)
{
break;
}
last = tmp;
}
}
var idx = parent.getIndex(cell);
idx = Math.max(0, i - ((i > idx) ? 1 : 0));
model.add(parent, cell, idx);
}
};
mxPartitionLayout.prototype.execute = function(parent)
{
var horizontal = this.isHorizontal();
var model = this.graph.getModel();
var pgeo = model.getGeometry(parent);
if (this.graph.container != null &&
((pgeo == null &&
model.isLayer(parent)) ||
parent == this.graph.getView().currentRoot))
{
var width = this.graph.container.offsetWidth - 1;
var height = this.graph.container.offsetHeight - 1;
pgeo = new mxRectangle(0, 0, width, height);
}
if (pgeo != null)
{
var children = [];
var childCount = model.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(parent, i);
if (!this.isVertexIgnored(child) &&
this.isVertexMovable(child))
{
children.push(child);
}
}
var n = children.length;
if (n > 0)
{
var x0 = this.border;
var y0 = this.border;
var other = (horizontal) ? pgeo.height : pgeo.width;
other -= 2 * this.border;
var size = (this.graph.isSwimlane(parent)) ?
this.graph.getStartSize(parent) :
new mxRectangle();
other -= (horizontal) ? size.height : size.width;
x0 = x0 + size.width;
y0 = y0 + size.height;
var tmp = this.border + (n - 1) * this.spacing;
var value = (horizontal) ?
((pgeo.width - x0 - tmp) / n) :
((pgeo.height - y0 - tmp) / n);
if (value > 0)
{
model.beginUpdate();
try
{
for (var i = 0; i < n; i++)
{
var child = children[i];
var geo = model.getGeometry(child);
if (geo != null)
{
geo = geo.clone();
geo.x = x0;
geo.y = y0;
if (horizontal)
{
if (this.resizeVertices)
{
geo.width = value;
geo.height = other;
}
x0 += value + this.spacing;
}
else
{
if (this.resizeVertices)
{
geo.height = value;
geo.width = other;
}
y0 += value + this.spacing;
}
model.setGeometry(child, geo);
}
}
}
finally
{
model.endUpdate();
}
}
}
}
};
__mxOutput.mxPartitionLayout = typeof mxPartitionLayout !== 'undefined' ? mxPartitionLayout : undefined;
function mxCompactTreeLayout(graph, horizontal, invert)
{
mxGraphLayout.call(this, graph);
this.horizontal = (horizontal != null) ? horizontal : true;
this.invert = (invert != null) ? invert : false;
} mxCompactTreeLayout.prototype = new mxGraphLayout();
mxCompactTreeLayout.prototype.constructor = mxCompactTreeLayout;
mxCompactTreeLayout.prototype.horizontal = null;
mxCompactTreeLayout.prototype.invert = null;
mxCompactTreeLayout.prototype.resizeParent = true;
mxCompactTreeLayout.prototype.maintainParentLocation = false;
mxCompactTreeLayout.prototype.groupPadding = 10;
mxCompactTreeLayout.prototype.groupPaddingTop = 0;
mxCompactTreeLayout.prototype.groupPaddingRight = 0;
mxCompactTreeLayout.prototype.groupPaddingBottom = 0;
mxCompactTreeLayout.prototype.groupPaddingLeft = 0;
mxCompactTreeLayout.prototype.parentsChanged = null;
mxCompactTreeLayout.prototype.moveTree = false;
mxCompactTreeLayout.prototype.visited = null;
mxCompactTreeLayout.prototype.levelDistance = 10;
mxCompactTreeLayout.prototype.nodeDistance = 20;
mxCompactTreeLayout.prototype.resetEdges = true;
mxCompactTreeLayout.prototype.prefHozEdgeSep = 5;
mxCompactTreeLayout.prototype.prefVertEdgeOff = 4;
mxCompactTreeLayout.prototype.minEdgeJetty = 8;
mxCompactTreeLayout.prototype.channelBuffer = 4;
mxCompactTreeLayout.prototype.edgeRouting = true;
mxCompactTreeLayout.prototype.sortEdges = false;
mxCompactTreeLayout.prototype.alignRanks = false;
mxCompactTreeLayout.prototype.maxRankHeight = null;
mxCompactTreeLayout.prototype.root = null;
mxCompactTreeLayout.prototype.node = null;
mxCompactTreeLayout.prototype.isVertexIgnored = function(vertex)
{
return mxGraphLayout.prototype.isVertexIgnored.apply(this, arguments) ||
this.graph.getConnections(vertex).length == 0;
};
mxCompactTreeLayout.prototype.isHorizontal = function()
{
return this.horizontal;
};
mxCompactTreeLayout.prototype.execute = function(parent, root)
{
this.parent = parent;
var model = this.graph.getModel();
if (root == null)
{
if (this.graph.getEdges(parent, model.getParent(parent),
this.invert, !this.invert, false).length > 0)
{
this.root = parent;
}
else
{
var roots = this.graph.findTreeRoots(parent, true, this.invert);
if (roots.length > 0)
{
for (var i = 0; i < roots.length; i++)
{
if (!this.isVertexIgnored(roots[i]) &&
this.graph.getEdges(roots[i], null,
this.invert, !this.invert, false).length > 0)
{
this.root = roots[i];
break;
}
}
}
}
}
else
{
this.root = root;
}
if (this.root != null)
{
if (this.resizeParent)
{
this.parentsChanged = new Object();
}
else
{
this.parentsChanged = null;
}
this.parentX = null;
this.parentY = null;
if (parent != this.root && model.isVertex(parent) != null && this.maintainParentLocation)
{
var geo = this.graph.getCellGeometry(parent);
if (geo != null)
{
this.parentX = geo.x;
this.parentY = geo.y;
}
}
model.beginUpdate();
try
{
this.visited = new Object();
this.node = this.dfs(this.root, parent);
if (this.alignRanks)
{
this.maxRankHeight = [];
this.findRankHeights(this.node, 0);
this.setCellHeights(this.node, 0);
}
if (this.node != null)
{
this.layout(this.node);
var x0 = this.graph.gridSize;
var y0 = x0;
if (!this.moveTree)
{
var g = this.getVertexBounds(this.root);
if (g != null)
{
x0 = g.x;
y0 = g.y;
}
}
var bounds = null;
if (this.isHorizontal())
{
bounds = this.horizontalLayout(this.node, x0, y0);
}
else
{
bounds = this.verticalLayout(this.node, null, x0, y0);
}
if (bounds != null)
{
var dx = 0;
var dy = 0;
if (bounds.x < 0)
{
dx = Math.abs(x0 - bounds.x);
}
if (bounds.y < 0)
{
dy = Math.abs(y0 - bounds.y);
}
if (dx != 0 || dy != 0)
{
this.moveNode(this.node, dx, dy);
}
if (this.resizeParent)
{
this.adjustParents();
}
if (this.edgeRouting)
{
this.localEdgeProcessing(this.node);
}
}
if (this.parentX != null && this.parentY != null)
{
var geo = this.graph.getCellGeometry(parent);
if (geo != null)
{
geo = geo.clone();
geo.x = this.parentX;
geo.y = this.parentY;
model.setGeometry(parent, geo);
}
}
}
}
finally
{
model.endUpdate();
}
}
};
mxCompactTreeLayout.prototype.moveNode = function(node, dx, dy)
{
node.x += dx;
node.y += dy;
this.apply(node);
var child = node.child;
while (child != null)
{
this.moveNode(child, dx, dy);
child = child.next;
}
};
mxCompactTreeLayout.prototype.sortOutgoingEdges = function(source, edges)
{
var lookup = new mxDictionary();
edges.sort(function(e1, e2)
{
var end1 = e1.getTerminal(e1.getTerminal(false) == source);
var p1 = lookup.get(end1);
if (p1 == null)
{
p1 = mxCellPath.create(end1).split(mxCellPath.PATH_SEPARATOR);
lookup.put(end1, p1);
}
var end2 = e2.getTerminal(e2.getTerminal(false) == source);
var p2 = lookup.get(end2);
if (p2 == null)
{
p2 = mxCellPath.create(end2).split(mxCellPath.PATH_SEPARATOR);
lookup.put(end2, p2);
}
return mxCellPath.compare(p1, p2);
});
};
mxCompactTreeLayout.prototype.findRankHeights = function(node, rank)
{
if (this.maxRankHeight[rank] == null || this.maxRankHeight[rank] < node.height)
{
this.maxRankHeight[rank] = node.height;
}
var child = node.child;
while (child != null)
{
this.findRankHeights(child, rank + 1);
child = child.next;
}
};
mxCompactTreeLayout.prototype.setCellHeights = function(node, rank)
{
if (this.maxRankHeight[rank] != null && this.maxRankHeight[rank] > node.height)
{
node.height = this.maxRankHeight[rank];
}
var child = node.child;
while (child != null)
{
this.setCellHeights(child, rank + 1);
child = child.next;
}
};
mxCompactTreeLayout.prototype.dfs = function(cell, parent)
{
var id = mxCellPath.create(cell);
var node = null;
if (cell != null && this.visited[id] == null && !this.isVertexIgnored(cell))
{
this.visited[id] = cell;
node = this.createNode(cell);
var model = this.graph.getModel();
var prev = null;
var out = this.graph.getEdges(cell, parent, this.invert, !this.invert, false, true);
var view = this.graph.getView();
if (this.sortEdges)
{
this.sortOutgoingEdges(cell, out);
}
for (var i = 0; i < out.length; i++)
{
var edge = out[i];
if (!this.isEdgeIgnored(edge))
{
if (this.resetEdges)
{
this.setEdgePoints(edge, null);
}
if (this.edgeRouting)
{
this.setEdgeStyleEnabled(edge, false);
this.setEdgePoints(edge, null);
}
var state = view.getState(edge);
var target = (state != null) ? state.getVisibleTerminal(this.invert) : view.getVisibleTerminal(edge, this.invert);
var tmp = this.dfs(target, parent);
if (tmp != null && model.getGeometry(target) != null)
{
if (prev == null)
{
node.child = tmp;
}
else
{
prev.next = tmp;
}
prev = tmp;
}
}
}
}
return node;
};
mxCompactTreeLayout.prototype.layout = function(node)
{
if (node != null)
{
var child = node.child;
while (child != null)
{
this.layout(child);
child = child.next;
}
if (node.child != null)
{
this.attachParent(node, this.join(node));
}
else
{
this.layoutLeaf(node);
}
}
};
mxCompactTreeLayout.prototype.horizontalLayout = function(node, x0, y0, bounds)
{
node.x += x0 + node.offsetX;
node.y += y0 + node.offsetY;
bounds = this.apply(node, bounds);
var child = node.child;
if (child != null)
{
bounds = this.horizontalLayout(child, node.x, node.y, bounds);
var siblingOffset = node.y + child.offsetY;
var s = child.next;
while (s != null)
{
bounds = this.horizontalLayout(s, node.x + child.offsetX, siblingOffset, bounds);
siblingOffset += s.offsetY;
s = s.next;
}
}
return bounds;
};
mxCompactTreeLayout.prototype.verticalLayout = function(node, parent, x0, y0, bounds)
{
node.x += x0 + node.offsetY;
node.y += y0 + node.offsetX;
bounds = this.apply(node, bounds);
var child = node.child;
if (child != null)
{
bounds = this.verticalLayout(child, node, node.x, node.y, bounds);
var siblingOffset = node.x + child.offsetY;
var s = child.next;
while (s != null)
{
bounds = this.verticalLayout(s, node, siblingOffset, node.y + child.offsetX, bounds);
siblingOffset += s.offsetY;
s = s.next;
}
}
return bounds;
};
mxCompactTreeLayout.prototype.attachParent = function(node, height)
{
var x = this.nodeDistance + this.levelDistance;
var y2 = (height - node.width) / 2 - this.nodeDistance;
var y1 = y2 + node.width + 2 * this.nodeDistance - height;
node.child.offsetX = x + node.height;
node.child.offsetY = y1;
node.contour.upperHead = this.createLine(node.height, 0,
this.createLine(x, y1, node.contour.upperHead));
node.contour.lowerHead = this.createLine(node.height, 0,
this.createLine(x, y2, node.contour.lowerHead));
};
mxCompactTreeLayout.prototype.layoutLeaf = function(node)
{
var dist = 2 * this.nodeDistance;
node.contour.upperTail = this.createLine(
node.height + dist, 0);
node.contour.upperHead = node.contour.upperTail;
node.contour.lowerTail = this.createLine(
0, -node.width - dist);
node.contour.lowerHead = this.createLine(
node.height + dist, 0, node.contour.lowerTail);
};
mxCompactTreeLayout.prototype.join = function(node)
{
var dist = 2 * this.nodeDistance;
var child = node.child;
node.contour = child.contour;
var h = child.width + dist;
var sum = h;
child = child.next;
while (child != null)
{
var d = this.merge(node.contour, child.contour);
child.offsetY = d + h;
child.offsetX = 0;
h = child.width + dist;
sum += d + h;
child = child.next;
}
return sum;
};
mxCompactTreeLayout.prototype.merge = function(p1, p2)
{
var x = 0;
var y = 0;
var total = 0;
var upper = p1.lowerHead;
var lower = p2.upperHead;
while (lower != null && upper != null)
{
var d = this.offset(x, y, lower.dx, lower.dy,
upper.dx, upper.dy);
y += d;
total += d;
if (x + lower.dx <= upper.dx)
{
x += lower.dx;
y += lower.dy;
lower = lower.next;
}
else
{
x -= upper.dx;
y -= upper.dy;
upper = upper.next;
}
}
if (lower != null)
{
var b = this.bridge(p1.upperTail, 0, 0, lower, x, y);
p1.upperTail = (b.next != null) ? p2.upperTail : b;
p1.lowerTail = p2.lowerTail;
}
else
{
var b = this.bridge(p2.lowerTail, x, y, upper, 0, 0);
if (b.next == null)
{
p1.lowerTail = b;
}
}
p1.lowerHead = p2.lowerHead;
return total;
};
mxCompactTreeLayout.prototype.offset = function(p1, p2, a1, a2, b1, b2)
{
var d = 0;
if (b1 <= p1 || p1 + a1 <= 0)
{
return 0;
}
var t = b1 * a2 - a1 * b2;
if (t > 0)
{
if (p1 < 0)
{
var s = p1 * a2;
d = s / a1 - p2;
}
else if (p1 > 0)
{
var s = p1 * b2;
d = s / b1 - p2;
}
else
{
d = -p2;
}
}
else if (b1 < p1 + a1)
{
var s = (b1 - p1) * a2;
d = b2 - (p2 + s / a1);
}
else if (b1 > p1 + a1)
{
var s = (a1 + p1) * b2;
d = s / b1 - (p2 + a2);
}
else
{
d = b2 - (p2 + a2);
}
if (d > 0)
{
return d;
}
else
{
return 0;
}
};
mxCompactTreeLayout.prototype.bridge = function(line1, x1, y1, line2, x2, y2)
{
var dx = x2 + line2.dx - x1;
var dy = 0;
var s = 0;
if (line2.dx == 0)
{
dy = line2.dy;
}
else
{
s = dx * line2.dy;
dy = s / line2.dx;
}
var r = this.createLine(dx, dy, line2.next);
line1.next = this.createLine(0, y2 + line2.dy - dy - y1, r);
return r;
};
mxCompactTreeLayout.prototype.createNode = function(cell)
{
var node = new Object();
node.cell = cell;
node.x = 0;
node.y = 0;
node.width = 0;
node.height = 0;
var geo = this.getVertexBounds(cell);
if (geo != null)
{
if (this.isHorizontal())
{
node.width = geo.height;
node.height = geo.width;
}
else
{
node.width = geo.width;
node.height = geo.height;
}
}
node.offsetX = 0;
node.offsetY = 0;
node.contour = new Object();
return node;
};
mxCompactTreeLayout.prototype.apply = function(node, bounds)
{
var model = this.graph.getModel();
var cell = node.cell;
var g = model.getGeometry(cell);
if (cell != null && g != null)
{
if (this.isVertexMovable(cell))
{
g = this.setVertexLocation(cell, node.x, node.y);
if (this.resizeParent)
{
var parent = model.getParent(cell);
var id = mxCellPath.create(parent);
if (this.parentsChanged[id] == null)
{
this.parentsChanged[id] = parent;
}
}
}
if (bounds == null)
{
bounds = new mxRectangle(g.x, g.y, g.width, g.height);
}
else
{
bounds = new mxRectangle(Math.min(bounds.x, g.x),
Math.min(bounds.y, g.y),
Math.max(bounds.x + bounds.width, g.x + g.width),
Math.max(bounds.y + bounds.height, g.y + g.height));
}
}
return bounds;
};
mxCompactTreeLayout.prototype.createLine = function(dx, dy, next)
{
var line = new Object();
line.dx = dx;
line.dy = dy;
line.next = next;
return line;
};
mxCompactTreeLayout.prototype.adjustParents = function()
{
var tmp = [];
for (var id in this.parentsChanged)
{
tmp.push(this.parentsChanged[id]);
}
this.arrangeGroups(mxUtils.sortCells(tmp, true), this.groupPadding, this.groupPaddingTop,
this.groupPaddingRight, this.groupPaddingBottom, this.groupPaddingLeft);
};
mxCompactTreeLayout.prototype.localEdgeProcessing = function(node)
{
this.processNodeOutgoing(node);
var child = node.child;
while (child != null)
{
this.localEdgeProcessing(child);
child = child.next;
}
};
mxCompactTreeLayout.prototype.processNodeOutgoing = function(node)
{
var child = node.child;
var parentCell = node.cell;
var childCount = 0;
var sortedCells = [];
while (child != null)
{
childCount++;
var sortingCriterion = child.x;
if (this.horizontal)
{
sortingCriterion = child.y;
}
sortedCells.push(new WeightedCellSorter(child, sortingCriterion));
child = child.next;
}
sortedCells.sort(WeightedCellSorter.prototype.compare);
var availableWidth = node.width;
var requiredWidth = (childCount + 1) * this.prefHozEdgeSep;
if (availableWidth > requiredWidth + (2 * this.prefHozEdgeSep))
{
availableWidth -= 2 * this.prefHozEdgeSep;
}
var edgeSpacing = availableWidth / childCount;
var currentXOffset = edgeSpacing / 2.0;
if (availableWidth > requiredWidth + (2 * this.prefHozEdgeSep))
{
currentXOffset += this.prefHozEdgeSep;
}
var currentYOffset = this.minEdgeJetty - this.prefVertEdgeOff;
var parentBounds = this.getVertexBounds(parentCell);
child = node.child;
for (var j = 0; j < sortedCells.length; j++)
{
var childCell = sortedCells[j].cell.cell;
var childBounds = this.getVertexBounds(childCell);
var edges = this.graph.getEdgesBetween(parentCell,
childCell, false);
var newPoints = [];
var x = 0;
var y = 0;
for (var i = 0; i < edges.length; i++)
{
if (this.horizontal)
{
x = parentBounds.x + parentBounds.width;
y = parentBounds.y + currentXOffset;
newPoints.push(new mxPoint(x, y));
x = parentBounds.x + parentBounds.width
+ currentYOffset;
newPoints.push(new mxPoint(x, y));
y = childBounds.y + childBounds.height / 2.0;
newPoints.push(new mxPoint(x, y));
this.setEdgePoints(edges[i], newPoints);
}
else
{
x = parentBounds.x + currentXOffset;
y = parentBounds.y + parentBounds.height;
newPoints.push(new mxPoint(x, y));
y = parentBounds.y + parentBounds.height
+ currentYOffset;
newPoints.push(new mxPoint(x, y));
x = childBounds.x + childBounds.width / 2.0;
newPoints.push(new mxPoint(x, y));
this.setEdgePoints(edges[i], newPoints);
}
}
if (j < childCount / 2)
{
currentYOffset += this.prefVertEdgeOff;
}
else if (j > childCount / 2)
{
currentYOffset -= this.prefVertEdgeOff;
}
currentXOffset += edgeSpacing;
}
};
__mxOutput.mxCompactTreeLayout = typeof mxCompactTreeLayout !== 'undefined' ? mxCompactTreeLayout : undefined;
function mxRadialTreeLayout(graph)
{
mxCompactTreeLayout.call(this, graph , false);
} mxUtils.extend(mxRadialTreeLayout, mxCompactTreeLayout);
mxRadialTreeLayout.prototype.angleOffset = 0.5;
mxRadialTreeLayout.prototype.rootx = 0;
mxRadialTreeLayout.prototype.rooty = 0;
mxRadialTreeLayout.prototype.levelDistance = 120;
mxRadialTreeLayout.prototype.nodeDistance = 10;
mxRadialTreeLayout.prototype.autoRadius = false;
mxRadialTreeLayout.prototype.sortEdges = false;
mxRadialTreeLayout.prototype.rowMinX = [];
mxRadialTreeLayout.prototype.rowMaxX = [];
mxRadialTreeLayout.prototype.rowMinCenX = [];
mxRadialTreeLayout.prototype.rowMaxCenX = [];
mxRadialTreeLayout.prototype.rowRadi = [];
mxRadialTreeLayout.prototype.row = [];
mxRadialTreeLayout.prototype.isVertexIgnored = function(vertex)
{
return mxGraphLayout.prototype.isVertexIgnored.apply(this, arguments) ||
this.graph.getConnections(vertex).length == 0;
};
mxRadialTreeLayout.prototype.execute = function(parent, root)
{
this.parent = parent;
this.useBoundingBox = false;
this.edgeRouting = false;
mxCompactTreeLayout.prototype.execute.apply(this, arguments);
var bounds = null;
var rootBounds = this.getVertexBounds(this.root);
this.centerX = rootBounds.x + rootBounds.width / 2;
this.centerY = rootBounds.y + rootBounds.height / 2;
for (var vertex in this.visited)
{
var vertexBounds = this.getVertexBounds(this.visited[vertex]);
bounds = (bounds != null) ? bounds : vertexBounds.clone();
bounds.add(vertexBounds);
}
this.calcRowDims([this.node], 0);
var maxLeftGrad = 0;
var maxRightGrad = 0;
for (var i = 0; i < this.row.length; i++)
{
var leftGrad = (this.centerX - this.rowMinX[i] - this.nodeDistance) / this.rowRadi[i];
var rightGrad = (this.rowMaxX[i] - this.centerX - this.nodeDistance) / this.rowRadi[i];
maxLeftGrad = Math.max (maxLeftGrad, leftGrad);
maxRightGrad = Math.max (maxRightGrad, rightGrad);
}
for (var i = 0; i < this.row.length; i++)
{
var xLeftLimit = this.centerX - this.nodeDistance - maxLeftGrad * this.rowRadi[i];
var xRightLimit = this.centerX + this.nodeDistance + maxRightGrad * this.rowRadi[i];
var fullWidth = xRightLimit - xLeftLimit;
for (var j = 0; j < this.row[i].length; j ++)
{
var row = this.row[i];
var node = row[j];
var vertexBounds = this.getVertexBounds(node.cell);
var xProportion = (vertexBounds.x + vertexBounds.width / 2 - xLeftLimit) / (fullWidth);
var theta = 2 * Math.PI * xProportion;
node.theta = theta;
}
}
for (var i = this.row.length - 2; i >= 0; i--)
{
var row = this.row[i];
for (var j = 0; j < row.length; j++)
{
var node = row[j];
var child = node.child;
var counter = 0;
var totalTheta = 0;
while (child != null)
{
totalTheta += child.theta;
counter++;
child = child.next;
}
if (counter > 0)
{
var averTheta = totalTheta / counter;
if (averTheta > node.theta && j < row.length - 1)
{
var nextTheta = row[j+1].theta;
node.theta = Math.min (averTheta, nextTheta - Math.PI/10);
}
else if (averTheta < node.theta && j > 0 )
{
var lastTheta = row[j-1].theta;
node.theta = Math.max (averTheta, lastTheta + Math.PI/10);
}
}
}
}
for (var i = 0; i < this.row.length; i++)
{
for (var j = 0; j < this.row[i].length; j ++)
{
var row = this.row[i];
var node = row[j];
var vertexBounds = this.getVertexBounds(node.cell);
this.setVertexLocation(node.cell,
this.centerX - vertexBounds.width / 2 + this.rowRadi[i] * Math.cos(node.theta),
this.centerY - vertexBounds.height / 2 + this.rowRadi[i] * Math.sin(node.theta));
}
}
};
mxRadialTreeLayout.prototype.calcRowDims = function(row, rowNum)
{
if (row == null || row.length == 0)
{
return;
}
this.rowMinX[rowNum] = this.centerX;
this.rowMaxX[rowNum] = this.centerX;
this.rowMinCenX[rowNum] = this.centerX;
this.rowMaxCenX[rowNum] = this.centerX;
this.row[rowNum] = [];
var rowHasChildren = false;
for (var i = 0; i < row.length; i++)
{
var child = row[i] != null ? row[i].child : null;
while (child != null)
{
var cell = child.cell;
var vertexBounds = this.getVertexBounds(cell);
this.rowMinX[rowNum] = Math.min(vertexBounds.x, this.rowMinX[rowNum]);
this.rowMaxX[rowNum] = Math.max(vertexBounds.x + vertexBounds.width, this.rowMaxX[rowNum]);
this.rowMinCenX[rowNum] = Math.min(vertexBounds.x + vertexBounds.width / 2, this.rowMinCenX[rowNum]);
this.rowMaxCenX[rowNum] = Math.max(vertexBounds.x + vertexBounds.width / 2, this.rowMaxCenX[rowNum]);
this.rowRadi[rowNum] = vertexBounds.y - this.getVertexBounds(this.root).y;
if (child.child != null)
{
rowHasChildren = true;
}
this.row[rowNum].push(child);
child = child.next;
}
}
if (rowHasChildren)
{
this.calcRowDims(this.row[rowNum], rowNum + 1);
}
};
__mxOutput.mxRadialTreeLayout = typeof mxRadialTreeLayout !== 'undefined' ? mxRadialTreeLayout : undefined;
function mxFastOrganicLayout(graph)
{
mxGraphLayout.call(this, graph);
} mxFastOrganicLayout.prototype = new mxGraphLayout();
mxFastOrganicLayout.prototype.constructor = mxFastOrganicLayout;
mxFastOrganicLayout.prototype.useInputOrigin = true;
mxFastOrganicLayout.prototype.resetEdges = true;
mxFastOrganicLayout.prototype.disableEdgeStyle = true;
mxFastOrganicLayout.prototype.forceConstant = 50;
mxFastOrganicLayout.prototype.forceConstantSquared = 0;
mxFastOrganicLayout.prototype.minDistanceLimit = 2;
mxFastOrganicLayout.prototype.maxDistanceLimit = 500;
mxFastOrganicLayout.prototype.minDistanceLimitSquared = 4;
mxFastOrganicLayout.prototype.initialTemp = 200;
mxFastOrganicLayout.prototype.temperature = 0;
mxFastOrganicLayout.prototype.maxIterations = 0;
mxFastOrganicLayout.prototype.iteration = 0;
mxFastOrganicLayout.prototype.vertexArray;
mxFastOrganicLayout.prototype.dispX;
mxFastOrganicLayout.prototype.dispY;
mxFastOrganicLayout.prototype.cellLocation;
mxFastOrganicLayout.prototype.radius;
mxFastOrganicLayout.prototype.radiusSquared;
mxFastOrganicLayout.prototype.isMoveable;
mxFastOrganicLayout.prototype.neighbours;
mxFastOrganicLayout.prototype.indices;
mxFastOrganicLayout.prototype.allowedToRun = true;
mxFastOrganicLayout.prototype.isVertexIgnored = function(vertex)
{
return mxGraphLayout.prototype.isVertexIgnored.apply(this, arguments) ||
this.graph.getConnections(vertex).length == 0;
};
mxFastOrganicLayout.prototype.execute = function(parent)
{
var model = this.graph.getModel();
this.vertexArray = [];
var cells = this.graph.getChildVertices(parent);
for (var i = 0; i < cells.length; i++)
{
if (!this.isVertexIgnored(cells[i]))
{
this.vertexArray.push(cells[i]);
}
}
var initialBounds = (this.useInputOrigin) ?
this.graph.getBoundingBoxFromGeometry(this.vertexArray) :
null;
var n = this.vertexArray.length;
this.indices = [];
this.dispX = [];
this.dispY = [];
this.cellLocation = [];
this.isMoveable = [];
this.neighbours = [];
this.radius = [];
this.radiusSquared = [];
if (this.forceConstant < 0.001)
{
this.forceConstant = 0.001;
}
this.forceConstantSquared = this.forceConstant * this.forceConstant;
for (var i = 0; i < this.vertexArray.length; i++)
{
var vertex = this.vertexArray[i];
this.cellLocation[i] = [];
var id = mxObjectIdentity.get(vertex);
this.indices[id] = i;
var bounds = this.getVertexBounds(vertex);
var width = bounds.width;
var height = bounds.height;
var x = bounds.x;
var y = bounds.y;
this.cellLocation[i][0] = x + width / 2.0;
this.cellLocation[i][1] = y + height / 2.0;
this.radius[i] = Math.min(width, height);
this.radiusSquared[i] = this.radius[i] * this.radius[i];
}
model.beginUpdate();
try
{
for (var i = 0; i < n; i++)
{
this.dispX[i] = 0;
this.dispY[i] = 0;
this.isMoveable[i] = this.isVertexMovable(this.vertexArray[i]);
var edges = this.graph.getConnections(this.vertexArray[i], parent);
var cells = this.graph.getOpposites(edges, this.vertexArray[i]);
this.neighbours[i] = [];
for (var j = 0; j < cells.length; j++)
{
if (this.resetEdges)
{
this.graph.resetEdge(edges[j]);
}
if (this.disableEdgeStyle)
{
this.setEdgeStyleEnabled(edges[j], false);
}
var id = mxObjectIdentity.get(cells[j]);
var index = this.indices[id];
if (index != null)
{
this.neighbours[i][j] = index;
}
else
{
this.neighbours[i][j] = i;
}
}
}
this.temperature = this.initialTemp;
if (this.maxIterations == 0)
{
this.maxIterations = 20 * Math.sqrt(n);
}
for (this.iteration = 0; this.iteration < this.maxIterations; this.iteration++)
{
if (!this.allowedToRun)
{
return;
}
this.calcRepulsion();
this.calcAttraction();
this.calcPositions();
this.reduceTemperature();
}
var minx = null;
var miny = null;
for (var i = 0; i < this.vertexArray.length; i++)
{
var vertex = this.vertexArray[i];
if (this.isVertexMovable(vertex))
{
var bounds = this.getVertexBounds(vertex);
if (bounds != null)
{
this.cellLocation[i][0] -= bounds.width / 2.0;
this.cellLocation[i][1] -= bounds.height / 2.0;
var x = this.graph.snap(Math.round(this.cellLocation[i][0]));
var y = this.graph.snap(Math.round(this.cellLocation[i][1]));
this.setVertexLocation(vertex, x, y);
if (minx == null)
{
minx = x;
}
else
{
minx = Math.min(minx, x);
}
if (miny == null)
{
miny = y;
}
else
{
miny = Math.min(miny, y);
}
}
}
}
var dx = -(minx || 0) + 1;
var dy = -(miny || 0) + 1;
if (initialBounds != null)
{
dx += initialBounds.x;
dy += initialBounds.y;
}
this.graph.moveCells(this.vertexArray, dx, dy);
}
finally
{
model.endUpdate();
}
};
mxFastOrganicLayout.prototype.calcPositions = function()
{
for (var index = 0; index < this.vertexArray.length; index++)
{
if (this.isMoveable[index])
{
var deltaLength = Math.sqrt(this.dispX[index] * this.dispX[index] +
this.dispY[index] * this.dispY[index]);
if (deltaLength < 0.001)
{
deltaLength = 0.001;
}
var newXDisp = this.dispX[index] / deltaLength
* Math.min(deltaLength, this.temperature);
var newYDisp = this.dispY[index] / deltaLength
* Math.min(deltaLength, this.temperature);
this.dispX[index] = 0;
this.dispY[index] = 0;
this.cellLocation[index][0] += newXDisp;
this.cellLocation[index][1] += newYDisp;
}
}
};
mxFastOrganicLayout.prototype.calcAttraction = function()
{
for (var i = 0; i < this.vertexArray.length; i++)
{
for (var k = 0; k < this.neighbours[i].length; k++)
{
var j = this.neighbours[i][k];
if (i != j &&
this.isMoveable[i] &&
this.isMoveable[j])
{
var xDelta = this.cellLocation[i][0] - this.cellLocation[j][0];
var yDelta = this.cellLocation[i][1] - this.cellLocation[j][1];
var deltaLengthSquared = xDelta * xDelta + yDelta
* yDelta - this.radiusSquared[i] - this.radiusSquared[j];
if (deltaLengthSquared < this.minDistanceLimitSquared)
{
deltaLengthSquared = this.minDistanceLimitSquared;
}
var deltaLength = Math.sqrt(deltaLengthSquared);
var force = (deltaLengthSquared) / this.forceConstant;
var displacementX = (xDelta / deltaLength) * force;
var displacementY = (yDelta / deltaLength) * force;
this.dispX[i] -= displacementX;
this.dispY[i] -= displacementY;
this.dispX[j] += displacementX;
this.dispY[j] += displacementY;
}
}
}
};
mxFastOrganicLayout.prototype.calcRepulsion = function()
{
var vertexCount = this.vertexArray.length;
for (var i = 0; i < vertexCount; i++)
{
for (var j = i; j < vertexCount; j++)
{
if (!this.allowedToRun)
{
return;
}
if (j != i &&
this.isMoveable[i] &&
this.isMoveable[j])
{
var xDelta = this.cellLocation[i][0] - this.cellLocation[j][0];
var yDelta = this.cellLocation[i][1] - this.cellLocation[j][1];
if (xDelta == 0)
{
xDelta = 0.01 + Math.random();
}
if (yDelta == 0)
{
yDelta = 0.01 + Math.random();
}
var deltaLength = Math.sqrt((xDelta * xDelta)
+ (yDelta * yDelta));
var deltaLengthWithRadius = deltaLength - this.radius[i]
- this.radius[j];
if (deltaLengthWithRadius > this.maxDistanceLimit)
{
continue;
}
if (deltaLengthWithRadius < this.minDistanceLimit)
{
deltaLengthWithRadius = this.minDistanceLimit;
}
var force = this.forceConstantSquared / deltaLengthWithRadius;
var displacementX = (xDelta / deltaLength) * force;
var displacementY = (yDelta / deltaLength) * force;
this.dispX[i] += displacementX;
this.dispY[i] += displacementY;
this.dispX[j] -= displacementX;
this.dispY[j] -= displacementY;
}
}
}
};
mxFastOrganicLayout.prototype.reduceTemperature = function()
{
this.temperature = this.initialTemp * (1.0 - this.iteration / this.maxIterations);
};
__mxOutput.mxFastOrganicLayout = typeof mxFastOrganicLayout !== 'undefined' ? mxFastOrganicLayout : undefined;
function mxCircleLayout(graph, radius)
{
mxGraphLayout.call(this, graph);
this.radius = (radius != null) ? radius : 100;
} mxCircleLayout.prototype = new mxGraphLayout();
mxCircleLayout.prototype.constructor = mxCircleLayout;
mxCircleLayout.prototype.radius = null;
mxCircleLayout.prototype.moveCircle = false;
mxCircleLayout.prototype.x0 = 0;
mxCircleLayout.prototype.y0 = 0;
mxCircleLayout.prototype.resetEdges = true;
mxCircleLayout.prototype.disableEdgeStyle = true;
mxCircleLayout.prototype.execute = function(parent)
{
var model = this.graph.getModel();
model.beginUpdate();
try
{
var max = 0;
var top = null;
var left = null;
var vertices = [];
var childCount = model.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
var cell = model.getChildAt(parent, i);
if (!this.isVertexIgnored(cell))
{
vertices.push(cell);
var bounds = this.getVertexBounds(cell);
if (top == null)
{
top = bounds.y;
}
else
{
top = Math.min(top, bounds.y);
}
if (left == null)
{
left = bounds.x;
}
else
{
left = Math.min(left, bounds.x);
}
max = Math.max(max, Math.max(bounds.width, bounds.height));
}
else if (!this.isEdgeIgnored(cell))
{
if (this.resetEdges)
{
this.graph.resetEdge(cell);
}
if (this.disableEdgeStyle)
{
this.setEdgeStyleEnabled(cell, false);
}
}
}
var r = this.getRadius(vertices.length, max);
if (this.moveCircle)
{
left = this.x0;
top = this.y0;
}
this.circle(vertices, r, left, top);
}
finally
{
model.endUpdate();
}
};
mxCircleLayout.prototype.getRadius = function(count, max)
{
return Math.max(count * max / Math.PI, this.radius);
};
mxCircleLayout.prototype.circle = function(vertices, r, left, top)
{
var vertexCount = vertices.length;
var phi = 2 * Math.PI / vertexCount;
for (var i = 0; i < vertexCount; i++)
{
if (this.isVertexMovable(vertices[i]))
{
this.setVertexLocation(vertices[i],
Math.round(left + r + r * Math.sin(i * phi)),
Math.round(top + r + r * Math.cos(i * phi)));
}
}
};
__mxOutput.mxCircleLayout = typeof mxCircleLayout !== 'undefined' ? mxCircleLayout : undefined;
function mxParallelEdgeLayout(graph)
{
mxGraphLayout.call(this, graph);
} mxParallelEdgeLayout.prototype = new mxGraphLayout();
mxParallelEdgeLayout.prototype.constructor = mxParallelEdgeLayout;
mxParallelEdgeLayout.prototype.spacing = 20;
mxParallelEdgeLayout.prototype.checkOverlap = false;
mxParallelEdgeLayout.prototype.execute = function(parent, cells)
{
var lookup = this.findParallels(parent, cells);
this.graph.model.beginUpdate();
try
{
for (var i in lookup)
{
var parallels = lookup[i];
if (parallels.length > 1)
{
this.layout(parallels);
}
}
}
finally
{
this.graph.model.endUpdate();
}
};
mxParallelEdgeLayout.prototype.findParallels = function(parent, cells)
{
var lookup = [];
var addCell = mxUtils.bind(this, function(cell)
{
if (!this.isEdgeIgnored(cell))
{
var id = this.getEdgeId(cell);
if (id != null)
{
if (lookup[id] == null)
{
lookup[id] = [];
}
lookup[id].push(cell);
}
}
});
if (cells != null)
{
for (var i = 0; i < cells.length; i++)
{
addCell(cells[i]);
}
}
else
{
var model = this.graph.getModel();
var childCount = model.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
addCell(model.getChildAt(parent, i));
}
}
return lookup;
};
mxParallelEdgeLayout.prototype.getEdgeId = function(edge)
{
var view = this.graph.getView();
var src = view.getVisibleTerminal(edge, true);
var trg = view.getVisibleTerminal(edge, false);
var pts = '';
if (src != null && trg != null)
{
src = mxObjectIdentity.get(src);
trg = mxObjectIdentity.get(trg);
if (this.checkOverlap)
{
var state = this.graph.view.getState(edge);
if (state != null && state.absolutePoints != null)
{
var tmp = [];
for (var i = 0; i < state.absolutePoints.length; i++)
{
var pt = state.absolutePoints[i];
if (pt != null)
{
tmp.push(pt.x, pt.y);
}
}
pts = tmp.join(',');
}
} return ((src > trg) ? trg + '-' + src : src + '-' + trg) + pts;
}
return null;
};
mxParallelEdgeLayout.prototype.layout = function(parallels)
{
var edge = parallels[0];
var view = this.graph.getView();
var model = this.graph.getModel();
var src = model.getGeometry(view.getVisibleTerminal(edge, true));
var trg = model.getGeometry(view.getVisibleTerminal(edge, false));
if (src == trg)
{
var x0 = src.x + src.width + this.spacing;
var y0 = src.y + src.height / 2;
for (var i = 0; i < parallels.length; i++)
{
this.route(parallels[i], x0, y0);
x0 += this.spacing;
}
}
else if (src != null && trg != null)
{
var scx = src.x + src.width / 2;
var scy = src.y + src.height / 2;
var tcx = trg.x + trg.width / 2;
var tcy = trg.y + trg.height / 2;
var dx = tcx - scx;
var dy = tcy - scy;
var len = Math.sqrt(dx * dx + dy * dy);
if (len > 0)
{
var x0 = scx + dx / 2;
var y0 = scy + dy / 2;
var nx = dy * this.spacing / len;
var ny = dx * this.spacing / len;
x0 += nx * (parallels.length - 1) / 2;
y0 -= ny * (parallels.length - 1) / 2;
for (var i = 0; i < parallels.length; i++)
{
this.route(parallels[i], x0, y0);
x0 -= nx;
y0 += ny;
}
}
}
};
mxParallelEdgeLayout.prototype.route = function(edge, x, y)
{
if (this.graph.isCellMovable(edge))
{
this.setEdgePoints(edge, [new mxPoint(x, y)]);
}
};
__mxOutput.mxParallelEdgeLayout = typeof mxParallelEdgeLayout !== 'undefined' ? mxParallelEdgeLayout : undefined;
function mxCompositeLayout(graph, layouts, master)
{
mxGraphLayout.call(this, graph);
this.layouts = layouts;
this.master = master;
} mxCompositeLayout.prototype = new mxGraphLayout();
mxCompositeLayout.prototype.constructor = mxCompositeLayout;
mxCompositeLayout.prototype.layouts = null;
mxCompositeLayout.prototype.master = null;
mxCompositeLayout.prototype.moveCell = function(cell, x, y)
{
if (this.master != null)
{
this.master.moveCell.apply(this.master, arguments);
}
else
{
this.layouts[0].moveCell.apply(this.layouts[0], arguments);
}
};
mxCompositeLayout.prototype.execute = function(parent)
{
var model = this.graph.getModel();
model.beginUpdate();
try
{
for (var i = 0; i < this.layouts.length; i++)
{
this.layouts[i].execute.apply(this.layouts[i], arguments);
}
}
finally
{
model.endUpdate();
}
};
__mxOutput.mxCompositeLayout = typeof mxCompositeLayout !== 'undefined' ? mxCompositeLayout : undefined;
function mxEdgeLabelLayout(graph, radius)
{
mxGraphLayout.call(this, graph);
} mxEdgeLabelLayout.prototype = new mxGraphLayout();
mxEdgeLabelLayout.prototype.constructor = mxEdgeLabelLayout;
mxEdgeLabelLayout.prototype.execute = function(parent)
{
var view = this.graph.view;
var model = this.graph.getModel();
var edges = [];
var vertices = [];
var childCount = model.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
var cell = model.getChildAt(parent, i);
var state = view.getState(cell);
if (state != null)
{
if (!this.isVertexIgnored(cell))
{
vertices.push(state);
}
else if (!this.isEdgeIgnored(cell))
{
edges.push(state);
}
}
}
this.placeLabels(vertices, edges);
};
mxEdgeLabelLayout.prototype.placeLabels = function(v, e)
{
var model = this.graph.getModel();
model.beginUpdate();
try
{
for (var i = 0; i < e.length; i++)
{
var edge = e[i];
if (edge != null && edge.text != null &&
edge.text.boundingBox != null)
{
for (var j = 0; j < v.length; j++)
{
var vertex = v[j];
if (vertex != null)
{
this.avoid(edge, vertex);
}
}
}
}
}
finally
{
model.endUpdate();
}
};
mxEdgeLabelLayout.prototype.avoid = function(edge, vertex)
{
var model = this.graph.getModel();
var labRect = edge.text.boundingBox;
if (mxUtils.intersects(labRect, vertex))
{
var dy1 = -labRect.y - labRect.height + vertex.y;
var dy2 = -labRect.y + vertex.y + vertex.height;
var dy = (Math.abs(dy1) < Math.abs(dy2)) ? dy1 : dy2;
var dx1 = -labRect.x - labRect.width + vertex.x;
var dx2 = -labRect.x + vertex.x + vertex.width;
var dx = (Math.abs(dx1) < Math.abs(dx2)) ? dx1 : dx2;
if (Math.abs(dx) < Math.abs(dy))
{
dy = 0;
}
else
{
dx = 0;
}
var g = model.getGeometry(edge.cell);
if (g != null)
{
g = g.clone();
if (g.offset != null)
{
g.offset.x += dx;
g.offset.y += dy;
}
else
{
g.offset = new mxPoint(dx, dy);
}
model.setGeometry(edge.cell, g);
}
}
};
__mxOutput.mxEdgeLabelLayout = typeof mxEdgeLabelLayout !== 'undefined' ? mxEdgeLabelLayout : undefined;
function mxGraphAbstractHierarchyCell()
{
this.x = [];
this.y = [];
this.temp = [];
} mxGraphAbstractHierarchyCell.prototype.maxRank = -1;
mxGraphAbstractHierarchyCell.prototype.minRank = -1;
mxGraphAbstractHierarchyCell.prototype.x = null;
mxGraphAbstractHierarchyCell.prototype.y = null;
mxGraphAbstractHierarchyCell.prototype.width = 0;
mxGraphAbstractHierarchyCell.prototype.height = 0;
mxGraphAbstractHierarchyCell.prototype.nextLayerConnectedCells = null;
mxGraphAbstractHierarchyCell.prototype.previousLayerConnectedCells = null;
mxGraphAbstractHierarchyCell.prototype.temp = null;
mxGraphAbstractHierarchyCell.prototype.getNextLayerConnectedCells = function(layer)
{
return null;
};
mxGraphAbstractHierarchyCell.prototype.getPreviousLayerConnectedCells = function(layer)
{
return null;
};
mxGraphAbstractHierarchyCell.prototype.isEdge = function()
{
return false;
};
mxGraphAbstractHierarchyCell.prototype.isVertex = function()
{
return false;
};
mxGraphAbstractHierarchyCell.prototype.getGeneralPurposeVariable = function(layer)
{
return null;
};
mxGraphAbstractHierarchyCell.prototype.setGeneralPurposeVariable = function(layer, value)
{
return null;
};
mxGraphAbstractHierarchyCell.prototype.setX = function(layer, value)
{
if (this.isVertex())
{
this.x[0] = value;
}
else if (this.isEdge())
{
this.x[layer - this.minRank - 1] = value;
}
};
mxGraphAbstractHierarchyCell.prototype.getX = function(layer)
{
if (this.isVertex())
{
return this.x[0];
}
else if (this.isEdge())
{
return this.x[layer - this.minRank - 1];
}
return 0.0;
};
mxGraphAbstractHierarchyCell.prototype.setY = function(layer, value)
{
if (this.isVertex())
{
this.y[0] = value;
}
else if (this.isEdge())
{
this.y[layer -this. minRank - 1] = value;
}
};
__mxOutput.mxGraphAbstractHierarchyCell = typeof mxGraphAbstractHierarchyCell !== 'undefined' ? mxGraphAbstractHierarchyCell : undefined;
function mxGraphHierarchyNode(cell)
{
mxGraphAbstractHierarchyCell.apply(this, arguments);
this.cell = cell;
this.id = mxObjectIdentity.get(cell);
this.connectsAsTarget = [];
this.connectsAsSource = [];
} mxGraphHierarchyNode.prototype = new mxGraphAbstractHierarchyCell();
mxGraphHierarchyNode.prototype.constructor = mxGraphHierarchyNode;
mxGraphHierarchyNode.prototype.cell = null;
mxGraphHierarchyNode.prototype.id = null;
mxGraphHierarchyNode.prototype.connectsAsTarget = null;
mxGraphHierarchyNode.prototype.connectsAsSource = null;
mxGraphHierarchyNode.prototype.hashCode = false;
mxGraphHierarchyNode.prototype.getRankValue = function(layer)
{
return this.maxRank;
};
mxGraphHierarchyNode.prototype.getNextLayerConnectedCells = function(layer)
{
if (this.nextLayerConnectedCells == null)
{
this.nextLayerConnectedCells = [];
this.nextLayerConnectedCells[0] = [];
for (var i = 0; i < this.connectsAsTarget.length; i++)
{
var edge = this.connectsAsTarget[i];
if (edge.maxRank == -1 || edge.maxRank == layer + 1)
{
this.nextLayerConnectedCells[0].push(edge.source);
}
else
{
this.nextLayerConnectedCells[0].push(edge);
}
}
}
return this.nextLayerConnectedCells[0];
};
mxGraphHierarchyNode.prototype.getPreviousLayerConnectedCells = function(layer)
{
if (this.previousLayerConnectedCells == null)
{
this.previousLayerConnectedCells = [];
this.previousLayerConnectedCells[0] = [];
for (var i = 0; i < this.connectsAsSource.length; i++)
{
var edge = this.connectsAsSource[i];
if (edge.minRank == -1 || edge.minRank == layer - 1)
{
this.previousLayerConnectedCells[0].push(edge.target);
}
else
{
this.previousLayerConnectedCells[0].push(edge);
}
}
}
return this.previousLayerConnectedCells[0];
};
mxGraphHierarchyNode.prototype.isVertex = function()
{
return true;
};
mxGraphHierarchyNode.prototype.getGeneralPurposeVariable = function(layer)
{
return this.temp[0];
};
mxGraphHierarchyNode.prototype.setGeneralPurposeVariable = function(layer, value)
{
this.temp[0] = value;
};
mxGraphHierarchyNode.prototype.isAncestor = function(otherNode)
{
if (otherNode != null && this.hashCode != null && otherNode.hashCode != null
&& this.hashCode.length < otherNode.hashCode.length)
{
if (this.hashCode == otherNode.hashCode)
{
return true;
}
if (this.hashCode == null || this.hashCode == null)
{
return false;
}
for (var i = 0; i < this.hashCode.length; i++)
{
if (this.hashCode[i] != otherNode.hashCode[i])
{
return false;
}
}
return true;
}
return false;
};
mxGraphHierarchyNode.prototype.getCoreCell = function()
{
return this.cell;
};
__mxOutput.mxGraphHierarchyNode = typeof mxGraphHierarchyNode !== 'undefined' ? mxGraphHierarchyNode : undefined;
function mxGraphHierarchyEdge(edges)
{
mxGraphAbstractHierarchyCell.apply(this, arguments);
this.edges = edges;
this.ids = [];
for (var i = 0; i < edges.length; i++)
{
this.ids.push(mxObjectIdentity.get(edges[i]));
}
} mxGraphHierarchyEdge.prototype = new mxGraphAbstractHierarchyCell();
mxGraphHierarchyEdge.prototype.constructor = mxGraphHierarchyEdge;
mxGraphHierarchyEdge.prototype.edges = null;
mxGraphHierarchyEdge.prototype.ids = null;
mxGraphHierarchyEdge.prototype.source = null;
mxGraphHierarchyEdge.prototype.target = null;
mxGraphHierarchyEdge.prototype.isReversed = false;
mxGraphHierarchyEdge.prototype.invert = function(layer)
{
var temp = this.source;
this.source = this.target;
this.target = temp;
this.isReversed = !this.isReversed;
};
mxGraphHierarchyEdge.prototype.getNextLayerConnectedCells = function(layer)
{
if (this.nextLayerConnectedCells == null)
{
this.nextLayerConnectedCells = [];
for (var i = 0; i < this.temp.length; i++)
{
this.nextLayerConnectedCells[i] = [];
if (i == this.temp.length - 1)
{
this.nextLayerConnectedCells[i].push(this.source);
}
else
{
this.nextLayerConnectedCells[i].push(this);
}
}
}
return this.nextLayerConnectedCells[layer - this.minRank - 1];
};
mxGraphHierarchyEdge.prototype.getPreviousLayerConnectedCells = function(layer)
{
if (this.previousLayerConnectedCells == null)
{
this.previousLayerConnectedCells = [];
for (var i = 0; i < this.temp.length; i++)
{
this.previousLayerConnectedCells[i] = [];
if (i == 0)
{
this.previousLayerConnectedCells[i].push(this.target);
}
else
{
this.previousLayerConnectedCells[i].push(this);
}
}
}
return this.previousLayerConnectedCells[layer - this.minRank - 1];
};
mxGraphHierarchyEdge.prototype.isEdge = function()
{
return true;
};
mxGraphHierarchyEdge.prototype.getGeneralPurposeVariable = function(layer)
{
return this.temp[layer - this.minRank - 1];
};
mxGraphHierarchyEdge.prototype.setGeneralPurposeVariable = function(layer, value)
{
this.temp[layer - this.minRank - 1] = value;
};
mxGraphHierarchyEdge.prototype.getCoreCell = function()
{
if (this.edges != null && this.edges.length > 0)
{
return this.edges[0];
}
return null;
};
__mxOutput.mxGraphHierarchyEdge = typeof mxGraphHierarchyEdge !== 'undefined' ? mxGraphHierarchyEdge : undefined;
function mxGraphHierarchyModel(layout, vertices, roots, parent, tightenToSource)
{
layout.getGraph();
this.tightenToSource = tightenToSource;
this.roots = roots;
this.parent = parent;
this.vertexMapper = new mxDictionary();
this.edgeMapper = new mxDictionary();
this.maxRank = 0;
var internalVertices = [];
if (vertices == null)
{
vertices = this.graph.getChildVertices(parent);
}
this.maxRank = this.SOURCESCANSTARTRANK;
this.createInternalCells(layout, vertices, internalVertices);
for (var i = 0; i < vertices.length; i++)
{
var edges = internalVertices[i].connectsAsSource;
for (var j = 0; j < edges.length; j++)
{
var internalEdge = edges[j];
var realEdges = internalEdge.edges;
if (realEdges != null && realEdges.length > 0)
{
var realEdge = realEdges[0];
var targetCell = layout.getVisibleTerminal(
realEdge, false);
var internalTargetCell = this.vertexMapper.get(targetCell);
if (internalVertices[i] == internalTargetCell)
{
targetCell = layout.getVisibleTerminal(
realEdge, true);
internalTargetCell = this.vertexMapper.get(targetCell);
}
if (internalTargetCell != null
&& internalVertices[i] != internalTargetCell)
{
internalEdge.target = internalTargetCell;
if (internalTargetCell.connectsAsTarget.length == 0)
{
internalTargetCell.connectsAsTarget = [];
}
if (mxUtils.indexOf(internalTargetCell.connectsAsTarget, internalEdge) < 0)
{
internalTargetCell.connectsAsTarget.push(internalEdge);
}
}
}
}
internalVertices[i].temp[0] = 1;
}
} mxGraphHierarchyModel.prototype.maxRank = null;
mxGraphHierarchyModel.prototype.vertexMapper = null;
mxGraphHierarchyModel.prototype.edgeMapper = null;
mxGraphHierarchyModel.prototype.ranks = null;
mxGraphHierarchyModel.prototype.roots = null;
mxGraphHierarchyModel.prototype.parent = null;
mxGraphHierarchyModel.prototype.dfsCount = 0;
mxGraphHierarchyModel.prototype.SOURCESCANSTARTRANK = 100000000;
mxGraphHierarchyModel.prototype.tightenToSource = false;
mxGraphHierarchyModel.prototype.createInternalCells = function(layout, vertices, internalVertices)
{
var graph = layout.getGraph();
for (var i = 0; i < vertices.length; i++)
{
internalVertices[i] = new mxGraphHierarchyNode(vertices[i]);
this.vertexMapper.put(vertices[i], internalVertices[i]);
var conns = layout.getEdges(vertices[i]);
internalVertices[i].connectsAsSource = [];
for (var j = 0; j < conns.length; j++)
{
var cell = layout.getVisibleTerminal(conns[j], false);
if (cell != vertices[i] && layout.graph.model.isVertex(cell) &&
!layout.isVertexIgnored(cell))
{
var undirectedEdges = layout.getEdgesBetween(vertices[i],
cell, false);
var directedEdges = layout.getEdgesBetween(vertices[i],
cell, true);
if (undirectedEdges != null &&
undirectedEdges.length > 0 &&
this.edgeMapper.get(undirectedEdges[0]) == null &&
directedEdges.length * 2 >= undirectedEdges.length)
{
var internalEdge = new mxGraphHierarchyEdge(undirectedEdges);
for (var k = 0; k < undirectedEdges.length; k++)
{
var edge = undirectedEdges[k];
this.edgeMapper.put(edge, internalEdge);
graph.resetEdge(edge);
if (layout.disableEdgeStyle)
{
layout.setEdgeStyleEnabled(edge, false);
layout.setOrthogonalEdge(edge,true);
}
}
internalEdge.source = internalVertices[i];
if (mxUtils.indexOf(internalVertices[i].connectsAsSource, internalEdge) < 0)
{
internalVertices[i].connectsAsSource.push(internalEdge);
}
}
}
}
internalVertices[i].temp[0] = 0;
}
};
mxGraphHierarchyModel.prototype.initialRank = function()
{
var startNodes = [];
if (this.roots != null)
{
for (var i = 0; i < this.roots.length; i++)
{
var internalNode = this.vertexMapper.get(this.roots[i]);
if (internalNode != null)
{
startNodes.push(internalNode);
}
}
}
var internalNodes = this.vertexMapper.getValues();
for (var i=0; i < internalNodes.length; i++)
{
internalNodes[i].temp[0] = -1;
}
var startNodesCopy = startNodes.slice();
while (startNodes.length > 0)
{
var internalNode = startNodes[0];
var layerDeterminingEdges;
var edgesToBeMarked;
layerDeterminingEdges = internalNode.connectsAsTarget;
edgesToBeMarked = internalNode.connectsAsSource;
var allEdgesScanned = true;
var minimumLayer = this.SOURCESCANSTARTRANK;
for (var i = 0; i < layerDeterminingEdges.length; i++)
{
var internalEdge = layerDeterminingEdges[i];
if (internalEdge.temp[0] == 5270620)
{
var otherNode = internalEdge.source;
minimumLayer = Math.min(minimumLayer, otherNode.temp[0] - 1);
}
else
{
allEdgesScanned = false;
break;
}
}
if (allEdgesScanned)
{
internalNode.temp[0] = minimumLayer;
this.maxRank = Math.min(this.maxRank, minimumLayer);
if (edgesToBeMarked != null)
{
for (var i = 0; i < edgesToBeMarked.length; i++)
{
var internalEdge = edgesToBeMarked[i];
internalEdge.temp[0] = 5270620;
var otherNode = internalEdge.target;
if (otherNode.temp[0] == -1)
{
startNodes.push(otherNode);
otherNode.temp[0] = -2;
}
}
}
startNodes.shift();
}
else
{
var removedCell = startNodes.shift();
startNodes.push(internalNode);
if (removedCell == internalNode && startNodes.length == 1)
{
break;
}
}
}
for (var i=0; i < internalNodes.length; i++)
{
internalNodes[i].temp[0] -= this.maxRank;
}
for ( var i = 0; i < startNodesCopy.length; i++)
{
var internalNode = startNodesCopy[i];
var currentMaxLayer = 0;
var layerDeterminingEdges = internalNode.connectsAsSource;
for ( var j = 0; j < layerDeterminingEdges.length; j++)
{
var internalEdge = layerDeterminingEdges[j];
var otherNode = internalEdge.target;
internalNode.temp[0] = Math.max(currentMaxLayer,
otherNode.temp[0] + 1);
currentMaxLayer = internalNode.temp[0];
}
}
this.maxRank = this.SOURCESCANSTARTRANK - this.maxRank;
};
mxGraphHierarchyModel.prototype.fixRanks = function()
{
var rankList = [];
this.ranks = [];
for (var i = 0; i < this.maxRank + 1; i++)
{
rankList[i] = [];
this.ranks[i] = rankList[i];
}
var rootsArray = null;
if (this.roots != null)
{
var oldRootsArray = this.roots;
rootsArray = [];
for (var i = 0; i < oldRootsArray.length; i++)
{
var cell = oldRootsArray[i];
var internalNode = this.vertexMapper.get(cell);
rootsArray[i] = internalNode;
}
}
this.visit(function(parent, node, edge, layer, seen)
{
if (seen == 0 && node.maxRank < 0 && node.minRank < 0)
{
rankList[node.temp[0]].push(node);
node.maxRank = node.temp[0];
node.minRank = node.temp[0];
node.temp[0] = rankList[node.maxRank].length - 1;
}
if (parent != null && edge != null)
{
var parentToCellRankDifference = parent.maxRank - node.maxRank;
if (parentToCellRankDifference > 1)
{
edge.maxRank = parent.maxRank;
edge.minRank = node.maxRank;
edge.temp = [];
edge.x = [];
edge.y = [];
for (var i = edge.minRank + 1; i < edge.maxRank; i++)
{
rankList[i].push(edge);
edge.setGeneralPurposeVariable(i, rankList[i]
.length - 1);
}
}
}
}, rootsArray, false, null);
};
mxGraphHierarchyModel.prototype.visit = function(visitor, dfsRoots, trackAncestors, seenNodes)
{
if (dfsRoots != null)
{
for (var i = 0; i < dfsRoots.length; i++)
{
var internalNode = dfsRoots[i];
if (internalNode != null)
{
if (seenNodes == null)
{
seenNodes = new Object();
}
if (trackAncestors)
{
internalNode.hashCode = [];
internalNode.hashCode[0] = this.dfsCount;
internalNode.hashCode[1] = i;
this.extendedDfs(null, internalNode, null, visitor, seenNodes,
internalNode.hashCode, i, 0);
}
else
{
this.dfs(null, internalNode, null, visitor, seenNodes, 0);
}
}
}
this.dfsCount++;
}
};
mxGraphHierarchyModel.prototype.dfs = function(parent, root, connectingEdge, visitor, seen, layer)
{
if (root != null)
{
var rootId = root.id;
if (seen[rootId] == null)
{
seen[rootId] = root;
visitor(parent, root, connectingEdge, layer, 0);
var outgoingEdges = root.connectsAsSource.slice();
for (var i = 0; i< outgoingEdges.length; i++)
{
var internalEdge = outgoingEdges[i];
var targetNode = internalEdge.target;
this.dfs(root, targetNode, internalEdge, visitor, seen,
layer + 1);
}
}
else
{
visitor(parent, root, connectingEdge, layer, 1);
}
}
};
mxGraphHierarchyModel.prototype.extendedDfs = function(parent, root, connectingEdge, visitor, seen, ancestors, childHash, layer)
{
if (root != null)
{
if (parent != null)
{
if (root.hashCode == null ||
root.hashCode[0] != parent.hashCode[0])
{
var hashCodeLength = parent.hashCode.length + 1;
root.hashCode = parent.hashCode.slice();
root.hashCode[hashCodeLength - 1] = childHash;
}
}
var rootId = root.id;
if (seen[rootId] == null)
{
seen[rootId] = root;
visitor(parent, root, connectingEdge, layer, 0);
var outgoingEdges = root.connectsAsSource.slice();
for (var i = 0; i < outgoingEdges.length; i++)
{
var internalEdge = outgoingEdges[i];
var targetNode = internalEdge.target;
this.extendedDfs(root, targetNode, internalEdge, visitor, seen,
root.hashCode, i, layer + 1);
}
}
else
{
visitor(parent, root, connectingEdge, layer, 1);
}
}
};
__mxOutput.mxGraphHierarchyModel = typeof mxGraphHierarchyModel !== 'undefined' ? mxGraphHierarchyModel : undefined;
function mxSwimlaneModel(layout, vertices, roots, parent, tightenToSource)
{
layout.getGraph();
this.tightenToSource = tightenToSource;
this.roots = roots;
this.parent = parent;
this.vertexMapper = new mxDictionary();
this.edgeMapper = new mxDictionary();
this.maxRank = 0;
var internalVertices = [];
if (vertices == null)
{
vertices = this.graph.getChildVertices(parent);
}
this.maxRank = this.SOURCESCANSTARTRANK;
this.createInternalCells(layout, vertices, internalVertices);
for (var i = 0; i < vertices.length; i++)
{
var edges = internalVertices[i].connectsAsSource;
for (var j = 0; j < edges.length; j++)
{
var internalEdge = edges[j];
var realEdges = internalEdge.edges;
if (realEdges != null && realEdges.length > 0)
{
var realEdge = realEdges[0];
var targetCell = layout.getVisibleTerminal(
realEdge, false);
var internalTargetCell = this.vertexMapper.get(targetCell);
if (internalVertices[i] == internalTargetCell)
{
targetCell = layout.getVisibleTerminal(
realEdge, true);
internalTargetCell = this.vertexMapper.get(targetCell);
}
if (internalTargetCell != null
&& internalVertices[i] != internalTargetCell)
{
internalEdge.target = internalTargetCell;
if (internalTargetCell.connectsAsTarget.length == 0)
{
internalTargetCell.connectsAsTarget = [];
}
if (mxUtils.indexOf(internalTargetCell.connectsAsTarget, internalEdge) < 0)
{
internalTargetCell.connectsAsTarget.push(internalEdge);
}
}
}
}
internalVertices[i].temp[0] = 1;
}
} mxSwimlaneModel.prototype.maxRank = null;
mxSwimlaneModel.prototype.vertexMapper = null;
mxSwimlaneModel.prototype.edgeMapper = null;
mxSwimlaneModel.prototype.ranks = null;
mxSwimlaneModel.prototype.roots = null;
mxSwimlaneModel.prototype.parent = null;
mxSwimlaneModel.prototype.dfsCount = 0;
mxSwimlaneModel.prototype.SOURCESCANSTARTRANK = 100000000;
mxSwimlaneModel.prototype.tightenToSource = false;
mxSwimlaneModel.prototype.ranksPerGroup = null;
mxSwimlaneModel.prototype.createInternalCells = function(layout, vertices, internalVertices)
{
var graph = layout.getGraph();
var swimlanes = layout.swimlanes;
for (var i = 0; i < vertices.length; i++)
{
internalVertices[i] = new mxGraphHierarchyNode(vertices[i]);
this.vertexMapper.put(vertices[i], internalVertices[i]);
internalVertices[i].swimlaneIndex = -1;
for (var ii = 0; ii < swimlanes.length; ii++)
{
if (graph.model.getParent(vertices[i]) == swimlanes[ii])
{
internalVertices[i].swimlaneIndex = ii;
break;
}
}
var conns = layout.getEdges(vertices[i]);
internalVertices[i].connectsAsSource = [];
for (var j = 0; j < conns.length; j++)
{
var cell = layout.getVisibleTerminal(conns[j], false);
if (cell != vertices[i] && layout.graph.model.isVertex(cell) &&
!layout.isVertexIgnored(cell))
{
var undirectedEdges = layout.getEdgesBetween(vertices[i],
cell, false);
var directedEdges = layout.getEdgesBetween(vertices[i],
cell, true);
if (undirectedEdges != null &&
undirectedEdges.length > 0 &&
this.edgeMapper.get(undirectedEdges[0]) == null &&
directedEdges.length * 2 >= undirectedEdges.length)
{
var internalEdge = new mxGraphHierarchyEdge(undirectedEdges);
for (var k = 0; k < undirectedEdges.length; k++)
{
var edge = undirectedEdges[k];
this.edgeMapper.put(edge, internalEdge);
graph.resetEdge(edge);
if (layout.disableEdgeStyle)
{
layout.setEdgeStyleEnabled(edge, false);
layout.setOrthogonalEdge(edge,true);
}
}
internalEdge.source = internalVertices[i];
if (mxUtils.indexOf(internalVertices[i].connectsAsSource, internalEdge) < 0)
{
internalVertices[i].connectsAsSource.push(internalEdge);
}
}
}
}
internalVertices[i].temp[0] = 0;
}
};
mxSwimlaneModel.prototype.initialRank = function()
{
this.ranksPerGroup = [];
var startNodes = [];
var seen = new Object();
if (this.roots != null)
{
for (var i = 0; i < this.roots.length; i++)
{
var internalNode = this.vertexMapper.get(this.roots[i]);
this.maxChainDfs(null, internalNode, null, seen, 0);
if (internalNode != null)
{
startNodes.push(internalNode);
}
}
}
var lowerRank = [];
var upperRank = [];
for (var i = this.ranksPerGroup.length - 1; i >= 0; i--)
{
if (i == this.ranksPerGroup.length - 1)
{
lowerRank[i] = 0;
}
else
{
lowerRank[i] = upperRank[i+1] + 1;
}
upperRank[i] = lowerRank[i] + this.ranksPerGroup[i];
}
this.maxRank = upperRank[0];
var internalNodes = this.vertexMapper.getValues();
for (var i=0; i < internalNodes.length; i++)
{
internalNodes[i].temp[0] = -1;
}
while (startNodes.length > 0)
{
var internalNode = startNodes[0];
var layerDeterminingEdges;
var edgesToBeMarked;
layerDeterminingEdges = internalNode.connectsAsTarget;
edgesToBeMarked = internalNode.connectsAsSource;
var allEdgesScanned = true;
var minimumLayer = upperRank[0];
for (var i = 0; i < layerDeterminingEdges.length; i++)
{
var internalEdge = layerDeterminingEdges[i];
if (internalEdge.temp[0] == 5270620)
{
var otherNode = internalEdge.source;
minimumLayer = Math.min(minimumLayer, otherNode.temp[0] - 1);
}
else
{
allEdgesScanned = false;
break;
}
}
if (allEdgesScanned)
{
if (minimumLayer > upperRank[internalNode.swimlaneIndex])
{
minimumLayer = upperRank[internalNode.swimlaneIndex];
}
internalNode.temp[0] = minimumLayer;
if (edgesToBeMarked != null)
{
for (var i = 0; i < edgesToBeMarked.length; i++)
{
var internalEdge = edgesToBeMarked[i];
internalEdge.temp[0] = 5270620;
var otherNode = internalEdge.target;
if (otherNode.temp[0] == -1)
{
startNodes.push(otherNode);
otherNode.temp[0] = -2;
}
}
}
startNodes.shift();
}
else
{
var removedCell = startNodes.shift();
startNodes.push(internalNode);
if (removedCell == internalNode && startNodes.length == 1)
{
break;
}
}
}
};
mxSwimlaneModel.prototype.maxChainDfs = function(parent, root, connectingEdge, seen, chainCount)
{
if (root != null)
{
var rootId = mxCellPath.create(root.cell);
if (seen[rootId] == null)
{
seen[rootId] = root;
var slIndex = root.swimlaneIndex;
if (this.ranksPerGroup[slIndex] == null || this.ranksPerGroup[slIndex] < chainCount)
{
this.ranksPerGroup[slIndex] = chainCount;
}
var outgoingEdges = root.connectsAsSource.slice();
for (var i = 0; i < outgoingEdges.length; i++)
{
var internalEdge = outgoingEdges[i];
var targetNode = internalEdge.target;
if (root.swimlaneIndex < targetNode.swimlaneIndex)
{
this.maxChainDfs(root, targetNode, internalEdge, mxUtils.clone(seen, null , true), 0);
}
else if (root.swimlaneIndex == targetNode.swimlaneIndex)
{
this.maxChainDfs(root, targetNode, internalEdge, mxUtils.clone(seen, null , true), chainCount + 1);
}
}
}
}
};
mxSwimlaneModel.prototype.fixRanks = function()
{
var rankList = [];
this.ranks = [];
for (var i = 0; i < this.maxRank + 1; i++)
{
rankList[i] = [];
this.ranks[i] = rankList[i];
}
var rootsArray = null;
if (this.roots != null)
{
var oldRootsArray = this.roots;
rootsArray = [];
for (var i = 0; i < oldRootsArray.length; i++)
{
var cell = oldRootsArray[i];
var internalNode = this.vertexMapper.get(cell);
rootsArray[i] = internalNode;
}
}
this.visit(function(parent, node, edge, layer, seen)
{
if (seen == 0 && node.maxRank < 0 && node.minRank < 0)
{
rankList[node.temp[0]].push(node);
node.maxRank = node.temp[0];
node.minRank = node.temp[0];
node.temp[0] = rankList[node.maxRank].length - 1;
}
if (parent != null && edge != null)
{
var parentToCellRankDifference = parent.maxRank - node.maxRank;
if (parentToCellRankDifference > 1)
{
edge.maxRank = parent.maxRank;
edge.minRank = node.maxRank;
edge.temp = [];
edge.x = [];
edge.y = [];
for (var i = edge.minRank + 1; i < edge.maxRank; i++)
{
rankList[i].push(edge);
edge.setGeneralPurposeVariable(i, rankList[i]
.length - 1);
}
}
}
}, rootsArray, false, null);
};
mxSwimlaneModel.prototype.visit = function(visitor, dfsRoots, trackAncestors, seenNodes)
{
if (dfsRoots != null)
{
for (var i = 0; i < dfsRoots.length; i++)
{
var internalNode = dfsRoots[i];
if (internalNode != null)
{
if (seenNodes == null)
{
seenNodes = new Object();
}
if (trackAncestors)
{
internalNode.hashCode = [];
internalNode.hashCode[0] = this.dfsCount;
internalNode.hashCode[1] = i;
this.extendedDfs(null, internalNode, null, visitor, seenNodes,
internalNode.hashCode, i, 0);
}
else
{
this.dfs(null, internalNode, null, visitor, seenNodes, 0);
}
}
}
this.dfsCount++;
}
};
mxSwimlaneModel.prototype.dfs = function(parent, root, connectingEdge, visitor, seen, layer)
{
if (root != null)
{
var rootId = root.id;
if (seen[rootId] == null)
{
seen[rootId] = root;
visitor(parent, root, connectingEdge, layer, 0);
var outgoingEdges = root.connectsAsSource.slice();
for (var i = 0; i< outgoingEdges.length; i++)
{
var internalEdge = outgoingEdges[i];
var targetNode = internalEdge.target;
this.dfs(root, targetNode, internalEdge, visitor, seen,
layer + 1);
}
}
else
{
visitor(parent, root, connectingEdge, layer, 1);
}
}
};
mxSwimlaneModel.prototype.extendedDfs = function(parent, root, connectingEdge, visitor, seen, ancestors, childHash, layer)
{
if (root != null)
{
if (parent != null)
{
if (root.hashCode == null ||
root.hashCode[0] != parent.hashCode[0])
{
var hashCodeLength = parent.hashCode.length + 1;
root.hashCode = parent.hashCode.slice();
root.hashCode[hashCodeLength - 1] = childHash;
}
}
var rootId = root.id;
if (seen[rootId] == null)
{
seen[rootId] = root;
visitor(parent, root, connectingEdge, layer, 0);
var outgoingEdges = root.connectsAsSource.slice();
var incomingEdges = root.connectsAsTarget.slice();
for (var i = 0; i < outgoingEdges.length; i++)
{
var internalEdge = outgoingEdges[i];
var targetNode = internalEdge.target;
if (root.swimlaneIndex <= targetNode.swimlaneIndex)
{
this.extendedDfs(root, targetNode, internalEdge, visitor, seen,
root.hashCode, i, layer + 1);
}
}
for (var i = 0; i < incomingEdges.length; i++)
{
var internalEdge = incomingEdges[i];
var targetNode = internalEdge.source;
if (root.swimlaneIndex < targetNode.swimlaneIndex)
{
this.extendedDfs(root, targetNode, internalEdge, visitor, seen,
root.hashCode, i, layer + 1);
}
}
}
else
{
visitor(parent, root, connectingEdge, layer, 1);
}
}
};
__mxOutput.mxSwimlaneModel = typeof mxSwimlaneModel !== 'undefined' ? mxSwimlaneModel : undefined;
function mxHierarchicalLayoutStage() { } mxHierarchicalLayoutStage.prototype.execute = function(parent) { };
__mxOutput.mxHierarchicalLayoutStage = typeof mxHierarchicalLayoutStage !== 'undefined' ? mxHierarchicalLayoutStage : undefined;
function mxMedianHybridCrossingReduction(layout)
{
this.layout = layout;
} mxMedianHybridCrossingReduction.prototype = new mxHierarchicalLayoutStage();
mxMedianHybridCrossingReduction.prototype.constructor = mxMedianHybridCrossingReduction;
mxMedianHybridCrossingReduction.prototype.layout = null;
mxMedianHybridCrossingReduction.prototype.maxIterations = 24;
mxMedianHybridCrossingReduction.prototype.nestedBestRanks = null;
mxMedianHybridCrossingReduction.prototype.currentBestCrossings = 0;
mxMedianHybridCrossingReduction.prototype.iterationsWithoutImprovement = 0;
mxMedianHybridCrossingReduction.prototype.maxNoImprovementIterations = 2;
mxMedianHybridCrossingReduction.prototype.execute = function(parent)
{
var model = this.layout.getModel();
this.nestedBestRanks = [];
for (var i = 0; i < model.ranks.length; i++)
{
this.nestedBestRanks[i] = model.ranks[i].slice();
}
var iterationsWithoutImprovement = 0;
var currentBestCrossings = this.calculateCrossings(model);
for (var i = 0; i < this.maxIterations &&
iterationsWithoutImprovement < this.maxNoImprovementIterations; i++)
{
this.weightedMedian(i, model);
this.transpose(i, model);
var candidateCrossings = this.calculateCrossings(model);
if (candidateCrossings < currentBestCrossings)
{
currentBestCrossings = candidateCrossings;
iterationsWithoutImprovement = 0;
for (var j = 0; j < this.nestedBestRanks.length; j++)
{
var rank = model.ranks[j];
for (var k = 0; k < rank.length; k++)
{
var cell = rank[k];
this.nestedBestRanks[j][cell.getGeneralPurposeVariable(j)] = cell;
}
}
}
else
{
iterationsWithoutImprovement++;
for (var j = 0; j < this.nestedBestRanks.length; j++)
{
var rank = model.ranks[j];
for (var k = 0; k < rank.length; k++)
{
var cell = rank[k];
cell.setGeneralPurposeVariable(j, k);
}
}
}
if (currentBestCrossings == 0)
{
break;
}
}
var ranks = [];
var rankList = [];
for (var i = 0; i < model.maxRank + 1; i++)
{
rankList[i] = [];
ranks[i] = rankList[i];
}
for (var i = 0; i < this.nestedBestRanks.length; i++)
{
for (var j = 0; j < this.nestedBestRanks[i].length; j++)
{
rankList[i].push(this.nestedBestRanks[i][j]);
}
}
model.ranks = ranks;
};
mxMedianHybridCrossingReduction.prototype.calculateCrossings = function(model)
{
var numRanks = model.ranks.length;
var totalCrossings = 0;
for (var i = 1; i < numRanks; i++)
{
totalCrossings += this.calculateRankCrossing(i, model);
}
return totalCrossings;
};
mxMedianHybridCrossingReduction.prototype.calculateRankCrossing = function(i, model)
{
var totalCrossings = 0;
var rank = model.ranks[i];
var previousRank = model.ranks[i - 1];
var tmpIndices = [];
for (var j = 0; j < rank.length; j++)
{
var node = rank[j];
var rankPosition = node.getGeneralPurposeVariable(i);
var connectedCells = node.getPreviousLayerConnectedCells(i);
var nodeIndices = [];
for (var k = 0; k < connectedCells.length; k++)
{
var connectedNode = connectedCells[k];
var otherCellRankPosition = connectedNode.getGeneralPurposeVariable(i - 1);
nodeIndices.push(otherCellRankPosition);
}
nodeIndices.sort(function(x, y) { return x - y; });
tmpIndices[rankPosition] = nodeIndices;
}
var indices = [];
for (var j = 0; j < tmpIndices.length; j++)
{
indices = indices.concat(tmpIndices[j]);
}
var firstIndex = 1;
while (firstIndex < previousRank.length)
{
firstIndex <<= 1;
}
var treeSize = 2 * firstIndex - 1;
firstIndex -= 1;
var tree = [];
for (var j = 0; j < treeSize; ++j)
{
tree[j] = 0;
}
for (var j = 0; j < indices.length; j++)
{
var index = indices[j];
var treeIndex = index + firstIndex;
++tree[treeIndex];
while (treeIndex > 0)
{
if (treeIndex % 2)
{
totalCrossings += tree[treeIndex + 1];
}
treeIndex = (treeIndex - 1) >> 1;
++tree[treeIndex];
}
}
return totalCrossings;
};
mxMedianHybridCrossingReduction.prototype.transpose = function(mainLoopIteration, model)
{
var improved = true;
var count = 0;
var maxCount = 10;
while (improved && count++ < maxCount)
{
var nudge = mainLoopIteration % 2 == 1 && count % 2 == 1;
improved = false;
for (var i = 0; i < model.ranks.length; i++)
{
var rank = model.ranks[i];
var orderedCells = [];
for (var j = 0; j < rank.length; j++)
{
var cell = rank[j];
var tempRank = cell.getGeneralPurposeVariable(i);
if (tempRank < 0)
{
tempRank = j;
}
orderedCells[tempRank] = cell;
}
var leftCellAboveConnections = null;
var leftCellBelowConnections = null;
var rightCellAboveConnections = null;
var rightCellBelowConnections = null;
var leftAbovePositions = null;
var leftBelowPositions = null;
var rightAbovePositions = null;
var rightBelowPositions = null;
var leftCell = null;
var rightCell = null;
for (var j = 0; j < (rank.length - 1); j++)
{
if (j == 0)
{
leftCell = orderedCells[j];
leftCellAboveConnections = leftCell
.getNextLayerConnectedCells(i);
leftCellBelowConnections = leftCell
.getPreviousLayerConnectedCells(i);
leftAbovePositions = [];
leftBelowPositions = [];
for (var k = 0; k < leftCellAboveConnections.length; k++)
{
leftAbovePositions[k] = leftCellAboveConnections[k].getGeneralPurposeVariable(i + 1);
}
for (var k = 0; k < leftCellBelowConnections.length; k++)
{
leftBelowPositions[k] = leftCellBelowConnections[k].getGeneralPurposeVariable(i - 1);
}
}
else
{
leftCellAboveConnections = rightCellAboveConnections;
leftCellBelowConnections = rightCellBelowConnections;
leftAbovePositions = rightAbovePositions;
leftBelowPositions = rightBelowPositions;
leftCell = rightCell;
}
rightCell = orderedCells[j + 1];
rightCellAboveConnections = rightCell
.getNextLayerConnectedCells(i);
rightCellBelowConnections = rightCell
.getPreviousLayerConnectedCells(i);
rightAbovePositions = [];
rightBelowPositions = [];
for (var k = 0; k < rightCellAboveConnections.length; k++)
{
rightAbovePositions[k] = rightCellAboveConnections[k].getGeneralPurposeVariable(i + 1);
}
for (var k = 0; k < rightCellBelowConnections.length; k++)
{
rightBelowPositions[k] = rightCellBelowConnections[k].getGeneralPurposeVariable(i - 1);
}
var totalCurrentCrossings = 0;
var totalSwitchedCrossings = 0;
for (var k = 0; k < leftAbovePositions.length; k++)
{
for (var ik = 0; ik < rightAbovePositions.length; ik++)
{
if (leftAbovePositions[k] > rightAbovePositions[ik])
{
totalCurrentCrossings++;
}
if (leftAbovePositions[k] < rightAbovePositions[ik])
{
totalSwitchedCrossings++;
}
}
}
for (var k = 0; k < leftBelowPositions.length; k++)
{
for (var ik = 0; ik < rightBelowPositions.length; ik++)
{
if (leftBelowPositions[k] > rightBelowPositions[ik])
{
totalCurrentCrossings++;
}
if (leftBelowPositions[k] < rightBelowPositions[ik])
{
totalSwitchedCrossings++;
}
}
}
if ((totalSwitchedCrossings < totalCurrentCrossings) ||
(totalSwitchedCrossings == totalCurrentCrossings &&
nudge))
{
var temp = leftCell.getGeneralPurposeVariable(i);
leftCell.setGeneralPurposeVariable(i, rightCell
.getGeneralPurposeVariable(i));
rightCell.setGeneralPurposeVariable(i, temp);
rightCellAboveConnections = leftCellAboveConnections;
rightCellBelowConnections = leftCellBelowConnections;
rightAbovePositions = leftAbovePositions;
rightBelowPositions = leftBelowPositions;
rightCell = leftCell;
if (!nudge)
{
improved = true;
}
}
}
}
}
};
mxMedianHybridCrossingReduction.prototype.weightedMedian = function(iteration, model)
{
var downwardSweep = (iteration % 2 == 0);
if (downwardSweep)
{
for (var j = model.maxRank - 1; j >= 0; j--)
{
this.medianRank(j, downwardSweep);
}
}
else
{
for (var j = 1; j < model.maxRank; j++)
{
this.medianRank(j, downwardSweep);
}
}
};
mxMedianHybridCrossingReduction.prototype.medianRank = function(rankValue, downwardSweep)
{
var numCellsForRank = this.nestedBestRanks[rankValue].length;
var medianValues = [];
var reservedPositions = [];
for (var i = 0; i < numCellsForRank; i++)
{
var cell = this.nestedBestRanks[rankValue][i];
var sorterEntry = new MedianCellSorter();
sorterEntry.cell = cell;
var nextLevelConnectedCells;
if (downwardSweep)
{
nextLevelConnectedCells = cell
.getNextLayerConnectedCells(rankValue);
}
else
{
nextLevelConnectedCells = cell
.getPreviousLayerConnectedCells(rankValue);
}
var nextRankValue;
if (downwardSweep)
{
nextRankValue = rankValue + 1;
}
else
{
nextRankValue = rankValue - 1;
}
if (nextLevelConnectedCells != null
&& nextLevelConnectedCells.length != 0)
{
sorterEntry.medianValue = this.medianValue(
nextLevelConnectedCells, nextRankValue);
medianValues.push(sorterEntry);
}
else
{
reservedPositions[cell.getGeneralPurposeVariable(rankValue)] = true;
}
}
medianValues.sort(MedianCellSorter.prototype.compare);
for (var i = 0; i < numCellsForRank; i++)
{
if (reservedPositions[i] == null)
{
var cell = medianValues.shift().cell;
cell.setGeneralPurposeVariable(rankValue, i);
}
}
};
mxMedianHybridCrossingReduction.prototype.medianValue = function(connectedCells, rankValue)
{
var medianValues = [];
var arrayCount = 0;
for (var i = 0; i < connectedCells.length; i++)
{
var cell = connectedCells[i];
medianValues[arrayCount++] = cell.getGeneralPurposeVariable(rankValue);
}
medianValues.sort(function(a,b){return a - b;});
if (arrayCount % 2 == 1)
{
return medianValues[Math.floor(arrayCount / 2)];
}
else if (arrayCount == 2)
{
return ((medianValues[0] + medianValues[1]) / 2.0);
}
else
{
var medianPoint = arrayCount / 2;
var leftMedian = medianValues[medianPoint - 1] - medianValues[0];
var rightMedian = medianValues[arrayCount - 1]
- medianValues[medianPoint];
return (medianValues[medianPoint - 1] * rightMedian + medianValues[medianPoint]
* leftMedian)
/ (leftMedian + rightMedian);
}
};
function MedianCellSorter()
{
} MedianCellSorter.prototype.medianValue = 0;
MedianCellSorter.prototype.cell = false;
MedianCellSorter.prototype.compare = function(a, b)
{
if (a != null && b != null)
{
if (b.medianValue > a.medianValue)
{
return -1;
}
else if (b.medianValue < a.medianValue)
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
};
__mxOutput.mxMedianHybridCrossingReduction = typeof mxMedianHybridCrossingReduction !== 'undefined' ? mxMedianHybridCrossingReduction : undefined;
function mxMinimumCycleRemover(layout)
{
this.layout = layout;
} mxMinimumCycleRemover.prototype = new mxHierarchicalLayoutStage();
mxMinimumCycleRemover.prototype.constructor = mxMinimumCycleRemover;
mxMinimumCycleRemover.prototype.layout = null;
mxMinimumCycleRemover.prototype.execute = function(parent)
{
var model = this.layout.getModel();
var seenNodes = new Object();
var unseenNodesArray = model.vertexMapper.getValues();
var unseenNodes = new Object();
for (var i = 0; i < unseenNodesArray.length; i++)
{
unseenNodes[unseenNodesArray[i].id] = unseenNodesArray[i];
}
var rootsArray = null;
if (model.roots != null)
{
var modelRoots = model.roots;
rootsArray = [];
for (var i = 0; i < modelRoots.length; i++)
{
rootsArray[i] = model.vertexMapper.get(modelRoots[i]);
}
}
model.visit(function(parent, node, connectingEdge, layer, seen)
{
if (node.isAncestor(parent))
{
connectingEdge.invert();
mxUtils.remove(connectingEdge, parent.connectsAsSource);
parent.connectsAsTarget.push(connectingEdge);
mxUtils.remove(connectingEdge, node.connectsAsTarget);
node.connectsAsSource.push(connectingEdge);
}
seenNodes[node.id] = node;
delete unseenNodes[node.id];
}, rootsArray, true, null);
var seenNodesCopy = mxUtils.clone(seenNodes, null, true);
model.visit(function(parent, node, connectingEdge, layer, seen)
{
if (node.isAncestor(parent))
{
connectingEdge.invert();
mxUtils.remove(connectingEdge, parent.connectsAsSource);
node.connectsAsSource.push(connectingEdge);
parent.connectsAsTarget.push(connectingEdge);
mxUtils.remove(connectingEdge, node.connectsAsTarget);
}
seenNodes[node.id] = node;
delete unseenNodes[node.id];
}, unseenNodes, true, seenNodesCopy);
};
__mxOutput.mxMinimumCycleRemover = typeof mxMinimumCycleRemover !== 'undefined' ? mxMinimumCycleRemover : undefined;
function mxCoordinateAssignment(layout, intraCellSpacing, interRankCellSpacing,
orientation, initialX, parallelEdgeSpacing)
{
this.layout = layout;
this.intraCellSpacing = intraCellSpacing;
this.interRankCellSpacing = interRankCellSpacing;
this.orientation = orientation;
this.initialX = initialX;
this.parallelEdgeSpacing = parallelEdgeSpacing;
} mxCoordinateAssignment.prototype = new mxHierarchicalLayoutStage();
mxCoordinateAssignment.prototype.constructor = mxCoordinateAssignment;
mxCoordinateAssignment.prototype.layout = null;
mxCoordinateAssignment.prototype.intraCellSpacing = 30;
mxCoordinateAssignment.prototype.interRankCellSpacing = 100;
mxCoordinateAssignment.prototype.parallelEdgeSpacing = 10;
mxCoordinateAssignment.prototype.maxIterations = 8;
mxCoordinateAssignment.prototype.prefHozEdgeSep = 5;
mxCoordinateAssignment.prototype.prefVertEdgeOff = 2;
mxCoordinateAssignment.prototype.minEdgeJetty = 12;
mxCoordinateAssignment.prototype.channelBuffer = 4;
mxCoordinateAssignment.prototype.jettyPositions = null;
mxCoordinateAssignment.prototype.orientation = mxConstants.DIRECTION_NORTH;
mxCoordinateAssignment.prototype.initialX = null;
mxCoordinateAssignment.prototype.limitX = null;
mxCoordinateAssignment.prototype.currentXDelta = null;
mxCoordinateAssignment.prototype.widestRank = null;
mxCoordinateAssignment.prototype.rankTopY = null;
mxCoordinateAssignment.prototype.rankBottomY = null;
mxCoordinateAssignment.prototype.widestRankValue = null;
mxCoordinateAssignment.prototype.rankWidths = null;
mxCoordinateAssignment.prototype.rankY = null;
mxCoordinateAssignment.prototype.fineTuning = true;
mxCoordinateAssignment.prototype.nextLayerConnectedCache = null;
mxCoordinateAssignment.prototype.previousLayerConnectedCache = null;
mxCoordinateAssignment.prototype.groupPadding = 10;
mxCoordinateAssignment.prototype.printStatus = function()
{
var model = this.layout.getModel();
mxLog.show();
mxLog.writeln('======Coord assignment debug=======');
for (var j = 0; j < model.ranks.length; j++)
{
mxLog.write('Rank ', j, ' : ' );
var rank = model.ranks[j];
for (var k = 0; k < rank.length; k++)
{
var cell = rank[k];
mxLog.write(cell.getGeneralPurposeVariable(j), ' ');
}
mxLog.writeln();
}
mxLog.writeln('====================================');
};
mxCoordinateAssignment.prototype.execute = function(parent)
{
this.jettyPositions = Object();
var model = this.layout.getModel();
this.currentXDelta = 0.0;
this.initialCoords(this.layout.getGraph(), model);
if (this.fineTuning)
{
this.minNode(model);
}
var bestXDelta = 100000000.0;
if (this.fineTuning)
{
for (var i = 0; i < this.maxIterations; i++)
{
if (i != 0)
{
this.medianPos(i, model);
this.minNode(model);
}
if (this.currentXDelta < bestXDelta)
{
for (var j = 0; j < model.ranks.length; j++)
{
var rank = model.ranks[j];
for (var k = 0; k < rank.length; k++)
{
var cell = rank[k];
cell.setX(j, cell.getGeneralPurposeVariable(j));
}
}
bestXDelta = this.currentXDelta;
}
else
{
for (var j = 0; j < model.ranks.length; j++)
{
var rank = model.ranks[j];
for (var k = 0; k < rank.length; k++)
{
var cell = rank[k];
cell.setGeneralPurposeVariable(j, cell.getX(j));
}
}
}
this.minPath(this.layout.getGraph(), model);
this.currentXDelta = 0;
}
}
this.setCellLocations(this.layout.getGraph(), model);
};
mxCoordinateAssignment.prototype.minNode = function(model)
{
var nodeList = [];
var map = new mxDictionary();
var rank = [];
for (var i = 0; i <= model.maxRank; i++)
{
rank[i] = model.ranks[i];
for (var j = 0; j < rank[i].length; j++)
{
var node = rank[i][j];
var nodeWrapper = new WeightedCellSorter(node, i);
nodeWrapper.rankIndex = j;
nodeWrapper.visited = true;
nodeList.push(nodeWrapper);
map.put(node, nodeWrapper);
}
}
var maxTries = nodeList.length * 10;
var count = 0;
var tolerance = 1;
while (nodeList.length > 0 && count <= maxTries)
{
var cellWrapper = nodeList.shift();
var cell = cellWrapper.cell;
var rankValue = cellWrapper.weightedValue;
var rankIndex = parseInt(cellWrapper.rankIndex);
var nextLayerConnectedCells = cell.getNextLayerConnectedCells(rankValue);
var previousLayerConnectedCells = cell.getPreviousLayerConnectedCells(rankValue);
var numNextLayerConnected = nextLayerConnectedCells.length;
var numPreviousLayerConnected = previousLayerConnectedCells.length;
var medianNextLevel = this.medianXValue(nextLayerConnectedCells,
rankValue + 1);
var medianPreviousLevel = this.medianXValue(previousLayerConnectedCells,
rankValue - 1);
var numConnectedNeighbours = numNextLayerConnected
+ numPreviousLayerConnected;
var currentPosition = cell.getGeneralPurposeVariable(rankValue);
var cellMedian = currentPosition;
if (numConnectedNeighbours > 0)
{
cellMedian = (medianNextLevel * numNextLayerConnected + medianPreviousLevel
* numPreviousLayerConnected)
/ numConnectedNeighbours;
}
var positionChanged = false;
if (cellMedian < currentPosition - tolerance)
{
if (rankIndex == 0)
{
cell.setGeneralPurposeVariable(rankValue, cellMedian);
positionChanged = true;
}
else
{
var leftCell = rank[rankValue][rankIndex - 1];
var leftLimit = leftCell
.getGeneralPurposeVariable(rankValue);
leftLimit = leftLimit + leftCell.width / 2
+ this.intraCellSpacing + cell.width / 2;
if (leftLimit < cellMedian)
{
cell.setGeneralPurposeVariable(rankValue, cellMedian);
positionChanged = true;
}
else if (leftLimit < cell
.getGeneralPurposeVariable(rankValue)
- tolerance)
{
cell.setGeneralPurposeVariable(rankValue, leftLimit);
positionChanged = true;
}
}
}
else if (cellMedian > currentPosition + tolerance)
{
var rankSize = rank[rankValue].length;
if (rankIndex == rankSize - 1)
{
cell.setGeneralPurposeVariable(rankValue, cellMedian);
positionChanged = true;
}
else
{
var rightCell = rank[rankValue][rankIndex + 1];
var rightLimit = rightCell
.getGeneralPurposeVariable(rankValue);
rightLimit = rightLimit - rightCell.width / 2
- this.intraCellSpacing - cell.width / 2;
if (rightLimit > cellMedian)
{
cell.setGeneralPurposeVariable(rankValue, cellMedian);
positionChanged = true;
}
else if (rightLimit > cell
.getGeneralPurposeVariable(rankValue)
+ tolerance)
{
cell.setGeneralPurposeVariable(rankValue, rightLimit);
positionChanged = true;
}
}
}
if (positionChanged)
{
for (var i = 0; i < nextLayerConnectedCells.length; i++)
{
var connectedCell = nextLayerConnectedCells[i];
var connectedCellWrapper = map.get(connectedCell);
if (connectedCellWrapper != null)
{
if (connectedCellWrapper.visited == false)
{
connectedCellWrapper.visited = true;
nodeList.push(connectedCellWrapper);
}
}
}
for (var i = 0; i < previousLayerConnectedCells.length; i++)
{
var connectedCell = previousLayerConnectedCells[i];
var connectedCellWrapper = map.get(connectedCell);
if (connectedCellWrapper != null)
{
if (connectedCellWrapper.visited == false)
{
connectedCellWrapper.visited = true;
nodeList.push(connectedCellWrapper);
}
}
}
}
cellWrapper.visited = false;
count++;
}
};
mxCoordinateAssignment.prototype.medianPos = function(i, model)
{
var downwardSweep = (i % 2 == 0);
if (downwardSweep)
{
for (var j = model.maxRank; j > 0; j--)
{
this.rankMedianPosition(j - 1, model, j);
}
}
else
{
for (var j = 0; j < model.maxRank - 1; j++)
{
this.rankMedianPosition(j + 1, model, j);
}
}
};
mxCoordinateAssignment.prototype.rankMedianPosition = function(rankValue, model, nextRankValue)
{
var rank = model.ranks[rankValue];
var weightedValues = [];
var cellMap = new Object();
for (var i = 0; i < rank.length; i++)
{
var currentCell = rank[i];
weightedValues[i] = new WeightedCellSorter();
weightedValues[i].cell = currentCell;
weightedValues[i].rankIndex = i;
cellMap[currentCell.id] = weightedValues[i];
var nextLayerConnectedCells = null;
if (nextRankValue < rankValue)
{
nextLayerConnectedCells = currentCell
.getPreviousLayerConnectedCells(rankValue);
}
else
{
nextLayerConnectedCells = currentCell
.getNextLayerConnectedCells(rankValue);
}
weightedValues[i].weightedValue = this.calculatedWeightedValue(
currentCell, nextLayerConnectedCells);
}
weightedValues.sort(WeightedCellSorter.prototype.compare);
for (var i = 0; i < weightedValues.length; i++)
{
var numConnectionsNextLevel = 0;
var cell = weightedValues[i].cell;
var nextLayerConnectedCells = null;
var medianNextLevel = 0;
if (nextRankValue < rankValue)
{
nextLayerConnectedCells = cell.getPreviousLayerConnectedCells(
rankValue).slice();
}
else
{
nextLayerConnectedCells = cell.getNextLayerConnectedCells(
rankValue).slice();
}
if (nextLayerConnectedCells != null)
{
numConnectionsNextLevel = nextLayerConnectedCells.length;
if (numConnectionsNextLevel > 0)
{
medianNextLevel = this.medianXValue(nextLayerConnectedCells,
nextRankValue);
}
else
{
medianNextLevel = cell.getGeneralPurposeVariable(rankValue);
}
}
var leftBuffer = 0.0;
var leftLimit = -1e8;
for (var j = weightedValues[i].rankIndex - 1; j >= 0;)
{
var weightedValue = cellMap[rank[j].id];
if (weightedValue != null)
{
var leftCell = weightedValue.cell;
if (weightedValue.visited)
{
leftLimit = leftCell
.getGeneralPurposeVariable(rankValue)
+ leftCell.width
/ 2.0
+ this.intraCellSpacing
+ leftBuffer + cell.width / 2.0;
j = -1;
}
else
{
leftBuffer += leftCell.width + this.intraCellSpacing;
j--;
}
}
}
var rightBuffer = 0.0;
var rightLimit = 100000000.0;
for (var j = weightedValues[i].rankIndex + 1; j < weightedValues.length;)
{
var weightedValue = cellMap[rank[j].id];
if (weightedValue != null)
{
var rightCell = weightedValue.cell;
if (weightedValue.visited)
{
rightLimit = rightCell
.getGeneralPurposeVariable(rankValue)
- rightCell.width
/ 2.0
- this.intraCellSpacing
- rightBuffer - cell.width / 2.0;
j = weightedValues.length;
}
else
{
rightBuffer += rightCell.width + this.intraCellSpacing;
j++;
}
}
}
if (medianNextLevel >= leftLimit && medianNextLevel <= rightLimit)
{
cell.setGeneralPurposeVariable(rankValue, medianNextLevel);
}
else if (medianNextLevel < leftLimit)
{
cell.setGeneralPurposeVariable(rankValue, leftLimit);
this.currentXDelta += leftLimit - medianNextLevel;
}
else if (medianNextLevel > rightLimit)
{
cell.setGeneralPurposeVariable(rankValue, rightLimit);
this.currentXDelta += medianNextLevel - rightLimit;
}
weightedValues[i].visited = true;
}
};
mxCoordinateAssignment.prototype.calculatedWeightedValue = function(currentCell, collection)
{
var totalWeight = 0;
for (var i = 0; i < collection.length; i++)
{
var cell = collection[i];
if (currentCell.isVertex() && cell.isVertex())
{
totalWeight++;
}
else if (currentCell.isEdge() && cell.isEdge())
{
totalWeight += 8;
}
else
{
totalWeight += 2;
}
}
return totalWeight;
};
mxCoordinateAssignment.prototype.medianXValue = function(connectedCells, rankValue)
{
if (connectedCells.length == 0)
{
return 0;
}
var medianValues = [];
for (var i = 0; i < connectedCells.length; i++)
{
medianValues[i] = connectedCells[i].getGeneralPurposeVariable(rankValue);
}
medianValues.sort(function(a,b){return a - b;});
if (connectedCells.length % 2 == 1)
{
return medianValues[Math.floor(connectedCells.length / 2)];
}
else
{
var medianPoint = connectedCells.length / 2;
var leftMedian = medianValues[medianPoint - 1];
var rightMedian = medianValues[medianPoint];
return ((leftMedian + rightMedian) / 2);
}
};
mxCoordinateAssignment.prototype.initialCoords = function(facade, model)
{
this.calculateWidestRank(facade, model);
for (var i = this.widestRank; i >= 0; i--)
{
if (i < model.maxRank)
{
this.rankCoordinates(i, facade, model);
}
}
for (var i = this.widestRank+1; i <= model.maxRank; i++)
{
if (i > 0)
{
this.rankCoordinates(i, facade, model);
}
}
};
mxCoordinateAssignment.prototype.rankCoordinates = function(rankValue, graph, model)
{
var rank = model.ranks[rankValue];
var maxY = 0.0;
var localX = this.initialX + (this.widestRankValue - this.rankWidths[rankValue])
/ 2;
var boundsWarning = false;
for (var i = 0; i < rank.length; i++)
{
var node = rank[i];
if (node.isVertex())
{
var bounds = this.layout.getVertexBounds(node.cell);
if (bounds != null)
{
if (this.orientation == mxConstants.DIRECTION_NORTH ||
this.orientation == mxConstants.DIRECTION_SOUTH)
{
node.width = bounds.width;
node.height = bounds.height;
}
else
{
node.width = bounds.height;
node.height = bounds.width;
}
}
else
{
boundsWarning = true;
}
maxY = Math.max(maxY, node.height);
}
else if (node.isEdge())
{
var numEdges = 1;
if (node.edges != null)
{
numEdges = node.edges.length;
}
else
{
mxLog.warn('edge.edges is null');
}
node.width = (numEdges - 1) * this.parallelEdgeSpacing;
}
localX += node.width / 2.0;
node.setX(rankValue, localX);
node.setGeneralPurposeVariable(rankValue, localX);
localX += node.width / 2.0;
localX += this.intraCellSpacing;
}
if (boundsWarning == true)
{
mxLog.warn('At least one cell has no bounds');
}
};
mxCoordinateAssignment.prototype.calculateWidestRank = function(graph, model)
{
var y = -this.interRankCellSpacing;
var lastRankMaxCellHeight = 0.0;
this.rankWidths = [];
this.rankY = [];
for (var rankValue = model.maxRank; rankValue >= 0; rankValue--)
{
var maxCellHeight = 0.0;
var rank = model.ranks[rankValue];
var localX = this.initialX;
var boundsWarning = false;
for (var i = 0; i < rank.length; i++)
{
var node = rank[i];
if (node.isVertex())
{
var bounds = this.layout.getVertexBounds(node.cell);
if (bounds != null)
{
if (this.orientation == mxConstants.DIRECTION_NORTH ||
this.orientation == mxConstants.DIRECTION_SOUTH)
{
node.width = bounds.width;
node.height = bounds.height;
}
else
{
node.width = bounds.height;
node.height = bounds.width;
}
}
else
{
boundsWarning = true;
}
maxCellHeight = Math.max(maxCellHeight, node.height);
}
else if (node.isEdge())
{
var numEdges = 1;
if (node.edges != null)
{
numEdges = node.edges.length;
}
else
{
mxLog.warn('edge.edges is null');
}
node.width = (numEdges - 1) * this.parallelEdgeSpacing;
}
localX += node.width / 2.0;
node.setX(rankValue, localX);
node.setGeneralPurposeVariable(rankValue, localX);
localX += node.width / 2.0;
localX += this.intraCellSpacing;
if (localX > this.widestRankValue)
{
this.widestRankValue = localX;
this.widestRank = rankValue;
}
this.rankWidths[rankValue] = localX;
}
if (boundsWarning == true)
{
mxLog.warn('At least one cell has no bounds');
}
this.rankY[rankValue] = y;
var distanceToNextRank = maxCellHeight / 2.0
+ lastRankMaxCellHeight / 2.0 + this.interRankCellSpacing;
lastRankMaxCellHeight = maxCellHeight;
if (this.orientation == mxConstants.DIRECTION_NORTH ||
this.orientation == mxConstants.DIRECTION_WEST)
{
y += distanceToNextRank;
}
else
{
y -= distanceToNextRank;
}
for (var i = 0; i < rank.length; i++)
{
var cell = rank[i];
cell.setY(rankValue, y);
}
}
};
mxCoordinateAssignment.prototype.minPath = function(graph, model)
{
var edges = model.edgeMapper.getValues();
for (var j = 0; j < edges.length; j++)
{
var cell = edges[j];
if (cell.maxRank - cell.minRank - 1 < 1)
{
continue;
}
var referenceX = cell
.getGeneralPurposeVariable(cell.minRank + 1);
var edgeStraight = true;
var refSegCount = 0;
for (var i = cell.minRank + 2; i < cell.maxRank; i++)
{
var x = cell.getGeneralPurposeVariable(i);
if (referenceX != x)
{
edgeStraight = false;
referenceX = x;
}
else
{
refSegCount++;
}
}
if (!edgeStraight)
{
var upSegCount = 0;
var downSegCount = 0;
var upXPositions = [];
var downXPositions = [];
var currentX = cell.getGeneralPurposeVariable(cell.minRank + 1);
for (var i = cell.minRank + 1; i < cell.maxRank - 1; i++)
{
var nextX = cell.getX(i + 1);
if (currentX == nextX)
{
upXPositions[i - cell.minRank - 1] = currentX;
upSegCount++;
}
else if (this.repositionValid(model, cell, i + 1, currentX))
{
upXPositions[i - cell.minRank - 1] = currentX;
upSegCount++;
}
else
{
upXPositions[i - cell.minRank - 1] = nextX;
currentX = nextX;
}
}
currentX = cell.getX(i);
for (var i = cell.maxRank - 1; i > cell.minRank + 1; i--)
{
var nextX = cell.getX(i - 1);
if (currentX == nextX)
{
downXPositions[i - cell.minRank - 2] = currentX;
downSegCount++;
}
else if (this.repositionValid(model, cell, i - 1, currentX))
{
downXPositions[i - cell.minRank - 2] = currentX;
downSegCount++;
}
else
{
downXPositions[i - cell.minRank - 2] = cell.getX(i-1);
currentX = nextX;
}
}
if (downSegCount > refSegCount || upSegCount > refSegCount)
{
if (downSegCount >= upSegCount)
{
for (var i = cell.maxRank - 2; i > cell.minRank; i--)
{
cell.setX(i, downXPositions[i - cell.minRank - 1]);
}
}
else if (upSegCount > downSegCount)
{
for (var i = cell.minRank + 2; i < cell.maxRank; i++)
{
cell.setX(i, upXPositions[i - cell.minRank - 2]);
}
}
else
;
}
}
}
};
mxCoordinateAssignment.prototype.repositionValid = function(model, cell, rank, position)
{
var rankArray = model.ranks[rank];
var rankIndex = -1;
for (var i = 0; i < rankArray.length; i++)
{
if (cell == rankArray[i])
{
rankIndex = i;
break;
}
}
if (rankIndex < 0)
{
return false;
}
var currentX = cell.getGeneralPurposeVariable(rank);
if (position < currentX)
{
if (rankIndex == 0)
{
return true;
}
var leftCell = rankArray[rankIndex - 1];
var leftLimit = leftCell.getGeneralPurposeVariable(rank);
leftLimit = leftLimit + leftCell.width / 2
+ this.intraCellSpacing + cell.width / 2;
if (leftLimit <= position)
{
return true;
}
else
{
return false;
}
}
else if (position > currentX)
{
if (rankIndex == rankArray.length - 1)
{
return true;
}
var rightCell = rankArray[rankIndex + 1];
var rightLimit = rightCell.getGeneralPurposeVariable(rank);
rightLimit = rightLimit - rightCell.width / 2
- this.intraCellSpacing - cell.width / 2;
if (rightLimit >= position)
{
return true;
}
else
{
return false;
}
}
return true;
};
mxCoordinateAssignment.prototype.setCellLocations = function(graph, model)
{
this.rankTopY = [];
this.rankBottomY = [];
for (var i = 0; i < model.ranks.length; i++)
{
this.rankTopY[i] = Number.MAX_VALUE;
this.rankBottomY[i] = -Number.MAX_VALUE;
}
var vertices = model.vertexMapper.getValues();
for (var i = 0; i < vertices.length; i++)
{
this.setVertexLocation(vertices[i]);
}
if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.ORTHOGONAL
|| this.layout.edgeStyle == mxHierarchicalEdgeStyle.POLYLINE
|| this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
{
this.localEdgeProcessing(model);
}
var edges = model.edgeMapper.getValues();
for (var i = 0; i < edges.length; i++)
{
this.setEdgePosition(edges[i]);
}
};
mxCoordinateAssignment.prototype.localEdgeProcessing = function(model)
{
for (var rankIndex = 0; rankIndex < model.ranks.length; rankIndex++)
{
var rank = model.ranks[rankIndex];
for (var cellIndex = 0; cellIndex < rank.length; cellIndex++)
{
var cell = rank[cellIndex];
if (cell.isVertex())
{
var currentCells = cell.getPreviousLayerConnectedCells(rankIndex);
var currentRank = rankIndex - 1;
for (var k = 0; k < 2; k++)
{
if (currentRank > -1
&& currentRank < model.ranks.length
&& currentCells != null
&& currentCells.length > 0)
{
var sortedCells = [];
for (var j = 0; j < currentCells.length; j++)
{
var sorter = new WeightedCellSorter(
currentCells[j], currentCells[j].getX(currentRank));
sortedCells.push(sorter);
}
sortedCells.sort(WeightedCellSorter.prototype.compare);
var leftLimit = cell.x[0] - cell.width / 2;
var rightLimit = leftLimit + cell.width;
var connectedEdgeCount = 0;
var connectedEdges = [];
for (var j = 0; j < sortedCells.length; j++)
{
var innerCell = sortedCells[j].cell;
var connections;
if (innerCell.isVertex())
{
if (k == 0)
{
connections = cell.connectsAsSource;
}
else
{
connections = cell.connectsAsTarget;
}
for (var connIndex = 0; connIndex < connections.length; connIndex++)
{
if (connections[connIndex].source == innerCell
|| connections[connIndex].target == innerCell)
{
connectedEdgeCount += connections[connIndex].edges
.length;
connectedEdges.push(connections[connIndex]);
}
}
}
else
{
connectedEdgeCount += innerCell.edges.length;
connectedEdges.push(innerCell);
}
}
var requiredWidth = (connectedEdgeCount + 1)
* this.prefHozEdgeSep;
if (cell.width > requiredWidth
+ (2 * this.prefHozEdgeSep))
{
leftLimit += this.prefHozEdgeSep;
rightLimit -= this.prefHozEdgeSep;
}
var availableWidth = rightLimit - leftLimit;
var edgeSpacing = availableWidth / connectedEdgeCount;
var currentX = leftLimit + edgeSpacing / 2.0;
var currentYOffset = this.minEdgeJetty - this.prefVertEdgeOff;
for (var j = 0; j < connectedEdges.length; j++)
{
var numActualEdges = connectedEdges[j].edges
.length;
var pos = this.jettyPositions[connectedEdges[j].ids[0]];
if (pos == null)
{
pos = [];
this.jettyPositions[connectedEdges[j].ids[0]] = pos;
}
if (j < connectedEdgeCount / 2)
{
currentYOffset += this.prefVertEdgeOff;
}
else if (j > connectedEdgeCount / 2)
{
currentYOffset -= this.prefVertEdgeOff;
}
for (var m = 0; m < numActualEdges; m++)
{
pos[m * 4 + k * 2] = currentX;
currentX += edgeSpacing;
pos[m * 4 + k * 2 + 1] = currentYOffset;
}
}
}
currentCells = cell.getNextLayerConnectedCells(rankIndex);
currentRank = rankIndex + 1;
}
}
}
}
};
mxCoordinateAssignment.prototype.setEdgePosition = function(cell)
{
var offsetX = 0;
if (cell.temp[0] != 101207)
{
var maxRank = cell.maxRank;
var minRank = cell.minRank;
if (maxRank == minRank)
{
maxRank = cell.source.maxRank;
minRank = cell.target.minRank;
}
var parallelEdgeCount = 0;
var jettys = this.jettyPositions[cell.ids[0]];
var source = cell.isReversed ? cell.target.cell : cell.source.cell;
var graph = this.layout.graph;
var layoutReversed = this.orientation == mxConstants.DIRECTION_EAST
|| this.orientation == mxConstants.DIRECTION_SOUTH;
for (var i = 0; i < cell.edges.length; i++)
{
var realEdge = cell.edges[i];
var realSource = this.layout.getVisibleTerminal(realEdge, true);
var newPoints = [];
var reversed = cell.isReversed;
if (realSource != source)
{
reversed = !reversed;
}
if (jettys != null)
{
var arrayOffset = reversed ? 2 : 0;
var y = reversed ?
(layoutReversed ? this.rankBottomY[minRank] : this.rankTopY[minRank]) :
(layoutReversed ? this.rankTopY[maxRank] : this.rankBottomY[maxRank]);
var jetty = jettys[parallelEdgeCount * 4 + 1 + arrayOffset];
if (reversed != layoutReversed)
{
jetty = -jetty;
}
y += jetty;
var x = jettys[parallelEdgeCount * 4 + arrayOffset];
var modelSource = graph.model.getTerminal(realEdge, true);
if (this.layout.isPort(modelSource) && graph.model.getParent(modelSource) == realSource)
{
var state = graph.view.getState(modelSource);
if (state != null)
{
x = state.x;
}
else
{
x = realSource.geometry.x + cell.source.width * modelSource.geometry.x;
}
}
if (this.orientation == mxConstants.DIRECTION_NORTH
|| this.orientation == mxConstants.DIRECTION_SOUTH)
{
newPoints.push(new mxPoint(x, y));
if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
{
newPoints.push(new mxPoint(x, y + jetty));
}
}
else
{
newPoints.push(new mxPoint(y, x));
if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
{
newPoints.push(new mxPoint(y + jetty, x));
}
}
}
var loopStart = cell.x.length - 1;
var loopLimit = -1;
var loopDelta = -1;
var currentRank = cell.maxRank - 1;
if (reversed)
{
loopStart = 0;
loopLimit = cell.x.length;
loopDelta = 1;
currentRank = cell.minRank + 1;
}
for (var j = loopStart; (cell.maxRank != cell.minRank) && j != loopLimit; j += loopDelta)
{
var positionX = cell.x[j] + offsetX;
var topChannelY = (this.rankTopY[currentRank] + this.rankBottomY[currentRank + 1]) / 2.0;
var bottomChannelY = (this.rankTopY[currentRank - 1] + this.rankBottomY[currentRank]) / 2.0;
if (reversed)
{
var tmp = topChannelY;
topChannelY = bottomChannelY;
bottomChannelY = tmp;
}
if (this.orientation == mxConstants.DIRECTION_NORTH ||
this.orientation == mxConstants.DIRECTION_SOUTH)
{
newPoints.push(new mxPoint(positionX, topChannelY));
newPoints.push(new mxPoint(positionX, bottomChannelY));
}
else
{
newPoints.push(new mxPoint(topChannelY, positionX));
newPoints.push(new mxPoint(bottomChannelY, positionX));
}
this.limitX = Math.max(this.limitX, positionX);
currentRank += loopDelta;
}
if (jettys != null)
{
var arrayOffset = reversed ? 2 : 0;
var rankY = reversed ?
(layoutReversed ? this.rankTopY[maxRank] : this.rankBottomY[maxRank]) :
(layoutReversed ? this.rankBottomY[minRank] : this.rankTopY[minRank]);
var jetty = jettys[parallelEdgeCount * 4 + 3 - arrayOffset];
if (reversed != layoutReversed)
{
jetty = -jetty;
}
var y = rankY - jetty;
var x = jettys[parallelEdgeCount * 4 + 2 - arrayOffset];
var modelTarget = graph.model.getTerminal(realEdge, false);
var realTarget = this.layout.getVisibleTerminal(realEdge, false);
if (this.layout.isPort(modelTarget) && graph.model.getParent(modelTarget) == realTarget)
{
var state = graph.view.getState(modelTarget);
if (state != null)
{
x = state.x;
}
else
{
x = realTarget.geometry.x + cell.target.width * modelTarget.geometry.x;
}
}
if (this.orientation == mxConstants.DIRECTION_NORTH ||
this.orientation == mxConstants.DIRECTION_SOUTH)
{
if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
{
newPoints.push(new mxPoint(x, y - jetty));
}
newPoints.push(new mxPoint(x, y));
}
else
{
if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
{
newPoints.push(new mxPoint(y - jetty, x));
}
newPoints.push(new mxPoint(y, x));
}
}
if (cell.isReversed)
{
this.processReversedEdge(cell, realEdge);
}
this.layout.setEdgePoints(realEdge, newPoints);
if (offsetX == 0.0)
{
offsetX = this.parallelEdgeSpacing;
}
else if (offsetX > 0)
{
offsetX = -offsetX;
}
else
{
offsetX = -offsetX + this.parallelEdgeSpacing;
}
parallelEdgeCount++;
}
cell.temp[0] = 101207;
}
};
mxCoordinateAssignment.prototype.setVertexLocation = function(cell)
{
var realCell = cell.cell;
var positionX = cell.x[0] - cell.width / 2;
var positionY = cell.y[0] - cell.height / 2;
this.rankTopY[cell.minRank] = Math.min(this.rankTopY[cell.minRank], positionY);
this.rankBottomY[cell.minRank] = Math.max(this.rankBottomY[cell.minRank],
positionY + cell.height);
if (this.orientation == mxConstants.DIRECTION_NORTH ||
this.orientation == mxConstants.DIRECTION_SOUTH)
{
this.layout.setVertexLocation(realCell, positionX, positionY);
}
else
{
this.layout.setVertexLocation(realCell, positionY, positionX);
}
this.limitX = Math.max(this.limitX, positionX + cell.width);
};
mxCoordinateAssignment.prototype.processReversedEdge = function(graph, model)
{
};
__mxOutput.mxCoordinateAssignment = typeof mxCoordinateAssignment !== 'undefined' ? mxCoordinateAssignment : undefined;
function mxSwimlaneOrdering(layout)
{
this.layout = layout;
} mxSwimlaneOrdering.prototype = new mxHierarchicalLayoutStage();
mxSwimlaneOrdering.prototype.constructor = mxSwimlaneOrdering;
mxSwimlaneOrdering.prototype.layout = null;
mxSwimlaneOrdering.prototype.execute = function(parent)
{
var model = this.layout.getModel();
var seenNodes = new Object();
var unseenNodes = mxUtils.clone(model.vertexMapper, null, true);
var rootsArray = null;
if (model.roots != null)
{
var modelRoots = model.roots;
rootsArray = [];
for (var i = 0; i < modelRoots.length; i++)
{
rootsArray[i] = model.vertexMapper.get(modelRoots[i]);
}
}
model.visit(function(parent, node, connectingEdge, layer, seen)
{
var isAncestor = parent != null && parent.swimlaneIndex == node.swimlaneIndex && node.isAncestor(parent);
var reversedOverSwimlane = parent != null && connectingEdge != null &&
parent.swimlaneIndex < node.swimlaneIndex && connectingEdge.source == node;
if (isAncestor)
{
connectingEdge.invert();
mxUtils.remove(connectingEdge, parent.connectsAsSource);
node.connectsAsSource.push(connectingEdge);
parent.connectsAsTarget.push(connectingEdge);
mxUtils.remove(connectingEdge, node.connectsAsTarget);
}
else if (reversedOverSwimlane)
{
connectingEdge.invert();
mxUtils.remove(connectingEdge, parent.connectsAsTarget);
node.connectsAsTarget.push(connectingEdge);
parent.connectsAsSource.push(connectingEdge);
mxUtils.remove(connectingEdge, node.connectsAsSource);
}
var cellId = mxCellPath.create(node.cell);
seenNodes[cellId] = node;
delete unseenNodes[cellId];
}, rootsArray, true, null);
};
__mxOutput.mxSwimlaneOrdering = typeof mxSwimlaneOrdering !== 'undefined' ? mxSwimlaneOrdering : undefined;
function mxHierarchicalLayout(graph, orientation, deterministic)
{
mxGraphLayout.call(this, graph);
this.orientation = (orientation != null) ? orientation : mxConstants.DIRECTION_NORTH;
this.deterministic = (deterministic != null) ? deterministic : true;
} var mxHierarchicalEdgeStyle =
{
ORTHOGONAL: 1,
POLYLINE: 2,
CURVE: 4
};
mxHierarchicalLayout.prototype = new mxGraphLayout();
mxHierarchicalLayout.prototype.constructor = mxHierarchicalLayout;
mxHierarchicalLayout.prototype.roots = null;
mxHierarchicalLayout.prototype.resizeParent = false;
mxHierarchicalLayout.prototype.maintainParentLocation = false;
mxHierarchicalLayout.prototype.moveParent = false;
mxHierarchicalLayout.prototype.parentBorder = 0;
mxHierarchicalLayout.prototype.intraCellSpacing = 30;
mxHierarchicalLayout.prototype.interRankCellSpacing = 100;
mxHierarchicalLayout.prototype.interHierarchySpacing = 60;
mxHierarchicalLayout.prototype.parallelEdgeSpacing = 10;
mxHierarchicalLayout.prototype.orientation = mxConstants.DIRECTION_NORTH;
mxHierarchicalLayout.prototype.fineTuning = true;
mxHierarchicalLayout.prototype.tightenToSource = true;
mxHierarchicalLayout.prototype.disableEdgeStyle = true;
mxHierarchicalLayout.prototype.traverseAncestors = true;
mxHierarchicalLayout.prototype.model = null;
mxHierarchicalLayout.prototype.edgesCache = null;
mxHierarchicalLayout.prototype.edgeSourceTermCache = null;
mxHierarchicalLayout.prototype.edgesTargetTermCache = null;
mxHierarchicalLayout.prototype.edgeStyle = mxHierarchicalEdgeStyle.POLYLINE;
mxHierarchicalLayout.prototype.getModel = function()
{
return this.model;
};
mxHierarchicalLayout.prototype.execute = function(parent, roots)
{
this.parent = parent;
var model = this.graph.model;
this.edgesCache = new mxDictionary();
this.edgeSourceTermCache = new mxDictionary();
this.edgesTargetTermCache = new mxDictionary();
if (roots != null && !(roots instanceof Array))
{
roots = [roots];
}
if (roots == null && parent == null)
{
return;
}
this.parentX = null;
this.parentY = null;
if (parent != this.root && model.isVertex(parent) != null && this.maintainParentLocation)
{
var geo = this.graph.getCellGeometry(parent);
if (geo != null)
{
this.parentX = geo.x;
this.parentY = geo.y;
}
}
if (roots != null)
{
var rootsCopy = [];
for (var i = 0; i < roots.length; i++)
{
var ancestor = parent != null ? model.isAncestor(parent, roots[i]) : true;
if (ancestor && model.isVertex(roots[i]))
{
rootsCopy.push(roots[i]);
}
}
this.roots = rootsCopy;
}
model.beginUpdate();
try
{
this.run(parent);
if (this.resizeParent && !this.graph.isCellCollapsed(parent))
{
this.graph.updateGroupBounds([parent], this.parentBorder, this.moveParent);
}
if (this.parentX != null && this.parentY != null)
{
var geo = this.graph.getCellGeometry(parent);
if (geo != null)
{
geo = geo.clone();
geo.x = this.parentX;
geo.y = this.parentY;
model.setGeometry(parent, geo);
}
}
}
finally
{
model.endUpdate();
}
};
mxHierarchicalLayout.prototype.findRoots = function(parent, vertices)
{
var roots = [];
if (parent != null && vertices != null)
{
var model = this.graph.model;
var best = null;
var maxDiff = -1e5;
for (var i in vertices)
{
var cell = vertices[i];
if (model.isVertex(cell) && this.graph.isCellVisible(cell))
{
var conns = this.getEdges(cell);
var fanOut = 0;
var fanIn = 0;
for (var k = 0; k < conns.length; k++)
{
var src = this.getVisibleTerminal(conns[k], true);
if (src == cell)
{
fanOut++;
}
else
{
fanIn++;
}
}
if (fanIn == 0 && fanOut > 0)
{
roots.push(cell);
}
var diff = fanOut - fanIn;
if (diff > maxDiff)
{
maxDiff = diff;
best = cell;
}
}
}
if (roots.length == 0 && best != null)
{
roots.push(best);
}
}
return roots;
};
mxHierarchicalLayout.prototype.getEdges = function(cell)
{
var cachedEdges = this.edgesCache.get(cell);
if (cachedEdges != null)
{
return cachedEdges;
}
var model = this.graph.model;
var edges = [];
var isCollapsed = this.graph.isCellCollapsed(cell);
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(cell, i);
if (this.isPort(child))
{
edges = edges.concat(model.getEdges(child, true, true));
}
else if (isCollapsed || !this.graph.isCellVisible(child))
{
edges = edges.concat(model.getEdges(child, true, true));
}
}
edges = edges.concat(model.getEdges(cell, true, true));
var result = [];
for (var i = 0; i < edges.length; i++)
{
var source = this.getVisibleTerminal(edges[i], true);
var target = this.getVisibleTerminal(edges[i], false);
if ((source == target) ||
((source != target) &&
((target == cell && (this.parent == null || this.isAncestor(this.parent, source, this.traverseAncestors))) ||
(source == cell && (this.parent == null || this.isAncestor(this.parent, target, this.traverseAncestors))))))
{
result.push(edges[i]);
}
}
this.edgesCache.put(cell, result);
return result;
};
mxHierarchicalLayout.prototype.getVisibleTerminal = function(edge, source)
{
var terminalCache = this.edgesTargetTermCache;
if (source)
{
terminalCache = this.edgeSourceTermCache;
}
var term = terminalCache.get(edge);
if (term != null)
{
return term;
}
var state = this.graph.view.getState(edge);
var terminal = (state != null) ? state.getVisibleTerminal(source) : this.graph.view.getVisibleTerminal(edge, source);
if (terminal == null)
{
terminal = (state != null) ? state.getVisibleTerminal(source) : this.graph.view.getVisibleTerminal(edge, source);
}
if (terminal != null)
{
if (this.isPort(terminal))
{
terminal = this.graph.model.getParent(terminal);
}
terminalCache.put(edge, terminal);
}
return terminal;
};
mxHierarchicalLayout.prototype.run = function(parent)
{
var hierarchyVertices = [];
var allVertexSet = [];
if (this.roots == null && parent != null)
{
var filledVertexSet = Object();
this.filterDescendants(parent, filledVertexSet);
this.roots = [];
var filledVertexSetEmpty = true;
for (var key in filledVertexSet)
{
if (filledVertexSet[key] != null)
{
filledVertexSetEmpty = false;
break;
}
}
while (!filledVertexSetEmpty)
{
var candidateRoots = this.findRoots(parent, filledVertexSet);
for (var i = 0; i < candidateRoots.length; i++)
{
var vertexSet = Object();
hierarchyVertices.push(vertexSet);
this.traverse(candidateRoots[i], true, null, allVertexSet, vertexSet,
hierarchyVertices, filledVertexSet);
}
for (var i = 0; i < candidateRoots.length; i++)
{
this.roots.push(candidateRoots[i]);
}
filledVertexSetEmpty = true;
for (var key in filledVertexSet)
{
if (filledVertexSet[key] != null)
{
filledVertexSetEmpty = false;
break;
}
}
}
}
else
{
for (var i = 0; i < this.roots.length; i++)
{
var vertexSet = Object();
hierarchyVertices.push(vertexSet);
this.traverse(this.roots[i], true, null, allVertexSet, vertexSet,
hierarchyVertices, null);
}
}
var initialX = 0;
for (var i = 0; i < hierarchyVertices.length; i++)
{
var vertexSet = hierarchyVertices[i];
var tmp = [];
for (var key in vertexSet)
{
tmp.push(vertexSet[key]);
}
this.model = new mxGraphHierarchyModel(this, tmp, this.roots,
parent, this.tightenToSource);
this.cycleStage(parent);
this.layeringStage();
this.crossingStage(parent);
initialX = this.placementStage(initialX, parent);
}
};
mxHierarchicalLayout.prototype.filterDescendants = function(cell, result)
{
var model = this.graph.model;
if (model.isVertex(cell) && cell != this.parent && this.graph.isCellVisible(cell))
{
result[mxObjectIdentity.get(cell)] = cell;
}
if (this.traverseAncestors || cell == this.parent
&& this.graph.isCellVisible(cell))
{
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(cell, i);
if (!this.isPort(child))
{
this.filterDescendants(child, result);
}
}
}
};
mxHierarchicalLayout.prototype.isPort = function(cell)
{
if (cell != null && cell.geometry != null)
{
return cell.geometry.relative;
}
else
{
return false;
}
};
mxHierarchicalLayout.prototype.getEdgesBetween = function(source, target, directed)
{
directed = (directed != null) ? directed : false;
var edges = this.getEdges(source);
var result = [];
for (var i = 0; i < edges.length; i++)
{
var src = this.getVisibleTerminal(edges[i], true);
var trg = this.getVisibleTerminal(edges[i], false);
if ((src == source && trg == target) || (!directed && src == target && trg == source))
{
result.push(edges[i]);
}
}
return result;
};
mxHierarchicalLayout.prototype.traverse = function(vertex, directed, edge, allVertices, currentComp,
hierarchyVertices, filledVertexSet)
{
if (vertex != null && allVertices != null)
{
var vertexID = mxObjectIdentity.get(vertex);
if ((allVertices[vertexID] == null)
&& (filledVertexSet == null ? true : filledVertexSet[vertexID] != null))
{
if (currentComp[vertexID] == null)
{
currentComp[vertexID] = vertex;
}
if (allVertices[vertexID] == null)
{
allVertices[vertexID] = vertex;
}
if (filledVertexSet !== null)
{
delete filledVertexSet[vertexID];
}
var edges = this.getEdges(vertex);
var edgeIsSource = [];
for (var i = 0; i < edges.length; i++)
{
edgeIsSource[i] = (this.getVisibleTerminal(edges[i], true) == vertex);
}
for (var i = 0; i < edges.length; i++)
{
if (!directed || edgeIsSource[i])
{
var next = this.getVisibleTerminal(edges[i], !edgeIsSource[i]);
var netCount = 1;
for (var j = 0; j < edges.length; j++)
{
if (j == i)
{
continue;
}
else
{
var isSource2 = edgeIsSource[j];
var otherTerm = this.getVisibleTerminal(edges[j], !isSource2);
if (otherTerm == next)
{
if (isSource2)
{
netCount++;
}
else
{
netCount--;
}
}
}
}
if (netCount >= 0)
{
currentComp = this.traverse(next, directed, edges[i], allVertices,
currentComp, hierarchyVertices,
filledVertexSet);
}
}
}
}
else
{
if (currentComp[vertexID] == null)
{
for (var i = 0; i < hierarchyVertices.length; i++)
{
var comp = hierarchyVertices[i];
if (comp[vertexID] != null)
{
for (var key in comp)
{
currentComp[key] = comp[key];
}
hierarchyVertices.splice(i, 1);
return currentComp;
}
}
}
}
}
return currentComp;
};
mxHierarchicalLayout.prototype.cycleStage = function(parent)
{
var cycleStage = new mxMinimumCycleRemover(this);
cycleStage.execute(parent);
};
mxHierarchicalLayout.prototype.layeringStage = function()
{
this.model.initialRank();
this.model.fixRanks();
};
mxHierarchicalLayout.prototype.crossingStage = function(parent)
{
var crossingStage = new mxMedianHybridCrossingReduction(this);
crossingStage.execute(parent);
};
mxHierarchicalLayout.prototype.placementStage = function(initialX, parent)
{
var placementStage = new mxCoordinateAssignment(this, this.intraCellSpacing,
this.interRankCellSpacing, this.orientation, initialX,
this.parallelEdgeSpacing);
placementStage.fineTuning = this.fineTuning;
placementStage.execute(parent);
return placementStage.limitX + this.interHierarchySpacing;
};
__mxOutput.mxHierarchicalLayout = typeof mxHierarchicalLayout !== 'undefined' ? mxHierarchicalLayout : undefined;
function mxSwimlaneLayout(graph, orientation, deterministic)
{
mxGraphLayout.call(this, graph);
this.orientation = (orientation != null) ? orientation : mxConstants.DIRECTION_NORTH;
this.deterministic = (deterministic != null) ? deterministic : true;
} mxSwimlaneLayout.prototype = new mxGraphLayout();
mxSwimlaneLayout.prototype.constructor = mxSwimlaneLayout;
mxSwimlaneLayout.prototype.roots = null;
mxSwimlaneLayout.prototype.swimlanes = null;
mxSwimlaneLayout.prototype.dummyVertexWidth = 50;
mxSwimlaneLayout.prototype.resizeParent = false;
mxSwimlaneLayout.prototype.maintainParentLocation = false;
mxSwimlaneLayout.prototype.moveParent = false;
mxSwimlaneLayout.prototype.parentBorder = 30;
mxSwimlaneLayout.prototype.intraCellSpacing = 30;
mxSwimlaneLayout.prototype.interRankCellSpacing = 100;
mxSwimlaneLayout.prototype.interHierarchySpacing = 60;
mxSwimlaneLayout.prototype.parallelEdgeSpacing = 10;
mxSwimlaneLayout.prototype.orientation = mxConstants.DIRECTION_NORTH;
mxSwimlaneLayout.prototype.fineTuning = true;
mxSwimlaneLayout.prototype.tightenToSource = true;
mxSwimlaneLayout.prototype.disableEdgeStyle = true;
mxSwimlaneLayout.prototype.traverseAncestors = true;
mxSwimlaneLayout.prototype.model = null;
mxSwimlaneLayout.prototype.edgesCache = null;
mxHierarchicalLayout.prototype.edgeSourceTermCache = null;
mxHierarchicalLayout.prototype.edgesTargetTermCache = null;
mxHierarchicalLayout.prototype.edgeStyle = mxHierarchicalEdgeStyle.POLYLINE;
mxSwimlaneLayout.prototype.getModel = function()
{
return this.model;
};
mxSwimlaneLayout.prototype.execute = function(parent, swimlanes)
{
this.parent = parent;
var model = this.graph.model;
this.edgesCache = new mxDictionary();
this.edgeSourceTermCache = new mxDictionary();
this.edgesTargetTermCache = new mxDictionary();
if (swimlanes == null || swimlanes.length < 1)
{
return;
}
if (parent == null)
{
parent = model.getParent(swimlanes[0]);
}
this.parentX = null;
this.parentY = null;
if (parent != this.root && model.isVertex(parent) != null && this.maintainParentLocation)
{
var geo = this.graph.getCellGeometry(parent);
if (geo != null)
{
this.parentX = geo.x;
this.parentY = geo.y;
}
}
this.swimlanes = swimlanes;
var dummyVertices = [];
for (var i = 0; i < swimlanes.length; i++)
{
var children = this.graph.getChildCells(swimlanes[i]);
if (children == null || children.length == 0)
{
var vertex = this.graph.insertVertex(swimlanes[i], null, null, 0, 0, this.dummyVertexWidth, 0);
dummyVertices.push(vertex);
}
}
model.beginUpdate();
try
{
this.run(parent);
if (this.resizeParent && !this.graph.isCellCollapsed(parent))
{
this.graph.updateGroupBounds([parent], this.parentBorder, this.moveParent);
}
if (this.parentX != null && this.parentY != null)
{
var geo = this.graph.getCellGeometry(parent);
if (geo != null)
{
geo = geo.clone();
geo.x = this.parentX;
geo.y = this.parentY;
model.setGeometry(parent, geo);
}
}
this.graph.removeCells(dummyVertices);
}
finally
{
model.endUpdate();
}
};
mxSwimlaneLayout.prototype.updateGroupBounds = function()
{
var cells = [];
var model = this.model;
for (var key in model.edgeMapper)
{
var edge = model.edgeMapper[key];
for (var i = 0; i < edge.edges.length; i++)
{
cells.push(edge.edges[i]);
}
}
var layoutBounds = this.graph.getBoundingBoxFromGeometry(cells, true);
var childBounds = [];
for (var i = 0; i < this.swimlanes.length; i++)
{
var lane = this.swimlanes[i];
var geo = this.graph.getCellGeometry(lane);
if (geo != null)
{
var children = this.graph.getChildCells(lane);
var size = (this.graph.isSwimlane(lane)) ?
this.graph.getStartSize(lane) : new mxRectangle();
var bounds = this.graph.getBoundingBoxFromGeometry(children);
childBounds[i] = bounds;
var childrenY = bounds.y + geo.y - size.height - this.parentBorder;
var maxChildrenY = bounds.y + geo.y + bounds.height;
if (layoutBounds == null)
{
layoutBounds = new mxRectangle(0, childrenY, 0, maxChildrenY - childrenY);
}
else
{
layoutBounds.y = Math.min(layoutBounds.y, childrenY);
var maxY = Math.max(layoutBounds.y + layoutBounds.height, maxChildrenY);
layoutBounds.height = maxY - layoutBounds.y;
}
}
}
for (var i = 0; i < this.swimlanes.length; i++)
{
var lane = this.swimlanes[i];
var geo = this.graph.getCellGeometry(lane);
if (geo != null)
{
var children = this.graph.getChildCells(lane);
var size = (this.graph.isSwimlane(lane)) ?
this.graph.getStartSize(lane) : new mxRectangle();
var newGeo = geo.clone();
var leftGroupBorder = (i == 0) ? this.parentBorder : this.interRankCellSpacing/2;
var w = size.width + leftGroupBorder;
var x = childBounds[i].x - w;
var y = layoutBounds.y - this.parentBorder;
newGeo.x += x;
newGeo.y = y;
newGeo.width = childBounds[i].width + w + this.interRankCellSpacing/2;
newGeo.height = layoutBounds.height + size.height + 2 * this.parentBorder;
this.graph.model.setGeometry(lane, newGeo);
this.graph.moveCells(children, -x, geo.y - y);
}
}
};
mxSwimlaneLayout.prototype.findRoots = function(parent, vertices)
{
var roots = [];
if (parent != null && vertices != null)
{
var model = this.graph.model;
var best = null;
var maxDiff = -1e5;
for (var i in vertices)
{
var cell = vertices[i];
if (cell != null && model.isVertex(cell) && this.graph.isCellVisible(cell) && model.isAncestor(parent, cell))
{
var conns = this.getEdges(cell);
var fanOut = 0;
var fanIn = 0;
for (var k = 0; k < conns.length; k++)
{
var src = this.getVisibleTerminal(conns[k], true);
if (src == cell)
{
var other = this.getVisibleTerminal(conns[k], false);
if (model.isAncestor(parent, other))
{
fanOut++;
}
}
else if (model.isAncestor(parent, src))
{
fanIn++;
}
}
if (fanIn == 0 && fanOut > 0)
{
roots.push(cell);
}
var diff = fanOut - fanIn;
if (diff > maxDiff)
{
maxDiff = diff;
best = cell;
}
}
}
if (roots.length == 0 && best != null)
{
roots.push(best);
}
}
return roots;
};
mxSwimlaneLayout.prototype.getEdges = function(cell)
{
var cachedEdges = this.edgesCache.get(cell);
if (cachedEdges != null)
{
return cachedEdges;
}
var model = this.graph.model;
var edges = [];
var isCollapsed = this.graph.isCellCollapsed(cell);
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(cell, i);
if (this.isPort(child))
{
edges = edges.concat(model.getEdges(child, true, true));
}
else if (isCollapsed || !this.graph.isCellVisible(child))
{
edges = edges.concat(model.getEdges(child, true, true));
}
}
edges = edges.concat(model.getEdges(cell, true, true));
var result = [];
for (var i = 0; i < edges.length; i++)
{
var source = this.getVisibleTerminal(edges[i], true);
var target = this.getVisibleTerminal(edges[i], false);
if ((source == target) || ((source != target) && ((target == cell && (this.parent == null || this.graph.isValidAncestor(source, this.parent, this.traverseAncestors))) ||
(source == cell && (this.parent == null ||
this.graph.isValidAncestor(target, this.parent, this.traverseAncestors))))))
{
result.push(edges[i]);
}
}
this.edgesCache.put(cell, result);
return result;
};
mxSwimlaneLayout.prototype.getVisibleTerminal = function(edge, source)
{
var terminalCache = this.edgesTargetTermCache;
if (source)
{
terminalCache = this.edgeSourceTermCache;
}
var term = terminalCache.get(edge);
if (term != null)
{
return term;
}
var state = this.graph.view.getState(edge);
var terminal = (state != null) ? state.getVisibleTerminal(source) : this.graph.view.getVisibleTerminal(edge, source);
if (terminal == null)
{
terminal = (state != null) ? state.getVisibleTerminal(source) : this.graph.view.getVisibleTerminal(edge, source);
}
if (terminal != null)
{
if (this.isPort(terminal))
{
terminal = this.graph.model.getParent(terminal);
}
terminalCache.put(edge, terminal);
}
return terminal;
};
mxSwimlaneLayout.prototype.run = function(parent)
{
var hierarchyVertices = [];
var allVertexSet = Object();
if (this.swimlanes != null && this.swimlanes.length > 0 && parent != null)
{
var filledVertexSet = Object();
for (var i = 0; i < this.swimlanes.length; i++)
{
this.filterDescendants(this.swimlanes[i], filledVertexSet);
}
this.roots = [];
var filledVertexSetEmpty = true;
for (var key in filledVertexSet)
{
if (filledVertexSet[key] != null)
{
filledVertexSetEmpty = false;
break;
}
}
var laneCounter = 0;
while (!filledVertexSetEmpty && laneCounter < this.swimlanes.length)
{
var candidateRoots = this.findRoots(this.swimlanes[laneCounter], filledVertexSet);
if (candidateRoots.length == 0)
{
laneCounter++;
continue;
}
for (var i = 0; i < candidateRoots.length; i++)
{
var vertexSet = Object();
hierarchyVertices.push(vertexSet);
this.traverse(candidateRoots[i], true, null, allVertexSet, vertexSet,
hierarchyVertices, filledVertexSet, laneCounter);
}
for (var i = 0; i < candidateRoots.length; i++)
{
this.roots.push(candidateRoots[i]);
}
filledVertexSetEmpty = true;
for (var key in filledVertexSet)
{
if (filledVertexSet[key] != null)
{
filledVertexSetEmpty = false;
break;
}
}
}
}
else
{
for (var i = 0; i < this.roots.length; i++)
{
var vertexSet = Object();
hierarchyVertices.push(vertexSet);
this.traverse(this.roots[i], true, null, allVertexSet, vertexSet,
hierarchyVertices, null);
}
}
var tmp = [];
for (var key in allVertexSet)
{
tmp.push(allVertexSet[key]);
}
this.model = new mxSwimlaneModel(this, tmp, this.roots,
parent, this.tightenToSource);
this.cycleStage(parent);
this.layeringStage();
this.crossingStage(parent);
this.placementStage(0, parent);
};
mxSwimlaneLayout.prototype.filterDescendants = function(cell, result)
{
var model = this.graph.model;
if (model.isVertex(cell) && cell != this.parent && model.getParent(cell) != this.parent && this.graph.isCellVisible(cell))
{
result[mxObjectIdentity.get(cell)] = cell;
}
if (this.traverseAncestors || cell == this.parent
&& this.graph.isCellVisible(cell))
{
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(cell, i);
if (!this.isPort(child))
{
this.filterDescendants(child, result);
}
}
}
};
mxSwimlaneLayout.prototype.isPort = function(cell)
{
if (cell.geometry.relative)
{
return true;
}
return false;
};
mxSwimlaneLayout.prototype.getEdgesBetween = function(source, target, directed)
{
directed = (directed != null) ? directed : false;
var edges = this.getEdges(source);
var result = [];
for (var i = 0; i < edges.length; i++)
{
var src = this.getVisibleTerminal(edges[i], true);
var trg = this.getVisibleTerminal(edges[i], false);
if ((src == source && trg == target) || (!directed && src == target && trg == source))
{
result.push(edges[i]);
}
}
return result;
};
mxSwimlaneLayout.prototype.traverse = function(vertex, directed, edge, allVertices, currentComp,
hierarchyVertices, filledVertexSet, swimlaneIndex)
{
if (vertex != null && allVertices != null)
{
var vertexID = mxObjectIdentity.get(vertex);
if ((allVertices[vertexID] == null)
&& (filledVertexSet == null ? true : filledVertexSet[vertexID] != null))
{
if (currentComp[vertexID] == null)
{
currentComp[vertexID] = vertex;
}
if (allVertices[vertexID] == null)
{
allVertices[vertexID] = vertex;
}
if (filledVertexSet !== null)
{
delete filledVertexSet[vertexID];
}
var edges = this.getEdges(vertex);
var model = this.graph.model;
for (var i = 0; i < edges.length; i++)
{
var otherVertex = this.getVisibleTerminal(edges[i], true);
var isSource = otherVertex == vertex;
if (isSource)
{
otherVertex = this.getVisibleTerminal(edges[i], false);
}
var otherIndex = 0;
for (otherIndex = 0; otherIndex < this.swimlanes.length; otherIndex++)
{
if (model.isAncestor(this.swimlanes[otherIndex], otherVertex))
{
break;
}
}
if (otherIndex >= this.swimlanes.length)
{
continue;
}
if ((otherIndex > swimlaneIndex) ||
((!directed || isSource) && otherIndex == swimlaneIndex))
{
currentComp = this.traverse(otherVertex, directed, edges[i], allVertices,
currentComp, hierarchyVertices,
filledVertexSet, otherIndex);
}
}
}
else
{
if (currentComp[vertexID] == null)
{
for (var i = 0; i < hierarchyVertices.length; i++)
{
var comp = hierarchyVertices[i];
if (comp[vertexID] != null)
{
for (var key in comp)
{
currentComp[key] = comp[key];
}
hierarchyVertices.splice(i, 1);
return currentComp;
}
}
}
}
}
return currentComp;
};
mxSwimlaneLayout.prototype.cycleStage = function(parent)
{
var cycleStage = new mxSwimlaneOrdering(this);
cycleStage.execute(parent);
};
mxSwimlaneLayout.prototype.layeringStage = function()
{
this.model.initialRank();
this.model.fixRanks();
};
mxSwimlaneLayout.prototype.crossingStage = function(parent)
{
var crossingStage = new mxMedianHybridCrossingReduction(this);
crossingStage.execute(parent);
};
mxSwimlaneLayout.prototype.placementStage = function(initialX, parent)
{
var placementStage = new mxCoordinateAssignment(this, this.intraCellSpacing,
this.interRankCellSpacing, this.orientation, initialX,
this.parallelEdgeSpacing);
placementStage.fineTuning = this.fineTuning;
placementStage.execute(parent);
return placementStage.limitX + this.interHierarchySpacing;
};
__mxOutput.mxSwimlaneLayout = typeof mxSwimlaneLayout !== 'undefined' ? mxSwimlaneLayout : undefined;
function mxGraphModel(root)
{
this.currentEdit = this.createUndoableEdit();
if (root != null)
{
this.setRoot(root);
}
else
{
this.clear();
}
} mxGraphModel.prototype = new mxEventSource();
mxGraphModel.prototype.constructor = mxGraphModel;
mxGraphModel.prototype.root = null;
mxGraphModel.prototype.cells = null;
mxGraphModel.prototype.maintainEdgeParent = true;
mxGraphModel.prototype.ignoreRelativeEdgeParent = true;
mxGraphModel.prototype.createIds = true;
mxGraphModel.prototype.prefix = '';
mxGraphModel.prototype.postfix = '';
mxGraphModel.prototype.nextId = 0;
mxGraphModel.prototype.currentEdit = null;
mxGraphModel.prototype.updateLevel = 0;
mxGraphModel.prototype.endingUpdate = false;
mxGraphModel.prototype.clear = function()
{
this.setRoot(this.createRoot());
};
mxGraphModel.prototype.isCreateIds = function()
{
return this.createIds;
};
mxGraphModel.prototype.setCreateIds = function(value)
{
this.createIds = value;
};
mxGraphModel.prototype.createRoot = function()
{
var cell = new mxCell();
cell.insert(new mxCell());
return cell;
};
mxGraphModel.prototype.getCell = function(id)
{
return (this.cells != null) ? this.cells[id] : null;
};
mxGraphModel.prototype.filterCells = function(cells, filter)
{
var result = null;
if (cells != null)
{
result = [];
for (var i = 0; i < cells.length; i++)
{
if (filter(cells[i]))
{
result.push(cells[i]);
}
}
}
return result;
};
mxGraphModel.prototype.getDescendants = function(parent)
{
return this.filterDescendants(null, parent);
};
mxGraphModel.prototype.filterDescendants = function(filter, parent)
{
var result = [];
parent = parent || this.getRoot();
if (filter == null || filter(parent))
{
result.push(parent);
}
var childCount = this.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
var child = this.getChildAt(parent, i);
result = result.concat(this.filterDescendants(filter, child));
}
return result;
};
mxGraphModel.prototype.getRoot = function(cell)
{
var root = cell || this.root;
if (cell != null)
{
while (cell != null)
{
root = cell;
cell = this.getParent(cell);
}
}
return root;
};
mxGraphModel.prototype.setRoot = function(root)
{
this.execute(new mxRootChange(this, root));
return root;
};
mxGraphModel.prototype.rootChanged = function(root)
{
var oldRoot = this.root;
this.root = root;
this.nextId = 0;
this.cells = null;
this.cellAdded(root);
return oldRoot;
};
mxGraphModel.prototype.isRoot = function(cell)
{
return cell != null && this.root == cell;
};
mxGraphModel.prototype.isLayer = function(cell)
{
return this.isRoot(this.getParent(cell));
};
mxGraphModel.prototype.isAncestor = function(parent, child)
{
while (child != null && child != parent)
{
child = this.getParent(child);
}
return child == parent;
};
mxGraphModel.prototype.contains = function(cell)
{
return this.isAncestor(this.root, cell);
};
mxGraphModel.prototype.getParent = function(cell)
{
return (cell != null) ? cell.getParent() : null;
};
mxGraphModel.prototype.add = function(parent, child, index)
{
if (child != parent && parent != null && child != null)
{
if (index == null)
{
index = this.getChildCount(parent);
}
var parentChanged = parent != this.getParent(child);
this.execute(new mxChildChange(this, parent, child, index));
if (this.maintainEdgeParent && parentChanged)
{
this.updateEdgeParents(child);
}
}
return child;
};
mxGraphModel.prototype.cellAdded = function(cell)
{
if (cell != null)
{
if (cell.getId() == null && this.createIds)
{
cell.setId(this.createId(cell));
}
if (cell.getId() != null)
{
var collision = this.getCell(cell.getId());
if (collision != cell)
{
while (collision != null)
{
cell.setId(this.createId(cell));
collision = this.getCell(cell.getId());
}
if (this.cells == null)
{
this.cells = new Object();
}
this.cells[cell.getId()] = cell;
}
}
if (mxUtils.isNumeric(cell.getId()))
{
this.nextId = Math.max(this.nextId, cell.getId());
}
var childCount = this.getChildCount(cell);
for (var i=0; i<childCount; i++)
{
this.cellAdded(this.getChildAt(cell, i));
}
}
};
mxGraphModel.prototype.createId = function(cell)
{
var id = this.nextId;
this.nextId++;
return this.prefix + id + this.postfix;
};
mxGraphModel.prototype.updateEdgeParents = function(cell, root)
{
root = root || this.getRoot(cell);
var childCount = this.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var child = this.getChildAt(cell, i);
this.updateEdgeParents(child, root);
}
var edgeCount = this.getEdgeCount(cell);
var edges = [];
for (var i = 0; i < edgeCount; i++)
{
edges.push(this.getEdgeAt(cell, i));
}
for (var i = 0; i < edges.length; i++)
{
var edge = edges[i];
if (this.isAncestor(root, edge))
{
this.updateEdgeParent(edge, root);
}
}
};
mxGraphModel.prototype.updateEdgeParent = function(edge, root)
{
var source = this.getTerminal(edge, true);
var target = this.getTerminal(edge, false);
var cell = null;
while (source != null && !this.isEdge(source) &&
source.geometry != null && source.geometry.relative)
{
source = this.getParent(source);
}
while (target != null && this.ignoreRelativeEdgeParent &&
!this.isEdge(target) && target.geometry != null &&
target.geometry.relative)
{
target = this.getParent(target);
}
if (this.isAncestor(root, source) && this.isAncestor(root, target))
{
if (source == target)
{
cell = this.getParent(source);
}
else
{
cell = this.getNearestCommonAncestor(source, target);
}
if (cell != null && (this.getParent(cell) != this.root ||
this.isAncestor(cell, edge)) && this.getParent(edge) != cell)
{
var geo = this.getGeometry(edge);
if (geo != null)
{
var origin1 = this.getOrigin(this.getParent(edge));
var origin2 = this.getOrigin(cell);
var dx = origin2.x - origin1.x;
var dy = origin2.y - origin1.y;
geo = geo.clone();
geo.translate(-dx, -dy);
this.setGeometry(edge, geo);
}
this.add(cell, edge, this.getChildCount(cell));
}
}
};
mxGraphModel.prototype.getOrigin = function(cell)
{
var result = null;
if (cell != null)
{
result = this.getOrigin(this.getParent(cell));
if (!this.isEdge(cell))
{
var geo = this.getGeometry(cell);
if (geo != null)
{
result.x += geo.x;
result.y += geo.y;
}
}
}
else
{
result = new mxPoint();
}
return result;
};
mxGraphModel.prototype.getNearestCommonAncestor = function(cell1, cell2)
{
if (cell1 != null && cell2 != null)
{
var path = mxCellPath.create(cell2);
if (path != null && path.length > 0)
{
var cell = cell1;
var current = mxCellPath.create(cell);
if (path.length < current.length)
{
cell = cell2;
var tmp = current;
current = path;
path = tmp;
}
while (cell != null)
{
var parent = this.getParent(cell);
if (path.indexOf(current + mxCellPath.PATH_SEPARATOR) == 0 && parent != null)
{
return cell;
}
current = mxCellPath.getParentPath(current);
cell = parent;
}
}
}
return null;
};
mxGraphModel.prototype.remove = function(cell)
{
if (cell == this.root)
{
this.setRoot(null);
}
else if (this.getParent(cell) != null)
{
this.execute(new mxChildChange(this, null, cell));
}
return cell;
};
mxGraphModel.prototype.cellRemoved = function(cell)
{
if (cell != null && this.cells != null)
{
var childCount = this.getChildCount(cell);
for (var i = childCount - 1; i >= 0; i--)
{
this.cellRemoved(this.getChildAt(cell, i));
}
if (this.cells != null && cell.getId() != null)
{
delete this.cells[cell.getId()];
}
}
};
mxGraphModel.prototype.parentForCellChanged = function(cell, parent, index)
{
var previous = this.getParent(cell);
if (parent != null)
{
if (parent != previous || previous.getIndex(cell) != index)
{
parent.insert(cell, index);
}
}
else if (previous != null)
{
var oldIndex = previous.getIndex(cell);
previous.remove(oldIndex);
}
var par = this.contains(parent);
var pre = this.contains(previous);
if (par && !pre)
{
this.cellAdded(cell);
}
else if (pre && !par)
{
this.cellRemoved(cell);
}
return previous;
};
mxGraphModel.prototype.getChildCount = function(cell)
{
return (cell != null) ? cell.getChildCount() : 0;
};
mxGraphModel.prototype.getChildAt = function(cell, index)
{
return (cell != null) ? cell.getChildAt(index) : null;
};
mxGraphModel.prototype.getChildren = function(cell)
{
return (cell != null) ? cell.children : null;
};
mxGraphModel.prototype.getChildVertices = function(parent)
{
return this.getChildCells(parent, true, false);
};
mxGraphModel.prototype.getChildEdges = function(parent)
{
return this.getChildCells(parent, false, true);
};
mxGraphModel.prototype.getChildCells = function(parent, vertices, edges)
{
vertices = (vertices != null) ? vertices : false;
edges = (edges != null) ? edges : false;
var childCount = this.getChildCount(parent);
var result = [];
for (var i = 0; i < childCount; i++)
{
var child = this.getChildAt(parent, i);
if ((!edges && !vertices) || (edges && this.isEdge(child)) ||
(vertices && this.isVertex(child)))
{
result.push(child);
}
}
return result;
};
mxGraphModel.prototype.getTerminal = function(edge, isSource)
{
return (edge != null) ? edge.getTerminal(isSource) : null;
};
mxGraphModel.prototype.setTerminal = function(edge, terminal, isSource)
{
var terminalChanged = terminal != this.getTerminal(edge, isSource);
this.execute(new mxTerminalChange(this, edge, terminal, isSource));
if (this.maintainEdgeParent && terminalChanged)
{
this.updateEdgeParent(edge, this.getRoot());
}
return terminal;
};
mxGraphModel.prototype.setTerminals = function(edge, source, target)
{
this.beginUpdate();
try
{
this.setTerminal(edge, source, true);
this.setTerminal(edge, target, false);
}
finally
{
this.endUpdate();
}
};
mxGraphModel.prototype.terminalForCellChanged = function(edge, terminal, isSource)
{
var previous = this.getTerminal(edge, isSource);
if (terminal != null)
{
terminal.insertEdge(edge, isSource);
}
else if (previous != null)
{
previous.removeEdge(edge, isSource);
}
return previous;
};
mxGraphModel.prototype.getEdgeCount = function(cell)
{
return (cell != null) ? cell.getEdgeCount() : 0;
};
mxGraphModel.prototype.getEdgeAt = function(cell, index)
{
return (cell != null) ? cell.getEdgeAt(index) : null;
};
mxGraphModel.prototype.getDirectedEdgeCount = function(cell, outgoing, ignoredEdge)
{
var count = 0;
var edgeCount = this.getEdgeCount(cell);
for (var i = 0; i < edgeCount; i++)
{
var edge = this.getEdgeAt(cell, i);
if (edge != ignoredEdge && this.getTerminal(edge, outgoing) == cell)
{
count++;
}
}
return count;
};
mxGraphModel.prototype.getConnections = function(cell)
{
return this.getEdges(cell, true, true, false);
};
mxGraphModel.prototype.getIncomingEdges = function(cell)
{
return this.getEdges(cell, true, false, false);
};
mxGraphModel.prototype.getOutgoingEdges = function(cell)
{
return this.getEdges(cell, false, true, false);
};
mxGraphModel.prototype.getEdges = function(cell, incoming, outgoing, includeLoops)
{
incoming = (incoming != null) ? incoming : true;
outgoing = (outgoing != null) ? outgoing : true;
includeLoops = (includeLoops != null) ? includeLoops : true;
var edgeCount = this.getEdgeCount(cell);
var result = [];
for (var i = 0; i < edgeCount; i++)
{
var edge = this.getEdgeAt(cell, i);
var source = this.getTerminal(edge, true);
var target = this.getTerminal(edge, false);
if ((includeLoops && source == target) || ((source != target) && ((incoming && target == cell) ||
(outgoing && source == cell))))
{
result.push(edge);
}
}
return result;
};
mxGraphModel.prototype.getEdgesBetween = function(source, target, directed)
{
directed = (directed != null) ? directed : false;
var tmp1 = this.getEdgeCount(source);
var tmp2 = this.getEdgeCount(target);
var terminal = source;
var edgeCount = tmp1;
if (tmp2 < tmp1)
{
edgeCount = tmp2;
terminal = target;
}
var result = [];
for (var i = 0; i < edgeCount; i++)
{
var edge = this.getEdgeAt(terminal, i);
var src = this.getTerminal(edge, true);
var trg = this.getTerminal(edge, false);
var directedMatch = (src == source) && (trg == target);
var oppositeMatch = (trg == source) && (src == target);
if (directedMatch || (!directed && oppositeMatch))
{
result.push(edge);
}
}
return result;
};
mxGraphModel.prototype.getOpposites = function(edges, terminal, sources, targets)
{
sources = (sources != null) ? sources : true;
targets = (targets != null) ? targets : true;
var terminals = [];
if (edges != null)
{
for (var i = 0; i < edges.length; i++)
{
var source = this.getTerminal(edges[i], true);
var target = this.getTerminal(edges[i], false);
if (source == terminal && target != null && target != terminal && targets)
{
terminals.push(target);
}
else if (target == terminal && source != null && source != terminal && sources)
{
terminals.push(source);
}
}
}
return terminals;
};
mxGraphModel.prototype.getTopmostCells = function(cells)
{
var dict = new mxDictionary();
var tmp = [];
for (var i = 0; i < cells.length; i++)
{
dict.put(cells[i], true);
}
for (var i = 0; i < cells.length; i++)
{
var cell = cells[i];
var topmost = true;
var parent = this.getParent(cell);
while (parent != null)
{
if (dict.get(parent))
{
topmost = false;
break;
}
parent = this.getParent(parent);
}
if (topmost)
{
tmp.push(cell);
}
}
return tmp;
};
mxGraphModel.prototype.isVertex = function(cell)
{
return (cell != null) ? cell.isVertex() : false;
};
mxGraphModel.prototype.isEdge = function(cell)
{
return (cell != null) ? cell.isEdge() : false;
};
mxGraphModel.prototype.isConnectable = function(cell)
{
return (cell != null) ? cell.isConnectable() : false;
};
mxGraphModel.prototype.getValue = function(cell)
{
return (cell != null) ? cell.getValue() : null;
};
mxGraphModel.prototype.setValue = function(cell, value)
{
this.execute(new mxValueChange(this, cell, value));
return value;
};
mxGraphModel.prototype.valueForCellChanged = function(cell, value)
{
return cell.valueChanged(value);
};
mxGraphModel.prototype.getGeometry = function(cell)
{
return (cell != null) ? cell.getGeometry() : null;
};
mxGraphModel.prototype.setGeometry = function(cell, geometry)
{
if (geometry != this.getGeometry(cell))
{
this.execute(new mxGeometryChange(this, cell, geometry));
}
return geometry;
};
mxGraphModel.prototype.geometryForCellChanged = function(cell, geometry)
{
var previous = this.getGeometry(cell);
cell.setGeometry(geometry);
return previous;
};
mxGraphModel.prototype.getStyle = function(cell)
{
return (cell != null) ? cell.getStyle() : null;
};
mxGraphModel.prototype.setStyle = function(cell, style)
{
if (style != this.getStyle(cell))
{
this.execute(new mxStyleChange(this, cell, style));
}
return style;
};
mxGraphModel.prototype.styleForCellChanged = function(cell, style)
{
var previous = this.getStyle(cell);
cell.setStyle(style);
return previous;
};
mxGraphModel.prototype.isCollapsed = function(cell)
{
return (cell != null) ? cell.isCollapsed() : false;
};
mxGraphModel.prototype.setCollapsed = function(cell, collapsed)
{
if (collapsed != this.isCollapsed(cell))
{
this.execute(new mxCollapseChange(this, cell, collapsed));
}
return collapsed;
};
mxGraphModel.prototype.collapsedStateForCellChanged = function(cell, collapsed)
{
var previous = this.isCollapsed(cell);
cell.setCollapsed(collapsed);
return previous;
};
mxGraphModel.prototype.isVisible = function(cell)
{
return (cell != null) ? cell.isVisible() : false;
};
mxGraphModel.prototype.setVisible = function(cell, visible)
{
if (visible != this.isVisible(cell))
{
this.execute(new mxVisibleChange(this, cell, visible));
}
return visible;
};
mxGraphModel.prototype.visibleStateForCellChanged = function(cell, visible)
{
var previous = this.isVisible(cell);
cell.setVisible(visible);
return previous;
};
mxGraphModel.prototype.execute = function(change)
{
change.execute();
this.beginUpdate();
this.currentEdit.add(change);
this.fireEvent(new mxEventObject(mxEvent.EXECUTE, 'change', change));
this.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
this.endUpdate();
};
mxGraphModel.prototype.beginUpdate = function()
{
this.updateLevel++;
this.fireEvent(new mxEventObject(mxEvent.BEGIN_UPDATE));
if (this.updateLevel == 1)
{
this.fireEvent(new mxEventObject(mxEvent.START_EDIT));
}
};
mxGraphModel.prototype.endUpdate = function()
{
this.updateLevel--;
if (this.updateLevel == 0)
{
this.fireEvent(new mxEventObject(mxEvent.END_EDIT));
}
if (!this.endingUpdate)
{
this.endingUpdate = this.updateLevel == 0;
this.fireEvent(new mxEventObject(mxEvent.END_UPDATE, 'edit', this.currentEdit));
try
{
if (this.endingUpdate && !this.currentEdit.isEmpty())
{
this.fireEvent(new mxEventObject(mxEvent.BEFORE_UNDO, 'edit', this.currentEdit));
var tmp = this.currentEdit;
this.currentEdit = this.createUndoableEdit();
tmp.notify();
this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', tmp));
}
}
finally
{
this.endingUpdate = false;
}
}
};
mxGraphModel.prototype.createUndoableEdit = function(significant)
{
var edit = new mxUndoableEdit(this, (significant != null) ? significant : true);
edit.notify = function()
{
edit.source.fireEvent(new mxEventObject(mxEvent.CHANGE,
'edit', edit, 'changes', edit.changes));
edit.source.fireEvent(new mxEventObject(mxEvent.NOTIFY,
'edit', edit, 'changes', edit.changes));
};
return edit;
};
mxGraphModel.prototype.mergeChildren = function(from, to, cloneAllEdges)
{
cloneAllEdges = (cloneAllEdges != null) ? cloneAllEdges : true;
this.beginUpdate();
try
{
var mapping = new Object();
this.mergeChildrenImpl(from, to, cloneAllEdges, mapping);
for (var key in mapping)
{
var cell = mapping[key];
var terminal = this.getTerminal(cell, true);
if (terminal != null)
{
terminal = mapping[mxCellPath.create(terminal)];
this.setTerminal(cell, terminal, true);
}
terminal = this.getTerminal(cell, false);
if (terminal != null)
{
terminal = mapping[mxCellPath.create(terminal)];
this.setTerminal(cell, terminal, false);
}
}
}
finally
{
this.endUpdate();
}
};
mxGraphModel.prototype.mergeChildrenImpl = function(from, to, cloneAllEdges, mapping)
{
this.beginUpdate();
try
{
var childCount = from.getChildCount();
for (var i = 0; i < childCount; i++)
{
var cell = from.getChildAt(i);
if (typeof(cell.getId) == 'function')
{
var id = cell.getId();
var target = (id != null && (!this.isEdge(cell) || !cloneAllEdges)) ?
this.getCell(id) : null;
if (target == null)
{
var clone = cell.clone();
clone.setId(id);
clone.setTerminal(cell.getTerminal(true), true);
clone.setTerminal(cell.getTerminal(false), false);
target = to.insert(clone);
this.cellAdded(target);
}
mapping[mxCellPath.create(cell)] = target;
this.mergeChildrenImpl(cell, target, cloneAllEdges, mapping);
}
}
}
finally
{
this.endUpdate();
}
};
mxGraphModel.prototype.getParents = function(cells)
{
var parents = [];
if (cells != null)
{
var dict = new mxDictionary();
for (var i = 0; i < cells.length; i++)
{
var parent = this.getParent(cells[i]);
if (parent != null && !dict.get(parent))
{
dict.put(parent, true);
parents.push(parent);
}
}
}
return parents;
};
mxGraphModel.prototype.cloneCell = function(cell, includeChildren)
{
if (cell != null)
{
return this.cloneCells([cell], includeChildren)[0];
}
return null;
};
mxGraphModel.prototype.cloneCells = function(cells, includeChildren, mapping)
{
includeChildren = (includeChildren != null) ? includeChildren : true;
mapping = (mapping != null) ? mapping : new Object();
var clones = [];
for (var i = 0; i < cells.length; i++)
{
if (cells[i] != null)
{
clones.push(this.cloneCellImpl(cells[i], mapping, includeChildren));
}
else
{
clones.push(null);
}
}
for (var i = 0; i < clones.length; i++)
{
if (clones[i] != null)
{
this.restoreClone(clones[i], cells[i], mapping);
}
}
return clones;
};
mxGraphModel.prototype.cloneCellImpl = function(cell, mapping, includeChildren)
{
var ident = mxObjectIdentity.get(cell);
var clone = mapping[ident];
if (clone == null)
{
clone = this.cellCloned(cell);
mapping[ident] = clone;
if (includeChildren)
{
var childCount = this.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var cloneChild = this.cloneCellImpl(
this.getChildAt(cell, i), mapping, true);
clone.insert(cloneChild);
}
}
}
return clone;
};
mxGraphModel.prototype.cellCloned = function(cell)
{
return cell.clone();
};
mxGraphModel.prototype.restoreClone = function(clone, cell, mapping)
{
var source = this.getTerminal(cell, true);
if (source != null)
{
var tmp = mapping[mxObjectIdentity.get(source)];
if (tmp != null)
{
tmp.insertEdge(clone, true);
}
}
var target = this.getTerminal(cell, false);
if (target != null)
{
var tmp = mapping[mxObjectIdentity.get(target)];
if (tmp != null)
{
tmp.insertEdge(clone, false);
}
}
var childCount = this.getChildCount(clone);
for (var i = 0; i < childCount; i++)
{
this.restoreClone(this.getChildAt(clone, i),
this.getChildAt(cell, i), mapping);
}
};
function mxRootChange(model, root)
{
this.model = model;
this.root = root;
this.previous = root;
} mxRootChange.prototype.execute = function()
{
this.root = this.previous;
this.previous = this.model.rootChanged(this.previous);
};
function mxChildChange(model, parent, child, index)
{
this.model = model;
this.parent = parent;
this.previous = parent;
this.child = child;
this.index = index;
this.previousIndex = index;
} mxChildChange.prototype.execute = function()
{
if (this.child != null)
{
var tmp = this.model.getParent(this.child);
var tmp2 = (tmp != null) ? tmp.getIndex(this.child) : 0;
if (this.previous == null)
{
this.connect(this.child, false);
}
tmp = this.model.parentForCellChanged(
this.child, this.previous, this.previousIndex);
if (this.previous != null)
{
this.connect(this.child, true);
}
this.parent = this.previous;
this.previous = tmp;
this.index = this.previousIndex;
this.previousIndex = tmp2;
}
};
mxChildChange.prototype.connect = function(cell, isConnect)
{
isConnect = (isConnect != null) ? isConnect : true;
var source = cell.getTerminal(true);
var target = cell.getTerminal(false);
if (source != null)
{
if (isConnect)
{
this.model.terminalForCellChanged(cell, source, true);
}
else
{
this.model.terminalForCellChanged(cell, null, true);
}
}
if (target != null)
{
if (isConnect)
{
this.model.terminalForCellChanged(cell, target, false);
}
else
{
this.model.terminalForCellChanged(cell, null, false);
}
}
cell.setTerminal(source, true);
cell.setTerminal(target, false);
var childCount = this.model.getChildCount(cell);
for (var i=0; i<childCount; i++)
{
this.connect(this.model.getChildAt(cell, i), isConnect);
}
};
function mxTerminalChange(model, cell, terminal, source)
{
this.model = model;
this.cell = cell;
this.terminal = terminal;
this.previous = terminal;
this.source = source;
} mxTerminalChange.prototype.execute = function()
{
if (this.cell != null)
{
this.terminal = this.previous;
this.previous = this.model.terminalForCellChanged(
this.cell, this.previous, this.source);
}
};
function mxValueChange(model, cell, value)
{
this.model = model;
this.cell = cell;
this.value = value;
this.previous = value;
} mxValueChange.prototype.execute = function()
{
if (this.cell != null)
{
this.value = this.previous;
this.previous = this.model.valueForCellChanged(
this.cell, this.previous);
}
};
function mxStyleChange(model, cell, style)
{
this.model = model;
this.cell = cell;
this.style = style;
this.previous = style;
} mxStyleChange.prototype.execute = function()
{
if (this.cell != null)
{
this.style = this.previous;
this.previous = this.model.styleForCellChanged(
this.cell, this.previous);
}
};
function mxGeometryChange(model, cell, geometry)
{
this.model = model;
this.cell = cell;
this.geometry = geometry;
this.previous = geometry;
} mxGeometryChange.prototype.execute = function()
{
if (this.cell != null)
{
this.geometry = this.previous;
this.previous = this.model.geometryForCellChanged(
this.cell, this.previous);
}
};
function mxCollapseChange(model, cell, collapsed)
{
this.model = model;
this.cell = cell;
this.collapsed = collapsed;
this.previous = collapsed;
} mxCollapseChange.prototype.execute = function()
{
if (this.cell != null)
{
this.collapsed = this.previous;
this.previous = this.model.collapsedStateForCellChanged(
this.cell, this.previous);
}
};
function mxVisibleChange(model, cell, visible)
{
this.model = model;
this.cell = cell;
this.visible = visible;
this.previous = visible;
} mxVisibleChange.prototype.execute = function()
{
if (this.cell != null)
{
this.visible = this.previous;
this.previous = this.model.visibleStateForCellChanged(
this.cell, this.previous);
}
};
function mxCellAttributeChange(cell, attribute, value)
{
this.cell = cell;
this.attribute = attribute;
this.value = value;
this.previous = value;
} mxCellAttributeChange.prototype.execute = function()
{
if (this.cell != null)
{
var tmp = this.cell.getAttribute(this.attribute);
if (this.previous == null)
{
this.cell.value.removeAttribute(this.attribute);
}
else
{
this.cell.setAttribute(this.attribute, this.previous);
}
this.previous = tmp;
}
};
__mxOutput.mxGraphModel = typeof mxGraphModel !== 'undefined' ? mxGraphModel : undefined;
function mxCell(value, geometry, style)
{
this.value = value;
this.setGeometry(geometry);
this.setStyle(style);
if (this.onInit != null)
{
this.onInit();
}
} mxCell.prototype.id = null;
mxCell.prototype.value = null;
mxCell.prototype.geometry = null;
mxCell.prototype.style = null;
mxCell.prototype.vertex = false;
mxCell.prototype.edge = false;
mxCell.prototype.connectable = true;
mxCell.prototype.visible = true;
mxCell.prototype.collapsed = false;
mxCell.prototype.parent = null;
mxCell.prototype.source = null;
mxCell.prototype.target = null;
mxCell.prototype.children = null;
mxCell.prototype.edges = null;
mxCell.prototype.mxTransient = ['id', 'value', 'parent', 'source',
'target', 'children', 'edges'];
mxCell.prototype.getId = function()
{
return this.id;
};
mxCell.prototype.setId = function(id)
{
this.id = id;
};
mxCell.prototype.getValue = function()
{
return this.value;
};
mxCell.prototype.setValue = function(value)
{
this.value = value;
};
mxCell.prototype.valueChanged = function(newValue)
{
var previous = this.getValue();
this.setValue(newValue);
return previous;
};
mxCell.prototype.getGeometry = function()
{
return this.geometry;
};
mxCell.prototype.setGeometry = function(geometry)
{
this.geometry = geometry;
};
mxCell.prototype.getStyle = function()
{
return this.style;
};
mxCell.prototype.setStyle = function(style)
{
this.style = style;
};
mxCell.prototype.isVertex = function()
{
return this.vertex != 0;
};
mxCell.prototype.setVertex = function(vertex)
{
this.vertex = vertex;
};
mxCell.prototype.isEdge = function()
{
return this.edge != 0;
};
mxCell.prototype.setEdge = function(edge)
{
this.edge = edge;
};
mxCell.prototype.isConnectable = function()
{
return this.connectable != 0;
};
mxCell.prototype.setConnectable = function(connectable)
{
this.connectable = connectable;
};
mxCell.prototype.isVisible = function()
{
return this.visible != 0;
};
mxCell.prototype.setVisible = function(visible)
{
this.visible = visible;
};
mxCell.prototype.isCollapsed = function()
{
return this.collapsed != 0;
};
mxCell.prototype.setCollapsed = function(collapsed)
{
this.collapsed = collapsed;
};
mxCell.prototype.getParent = function()
{
return this.parent;
};
mxCell.prototype.setParent = function(parent)
{
this.parent = parent;
};
mxCell.prototype.getTerminal = function(source)
{
return (source) ? this.source : this.target;
};
mxCell.prototype.setTerminal = function(terminal, isSource)
{
if (isSource)
{
this.source = terminal;
}
else
{
this.target = terminal;
}
return terminal;
};
mxCell.prototype.getChildCount = function()
{
return (this.children == null) ? 0 : this.children.length;
};
mxCell.prototype.getIndex = function(child)
{
return mxUtils.indexOf(this.children, child);
};
mxCell.prototype.getChildAt = function(index)
{
return (this.children == null) ? null : this.children[index];
};
mxCell.prototype.insert = function(child, index)
{
if (child != null)
{
if (index == null)
{
index = this.getChildCount();
if (child.getParent() == this)
{
index--;
}
}
child.removeFromParent();
child.setParent(this);
if (this.children == null)
{
this.children = [];
this.children.push(child);
}
else
{
this.children.splice(index, 0, child);
}
}
return child;
};
mxCell.prototype.remove = function(index)
{
var child = null;
if (this.children != null && index >= 0)
{
child = this.getChildAt(index);
if (child != null)
{
this.children.splice(index, 1);
child.setParent(null);
}
}
return child;
};
mxCell.prototype.removeFromParent = function()
{
if (this.parent != null)
{
var index = this.parent.getIndex(this);
this.parent.remove(index);
}
};
mxCell.prototype.getEdgeCount = function()
{
return (this.edges == null) ? 0 : this.edges.length;
};
mxCell.prototype.getEdgeIndex = function(edge)
{
return mxUtils.indexOf(this.edges, edge);
};
mxCell.prototype.getEdgeAt = function(index)
{
return (this.edges == null) ? null : this.edges[index];
};
mxCell.prototype.insertEdge = function(edge, isOutgoing)
{
if (edge != null)
{
edge.removeFromTerminal(isOutgoing);
edge.setTerminal(this, isOutgoing);
if (this.edges == null ||
edge.getTerminal(!isOutgoing) != this ||
mxUtils.indexOf(this.edges, edge) < 0)
{
if (this.edges == null)
{
this.edges = [];
}
this.edges.push(edge);
}
}
return edge;
};
mxCell.prototype.removeEdge = function(edge, isOutgoing)
{
if (edge != null)
{
if (edge.getTerminal(!isOutgoing) != this &&
this.edges != null)
{
var index = this.getEdgeIndex(edge);
if (index >= 0)
{
this.edges.splice(index, 1);
}
}
edge.setTerminal(null, isOutgoing);
}
return edge;
};
mxCell.prototype.removeFromTerminal = function(isSource)
{
var terminal = this.getTerminal(isSource);
if (terminal != null)
{
terminal.removeEdge(this, isSource);
}
};
mxCell.prototype.hasAttribute = function(name)
{
var userObject = this.getValue();
return (userObject != null &&
userObject.nodeType == mxConstants.NODETYPE_ELEMENT && userObject.hasAttribute) ?
userObject.hasAttribute(name) : userObject.getAttribute(name) != null;
};
mxCell.prototype.getAttribute = function(name, defaultValue)
{
var userObject = this.getValue();
var val = (userObject != null &&
userObject.nodeType == mxConstants.NODETYPE_ELEMENT) ?
userObject.getAttribute(name) : null;
return (val != null) ? val : defaultValue;
};
mxCell.prototype.setAttribute = function(name, value)
{
var userObject = this.getValue();
if (userObject != null &&
userObject.nodeType == mxConstants.NODETYPE_ELEMENT)
{
userObject.setAttribute(name, value);
}
};
mxCell.prototype.clone = function()
{
var clone = mxUtils.clone(this, this.mxTransient);
clone.setValue(this.cloneValue());
return clone;
};
mxCell.prototype.cloneValue = function()
{
var value = this.getValue();
if (value != null)
{
if (typeof(value.clone) == 'function')
{
value = value.clone();
}
else if (!isNaN(value.nodeType))
{
value = value.cloneNode(true);
}
}
return value;
};
__mxOutput.mxCell = typeof mxCell !== 'undefined' ? mxCell : undefined;
function mxGeometry(x, y, width, height)
{
mxRectangle.call(this, x, y, width, height);
} mxGeometry.prototype = new mxRectangle();
mxGeometry.prototype.constructor = mxGeometry;
mxGeometry.prototype.TRANSLATE_CONTROL_POINTS = true;
mxGeometry.prototype.alternateBounds = null;
mxGeometry.prototype.sourcePoint = null;
mxGeometry.prototype.targetPoint = null;
mxGeometry.prototype.points = null;
mxGeometry.prototype.offset = null;
mxGeometry.prototype.relative = false;
mxGeometry.prototype.swap = function()
{
if (this.alternateBounds != null)
{
var old = new mxRectangle(
this.x, this.y, this.width, this.height);
this.x = this.alternateBounds.x;
this.y = this.alternateBounds.y;
this.width = this.alternateBounds.width;
this.height = this.alternateBounds.height;
this.alternateBounds = old;
}
};
mxGeometry.prototype.getTerminalPoint = function(isSource)
{
return (isSource) ? this.sourcePoint : this.targetPoint;
};
mxGeometry.prototype.setTerminalPoint = function(point, isSource)
{
if (isSource)
{
this.sourcePoint = point;
}
else
{
this.targetPoint = point;
}
return point;
};
mxGeometry.prototype.rotate = function(angle, cx)
{
var rad = mxUtils.toRadians(angle);
var cos = Math.cos(rad);
var sin = Math.sin(rad);
if (!this.relative)
{
var ct = new mxPoint(this.getCenterX(), this.getCenterY());
var pt = mxUtils.getRotatedPoint(ct, cos, sin, cx);
this.x = Math.round(pt.x - this.width / 2);
this.y = Math.round(pt.y - this.height / 2);
}
if (this.sourcePoint != null)
{
var pt = mxUtils.getRotatedPoint(this.sourcePoint, cos, sin, cx);
this.sourcePoint.x = Math.round(pt.x);
this.sourcePoint.y = Math.round(pt.y);
}
if (this.targetPoint != null)
{
var pt = mxUtils.getRotatedPoint(this.targetPoint, cos, sin, cx);
this.targetPoint.x = Math.round(pt.x);
this.targetPoint.y = Math.round(pt.y);
}
if (this.points != null)
{
for (var i = 0; i < this.points.length; i++)
{
if (this.points[i] != null)
{
var pt = mxUtils.getRotatedPoint(this.points[i], cos, sin, cx);
this.points[i].x = Math.round(pt.x);
this.points[i].y = Math.round(pt.y);
}
}
}
};
mxGeometry.prototype.translate = function(dx, dy)
{
dx = parseFloat(dx);
dy = parseFloat(dy);
if (!this.relative)
{
this.x = parseFloat(this.x) + dx;
this.y = parseFloat(this.y) + dy;
}
if (this.sourcePoint != null)
{
this.sourcePoint.x = parseFloat(this.sourcePoint.x) + dx;
this.sourcePoint.y = parseFloat(this.sourcePoint.y) + dy;
}
if (this.targetPoint != null)
{
this.targetPoint.x = parseFloat(this.targetPoint.x) + dx;
this.targetPoint.y = parseFloat(this.targetPoint.y) + dy;
}
if (this.TRANSLATE_CONTROL_POINTS && this.points != null)
{
for (var i = 0; i < this.points.length; i++)
{
if (this.points[i] != null)
{
this.points[i].x = parseFloat(this.points[i].x) + dx;
this.points[i].y = parseFloat(this.points[i].y) + dy;
}
}
}
};
mxGeometry.prototype.scale = function(sx, sy, fixedAspect)
{
sx = parseFloat(sx);
sy = parseFloat(sy);
if (this.sourcePoint != null)
{
this.sourcePoint.x = parseFloat(this.sourcePoint.x) * sx;
this.sourcePoint.y = parseFloat(this.sourcePoint.y) * sy;
}
if (this.targetPoint != null)
{
this.targetPoint.x = parseFloat(this.targetPoint.x) * sx;
this.targetPoint.y = parseFloat(this.targetPoint.y) * sy;
}
if (this.points != null)
{
for (var i = 0; i < this.points.length; i++)
{
if (this.points[i] != null)
{
this.points[i].x = parseFloat(this.points[i].x) * sx;
this.points[i].y = parseFloat(this.points[i].y) * sy;
}
}
}
if (!this.relative)
{
this.x = parseFloat(this.x) * sx;
this.y = parseFloat(this.y) * sy;
if (fixedAspect)
{
sy = sx = Math.min(sx, sy);
}
this.width = parseFloat(this.width) * sx;
this.height = parseFloat(this.height) * sy;
}
};
mxGeometry.prototype.equals = function(obj)
{
return mxRectangle.prototype.equals.apply(this, arguments) &&
this.relative == obj.relative &&
((this.sourcePoint == null && obj.sourcePoint == null) || (this.sourcePoint != null && this.sourcePoint.equals(obj.sourcePoint))) &&
((this.targetPoint == null && obj.targetPoint == null) || (this.targetPoint != null && this.targetPoint.equals(obj.targetPoint))) &&
((this.points == null && obj.points == null) || (this.points != null && mxUtils.equalPoints(this.points, obj.points))) &&
((this.alternateBounds == null && obj.alternateBounds == null) || (this.alternateBounds != null && this.alternateBounds.equals(obj.alternateBounds))) &&
((this.offset == null && obj.offset == null) || (this.offset != null && this.offset.equals(obj.offset)));
};
__mxOutput.mxGeometry = typeof mxGeometry !== 'undefined' ? mxGeometry : undefined;
var mxCellPath =
{
PATH_SEPARATOR: '.',
create: function(cell)
{
var result = '';
if (cell != null)
{
var parent = cell.getParent();
while (parent != null)
{
var index = parent.getIndex(cell);
result = index + mxCellPath.PATH_SEPARATOR + result;
cell = parent;
parent = cell.getParent();
}
}
var n = result.length;
if (n > 1)
{
result = result.substring(0, n - 1);
}
return result;
},
getParentPath: function(path)
{
if (path != null)
{
var index = path.lastIndexOf(mxCellPath.PATH_SEPARATOR);
if (index >= 0)
{
return path.substring(0, index);
}
else if (path.length > 0)
{
return '';
}
}
return null;
},
resolve: function(root, path)
{
var parent = root;
if (path != null)
{
var tokens = path.split(mxCellPath.PATH_SEPARATOR);
for (var i=0; i<tokens.length; i++)
{
parent = parent.getChildAt(parseInt(tokens[i]));
}
}
return parent;
},
compare: function(p1, p2)
{
var min = Math.min(p1.length, p2.length);
var comp = 0;
for (var i = 0; i < min; i++)
{
if (p1[i] != p2[i])
{
if (p1[i].length == 0 ||
p2[i].length == 0)
{
comp = (p1[i] == p2[i]) ? 0 : ((p1[i] > p2[i]) ? 1 : -1);
}
else
{
var t1 = parseInt(p1[i]);
var t2 = parseInt(p2[i]);
comp = (t1 == t2) ? 0 : ((t1 > t2) ? 1 : -1);
}
break;
}
}
if (comp == 0)
{
var t1 = p1.length;
var t2 = p2.length;
if (t1 != t2)
{
comp = (t1 > t2) ? 1 : -1;
}
}
return comp;
}
};
__mxOutput.mxCellPath = typeof mxCellPath !== 'undefined' ? mxCellPath : undefined;
var mxPerimeter =
{
RectanglePerimeter: function (bounds, vertex, next, orthogonal)
{
var cx = bounds.getCenterX();
var cy = bounds.getCenterY();
var dx = next.x - cx;
var dy = next.y - cy;
var alpha = Math.atan2(dy, dx);
var p = new mxPoint(0, 0);
var pi = Math.PI;
var pi2 = Math.PI/2;
var beta = pi2 - alpha;
var t = Math.atan2(bounds.height, bounds.width);
if (alpha < -pi + t || alpha > pi - t)
{
p.x = bounds.x;
p.y = cy - bounds.width * Math.tan(alpha) / 2;
}
else if (alpha < -t)
{
p.y = bounds.y;
p.x = cx - bounds.height * Math.tan(beta) / 2;
}
else if (alpha < t)
{
p.x = bounds.x + bounds.width;
p.y = cy + bounds.width * Math.tan(alpha) / 2;
}
else
{
p.y = bounds.y + bounds.height;
p.x = cx + bounds.height * Math.tan(beta) / 2;
}
if (orthogonal)
{
if (next.x >= bounds.x &&
next.x <= bounds.x + bounds.width)
{
p.x = next.x;
}
else if (next.y >= bounds.y &&
next.y <= bounds.y + bounds.height)
{
p.y = next.y;
}
if (next.x < bounds.x)
{
p.x = bounds.x;
}
else if (next.x > bounds.x + bounds.width)
{
p.x = bounds.x + bounds.width;
}
if (next.y < bounds.y)
{
p.y = bounds.y;
}
else if (next.y > bounds.y + bounds.height)
{
p.y = bounds.y + bounds.height;
}
}
return p;
},
EllipsePerimeter: function (bounds, vertex, next, orthogonal)
{
var x = bounds.x;
var y = bounds.y;
var a = bounds.width / 2;
var b = bounds.height / 2;
var cx = x + a;
var cy = y + b;
var px = next.x;
var py = next.y;
var dx = parseInt(px - cx);
var dy = parseInt(py - cy);
if (dx == 0 && dy != 0)
{
return new mxPoint(cx, cy + b * dy / Math.abs(dy));
}
else if (dx == 0 && dy == 0)
{
return new mxPoint(px, py);
}
if (orthogonal)
{
if (py >= y && py <= y + bounds.height)
{
var ty = py - cy;
var tx = Math.sqrt(a*a*(1-(ty*ty)/(b*b))) || 0;
if (px <= x)
{
tx = -tx;
}
return new mxPoint(cx+tx, py);
}
if (px >= x && px <= x + bounds.width)
{
var tx = px - cx;
var ty = Math.sqrt(b*b*(1-(tx*tx)/(a*a))) || 0;
if (py <= y)
{
ty = -ty;
}
return new mxPoint(px, cy+ty);
}
}
var d = dy / dx;
var h = cy - d * cx;
var e = a * a * d * d + b * b;
var f = -2 * cx * e;
var g = a * a * d * d * cx * cx +
b * b * cx * cx -
a * a * b * b;
var det = Math.sqrt(f * f - 4 * e * g);
var xout1 = (-f + det) / (2 * e);
var xout2 = (-f - det) / (2 * e);
var yout1 = d * xout1 + h;
var yout2 = d * xout2 + h;
var dist1 = Math.sqrt(Math.pow((xout1 - px), 2)
+ Math.pow((yout1 - py), 2));
var dist2 = Math.sqrt(Math.pow((xout2 - px), 2)
+ Math.pow((yout2 - py), 2));
var xout = 0;
var yout = 0;
if (dist1 < dist2)
{
xout = xout1;
yout = yout1;
}
else
{
xout = xout2;
yout = yout2;
}
return new mxPoint(xout, yout);
},
RhombusPerimeter: function (bounds, vertex, next, orthogonal)
{
var x = bounds.x;
var y = bounds.y;
var w = bounds.width;
var h = bounds.height;
var cx = x + w / 2;
var cy = y + h / 2;
var px = next.x;
var py = next.y;
if (cx == px)
{
if (cy > py)
{
return new mxPoint(cx, y);
}
else
{
return new mxPoint(cx, y + h);
}
}
else if (cy == py)
{
if (cx > px)
{
return new mxPoint(x, cy);
}
else
{
return new mxPoint(x + w, cy);
}
}
var tx = cx;
var ty = cy;
if (orthogonal)
{
if (px >= x && px <= x + w)
{
tx = px;
}
else if (py >= y && py <= y + h)
{
ty = py;
}
}
if (px < cx)
{
if (py < cy)
{
return mxUtils.intersection(px, py, tx, ty, cx, y, x, cy);
}
else
{
return mxUtils.intersection(px, py, tx, ty, cx, y + h, x, cy);
}
}
else if (py < cy)
{
return mxUtils.intersection(px, py, tx, ty, cx, y, x + w, cy);
}
else
{
return mxUtils.intersection(px, py, tx, ty, cx, y + h, x + w, cy);
}
},
TrianglePerimeter: function (bounds, vertex, next, orthogonal)
{
var direction = (vertex != null) ?
vertex.style[mxConstants.STYLE_DIRECTION] : null;
var vertical = direction == mxConstants.DIRECTION_NORTH ||
direction == mxConstants.DIRECTION_SOUTH;
var x = bounds.x;
var y = bounds.y;
var w = bounds.width;
var h = bounds.height;
var cx = x + w / 2;
var cy = y + h / 2;
var start = new mxPoint(x, y);
var corner = new mxPoint(x + w, cy);
var end = new mxPoint(x, y + h);
if (direction == mxConstants.DIRECTION_NORTH)
{
start = end;
corner = new mxPoint(cx, y);
end = new mxPoint(x + w, y + h);
}
else if (direction == mxConstants.DIRECTION_SOUTH)
{
corner = new mxPoint(cx, y + h);
end = new mxPoint(x + w, y);
}
else if (direction == mxConstants.DIRECTION_WEST)
{
start = new mxPoint(x + w, y);
corner = new mxPoint(x, cy);
end = new mxPoint(x + w, y + h);
}
var dx = next.x - cx;
var dy = next.y - cy;
var alpha = (vertical) ? Math.atan2(dx, dy) : Math.atan2(dy, dx);
var t = (vertical) ? Math.atan2(w, h) : Math.atan2(h, w);
var base = false;
if (direction == mxConstants.DIRECTION_NORTH ||
direction == mxConstants.DIRECTION_WEST)
{
base = alpha > -t && alpha < t;
}
else
{
base = alpha < -Math.PI + t || alpha > Math.PI - t;
}
var result = null;
if (base)
{
if (orthogonal && ((vertical && next.x >= start.x && next.x <= end.x) ||
(!vertical && next.y >= start.y && next.y <= end.y)))
{
if (vertical)
{
result = new mxPoint(next.x, start.y);
}
else
{
result = new mxPoint(start.x, next.y);
}
}
else
{
if (direction == mxConstants.DIRECTION_NORTH)
{
result = new mxPoint(x + w / 2 + h * Math.tan(alpha) / 2,
y + h);
}
else if (direction == mxConstants.DIRECTION_SOUTH)
{
result = new mxPoint(x + w / 2 - h * Math.tan(alpha) / 2,
y);
}
else if (direction == mxConstants.DIRECTION_WEST)
{
result = new mxPoint(x + w, y + h / 2 +
w * Math.tan(alpha) / 2);
}
else
{
result = new mxPoint(x, y + h / 2 -
w * Math.tan(alpha) / 2);
}
}
}
else
{
if (orthogonal)
{
var pt = new mxPoint(cx, cy);
if (next.y >= y && next.y <= y + h)
{
pt.x = (vertical) ? cx : (
(direction == mxConstants.DIRECTION_WEST) ?
x + w : x);
pt.y = next.y;
}
else if (next.x >= x && next.x <= x + w)
{
pt.x = next.x;
pt.y = (!vertical) ? cy : (
(direction == mxConstants.DIRECTION_NORTH) ?
y + h : y);
}
dx = next.x - pt.x;
dy = next.y - pt.y;
cx = pt.x;
cy = pt.y;
}
if ((vertical && next.x <= x + w / 2) ||
(!vertical && next.y <= y + h / 2))
{
result = mxUtils.intersection(next.x, next.y, cx, cy,
start.x, start.y, corner.x, corner.y);
}
else
{
result = mxUtils.intersection(next.x, next.y, cx, cy,
corner.x, corner.y, end.x, end.y);
}
}
if (result == null)
{
result = new mxPoint(cx, cy);
}
return result;
},
HexagonPerimeter: function (bounds, vertex, next, orthogonal)
{
var x = bounds.x;
var y = bounds.y;
var w = bounds.width;
var h = bounds.height;
var cx = bounds.getCenterX();
var cy = bounds.getCenterY();
var px = next.x;
var py = next.y;
var dx = px - cx;
var dy = py - cy;
var alpha = -Math.atan2(dy, dx);
var pi = Math.PI;
var pi2 = Math.PI / 2;
var result = new mxPoint(cx, cy);
var direction = (vertex != null) ? mxUtils.getValue(
vertex.style, mxConstants.STYLE_DIRECTION,
mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST;
var vertical = direction == mxConstants.DIRECTION_NORTH
|| direction == mxConstants.DIRECTION_SOUTH;
var a = new mxPoint();
var b = new mxPoint();
if ((px < x) && (py < y) || (px < x) && (py > y + h)
|| (px > x + w) && (py < y) || (px > x + w) && (py > y + h))
{
orthogonal = false;
}
if (orthogonal)
{
if (vertical)
{
if (px == cx)
{
if (py <= y)
{
return new mxPoint(cx, y);
}
else if (py >= y + h)
{
return new mxPoint(cx, y + h);
}
}
else if (px < x)
{
if (py == y + h / 4)
{
return new mxPoint(x, y + h / 4);
}
else if (py == y + 3 * h / 4)
{
return new mxPoint(x, y + 3 * h / 4);
}
}
else if (px > x + w)
{
if (py == y + h / 4)
{
return new mxPoint(x + w, y + h / 4);
}
else if (py == y + 3 * h / 4)
{
return new mxPoint(x + w, y + 3 * h / 4);
}
}
else if (px == x)
{
if (py < cy)
{
return new mxPoint(x, y + h / 4);
}
else if (py > cy)
{
return new mxPoint(x, y + 3 * h / 4);
}
}
else if (px == x + w)
{
if (py < cy)
{
return new mxPoint(x + w, y + h / 4);
}
else if (py > cy)
{
return new mxPoint(x + w, y + 3 * h / 4);
}
}
if (py == y)
{
return new mxPoint(cx, y);
}
else if (py == y + h)
{
return new mxPoint(cx, y + h);
}
if (px < cx)
{
if ((py > y + h / 4) && (py < y + 3 * h / 4))
{
a = new mxPoint(x, y);
b = new mxPoint(x, y + h);
}
else if (py < y + h / 4)
{
a = new mxPoint(x - Math.floor(0.5 * w), y
+ Math.floor(0.5 * h));
b = new mxPoint(x + w, y - Math.floor(0.25 * h));
}
else if (py > y + 3 * h / 4)
{
a = new mxPoint(x - Math.floor(0.5 * w), y
+ Math.floor(0.5 * h));
b = new mxPoint(x + w, y + Math.floor(1.25 * h));
}
}
else if (px > cx)
{
if ((py > y + h / 4) && (py < y + 3 * h / 4))
{
a = new mxPoint(x + w, y);
b = new mxPoint(x + w, y + h);
}
else if (py < y + h / 4)
{
a = new mxPoint(x, y - Math.floor(0.25 * h));
b = new mxPoint(x + Math.floor(1.5 * w), y
+ Math.floor(0.5 * h));
}
else if (py > y + 3 * h / 4)
{
a = new mxPoint(x + Math.floor(1.5 * w), y
+ Math.floor(0.5 * h));
b = new mxPoint(x, y + Math.floor(1.25 * h));
}
}
}
else
{
if (py == cy)
{
if (px <= x)
{
return new mxPoint(x, y + h / 2);
}
else if (px >= x + w)
{
return new mxPoint(x + w, y + h / 2);
}
}
else if (py < y)
{
if (px == x + w / 4)
{
return new mxPoint(x + w / 4, y);
}
else if (px == x + 3 * w / 4)
{
return new mxPoint(x + 3 * w / 4, y);
}
}
else if (py > y + h)
{
if (px == x + w / 4)
{
return new mxPoint(x + w / 4, y + h);
}
else if (px == x + 3 * w / 4)
{
return new mxPoint(x + 3 * w / 4, y + h);
}
}
else if (py == y)
{
if (px < cx)
{
return new mxPoint(x + w / 4, y);
}
else if (px > cx)
{
return new mxPoint(x + 3 * w / 4, y);
}
}
else if (py == y + h)
{
if (px < cx)
{
return new mxPoint(x + w / 4, y + h);
}
else if (py > cy)
{
return new mxPoint(x + 3 * w / 4, y + h);
}
}
if (px == x)
{
return new mxPoint(x, cy);
}
else if (px == x + w)
{
return new mxPoint(x + w, cy);
}
if (py < cy)
{
if ((px > x + w / 4) && (px < x + 3 * w / 4))
{
a = new mxPoint(x, y);
b = new mxPoint(x + w, y);
}
else if (px < x + w / 4)
{
a = new mxPoint(x - Math.floor(0.25 * w), y + h);
b = new mxPoint(x + Math.floor(0.5 * w), y
- Math.floor(0.5 * h));
}
else if (px > x + 3 * w / 4)
{
a = new mxPoint(x + Math.floor(0.5 * w), y
- Math.floor(0.5 * h));
b = new mxPoint(x + Math.floor(1.25 * w), y + h);
}
}
else if (py > cy)
{
if ((px > x + w / 4) && (px < x + 3 * w / 4))
{
a = new mxPoint(x, y + h);
b = new mxPoint(x + w, y + h);
}
else if (px < x + w / 4)
{
a = new mxPoint(x - Math.floor(0.25 * w), y);
b = new mxPoint(x + Math.floor(0.5 * w), y
+ Math.floor(1.5 * h));
}
else if (px > x + 3 * w / 4)
{
a = new mxPoint(x + Math.floor(0.5 * w), y
+ Math.floor(1.5 * h));
b = new mxPoint(x + Math.floor(1.25 * w), y);
}
}
}
var tx = cx;
var ty = cy;
if (px >= x && px <= x + w)
{
tx = px;
if (py < cy)
{
ty = y + h;
}
else
{
ty = y;
}
}
else if (py >= y && py <= y + h)
{
ty = py;
if (px < cx)
{
tx = x + w;
}
else
{
tx = x;
}
}
result = mxUtils.intersection(tx, ty, next.x, next.y, a.x, a.y, b.x, b.y);
}
else
{
if (vertical)
{
var beta = Math.atan2(h / 4, w / 2);
if (alpha == beta)
{
return new mxPoint(x + w, y + Math.floor(0.25 * h));
}
else if (alpha == pi2)
{
return new mxPoint(x + Math.floor(0.5 * w), y);
}
else if (alpha == (pi - beta))
{
return new mxPoint(x, y + Math.floor(0.25 * h));
}
else if (alpha == -beta)
{
return new mxPoint(x + w, y + Math.floor(0.75 * h));
}
else if (alpha == (-pi2))
{
return new mxPoint(x + Math.floor(0.5 * w), y + h);
}
else if (alpha == (-pi + beta))
{
return new mxPoint(x, y + Math.floor(0.75 * h));
}
if ((alpha < beta) && (alpha > -beta))
{
a = new mxPoint(x + w, y);
b = new mxPoint(x + w, y + h);
}
else if ((alpha > beta) && (alpha < pi2))
{
a = new mxPoint(x, y - Math.floor(0.25 * h));
b = new mxPoint(x + Math.floor(1.5 * w), y
+ Math.floor(0.5 * h));
}
else if ((alpha > pi2) && (alpha < (pi - beta)))
{
a = new mxPoint(x - Math.floor(0.5 * w), y
+ Math.floor(0.5 * h));
b = new mxPoint(x + w, y - Math.floor(0.25 * h));
}
else if (((alpha > (pi - beta)) && (alpha <= pi))
|| ((alpha < (-pi + beta)) && (alpha >= -pi)))
{
a = new mxPoint(x, y);
b = new mxPoint(x, y + h);
}
else if ((alpha < -beta) && (alpha > -pi2))
{
a = new mxPoint(x + Math.floor(1.5 * w), y
+ Math.floor(0.5 * h));
b = new mxPoint(x, y + Math.floor(1.25 * h));
}
else if ((alpha < -pi2) && (alpha > (-pi + beta)))
{
a = new mxPoint(x - Math.floor(0.5 * w), y
+ Math.floor(0.5 * h));
b = new mxPoint(x + w, y + Math.floor(1.25 * h));
}
}
else
{
var beta = Math.atan2(h / 2, w / 4);
if (alpha == beta)
{
return new mxPoint(x + Math.floor(0.75 * w), y);
}
else if (alpha == (pi - beta))
{
return new mxPoint(x + Math.floor(0.25 * w), y);
}
else if ((alpha == pi) || (alpha == -pi))
{
return new mxPoint(x, y + Math.floor(0.5 * h));
}
else if (alpha == 0)
{
return new mxPoint(x + w, y + Math.floor(0.5 * h));
}
else if (alpha == -beta)
{
return new mxPoint(x + Math.floor(0.75 * w), y + h);
}
else if (alpha == (-pi + beta))
{
return new mxPoint(x + Math.floor(0.25 * w), y + h);
}
if ((alpha > 0) && (alpha < beta))
{
a = new mxPoint(x + Math.floor(0.5 * w), y
- Math.floor(0.5 * h));
b = new mxPoint(x + Math.floor(1.25 * w), y + h);
}
else if ((alpha > beta) && (alpha < (pi - beta)))
{
a = new mxPoint(x, y);
b = new mxPoint(x + w, y);
}
else if ((alpha > (pi - beta)) && (alpha < pi))
{
a = new mxPoint(x - Math.floor(0.25 * w), y + h);
b = new mxPoint(x + Math.floor(0.5 * w), y
- Math.floor(0.5 * h));
}
else if ((alpha < 0) && (alpha > -beta))
{
a = new mxPoint(x + Math.floor(0.5 * w), y
+ Math.floor(1.5 * h));
b = new mxPoint(x + Math.floor(1.25 * w), y);
}
else if ((alpha < -beta) && (alpha > (-pi + beta)))
{
a = new mxPoint(x, y + h);
b = new mxPoint(x + w, y + h);
}
else if ((alpha < (-pi + beta)) && (alpha > -pi))
{
a = new mxPoint(x - Math.floor(0.25 * w), y);
b = new mxPoint(x + Math.floor(0.5 * w), y
+ Math.floor(1.5 * h));
}
}
result = mxUtils.intersection(cx, cy, next.x, next.y, a.x, a.y, b.x, b.y);
}
if (result == null)
{
return new mxPoint(cx, cy);
}
return result;
}
};
__mxOutput.mxPerimeter = typeof mxPerimeter !== 'undefined' ? mxPerimeter : undefined;
function mxPrintPreview(graph, scale, pageFormat, border, x0, y0, borderColor, title, pageSelector)
{
this.graph = graph;
this.scale = (scale != null) ? scale : 1 / graph.pageScale;
this.border = (border != null) ? border : 0;
this.pageFormat = mxRectangle.fromRectangle((pageFormat != null) ? pageFormat : graph.pageFormat);
this.title = (title != null) ? title : 'Printer-friendly version';
this.x0 = (x0 != null) ? x0 : 0;
this.y0 = (y0 != null) ? y0 : 0;
this.borderColor = borderColor;
this.pageSelector = (pageSelector != null) ? pageSelector : true;
} mxPrintPreview.prototype.graph = null;
mxPrintPreview.prototype.pageFormat = null;
mxPrintPreview.prototype.scale = null;
mxPrintPreview.prototype.border = 0;
mxPrintPreview.prototype.marginTop = 0;
mxPrintPreview.prototype.marginBottom = 0;
mxPrintPreview.prototype.x0 = 0;
mxPrintPreview.prototype.y0 = 0;
mxPrintPreview.prototype.autoOrigin = true;
mxPrintPreview.prototype.printOverlays = false;
mxPrintPreview.prototype.printControls = false;
mxPrintPreview.prototype.printBackgroundImage = false;
mxPrintPreview.prototype.backgroundColor = '#ffffff';
mxPrintPreview.prototype.borderColor = null;
mxPrintPreview.prototype.title = null;
mxPrintPreview.prototype.pageSelector = null;
mxPrintPreview.prototype.wnd = null;
mxPrintPreview.prototype.targetWindow = null;
mxPrintPreview.prototype.pageCount = 0;
mxPrintPreview.prototype.clipping = true;
mxPrintPreview.prototype.getWindow = function()
{
return this.wnd;
};
mxPrintPreview.prototype.getDoctype = function()
{
var dt = '';
if (document.documentMode == 5)
{
dt = '<meta http-equiv="X-UA-Compatible" content="IE=5">';
}
else if (document.documentMode == 8)
{
dt = '<meta http-equiv="X-UA-Compatible" content="IE=8">';
}
else if (document.documentMode > 8)
{
dt = '<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->';
}
return dt;
};
mxPrintPreview.prototype.appendGraph = function(graph, scale, x0, y0, forcePageBreaks, keepOpen)
{
this.graph = graph;
this.scale = (scale != null) ? scale : 1 / graph.pageScale;
this.x0 = x0;
this.y0 = y0;
this.open(null, null, forcePageBreaks, keepOpen);
};
mxPrintPreview.prototype.open = function(css, targetWindow, forcePageBreaks, keepOpen)
{
var previousInitializeOverlay = this.graph.cellRenderer.initializeOverlay;
var div = null;
try
{
if (this.printOverlays)
{
this.graph.cellRenderer.initializeOverlay = function(state, overlay)
{
overlay.init(state.view.getDrawPane());
};
}
if (this.printControls)
{
this.graph.cellRenderer.initControl = function(state, control, handleEvents, clickHandler)
{
control.dialect = state.view.graph.dialect;
control.init(state.view.getDrawPane());
};
}
this.wnd = (targetWindow != null) ? targetWindow : this.wnd;
var isNewWindow = false;
if (this.wnd == null)
{
isNewWindow = true;
this.wnd = window.open();
}
var doc = this.wnd.document;
if (isNewWindow)
{
var dt = this.getDoctype();
if (dt != null && dt.length > 0)
{
doc.writeln(dt);
}
if (mxClient.IS_VML)
{
doc.writeln('<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">');
}
else
{
if (document.compatMode === 'CSS1Compat')
{
doc.writeln('<!DOCTYPE html>');
}
doc.writeln('<html>');
}
doc.writeln('<head>');
this.writeHead(doc, css);
doc.writeln('</head>');
doc.writeln('<body class="mxPage">');
}
var bounds = this.graph.getGraphBounds().clone();
var currentScale = this.graph.getView().getScale();
var sc = currentScale / this.scale;
var tr = this.graph.getView().getTranslate();
if (!this.autoOrigin)
{
this.x0 -= tr.x * this.scale;
this.y0 -= tr.y * this.scale;
bounds.width += bounds.x;
bounds.height += bounds.y;
bounds.x = 0;
bounds.y = 0;
this.border = 0;
}
var availableWidth = this.pageFormat.width - (this.border * 2);
var availableHeight = this.pageFormat.height - (this.border * 2);
this.pageFormat.height += this.marginTop + this.marginBottom;
bounds.width /= sc;
bounds.height /= sc;
var hpages = Math.max(1, Math.ceil((bounds.width + this.x0) / availableWidth));
var vpages = Math.max(1, Math.ceil((bounds.height + this.y0) / availableHeight));
this.pageCount = hpages * vpages;
var writePageSelector = mxUtils.bind(this, function()
{
if (this.pageSelector && (vpages > 1 || hpages > 1))
{
var table = this.createPageSelector(vpages, hpages);
doc.body.appendChild(table);
if (mxClient.IS_IE && doc.documentMode == null || doc.documentMode == 5 || doc.documentMode == 8 || doc.documentMode == 7)
{
table.style.position = 'absolute';
var update = function()
{
table.style.top = ((doc.body.scrollTop || doc.documentElement.scrollTop) + 10) + 'px';
};
mxEvent.addListener(this.wnd, 'scroll', function(evt)
{
update();
});
mxEvent.addListener(this.wnd, 'resize', function(evt)
{
update();
});
}
}
});
var addPage = mxUtils.bind(this, function(div, addBreak)
{
if (this.borderColor != null)
{
div.style.borderColor = this.borderColor;
div.style.borderStyle = 'solid';
div.style.borderWidth = '1px';
}
div.style.background = this.backgroundColor;
if (forcePageBreaks || addBreak)
{
div.style.pageBreakAfter = 'always';
}
if (isNewWindow && (mxClient.IS_IE || document.documentMode >= 11 || mxClient.IS_EDGE))
{
doc.writeln(div.outerHTML);
div.parentNode.removeChild(div);
}
else if (mxClient.IS_IE || document.documentMode >= 11 || mxClient.IS_EDGE)
{
var clone = doc.createElement('div');
clone.innerHTML = div.outerHTML;
clone = clone.getElementsByTagName('div')[0];
doc.body.appendChild(clone);
div.parentNode.removeChild(div);
}
else
{
div.parentNode.removeChild(div);
doc.body.appendChild(div);
}
if (forcePageBreaks || addBreak)
{
this.addPageBreak(doc);
}
});
var cov = this.getCoverPages(this.pageFormat.width, this.pageFormat.height);
if (cov != null)
{
for (var i = 0; i < cov.length; i++)
{
addPage(cov[i], true);
}
}
var apx = this.getAppendices(this.pageFormat.width, this.pageFormat.height);
for (var i = 0; i < vpages; i++)
{
var dy = i * availableHeight / this.scale - this.y0 / this.scale +
(bounds.y - tr.y * currentScale) / currentScale;
for (var j = 0; j < hpages; j++)
{
if (this.wnd == null)
{
return null;
}
var dx = j * availableWidth / this.scale - this.x0 / this.scale +
(bounds.x - tr.x * currentScale) / currentScale;
var pageNum = i * hpages + j + 1;
var clip = new mxRectangle(dx, dy, availableWidth, availableHeight);
div = this.renderPage(this.pageFormat.width, this.pageFormat.height, 0, 0, mxUtils.bind(this, function(div)
{
this.addGraphFragment(-dx, -dy, this.scale, pageNum, div, clip);
if (this.printBackgroundImage)
{
this.insertBackgroundImage(div, -dx, -dy);
}
}), pageNum);
div.setAttribute('id', 'mxPage-'+pageNum);
addPage(div, apx != null || i < vpages - 1 || j < hpages - 1);
}
}
if (apx != null)
{
for (var i = 0; i < apx.length; i++)
{
addPage(apx[i], i < apx.length - 1);
}
}
if (isNewWindow && !keepOpen)
{
this.closeDocument();
writePageSelector();
}
this.wnd.focus();
}
catch (e)
{
if (div != null && div.parentNode != null)
{
div.parentNode.removeChild(div);
}
}
finally
{
this.graph.cellRenderer.initializeOverlay = previousInitializeOverlay;
}
return this.wnd;
};
mxPrintPreview.prototype.addPageBreak = function(doc)
{
var hr = doc.createElement('hr');
hr.className = 'mxPageBreak';
doc.body.appendChild(hr);
};
mxPrintPreview.prototype.closeDocument = function()
{
try
{
if (this.wnd != null && this.wnd.document != null)
{
var doc = this.wnd.document;
this.writePostfix(doc);
doc.writeln('</body>');
doc.writeln('</html>');
doc.close();
mxEvent.release(doc.body);
}
}
catch (e)
{
}
};
mxPrintPreview.prototype.writeHead = function(doc, css)
{
if (this.title != null)
{
doc.writeln('<title>' + this.title + '</title>');
}
if (mxClient.IS_VML)
{
doc.writeln('<style type="text/css">v\\:*{behavior:url(#default#VML)}o\\:*{behavior:url(#default#VML)}</style>');
}
mxClient.link('stylesheet', mxClient.basePath + '/css/common.css', doc);
doc.writeln('<style type="text/css">');
doc.writeln('@media print {');
doc.writeln(' * { -webkit-print-color-adjust: exact; }');
doc.writeln(' table.mxPageSelector { display: none; }');
doc.writeln(' hr.mxPageBreak { display: none; }');
doc.writeln('}');
doc.writeln('@media screen {');
doc.writeln(' table.mxPageSelector { position: fixed; right: 10px; top: 10px;' +
'font-family: Arial; font-size:10pt; border: solid 1px darkgray;' +
'background: white; border-collapse:collapse; }');
doc.writeln(' table.mxPageSelector td { border: solid 1px gray; padding:4px; }');
doc.writeln(' body.mxPage { background: gray; }');
doc.writeln('}');
if (css != null)
{
doc.writeln(css);
}
doc.writeln('</style>');
};
mxPrintPreview.prototype.writePostfix = function(doc)
{
};
mxPrintPreview.prototype.createPageSelector = function(vpages, hpages)
{
var doc = this.wnd.document;
var table = doc.createElement('table');
table.className = 'mxPageSelector';
table.setAttribute('border', '0');
var tbody = doc.createElement('tbody');
for (var i = 0; i < vpages; i++)
{
var row = doc.createElement('tr');
for (var j = 0; j < hpages; j++)
{
var pageNum = i * hpages + j + 1;
var cell = doc.createElement('td');
var a = doc.createElement('a');
a.setAttribute('href', '#mxPage-' + pageNum);
if (mxClient.IS_NS && !mxClient.IS_SF && !mxClient.IS_GC)
{
var js = 'var page = document.getElementById(\'mxPage-' + pageNum + '\');page.scrollIntoView(true);event.preventDefault();';
a.setAttribute('onclick', js);
}
mxUtils.write(a, pageNum, doc);
cell.appendChild(a);
row.appendChild(cell);
}
tbody.appendChild(row);
}
table.appendChild(tbody);
return table;
};
mxPrintPreview.prototype.renderPage = function(w, h, dx, dy, content, pageNumber)
{
var doc = this.wnd.document;
var div = document.createElement('div');
var arg = null;
try
{
if (dx != 0 || dy != 0)
{
div.style.position = 'relative';
div.style.width = w + 'px';
div.style.height = h + 'px';
div.style.pageBreakInside = 'avoid';
var innerDiv = document.createElement('div');
innerDiv.style.position = 'relative';
innerDiv.style.top = this.border + 'px';
innerDiv.style.left = this.border + 'px';
innerDiv.style.width = (w - 2 * this.border) + 'px';
innerDiv.style.height = (h - 2 * this.border) + 'px';
innerDiv.style.overflow = 'hidden';
var viewport = document.createElement('div');
viewport.style.position = 'relative';
viewport.style.marginLeft = dx + 'px';
viewport.style.marginTop = dy + 'px';
if (doc.documentMode == 8)
{
innerDiv.style.position = 'absolute';
viewport.style.position = 'absolute';
}
if (doc.documentMode == 10)
{
viewport.style.width = '100%';
viewport.style.height = '100%';
}
innerDiv.appendChild(viewport);
div.appendChild(innerDiv);
document.body.appendChild(div);
arg = viewport;
}
else
{
div.style.width = w + 'px';
div.style.height = h + 'px';
div.style.overflow = 'hidden';
div.style.pageBreakInside = 'avoid';
if (doc.documentMode == 8)
{
div.style.position = 'relative';
}
var innerDiv = document.createElement('div');
innerDiv.style.width = (w - 2 * this.border) + 'px';
innerDiv.style.height = (h - 2 * this.border) + 'px';
innerDiv.style.overflow = 'hidden';
if (mxClient.IS_IE && (doc.documentMode == null || doc.documentMode == 5 ||
doc.documentMode == 8 || doc.documentMode == 7))
{
innerDiv.style.marginTop = this.border + 'px';
innerDiv.style.marginLeft = this.border + 'px';
}
else
{
innerDiv.style.top = this.border + 'px';
innerDiv.style.left = this.border + 'px';
}
if (this.graph.dialect == mxConstants.DIALECT_VML)
{
innerDiv.style.position = 'absolute';
}
div.appendChild(innerDiv);
document.body.appendChild(div);
arg = innerDiv;
}
}
catch (e)
{
div.parentNode.removeChild(div);
div = null;
throw e;
}
content(arg);
return div;
};
mxPrintPreview.prototype.getRoot = function()
{
var root = this.graph.view.currentRoot;
if (root == null)
{
root = this.graph.getModel().getRoot();
}
return root;
};
mxPrintPreview.prototype.useCssTransforms = function()
{
return !mxClient.NO_FO && !mxClient.IS_SF;
};
mxPrintPreview.prototype.addGraphFragment = function(dx, dy, scale, pageNumber, div, clip)
{
var view = this.graph.getView();
var previousContainer = this.graph.container;
this.graph.container = div;
var canvas = view.getCanvas();
var backgroundPane = view.getBackgroundPane();
var drawPane = view.getDrawPane();
var overlayPane = view.getOverlayPane();
var realScale = scale;
if (this.graph.dialect == mxConstants.DIALECT_SVG)
{
view.createSvg();
if (this.useCssTransforms())
{
var g = view.getDrawPane().parentNode;
g.getAttribute('transform');
g.setAttribute('transformOrigin', '0 0');
g.setAttribute('transform', 'scale(' + scale + ',' + scale + ')' +
'translate(' + dx + ',' + dy + ')');
scale = 1;
dx = 0;
dy = 0;
}
}
else if (this.graph.dialect == mxConstants.DIALECT_VML)
{
view.createVml();
}
else
{
view.createHtml();
}
var eventsEnabled = view.isEventsEnabled();
view.setEventsEnabled(false);
var graphEnabled = this.graph.isEnabled();
this.graph.setEnabled(false);
var translate = view.getTranslate();
view.translate = new mxPoint(dx, dy);
var redraw = this.graph.cellRenderer.redraw;
var states = view.states;
var s = view.scale;
if (this.clipping)
{
var tempClip = new mxRectangle((clip.x + translate.x) * s, (clip.y + translate.y) * s,
clip.width * s / realScale, clip.height * s / realScale);
this.graph.cellRenderer.redraw = function(state, force, rendering)
{
if (state != null)
{
var orig = states.get(state.cell);
if (orig != null)
{
var bbox = view.getBoundingBox(orig, false);
if (bbox != null && bbox.width > 0 && bbox.height > 0 &&
!mxUtils.intersects(tempClip, bbox))
{
return;
}
}
}
redraw.apply(this, arguments);
};
}
var temp = null;
try
{
var cells = [this.getRoot()];
temp = new mxTemporaryCellStates(view, scale, cells, null, mxUtils.bind(this, function(state)
{
return this.getLinkForCellState(state);
}));
}
finally
{
if (mxClient.IS_IE)
{
view.overlayPane.innerHTML = '';
view.canvas.style.overflow = 'hidden';
view.canvas.style.position = 'relative';
view.canvas.style.top = this.marginTop + 'px';
view.canvas.style.width = clip.width + 'px';
view.canvas.style.height = clip.height + 'px';
}
else
{
var tmp = div.firstChild;
while (tmp != null)
{
var next = tmp.nextSibling;
var name = tmp.nodeName.toLowerCase();
if (name == 'svg')
{
tmp.style.overflow = 'hidden';
tmp.style.position = 'relative';
tmp.style.top = this.marginTop + 'px';
tmp.setAttribute('width', clip.width);
tmp.setAttribute('height', clip.height);
tmp.style.width = '';
tmp.style.height = '';
}
else if (tmp.style.cursor != 'default' && name != 'div')
{
tmp.parentNode.removeChild(tmp);
}
tmp = next;
}
}
if (this.printBackgroundImage)
{
var svgs = div.getElementsByTagName('svg');
if (svgs.length > 0)
{
svgs[0].style.position = 'absolute';
}
}
view.overlayPane.parentNode.removeChild(view.overlayPane);
this.graph.setEnabled(graphEnabled);
this.graph.container = previousContainer;
this.graph.cellRenderer.redraw = redraw;
view.canvas = canvas;
view.backgroundPane = backgroundPane;
view.drawPane = drawPane;
view.overlayPane = overlayPane;
view.translate = translate;
temp.destroy();
view.setEventsEnabled(eventsEnabled);
}
};
mxPrintPreview.prototype.getLinkForCellState = function(state)
{
return this.graph.getLinkForCell(state.cell);
};
mxPrintPreview.prototype.insertBackgroundImage = function(div, dx, dy)
{
var bg = this.graph.backgroundImage;
if (bg != null)
{
var img = document.createElement('img');
img.style.position = 'absolute';
img.style.marginLeft = Math.round(dx * this.scale) + 'px';
img.style.marginTop = Math.round(dy * this.scale) + 'px';
img.setAttribute('width', Math.round(this.scale * bg.width));
img.setAttribute('height', Math.round(this.scale * bg.height));
img.src = bg.src;
div.insertBefore(img, div.firstChild);
}
};
mxPrintPreview.prototype.getCoverPages = function()
{
return null;
};
mxPrintPreview.prototype.getAppendices = function()
{
return null;
};
mxPrintPreview.prototype.print = function(css)
{
var wnd = this.open(css);
if (wnd != null)
{
wnd.print();
}
};
mxPrintPreview.prototype.close = function()
{
if (this.wnd != null)
{
this.wnd.close();
this.wnd = null;
}
};
__mxOutput.mxPrintPreview = typeof mxPrintPreview !== 'undefined' ? mxPrintPreview : undefined;
function mxStylesheet()
{
this.styles = new Object();
this.putDefaultVertexStyle(this.createDefaultVertexStyle());
this.putDefaultEdgeStyle(this.createDefaultEdgeStyle());
} mxStylesheet.prototype.styles;
mxStylesheet.prototype.createDefaultVertexStyle = function()
{
var style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_FILLCOLOR] = '#C3D9FF';
style[mxConstants.STYLE_STROKECOLOR] = '#6482B9';
style[mxConstants.STYLE_FONTCOLOR] = '#774400';
return style;
};
mxStylesheet.prototype.createDefaultEdgeStyle = function()
{
var style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CONNECTOR;
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_STROKECOLOR] = '#6482B9';
style[mxConstants.STYLE_FONTCOLOR] = '#446299';
return style;
};
mxStylesheet.prototype.putDefaultVertexStyle = function(style)
{
this.putCellStyle('defaultVertex', style);
};
mxStylesheet.prototype.putDefaultEdgeStyle = function(style)
{
this.putCellStyle('defaultEdge', style);
};
mxStylesheet.prototype.getDefaultVertexStyle = function()
{
return this.styles['defaultVertex'];
};
mxStylesheet.prototype.getDefaultEdgeStyle = function()
{
return this.styles['defaultEdge'];
};
mxStylesheet.prototype.putCellStyle = function(name, style)
{
this.styles[name] = style;
};
mxStylesheet.prototype.getCellStyle = function(name, defaultStyle)
{
var style = defaultStyle;
if (name != null && name.length > 0)
{
var pairs = name.split(';');
if (style != null &&
name.charAt(0) != ';')
{
style = mxUtils.clone(style);
}
else
{
style = new Object();
}
for (var i = 0; i < pairs.length; i++)
{
var tmp = pairs[i];
var pos = tmp.indexOf('=');
if (pos >= 0)
{
var key = tmp.substring(0, pos);
var value = tmp.substring(pos + 1);
if (value == mxConstants.NONE)
{
delete style[key];
}
else if (mxUtils.isNumeric(value))
{
style[key] = parseFloat(value);
}
else
{
style[key] = value;
}
}
else
{
var tmpStyle = this.styles[tmp];
if (tmpStyle != null)
{
for (var key in tmpStyle)
{
style[key] = tmpStyle[key];
}
}
}
}
}
return style;
};
__mxOutput.mxStylesheet = typeof mxStylesheet !== 'undefined' ? mxStylesheet : undefined;
function mxCellState(view, cell, style)
{
this.view = view;
this.cell = cell;
this.style = (style != null) ? style : {};
this.origin = new mxPoint();
this.absoluteOffset = new mxPoint();
} mxCellState.prototype = new mxRectangle();
mxCellState.prototype.constructor = mxCellState;
mxCellState.prototype.view = null;
mxCellState.prototype.cell = null;
mxCellState.prototype.style = null;
mxCellState.prototype.invalidStyle = false;
mxCellState.prototype.invalid = true;
mxCellState.prototype.origin = null;
mxCellState.prototype.absolutePoints = null;
mxCellState.prototype.absoluteOffset = null;
mxCellState.prototype.visibleSourceState = null;
mxCellState.prototype.visibleTargetState = null;
mxCellState.prototype.terminalDistance = 0;
mxCellState.prototype.length = 0;
mxCellState.prototype.segments = null;
mxCellState.prototype.shape = null;
mxCellState.prototype.text = null;
mxCellState.prototype.unscaledWidth = null;
mxCellState.prototype.unscaledHeight = null;
mxCellState.prototype.getPerimeterBounds = function(border, bounds)
{
border = border || 0;
bounds = (bounds != null) ? bounds : new mxRectangle(this.x, this.y, this.width, this.height);
if (this.shape != null && this.shape.stencil != null && this.shape.stencil.aspect == 'fixed')
{
var aspect = this.shape.stencil.computeAspect(this.style, bounds.x, bounds.y, bounds.width, bounds.height);
bounds.x = aspect.x;
bounds.y = aspect.y;
bounds.width = this.shape.stencil.w0 * aspect.width;
bounds.height = this.shape.stencil.h0 * aspect.height;
}
if (border != 0)
{
bounds.grow(border);
}
return bounds;
};
mxCellState.prototype.setAbsoluteTerminalPoint = function(point, isSource)
{
if (isSource)
{
if (this.absolutePoints == null)
{
this.absolutePoints = [];
}
if (this.absolutePoints.length == 0)
{
this.absolutePoints.push(point);
}
else
{
this.absolutePoints[0] = point;
}
}
else
{
if (this.absolutePoints == null)
{
this.absolutePoints = [];
this.absolutePoints.push(null);
this.absolutePoints.push(point);
}
else if (this.absolutePoints.length == 1)
{
this.absolutePoints.push(point);
}
else
{
this.absolutePoints[this.absolutePoints.length - 1] = point;
}
}
};
mxCellState.prototype.setCursor = function(cursor)
{
if (this.shape != null)
{
this.shape.setCursor(cursor);
}
if (this.text != null)
{
this.text.setCursor(cursor);
}
};
mxCellState.prototype.getVisibleTerminal = function(source)
{
var tmp = this.getVisibleTerminalState(source);
return (tmp != null) ? tmp.cell : null;
};
mxCellState.prototype.getVisibleTerminalState = function(source)
{
return (source) ? this.visibleSourceState : this.visibleTargetState;
};
mxCellState.prototype.setVisibleTerminalState = function(terminalState, source)
{
if (source)
{
this.visibleSourceState = terminalState;
}
else
{
this.visibleTargetState = terminalState;
}
};
mxCellState.prototype.getCellBounds = function()
{
return this.cellBounds;
};
mxCellState.prototype.getPaintBounds = function()
{
return this.paintBounds;
};
mxCellState.prototype.updateCachedBounds = function()
{
var tr = this.view.translate;
var s = this.view.scale;
this.cellBounds = new mxRectangle(this.x / s - tr.x, this.y / s - tr.y, this.width / s, this.height / s);
this.paintBounds = mxRectangle.fromRectangle(this.cellBounds);
if (this.shape != null && this.shape.isPaintBoundsInverted())
{
this.paintBounds.rotate90();
}
};
mxCellState.prototype.setState = function(state)
{
this.view = state.view;
this.cell = state.cell;
this.style = state.style;
this.absolutePoints = state.absolutePoints;
this.origin = state.origin;
this.absoluteOffset = state.absoluteOffset;
this.boundingBox = state.boundingBox;
this.terminalDistance = state.terminalDistance;
this.segments = state.segments;
this.length = state.length;
this.x = state.x;
this.y = state.y;
this.width = state.width;
this.height = state.height;
this.unscaledWidth = state.unscaledWidth;
this.unscaledHeight = state.unscaledHeight;
};
mxCellState.prototype.clone = function()
{
var clone = new mxCellState(this.view, this.cell, this.style);
if (this.absolutePoints != null)
{
clone.absolutePoints = [];
for (var i = 0; i < this.absolutePoints.length; i++)
{
clone.absolutePoints[i] = this.absolutePoints[i].clone();
}
}
if (this.origin != null)
{
clone.origin = this.origin.clone();
}
if (this.absoluteOffset != null)
{
clone.absoluteOffset = this.absoluteOffset.clone();
}
if (this.boundingBox != null)
{
clone.boundingBox = this.boundingBox.clone();
}
clone.terminalDistance = this.terminalDistance;
clone.segments = this.segments;
clone.length = this.length;
clone.x = this.x;
clone.y = this.y;
clone.width = this.width;
clone.height = this.height;
clone.unscaledWidth = this.unscaledWidth;
clone.unscaledHeight = this.unscaledHeight;
return clone;
};
mxCellState.prototype.destroy = function()
{
this.view.graph.cellRenderer.destroy(this);
};
__mxOutput.mxCellState = typeof mxCellState !== 'undefined' ? mxCellState : undefined;
function mxGraphSelectionModel(graph)
{
this.graph = graph;
this.cells = [];
} mxGraphSelectionModel.prototype = new mxEventSource();
mxGraphSelectionModel.prototype.constructor = mxGraphSelectionModel;
mxGraphSelectionModel.prototype.doneResource = (mxClient.language != 'none') ? 'done' : '';
mxGraphSelectionModel.prototype.updatingSelectionResource = (mxClient.language != 'none') ? 'updatingSelection' : '';
mxGraphSelectionModel.prototype.graph = null;
mxGraphSelectionModel.prototype.singleSelection = false;
mxGraphSelectionModel.prototype.isSingleSelection = function()
{
return this.singleSelection;
};
mxGraphSelectionModel.prototype.setSingleSelection = function(singleSelection)
{
this.singleSelection = singleSelection;
};
mxGraphSelectionModel.prototype.isSelected = function(cell)
{
if (cell != null)
{
return mxUtils.indexOf(this.cells, cell) >= 0;
}
return false;
};
mxGraphSelectionModel.prototype.isEmpty = function()
{
return this.cells.length == 0;
};
mxGraphSelectionModel.prototype.clear = function()
{
this.changeSelection(null, this.cells);
};
mxGraphSelectionModel.prototype.setCell = function(cell)
{
if (cell != null)
{
this.setCells([cell]);
}
};
mxGraphSelectionModel.prototype.setCells = function(cells)
{
if (cells != null)
{
if (this.singleSelection)
{
cells = [this.getFirstSelectableCell(cells)];
}
var tmp = [];
for (var i = 0; i < cells.length; i++)
{
if (this.graph.isCellSelectable(cells[i]))
{
tmp.push(cells[i]);
}
}
this.changeSelection(tmp, this.cells);
}
};
mxGraphSelectionModel.prototype.getFirstSelectableCell = function(cells)
{
if (cells != null)
{
for (var i = 0; i < cells.length; i++)
{
if (this.graph.isCellSelectable(cells[i]))
{
return cells[i];
}
}
}
return null;
};
mxGraphSelectionModel.prototype.addCell = function(cell)
{
if (cell != null)
{
this.addCells([cell]);
}
};
mxGraphSelectionModel.prototype.addCells = function(cells)
{
if (cells != null)
{
var remove = null;
if (this.singleSelection)
{
remove = this.cells;
cells = [this.getFirstSelectableCell(cells)];
}
var tmp = [];
for (var i = 0; i < cells.length; i++)
{
if (!this.isSelected(cells[i]) &&
this.graph.isCellSelectable(cells[i]))
{
tmp.push(cells[i]);
}
}
this.changeSelection(tmp, remove);
}
};
mxGraphSelectionModel.prototype.removeCell = function(cell)
{
if (cell != null)
{
this.removeCells([cell]);
}
};
mxGraphSelectionModel.prototype.removeCells = function(cells)
{
if (cells != null)
{
var tmp = [];
for (var i = 0; i < cells.length; i++)
{
if (this.isSelected(cells[i]))
{
tmp.push(cells[i]);
}
}
this.changeSelection(null, tmp);
}
};
mxGraphSelectionModel.prototype.changeSelection = function(added, removed)
{
if ((added != null &&
added.length > 0 &&
added[0] != null) ||
(removed != null &&
removed.length > 0 &&
removed[0] != null))
{
var change = new mxSelectionChange(this, added, removed);
change.execute();
var edit = new mxUndoableEdit(this, false);
edit.add(change);
this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
}
};
mxGraphSelectionModel.prototype.cellAdded = function(cell)
{
if (cell != null &&
!this.isSelected(cell))
{
this.cells.push(cell);
}
};
mxGraphSelectionModel.prototype.cellRemoved = function(cell)
{
if (cell != null)
{
var index = mxUtils.indexOf(this.cells, cell);
if (index >= 0)
{
this.cells.splice(index, 1);
}
}
};
function mxSelectionChange(selectionModel, added, removed)
{
this.selectionModel = selectionModel;
this.added = (added != null) ? added.slice() : null;
this.removed = (removed != null) ? removed.slice() : null;
} mxSelectionChange.prototype.execute = function()
{
var t0 = mxLog.enter('mxSelectionChange.execute');
window.status = mxResources.get(
this.selectionModel.updatingSelectionResource) ||
this.selectionModel.updatingSelectionResource;
if (this.removed != null)
{
for (var i = 0; i < this.removed.length; i++)
{
this.selectionModel.cellRemoved(this.removed[i]);
}
}
if (this.added != null)
{
for (var i = 0; i < this.added.length; i++)
{
this.selectionModel.cellAdded(this.added[i]);
}
}
var tmp = this.added;
this.added = this.removed;
this.removed = tmp;
window.status = mxResources.get(this.selectionModel.doneResource) ||
this.selectionModel.doneResource;
mxLog.leave('mxSelectionChange.execute', t0);
this.selectionModel.fireEvent(new mxEventObject(mxEvent.CHANGE,
'added', this.added, 'removed', this.removed));
};
__mxOutput.mxGraphSelectionModel = typeof mxGraphSelectionModel !== 'undefined' ? mxGraphSelectionModel : undefined;
function mxCellEditor(graph)
{
this.graph = graph;
this.zoomHandler = mxUtils.bind(this, function()
{
if (this.graph.isEditing())
{
this.resize();
}
});
this.graph.view.addListener(mxEvent.SCALE, this.zoomHandler);
this.graph.view.addListener(mxEvent.SCALE_AND_TRANSLATE, this.zoomHandler);
this.changeHandler = mxUtils.bind(this, function(sender)
{
if (this.editingCell != null && this.graph.getView().getState(this.editingCell) == null)
{
this.stopEditing(true);
}
});
this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
} mxCellEditor.prototype.graph = null;
mxCellEditor.prototype.textarea = null;
mxCellEditor.prototype.editingCell = null;
mxCellEditor.prototype.trigger = null;
mxCellEditor.prototype.modified = false;
mxCellEditor.prototype.autoSize = true;
mxCellEditor.prototype.selectText = true;
mxCellEditor.prototype.emptyLabelText = (mxClient.IS_FF) ? '<br>' : '';
mxCellEditor.prototype.escapeCancelsEditing = true;
mxCellEditor.prototype.textNode = '';
mxCellEditor.prototype.zIndex = 5;
mxCellEditor.prototype.minResize = new mxRectangle(0, 20);
mxCellEditor.prototype.wordWrapPadding = (mxClient.IS_QUIRKS) ? 2 : (!mxClient.IS_IE11) ? 1 : 0;
mxCellEditor.prototype.blurEnabled = false;
mxCellEditor.prototype.initialValue = null;
mxCellEditor.prototype.align = null;
mxCellEditor.prototype.init = function ()
{
this.textarea = document.createElement('div');
this.textarea.className = 'mxCellEditor mxPlainTextEditor';
this.textarea.contentEditable = true;
if (mxClient.IS_GC)
{
this.textarea.style.minHeight = '1em';
}
this.textarea.style.position = ((this.isLegacyEditor())) ? 'absolute' : 'relative';
this.installListeners(this.textarea);
};
mxCellEditor.prototype.applyValue = function(state, value)
{
this.graph.labelChanged(state.cell, value, this.trigger);
};
mxCellEditor.prototype.setAlign = function (align)
{
if (this.textarea != null)
{
this.textarea.style.textAlign = align;
}
this.align = align;
this.resize();
};
mxCellEditor.prototype.getInitialValue = function(state, trigger)
{
var result = mxUtils.htmlEntities(this.graph.getEditingValue(state.cell, trigger), false);
if (!mxClient.IS_QUIRKS && document.documentMode != 8 && document.documentMode != 9 &&
document.documentMode != 10)
{
result = mxUtils.replaceTrailingNewlines(result, '<div><br></div>');
}
return result.replace(/\n/g, '<br>');
};
mxCellEditor.prototype.getCurrentValue = function(state)
{
return mxUtils.extractTextWithWhitespace(this.textarea.childNodes);
};
mxCellEditor.prototype.isCancelEditingKeyEvent = function(evt)
{
return this.escapeCancelsEditing || mxEvent.isShiftDown(evt) || mxEvent.isControlDown(evt) || mxEvent.isMetaDown(evt);
};
mxCellEditor.prototype.installListeners = function(elt)
{
mxEvent.addListener(elt, 'dragstart', mxUtils.bind(this, function(evt)
{
this.graph.stopEditing(false);
mxEvent.consume(evt);
}));
mxEvent.addListener(elt, 'blur', mxUtils.bind(this, function(evt)
{
if (this.blurEnabled)
{
this.focusLost(evt);
}
}));
mxEvent.addListener(elt, 'keydown', mxUtils.bind(this, function(evt)
{
if (!mxEvent.isConsumed(evt))
{
if (this.isStopEditingEvent(evt))
{
this.graph.stopEditing(false);
mxEvent.consume(evt);
}
else if (evt.keyCode == 27 )
{
this.graph.stopEditing(this.isCancelEditingKeyEvent(evt));
mxEvent.consume(evt);
}
}
}));
var keypressHandler = mxUtils.bind(this, function(evt)
{
if (this.editingCell != null)
{
if (this.clearOnChange && elt.innerHTML == this.getEmptyLabelText() &&
(!mxClient.IS_FF || (evt.keyCode != 8 && evt.keyCode != 46 )))
{
this.clearOnChange = false;
elt.innerHTML = '';
}
}
});
mxEvent.addListener(elt, 'keypress', keypressHandler);
mxEvent.addListener(elt, 'paste', keypressHandler);
var keyupHandler = mxUtils.bind(this, function(evt)
{
if (this.editingCell != null)
{
if (this.textarea.innerHTML.length == 0 || this.textarea.innerHTML == '<br>')
{
this.textarea.innerHTML = this.getEmptyLabelText();
this.clearOnChange = this.textarea.innerHTML.length > 0;
}
else
{
this.clearOnChange = false;
}
}
});
mxEvent.addListener(elt, (!mxClient.IS_IE11 && !mxClient.IS_IE) ? 'input' : 'keyup', keyupHandler);
mxEvent.addListener(elt, 'cut', keyupHandler);
mxEvent.addListener(elt, 'paste', keyupHandler);
var evtName = (!mxClient.IS_IE11 && !mxClient.IS_IE) ? 'input' : 'keydown';
var resizeHandler = mxUtils.bind(this, function(evt)
{
if (this.editingCell != null && this.autoSize && !mxEvent.isConsumed(evt))
{
if (this.resizeThread != null)
{
window.clearTimeout(this.resizeThread);
}
this.resizeThread = window.setTimeout(mxUtils.bind(this, function()
{
this.resizeThread = null;
this.resize();
}), 0);
}
});
mxEvent.addListener(elt, evtName, resizeHandler);
mxEvent.addListener(window, 'resize', resizeHandler);
if (document.documentMode >= 9)
{
mxEvent.addListener(elt, 'DOMNodeRemoved', resizeHandler);
mxEvent.addListener(elt, 'DOMNodeInserted', resizeHandler);
}
else
{
mxEvent.addListener(elt, 'cut', resizeHandler);
mxEvent.addListener(elt, 'paste', resizeHandler);
}
};
mxCellEditor.prototype.isStopEditingEvent = function(evt)
{
return evt.keyCode == 113 || (this.graph.isEnterStopsCellEditing() &&
evt.keyCode == 13 && !mxEvent.isControlDown(evt) &&
!mxEvent.isShiftDown(evt));
};
mxCellEditor.prototype.isEventSource = function(evt)
{
return mxEvent.getSource(evt) == this.textarea;
};
mxCellEditor.prototype.resize = function()
{
var state = this.graph.getView().getState(this.editingCell);
if (state == null)
{
this.stopEditing(true);
}
else if (this.textarea != null)
{
var isEdge = this.graph.getModel().isEdge(state.cell);
var scale = this.graph.getView().scale;
var m = null;
if (!this.autoSize || (state.style[mxConstants.STYLE_OVERFLOW] == 'fill'))
{
this.bounds = this.getEditorBounds(state);
this.textarea.style.width = Math.round(this.bounds.width / scale) + 'px';
this.textarea.style.height = Math.round(this.bounds.height / scale) + 'px';
if (document.documentMode == 8 || mxClient.IS_QUIRKS)
{
this.textarea.style.left = Math.round(this.bounds.x) + 'px';
this.textarea.style.top = Math.round(this.bounds.y) + 'px';
}
else
{
this.textarea.style.left = Math.max(0, Math.round(this.bounds.x + 1)) + 'px';
this.textarea.style.top = Math.max(0, Math.round(this.bounds.y + 1)) + 'px';
}
if (this.graph.isWrapping(state.cell) && (this.bounds.width >= 2 || this.bounds.height >= 2) &&
this.textarea.innerHTML != this.getEmptyLabelText())
{
this.textarea.style.wordWrap = mxConstants.WORD_WRAP;
this.textarea.style.whiteSpace = 'normal';
if (state.style[mxConstants.STYLE_OVERFLOW] != 'fill')
{
this.textarea.style.width = Math.round(this.bounds.width / scale) + this.wordWrapPadding + 'px';
}
}
else
{
this.textarea.style.whiteSpace = 'nowrap';
if (state.style[mxConstants.STYLE_OVERFLOW] != 'fill')
{
this.textarea.style.width = '';
}
}
}
else
{
var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
m = (state.text != null && this.align == null) ? state.text.margin : null;
if (m == null)
{
m = mxUtils.getAlignmentAsPoint(this.align || mxUtils.getValue(state.style, mxConstants.STYLE_ALIGN, mxConstants.ALIGN_CENTER),
mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE));
}
if (isEdge)
{
this.bounds = new mxRectangle(state.absoluteOffset.x, state.absoluteOffset.y, 0, 0);
if (lw != null)
{
var tmp = (parseFloat(lw) + 2) * scale;
this.bounds.width = tmp;
this.bounds.x += m.x * tmp;
}
}
else
{
var bds = mxRectangle.fromRectangle(state);
var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
bds = (state.shape != null && hpos == mxConstants.ALIGN_CENTER && vpos == mxConstants.ALIGN_MIDDLE) ? state.shape.getLabelBounds(bds) : bds;
if (lw != null)
{
bds.width = parseFloat(lw) * scale;
}
if (!state.view.graph.cellRenderer.legacySpacing || state.style[mxConstants.STYLE_OVERFLOW] != 'width')
{
var spacing = parseInt(state.style[mxConstants.STYLE_SPACING] || 2) * scale;
var spacingTop = (parseInt(state.style[mxConstants.STYLE_SPACING_TOP] || 0) + mxText.prototype.baseSpacingTop) * scale + spacing;
var spacingRight = (parseInt(state.style[mxConstants.STYLE_SPACING_RIGHT] || 0) + mxText.prototype.baseSpacingRight) * scale + spacing;
var spacingBottom = (parseInt(state.style[mxConstants.STYLE_SPACING_BOTTOM] || 0) + mxText.prototype.baseSpacingBottom) * scale + spacing;
var spacingLeft = (parseInt(state.style[mxConstants.STYLE_SPACING_LEFT] || 0) + mxText.prototype.baseSpacingLeft) * scale + spacing;
var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
bds = new mxRectangle(bds.x + spacingLeft, bds.y + spacingTop,
bds.width - ((hpos == mxConstants.ALIGN_CENTER && lw == null) ? (spacingLeft + spacingRight) : 0),
bds.height - ((vpos == mxConstants.ALIGN_MIDDLE) ? (spacingTop + spacingBottom) : 0));
}
this.bounds = new mxRectangle(bds.x + state.absoluteOffset.x, bds.y + state.absoluteOffset.y, bds.width, bds.height);
}
if (this.graph.isWrapping(state.cell) && (this.bounds.width >= 2 || this.bounds.height >= 2) &&
this.textarea.innerHTML != this.getEmptyLabelText())
{
this.textarea.style.wordWrap = mxConstants.WORD_WRAP;
this.textarea.style.whiteSpace = 'normal';
var tmp = Math.round(this.bounds.width / ((document.documentMode == 8) ? scale : scale)) + this.wordWrapPadding;
if (this.textarea.style.position != 'relative')
{
this.textarea.style.width = tmp + 'px';
if (this.textarea.scrollWidth > tmp)
{
this.textarea.style.width = this.textarea.scrollWidth + 'px';
}
}
else
{
this.textarea.style.maxWidth = tmp + 'px';
}
}
else
{
this.textarea.style.whiteSpace = 'nowrap';
this.textarea.style.width = '';
}
if (document.documentMode == 8)
{
this.textarea.style.zoom = '1';
this.textarea.style.height = 'auto';
}
var ow = this.textarea.scrollWidth;
var oh = this.textarea.scrollHeight;
if (document.documentMode == 8)
{
this.textarea.style.left = Math.max(0, Math.ceil((this.bounds.x - m.x * (this.bounds.width - (ow + 1) * scale) + ow * (scale - 1) * 0 + (m.x + 0.5) * 2) / scale)) + 'px';
this.textarea.style.top = Math.max(0, Math.ceil((this.bounds.y - m.y * (this.bounds.height - (oh + 0.5) * scale) + oh * (scale - 1) * 0 + Math.abs(m.y + 0.5) * 1) / scale)) + 'px';
this.textarea.style.width = Math.round(ow * scale) + 'px';
this.textarea.style.height = Math.round(oh * scale) + 'px';
}
else if (mxClient.IS_QUIRKS)
{
this.textarea.style.left = Math.max(0, Math.ceil(this.bounds.x - m.x * (this.bounds.width - (ow + 1) * scale) + ow * (scale - 1) * 0 + (m.x + 0.5) * 2)) + 'px';
this.textarea.style.top = Math.max(0, Math.ceil(this.bounds.y - m.y * (this.bounds.height - (oh + 0.5) * scale) + oh * (scale - 1) * 0 + Math.abs(m.y + 0.5) * 1)) + 'px';
}
else
{
this.textarea.style.left = Math.max(0, Math.round(this.bounds.x - m.x * (this.bounds.width - 2)) + 1) + 'px';
this.textarea.style.top = Math.max(0, Math.round(this.bounds.y - m.y * (this.bounds.height - 4) + ((m.y == -1) ? 3 : 0)) + 1) + 'px';
}
}
if (mxClient.IS_VML)
{
this.textarea.style.zoom = scale;
}
else
{
mxUtils.setPrefixedStyle(this.textarea.style, 'transformOrigin', '0px 0px');
mxUtils.setPrefixedStyle(this.textarea.style, 'transform',
'scale(' + scale + ',' + scale + ')' + ((m == null) ? '' :
' translate(' + (m.x * 100) + '%,' + (m.y * 100) + '%)'));
}
}
};
mxCellEditor.prototype.focusLost = function()
{
this.stopEditing(!this.graph.isInvokesStopCellEditing());
};
mxCellEditor.prototype.getBackgroundColor = function(state)
{
return null;
};
mxCellEditor.prototype.isLegacyEditor = function()
{
if (mxClient.IS_VML)
{
return true;
}
else
{
var absoluteRoot = false;
if (mxClient.IS_SVG)
{
var root = this.graph.view.getDrawPane().ownerSVGElement;
if (root != null)
{
var css = mxUtils.getCurrentStyle(root);
if (css != null)
{
absoluteRoot = css.position == 'absolute';
}
}
}
return !absoluteRoot;
}
};
mxCellEditor.prototype.startEditing = function(cell, trigger)
{
this.stopEditing(true);
this.align = null;
if (this.textarea == null)
{
this.init();
}
if (this.graph.tooltipHandler != null)
{
this.graph.tooltipHandler.hideTooltip();
}
var state = this.graph.getView().getState(cell);
if (state != null)
{
this.graph.getView().scale;
var size = mxUtils.getValue(state.style, mxConstants.STYLE_FONTSIZE, mxConstants.DEFAULT_FONTSIZE);
var family = mxUtils.getValue(state.style, mxConstants.STYLE_FONTFAMILY, mxConstants.DEFAULT_FONTFAMILY);
var color = mxUtils.getValue(state.style, mxConstants.STYLE_FONTCOLOR, 'black');
var align = mxUtils.getValue(state.style, mxConstants.STYLE_ALIGN, mxConstants.ALIGN_LEFT);
var bold = (mxUtils.getValue(state.style, mxConstants.STYLE_FONTSTYLE, 0) &
mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD;
var italic = (mxUtils.getValue(state.style, mxConstants.STYLE_FONTSTYLE, 0) &
mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC;
var txtDecor = [];
if ((mxUtils.getValue(state.style, mxConstants.STYLE_FONTSTYLE, 0) &
mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
{
txtDecor.push('underline');
}
if ((mxUtils.getValue(state.style, mxConstants.STYLE_FONTSTYLE, 0) &
mxConstants.FONT_STRIKETHROUGH) == mxConstants.FONT_STRIKETHROUGH)
{
txtDecor.push('line-through');
}
this.textarea.style.lineHeight = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? Math.round(size * mxConstants.LINE_HEIGHT) + 'px' : mxConstants.LINE_HEIGHT;
this.textarea.style.backgroundColor = this.getBackgroundColor(state);
this.textarea.style.textDecoration = txtDecor.join(' ');
this.textarea.style.fontWeight = (bold) ? 'bold' : 'normal';
this.textarea.style.fontStyle = (italic) ? 'italic' : '';
this.textarea.style.fontSize = Math.round(size) + 'px';
this.textarea.style.zIndex = this.zIndex;
this.textarea.style.fontFamily = family;
this.textarea.style.textAlign = align;
this.textarea.style.outline = 'none';
this.textarea.style.color = color;
var dir = this.textDirection = mxUtils.getValue(state.style, mxConstants.STYLE_TEXT_DIRECTION, mxConstants.DEFAULT_TEXT_DIRECTION);
if (dir == mxConstants.TEXT_DIRECTION_AUTO)
{
if (state != null && state.text != null && state.text.dialect != mxConstants.DIALECT_STRICTHTML &&
!mxUtils.isNode(state.text.value))
{
dir = state.text.getAutoDirection();
}
}
if (dir == mxConstants.TEXT_DIRECTION_LTR || dir == mxConstants.TEXT_DIRECTION_RTL)
{
this.textarea.setAttribute('dir', dir);
}
else
{
this.textarea.removeAttribute('dir');
}
this.textarea.innerHTML = this.getInitialValue(state, trigger) || '';
this.initialValue = this.textarea.innerHTML;
if (this.textarea.innerHTML.length == 0 || this.textarea.innerHTML == '<br>')
{
this.textarea.innerHTML = this.getEmptyLabelText();
this.clearOnChange = true;
}
else
{
this.clearOnChange = this.textarea.innerHTML == this.getEmptyLabelText();
}
this.graph.container.appendChild(this.textarea);
this.editingCell = cell;
this.trigger = trigger;
this.textNode = null;
if (state.text != null && this.isHideLabel(state))
{
this.textNode = state.text.node;
this.textNode.style.visibility = 'hidden';
}
if (this.autoSize && (this.graph.model.isEdge(state.cell) || state.style[mxConstants.STYLE_OVERFLOW] != 'fill'))
{
window.setTimeout(mxUtils.bind(this, function()
{
this.resize();
}), 0);
}
this.resize();
try
{
this.textarea.focus();
if (this.isSelectText() && this.textarea.innerHTML.length > 0 &&
(this.textarea.innerHTML != this.getEmptyLabelText() || !this.clearOnChange))
{
document.execCommand('selectAll', false, null);
}
}
catch (e)
{
}
}
};
mxCellEditor.prototype.isSelectText = function()
{
return this.selectText;
};
mxCellEditor.prototype.clearSelection = function()
{
var selection = null;
if (window.getSelection)
{
selection = window.getSelection();
}
else if (document.selection)
{
selection = document.selection;
}
if (selection != null)
{
if (selection.empty)
{
selection.empty();
}
else if (selection.removeAllRanges)
{
selection.removeAllRanges();
}
}
};
mxCellEditor.prototype.stopEditing = function(cancel)
{
cancel = cancel || false;
if (this.editingCell != null)
{
if (this.textNode != null)
{
this.textNode.style.visibility = 'visible';
this.textNode = null;
}
var state = (!cancel) ? this.graph.view.getState(this.editingCell) : null;
var initial = this.initialValue;
this.initialValue = null;
this.editingCell = null;
this.trigger = null;
this.bounds = null;
this.textarea.blur();
this.clearSelection();
if (this.textarea.parentNode != null)
{
this.textarea.parentNode.removeChild(this.textarea);
}
if (this.clearOnChange && this.textarea.innerHTML == this.getEmptyLabelText())
{
this.textarea.innerHTML = '';
this.clearOnChange = false;
}
if (state != null && (this.textarea.innerHTML != initial || this.align != null))
{
this.prepareTextarea();
var value = this.getCurrentValue(state);
this.graph.getModel().beginUpdate();
try
{
if (value != null)
{
this.applyValue(state, value);
}
if (this.align != null)
{
this.graph.setCellStyles(mxConstants.STYLE_ALIGN, this.align, [state.cell]);
}
}
finally
{
this.graph.getModel().endUpdate();
}
}
mxEvent.release(this.textarea);
this.textarea = null;
this.align = null;
}
};
mxCellEditor.prototype.prepareTextarea = function()
{
if (this.textarea.lastChild != null &&
this.textarea.lastChild.nodeName == 'BR')
{
this.textarea.removeChild(this.textarea.lastChild);
}
};
mxCellEditor.prototype.isHideLabel = function(state)
{
return true;
};
mxCellEditor.prototype.getMinimumSize = function(state)
{
var scale = this.graph.getView().scale;
return new mxRectangle(0, 0, (state.text == null) ? 30 : state.text.size * scale + 20,
(this.textarea.style.textAlign == 'left') ? 120 : 40);
};
mxCellEditor.prototype.getEditorBounds = function(state)
{
var isEdge = this.graph.getModel().isEdge(state.cell);
var scale = this.graph.getView().scale;
var minSize = this.getMinimumSize(state);
var minWidth = minSize.width;
var minHeight = minSize.height;
var result = null;
if (!isEdge && state.view.graph.cellRenderer.legacySpacing && state.style[mxConstants.STYLE_OVERFLOW] == 'fill')
{
result = state.shape.getLabelBounds(mxRectangle.fromRectangle(state));
}
else
{
var spacing = parseInt(state.style[mxConstants.STYLE_SPACING] || 0) * scale;
var spacingTop = (parseInt(state.style[mxConstants.STYLE_SPACING_TOP] || 0) + mxText.prototype.baseSpacingTop) * scale + spacing;
var spacingRight = (parseInt(state.style[mxConstants.STYLE_SPACING_RIGHT] || 0) + mxText.prototype.baseSpacingRight) * scale + spacing;
var spacingBottom = (parseInt(state.style[mxConstants.STYLE_SPACING_BOTTOM] || 0) + mxText.prototype.baseSpacingBottom) * scale + spacing;
var spacingLeft = (parseInt(state.style[mxConstants.STYLE_SPACING_LEFT] || 0) + mxText.prototype.baseSpacingLeft) * scale + spacing;
result = new mxRectangle(state.x, state.y,
Math.max(minWidth, state.width - spacingLeft - spacingRight),
Math.max(minHeight, state.height - spacingTop - spacingBottom));
var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
result = (state.shape != null && hpos == mxConstants.ALIGN_CENTER && vpos == mxConstants.ALIGN_MIDDLE) ? state.shape.getLabelBounds(result) : result;
if (isEdge)
{
result.x = state.absoluteOffset.x;
result.y = state.absoluteOffset.y;
if (state.text != null && state.text.boundingBox != null)
{
if (state.text.boundingBox.x > 0)
{
result.x = state.text.boundingBox.x;
}
if (state.text.boundingBox.y > 0)
{
result.y = state.text.boundingBox.y;
}
}
}
else if (state.text != null && state.text.boundingBox != null)
{
result.x = Math.min(result.x, state.text.boundingBox.x);
result.y = Math.min(result.y, state.text.boundingBox.y);
}
result.x += spacingLeft;
result.y += spacingTop;
if (state.text != null && state.text.boundingBox != null)
{
if (!isEdge)
{
result.width = Math.max(result.width, state.text.boundingBox.width);
result.height = Math.max(result.height, state.text.boundingBox.height);
}
else
{
result.width = Math.max(minWidth, state.text.boundingBox.width);
result.height = Math.max(minHeight, state.text.boundingBox.height);
}
}
if (this.graph.getModel().isVertex(state.cell))
{
var horizontal = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
if (horizontal == mxConstants.ALIGN_LEFT)
{
result.x -= state.width;
}
else if (horizontal == mxConstants.ALIGN_RIGHT)
{
result.x += state.width;
}
var vertical = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
if (vertical == mxConstants.ALIGN_TOP)
{
result.y -= state.height;
}
else if (vertical == mxConstants.ALIGN_BOTTOM)
{
result.y += state.height;
}
}
}
return new mxRectangle(Math.round(result.x), Math.round(result.y), Math.round(result.width), Math.round(result.height));
};
mxCellEditor.prototype.getEmptyLabelText = function (cell)
{
return this.emptyLabelText;
};
mxCellEditor.prototype.getEditingCell = function ()
{
return this.editingCell;
};
mxCellEditor.prototype.destroy = function ()
{
if (this.textarea != null)
{
mxEvent.release(this.textarea);
if (this.textarea.parentNode != null)
{
this.textarea.parentNode.removeChild(this.textarea);
}
this.textarea = null;
}
if (this.changeHandler != null)
{
this.graph.getModel().removeListener(this.changeHandler);
this.changeHandler = null;
}
if (this.zoomHandler)
{
this.graph.view.removeListener(this.zoomHandler);
this.zoomHandler = null;
}
};
__mxOutput.mxCellEditor = typeof mxCellEditor !== 'undefined' ? mxCellEditor : undefined;
function mxCellRenderer() { } mxCellRenderer.defaultShapes = new Object();
mxCellRenderer.prototype.defaultEdgeShape = mxConnector;
mxCellRenderer.prototype.defaultVertexShape = mxRectangleShape;
mxCellRenderer.prototype.defaultTextShape = mxText;
mxCellRenderer.prototype.legacyControlPosition = true;
mxCellRenderer.prototype.legacySpacing = true;
mxCellRenderer.prototype.antiAlias = true;
mxCellRenderer.prototype.minSvgStrokeWidth = 1;
mxCellRenderer.prototype.forceControlClickHandler = false;
mxCellRenderer.registerShape = function(key, shape)
{
mxCellRenderer.defaultShapes[key] = shape;
};
mxCellRenderer.registerShape(mxConstants.SHAPE_RECTANGLE, mxRectangleShape);
mxCellRenderer.registerShape(mxConstants.SHAPE_ELLIPSE, mxEllipse);
mxCellRenderer.registerShape(mxConstants.SHAPE_RHOMBUS, mxRhombus);
mxCellRenderer.registerShape(mxConstants.SHAPE_CYLINDER, mxCylinder);
mxCellRenderer.registerShape(mxConstants.SHAPE_CONNECTOR, mxConnector);
mxCellRenderer.registerShape(mxConstants.SHAPE_ACTOR, mxActor);
mxCellRenderer.registerShape(mxConstants.SHAPE_TRIANGLE, mxTriangle);
mxCellRenderer.registerShape(mxConstants.SHAPE_HEXAGON, mxHexagon);
mxCellRenderer.registerShape(mxConstants.SHAPE_CLOUD, mxCloud);
mxCellRenderer.registerShape(mxConstants.SHAPE_LINE, mxLine);
mxCellRenderer.registerShape(mxConstants.SHAPE_ARROW, mxArrow);
mxCellRenderer.registerShape(mxConstants.SHAPE_ARROW_CONNECTOR, mxArrowConnector);
mxCellRenderer.registerShape(mxConstants.SHAPE_DOUBLE_ELLIPSE, mxDoubleEllipse);
mxCellRenderer.registerShape(mxConstants.SHAPE_SWIMLANE, mxSwimlane);
mxCellRenderer.registerShape(mxConstants.SHAPE_IMAGE, mxImageShape);
mxCellRenderer.registerShape(mxConstants.SHAPE_LABEL, mxLabel);
mxCellRenderer.prototype.initializeShape = function(state)
{
state.shape.dialect = state.view.graph.dialect;
this.configureShape(state);
state.shape.init(state.view.getDrawPane());
};
mxCellRenderer.prototype.createShape = function(state)
{
var shape = null;
if (state.style != null)
{
var stencil = mxStencilRegistry.getStencil(state.style[mxConstants.STYLE_SHAPE]);
if (stencil != null)
{
shape = new mxShape(stencil);
}
else
{
var ctor = this.getShapeConstructor(state);
shape = new ctor();
}
}
return shape;
};
mxCellRenderer.prototype.createIndicatorShape = function(state)
{
state.shape.indicatorShape = this.getShape(state.view.graph.getIndicatorShape(state));
};
mxCellRenderer.prototype.getShape = function(name)
{
return (name != null) ? mxCellRenderer.defaultShapes[name] : null;
};
mxCellRenderer.prototype.getShapeConstructor = function(state)
{
var ctor = this.getShape(state.style[mxConstants.STYLE_SHAPE]);
if (ctor == null)
{
ctor = (state.view.graph.getModel().isEdge(state.cell)) ?
this.defaultEdgeShape : this.defaultVertexShape;
}
return ctor;
};
mxCellRenderer.prototype.configureShape = function(state)
{
state.shape.apply(state);
state.shape.image = state.view.graph.getImage(state);
state.shape.indicatorColor = state.view.graph.getIndicatorColor(state);
state.shape.indicatorStrokeColor = state.style[mxConstants.STYLE_INDICATOR_STROKECOLOR];
state.shape.indicatorGradientColor = state.view.graph.getIndicatorGradientColor(state);
state.shape.indicatorDirection = state.style[mxConstants.STYLE_INDICATOR_DIRECTION];
state.shape.indicatorImage = state.view.graph.getIndicatorImage(state);
this.postConfigureShape(state);
};
mxCellRenderer.prototype.postConfigureShape = function(state)
{
if (state.shape != null)
{
this.resolveColor(state, 'indicatorGradientColor', mxConstants.STYLE_GRADIENTCOLOR);
this.resolveColor(state, 'indicatorColor', mxConstants.STYLE_FILLCOLOR);
this.resolveColor(state, 'gradient', mxConstants.STYLE_GRADIENTCOLOR);
this.resolveColor(state, 'stroke', mxConstants.STYLE_STROKECOLOR);
this.resolveColor(state, 'fill', mxConstants.STYLE_FILLCOLOR);
}
};
mxCellRenderer.prototype.checkPlaceholderStyles = function(state)
{
if (state.style != null)
{
var values = ['inherit', 'swimlane', 'indicated'];
var styles = [mxConstants.STYLE_FILLCOLOR, mxConstants.STYLE_STROKECOLOR,
mxConstants.STYLE_GRADIENTCOLOR, mxConstants.STYLE_FONTCOLOR];
for (var i = 0; i < styles.length; i++)
{
if (mxUtils.indexOf(values, state.style[styles[i]]) >= 0)
{
return true;
}
}
}
return false;
};
mxCellRenderer.prototype.resolveColor = function(state, field, key)
{
var shape = (key == mxConstants.STYLE_FONTCOLOR) ?
state.text : state.shape;
if (shape != null)
{
var graph = state.view.graph;
var value = shape[field];
var referenced = null;
if (value == 'inherit')
{
referenced = graph.model.getParent(state.cell);
}
else if (value == 'swimlane')
{
shape[field] = (key == mxConstants.STYLE_STROKECOLOR ||
key == mxConstants.STYLE_FONTCOLOR) ?
'#000000' : '#ffffff';
if (graph.model.getTerminal(state.cell, false) != null)
{
referenced = graph.model.getTerminal(state.cell, false);
}
else
{
referenced = state.cell;
}
referenced = graph.getSwimlane(referenced);
key = graph.swimlaneIndicatorColorAttribute;
}
else if (value == 'indicated' && state.shape != null)
{
shape[field] = state.shape.indicatorColor;
}
else if (key != mxConstants.STYLE_FILLCOLOR &&
value == mxConstants.STYLE_FILLCOLOR &&
state.shape != null)
{
shape[field] = state.style[mxConstants.STYLE_FILLCOLOR];
}
else if (key != mxConstants.STYLE_STROKECOLOR &&
value == mxConstants.STYLE_STROKECOLOR &&
state.shape != null)
{
shape[field] = state.style[mxConstants.STYLE_STROKECOLOR];
}
if (referenced != null)
{
var rstate = graph.getView().getState(referenced);
shape[field] = null;
if (rstate != null)
{
var rshape = (key == mxConstants.STYLE_FONTCOLOR) ? rstate.text : rstate.shape;
if (rshape != null && field != 'indicatorColor')
{
shape[field] = rshape[field];
}
else
{
shape[field] = rstate.style[key];
}
}
}
}
};
mxCellRenderer.prototype.getLabelValue = function(state)
{
return state.view.graph.getLabel(state.cell);
};
mxCellRenderer.prototype.createLabel = function(state, value)
{
var graph = state.view.graph;
graph.getModel().isEdge(state.cell);
if (state.style[mxConstants.STYLE_FONTSIZE] > 0 || state.style[mxConstants.STYLE_FONTSIZE] == null)
{
var isForceHtml = (graph.isHtmlLabel(state.cell) || (value != null && mxUtils.isNode(value)));
state.text = new this.defaultTextShape(value, new mxRectangle(),
(state.style[mxConstants.STYLE_ALIGN] || mxConstants.ALIGN_CENTER),
graph.getVerticalAlign(state),
state.style[mxConstants.STYLE_FONTCOLOR],
state.style[mxConstants.STYLE_FONTFAMILY],
state.style[mxConstants.STYLE_FONTSIZE],
state.style[mxConstants.STYLE_FONTSTYLE],
state.style[mxConstants.STYLE_SPACING],
state.style[mxConstants.STYLE_SPACING_TOP],
state.style[mxConstants.STYLE_SPACING_RIGHT],
state.style[mxConstants.STYLE_SPACING_BOTTOM],
state.style[mxConstants.STYLE_SPACING_LEFT],
state.style[mxConstants.STYLE_HORIZONTAL],
state.style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR],
state.style[mxConstants.STYLE_LABEL_BORDERCOLOR],
graph.isWrapping(state.cell) && graph.isHtmlLabel(state.cell),
graph.isLabelClipped(state.cell),
state.style[mxConstants.STYLE_OVERFLOW],
state.style[mxConstants.STYLE_LABEL_PADDING],
mxUtils.getValue(state.style, mxConstants.STYLE_TEXT_DIRECTION, mxConstants.DEFAULT_TEXT_DIRECTION));
state.text.opacity = mxUtils.getValue(state.style, mxConstants.STYLE_TEXT_OPACITY, 100);
state.text.dialect = (isForceHtml) ? mxConstants.DIALECT_STRICTHTML : state.view.graph.dialect;
state.text.style = state.style;
state.text.state = state;
this.initializeLabel(state, state.text);
var forceGetCell = false;
var getState = function(evt)
{
var result = state;
if (mxClient.IS_TOUCH || forceGetCell)
{
var x = mxEvent.getClientX(evt);
var y = mxEvent.getClientY(evt);
var pt = mxUtils.convertPoint(graph.container, x, y);
result = graph.view.getState(graph.getCellAt(pt.x, pt.y));
}
return result;
};
mxEvent.addGestureListeners(state.text.node,
mxUtils.bind(this, function(evt)
{
if (this.isLabelEvent(state, evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, state));
forceGetCell = graph.dialect != mxConstants.DIALECT_SVG &&
mxEvent.getSource(evt).nodeName == 'IMG';
}
}),
mxUtils.bind(this, function(evt)
{
if (this.isLabelEvent(state, evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, getState(evt)));
}
}),
mxUtils.bind(this, function(evt)
{
if (this.isLabelEvent(state, evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, getState(evt)));
forceGetCell = false;
}
})
);
if (graph.nativeDblClickEnabled)
{
mxEvent.addListener(state.text.node, 'dblclick',
mxUtils.bind(this, function(evt)
{
if (this.isLabelEvent(state, evt))
{
graph.dblClick(evt, state.cell);
mxEvent.consume(evt);
}
})
);
}
}
};
mxCellRenderer.prototype.initializeLabel = function(state, shape)
{
if (mxClient.IS_SVG && mxClient.NO_FO && shape.dialect != mxConstants.DIALECT_SVG)
{
shape.init(state.view.graph.container);
}
else
{
shape.init(state.view.getDrawPane());
}
};
mxCellRenderer.prototype.createCellOverlays = function(state)
{
var graph = state.view.graph;
var overlays = graph.getCellOverlays(state.cell);
var dict = null;
if (overlays != null)
{
dict = new mxDictionary();
for (var i = 0; i < overlays.length; i++)
{
var shape = (state.overlays != null) ? state.overlays.remove(overlays[i]) : null;
if (shape == null)
{
var tmp = new mxImageShape(new mxRectangle(), overlays[i].image.src);
tmp.dialect = state.view.graph.dialect;
tmp.preserveImageAspect = false;
tmp.overlay = overlays[i];
this.initializeOverlay(state, tmp);
this.installCellOverlayListeners(state, overlays[i], tmp);
if (overlays[i].cursor != null)
{
tmp.node.style.cursor = overlays[i].cursor;
}
dict.put(overlays[i], tmp);
}
else
{
dict.put(overlays[i], shape);
}
}
}
if (state.overlays != null)
{
state.overlays.visit(function(id, shape)
{
shape.destroy();
});
}
state.overlays = dict;
};
mxCellRenderer.prototype.initializeOverlay = function(state, overlay)
{
overlay.init(state.view.getOverlayPane());
};
mxCellRenderer.prototype.installCellOverlayListeners = function(state, overlay, shape)
{
var graph = state.view.graph;
mxEvent.addListener(shape.node, 'click', function (evt)
{
if (graph.isEditing())
{
graph.stopEditing(!graph.isInvokesStopCellEditing());
}
overlay.fireEvent(new mxEventObject(mxEvent.CLICK,
'event', evt, 'cell', state.cell));
});
mxEvent.addGestureListeners(shape.node,
function (evt)
{
mxEvent.consume(evt);
},
function (evt)
{
graph.fireMouseEvent(mxEvent.MOUSE_MOVE,
new mxMouseEvent(evt, state));
});
if (mxClient.IS_TOUCH)
{
mxEvent.addListener(shape.node, 'touchend', function (evt)
{
overlay.fireEvent(new mxEventObject(mxEvent.CLICK,
'event', evt, 'cell', state.cell));
});
}
};
mxCellRenderer.prototype.createControl = function(state)
{
var graph = state.view.graph;
var image = graph.getFoldingImage(state);
if (graph.foldingEnabled && image != null)
{
if (state.control == null)
{
var b = new mxRectangle(0, 0, image.width, image.height);
state.control = new mxImageShape(b, image.src);
state.control.preserveImageAspect = false;
state.control.dialect = graph.dialect;
this.initControl(state, state.control, true, this.createControlClickHandler(state));
}
}
else if (state.control != null)
{
state.control.destroy();
state.control = null;
}
};
mxCellRenderer.prototype.createControlClickHandler = function(state)
{
var graph = state.view.graph;
return mxUtils.bind(this, function (evt)
{
if (this.forceControlClickHandler || graph.isEnabled())
{
var collapse = !graph.isCellCollapsed(state.cell);
graph.foldCells(collapse, false, [state.cell], null, evt);
mxEvent.consume(evt);
}
});
};
mxCellRenderer.prototype.initControl = function(state, control, handleEvents, clickHandler)
{
var graph = state.view.graph;
var isForceHtml = graph.isHtmlLabel(state.cell) && mxClient.NO_FO &&
graph.dialect == mxConstants.DIALECT_SVG;
if (isForceHtml)
{
control.dialect = mxConstants.DIALECT_PREFERHTML;
control.init(graph.container);
control.node.style.zIndex = 1;
}
else
{
control.init(state.view.getOverlayPane());
}
var node = control.innerNode || control.node;
if (clickHandler != null && !mxClient.IS_IOS)
{
if (graph.isEnabled())
{
node.style.cursor = 'pointer';
}
mxEvent.addListener(node, 'click', clickHandler);
}
if (handleEvents)
{
var first = null;
mxEvent.addGestureListeners(node,
function (evt)
{
first = new mxPoint(mxEvent.getClientX(evt), mxEvent.getClientY(evt));
graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, state));
mxEvent.consume(evt);
},
function (evt)
{
graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, state));
},
function (evt)
{
graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, state));
mxEvent.consume(evt);
});
if (clickHandler != null && mxClient.IS_IOS)
{
node.addEventListener('touchend', function(evt)
{
if (first != null)
{
var tol = graph.tolerance;
if (Math.abs(first.x - mxEvent.getClientX(evt)) < tol &&
Math.abs(first.y - mxEvent.getClientY(evt)) < tol)
{
clickHandler.call(clickHandler, evt);
mxEvent.consume(evt);
}
}
}, true);
}
}
return node;
};
mxCellRenderer.prototype.isShapeEvent = function(state, evt)
{
return true;
};
mxCellRenderer.prototype.isLabelEvent = function(state, evt)
{
return true;
};
mxCellRenderer.prototype.installListeners = function(state)
{
var graph = state.view.graph;
var getState = function(evt)
{
var result = state;
if ((graph.dialect != mxConstants.DIALECT_SVG && mxEvent.getSource(evt).nodeName == 'IMG') || mxClient.IS_TOUCH)
{
var x = mxEvent.getClientX(evt);
var y = mxEvent.getClientY(evt);
var pt = mxUtils.convertPoint(graph.container, x, y);
result = graph.view.getState(graph.getCellAt(pt.x, pt.y));
}
return result;
};
mxEvent.addGestureListeners(state.shape.node,
mxUtils.bind(this, function(evt)
{
if (this.isShapeEvent(state, evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, state));
}
}),
mxUtils.bind(this, function(evt)
{
if (this.isShapeEvent(state, evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, getState(evt)));
}
}),
mxUtils.bind(this, function(evt)
{
if (this.isShapeEvent(state, evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, getState(evt)));
}
})
);
if (graph.nativeDblClickEnabled)
{
mxEvent.addListener(state.shape.node, 'dblclick',
mxUtils.bind(this, function(evt)
{
if (this.isShapeEvent(state, evt))
{
graph.dblClick(evt, state.cell);
mxEvent.consume(evt);
}
})
);
}
};
mxCellRenderer.prototype.redrawLabel = function(state, forced)
{
var graph = state.view.graph;
var value = this.getLabelValue(state);
var wrapping = graph.isWrapping(state.cell);
var clipping = graph.isLabelClipped(state.cell);
var isForceHtml = (state.view.graph.isHtmlLabel(state.cell) || (value != null && mxUtils.isNode(value)));
var dialect = (isForceHtml) ? mxConstants.DIALECT_STRICTHTML : state.view.graph.dialect;
var overflow = state.style[mxConstants.STYLE_OVERFLOW] || 'visible';
if (state.text != null && (state.text.wrap != wrapping || state.text.clipped != clipping ||
state.text.overflow != overflow || state.text.dialect != dialect))
{
state.text.destroy();
state.text = null;
}
if (state.text == null && value != null && (mxUtils.isNode(value) || value.length > 0))
{
this.createLabel(state, value);
}
else if (state.text != null && (value == null || value.length == 0))
{
state.text.destroy();
state.text = null;
}
if (state.text != null)
{
if (forced)
{
if (state.text.lastValue != null && this.isTextShapeInvalid(state, state.text))
{
state.text.lastValue = null;
}
state.text.resetStyles();
state.text.apply(state);
state.text.valign = graph.getVerticalAlign(state);
}
var bounds = this.getLabelBounds(state);
var nextScale = this.getTextScale(state);
this.resolveColor(state, 'color', mxConstants.STYLE_FONTCOLOR);
if (forced || state.text.value != value || state.text.isWrapping != wrapping ||
state.text.overflow != overflow || state.text.isClipping != clipping ||
state.text.scale != nextScale || state.text.dialect != dialect ||
state.text.bounds == null || !state.text.bounds.equals(bounds))
{
state.text.dialect = dialect;
state.text.value = value;
state.text.bounds = bounds;
state.text.scale = nextScale;
state.text.wrap = wrapping;
state.text.clipped = clipping;
state.text.overflow = overflow;
var vis = state.text.node.style.visibility;
this.redrawLabelShape(state.text);
state.text.node.style.visibility = vis;
}
}
};
mxCellRenderer.prototype.isTextShapeInvalid = function(state, shape)
{
function check(property, stylename, defaultValue)
{
var result = false;
if (stylename == 'spacingTop' || stylename == 'spacingRight' ||
stylename == 'spacingBottom' || stylename == 'spacingLeft')
{
result = parseFloat(shape[property]) - parseFloat(shape.spacing) !=
(state.style[stylename] || defaultValue);
}
else
{
result = shape[property] != (state.style[stylename] || defaultValue);
}
return result;
} return check('fontStyle', mxConstants.STYLE_FONTSTYLE, mxConstants.DEFAULT_FONTSTYLE) ||
check('family', mxConstants.STYLE_FONTFAMILY, mxConstants.DEFAULT_FONTFAMILY) ||
check('size', mxConstants.STYLE_FONTSIZE, mxConstants.DEFAULT_FONTSIZE) ||
check('color', mxConstants.STYLE_FONTCOLOR, 'black') ||
check('align', mxConstants.STYLE_ALIGN, '') ||
check('valign', mxConstants.STYLE_VERTICAL_ALIGN, '') ||
check('spacing', mxConstants.STYLE_SPACING, 2) ||
check('spacingTop', mxConstants.STYLE_SPACING_TOP, 0) ||
check('spacingRight', mxConstants.STYLE_SPACING_RIGHT, 0) ||
check('spacingBottom', mxConstants.STYLE_SPACING_BOTTOM, 0) ||
check('spacingLeft', mxConstants.STYLE_SPACING_LEFT, 0) ||
check('horizontal', mxConstants.STYLE_HORIZONTAL, true) ||
check('background', mxConstants.STYLE_LABEL_BACKGROUNDCOLOR) ||
check('border', mxConstants.STYLE_LABEL_BORDERCOLOR) ||
check('opacity', mxConstants.STYLE_TEXT_OPACITY, 100) ||
check('textDirection', mxConstants.STYLE_TEXT_DIRECTION, mxConstants.DEFAULT_TEXT_DIRECTION);
};
mxCellRenderer.prototype.redrawLabelShape = function(shape)
{
shape.redraw();
};
mxCellRenderer.prototype.getTextScale = function(state)
{
return state.view.scale;
};
mxCellRenderer.prototype.getLabelBounds = function(state)
{
var graph = state.view.graph;
var scale = state.view.scale;
var isEdge = graph.getModel().isEdge(state.cell);
var bounds = new mxRectangle(state.absoluteOffset.x, state.absoluteOffset.y);
if (isEdge)
{
var spacing = state.text.getSpacing();
bounds.x += spacing.x * scale;
bounds.y += spacing.y * scale;
var geo = graph.getCellGeometry(state.cell);
if (geo != null)
{
bounds.width = Math.max(0, geo.width * scale);
bounds.height = Math.max(0, geo.height * scale);
}
}
else
{
if (state.text.isPaintBoundsInverted())
{
var tmp = bounds.x;
bounds.x = bounds.y;
bounds.y = tmp;
}
bounds.x += state.x;
bounds.y += state.y;
bounds.width = Math.max(1, state.width);
bounds.height = Math.max(1, state.height);
}
if (state.text.isPaintBoundsInverted())
{
var t = (state.width - state.height) / 2;
bounds.x += t;
bounds.y -= t;
var tmp = bounds.width;
bounds.width = bounds.height;
bounds.height = tmp;
}
if (state.shape != null)
{
var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
if (hpos == mxConstants.ALIGN_CENTER && vpos == mxConstants.ALIGN_MIDDLE)
{
bounds = state.shape.getLabelBounds(bounds);
}
}
var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
if (lw != null)
{
bounds.width = parseFloat(lw) * scale;
}
if (!isEdge)
{
this.rotateLabelBounds(state, bounds);
}
return bounds;
};
mxCellRenderer.prototype.rotateLabelBounds = function(state, bounds)
{
bounds.y -= state.text.margin.y * bounds.height;
bounds.x -= state.text.margin.x * bounds.width;
if (!this.legacySpacing || (state.style[mxConstants.STYLE_OVERFLOW] != 'fill' && state.style[mxConstants.STYLE_OVERFLOW] != 'width'))
{
var s = state.view.scale;
var spacing = state.text.getSpacing();
bounds.x += spacing.x * s;
bounds.y += spacing.y * s;
var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
bounds.width = Math.max(0, bounds.width - ((hpos == mxConstants.ALIGN_CENTER && lw == null) ? (state.text.spacingLeft * s + state.text.spacingRight * s) : 0));
bounds.height = Math.max(0, bounds.height - ((vpos == mxConstants.ALIGN_MIDDLE) ? (state.text.spacingTop * s + state.text.spacingBottom * s) : 0));
}
var theta = state.text.getTextRotation();
if (theta != 0 && state != null && state.view.graph.model.isVertex(state.cell))
{
var cx = state.getCenterX();
var cy = state.getCenterY();
if (bounds.x != cx || bounds.y != cy)
{
var rad = theta * (Math.PI / 180);
var pt = mxUtils.getRotatedPoint(new mxPoint(bounds.x, bounds.y),
Math.cos(rad), Math.sin(rad), new mxPoint(cx, cy));
bounds.x = pt.x;
bounds.y = pt.y;
}
}
};
mxCellRenderer.prototype.redrawCellOverlays = function(state, forced)
{
this.createCellOverlays(state);
if (state.overlays != null)
{
var rot = mxUtils.mod(mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION, 0), 90);
var rad = mxUtils.toRadians(rot);
var cos = Math.cos(rad);
var sin = Math.sin(rad);
state.overlays.visit(function(id, shape)
{
var bounds = shape.overlay.getBounds(state);
if (!state.view.graph.getModel().isEdge(state.cell))
{
if (state.shape != null && rot != 0)
{
var cx = bounds.getCenterX();
var cy = bounds.getCenterY();
var point = mxUtils.getRotatedPoint(new mxPoint(cx, cy), cos, sin,
new mxPoint(state.getCenterX(), state.getCenterY()));
cx = point.x;
cy = point.y;
bounds.x = Math.round(cx - bounds.width / 2);
bounds.y = Math.round(cy - bounds.height / 2);
}
}
if (forced || shape.bounds == null || shape.scale != state.view.scale ||
!shape.bounds.equals(bounds))
{
shape.bounds = bounds;
shape.scale = state.view.scale;
shape.redraw();
}
});
}
};
mxCellRenderer.prototype.redrawControl = function(state, forced)
{
var image = state.view.graph.getFoldingImage(state);
if (state.control != null && image != null)
{
var bounds = this.getControlBounds(state, image.width, image.height);
var r = (this.legacyControlPosition) ?
mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION, 0) :
state.shape.getTextRotation();
var s = state.view.scale;
if (forced || state.control.scale != s || !state.control.bounds.equals(bounds) ||
state.control.rotation != r)
{
state.control.rotation = r;
state.control.bounds = bounds;
state.control.scale = s;
state.control.redraw();
}
}
};
mxCellRenderer.prototype.getControlBounds = function(state, w, h)
{
if (state.control != null)
{
var s = state.view.scale;
var cx = state.getCenterX();
var cy = state.getCenterY();
if (!state.view.graph.getModel().isEdge(state.cell))
{
cx = state.x + w * s;
cy = state.y + h * s;
if (state.shape != null)
{
var rot = state.shape.getShapeRotation();
if (this.legacyControlPosition)
{
rot = mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION, 0);
}
else
{
if (state.shape.isPaintBoundsInverted())
{
var t = (state.width - state.height) / 2;
cx += t;
cy -= t;
}
}
if (rot != 0)
{
var rad = mxUtils.toRadians(rot);
var cos = Math.cos(rad);
var sin = Math.sin(rad);
var point = mxUtils.getRotatedPoint(new mxPoint(cx, cy), cos, sin,
new mxPoint(state.getCenterX(), state.getCenterY()));
cx = point.x;
cy = point.y;
}
}
}
return (state.view.graph.getModel().isEdge(state.cell)) ?
new mxRectangle(Math.round(cx - w / 2 * s), Math.round(cy - h / 2 * s), Math.round(w * s), Math.round(h * s))
: new mxRectangle(Math.round(cx - w / 2 * s), Math.round(cy - h / 2 * s), Math.round(w * s), Math.round(h * s));
}
return null;
};
mxCellRenderer.prototype.insertStateAfter = function(state, node, htmlNode)
{
var shapes = this.getShapesForState(state);
for (var i = 0; i < shapes.length; i++)
{
if (shapes[i] != null && shapes[i].node != null)
{
var html = shapes[i].node.parentNode != state.view.getDrawPane() &&
shapes[i].node.parentNode != state.view.getOverlayPane();
var temp = (html) ? htmlNode : node;
if (temp != null && temp.nextSibling != shapes[i].node)
{
if (temp.nextSibling == null)
{
temp.parentNode.appendChild(shapes[i].node);
}
else
{
temp.parentNode.insertBefore(shapes[i].node, temp.nextSibling);
}
}
else if (temp == null)
{
if (shapes[i].node.parentNode == state.view.graph.container)
{
var canvas = state.view.canvas;
while (canvas != null && canvas.parentNode != state.view.graph.container)
{
canvas = canvas.parentNode;
}
if (canvas != null && canvas.nextSibling != null)
{
if (canvas.nextSibling != shapes[i].node)
{
shapes[i].node.parentNode.insertBefore(shapes[i].node, canvas.nextSibling);
}
}
else
{
shapes[i].node.parentNode.appendChild(shapes[i].node);
}
}
else if (shapes[i].node.parentNode != null &&
shapes[i].node.parentNode.firstChild != null &&
shapes[i].node.parentNode.firstChild != shapes[i].node)
{
shapes[i].node.parentNode.insertBefore(shapes[i].node, shapes[i].node.parentNode.firstChild);
}
}
if (html)
{
htmlNode = shapes[i].node;
}
else
{
node = shapes[i].node;
}
}
}
return [node, htmlNode];
};
mxCellRenderer.prototype.getShapesForState = function(state)
{
return [state.shape, state.text, state.control];
};
mxCellRenderer.prototype.redraw = function(state, force, rendering)
{
var shapeChanged = this.redrawShape(state, force, rendering);
if (state.shape != null && (rendering == null || rendering))
{
this.redrawLabel(state, shapeChanged);
this.redrawCellOverlays(state, shapeChanged);
this.redrawControl(state, shapeChanged);
}
};
mxCellRenderer.prototype.redrawShape = function(state, force, rendering)
{
var model = state.view.graph.model;
var shapeChanged = false;
if (state.shape != null && state.shape.style != null && state.style != null &&
state.shape.style[mxConstants.STYLE_SHAPE] != state.style[mxConstants.STYLE_SHAPE])
{
state.shape.destroy();
state.shape = null;
}
if (state.shape == null && state.view.graph.container != null &&
state.cell != state.view.currentRoot &&
(model.isVertex(state.cell) || model.isEdge(state.cell)))
{
state.shape = this.createShape(state);
if (state.shape != null)
{
state.shape.minSvgStrokeWidth = this.minSvgStrokeWidth;
state.shape.antiAlias = this.antiAlias;
this.createIndicatorShape(state);
this.initializeShape(state);
this.createCellOverlays(state);
this.installListeners(state);
state.view.graph.selectionCellsHandler.updateHandler(state);
}
}
else if (!force && state.shape != null && (!mxUtils.equalEntries(state.shape.style,
state.style) || this.checkPlaceholderStyles(state)))
{
state.shape.resetStyles();
this.configureShape(state);
state.view.graph.selectionCellsHandler.updateHandler(state);
force = true;
}
if (state.shape != null && state.shape.indicatorShape !=
this.getShape(state.view.graph.getIndicatorShape(state)))
{
if (state.shape.indicator != null)
{
state.shape.indicator.destroy();
state.shape.indicator = null;
}
this.createIndicatorShape(state);
if (state.shape.indicatorShape != null)
{
state.shape.indicator = new state.shape.indicatorShape();
state.shape.indicator.dialect = state.shape.dialect;
state.shape.indicator.init(state.node);
force = true;
}
}
if (state.shape != null)
{
this.createControl(state);
if (force || this.isShapeInvalid(state, state.shape))
{
if (state.absolutePoints != null)
{
state.shape.points = state.absolutePoints.slice();
state.shape.bounds = null;
}
else
{
state.shape.points = null;
state.shape.bounds = new mxRectangle(state.x, state.y, state.width, state.height);
}
state.shape.scale = state.view.scale;
if (rendering == null || rendering)
{
this.doRedrawShape(state);
}
else
{
state.shape.updateBoundingBox();
}
shapeChanged = true;
}
}
return shapeChanged;
};
mxCellRenderer.prototype.doRedrawShape = function(state)
{
state.shape.redraw();
};
mxCellRenderer.prototype.isShapeInvalid = function(state, shape)
{
return shape.bounds == null || shape.scale != state.view.scale ||
(state.absolutePoints == null && !shape.bounds.equals(state)) ||
(state.absolutePoints != null && !mxUtils.equalPoints(shape.points, state.absolutePoints))
};
mxCellRenderer.prototype.destroy = function(state)
{
if (state.shape != null)
{
if (state.text != null)
{
state.text.destroy();
state.text = null;
}
if (state.overlays != null)
{
state.overlays.visit(function(id, shape)
{
shape.destroy();
});
state.overlays = null;
}
if (state.control != null)
{
state.control.destroy();
state.control = null;
}
state.shape.destroy();
state.shape = null;
}
};
__mxOutput.mxCellRenderer = typeof mxCellRenderer !== 'undefined' ? mxCellRenderer : undefined;
var mxEdgeStyle =
{
EntityRelation: function(state, source, target, points, result)
{
var view = state.view;
var graph = view.graph;
var segment = mxUtils.getValue(state.style,
mxConstants.STYLE_SEGMENT,
mxConstants.ENTITY_SEGMENT) * view.scale;
var pts = state.absolutePoints;
var p0 = pts[0];
var pe = pts[pts.length-1];
var isSourceLeft = false;
if (source != null)
{
var sourceGeometry = graph.getCellGeometry(source.cell);
if (sourceGeometry.relative)
{
isSourceLeft = sourceGeometry.x <= 0.5;
}
else if (target != null)
{
isSourceLeft = ((pe != null) ? pe.x : target.x + target.width) < ((p0 != null) ? p0.x : source.x);
}
}
if (p0 != null)
{
source = new mxCellState();
source.x = p0.x;
source.y = p0.y;
}
else if (source != null)
{
var constraint = mxUtils.getPortConstraints(source, state, true, mxConstants.DIRECTION_MASK_NONE);
if (constraint != mxConstants.DIRECTION_MASK_NONE && constraint != mxConstants.DIRECTION_MASK_WEST +
mxConstants.DIRECTION_MASK_EAST)
{
isSourceLeft = constraint == mxConstants.DIRECTION_MASK_WEST;
}
}
else
{
return;
}
var isTargetLeft = true;
if (target != null)
{
var targetGeometry = graph.getCellGeometry(target.cell);
if (targetGeometry.relative)
{
isTargetLeft = targetGeometry.x <= 0.5;
}
else if (source != null)
{
isTargetLeft = ((p0 != null) ? p0.x : source.x + source.width) < ((pe != null) ? pe.x : target.x);
}
}
if (pe != null)
{
target = new mxCellState();
target.x = pe.x;
target.y = pe.y;
}
else if (target != null)
{
var constraint = mxUtils.getPortConstraints(target, state, false, mxConstants.DIRECTION_MASK_NONE);
if (constraint != mxConstants.DIRECTION_MASK_NONE && constraint != mxConstants.DIRECTION_MASK_WEST +
mxConstants.DIRECTION_MASK_EAST)
{
isTargetLeft = constraint == mxConstants.DIRECTION_MASK_WEST;
}
}
if (source != null && target != null)
{
var x0 = (isSourceLeft) ? source.x : source.x + source.width;
var y0 = view.getRoutingCenterY(source);
var xe = (isTargetLeft) ? target.x : target.x + target.width;
var ye = view.getRoutingCenterY(target);
var seg = segment;
var dx = (isSourceLeft) ? -seg : seg;
var dep = new mxPoint(x0 + dx, y0);
dx = (isTargetLeft) ? -seg : seg;
var arr = new mxPoint(xe + dx, ye);
if (isSourceLeft == isTargetLeft)
{
var x = (isSourceLeft) ?
Math.min(x0, xe)-segment :
Math.max(x0, xe)+segment;
result.push(new mxPoint(x, y0));
result.push(new mxPoint(x, ye));
}
else if ((dep.x < arr.x) == isSourceLeft)
{
var midY = y0 + (ye - y0) / 2;
result.push(dep);
result.push(new mxPoint(dep.x, midY));
result.push(new mxPoint(arr.x, midY));
result.push(arr);
}
else
{
result.push(dep);
result.push(arr);
}
}
},
Loop: function(state, source, target, points, result)
{
var pts = state.absolutePoints;
var p0 = pts[0];
var pe = pts[pts.length-1];
if (p0 != null && pe != null)
{
if (points != null && points.length > 0)
{
for (var i = 0; i < points.length; i++)
{
var pt = points[i];
pt = state.view.transformControlPoint(state, pt);
result.push(new mxPoint(pt.x, pt.y));
}
}
return;
}
if (source != null)
{
var view = state.view;
var graph = view.graph;
var pt = (points != null && points.length > 0) ? points[0] : null;
if (pt != null)
{
pt = view.transformControlPoint(state, pt);
if (mxUtils.contains(source, pt.x, pt.y))
{
pt = null;
}
}
var x = 0;
var dx = 0;
var y = 0;
var dy = 0;
var seg = mxUtils.getValue(state.style, mxConstants.STYLE_SEGMENT,
graph.gridSize) * view.scale;
var dir = mxUtils.getValue(state.style, mxConstants.STYLE_DIRECTION,
mxConstants.DIRECTION_WEST);
if (dir == mxConstants.DIRECTION_NORTH ||
dir == mxConstants.DIRECTION_SOUTH)
{
x = view.getRoutingCenterX(source);
dx = seg;
}
else
{
y = view.getRoutingCenterY(source);
dy = seg;
}
if (pt == null ||
pt.x < source.x ||
pt.x > source.x + source.width)
{
if (pt != null)
{
x = pt.x;
dy = Math.max(Math.abs(y - pt.y), dy);
}
else
{
if (dir == mxConstants.DIRECTION_NORTH)
{
y = source.y - 2 * dx;
}
else if (dir == mxConstants.DIRECTION_SOUTH)
{
y = source.y + source.height + 2 * dx;
}
else if (dir == mxConstants.DIRECTION_EAST)
{
x = source.x - 2 * dy;
}
else
{
x = source.x + source.width + 2 * dy;
}
}
}
else if (pt != null)
{
x = view.getRoutingCenterX(source);
dx = Math.max(Math.abs(x - pt.x), dy);
y = pt.y;
dy = 0;
}
result.push(new mxPoint(x - dx, y - dy));
result.push(new mxPoint(x + dx, y + dy));
}
},
ElbowConnector: function(state, source, target, points, result)
{
var pt = (points != null && points.length > 0) ? points[0] : null;
var vertical = false;
var horizontal = false;
if (source != null && target != null)
{
if (pt != null)
{
var left = Math.min(source.x, target.x);
var right = Math.max(source.x + source.width,
target.x + target.width);
var top = Math.min(source.y, target.y);
var bottom = Math.max(source.y + source.height,
target.y + target.height);
pt = state.view.transformControlPoint(state, pt);
vertical = pt.y < top || pt.y > bottom;
horizontal = pt.x < left || pt.x > right;
}
else
{
var left = Math.max(source.x, target.x);
var right = Math.min(source.x + source.width,
target.x + target.width);
vertical = left == right;
if (!vertical)
{
var top = Math.max(source.y, target.y);
var bottom = Math.min(source.y + source.height,
target.y + target.height);
horizontal = top == bottom;
}
}
}
if (!horizontal && (vertical ||
state.style[mxConstants.STYLE_ELBOW] == mxConstants.ELBOW_VERTICAL))
{
mxEdgeStyle.TopToBottom(state, source, target, points, result);
}
else
{
mxEdgeStyle.SideToSide(state, source, target, points, result);
}
},
SideToSide: function(state, source, target, points, result)
{
var view = state.view;
var pt = (points != null && points.length > 0) ? points[0] : null;
var pts = state.absolutePoints;
var p0 = pts[0];
var pe = pts[pts.length-1];
if (pt != null)
{
pt = view.transformControlPoint(state, pt);
}
if (p0 != null)
{
source = new mxCellState();
source.x = p0.x;
source.y = p0.y;
}
if (pe != null)
{
target = new mxCellState();
target.x = pe.x;
target.y = pe.y;
}
if (source != null && target != null)
{
var l = Math.max(source.x, target.x);
var r = Math.min(source.x + source.width,
target.x + target.width);
var x = (pt != null) ? pt.x : Math.round(r + (l - r) / 2);
var y1 = view.getRoutingCenterY(source);
var y2 = view.getRoutingCenterY(target);
if (pt != null)
{
if (pt.y >= source.y && pt.y <= source.y + source.height)
{
y1 = pt.y;
}
if (pt.y >= target.y && pt.y <= target.y + target.height)
{
y2 = pt.y;
}
}
if (!mxUtils.contains(target, x, y1) &&
!mxUtils.contains(source, x, y1))
{
result.push(new mxPoint(x, y1));
}
if (!mxUtils.contains(target, x, y2) &&
!mxUtils.contains(source, x, y2))
{
result.push(new mxPoint(x, y2));
}
if (result.length == 1)
{
if (pt != null)
{
if (!mxUtils.contains(target, x, pt.y) &&
!mxUtils.contains(source, x, pt.y))
{
result.push(new mxPoint(x, pt.y));
}
}
else
{
var t = Math.max(source.y, target.y);
var b = Math.min(source.y + source.height,
target.y + target.height);
result.push(new mxPoint(x, t + (b - t) / 2));
}
}
}
},
TopToBottom: function(state, source, target, points, result)
{
var view = state.view;
var pt = (points != null && points.length > 0) ? points[0] : null;
var pts = state.absolutePoints;
var p0 = pts[0];
var pe = pts[pts.length-1];
if (pt != null)
{
pt = view.transformControlPoint(state, pt);
}
if (p0 != null)
{
source = new mxCellState();
source.x = p0.x;
source.y = p0.y;
}
if (pe != null)
{
target = new mxCellState();
target.x = pe.x;
target.y = pe.y;
}
if (source != null && target != null)
{
var t = Math.max(source.y, target.y);
var b = Math.min(source.y + source.height,
target.y + target.height);
var x = view.getRoutingCenterX(source);
if (pt != null &&
pt.x >= source.x &&
pt.x <= source.x + source.width)
{
x = pt.x;
}
var y = (pt != null) ? pt.y : Math.round(b + (t - b) / 2);
if (!mxUtils.contains(target, x, y) &&
!mxUtils.contains(source, x, y))
{
result.push(new mxPoint(x, y));
}
if (pt != null &&
pt.x >= target.x &&
pt.x <= target.x + target.width)
{
x = pt.x;
}
else
{
x = view.getRoutingCenterX(target);
}
if (!mxUtils.contains(target, x, y) &&
!mxUtils.contains(source, x, y))
{
result.push(new mxPoint(x, y));
}
if (result.length == 1)
{
if (pt != null && result.length == 1)
{
if (!mxUtils.contains(target, pt.x, y) &&
!mxUtils.contains(source, pt.x, y))
{
result.push(new mxPoint(pt.x, y));
}
}
else
{
var l = Math.max(source.x, target.x);
var r = Math.min(source.x + source.width,
target.x + target.width);
result.push(new mxPoint(l + (r - l) / 2, y));
}
}
}
},
SegmentConnector: function(state, sourceScaled, targetScaled, controlHints, result)
{
var pts = mxEdgeStyle.scalePointArray(state.absolutePoints, state.view.scale);
var source = mxEdgeStyle.scaleCellState(sourceScaled, state.view.scale);
var target = mxEdgeStyle.scaleCellState(targetScaled, state.view.scale);
var tol = 1;
var lastPushed = (result.length > 0) ? result[0] : null;
var horizontal = true;
var hint = null;
function pushPoint(pt)
{
pt.x = Math.round(pt.x * state.view.scale * 10) / 10;
pt.y = Math.round(pt.y * state.view.scale * 10) / 10;
if (lastPushed == null || Math.abs(lastPushed.x - pt.x) >= tol || Math.abs(lastPushed.y - pt.y) >= Math.max(1, state.view.scale))
{
result.push(pt);
lastPushed = pt;
}
return lastPushed;
} var pt = pts[0];
if (pt == null && source != null)
{
pt = new mxPoint(state.view.getRoutingCenterX(source), state.view.getRoutingCenterY(source));
}
else if (pt != null)
{
pt = pt.clone();
}
var lastInx = pts.length - 1;
if (controlHints != null && controlHints.length > 0)
{
var hints = [];
for (var i = 0; i < controlHints.length; i++)
{
var tmp = state.view.transformControlPoint(state, controlHints[i], true);
if (tmp != null)
{
hints.push(tmp);
}
}
if (hints.length == 0)
{
return;
}
if (pt != null && hints[0] != null)
{
if (Math.abs(hints[0].x - pt.x) < tol)
{
hints[0].x = pt.x;
}
if (Math.abs(hints[0].y - pt.y) < tol)
{
hints[0].y = pt.y;
}
}
var pe = pts[lastInx];
if (pe != null && hints[hints.length - 1] != null)
{
if (Math.abs(hints[hints.length - 1].x - pe.x) < tol)
{
hints[hints.length - 1].x = pe.x;
}
if (Math.abs(hints[hints.length - 1].y - pe.y) < tol)
{
hints[hints.length - 1].y = pe.y;
}
}
hint = hints[0];
var currentTerm = source;
var currentPt = pts[0];
var hozChan = false;
var vertChan = false;
var currentHint = hint;
if (currentPt != null)
{
currentTerm = null;
}
for (var i = 0; i < 2; i++)
{
var fixedVertAlign = currentPt != null && currentPt.x == currentHint.x;
var fixedHozAlign = currentPt != null && currentPt.y == currentHint.y;
var inHozChan = currentTerm != null && (currentHint.y >= currentTerm.y &&
currentHint.y <= currentTerm.y + currentTerm.height);
var inVertChan = currentTerm != null && (currentHint.x >= currentTerm.x &&
currentHint.x <= currentTerm.x + currentTerm.width);
hozChan = fixedHozAlign || (currentPt == null && inHozChan);
vertChan = fixedVertAlign || (currentPt == null && inVertChan);
if (i==0 && ((hozChan && vertChan) || (fixedVertAlign && fixedHozAlign)))
;
else
{
if (currentPt != null && (!fixedHozAlign && !fixedVertAlign) && (inHozChan || inVertChan))
{
horizontal = inHozChan ? false : true;
break;
}
if (vertChan || hozChan)
{
horizontal = hozChan;
if (i == 1)
{
horizontal = hints.length % 2 == 0 ? hozChan : vertChan;
}
break;
}
}
currentTerm = target;
currentPt = pts[lastInx];
if (currentPt != null)
{
currentTerm = null;
}
currentHint = hints[hints.length - 1];
if (fixedVertAlign && fixedHozAlign)
{
hints = hints.slice(1);
}
}
if (horizontal && ((pts[0] != null && pts[0].y != hint.y) ||
(pts[0] == null && source != null &&
(hint.y < source.y || hint.y > source.y + source.height))))
{
pushPoint(new mxPoint(pt.x, hint.y));
}
else if (!horizontal && ((pts[0] != null && pts[0].x != hint.x) ||
(pts[0] == null && source != null &&
(hint.x < source.x || hint.x > source.x + source.width))))
{
pushPoint(new mxPoint(hint.x, pt.y));
}
if (horizontal)
{
pt.y = hint.y;
}
else
{
pt.x = hint.x;
}
for (var i = 0; i < hints.length; i++)
{
horizontal = !horizontal;
hint = hints[i];
if (horizontal)
{
pt.y = hint.y;
}
else
{
pt.x = hint.x;
}
pushPoint(pt.clone());
}
}
else
{
hint = pt;
horizontal = true;
}
pt = pts[lastInx];
if (pt == null && target != null)
{
pt = new mxPoint(state.view.getRoutingCenterX(target), state.view.getRoutingCenterY(target));
}
if (pt != null)
{
if (hint != null)
{
if (horizontal && ((pts[lastInx] != null && pts[lastInx].y != hint.y) ||
(pts[lastInx] == null && target != null &&
(hint.y < target.y || hint.y > target.y + target.height))))
{
pushPoint(new mxPoint(pt.x, hint.y));
}
else if (!horizontal && ((pts[lastInx] != null && pts[lastInx].x != hint.x) ||
(pts[lastInx] == null && target != null &&
(hint.x < target.x || hint.x > target.x + target.width))))
{
pushPoint(new mxPoint(hint.x, pt.y));
}
}
}
if (pts[0] == null && source != null)
{
while (result.length > 1 && result[1] != null &&
mxUtils.contains(source, result[1].x, result[1].y))
{
result.splice(1, 1);
}
}
if (pts[lastInx] == null && target != null)
{
while (result.length > 1 && result[result.length - 1] != null &&
mxUtils.contains(target, result[result.length - 1].x, result[result.length - 1].y))
{
result.splice(result.length - 1, 1);
}
}
if (pe != null && result[result.length - 1] != null &&
Math.abs(pe.x - result[result.length - 1].x) <= tol &&
Math.abs(pe.y - result[result.length - 1].y) <= tol)
{
result.splice(result.length - 1, 1);
if (result[result.length - 1] != null)
{
if (Math.abs(result[result.length - 1].x - pe.x) < tol)
{
result[result.length - 1].x = pe.x;
}
if (Math.abs(result[result.length - 1].y - pe.y) < tol)
{
result[result.length - 1].y = pe.y;
}
}
}
},
orthBuffer: 10,
orthPointsFallback: true,
dirVectors: [ [ -1, 0 ],
[ 0, -1 ], [ 1, 0 ], [ 0, 1 ], [ -1, 0 ], [ 0, -1 ], [ 1, 0 ] ],
wayPoints1: [ [ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0],
[ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0] ],
routePatterns: [
[ [ 513, 2308, 2081, 2562 ], [ 513, 1090, 514, 2184, 2114, 2561 ],
[ 513, 1090, 514, 2564, 2184, 2562 ],
[ 513, 2308, 2561, 1090, 514, 2568, 2308 ] ],
[ [ 514, 1057, 513, 2308, 2081, 2562 ], [ 514, 2184, 2114, 2561 ],
[ 514, 2184, 2562, 1057, 513, 2564, 2184 ],
[ 514, 1057, 513, 2568, 2308, 2561 ] ],
[ [ 1090, 514, 1057, 513, 2308, 2081, 2562 ], [ 2114, 2561 ],
[ 1090, 2562, 1057, 513, 2564, 2184 ],
[ 1090, 514, 1057, 513, 2308, 2561, 2568 ] ],
[ [ 2081, 2562 ], [ 1057, 513, 1090, 514, 2184, 2114, 2561 ],
[ 1057, 513, 1090, 514, 2184, 2562, 2564 ],
[ 1057, 2561, 1090, 514, 2568, 2308 ] ] ],
inlineRoutePatterns: [
[ null, [ 2114, 2568 ], null, null ],
[ null, [ 514, 2081, 2114, 2568 ] , null, null ],
[ null, [ 2114, 2561 ], null, null ],
[ [ 2081, 2562 ], [ 1057, 2114, 2568 ],
[ 2184, 2562 ],
null ] ],
vertexSeperations: [],
limits: [
[ 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ],
LEFT_MASK: 32,
TOP_MASK: 64,
RIGHT_MASK: 128,
BOTTOM_MASK: 256,
LEFT: 1,
TOP: 2,
RIGHT: 4,
BOTTOM: 8,
SIDE_MASK: 480,
CENTER_MASK: 512,
SOURCE_MASK: 1024,
TARGET_MASK: 2048,
VERTEX_MASK: 3072,
getJettySize: function(state, isSource)
{
var value = mxUtils.getValue(state.style, (isSource) ? mxConstants.STYLE_SOURCE_JETTY_SIZE :
mxConstants.STYLE_TARGET_JETTY_SIZE, mxUtils.getValue(state.style,
mxConstants.STYLE_JETTY_SIZE, mxEdgeStyle.orthBuffer));
if (value == 'auto')
{
var type = mxUtils.getValue(state.style, (isSource) ? mxConstants.STYLE_STARTARROW : mxConstants.STYLE_ENDARROW, mxConstants.NONE);
if (type != mxConstants.NONE)
{
var size = mxUtils.getNumber(state.style, (isSource) ? mxConstants.STYLE_STARTSIZE : mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE);
value = Math.max(2, Math.ceil((size + mxEdgeStyle.orthBuffer) / mxEdgeStyle.orthBuffer)) * mxEdgeStyle.orthBuffer;
}
else
{
value = 2 * mxEdgeStyle.orthBuffer;
}
}
return value;
},
scalePointArray: function(points, scale)
{
var result = [];
if (points != null)
{
for (var i = 0; i < points.length; i++)
{
if (points[i] != null)
{
var pt = new mxPoint(Math.round(points[i].x / scale * 10) / 10,
Math.round(points[i].y / scale * 10) / 10);
result[i] = pt;
}
else
{
result[i] = null;
}
}
}
else
{
result = null;
}
return result;
},
scaleCellState: function(state, scale)
{
var result = null;
if (state != null)
{
result = state.clone();
result.setRect(Math.round(state.x / scale * 10) / 10,
Math.round(state.y / scale * 10) / 10,
Math.round(state.width / scale * 10) / 10,
Math.round(state.height / scale * 10) / 10);
}
else
{
result = null;
}
return result;
},
OrthConnector: function(state, sourceScaled, targetScaled, controlHints, result)
{
var graph = state.view.graph;
var sourceEdge = source == null ? false : graph.getModel().isEdge(source.cell);
var targetEdge = target == null ? false : graph.getModel().isEdge(target.cell);
var pts = mxEdgeStyle.scalePointArray(state.absolutePoints, state.view.scale);
var source = mxEdgeStyle.scaleCellState(sourceScaled, state.view.scale);
var target = mxEdgeStyle.scaleCellState(targetScaled, state.view.scale);
var p0 = pts[0];
var pe = pts[pts.length-1];
var sourceX = source != null ? source.x : p0.x;
var sourceY = source != null ? source.y : p0.y;
var sourceWidth = source != null ? source.width : 0;
var sourceHeight = source != null ? source.height : 0;
var targetX = target != null ? target.x : pe.x;
var targetY = target != null ? target.y : pe.y;
var targetWidth = target != null ? target.width : 0;
var targetHeight = target != null ? target.height : 0;
var sourceBuffer = mxEdgeStyle.getJettySize(state, true);
var targetBuffer = mxEdgeStyle.getJettySize(state, false);
if (source != null && target == source)
{
targetBuffer = Math.max(sourceBuffer, targetBuffer);
sourceBuffer = targetBuffer;
}
var totalBuffer = targetBuffer + sourceBuffer;
var tooShort = false;
if (p0 != null && pe != null)
{
var dx = pe.x - p0.x;
var dy = pe.y - p0.y;
tooShort = dx * dx + dy * dy < totalBuffer * totalBuffer;
}
if (tooShort || (mxEdgeStyle.orthPointsFallback && (controlHints != null &&
controlHints.length > 0)) || sourceEdge || targetEdge)
{
mxEdgeStyle.SegmentConnector(state, sourceScaled, targetScaled, controlHints, result);
return;
}
var portConstraint = [mxConstants.DIRECTION_MASK_ALL, mxConstants.DIRECTION_MASK_ALL];
var rotation = 0;
if (source != null)
{
portConstraint[0] = mxUtils.getPortConstraints(source, state, true,
mxConstants.DIRECTION_MASK_ALL);
rotation = mxUtils.getValue(source.style, mxConstants.STYLE_ROTATION, 0);
if (rotation != 0)
{
var newRect = mxUtils.getBoundingBox(new mxRectangle(sourceX, sourceY, sourceWidth, sourceHeight), rotation);
sourceX = newRect.x;
sourceY = newRect.y;
sourceWidth = newRect.width;
sourceHeight = newRect.height;
}
}
if (target != null)
{
portConstraint[1] = mxUtils.getPortConstraints(target, state, false,
mxConstants.DIRECTION_MASK_ALL);
rotation = mxUtils.getValue(target.style, mxConstants.STYLE_ROTATION, 0);
if (rotation != 0)
{
var newRect = mxUtils.getBoundingBox(new mxRectangle(targetX, targetY, targetWidth, targetHeight), rotation);
targetX = newRect.x;
targetY = newRect.y;
targetWidth = newRect.width;
targetHeight = newRect.height;
}
}
var dir = [0, 0];
var geo = [ [sourceX, sourceY, sourceWidth, sourceHeight] ,
[targetX, targetY, targetWidth, targetHeight] ];
var buffer = [sourceBuffer, targetBuffer];
for (var i = 0; i < 2; i++)
{
mxEdgeStyle.limits[i][1] = geo[i][0] - buffer[i];
mxEdgeStyle.limits[i][2] = geo[i][1] - buffer[i];
mxEdgeStyle.limits[i][4] = geo[i][0] + geo[i][2] + buffer[i];
mxEdgeStyle.limits[i][8] = geo[i][1] + geo[i][3] + buffer[i];
}
var sourceCenX = geo[0][0] + geo[0][2] / 2.0;
var sourceCenY = geo[0][1] + geo[0][3] / 2.0;
var targetCenX = geo[1][0] + geo[1][2] / 2.0;
var targetCenY = geo[1][1] + geo[1][3] / 2.0;
var dx = sourceCenX - targetCenX;
var dy = sourceCenY - targetCenY;
var quad = 0;
if (dx < 0)
{
if (dy < 0)
{
quad = 2;
}
else
{
quad = 1;
}
}
else
{
if (dy <= 0)
{
quad = 3;
if (dx == 0)
{
quad = 2;
}
}
}
var currentTerm = null;
if (source != null)
{
currentTerm = p0;
}
var constraint = [ [0.5, 0.5] , [0.5, 0.5] ];
for (var i = 0; i < 2; i++)
{
if (currentTerm != null)
{
constraint[i][0] = (currentTerm.x - geo[i][0]) / geo[i][2];
if (Math.abs(currentTerm.x - geo[i][0]) <= 1)
{
dir[i] = mxConstants.DIRECTION_MASK_WEST;
}
else if (Math.abs(currentTerm.x - geo[i][0] - geo[i][2]) <= 1)
{
dir[i] = mxConstants.DIRECTION_MASK_EAST;
}
constraint[i][1] = (currentTerm.y - geo[i][1]) / geo[i][3];
if (Math.abs(currentTerm.y - geo[i][1]) <= 1)
{
dir[i] = mxConstants.DIRECTION_MASK_NORTH;
}
else if (Math.abs(currentTerm.y - geo[i][1] - geo[i][3]) <= 1)
{
dir[i] = mxConstants.DIRECTION_MASK_SOUTH;
}
}
currentTerm = null;
if (target != null)
{
currentTerm = pe;
}
}
var sourceTopDist = geo[0][1] - (geo[1][1] + geo[1][3]);
var sourceLeftDist = geo[0][0] - (geo[1][0] + geo[1][2]);
var sourceBottomDist = geo[1][1] - (geo[0][1] + geo[0][3]);
var sourceRightDist = geo[1][0] - (geo[0][0] + geo[0][2]);
mxEdgeStyle.vertexSeperations[1] = Math.max(sourceLeftDist - totalBuffer, 0);
mxEdgeStyle.vertexSeperations[2] = Math.max(sourceTopDist - totalBuffer, 0);
mxEdgeStyle.vertexSeperations[4] = Math.max(sourceBottomDist - totalBuffer, 0);
mxEdgeStyle.vertexSeperations[3] = Math.max(sourceRightDist - totalBuffer, 0);
var dirPref = [];
var horPref = [];
var vertPref = [];
horPref[0] = (sourceLeftDist >= sourceRightDist) ? mxConstants.DIRECTION_MASK_WEST
: mxConstants.DIRECTION_MASK_EAST;
vertPref[0] = (sourceTopDist >= sourceBottomDist) ? mxConstants.DIRECTION_MASK_NORTH
: mxConstants.DIRECTION_MASK_SOUTH;
horPref[1] = mxUtils.reversePortConstraints(horPref[0]);
vertPref[1] = mxUtils.reversePortConstraints(vertPref[0]);
var preferredHorizDist = sourceLeftDist >= sourceRightDist ? sourceLeftDist
: sourceRightDist;
var preferredVertDist = sourceTopDist >= sourceBottomDist ? sourceTopDist
: sourceBottomDist;
var prefOrdering = [ [0, 0] , [0, 0] ];
var preferredOrderSet = false;
for (var i = 0; i < 2; i++)
{
if (dir[i] != 0x0)
{
continue;
}
if ((horPref[i] & portConstraint[i]) == 0)
{
horPref[i] = mxUtils.reversePortConstraints(horPref[i]);
}
if ((vertPref[i] & portConstraint[i]) == 0)
{
vertPref[i] = mxUtils
.reversePortConstraints(vertPref[i]);
}
prefOrdering[i][0] = vertPref[i];
prefOrdering[i][1] = horPref[i];
}
if (preferredVertDist > 0
&& preferredHorizDist > 0)
{
if (((horPref[0] & portConstraint[0]) > 0)
&& ((vertPref[1] & portConstraint[1]) > 0))
{
prefOrdering[0][0] = horPref[0];
prefOrdering[0][1] = vertPref[0];
prefOrdering[1][0] = vertPref[1];
prefOrdering[1][1] = horPref[1];
preferredOrderSet = true;
}
else if (((vertPref[0] & portConstraint[0]) > 0)
&& ((horPref[1] & portConstraint[1]) > 0))
{
prefOrdering[0][0] = vertPref[0];
prefOrdering[0][1] = horPref[0];
prefOrdering[1][0] = horPref[1];
prefOrdering[1][1] = vertPref[1];
preferredOrderSet = true;
}
}
if (preferredVertDist > 0 && !preferredOrderSet)
{
prefOrdering[0][0] = vertPref[0];
prefOrdering[0][1] = horPref[0];
prefOrdering[1][0] = vertPref[1];
prefOrdering[1][1] = horPref[1];
preferredOrderSet = true;
}
if (preferredHorizDist > 0 && !preferredOrderSet)
{
prefOrdering[0][0] = horPref[0];
prefOrdering[0][1] = vertPref[0];
prefOrdering[1][0] = horPref[1];
prefOrdering[1][1] = vertPref[1];
preferredOrderSet = true;
}
for (var i = 0; i < 2; i++)
{
if (dir[i] != 0x0)
{
continue;
}
if ((prefOrdering[i][0] & portConstraint[i]) == 0)
{
prefOrdering[i][0] = prefOrdering[i][1];
}
dirPref[i] = prefOrdering[i][0] & portConstraint[i];
dirPref[i] |= (prefOrdering[i][1] & portConstraint[i]) << 8;
dirPref[i] |= (prefOrdering[1 - i][i] & portConstraint[i]) << 16;
dirPref[i] |= (prefOrdering[1 - i][1 - i] & portConstraint[i]) << 24;
if ((dirPref[i] & 0xF) == 0)
{
dirPref[i] = dirPref[i] << 8;
}
if ((dirPref[i] & 0xF00) == 0)
{
dirPref[i] = (dirPref[i] & 0xF) | dirPref[i] >> 8;
}
if ((dirPref[i] & 0xF0000) == 0)
{
dirPref[i] = (dirPref[i] & 0xFFFF)
| ((dirPref[i] & 0xF000000) >> 8);
}
dir[i] = dirPref[i] & 0xF;
if (portConstraint[i] == mxConstants.DIRECTION_MASK_WEST
|| portConstraint[i] == mxConstants.DIRECTION_MASK_NORTH
|| portConstraint[i] == mxConstants.DIRECTION_MASK_EAST
|| portConstraint[i] == mxConstants.DIRECTION_MASK_SOUTH)
{
dir[i] = portConstraint[i];
}
}
var sourceIndex = dir[0] == mxConstants.DIRECTION_MASK_EAST ? 3
: dir[0];
var targetIndex = dir[1] == mxConstants.DIRECTION_MASK_EAST ? 3
: dir[1];
sourceIndex -= quad;
targetIndex -= quad;
if (sourceIndex < 1)
{
sourceIndex += 4;
}
if (targetIndex < 1)
{
targetIndex += 4;
}
var routePattern = mxEdgeStyle.routePatterns[sourceIndex - 1][targetIndex - 1];
mxEdgeStyle.wayPoints1[0][0] = geo[0][0];
mxEdgeStyle.wayPoints1[0][1] = geo[0][1];
switch (dir[0])
{
case mxConstants.DIRECTION_MASK_WEST:
mxEdgeStyle.wayPoints1[0][0] -= sourceBuffer;
mxEdgeStyle.wayPoints1[0][1] += constraint[0][1] * geo[0][3];
break;
case mxConstants.DIRECTION_MASK_SOUTH:
mxEdgeStyle.wayPoints1[0][0] += constraint[0][0] * geo[0][2];
mxEdgeStyle.wayPoints1[0][1] += geo[0][3] + sourceBuffer;
break;
case mxConstants.DIRECTION_MASK_EAST:
mxEdgeStyle.wayPoints1[0][0] += geo[0][2] + sourceBuffer;
mxEdgeStyle.wayPoints1[0][1] += constraint[0][1] * geo[0][3];
break;
case mxConstants.DIRECTION_MASK_NORTH:
mxEdgeStyle.wayPoints1[0][0] += constraint[0][0] * geo[0][2];
mxEdgeStyle.wayPoints1[0][1] -= sourceBuffer;
break;
}
var currentIndex = 0;
var lastOrientation = (dir[0] & (mxConstants.DIRECTION_MASK_EAST | mxConstants.DIRECTION_MASK_WEST)) > 0 ? 0
: 1;
var initialOrientation = lastOrientation;
var currentOrientation = 0;
for (var i = 0; i < routePattern.length; i++)
{
var nextDirection = routePattern[i] & 0xF;
var directionIndex = nextDirection == mxConstants.DIRECTION_MASK_EAST ? 3
: nextDirection;
directionIndex += quad;
if (directionIndex > 4)
{
directionIndex -= 4;
}
var direction = mxEdgeStyle.dirVectors[directionIndex - 1];
currentOrientation = (directionIndex % 2 > 0) ? 0 : 1;
if (currentOrientation != lastOrientation)
{
currentIndex++;
mxEdgeStyle.wayPoints1[currentIndex][0] = mxEdgeStyle.wayPoints1[currentIndex - 1][0];
mxEdgeStyle.wayPoints1[currentIndex][1] = mxEdgeStyle.wayPoints1[currentIndex - 1][1];
}
var tar = (routePattern[i] & mxEdgeStyle.TARGET_MASK) > 0;
var sou = (routePattern[i] & mxEdgeStyle.SOURCE_MASK) > 0;
var side = (routePattern[i] & mxEdgeStyle.SIDE_MASK) >> 5;
side = side << quad;
if (side > 0xF)
{
side = side >> 4;
}
var center = (routePattern[i] & mxEdgeStyle.CENTER_MASK) > 0;
if ((sou || tar) && side < 9)
{
var limit = 0;
var souTar = sou ? 0 : 1;
if (center && currentOrientation == 0)
{
limit = geo[souTar][0] + constraint[souTar][0] * geo[souTar][2];
}
else if (center)
{
limit = geo[souTar][1] + constraint[souTar][1] * geo[souTar][3];
}
else
{
limit = mxEdgeStyle.limits[souTar][side];
}
if (currentOrientation == 0)
{
var lastX = mxEdgeStyle.wayPoints1[currentIndex][0];
var deltaX = (limit - lastX) * direction[0];
if (deltaX > 0)
{
mxEdgeStyle.wayPoints1[currentIndex][0] += direction[0]
* deltaX;
}
}
else
{
var lastY = mxEdgeStyle.wayPoints1[currentIndex][1];
var deltaY = (limit - lastY) * direction[1];
if (deltaY > 0)
{
mxEdgeStyle.wayPoints1[currentIndex][1] += direction[1]
* deltaY;
}
}
}
else if (center)
{
mxEdgeStyle.wayPoints1[currentIndex][0] += direction[0]
* Math.abs(mxEdgeStyle.vertexSeperations[directionIndex] / 2);
mxEdgeStyle.wayPoints1[currentIndex][1] += direction[1]
* Math.abs(mxEdgeStyle.vertexSeperations[directionIndex] / 2);
}
if (currentIndex > 0
&& mxEdgeStyle.wayPoints1[currentIndex][currentOrientation] == mxEdgeStyle.wayPoints1[currentIndex - 1][currentOrientation])
{
currentIndex--;
}
else
{
lastOrientation = currentOrientation;
}
}
for (var i = 0; i <= currentIndex; i++)
{
if (i == currentIndex)
{
var targetOrientation = (dir[1] & (mxConstants.DIRECTION_MASK_EAST | mxConstants.DIRECTION_MASK_WEST)) > 0 ? 0
: 1;
var sameOrient = targetOrientation == initialOrientation ? 0 : 1;
if (sameOrient != (currentIndex + 1) % 2)
{
break;
}
}
result.push(new mxPoint(Math.round(mxEdgeStyle.wayPoints1[i][0] * state.view.scale * 10) / 10,
Math.round(mxEdgeStyle.wayPoints1[i][1] * state.view.scale * 10) / 10));
}
var index = 1;
while (index < result.length)
{
if (result[index - 1] == null || result[index] == null ||
result[index - 1].x != result[index].x ||
result[index - 1].y != result[index].y)
{
index++;
}
else
{
result.splice(index, 1);
}
}
},
getRoutePattern: function(dir, quad, dx, dy)
{
var sourceIndex = dir[0] == mxConstants.DIRECTION_MASK_EAST ? 3
: dir[0];
var targetIndex = dir[1] == mxConstants.DIRECTION_MASK_EAST ? 3
: dir[1];
sourceIndex -= quad;
targetIndex -= quad;
if (sourceIndex < 1)
{
sourceIndex += 4;
}
if (targetIndex < 1)
{
targetIndex += 4;
}
var result = routePatterns[sourceIndex - 1][targetIndex - 1];
if (dx == 0 || dy == 0)
{
if (inlineRoutePatterns[sourceIndex - 1][targetIndex - 1] != null)
{
result = inlineRoutePatterns[sourceIndex - 1][targetIndex - 1];
}
}
return result;
}
};
__mxOutput.mxEdgeStyle = typeof mxEdgeStyle !== 'undefined' ? mxEdgeStyle : undefined;
var mxStyleRegistry =
{
values: [],
putValue: function(name, obj)
{
mxStyleRegistry.values[name] = obj;
},
getValue: function(name)
{
return mxStyleRegistry.values[name];
},
getName: function(value)
{
for (var key in mxStyleRegistry.values)
{
if (mxStyleRegistry.values[key] == value)
{
return key;
}
}
return null;
}
};
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_ELBOW, mxEdgeStyle.ElbowConnector);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_ENTITY_RELATION, mxEdgeStyle.EntityRelation);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_LOOP, mxEdgeStyle.Loop);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_SIDETOSIDE, mxEdgeStyle.SideToSide);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_TOPTOBOTTOM, mxEdgeStyle.TopToBottom);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_ORTHOGONAL, mxEdgeStyle.OrthConnector);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_SEGMENT, mxEdgeStyle.SegmentConnector);
mxStyleRegistry.putValue(mxConstants.PERIMETER_ELLIPSE, mxPerimeter.EllipsePerimeter);
mxStyleRegistry.putValue(mxConstants.PERIMETER_RECTANGLE, mxPerimeter.RectanglePerimeter);
mxStyleRegistry.putValue(mxConstants.PERIMETER_RHOMBUS, mxPerimeter.RhombusPerimeter);
mxStyleRegistry.putValue(mxConstants.PERIMETER_TRIANGLE, mxPerimeter.TrianglePerimeter);
mxStyleRegistry.putValue(mxConstants.PERIMETER_HEXAGON, mxPerimeter.HexagonPerimeter);
__mxOutput.mxStyleRegistry = typeof mxStyleRegistry !== 'undefined' ? mxStyleRegistry : undefined;
function mxGraphView(graph)
{
this.graph = graph;
this.translate = new mxPoint();
this.graphBounds = new mxRectangle();
this.states = new mxDictionary();
} mxGraphView.prototype = new mxEventSource();
mxGraphView.prototype.constructor = mxGraphView;
mxGraphView.prototype.EMPTY_POINT = new mxPoint();
mxGraphView.prototype.doneResource = (mxClient.language != 'none') ? 'done' : '';
mxGraphView.prototype.updatingDocumentResource = (mxClient.language != 'none') ? 'updatingDocument' : '';
mxGraphView.prototype.allowEval = false;
mxGraphView.prototype.captureDocumentGesture = true;
mxGraphView.prototype.optimizeVmlReflows = true;
mxGraphView.prototype.rendering = true;
mxGraphView.prototype.graph = null;
mxGraphView.prototype.currentRoot = null;
mxGraphView.prototype.graphBounds = null;
mxGraphView.prototype.scale = 1;
mxGraphView.prototype.translate = null;
mxGraphView.prototype.states = null;
mxGraphView.prototype.updateStyle = false;
mxGraphView.prototype.lastNode = null;
mxGraphView.prototype.lastHtmlNode = null;
mxGraphView.prototype.lastForegroundNode = null;
mxGraphView.prototype.lastForegroundHtmlNode = null;
mxGraphView.prototype.getGraphBounds = function()
{
return this.graphBounds;
};
mxGraphView.prototype.setGraphBounds = function(value)
{
this.graphBounds = value;
};
mxGraphView.prototype.getBounds = function(cells)
{
var result = null;
if (cells != null && cells.length > 0)
{
var model = this.graph.getModel();
for (var i = 0; i < cells.length; i++)
{
if (model.isVertex(cells[i]) || model.isEdge(cells[i]))
{
var state = this.getState(cells[i]);
if (state != null)
{
if (result == null)
{
result = mxRectangle.fromRectangle(state);
}
else
{
result.add(state);
}
}
}
}
}
return result;
};
mxGraphView.prototype.setCurrentRoot = function(root)
{
if (this.currentRoot != root)
{
var change = new mxCurrentRootChange(this, root);
change.execute();
var edit = new mxUndoableEdit(this, true);
edit.add(change);
this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
this.graph.sizeDidChange();
}
return root;
};
mxGraphView.prototype.scaleAndTranslate = function(scale, dx, dy)
{
var previousScale = this.scale;
var previousTranslate = new mxPoint(this.translate.x, this.translate.y);
if (this.scale != scale || this.translate.x != dx || this.translate.y != dy)
{
this.scale = scale;
this.translate.x = dx;
this.translate.y = dy;
if (this.isEventsEnabled())
{
this.viewStateChanged();
}
}
this.fireEvent(new mxEventObject(mxEvent.SCALE_AND_TRANSLATE,
'scale', scale, 'previousScale', previousScale,
'translate', this.translate, 'previousTranslate', previousTranslate));
};
mxGraphView.prototype.getScale = function()
{
return this.scale;
};
mxGraphView.prototype.setScale = function(value)
{
var previousScale = this.scale;
if (this.scale != value)
{
this.scale = value;
if (this.isEventsEnabled())
{
this.viewStateChanged();
}
}
this.fireEvent(new mxEventObject(mxEvent.SCALE,
'scale', value, 'previousScale', previousScale));
};
mxGraphView.prototype.getTranslate = function()
{
return this.translate;
};
mxGraphView.prototype.setTranslate = function(dx, dy)
{
var previousTranslate = new mxPoint(this.translate.x, this.translate.y);
if (this.translate.x != dx || this.translate.y != dy)
{
this.translate.x = dx;
this.translate.y = dy;
if (this.isEventsEnabled())
{
this.viewStateChanged();
}
}
this.fireEvent(new mxEventObject(mxEvent.TRANSLATE,
'translate', this.translate, 'previousTranslate', previousTranslate));
};
mxGraphView.prototype.viewStateChanged = function()
{
this.revalidate();
this.graph.sizeDidChange();
};
mxGraphView.prototype.refresh = function()
{
if (this.currentRoot != null)
{
this.clear();
}
this.revalidate();
};
mxGraphView.prototype.revalidate = function()
{
this.invalidate();
this.validate();
};
mxGraphView.prototype.clear = function(cell, force, recurse)
{
var model = this.graph.getModel();
cell = cell || model.getRoot();
force = (force != null) ? force : false;
recurse = (recurse != null) ? recurse : true;
this.removeState(cell);
if (recurse && (force || cell != this.currentRoot))
{
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
this.clear(model.getChildAt(cell, i), force);
}
}
else
{
this.invalidate(cell);
}
};
mxGraphView.prototype.invalidate = function(cell, recurse, includeEdges)
{
var model = this.graph.getModel();
cell = cell || model.getRoot();
recurse = (recurse != null) ? recurse : true;
includeEdges = (includeEdges != null) ? includeEdges : true;
var state = this.getState(cell);
if (state != null)
{
state.invalid = true;
}
if (!cell.invalidating)
{
cell.invalidating = true;
if (recurse)
{
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(cell, i);
this.invalidate(child, recurse, includeEdges);
}
}
if (includeEdges)
{
var edgeCount = model.getEdgeCount(cell);
for (var i = 0; i < edgeCount; i++)
{
this.invalidate(model.getEdgeAt(cell, i), recurse, includeEdges);
}
}
delete cell.invalidating;
}
};
mxGraphView.prototype.validate = function(cell)
{
var t0 = mxLog.enter('mxGraphView.validate');
window.status = mxResources.get(this.updatingDocumentResource) ||
this.updatingDocumentResource;
this.resetValidationState();
var prevDisplay = null;
if (this.optimizeVmlReflows && this.canvas != null && this.textDiv == null &&
((document.documentMode == 8 && !mxClient.IS_EM) || mxClient.IS_QUIRKS))
{
this.placeholder = document.createElement('div');
this.placeholder.style.position = 'absolute';
this.placeholder.style.width = this.canvas.clientWidth + 'px';
this.placeholder.style.height = this.canvas.clientHeight + 'px';
this.canvas.parentNode.appendChild(this.placeholder);
prevDisplay = this.drawPane.style.display;
this.canvas.style.display = 'none';
this.textDiv = document.createElement('div');
this.textDiv.style.position = 'absolute';
this.textDiv.style.whiteSpace = 'nowrap';
this.textDiv.style.visibility = 'hidden';
this.textDiv.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
this.textDiv.style.zoom = '1';
document.body.appendChild(this.textDiv);
}
var graphBounds = this.getBoundingBox(this.validateCellState(
this.validateCell(cell || ((this.currentRoot != null) ?
this.currentRoot : this.graph.getModel().getRoot()))));
this.setGraphBounds((graphBounds != null) ? graphBounds : this.getEmptyBounds());
this.validateBackground();
if (prevDisplay != null)
{
this.canvas.style.display = prevDisplay;
this.textDiv.parentNode.removeChild(this.textDiv);
if (this.placeholder != null)
{
this.placeholder.parentNode.removeChild(this.placeholder);
}
this.textDiv = null;
}
this.resetValidationState();
window.status = mxResources.get(this.doneResource) ||
this.doneResource;
mxLog.leave('mxGraphView.validate', t0);
};
mxGraphView.prototype.getEmptyBounds = function()
{
return new mxRectangle(this.translate.x * this.scale, this.translate.y * this.scale);
};
mxGraphView.prototype.getBoundingBox = function(state, recurse)
{
recurse = (recurse != null) ? recurse : true;
var bbox = null;
if (state != null)
{
if (state.shape != null && state.shape.boundingBox != null)
{
bbox = state.shape.boundingBox.clone();
}
if (state.text != null && state.text.boundingBox != null)
{
if (bbox != null)
{
bbox.add(state.text.boundingBox);
}
else
{
bbox = state.text.boundingBox.clone();
}
}
if (recurse)
{
var model = this.graph.getModel();
var childCount = model.getChildCount(state.cell);
for (var i = 0; i < childCount; i++)
{
var bounds = this.getBoundingBox(this.getState(model.getChildAt(state.cell, i)));
if (bounds != null)
{
if (bbox == null)
{
bbox = bounds;
}
else
{
bbox.add(bounds);
}
}
}
}
}
return bbox;
};
mxGraphView.prototype.createBackgroundPageShape = function(bounds)
{
return new mxRectangleShape(bounds, 'white', 'black');
};
mxGraphView.prototype.validateBackground = function()
{
this.validateBackgroundImage();
this.validateBackgroundPage();
};
mxGraphView.prototype.validateBackgroundImage = function()
{
var bg = this.graph.getBackgroundImage();
if (bg != null)
{
if (this.backgroundImage == null || this.backgroundImage.image != bg.src)
{
if (this.backgroundImage != null)
{
this.backgroundImage.destroy();
}
var bounds = new mxRectangle(0, 0, 1, 1);
this.backgroundImage = new mxImageShape(bounds, bg.src);
this.backgroundImage.dialect = this.graph.dialect;
this.backgroundImage.init(this.backgroundPane);
this.backgroundImage.redraw();
if (document.documentMode == 8 && !mxClient.IS_EM)
{
mxEvent.addGestureListeners(this.backgroundImage.node,
mxUtils.bind(this, function(evt)
{
this.graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt));
}),
mxUtils.bind(this, function(evt)
{
this.graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt));
}),
mxUtils.bind(this, function(evt)
{
this.graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
})
);
}
}
this.redrawBackgroundImage(this.backgroundImage, bg);
}
else if (this.backgroundImage != null)
{
this.backgroundImage.destroy();
this.backgroundImage = null;
}
};
mxGraphView.prototype.validateBackgroundPage = function()
{
if (this.graph.pageVisible)
{
var bounds = this.getBackgroundPageBounds();
if (this.backgroundPageShape == null)
{
this.backgroundPageShape = this.createBackgroundPageShape(bounds);
this.backgroundPageShape.scale = this.scale;
this.backgroundPageShape.isShadow = true;
this.backgroundPageShape.dialect = this.graph.dialect;
this.backgroundPageShape.init(this.backgroundPane);
this.backgroundPageShape.redraw();
if (this.graph.nativeDblClickEnabled)
{
mxEvent.addListener(this.backgroundPageShape.node, 'dblclick', mxUtils.bind(this, function(evt)
{
this.graph.dblClick(evt);
}));
}
mxEvent.addGestureListeners(this.backgroundPageShape.node,
mxUtils.bind(this, function(evt)
{
this.graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt));
}),
mxUtils.bind(this, function(evt)
{
if (this.graph.tooltipHandler != null && this.graph.tooltipHandler.isHideOnHover())
{
this.graph.tooltipHandler.hide();
}
if (this.graph.isMouseDown && !mxEvent.isConsumed(evt))
{
this.graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt));
}
}),
mxUtils.bind(this, function(evt)
{
this.graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
})
);
}
else
{
this.backgroundPageShape.scale = this.scale;
this.backgroundPageShape.bounds = bounds;
this.backgroundPageShape.redraw();
}
}
else if (this.backgroundPageShape != null)
{
this.backgroundPageShape.destroy();
this.backgroundPageShape = null;
}
};
mxGraphView.prototype.getBackgroundPageBounds = function()
{
var fmt = this.graph.pageFormat;
var ps = this.scale * this.graph.pageScale;
var bounds = new mxRectangle(this.scale * this.translate.x, this.scale * this.translate.y,
fmt.width * ps, fmt.height * ps);
return bounds;
};
mxGraphView.prototype.redrawBackgroundImage = function(backgroundImage, bg)
{
backgroundImage.scale = this.scale;
backgroundImage.bounds.x = this.scale * this.translate.x;
backgroundImage.bounds.y = this.scale * this.translate.y;
backgroundImage.bounds.width = this.scale * bg.width;
backgroundImage.bounds.height = this.scale * bg.height;
backgroundImage.redraw();
};
mxGraphView.prototype.validateCell = function(cell, visible)
{
visible = (visible != null) ? visible : true;
if (cell != null)
{
visible = visible && this.graph.isCellVisible(cell);
var state = this.getState(cell, visible);
if (state != null && !visible)
{
this.removeState(cell);
}
else
{
var model = this.graph.getModel();
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
this.validateCell(model.getChildAt(cell, i), visible &&
(!this.isCellCollapsed(cell) || cell == this.currentRoot));
}
}
}
return cell;
};
mxGraphView.prototype.validateCellState = function(cell, recurse)
{
recurse = (recurse != null) ? recurse : true;
var state = null;
if (cell != null)
{
state = this.getState(cell);
if (state != null)
{
var model = this.graph.getModel();
if (state.invalid)
{
state.invalid = false;
if (state.style == null || state.invalidStyle)
{
state.style = this.graph.getCellStyle(state.cell);
state.invalidStyle = false;
}
if (cell != this.currentRoot)
{
this.validateCellState(model.getParent(cell), false);
}
state.setVisibleTerminalState(this.validateCellState(this.getVisibleTerminal(cell, true), false), true);
state.setVisibleTerminalState(this.validateCellState(this.getVisibleTerminal(cell, false), false), false);
this.updateCellState(state);
if (cell != this.currentRoot && !state.invalid)
{
this.graph.cellRenderer.redraw(state, false, this.isRendering());
state.updateCachedBounds();
}
}
if (recurse && !state.invalid)
{
if (state.shape != null)
{
this.stateValidated(state);
}
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
this.validateCellState(model.getChildAt(cell, i));
}
}
}
}
return state;
};
mxGraphView.prototype.updateCellState = function(state)
{
state.absoluteOffset.x = 0;
state.absoluteOffset.y = 0;
state.origin.x = 0;
state.origin.y = 0;
state.length = 0;
if (state.cell != this.currentRoot)
{
var model = this.graph.getModel();
var pState = this.getState(model.getParent(state.cell));
if (pState != null && pState.cell != this.currentRoot)
{
state.origin.x += pState.origin.x;
state.origin.y += pState.origin.y;
}
var offset = this.graph.getChildOffsetForCell(state.cell);
if (offset != null)
{
state.origin.x += offset.x;
state.origin.y += offset.y;
}
var geo = this.graph.getCellGeometry(state.cell);
if (geo != null)
{
if (!model.isEdge(state.cell))
{
offset = (geo.offset != null) ? geo.offset : this.EMPTY_POINT;
if (geo.relative && pState != null)
{
if (model.isEdge(pState.cell))
{
var origin = this.getPoint(pState, geo);
if (origin != null)
{
state.origin.x += (origin.x / this.scale) - pState.origin.x - this.translate.x;
state.origin.y += (origin.y / this.scale) - pState.origin.y - this.translate.y;
}
}
else
{
state.origin.x += geo.x * pState.unscaledWidth + offset.x;
state.origin.y += geo.y * pState.unscaledHeight + offset.y;
}
}
else
{
state.absoluteOffset.x = this.scale * offset.x;
state.absoluteOffset.y = this.scale * offset.y;
state.origin.x += geo.x;
state.origin.y += geo.y;
}
}
state.x = this.scale * (this.translate.x + state.origin.x);
state.y = this.scale * (this.translate.y + state.origin.y);
state.width = this.scale * geo.width;
state.unscaledWidth = geo.width;
state.height = this.scale * geo.height;
state.unscaledHeight = geo.height;
if (model.isVertex(state.cell))
{
this.updateVertexState(state, geo);
}
if (model.isEdge(state.cell))
{
this.updateEdgeState(state, geo);
}
}
}
state.updateCachedBounds();
};
mxGraphView.prototype.isCellCollapsed = function(cell)
{
return this.graph.isCellCollapsed(cell);
};
mxGraphView.prototype.updateVertexState = function(state, geo)
{
var model = this.graph.getModel();
var pState = this.getState(model.getParent(state.cell));
if (geo.relative && pState != null && !model.isEdge(pState.cell))
{
var alpha = mxUtils.toRadians(pState.style[mxConstants.STYLE_ROTATION] || '0');
if (alpha != 0)
{
var cos = Math.cos(alpha);
var sin = Math.sin(alpha);
var ct = new mxPoint(state.getCenterX(), state.getCenterY());
var cx = new mxPoint(pState.getCenterX(), pState.getCenterY());
var pt = mxUtils.getRotatedPoint(ct, cos, sin, cx);
state.x = pt.x - state.width / 2;
state.y = pt.y - state.height / 2;
}
}
this.updateVertexLabelOffset(state);
};
mxGraphView.prototype.updateEdgeState = function(state, geo)
{
var source = state.getVisibleTerminalState(true);
var target = state.getVisibleTerminalState(false);
if ((this.graph.model.getTerminal(state.cell, true) != null && source == null) ||
(source == null && geo.getTerminalPoint(true) == null) ||
(this.graph.model.getTerminal(state.cell, false) != null && target == null) ||
(target == null && geo.getTerminalPoint(false) == null))
{
this.clear(state.cell, true);
}
else
{
this.updateFixedTerminalPoints(state, source, target);
this.updatePoints(state, geo.points, source, target);
this.updateFloatingTerminalPoints(state, source, target);
var pts = state.absolutePoints;
if (state.cell != this.currentRoot && (pts == null || pts.length < 2 ||
pts[0] == null || pts[pts.length - 1] == null))
{
this.clear(state.cell, true);
}
else
{
this.updateEdgeBounds(state);
this.updateEdgeLabelOffset(state);
}
}
};
mxGraphView.prototype.updateVertexLabelOffset = function(state)
{
var h = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
if (h == mxConstants.ALIGN_LEFT)
{
var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
if (lw != null)
{
lw *= this.scale;
}
else
{
lw = state.width;
}
state.absoluteOffset.x -= lw;
}
else if (h == mxConstants.ALIGN_RIGHT)
{
state.absoluteOffset.x += state.width;
}
else if (h == mxConstants.ALIGN_CENTER)
{
var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
if (lw != null)
{
var align = mxUtils.getValue(state.style, mxConstants.STYLE_ALIGN, mxConstants.ALIGN_CENTER);
var dx = 0;
if (align == mxConstants.ALIGN_CENTER)
{
dx = 0.5;
}
else if (align == mxConstants.ALIGN_RIGHT)
{
dx = 1;
}
if (dx != 0)
{
state.absoluteOffset.x -= (lw * this.scale - state.width) * dx;
}
}
}
var v = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
if (v == mxConstants.ALIGN_TOP)
{
state.absoluteOffset.y -= state.height;
}
else if (v == mxConstants.ALIGN_BOTTOM)
{
state.absoluteOffset.y += state.height;
}
};
mxGraphView.prototype.resetValidationState = function()
{
this.lastNode = null;
this.lastHtmlNode = null;
this.lastForegroundNode = null;
this.lastForegroundHtmlNode = null;
};
mxGraphView.prototype.stateValidated = function(state)
{
var fg = (this.graph.getModel().isEdge(state.cell) && this.graph.keepEdgesInForeground) ||
(this.graph.getModel().isVertex(state.cell) && this.graph.keepEdgesInBackground);
var htmlNode = (fg) ? this.lastForegroundHtmlNode || this.lastHtmlNode : this.lastHtmlNode;
var node = (fg) ? this.lastForegroundNode || this.lastNode : this.lastNode;
var result = this.graph.cellRenderer.insertStateAfter(state, node, htmlNode);
if (fg)
{
this.lastForegroundHtmlNode = result[1];
this.lastForegroundNode = result[0];
}
else
{
this.lastHtmlNode = result[1];
this.lastNode = result[0];
}
};
mxGraphView.prototype.updateFixedTerminalPoints = function(edge, source, target)
{
this.updateFixedTerminalPoint(edge, source, true,
this.graph.getConnectionConstraint(edge, source, true));
this.updateFixedTerminalPoint(edge, target, false,
this.graph.getConnectionConstraint(edge, target, false));
};
mxGraphView.prototype.updateFixedTerminalPoint = function(edge, terminal, source, constraint)
{
edge.setAbsoluteTerminalPoint(this.getFixedTerminalPoint(edge, terminal, source, constraint), source);
};
mxGraphView.prototype.getFixedTerminalPoint = function(edge, terminal, source, constraint)
{
var pt = null;
if (constraint != null)
{
pt = this.graph.getConnectionPoint(terminal, constraint, false);
}
if (pt == null && terminal == null)
{
var s = this.scale;
var tr = this.translate;
var orig = edge.origin;
var geo = this.graph.getCellGeometry(edge.cell);
pt = geo.getTerminalPoint(source);
if (pt != null)
{
pt = new mxPoint(s * (tr.x + pt.x + orig.x),
s * (tr.y + pt.y + orig.y));
}
}
return pt;
};
mxGraphView.prototype.updateBoundsFromStencil = function(state)
{
var previous = null;
if (state != null && state.shape != null && state.shape.stencil != null && state.shape.stencil.aspect == 'fixed')
{
previous = mxRectangle.fromRectangle(state);
var asp = state.shape.stencil.computeAspect(state.style, state.x, state.y, state.width, state.height);
state.setRect(asp.x, asp.y, state.shape.stencil.w0 * asp.width, state.shape.stencil.h0 * asp.height);
}
return previous;
};
mxGraphView.prototype.updatePoints = function(edge, points, source, target)
{
if (edge != null)
{
var pts = [];
pts.push(edge.absolutePoints[0]);
var edgeStyle = this.getEdgeStyle(edge, points, source, target);
if (edgeStyle != null)
{
var src = this.getTerminalPort(edge, source, true);
var trg = this.getTerminalPort(edge, target, false);
var srcBounds = this.updateBoundsFromStencil(src);
var trgBounds = this.updateBoundsFromStencil(trg);
edgeStyle(edge, src, trg, points, pts);
if (srcBounds != null)
{
src.setRect(srcBounds.x, srcBounds.y, srcBounds.width, srcBounds.height);
}
if (trgBounds != null)
{
trg.setRect(trgBounds.x, trgBounds.y, trgBounds.width, trgBounds.height);
}
}
else if (points != null)
{
for (var i = 0; i < points.length; i++)
{
if (points[i] != null)
{
var pt = mxUtils.clone(points[i]);
pts.push(this.transformControlPoint(edge, pt));
}
}
}
var tmp = edge.absolutePoints;
pts.push(tmp[tmp.length-1]);
edge.absolutePoints = pts;
}
};
mxGraphView.prototype.transformControlPoint = function(state, pt, ignoreScale)
{
if (state != null && pt != null)
{
var orig = state.origin;
var scale = ignoreScale ? 1 : this.scale;
return new mxPoint(scale * (pt.x + this.translate.x + orig.x),
scale * (pt.y + this.translate.y + orig.y));
}
return null;
};
mxGraphView.prototype.isLoopStyleEnabled = function(edge, points, source, target)
{
var sc = this.graph.getConnectionConstraint(edge, source, true);
var tc = this.graph.getConnectionConstraint(edge, target, false);
if ((points == null || points.length < 2) &&
(!mxUtils.getValue(edge.style, mxConstants.STYLE_ORTHOGONAL_LOOP, false) ||
((sc == null || sc.point == null) && (tc == null || tc.point == null))))
{
return source != null && source == target;
}
return false;
};
mxGraphView.prototype.getEdgeStyle = function(edge, points, source, target)
{
var edgeStyle = this.isLoopStyleEnabled(edge, points, source, target) ?
mxUtils.getValue(edge.style, mxConstants.STYLE_LOOP, this.graph.defaultLoopStyle) :
(!mxUtils.getValue(edge.style, mxConstants.STYLE_NOEDGESTYLE, false) ?
edge.style[mxConstants.STYLE_EDGE] : null);
if (typeof(edgeStyle) == "string")
{
var tmp = mxStyleRegistry.getValue(edgeStyle);
if (tmp == null && this.isAllowEval())
{
tmp = mxUtils.eval(edgeStyle);
}
edgeStyle = tmp;
}
if (typeof(edgeStyle) == "function")
{
return edgeStyle;
}
return null;
};
mxGraphView.prototype.updateFloatingTerminalPoints = function(state, source, target)
{
var pts = state.absolutePoints;
var p0 = pts[0];
var pe = pts[pts.length - 1];
if (pe == null && target != null)
{
this.updateFloatingTerminalPoint(state, target, source, false);
}
if (p0 == null && source != null)
{
this.updateFloatingTerminalPoint(state, source, target, true);
}
};
mxGraphView.prototype.updateFloatingTerminalPoint = function(edge, start, end, source)
{
edge.setAbsoluteTerminalPoint(this.getFloatingTerminalPoint(edge, start, end, source), source);
};
mxGraphView.prototype.getFloatingTerminalPoint = function(edge, start, end, source)
{
start = this.getTerminalPort(edge, start, source);
var next = this.getNextPoint(edge, end, source);
var orth = this.graph.isOrthogonal(edge);
var alpha = mxUtils.toRadians(Number(start.style[mxConstants.STYLE_ROTATION] || '0'));
var center = new mxPoint(start.getCenterX(), start.getCenterY());
if (alpha != 0)
{
var cos = Math.cos(-alpha);
var sin = Math.sin(-alpha);
next = mxUtils.getRotatedPoint(next, cos, sin, center);
}
var border = parseFloat(edge.style[mxConstants.STYLE_PERIMETER_SPACING] || 0);
border += parseFloat(edge.style[(source) ?
mxConstants.STYLE_SOURCE_PERIMETER_SPACING :
mxConstants.STYLE_TARGET_PERIMETER_SPACING] || 0);
var pt = this.getPerimeterPoint(start, next, alpha == 0 && orth, border);
if (alpha != 0)
{
var cos = Math.cos(alpha);
var sin = Math.sin(alpha);
pt = mxUtils.getRotatedPoint(pt, cos, sin, center);
}
return pt;
};
mxGraphView.prototype.getTerminalPort = function(state, terminal, source)
{
var key = (source) ? mxConstants.STYLE_SOURCE_PORT :
mxConstants.STYLE_TARGET_PORT;
var id = mxUtils.getValue(state.style, key);
if (id != null)
{
var tmp = this.getState(this.graph.getModel().getCell(id));
if (tmp != null)
{
terminal = tmp;
}
}
return terminal;
};
mxGraphView.prototype.getPerimeterPoint = function(terminal, next, orthogonal, border)
{
var point = null;
if (terminal != null)
{
var perimeter = this.getPerimeterFunction(terminal);
if (perimeter != null && next != null)
{
var bounds = this.getPerimeterBounds(terminal, border);
if (bounds.width > 0 || bounds.height > 0)
{
point = new mxPoint(next.x, next.y);
var flipH = false;
var flipV = false;
if (this.graph.model.isVertex(terminal.cell))
{
flipH = mxUtils.getValue(terminal.style, mxConstants.STYLE_FLIPH, 0) == 1;
flipV = mxUtils.getValue(terminal.style, mxConstants.STYLE_FLIPV, 0) == 1;
if (terminal.shape != null && terminal.shape.stencil != null)
{
flipH = (mxUtils.getValue(terminal.style, 'stencilFlipH', 0) == 1) || flipH;
flipV = (mxUtils.getValue(terminal.style, 'stencilFlipV', 0) == 1) || flipV;
}
if (flipH)
{
point.x = 2 * bounds.getCenterX() - point.x;
}
if (flipV)
{
point.y = 2 * bounds.getCenterY() - point.y;
}
}
point = perimeter(bounds, terminal, point, orthogonal);
if (point != null)
{
if (flipH)
{
point.x = 2 * bounds.getCenterX() - point.x;
}
if (flipV)
{
point.y = 2 * bounds.getCenterY() - point.y;
}
}
}
}
if (point == null)
{
point = this.getPoint(terminal);
}
}
return point;
};
mxGraphView.prototype.getRoutingCenterX = function (state)
{
var f = (state.style != null) ? parseFloat(state.style
[mxConstants.STYLE_ROUTING_CENTER_X]) || 0 : 0;
return state.getCenterX() + f * state.width;
};
mxGraphView.prototype.getRoutingCenterY = function (state)
{
var f = (state.style != null) ? parseFloat(state.style
[mxConstants.STYLE_ROUTING_CENTER_Y]) || 0 : 0;
return state.getCenterY() + f * state.height;
};
mxGraphView.prototype.getPerimeterBounds = function(terminal, border)
{
border = (border != null) ? border : 0;
if (terminal != null)
{
border += parseFloat(terminal.style[mxConstants.STYLE_PERIMETER_SPACING] || 0);
}
return terminal.getPerimeterBounds(border * this.scale);
};
mxGraphView.prototype.getPerimeterFunction = function(state)
{
var perimeter = state.style[mxConstants.STYLE_PERIMETER];
if (typeof(perimeter) == "string")
{
var tmp = mxStyleRegistry.getValue(perimeter);
if (tmp == null && this.isAllowEval())
{
tmp = mxUtils.eval(perimeter);
}
perimeter = tmp;
}
if (typeof(perimeter) == "function")
{
return perimeter;
}
return null;
};
mxGraphView.prototype.getNextPoint = function(edge, opposite, source)
{
var pts = edge.absolutePoints;
var point = null;
if (pts != null && pts.length >= 2)
{
var count = pts.length;
point = pts[(source) ? Math.min(1, count - 1) : Math.max(0, count - 2)];
}
if (point == null && opposite != null)
{
point = new mxPoint(opposite.getCenterX(), opposite.getCenterY());
}
return point;
};
mxGraphView.prototype.getVisibleTerminal = function(edge, source)
{
var model = this.graph.getModel();
var result = model.getTerminal(edge, source);
var best = result;
while (result != null && result != this.currentRoot)
{
if (!this.graph.isCellVisible(best) || this.isCellCollapsed(result))
{
best = result;
}
result = model.getParent(result);
}
if (best != null && (!model.contains(best) ||
model.getParent(best) == model.getRoot() ||
best == this.currentRoot))
{
best = null;
}
return best;
};
mxGraphView.prototype.updateEdgeBounds = function(state)
{
var points = state.absolutePoints;
var p0 = points[0];
var pe = points[points.length - 1];
if (p0.x != pe.x || p0.y != pe.y)
{
var dx = pe.x - p0.x;
var dy = pe.y - p0.y;
state.terminalDistance = Math.sqrt(dx * dx + dy * dy);
}
else
{
state.terminalDistance = 0;
}
var length = 0;
var segments = [];
var pt = p0;
if (pt != null)
{
var minX = pt.x;
var minY = pt.y;
var maxX = minX;
var maxY = minY;
for (var i = 1; i < points.length; i++)
{
var tmp = points[i];
if (tmp != null)
{
var dx = pt.x - tmp.x;
var dy = pt.y - tmp.y;
var segment = Math.sqrt(dx * dx + dy * dy);
segments.push(segment);
length += segment;
pt = tmp;
minX = Math.min(pt.x, minX);
minY = Math.min(pt.y, minY);
maxX = Math.max(pt.x, maxX);
maxY = Math.max(pt.y, maxY);
}
}
state.length = length;
state.segments = segments;
var markerSize = 1;
state.x = minX;
state.y = minY;
state.width = Math.max(markerSize, maxX - minX);
state.height = Math.max(markerSize, maxY - minY);
}
};
mxGraphView.prototype.getPoint = function(state, geometry)
{
var x = state.getCenterX();
var y = state.getCenterY();
if (state.segments != null && (geometry == null || geometry.relative))
{
var gx = (geometry != null) ? geometry.x / 2 : 0;
var pointCount = state.absolutePoints.length;
var dist = Math.round((gx + 0.5) * state.length);
var segment = state.segments[0];
var length = 0;
var index = 1;
while (dist >= Math.round(length + segment) && index < pointCount - 1)
{
length += segment;
segment = state.segments[index++];
}
var factor = (segment == 0) ? 0 : (dist - length) / segment;
var p0 = state.absolutePoints[index-1];
var pe = state.absolutePoints[index];
if (p0 != null && pe != null)
{
var gy = 0;
var offsetX = 0;
var offsetY = 0;
if (geometry != null)
{
gy = geometry.y;
var offset = geometry.offset;
if (offset != null)
{
offsetX = offset.x;
offsetY = offset.y;
}
}
var dx = pe.x - p0.x;
var dy = pe.y - p0.y;
var nx = (segment == 0) ? 0 : dy / segment;
var ny = (segment == 0) ? 0 : dx / segment;
x = p0.x + dx * factor + (nx * gy + offsetX) * this.scale;
y = p0.y + dy * factor - (ny * gy - offsetY) * this.scale;
}
}
else if (geometry != null)
{
var offset = geometry.offset;
if (offset != null)
{
x += offset.x;
y += offset.y;
}
}
return new mxPoint(x, y);
};
mxGraphView.prototype.getRelativePoint = function(edgeState, x, y)
{
var model = this.graph.getModel();
var geometry = model.getGeometry(edgeState.cell);
if (geometry != null)
{
var pointCount = edgeState.absolutePoints.length;
if (geometry.relative && pointCount > 1)
{
var totalLength = edgeState.length;
var segments = edgeState.segments;
var p0 = edgeState.absolutePoints[0];
var pe = edgeState.absolutePoints[1];
var minDist = mxUtils.ptSegDistSq(p0.x, p0.y, pe.x, pe.y, x, y);
var index = 0;
var tmp = 0;
var length = 0;
for (var i = 2; i < pointCount; i++)
{
tmp += segments[i - 2];
pe = edgeState.absolutePoints[i];
var dist = mxUtils.ptSegDistSq(p0.x, p0.y, pe.x, pe.y, x, y);
if (dist <= minDist)
{
minDist = dist;
index = i - 1;
length = tmp;
}
p0 = pe;
}
var seg = segments[index];
p0 = edgeState.absolutePoints[index];
pe = edgeState.absolutePoints[index + 1];
var x2 = p0.x;
var y2 = p0.y;
var x1 = pe.x;
var y1 = pe.y;
var px = x;
var py = y;
var xSegment = x2 - x1;
var ySegment = y2 - y1;
px -= x1;
py -= y1;
var projlenSq = 0;
px = xSegment - px;
py = ySegment - py;
var dotprod = px * xSegment + py * ySegment;
if (dotprod <= 0.0)
{
projlenSq = 0;
}
else
{
projlenSq = dotprod * dotprod
/ (xSegment * xSegment + ySegment * ySegment);
}
var projlen = Math.sqrt(projlenSq);
if (projlen > seg)
{
projlen = seg;
}
var yDistance = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, pe
.x, pe.y, x, y));
var direction = mxUtils.relativeCcw(p0.x, p0.y, pe.x, pe.y, x, y);
if (direction == -1)
{
yDistance = -yDistance;
}
return new mxPoint(((totalLength / 2 - length - projlen) / totalLength) * -2,
yDistance / this.scale);
}
}
return new mxPoint();
};
mxGraphView.prototype.updateEdgeLabelOffset = function(state)
{
var points = state.absolutePoints;
state.absoluteOffset.x = state.getCenterX();
state.absoluteOffset.y = state.getCenterY();
if (points != null && points.length > 0 && state.segments != null)
{
var geometry = this.graph.getCellGeometry(state.cell);
if (geometry.relative)
{
var offset = this.getPoint(state, geometry);
if (offset != null)
{
state.absoluteOffset = offset;
}
}
else
{
var p0 = points[0];
var pe = points[points.length - 1];
if (p0 != null && pe != null)
{
var dx = pe.x - p0.x;
var dy = pe.y - p0.y;
var x0 = 0;
var y0 = 0;
var off = geometry.offset;
if (off != null)
{
x0 = off.x;
y0 = off.y;
}
var x = p0.x + dx / 2 + x0 * this.scale;
var y = p0.y + dy / 2 + y0 * this.scale;
state.absoluteOffset.x = x;
state.absoluteOffset.y = y;
}
}
}
};
mxGraphView.prototype.getState = function(cell, create)
{
create = create || false;
var state = null;
if (cell != null)
{
state = this.states.get(cell);
if (create && (state == null || this.updateStyle) && this.graph.isCellVisible(cell))
{
if (state == null)
{
state = this.createState(cell);
this.states.put(cell, state);
}
else
{
state.style = this.graph.getCellStyle(cell);
}
}
}
return state;
};
mxGraphView.prototype.isRendering = function()
{
return this.rendering;
};
mxGraphView.prototype.setRendering = function(value)
{
this.rendering = value;
};
mxGraphView.prototype.isAllowEval = function()
{
return this.allowEval;
};
mxGraphView.prototype.setAllowEval = function(value)
{
this.allowEval = value;
};
mxGraphView.prototype.getStates = function()
{
return this.states;
};
mxGraphView.prototype.setStates = function(value)
{
this.states = value;
};
mxGraphView.prototype.getCellStates = function(cells)
{
if (cells == null)
{
return this.states;
}
else
{
var result = [];
for (var i = 0; i < cells.length; i++)
{
var state = this.getState(cells[i]);
if (state != null)
{
result.push(state);
}
}
return result;
}
};
mxGraphView.prototype.removeState = function(cell)
{
var state = null;
if (cell != null)
{
state = this.states.remove(cell);
if (state != null)
{
this.graph.cellRenderer.destroy(state);
state.invalid = true;
state.destroy();
}
}
return state;
};
mxGraphView.prototype.createState = function(cell)
{
return new mxCellState(this, cell, this.graph.getCellStyle(cell));
};
mxGraphView.prototype.getCanvas = function()
{
return this.canvas;
};
mxGraphView.prototype.getBackgroundPane = function()
{
return this.backgroundPane;
};
mxGraphView.prototype.getDrawPane = function()
{
return this.drawPane;
};
mxGraphView.prototype.getOverlayPane = function()
{
return this.overlayPane;
};
mxGraphView.prototype.getDecoratorPane = function()
{
return this.decoratorPane;
};
mxGraphView.prototype.isContainerEvent = function(evt)
{
var source = mxEvent.getSource(evt);
return (source == this.graph.container ||
source.parentNode == this.backgroundPane ||
(source.parentNode != null &&
source.parentNode.parentNode == this.backgroundPane) ||
source == this.canvas.parentNode ||
source == this.canvas ||
source == this.backgroundPane ||
source == this.drawPane ||
source == this.overlayPane ||
source == this.decoratorPane);
};
mxGraphView.prototype.isScrollEvent = function(evt)
{
var offset = mxUtils.getOffset(this.graph.container);
var pt = new mxPoint(evt.clientX - offset.x, evt.clientY - offset.y);
var outWidth = this.graph.container.offsetWidth;
var inWidth = this.graph.container.clientWidth;
if (outWidth > inWidth && pt.x > inWidth + 2 && pt.x <= outWidth)
{
return true;
}
var outHeight = this.graph.container.offsetHeight;
var inHeight = this.graph.container.clientHeight;
if (outHeight > inHeight && pt.y > inHeight + 2 && pt.y <= outHeight)
{
return true;
}
return false;
};
mxGraphView.prototype.init = function()
{
this.installListeners();
var graph = this.graph;
if (graph.dialect == mxConstants.DIALECT_SVG)
{
this.createSvg();
}
else if (graph.dialect == mxConstants.DIALECT_VML)
{
this.createVml();
}
else
{
this.createHtml();
}
};
mxGraphView.prototype.installListeners = function()
{
var graph = this.graph;
var container = graph.container;
if (container != null)
{
if (mxClient.IS_TOUCH)
{
mxEvent.addListener(container, 'gesturestart', mxUtils.bind(this, function(evt)
{
graph.fireGestureEvent(evt);
mxEvent.consume(evt);
}));
mxEvent.addListener(container, 'gesturechange', mxUtils.bind(this, function(evt)
{
graph.fireGestureEvent(evt);
mxEvent.consume(evt);
}));
mxEvent.addListener(container, 'gestureend', mxUtils.bind(this, function(evt)
{
graph.fireGestureEvent(evt);
mxEvent.consume(evt);
}));
}
var pointerId = null;
mxEvent.addGestureListeners(container, mxUtils.bind(this, function(evt)
{
if (this.isContainerEvent(evt) && ((!mxClient.IS_IE && !mxClient.IS_IE11 && !mxClient.IS_GC &&
!mxClient.IS_OP && !mxClient.IS_SF) || !this.isScrollEvent(evt)))
{
graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt));
pointerId = evt.pointerId;
}
}),
mxUtils.bind(this, function(evt)
{
if (this.isContainerEvent(evt) && (pointerId == null || evt.pointerId == pointerId))
{
graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt));
}
}),
mxUtils.bind(this, function(evt)
{
if (this.isContainerEvent(evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
}
pointerId = null;
}));
mxEvent.addListener(container, 'dblclick', mxUtils.bind(this, function(evt)
{
if (this.isContainerEvent(evt))
{
graph.dblClick(evt);
}
}));
var getState = function(evt)
{
var state = null;
if (mxClient.IS_TOUCH)
{
var x = mxEvent.getClientX(evt);
var y = mxEvent.getClientY(evt);
var pt = mxUtils.convertPoint(container, x, y);
state = graph.view.getState(graph.getCellAt(pt.x, pt.y));
}
return state;
};
graph.addMouseListener(
{
mouseDown: function(sender, me)
{
graph.popupMenuHandler.hideMenu();
},
mouseMove: function() { },
mouseUp: function() { }
});
this.moveHandler = mxUtils.bind(this, function(evt)
{
if (graph.tooltipHandler != null && graph.tooltipHandler.isHideOnHover())
{
graph.tooltipHandler.hide();
}
if (this.captureDocumentGesture && graph.isMouseDown && graph.container != null &&
!this.isContainerEvent(evt) && graph.container.style.display != 'none' &&
graph.container.style.visibility != 'hidden' && !mxEvent.isConsumed(evt))
{
graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, getState(evt)));
}
});
this.endHandler = mxUtils.bind(this, function(evt)
{
if (this.captureDocumentGesture && graph.isMouseDown && graph.container != null &&
!this.isContainerEvent(evt) && graph.container.style.display != 'none' &&
graph.container.style.visibility != 'hidden')
{
graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
}
});
mxEvent.addGestureListeners(document, null, this.moveHandler, this.endHandler);
}
};
mxGraphView.prototype.createHtml = function()
{
var container = this.graph.container;
if (container != null)
{
this.canvas = this.createHtmlPane('100%', '100%');
this.canvas.style.overflow = 'hidden';
this.backgroundPane = this.createHtmlPane('1px', '1px');
this.drawPane = this.createHtmlPane('1px', '1px');
this.overlayPane = this.createHtmlPane('1px', '1px');
this.decoratorPane = this.createHtmlPane('1px', '1px');
this.canvas.appendChild(this.backgroundPane);
this.canvas.appendChild(this.drawPane);
this.canvas.appendChild(this.overlayPane);
this.canvas.appendChild(this.decoratorPane);
container.appendChild(this.canvas);
this.updateContainerStyle(container);
if (mxClient.IS_QUIRKS)
{
var onResize = mxUtils.bind(this, function(evt)
{
var bounds = this.getGraphBounds();
var width = bounds.x + bounds.width + this.graph.border;
var height = bounds.y + bounds.height + this.graph.border;
this.updateHtmlCanvasSize(width, height);
});
mxEvent.addListener(window, 'resize', onResize);
}
}
};
mxGraphView.prototype.updateHtmlCanvasSize = function(width, height)
{
if (this.graph.container != null)
{
var ow = this.graph.container.offsetWidth;
var oh = this.graph.container.offsetHeight;
if (ow < width)
{
this.canvas.style.width = width + 'px';
}
else
{
this.canvas.style.width = '100%';
}
if (oh < height)
{
this.canvas.style.height = height + 'px';
}
else
{
this.canvas.style.height = '100%';
}
}
};
mxGraphView.prototype.createHtmlPane = function(width, height)
{
var pane = document.createElement('DIV');
if (width != null && height != null)
{
pane.style.position = 'absolute';
pane.style.left = '0px';
pane.style.top = '0px';
pane.style.width = width;
pane.style.height = height;
}
else
{
pane.style.position = 'relative';
}
return pane;
};
mxGraphView.prototype.createVml = function()
{
var container = this.graph.container;
if (container != null)
{
var width = container.offsetWidth;
var height = container.offsetHeight;
this.canvas = this.createVmlPane(width, height);
this.canvas.style.overflow = 'hidden';
this.backgroundPane = this.createVmlPane(width, height);
this.drawPane = this.createVmlPane(width, height);
this.overlayPane = this.createVmlPane(width, height);
this.decoratorPane = this.createVmlPane(width, height);
this.canvas.appendChild(this.backgroundPane);
this.canvas.appendChild(this.drawPane);
this.canvas.appendChild(this.overlayPane);
this.canvas.appendChild(this.decoratorPane);
container.appendChild(this.canvas);
}
};
mxGraphView.prototype.createVmlPane = function(width, height)
{
var pane = document.createElement(mxClient.VML_PREFIX + ':group');
pane.style.position = 'absolute';
pane.style.left = '0px';
pane.style.top = '0px';
pane.style.width = width + 'px';
pane.style.height = height + 'px';
pane.setAttribute('coordsize', width + ',' + height);
pane.setAttribute('coordorigin', '0,0');
return pane;
};
mxGraphView.prototype.createSvg = function()
{
var container = this.graph.container;
this.canvas = document.createElementNS(mxConstants.NS_SVG, 'g');
this.backgroundPane = document.createElementNS(mxConstants.NS_SVG, 'g');
this.canvas.appendChild(this.backgroundPane);
this.drawPane = document.createElementNS(mxConstants.NS_SVG, 'g');
this.canvas.appendChild(this.drawPane);
this.overlayPane = document.createElementNS(mxConstants.NS_SVG, 'g');
this.canvas.appendChild(this.overlayPane);
this.decoratorPane = document.createElementNS(mxConstants.NS_SVG, 'g');
this.canvas.appendChild(this.decoratorPane);
var root = document.createElementNS(mxConstants.NS_SVG, 'svg');
root.style.left = '0px';
root.style.top = '0px';
root.style.width = '100%';
root.style.height = '100%';
root.style.display = 'block';
root.appendChild(this.canvas);
if (mxClient.IS_IE || mxClient.IS_IE11)
{
root.style.overflow = 'hidden';
}
if (container != null)
{
container.appendChild(root);
this.updateContainerStyle(container);
}
};
mxGraphView.prototype.updateContainerStyle = function(container)
{
var style = mxUtils.getCurrentStyle(container);
if (style != null && style.position == 'static')
{
container.style.position = 'relative';
}
if (mxClient.IS_POINTER)
{
container.style.touchAction = 'none';
}
};
mxGraphView.prototype.destroy = function()
{
var root = (this.canvas != null) ? this.canvas.ownerSVGElement : null;
if (root == null)
{
root = this.canvas;
}
if (root != null && root.parentNode != null)
{
this.clear(this.currentRoot, true);
mxEvent.removeGestureListeners(document, null, this.moveHandler, this.endHandler);
mxEvent.release(this.graph.container);
root.parentNode.removeChild(root);
this.moveHandler = null;
this.endHandler = null;
this.canvas = null;
this.backgroundPane = null;
this.drawPane = null;
this.overlayPane = null;
this.decoratorPane = null;
}
};
function mxCurrentRootChange(view, root)
{
this.view = view;
this.root = root;
this.previous = root;
this.isUp = root == null;
if (!this.isUp)
{
var tmp = this.view.currentRoot;
var model = this.view.graph.getModel();
while (tmp != null)
{
if (tmp == root)
{
this.isUp = true;
break;
}
tmp = model.getParent(tmp);
}
}
} mxCurrentRootChange.prototype.execute = function()
{
var tmp = this.view.currentRoot;
this.view.currentRoot = this.previous;
this.previous = tmp;
var translate = this.view.graph.getTranslateForRoot(this.view.currentRoot);
if (translate != null)
{
this.view.translate = new mxPoint(-translate.x, -translate.y);
}
if (this.isUp)
{
this.view.clear(this.view.currentRoot, true);
this.view.validate();
}
else
{
this.view.refresh();
}
var name = (this.isUp) ? mxEvent.UP : mxEvent.DOWN;
this.view.fireEvent(new mxEventObject(name,
'root', this.view.currentRoot, 'previous', this.previous));
this.isUp = !this.isUp;
};
__mxOutput.mxGraphView = typeof mxGraphView !== 'undefined' ? mxGraphView : undefined;
function mxGraph(container, model, renderHint, stylesheet)
{
this.mouseListeners = null;
this.renderHint = renderHint;
if (mxClient.IS_SVG)
{
this.dialect = mxConstants.DIALECT_SVG;
}
else if (renderHint == mxConstants.RENDERING_HINT_EXACT && mxClient.IS_VML)
{
this.dialect = mxConstants.DIALECT_VML;
}
else if (renderHint == mxConstants.RENDERING_HINT_FASTEST)
{
this.dialect = mxConstants.DIALECT_STRICTHTML;
}
else if (renderHint == mxConstants.RENDERING_HINT_FASTER)
{
this.dialect = mxConstants.DIALECT_PREFERHTML;
}
else
{
this.dialect = mxConstants.DIALECT_MIXEDHTML;
}
this.model = (model != null) ? model : new mxGraphModel();
this.multiplicities = [];
this.imageBundles = [];
this.cellRenderer = this.createCellRenderer();
this.setSelectionModel(this.createSelectionModel());
this.setStylesheet((stylesheet != null) ? stylesheet : this.createStylesheet());
this.view = this.createGraphView();
this.graphModelChangeListener = mxUtils.bind(this, function(sender, evt)
{
this.graphModelChanged(evt.getProperty('edit').changes);
});
this.model.addListener(mxEvent.CHANGE, this.graphModelChangeListener);
this.createHandlers();
if (container != null)
{
this.init(container);
}
this.view.revalidate();
} if (mxLoadResources)
{
mxResources.add(mxClient.basePath + '/resources/graph');
}
else
{
mxClient.defaultBundles.push(mxClient.basePath + '/resources/graph');
}
mxGraph.prototype = new mxEventSource();
mxGraph.prototype.constructor = mxGraph;
mxGraph.prototype.mouseListeners = null;
mxGraph.prototype.isMouseDown = false;
mxGraph.prototype.model = null;
mxGraph.prototype.view = null;
mxGraph.prototype.stylesheet = null;
mxGraph.prototype.selectionModel = null;
mxGraph.prototype.cellEditor = null;
mxGraph.prototype.cellRenderer = null;
mxGraph.prototype.multiplicities = null;
mxGraph.prototype.renderHint = null;
mxGraph.prototype.dialect = null;
mxGraph.prototype.gridSize = 10;
mxGraph.prototype.gridEnabled = true;
mxGraph.prototype.portsEnabled = true;
mxGraph.prototype.nativeDblClickEnabled = true;
mxGraph.prototype.doubleTapEnabled = true;
mxGraph.prototype.doubleTapTimeout = 500;
mxGraph.prototype.doubleTapTolerance = 25;
mxGraph.prototype.lastTouchY = 0;
mxGraph.prototype.lastTouchY = 0;
mxGraph.prototype.lastTouchTime = 0;
mxGraph.prototype.tapAndHoldEnabled = true;
mxGraph.prototype.tapAndHoldDelay = 500;
mxGraph.prototype.tapAndHoldInProgress = false;
mxGraph.prototype.tapAndHoldValid = false;
mxGraph.prototype.initialTouchX = 0;
mxGraph.prototype.initialTouchY = 0;
mxGraph.prototype.tolerance = 4;
mxGraph.prototype.defaultOverlap = 0.5;
mxGraph.prototype.defaultParent = null;
mxGraph.prototype.alternateEdgeStyle = null;
mxGraph.prototype.backgroundImage = null;
mxGraph.prototype.pageVisible = false;
mxGraph.prototype.pageBreaksVisible = false;
mxGraph.prototype.pageBreakColor = 'gray';
mxGraph.prototype.pageBreakDashed = true;
mxGraph.prototype.minPageBreakDist = 20;
mxGraph.prototype.preferPageSize = false;
mxGraph.prototype.pageFormat = mxConstants.PAGE_FORMAT_A4_PORTRAIT;
mxGraph.prototype.pageScale = 1.5;
mxGraph.prototype.enabled = true;
mxGraph.prototype.escapeEnabled = true;
mxGraph.prototype.invokesStopCellEditing = true;
mxGraph.prototype.enterStopsCellEditing = false;
mxGraph.prototype.useScrollbarsForPanning = true;
mxGraph.prototype.exportEnabled = true;
mxGraph.prototype.importEnabled = true;
mxGraph.prototype.cellsLocked = false;
mxGraph.prototype.cellsCloneable = true;
mxGraph.prototype.foldingEnabled = true;
mxGraph.prototype.cellsEditable = true;
mxGraph.prototype.cellsDeletable = true;
mxGraph.prototype.cellsMovable = true;
mxGraph.prototype.edgeLabelsMovable = true;
mxGraph.prototype.vertexLabelsMovable = false;
mxGraph.prototype.dropEnabled = false;
mxGraph.prototype.splitEnabled = true;
mxGraph.prototype.cellsResizable = true;
mxGraph.prototype.cellsBendable = true;
mxGraph.prototype.cellsSelectable = true;
mxGraph.prototype.cellsDisconnectable = true;
mxGraph.prototype.autoSizeCells = false;
mxGraph.prototype.autoSizeCellsOnAdd = false;
mxGraph.prototype.autoScroll = true;
mxGraph.prototype.ignoreScrollbars = false;
mxGraph.prototype.translateToScrollPosition = false;
mxGraph.prototype.timerAutoScroll = false;
mxGraph.prototype.allowAutoPanning = false;
mxGraph.prototype.autoExtend = true;
mxGraph.prototype.maximumGraphBounds = null;
mxGraph.prototype.minimumGraphSize = null;
mxGraph.prototype.minimumContainerSize = null;
mxGraph.prototype.maximumContainerSize = null;
mxGraph.prototype.resizeContainer = false;
mxGraph.prototype.border = 0;
mxGraph.prototype.keepEdgesInForeground = false;
mxGraph.prototype.keepEdgesInBackground = false;
mxGraph.prototype.allowNegativeCoordinates = true;
mxGraph.prototype.constrainChildren = true;
mxGraph.prototype.constrainRelativeChildren = false;
mxGraph.prototype.extendParents = true;
mxGraph.prototype.extendParentsOnAdd = true;
mxGraph.prototype.extendParentsOnMove = false;
mxGraph.prototype.recursiveResize = false;
mxGraph.prototype.collapseToPreferredSize = true;
mxGraph.prototype.zoomFactor = 1.2;
mxGraph.prototype.keepSelectionVisibleOnZoom = false;
mxGraph.prototype.centerZoom = true;
mxGraph.prototype.resetViewOnRootChange = true;
mxGraph.prototype.resetEdgesOnResize = false;
mxGraph.prototype.resetEdgesOnMove = false;
mxGraph.prototype.resetEdgesOnConnect = true;
mxGraph.prototype.allowLoops = false;
mxGraph.prototype.defaultLoopStyle = mxEdgeStyle.Loop;
mxGraph.prototype.multigraph = true;
mxGraph.prototype.connectableEdges = false;
mxGraph.prototype.allowDanglingEdges = true;
mxGraph.prototype.cloneInvalidEdges = false;
mxGraph.prototype.disconnectOnMove = true;
mxGraph.prototype.labelsVisible = true;
mxGraph.prototype.htmlLabels = false;
mxGraph.prototype.swimlaneSelectionEnabled = true;
mxGraph.prototype.swimlaneNesting = true;
mxGraph.prototype.swimlaneIndicatorColorAttribute = mxConstants.STYLE_FILLCOLOR;
mxGraph.prototype.imageBundles = null;
mxGraph.prototype.minFitScale = 0.1;
mxGraph.prototype.maxFitScale = 8;
mxGraph.prototype.panDx = 0;
mxGraph.prototype.panDy = 0;
mxGraph.prototype.collapsedImage = new mxImage(mxClient.imageBasePath + '/collapsed.gif', 9, 9);
mxGraph.prototype.expandedImage = new mxImage(mxClient.imageBasePath + '/expanded.gif', 9, 9);
mxGraph.prototype.warningImage = new mxImage(mxClient.imageBasePath + '/warning'+
((mxClient.IS_MAC) ? '.png' : '.gif'), 16, 16);
mxGraph.prototype.alreadyConnectedResource = (mxClient.language != 'none') ? 'alreadyConnected' : '';
mxGraph.prototype.containsValidationErrorsResource = (mxClient.language != 'none') ? 'containsValidationErrors' : '';
mxGraph.prototype.collapseExpandResource = (mxClient.language != 'none') ? 'collapse-expand' : '';
mxGraph.prototype.init = function(container)
{
this.container = container;
this.cellEditor = this.createCellEditor();
this.view.init();
this.sizeDidChange();
mxEvent.addListener(container, 'mouseleave', mxUtils.bind(this, function(evt)
{
if (this.tooltipHandler != null && this.tooltipHandler.div != null &&
this.tooltipHandler.div != evt.relatedTarget)
{
this.tooltipHandler.hide();
}
}));
if (mxClient.IS_IE)
{
mxEvent.addListener(window, 'unload', mxUtils.bind(this, function()
{
this.destroy();
}));
mxEvent.addListener(container, 'selectstart',
mxUtils.bind(this, function(evt)
{
return this.isEditing() || (!this.isMouseDown && !mxEvent.isShiftDown(evt));
})
);
}
if (document.documentMode == 8)
{
container.insertAdjacentHTML('beforeend', '<' + mxClient.VML_PREFIX + ':group' +
' style="DISPLAY: none;"></' + mxClient.VML_PREFIX + ':group>');
}
};
mxGraph.prototype.createHandlers = function()
{
this.tooltipHandler = this.createTooltipHandler();
this.tooltipHandler.setEnabled(false);
this.selectionCellsHandler = this.createSelectionCellsHandler();
this.connectionHandler = this.createConnectionHandler();
this.connectionHandler.setEnabled(false);
this.graphHandler = this.createGraphHandler();
this.panningHandler = this.createPanningHandler();
this.panningHandler.panningEnabled = false;
this.popupMenuHandler = this.createPopupMenuHandler();
};
mxGraph.prototype.createTooltipHandler = function()
{
return new mxTooltipHandler(this);
};
mxGraph.prototype.createSelectionCellsHandler = function()
{
return new mxSelectionCellsHandler(this);
};
mxGraph.prototype.createConnectionHandler = function()
{
return new mxConnectionHandler(this);
};
mxGraph.prototype.createGraphHandler = function()
{
return new mxGraphHandler(this);
};
mxGraph.prototype.createPanningHandler = function()
{
return new mxPanningHandler(this);
};
mxGraph.prototype.createPopupMenuHandler = function()
{
return new mxPopupMenuHandler(this);
};
mxGraph.prototype.createSelectionModel = function()
{
return new mxGraphSelectionModel(this);
};
mxGraph.prototype.createStylesheet = function()
{
return new mxStylesheet();
};
mxGraph.prototype.createGraphView = function()
{
return new mxGraphView(this);
};
mxGraph.prototype.createCellRenderer = function()
{
return new mxCellRenderer();
};
mxGraph.prototype.createCellEditor = function()
{
return new mxCellEditor(this);
};
mxGraph.prototype.getModel = function()
{
return this.model;
};
mxGraph.prototype.getView = function()
{
return this.view;
};
mxGraph.prototype.getStylesheet = function()
{
return this.stylesheet;
};
mxGraph.prototype.setStylesheet = function(stylesheet)
{
this.stylesheet = stylesheet;
};
mxGraph.prototype.getSelectionModel = function()
{
return this.selectionModel;
};
mxGraph.prototype.setSelectionModel = function(selectionModel)
{
this.selectionModel = selectionModel;
};
mxGraph.prototype.getSelectionCellsForChanges = function(changes, ignoreFn)
{
var dict = new mxDictionary();
var cells = [];
var addCell = mxUtils.bind(this, function(cell)
{
if (!dict.get(cell) && this.model.contains(cell))
{
if (this.model.isEdge(cell) || this.model.isVertex(cell))
{
dict.put(cell, true);
cells.push(cell);
}
else
{
var childCount = this.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
addCell(this.model.getChildAt(cell, i));
}
}
}
});
for (var i = 0; i < changes.length; i++)
{
var change = changes[i];
if (change.constructor != mxRootChange &&
(ignoreFn == null || !ignoreFn(change)))
{
var cell = null;
if (change instanceof mxChildChange)
{
cell = change.child;
}
else if (change.cell != null &&
change.cell instanceof mxCell)
{
cell = change.cell;
}
if (cell != null)
{
addCell(cell);
}
}
}
return cells;
};
mxGraph.prototype.graphModelChanged = function(changes)
{
for (var i = 0; i < changes.length; i++)
{
this.processChange(changes[i]);
}
this.updateSelection();
this.view.validate();
this.sizeDidChange();
};
mxGraph.prototype.updateSelection = function()
{
var cells = this.getSelectionCells();
var removed = [];
for (var i = 0; i < cells.length; i++)
{
if (!this.model.contains(cells[i]) || !this.isCellVisible(cells[i]))
{
removed.push(cells[i]);
}
else
{
var par = this.model.getParent(cells[i]);
while (par != null && par != this.view.currentRoot)
{
if (this.isCellCollapsed(par) || !this.isCellVisible(par))
{
removed.push(cells[i]);
break;
}
par = this.model.getParent(par);
}
}
}
this.removeSelectionCells(removed);
};
mxGraph.prototype.processChange = function(change)
{
if (change instanceof mxRootChange)
{
this.clearSelection();
this.setDefaultParent(null);
this.removeStateForCell(change.previous);
if (this.resetViewOnRootChange)
{
this.view.scale = 1;
this.view.translate.x = 0;
this.view.translate.y = 0;
}
this.fireEvent(new mxEventObject(mxEvent.ROOT));
}
else if (change instanceof mxChildChange)
{
var newParent = this.model.getParent(change.child);
this.view.invalidate(change.child, true, true);
if (!this.model.contains(newParent) || this.isCellCollapsed(newParent))
{
this.view.invalidate(change.child, true, true);
this.removeStateForCell(change.child);
if (this.view.currentRoot == change.child)
{
this.home();
}
}
if (newParent != change.previous)
{
if (newParent != null)
{
this.view.invalidate(newParent, false, false);
}
if (change.previous != null)
{
this.view.invalidate(change.previous, false, false);
}
}
}
else if (change instanceof mxTerminalChange || change instanceof mxGeometryChange)
{
if (change instanceof mxTerminalChange || ((change.previous == null && change.geometry != null) ||
(change.previous != null && !change.previous.equals(change.geometry))))
{
this.view.invalidate(change.cell);
}
}
else if (change instanceof mxValueChange)
{
this.view.invalidate(change.cell, false, false);
}
else if (change instanceof mxStyleChange)
{
this.view.invalidate(change.cell, true, true);
var state = this.view.getState(change.cell);
if (state != null)
{
state.invalidStyle = true;
}
}
else if (change.cell != null && change.cell instanceof mxCell)
{
this.removeStateForCell(change.cell);
}
};
mxGraph.prototype.removeStateForCell = function(cell)
{
var childCount = this.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
this.removeStateForCell(this.model.getChildAt(cell, i));
}
this.view.invalidate(cell, false, true);
this.view.removeState(cell);
};
mxGraph.prototype.addCellOverlay = function(cell, overlay)
{
if (cell.overlays == null)
{
cell.overlays = [];
}
cell.overlays.push(overlay);
var state = this.view.getState(cell);
if (state != null)
{
this.cellRenderer.redraw(state);
}
this.fireEvent(new mxEventObject(mxEvent.ADD_OVERLAY,
'cell', cell, 'overlay', overlay));
return overlay;
};
mxGraph.prototype.getCellOverlays = function(cell)
{
return cell.overlays;
};
mxGraph.prototype.removeCellOverlay = function(cell, overlay)
{
if (overlay == null)
{
this.removeCellOverlays(cell);
}
else
{
var index = mxUtils.indexOf(cell.overlays, overlay);
if (index >= 0)
{
cell.overlays.splice(index, 1);
if (cell.overlays.length == 0)
{
cell.overlays = null;
}
var state = this.view.getState(cell);
if (state != null)
{
this.cellRenderer.redraw(state);
}
this.fireEvent(new mxEventObject(mxEvent.REMOVE_OVERLAY,
'cell', cell, 'overlay', overlay));
}
else
{
overlay = null;
}
}
return overlay;
};
mxGraph.prototype.removeCellOverlays = function(cell)
{
var overlays = cell.overlays;
if (overlays != null)
{
cell.overlays = null;
var state = this.view.getState(cell);
if (state != null)
{
this.cellRenderer.redraw(state);
}
for (var i = 0; i < overlays.length; i++)
{
this.fireEvent(new mxEventObject(mxEvent.REMOVE_OVERLAY,
'cell', cell, 'overlay', overlays[i]));
}
}
return overlays;
};
mxGraph.prototype.clearCellOverlays = function(cell)
{
cell = (cell != null) ? cell : this.model.getRoot();
this.removeCellOverlays(cell);
var childCount = this.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var child = this.model.getChildAt(cell, i);
this.clearCellOverlays(child);
}
};
mxGraph.prototype.setCellWarning = function(cell, warning, img, isSelect)
{
if (warning != null && warning.length > 0)
{
img = (img != null) ? img : this.warningImage;
var overlay = new mxCellOverlay(img,
'<font color=red>'+warning+'</font>');
if (isSelect)
{
overlay.addListener(mxEvent.CLICK,
mxUtils.bind(this, function(sender, evt)
{
if (this.isEnabled())
{
this.setSelectionCell(cell);
}
})
);
}
return this.addCellOverlay(cell, overlay);
}
else
{
this.removeCellOverlays(cell);
}
return null;
};
mxGraph.prototype.startEditing = function(evt)
{
this.startEditingAtCell(null, evt);
};
mxGraph.prototype.startEditingAtCell = function(cell, evt)
{
if (evt == null || !mxEvent.isMultiTouchEvent(evt))
{
if (cell == null)
{
cell = this.getSelectionCell();
if (cell != null && !this.isCellEditable(cell))
{
cell = null;
}
}
if (cell != null)
{
this.fireEvent(new mxEventObject(mxEvent.START_EDITING,
'cell', cell, 'event', evt));
this.cellEditor.startEditing(cell, evt);
this.fireEvent(new mxEventObject(mxEvent.EDITING_STARTED,
'cell', cell, 'event', evt));
}
}
};
mxGraph.prototype.getEditingValue = function(cell, evt)
{
return this.convertValueToString(cell);
};
mxGraph.prototype.stopEditing = function(cancel)
{
this.cellEditor.stopEditing(cancel);
this.fireEvent(new mxEventObject(mxEvent.EDITING_STOPPED, 'cancel', cancel));
};
mxGraph.prototype.labelChanged = function(cell, value, evt)
{
this.model.beginUpdate();
try
{
var old = cell.value;
this.cellLabelChanged(cell, value, this.isAutoSizeCell(cell));
this.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED,
'cell', cell, 'value', value, 'old', old, 'event', evt));
}
finally
{
this.model.endUpdate();
}
return cell;
};
mxGraph.prototype.cellLabelChanged = function(cell, value, autoSize)
{
this.model.beginUpdate();
try
{
this.model.setValue(cell, value);
if (autoSize)
{
this.cellSizeUpdated(cell, false);
}
}
finally
{
this.model.endUpdate();
}
};
mxGraph.prototype.escape = function(evt)
{
this.fireEvent(new mxEventObject(mxEvent.ESCAPE, 'event', evt));
};
mxGraph.prototype.click = function(me)
{
var evt = me.getEvent();
var cell = me.getCell();
var mxe = new mxEventObject(mxEvent.CLICK, 'event', evt, 'cell', cell);
if (me.isConsumed())
{
mxe.consume();
}
this.fireEvent(mxe);
if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed())
{
if (cell != null)
{
if (this.isTransparentClickEvent(evt))
{
var active = false;
var tmp = this.getCellAt(me.graphX, me.graphY, null, null, null,
mxUtils.bind(this, function(state)
{
var selected = this.isCellSelected(state.cell);
active = active || selected;
return !active || selected || (state.cell != cell &&
this.model.isAncestor(state.cell, cell));
}));
if (tmp != null)
{
cell = tmp;
}
}
}
else if (this.isSwimlaneSelectionEnabled())
{
cell = this.getSwimlaneAt(me.getGraphX(), me.getGraphY());
if (cell != null && (!this.isToggleEvent(evt) ||
!mxEvent.isAltDown(evt)))
{
var temp = cell;
var swimlanes = [];
while (temp != null)
{
temp = this.model.getParent(temp);
var state = this.view.getState(temp);
if (this.isSwimlane(temp) && state != null)
{
swimlanes.push(temp);
}
}
if (swimlanes.length > 0)
{
swimlanes = swimlanes.reverse();
swimlanes.splice(0, 0, cell);
swimlanes.push(cell);
for (var i = 0; i < swimlanes.length - 1; i++)
{
if (this.isCellSelected(swimlanes[i]))
{
cell = swimlanes[(this.isToggleEvent(evt)) ?
i : i + 1];
}
}
}
}
}
if (cell != null)
{
this.selectCellForEvent(cell, evt);
}
else if (!this.isToggleEvent(evt))
{
this.clearSelection();
}
}
};
mxGraph.prototype.isSiblingSelected = function(cell)
{
var model = this.model;
var parent = model.getParent(cell);
var childCount = model.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(parent, i);
if (cell != child && this.isCellSelected(child))
{
return true;
}
}
return false;
};
mxGraph.prototype.dblClick = function(evt, cell)
{
var mxe = new mxEventObject(mxEvent.DOUBLE_CLICK, 'event', evt, 'cell', cell);
this.fireEvent(mxe);
if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed() &&
cell != null && this.isCellEditable(cell) && !this.isEditing(cell))
{
this.startEditingAtCell(cell, evt);
mxEvent.consume(evt);
}
};
mxGraph.prototype.tapAndHold = function(me)
{
var evt = me.getEvent();
var mxe = new mxEventObject(mxEvent.TAP_AND_HOLD, 'event', evt, 'cell', me.getCell());
this.fireEvent(mxe);
if (mxe.isConsumed())
{
this.panningHandler.panningTrigger = false;
}
if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed() && this.connectionHandler.isEnabled())
{
var state = this.view.getState(this.connectionHandler.marker.getCell(me));
if (state != null)
{
this.connectionHandler.marker.currentColor = this.connectionHandler.marker.validColor;
this.connectionHandler.marker.markedState = state;
this.connectionHandler.marker.mark();
this.connectionHandler.first = new mxPoint(me.getGraphX(), me.getGraphY());
this.connectionHandler.edgeState = this.connectionHandler.createEdgeState(me);
this.connectionHandler.previous = state;
this.connectionHandler.fireEvent(new mxEventObject(mxEvent.START, 'state', this.connectionHandler.previous));
}
}
};
mxGraph.prototype.scrollPointToVisible = function(x, y, extend, border)
{
if (!this.timerAutoScroll && (this.ignoreScrollbars || mxUtils.hasScrollbars(this.container)))
{
var c = this.container;
border = (border != null) ? border : 20;
if (x >= c.scrollLeft && y >= c.scrollTop && x <= c.scrollLeft + c.clientWidth &&
y <= c.scrollTop + c.clientHeight)
{
var dx = c.scrollLeft + c.clientWidth - x;
if (dx < border)
{
var old = c.scrollLeft;
c.scrollLeft += border - dx;
if (extend && old == c.scrollLeft)
{
if (this.dialect == mxConstants.DIALECT_SVG)
{
var root = this.view.getDrawPane().ownerSVGElement;
var width = this.container.scrollWidth + border - dx;
root.style.width = width + 'px';
}
else
{
var width = Math.max(c.clientWidth, c.scrollWidth) + border - dx;
var canvas = this.view.getCanvas();
canvas.style.width = width + 'px';
}
c.scrollLeft += border - dx;
}
}
else
{
dx = x - c.scrollLeft;
if (dx < border)
{
c.scrollLeft -= border - dx;
}
}
var dy = c.scrollTop + c.clientHeight - y;
if (dy < border)
{
var old = c.scrollTop;
c.scrollTop += border - dy;
if (old == c.scrollTop && extend)
{
if (this.dialect == mxConstants.DIALECT_SVG)
{
var root = this.view.getDrawPane().ownerSVGElement;
var height = this.container.scrollHeight + border - dy;
root.style.height = height + 'px';
}
else
{
var height = Math.max(c.clientHeight, c.scrollHeight) + border - dy;
var canvas = this.view.getCanvas();
canvas.style.height = height + 'px';
}
c.scrollTop += border - dy;
}
}
else
{
dy = y - c.scrollTop;
if (dy < border)
{
c.scrollTop -= border - dy;
}
}
}
}
else if (this.allowAutoPanning && !this.panningHandler.isActive())
{
if (this.panningManager == null)
{
this.panningManager = this.createPanningManager();
}
this.panningManager.panTo(x + this.panDx, y + this.panDy);
}
};
mxGraph.prototype.createPanningManager = function()
{
return new mxPanningManager(this);
};
mxGraph.prototype.getBorderSizes = function()
{
var css = mxUtils.getCurrentStyle(this.container);
return new mxRectangle(mxUtils.parseCssNumber(css.paddingLeft) +
((css.borderLeftStyle != 'none') ? mxUtils.parseCssNumber(css.borderLeftWidth) : 0),
mxUtils.parseCssNumber(css.paddingTop) +
((css.borderTopStyle != 'none') ? mxUtils.parseCssNumber(css.borderTopWidth) : 0),
mxUtils.parseCssNumber(css.paddingRight) +
((css.borderRightStyle != 'none') ? mxUtils.parseCssNumber(css.borderRightWidth) : 0),
mxUtils.parseCssNumber(css.paddingBottom) +
((css.borderBottomStyle != 'none') ? mxUtils.parseCssNumber(css.borderBottomWidth) : 0));
};
mxGraph.prototype.getPreferredPageSize = function(bounds, width, height)
{
this.view.scale;
var tr = this.view.translate;
var fmt = this.pageFormat;
var ps = this.pageScale;
var page = new mxRectangle(0, 0, Math.ceil(fmt.width * ps), Math.ceil(fmt.height * ps));
var hCount = (this.pageBreaksVisible) ? Math.ceil(width / page.width) : 1;
var vCount = (this.pageBreaksVisible) ? Math.ceil(height / page.height) : 1;
return new mxRectangle(0, 0, hCount * page.width + 2 + tr.x, vCount * page.height + 2 + tr.y);
};
mxGraph.prototype.fit = function(border, keepOrigin, margin, enabled, ignoreWidth, ignoreHeight, maxHeight)
{
if (this.container != null)
{
border = (border != null) ? border : this.getBorder();
keepOrigin = (keepOrigin != null) ? keepOrigin : false;
margin = (margin != null) ? margin : 0;
enabled = (enabled != null) ? enabled : true;
ignoreWidth = (ignoreWidth != null) ? ignoreWidth : false;
ignoreHeight = (ignoreHeight != null) ? ignoreHeight : false;
var cssBorder = this.getBorderSizes();
var w1 = this.container.offsetWidth - cssBorder.x - cssBorder.width - 1;
var h1 = (maxHeight != null) ? maxHeight : this.container.offsetHeight - cssBorder.y - cssBorder.height - 1;
var bounds = this.view.getGraphBounds();
if (bounds.width > 0 && bounds.height > 0)
{
if (keepOrigin && bounds.x != null && bounds.y != null)
{
bounds = bounds.clone();
bounds.width += bounds.x;
bounds.height += bounds.y;
bounds.x = 0;
bounds.y = 0;
}
var s = this.view.scale;
var w2 = bounds.width / s;
var h2 = bounds.height / s;
if (this.backgroundImage != null)
{
w2 = Math.max(w2, this.backgroundImage.width - bounds.x / s);
h2 = Math.max(h2, this.backgroundImage.height - bounds.y / s);
}
var b = ((keepOrigin) ? border : 2 * border) + margin + 1;
w1 -= b;
h1 -= b;
var s2 = (((ignoreWidth) ? h1 / h2 : (ignoreHeight) ? w1 / w2 :
Math.min(w1 / w2, h1 / h2)));
if (this.minFitScale != null)
{
s2 = Math.max(s2, this.minFitScale);
}
if (this.maxFitScale != null)
{
s2 = Math.min(s2, this.maxFitScale);
}
if (enabled)
{
if (!keepOrigin)
{
if (!mxUtils.hasScrollbars(this.container))
{
var x0 = (bounds.x != null) ? Math.floor(this.view.translate.x - bounds.x / s + border / s2 + margin / 2) : border;
var y0 = (bounds.y != null) ? Math.floor(this.view.translate.y - bounds.y / s + border / s2 + margin / 2) : border;
this.view.scaleAndTranslate(s2, x0, y0);
}
else
{
this.view.setScale(s2);
var b2 = this.getGraphBounds();
if (b2.x != null)
{
this.container.scrollLeft = b2.x;
}
if (b2.y != null)
{
this.container.scrollTop = b2.y;
}
}
}
else if (this.view.scale != s2)
{
this.view.setScale(s2);
}
}
else
{
return s2;
}
}
}
return this.view.scale;
};
mxGraph.prototype.sizeDidChange = function()
{
var bounds = this.getGraphBounds();
if (this.container != null)
{
var border = this.getBorder();
var width = Math.max(0, bounds.x) + bounds.width + 2 * border;
var height = Math.max(0, bounds.y) + bounds.height + 2 * border;
if (this.minimumContainerSize != null)
{
width = Math.max(width, this.minimumContainerSize.width);
height = Math.max(height, this.minimumContainerSize.height);
}
if (this.resizeContainer)
{
this.doResizeContainer(width, height);
}
if (this.preferPageSize || (!mxClient.IS_IE && this.pageVisible))
{
var size = this.getPreferredPageSize(bounds, Math.max(1, width), Math.max(1, height));
if (size != null)
{
width = size.width * this.view.scale;
height = size.height * this.view.scale;
}
}
if (this.minimumGraphSize != null)
{
width = Math.max(width, this.minimumGraphSize.width * this.view.scale);
height = Math.max(height, this.minimumGraphSize.height * this.view.scale);
}
width = Math.ceil(width);
height = Math.ceil(height);
if (this.dialect == mxConstants.DIALECT_SVG)
{
var root = this.view.getDrawPane().ownerSVGElement;
if (root != null)
{
root.style.minWidth = Math.max(1, width) + 'px';
root.style.minHeight = Math.max(1, height) + 'px';
root.style.width = '100%';
root.style.height = '100%';
}
}
else
{
if (mxClient.IS_QUIRKS)
{
this.view.updateHtmlCanvasSize(Math.max(1, width), Math.max(1, height));
}
else
{
this.view.canvas.style.minWidth = Math.max(1, width) + 'px';
this.view.canvas.style.minHeight = Math.max(1, height) + 'px';
}
}
this.updatePageBreaks(this.pageBreaksVisible, width, height);
}
this.fireEvent(new mxEventObject(mxEvent.SIZE, 'bounds', bounds));
};
mxGraph.prototype.doResizeContainer = function(width, height)
{
if (this.maximumContainerSize != null)
{
width = Math.min(this.maximumContainerSize.width, width);
height = Math.min(this.maximumContainerSize.height, height);
}
this.container.style.width = Math.ceil(width) + 'px';
this.container.style.height = Math.ceil(height) + 'px';
};
mxGraph.prototype.updatePageBreaks = function(visible, width, height)
{
var scale = this.view.scale;
var tr = this.view.translate;
var fmt = this.pageFormat;
var ps = scale * this.pageScale;
var bounds = new mxRectangle(0, 0, fmt.width * ps, fmt.height * ps);
var gb = mxRectangle.fromRectangle(this.getGraphBounds());
gb.width = Math.max(1, gb.width);
gb.height = Math.max(1, gb.height);
bounds.x = Math.floor((gb.x - tr.x * scale) / bounds.width) * bounds.width + tr.x * scale;
bounds.y = Math.floor((gb.y - tr.y * scale) / bounds.height) * bounds.height + tr.y * scale;
gb.width = Math.ceil((gb.width + (gb.x - bounds.x)) / bounds.width) * bounds.width;
gb.height = Math.ceil((gb.height + (gb.y - bounds.y)) / bounds.height) * bounds.height;
visible = visible && Math.min(bounds.width, bounds.height) > this.minPageBreakDist;
var horizontalCount = (visible) ? Math.ceil(gb.height / bounds.height) + 1 : 0;
var verticalCount = (visible) ? Math.ceil(gb.width / bounds.width) + 1 : 0;
var right = (verticalCount - 1) * bounds.width;
var bottom = (horizontalCount - 1) * bounds.height;
if (this.horizontalPageBreaks == null && horizontalCount > 0)
{
this.horizontalPageBreaks = [];
}
if (this.verticalPageBreaks == null && verticalCount > 0)
{
this.verticalPageBreaks = [];
}
var drawPageBreaks = mxUtils.bind(this, function(breaks)
{
if (breaks != null)
{
var count = (breaks == this.horizontalPageBreaks) ? horizontalCount : verticalCount;
for (var i = 0; i <= count; i++)
{
var pts = (breaks == this.horizontalPageBreaks) ?
[new mxPoint(Math.round(bounds.x), Math.round(bounds.y + i * bounds.height)),
new mxPoint(Math.round(bounds.x + right), Math.round(bounds.y + i * bounds.height))] :
[new mxPoint(Math.round(bounds.x + i * bounds.width), Math.round(bounds.y)),
new mxPoint(Math.round(bounds.x + i * bounds.width), Math.round(bounds.y + bottom))];
if (breaks[i] != null)
{
breaks[i].points = pts;
breaks[i].redraw();
}
else
{
var pageBreak = new mxPolyline(pts, this.pageBreakColor);
pageBreak.dialect = this.dialect;
pageBreak.pointerEvents = false;
pageBreak.isDashed = this.pageBreakDashed;
pageBreak.init(this.view.backgroundPane);
pageBreak.redraw();
breaks[i] = pageBreak;
}
}
for (var i = count; i < breaks.length; i++)
{
breaks[i].destroy();
}
breaks.splice(count, breaks.length - count);
}
});
drawPageBreaks(this.horizontalPageBreaks);
drawPageBreaks(this.verticalPageBreaks);
};
mxGraph.prototype.getCurrentCellStyle = function(cell, ignoreState)
{
var state = (ignoreState) ? null : this.view.getState(cell);
return (state != null) ? state.style : this.getCellStyle(cell);
};
mxGraph.prototype.getCellStyle = function(cell)
{
var stylename = this.model.getStyle(cell);
var style = null;
if (this.model.isEdge(cell))
{
style = this.stylesheet.getDefaultEdgeStyle();
}
else
{
style = this.stylesheet.getDefaultVertexStyle();
}
if (stylename != null)
{
style = this.postProcessCellStyle(this.stylesheet.getCellStyle(stylename, style));
}
if (style == null)
{
style = new Object();
}
return style;
};
mxGraph.prototype.postProcessCellStyle = function(style)
{
if (style != null)
{
var key = style[mxConstants.STYLE_IMAGE];
var image = this.getImageFromBundles(key);
if (image != null)
{
style[mxConstants.STYLE_IMAGE] = image;
}
else
{
image = key;
}
if (image != null && image.substring(0, 11) == 'data:image/')
{
if (image.substring(0, 20) == 'data:image/svg+xml,<')
{
image = image.substring(0, 19) + encodeURIComponent(image.substring(19));
}
else if (image.substring(0, 22) != 'data:image/svg+xml,%3C')
{
var comma = image.indexOf(',');
if (comma > 0 && image.substring(comma - 7, comma + 1) != ';base64,')
{
image = image.substring(0, comma) + ';base64,'
+ image.substring(comma + 1);
}
}
style[mxConstants.STYLE_IMAGE] = image;
}
}
return style;
};
mxGraph.prototype.setCellStyle = function(style, cells)
{
cells = cells || this.getSelectionCells();
if (cells != null)
{
this.model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
this.model.setStyle(cells[i], style);
}
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.toggleCellStyle = function(key, defaultValue, cell)
{
cell = cell || this.getSelectionCell();
return this.toggleCellStyles(key, defaultValue, [cell]);
};
mxGraph.prototype.toggleCellStyles = function(key, defaultValue, cells)
{
defaultValue = (defaultValue != null) ? defaultValue : false;
cells = cells || this.getSelectionCells();
var value = null;
if (cells != null && cells.length > 0)
{
var style = this.getCurrentCellStyle(cells[0]);
value = (mxUtils.getValue(style, key, defaultValue)) ? 0 : 1;
this.setCellStyles(key, value, cells);
}
return value;
};
mxGraph.prototype.setCellStyles = function(key, value, cells)
{
cells = cells || this.getSelectionCells();
mxUtils.setCellStyles(this.model, cells, key, value);
};
mxGraph.prototype.toggleCellStyleFlags = function(key, flag, cells)
{
this.setCellStyleFlags(key, flag, null, cells);
};
mxGraph.prototype.setCellStyleFlags = function(key, flag, value, cells)
{
cells = cells || this.getSelectionCells();
if (cells != null && cells.length > 0)
{
if (value == null)
{
var style = this.getCurrentCellStyle(cells[0]);
var current = parseInt(style[key] || 0);
value = !((current & flag) == flag);
}
mxUtils.setCellStyleFlags(this.model, cells, key, flag, value);
}
};
mxGraph.prototype.alignCells = function(align, cells, param)
{
if (cells == null)
{
cells = this.getSelectionCells();
}
if (cells != null && cells.length > 1)
{
if (param == null)
{
for (var i = 0; i < cells.length; i++)
{
var state = this.view.getState(cells[i]);
if (state != null && !this.model.isEdge(cells[i]))
{
if (param == null)
{
if (align == mxConstants.ALIGN_CENTER)
{
param = state.x + state.width / 2;
break;
}
else if (align == mxConstants.ALIGN_RIGHT)
{
param = state.x + state.width;
}
else if (align == mxConstants.ALIGN_TOP)
{
param = state.y;
}
else if (align == mxConstants.ALIGN_MIDDLE)
{
param = state.y + state.height / 2;
break;
}
else if (align == mxConstants.ALIGN_BOTTOM)
{
param = state.y + state.height;
}
else
{
param = state.x;
}
}
else
{
if (align == mxConstants.ALIGN_RIGHT)
{
param = Math.max(param, state.x + state.width);
}
else if (align == mxConstants.ALIGN_TOP)
{
param = Math.min(param, state.y);
}
else if (align == mxConstants.ALIGN_BOTTOM)
{
param = Math.max(param, state.y + state.height);
}
else
{
param = Math.min(param, state.x);
}
}
}
}
}
if (param != null)
{
var s = this.view.scale;
this.model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
var state = this.view.getState(cells[i]);
if (state != null)
{
var geo = this.getCellGeometry(cells[i]);
if (geo != null && !this.model.isEdge(cells[i]))
{
geo = geo.clone();
if (align == mxConstants.ALIGN_CENTER)
{
geo.x += (param - state.x - state.width / 2) / s;
}
else if (align == mxConstants.ALIGN_RIGHT)
{
geo.x += (param - state.x - state.width) / s;
}
else if (align == mxConstants.ALIGN_TOP)
{
geo.y += (param - state.y) / s;
}
else if (align == mxConstants.ALIGN_MIDDLE)
{
geo.y += (param - state.y - state.height / 2) / s;
}
else if (align == mxConstants.ALIGN_BOTTOM)
{
geo.y += (param - state.y - state.height) / s;
}
else
{
geo.x += (param - state.x) / s;
}
this.resizeCell(cells[i], geo);
}
}
}
this.fireEvent(new mxEventObject(mxEvent.ALIGN_CELLS,
'align', align, 'cells', cells));
}
finally
{
this.model.endUpdate();
}
}
}
return cells;
};
mxGraph.prototype.flipEdge = function(edge)
{
if (edge != null &&
this.alternateEdgeStyle != null)
{
this.model.beginUpdate();
try
{
var style = this.model.getStyle(edge);
if (style == null || style.length == 0)
{
this.model.setStyle(edge, this.alternateEdgeStyle);
}
else
{
this.model.setStyle(edge, null);
}
this.resetEdge(edge);
this.fireEvent(new mxEventObject(mxEvent.FLIP_EDGE, 'edge', edge));
}
finally
{
this.model.endUpdate();
}
}
return edge;
};
mxGraph.prototype.addImageBundle = function(bundle)
{
this.imageBundles.push(bundle);
};
mxGraph.prototype.removeImageBundle = function(bundle)
{
var tmp = [];
for (var i = 0; i < this.imageBundles.length; i++)
{
if (this.imageBundles[i] != bundle)
{
tmp.push(this.imageBundles[i]);
}
}
this.imageBundles = tmp;
};
mxGraph.prototype.getImageFromBundles = function(key)
{
if (key != null)
{
for (var i = 0; i < this.imageBundles.length; i++)
{
var image = this.imageBundles[i].getImage(key);
if (image != null)
{
return image;
}
}
}
return null;
};
mxGraph.prototype.orderCells = function(back, cells)
{
if (cells == null)
{
cells = mxUtils.sortCells(this.getSelectionCells(), true);
}
this.model.beginUpdate();
try
{
this.cellsOrdered(cells, back);
this.fireEvent(new mxEventObject(mxEvent.ORDER_CELLS,
'back', back, 'cells', cells));
}
finally
{
this.model.endUpdate();
}
return cells;
};
mxGraph.prototype.cellsOrdered = function(cells, back)
{
if (cells != null)
{
this.model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
var parent = this.model.getParent(cells[i]);
if (back)
{
this.model.add(parent, cells[i], i);
}
else
{
this.model.add(parent, cells[i],
this.model.getChildCount(parent) - 1);
}
}
this.fireEvent(new mxEventObject(mxEvent.CELLS_ORDERED,
'back', back, 'cells', cells));
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.groupCells = function(group, border, cells)
{
if (cells == null)
{
cells = mxUtils.sortCells(this.getSelectionCells(), true);
}
cells = this.getCellsForGroup(cells);
if (group == null)
{
group = this.createGroupCell(cells);
}
var bounds = this.getBoundsForGroup(group, cells, border);
if (cells.length > 1 && bounds != null)
{
var parent = this.model.getParent(group);
if (parent == null)
{
parent = this.model.getParent(cells[0]);
}
this.model.beginUpdate();
try
{
if (this.getCellGeometry(group) == null)
{
this.model.setGeometry(group, new mxGeometry());
}
var index = this.model.getChildCount(parent);
this.cellsAdded([group], parent, index, null, null, false, false, false);
index = this.model.getChildCount(group);
this.cellsAdded(cells, group, index, null, null, false, false, false);
this.cellsMoved(cells, -bounds.x, -bounds.y, false, false, false);
this.cellsResized([group], [bounds], false);
this.fireEvent(new mxEventObject(mxEvent.GROUP_CELLS,
'group', group, 'border', border, 'cells', cells));
}
finally
{
this.model.endUpdate();
}
}
return group;
};
mxGraph.prototype.getCellsForGroup = function(cells)
{
var result = [];
if (cells != null && cells.length > 0)
{
var parent = this.model.getParent(cells[0]);
result.push(cells[0]);
for (var i = 1; i < cells.length; i++)
{
if (this.model.getParent(cells[i]) == parent)
{
result.push(cells[i]);
}
}
}
return result;
};
mxGraph.prototype.getBoundsForGroup = function(group, children, border)
{
var result = this.getBoundingBoxFromGeometry(children, true);
if (result != null)
{
if (this.isSwimlane(group))
{
var size = this.getStartSize(group);
result.x -= size.width;
result.y -= size.height;
result.width += size.width;
result.height += size.height;
}
if (border != null)
{
result.x -= border;
result.y -= border;
result.width += 2 * border;
result.height += 2 * border;
}
}
return result;
};
mxGraph.prototype.createGroupCell = function(cells)
{
var group = new mxCell('');
group.setVertex(true);
group.setConnectable(false);
return group;
};
mxGraph.prototype.ungroupCells = function(cells)
{
var result = [];
if (cells == null)
{
cells = this.getCellsForUngroup();
}
if (cells != null && cells.length > 0)
{
this.model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
var children = this.model.getChildren(cells[i]);
if (children != null && children.length > 0)
{
children = children.slice();
var parent = this.model.getParent(cells[i]);
var index = this.model.getChildCount(parent);
this.cellsAdded(children, parent, index, null, null, true);
result = result.concat(children);
for (var j = 0; j < children.length; j++)
{
var state = this.view.getState(children[j]);
var geo = this.getCellGeometry(children[j]);
if (state != null && geo != null && geo.relative)
{
geo = geo.clone();
geo.x = state.origin.x;
geo.y = state.origin.y;
geo.relative = false;
this.model.setGeometry(children[j], geo);
}
}
}
}
this.removeCellsAfterUngroup(cells);
this.fireEvent(new mxEventObject(mxEvent.UNGROUP_CELLS, 'cells', cells));
}
finally
{
this.model.endUpdate();
}
}
return result;
};
mxGraph.prototype.getCellsForUngroup = function()
{
var cells = this.getSelectionCells();
var tmp = [];
for (var i = 0; i < cells.length; i++)
{
if (this.model.isVertex(cells[i]) &&
this.model.getChildCount(cells[i]) > 0)
{
tmp.push(cells[i]);
}
}
return tmp;
};
mxGraph.prototype.removeCellsAfterUngroup = function(cells)
{
this.cellsRemoved(this.addAllEdges(cells));
};
mxGraph.prototype.removeCellsFromParent = function(cells)
{
if (cells == null)
{
cells = this.getSelectionCells();
}
this.model.beginUpdate();
try
{
var parent = this.getDefaultParent();
var index = this.model.getChildCount(parent);
this.cellsAdded(cells, parent, index, null, null, true);
this.fireEvent(new mxEventObject(mxEvent.REMOVE_CELLS_FROM_PARENT, 'cells', cells));
}
finally
{
this.model.endUpdate();
}
return cells;
};
mxGraph.prototype.updateGroupBounds = function(cells, border, moveGroup, topBorder, rightBorder, bottomBorder, leftBorder)
{
if (cells == null)
{
cells = this.getSelectionCells();
}
border = (border != null) ? border : 0;
moveGroup = (moveGroup != null) ? moveGroup : false;
topBorder = (topBorder != null) ? topBorder : 0;
rightBorder = (rightBorder != null) ? rightBorder : 0;
bottomBorder = (bottomBorder != null) ? bottomBorder : 0;
leftBorder = (leftBorder != null) ? leftBorder : 0;
this.model.beginUpdate();
try
{
for (var i = cells.length - 1; i >= 0; i--)
{
var geo = this.getCellGeometry(cells[i]);
if (geo != null)
{
var children = this.getChildCells(cells[i]);
if (children != null && children.length > 0)
{
var bounds = this.getBoundingBoxFromGeometry(children, true);
if (bounds != null && bounds.width > 0 && bounds.height > 0)
{
var size = (this.isSwimlane(cells[i])) ?
this.getActualStartSize(cells[i], true) : new mxRectangle();
geo = geo.clone();
if (moveGroup)
{
geo.x = Math.round(geo.x + bounds.x - border - size.x - leftBorder);
geo.y = Math.round(geo.y + bounds.y - border - size.y - topBorder);
}
geo.width = Math.round(bounds.width + 2 * border + size.x + leftBorder + rightBorder + size.width);
geo.height = Math.round(bounds.height + 2 * border + size.y + topBorder + bottomBorder + size.height);
this.model.setGeometry(cells[i], geo);
this.moveCells(children, border + size.x - bounds.x + leftBorder,
border + size.y - bounds.y + topBorder);
}
}
}
}
}
finally
{
this.model.endUpdate();
}
return cells;
};
mxGraph.prototype.getBoundingBox = function(cells)
{
var result = null;
if (cells != null && cells.length > 0)
{
for (var i = 0; i < cells.length; i++)
{
if (this.model.isVertex(cells[i]) || this.model.isEdge(cells[i]))
{
var bbox = this.view.getBoundingBox(this.view.getState(cells[i]), true);
if (bbox != null)
{
if (result == null)
{
result = mxRectangle.fromRectangle(bbox);
}
else
{
result.add(bbox);
}
}
}
}
}
return result;
};
mxGraph.prototype.cloneCell = function(cell, allowInvalidEdges, mapping, keepPosition)
{
return this.cloneCells([cell], allowInvalidEdges, mapping, keepPosition)[0];
};
mxGraph.prototype.cloneCells = function(cells, allowInvalidEdges, mapping, keepPosition)
{
allowInvalidEdges = (allowInvalidEdges != null) ? allowInvalidEdges : true;
var clones = null;
if (cells != null)
{
var dict = new mxDictionary();
var tmp = [];
for (var i = 0; i < cells.length; i++)
{
dict.put(cells[i], true);
tmp.push(cells[i]);
}
if (tmp.length > 0)
{
var scale = this.view.scale;
var trans = this.view.translate;
clones = this.model.cloneCells(cells, true, mapping);
for (var i = 0; i < cells.length; i++)
{
if (!allowInvalidEdges && this.model.isEdge(clones[i]) &&
this.getEdgeValidationError(clones[i],
this.model.getTerminal(clones[i], true),
this.model.getTerminal(clones[i], false)) != null)
{
clones[i] = null;
}
else
{
var g = this.model.getGeometry(clones[i]);
if (g != null)
{
var state = this.view.getState(cells[i]);
var pstate = this.view.getState(this.model.getParent(cells[i]));
if (state != null && pstate != null)
{
var dx = (keepPosition) ? 0 : pstate.origin.x;
var dy = (keepPosition) ? 0 : pstate.origin.y;
if (this.model.isEdge(clones[i]))
{
var pts = state.absolutePoints;
if (pts != null)
{
var src = this.model.getTerminal(cells[i], true);
while (src != null && !dict.get(src))
{
src = this.model.getParent(src);
}
if (src == null && pts[0] != null)
{
g.setTerminalPoint(
new mxPoint(pts[0].x / scale - trans.x,
pts[0].y / scale - trans.y), true);
}
var trg = this.model.getTerminal(cells[i], false);
while (trg != null && !dict.get(trg))
{
trg = this.model.getParent(trg);
}
var n = pts.length - 1;
if (trg == null && pts[n] != null)
{
g.setTerminalPoint(
new mxPoint(pts[n].x / scale - trans.x,
pts[n].y / scale - trans.y), false);
}
var points = g.points;
if (points != null)
{
for (var j = 0; j < points.length; j++)
{
points[j].x += dx;
points[j].y += dy;
}
}
}
}
else
{
g.translate(dx, dy);
}
}
}
}
}
}
else
{
clones = [];
}
}
return clones;
};
mxGraph.prototype.insertVertex = function(parent, id, value,
x, y, width, height, style, relative)
{
var vertex = this.createVertex(parent, id, value, x, y, width, height, style, relative);
return this.addCell(vertex, parent);
};
mxGraph.prototype.createVertex = function(parent, id, value,
x, y, width, height, style, relative)
{
var geometry = new mxGeometry(x, y, width, height);
geometry.relative = (relative != null) ? relative : false;
var vertex = new mxCell(value, geometry, style);
vertex.setId(id);
vertex.setVertex(true);
vertex.setConnectable(true);
return vertex;
};
mxGraph.prototype.insertEdge = function(parent, id, value, source, target, style)
{
var edge = this.createEdge(parent, id, value, source, target, style);
return this.addEdge(edge, parent, source, target);
};
mxGraph.prototype.createEdge = function(parent, id, value, source, target, style)
{
var edge = new mxCell(value, new mxGeometry(), style);
edge.setId(id);
edge.setEdge(true);
edge.geometry.relative = true;
return edge;
};
mxGraph.prototype.addEdge = function(edge, parent, source, target, index)
{
return this.addCell(edge, parent, index, source, target);
};
mxGraph.prototype.addCell = function(cell, parent, index, source, target)
{
return this.addCells([cell], parent, index, source, target)[0];
};
mxGraph.prototype.addCells = function(cells, parent, index, source, target, absolute)
{
if (parent == null)
{
parent = this.getDefaultParent();
}
if (index == null)
{
index = this.model.getChildCount(parent);
}
this.model.beginUpdate();
try
{
this.cellsAdded(cells, parent, index, source, target, (absolute != null) ? absolute : false, true);
this.fireEvent(new mxEventObject(mxEvent.ADD_CELLS, 'cells', cells,
'parent', parent, 'index', index, 'source', source, 'target', target));
}
finally
{
this.model.endUpdate();
}
return cells;
};
mxGraph.prototype.cellsAdded = function(cells, parent, index, source, target, absolute, constrain, extend)
{
if (cells != null && parent != null && index != null)
{
this.model.beginUpdate();
try
{
var parentState = (absolute) ? this.view.getState(parent) : null;
var o1 = (parentState != null) ? parentState.origin : null;
var zero = new mxPoint(0, 0);
for (var i = 0; i < cells.length; i++)
{
if (cells[i] == null)
{
index--;
}
else
{
var previous = this.model.getParent(cells[i]);
if (o1 != null && cells[i] != parent && parent != previous)
{
var oldState = this.view.getState(previous);
var o2 = (oldState != null) ? oldState.origin : zero;
var geo = this.model.getGeometry(cells[i]);
if (geo != null)
{
var dx = o2.x - o1.x;
var dy = o2.y - o1.y;
geo = geo.clone();
geo.translate(dx, dy);
if (!geo.relative && this.model.isVertex(cells[i]) &&
!this.isAllowNegativeCoordinates())
{
geo.x = Math.max(0, geo.x);
geo.y = Math.max(0, geo.y);
}
this.model.setGeometry(cells[i], geo);
}
}
if (parent == previous && index + i > this.model.getChildCount(parent))
{
index--;
}
this.model.add(parent, cells[i], index + i);
if (this.autoSizeCellsOnAdd)
{
this.autoSizeCell(cells[i], true);
}
if ((extend == null || extend) &&
this.isExtendParentsOnAdd(cells[i]) && this.isExtendParent(cells[i]))
{
this.extendParent(cells[i]);
}
if (constrain == null || constrain)
{
this.constrainChild(cells[i]);
}
if (source != null)
{
this.cellConnected(cells[i], source, true);
}
if (target != null)
{
this.cellConnected(cells[i], target, false);
}
}
}
this.fireEvent(new mxEventObject(mxEvent.CELLS_ADDED, 'cells', cells,
'parent', parent, 'index', index, 'source', source, 'target', target,
'absolute', absolute));
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.autoSizeCell = function(cell, recurse)
{
recurse = (recurse != null) ? recurse : true;
if (recurse)
{
var childCount = this.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
this.autoSizeCell(this.model.getChildAt(cell, i));
}
}
if (this.getModel().isVertex(cell) && this.isAutoSizeCell(cell))
{
this.updateCellSize(cell);
}
};
mxGraph.prototype.removeCells = function(cells, includeEdges)
{
includeEdges = (includeEdges != null) ? includeEdges : true;
if (cells == null)
{
cells = this.getDeletableCells(this.getSelectionCells());
}
if (includeEdges)
{
cells = this.getDeletableCells(this.addAllEdges(cells));
}
else
{
cells = cells.slice();
var edges = this.getDeletableCells(this.getAllEdges(cells));
var dict = new mxDictionary();
for (var i = 0; i < cells.length; i++)
{
dict.put(cells[i], true);
}
for (var i = 0; i < edges.length; i++)
{
if (this.view.getState(edges[i]) == null &&
!dict.get(edges[i]))
{
dict.put(edges[i], true);
cells.push(edges[i]);
}
}
}
this.model.beginUpdate();
try
{
this.cellsRemoved(cells);
this.fireEvent(new mxEventObject(mxEvent.REMOVE_CELLS,
'cells', cells, 'includeEdges', includeEdges));
}
finally
{
this.model.endUpdate();
}
return cells;
};
mxGraph.prototype.cellsRemoved = function(cells)
{
if (cells != null && cells.length > 0)
{
var scale = this.view.scale;
var tr = this.view.translate;
this.model.beginUpdate();
try
{
var dict = new mxDictionary();
for (var i = 0; i < cells.length; i++)
{
dict.put(cells[i], true);
}
for (var i = 0; i < cells.length; i++)
{
var edges = this.getAllEdges([cells[i]]);
var disconnectTerminal = mxUtils.bind(this, function(edge, source)
{
var geo = this.model.getGeometry(edge);
if (geo != null)
{
var terminal = this.model.getTerminal(edge, source);
var connected = false;
var tmp = terminal;
while (tmp != null)
{
if (cells[i] == tmp)
{
connected = true;
break;
}
tmp = this.model.getParent(tmp);
}
if (connected)
{
geo = geo.clone();
var state = this.view.getState(edge);
if (state != null && state.absolutePoints != null)
{
var pts = state.absolutePoints;
var n = (source) ? 0 : pts.length - 1;
geo.setTerminalPoint(new mxPoint(
pts[n].x / scale - tr.x - state.origin.x,
pts[n].y / scale - tr.y - state.origin.y), source);
}
else
{
var tstate = this.view.getState(terminal);
if (tstate != null)
{
geo.setTerminalPoint(new mxPoint(
tstate.getCenterX() / scale - tr.x,
tstate.getCenterY() / scale - tr.y), source);
}
}
this.model.setGeometry(edge, geo);
this.model.setTerminal(edge, null, source);
}
}
});
for (var j = 0; j < edges.length; j++)
{
if (!dict.get(edges[j]))
{
dict.put(edges[j], true);
disconnectTerminal(edges[j], true);
disconnectTerminal(edges[j], false);
}
}
this.model.remove(cells[i]);
}
this.fireEvent(new mxEventObject(mxEvent.CELLS_REMOVED, 'cells', cells));
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.splitEdge = function(edge, cells, newEdge, dx, dy, x, y, parent)
{
dx = dx || 0;
dy = dy || 0;
parent = (parent != null) ? parent : this.model.getParent(edge);
var source = this.model.getTerminal(edge, true);
this.model.beginUpdate();
try
{
if (newEdge == null)
{
newEdge = this.cloneCell(edge);
var state = this.view.getState(edge);
var geo = this.getCellGeometry(newEdge);
if (geo != null && geo.points != null && state != null)
{
var t = this.view.translate;
var s = this.view.scale;
var idx = mxUtils.findNearestSegment(state, (dx + t.x) * s, (dy + t.y) * s);
geo.points = geo.points.slice(0, idx);
geo = this.getCellGeometry(edge);
if (geo != null && geo.points != null)
{
geo = geo.clone();
geo.points = geo.points.slice(idx);
this.model.setGeometry(edge, geo);
}
}
}
this.cellsMoved(cells, dx, dy, false, false);
this.cellsAdded(cells, parent, this.model.getChildCount(parent), null, null,
true);
this.cellsAdded([newEdge], parent, this.model.getChildCount(parent),
source, cells[0], false);
this.cellConnected(edge, cells[0], true);
this.fireEvent(new mxEventObject(mxEvent.SPLIT_EDGE, 'edge', edge,
'cells', cells, 'newEdge', newEdge, 'dx', dx, 'dy', dy));
}
finally
{
this.model.endUpdate();
}
return newEdge;
};
mxGraph.prototype.toggleCells = function(show, cells, includeEdges)
{
if (cells == null)
{
cells = this.getSelectionCells();
}
if (includeEdges)
{
cells = this.addAllEdges(cells);
}
this.model.beginUpdate();
try
{
this.cellsToggled(cells, show);
this.fireEvent(new mxEventObject(mxEvent.TOGGLE_CELLS,
'show', show, 'cells', cells, 'includeEdges', includeEdges));
}
finally
{
this.model.endUpdate();
}
return cells;
};
mxGraph.prototype.cellsToggled = function(cells, show)
{
if (cells != null && cells.length > 0)
{
this.model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
this.model.setVisible(cells[i], show);
}
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.foldCells = function(collapse, recurse, cells, checkFoldable, evt)
{
recurse = (recurse != null) ? recurse : false;
if (cells == null)
{
cells = this.getFoldableCells(this.getSelectionCells(), collapse);
}
this.stopEditing(false);
this.model.beginUpdate();
try
{
this.cellsFolded(cells, collapse, recurse, checkFoldable);
this.fireEvent(new mxEventObject(mxEvent.FOLD_CELLS,
'collapse', collapse, 'recurse', recurse, 'cells', cells));
}
finally
{
this.model.endUpdate();
}
return cells;
};
mxGraph.prototype.cellsFolded = function(cells, collapse, recurse, checkFoldable)
{
if (cells != null && cells.length > 0)
{
this.model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
if ((!checkFoldable || this.isCellFoldable(cells[i], collapse)) &&
collapse != this.isCellCollapsed(cells[i]))
{
this.model.setCollapsed(cells[i], collapse);
this.swapBounds(cells[i], collapse);
if (this.isExtendParent(cells[i]))
{
this.extendParent(cells[i]);
}
if (recurse)
{
var children = this.model.getChildren(cells[i]);
this.cellsFolded(children, collapse, recurse);
}
this.constrainChild(cells[i]);
}
}
this.fireEvent(new mxEventObject(mxEvent.CELLS_FOLDED,
'cells', cells, 'collapse', collapse, 'recurse', recurse));
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.swapBounds = function(cell, willCollapse)
{
if (cell != null)
{
var geo = this.model.getGeometry(cell);
if (geo != null)
{
geo = geo.clone();
this.updateAlternateBounds(cell, geo, willCollapse);
geo.swap();
this.model.setGeometry(cell, geo);
}
}
};
mxGraph.prototype.updateAlternateBounds = function(cell, geo, willCollapse)
{
if (cell != null && geo != null)
{
var style = this.getCurrentCellStyle(cell);
if (geo.alternateBounds == null)
{
var bounds = geo;
if (this.collapseToPreferredSize)
{
var tmp = this.getPreferredSizeForCell(cell);
if (tmp != null)
{
bounds = tmp;
var startSize = mxUtils.getValue(style, mxConstants.STYLE_STARTSIZE);
if (startSize > 0)
{
bounds.height = Math.max(bounds.height, startSize);
}
}
}
geo.alternateBounds = new mxRectangle(0, 0, bounds.width, bounds.height);
}
if (geo.alternateBounds != null)
{
geo.alternateBounds.x = geo.x;
geo.alternateBounds.y = geo.y;
var alpha = mxUtils.toRadians(style[mxConstants.STYLE_ROTATION] || 0);
if (alpha != 0)
{
var dx = geo.alternateBounds.getCenterX() - geo.getCenterX();
var dy = geo.alternateBounds.getCenterY() - geo.getCenterY();
var cos = Math.cos(alpha);
var sin = Math.sin(alpha);
var dx2 = cos * dx - sin * dy;
var dy2 = sin * dx + cos * dy;
geo.alternateBounds.x += dx2 - dx;
geo.alternateBounds.y += dy2 - dy;
}
}
}
};
mxGraph.prototype.addAllEdges = function(cells)
{
var allCells = cells.slice();
return mxUtils.removeDuplicates(allCells.concat(this.getAllEdges(cells)));
};
mxGraph.prototype.getAllEdges = function(cells)
{
var edges = [];
if (cells != null)
{
for (var i = 0; i < cells.length; i++)
{
var edgeCount = this.model.getEdgeCount(cells[i]);
for (var j = 0; j < edgeCount; j++)
{
edges.push(this.model.getEdgeAt(cells[i], j));
}
var children = this.model.getChildren(cells[i]);
edges = edges.concat(this.getAllEdges(children));
}
}
return edges;
};
mxGraph.prototype.updateCellSize = function(cell, ignoreChildren)
{
ignoreChildren = (ignoreChildren != null) ? ignoreChildren : false;
this.model.beginUpdate();
try
{
this.cellSizeUpdated(cell, ignoreChildren);
this.fireEvent(new mxEventObject(mxEvent.UPDATE_CELL_SIZE,
'cell', cell, 'ignoreChildren', ignoreChildren));
}
finally
{
this.model.endUpdate();
}
return cell;
};
mxGraph.prototype.cellSizeUpdated = function(cell, ignoreChildren)
{
if (cell != null)
{
this.model.beginUpdate();
try
{
var size = this.getPreferredSizeForCell(cell);
var geo = this.model.getGeometry(cell);
if (size != null && geo != null)
{
var collapsed = this.isCellCollapsed(cell);
geo = geo.clone();
if (this.isSwimlane(cell))
{
var style = this.getCellStyle(cell);
var cellStyle = this.model.getStyle(cell);
if (cellStyle == null)
{
cellStyle = '';
}
if (mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true))
{
cellStyle = mxUtils.setStyle(cellStyle,
mxConstants.STYLE_STARTSIZE, size.height + 8);
if (collapsed)
{
geo.height = size.height + 8;
}
geo.width = size.width;
}
else
{
cellStyle = mxUtils.setStyle(cellStyle,
mxConstants.STYLE_STARTSIZE, size.width + 8);
if (collapsed)
{
geo.width = size.width + 8;
}
geo.height = size.height;
}
this.model.setStyle(cell, cellStyle);
}
else
{
var state = this.view.createState(cell);
var align = (state.style[mxConstants.STYLE_ALIGN] || mxConstants.ALIGN_CENTER);
if (align == mxConstants.ALIGN_RIGHT)
{
geo.x += geo.width - size.width;
}
else if (align == mxConstants.ALIGN_CENTER)
{
geo.x += Math.round((geo.width - size.width) / 2);
}
var valign = this.getVerticalAlign(state);
if (valign == mxConstants.ALIGN_BOTTOM)
{
geo.y += geo.height - size.height;
}
else if (valign == mxConstants.ALIGN_MIDDLE)
{
geo.y += Math.round((geo.height - size.height) / 2);
}
geo.width = size.width;
geo.height = size.height;
}
if (!ignoreChildren && !collapsed)
{
var bounds = this.view.getBounds(this.model.getChildren(cell));
if (bounds != null)
{
var tr = this.view.translate;
var scale = this.view.scale;
var width = (bounds.x + bounds.width) / scale - geo.x - tr.x;
var height = (bounds.y + bounds.height) / scale - geo.y - tr.y;
geo.width = Math.max(geo.width, width);
geo.height = Math.max(geo.height, height);
}
}
this.cellsResized([cell], [geo], false);
}
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.getPreferredSizeForCell = function(cell, textWidth)
{
var result = null;
if (cell != null)
{
var state = this.view.createState(cell);
var style = state.style;
if (!this.model.isEdge(cell))
{
var fontSize = style[mxConstants.STYLE_FONTSIZE] || mxConstants.DEFAULT_FONTSIZE;
var dx = 0;
var dy = 0;
if (this.getImage(state) != null || style[mxConstants.STYLE_IMAGE] != null)
{
if (style[mxConstants.STYLE_SHAPE] == mxConstants.SHAPE_LABEL)
{
if (style[mxConstants.STYLE_VERTICAL_ALIGN] == mxConstants.ALIGN_MIDDLE)
{
dx += parseFloat(style[mxConstants.STYLE_IMAGE_WIDTH]) || mxLabel.prototype.imageSize;
}
if (style[mxConstants.STYLE_ALIGN] != mxConstants.ALIGN_CENTER)
{
dy += parseFloat(style[mxConstants.STYLE_IMAGE_HEIGHT]) || mxLabel.prototype.imageSize;
}
}
}
dx += 2 * (style[mxConstants.STYLE_SPACING] || 0);
dx += style[mxConstants.STYLE_SPACING_LEFT] || 0;
dx += style[mxConstants.STYLE_SPACING_RIGHT] || 0;
dy += 2 * (style[mxConstants.STYLE_SPACING] || 0);
dy += style[mxConstants.STYLE_SPACING_TOP] || 0;
dy += style[mxConstants.STYLE_SPACING_BOTTOM] || 0;
var image = this.getFoldingImage(state);
if (image != null)
{
dx += image.width + 8;
}
var value = this.cellRenderer.getLabelValue(state);
if (value != null && value.length > 0)
{
if (!this.isHtmlLabel(state.cell))
{
value = mxUtils.htmlEntities(value, false);
}
value = value.replace(/\n/g, '<br>');
var size = mxUtils.getSizeForString(value, fontSize,
style[mxConstants.STYLE_FONTFAMILY], textWidth,
style[mxConstants.STYLE_FONTSTYLE]);
var width = size.width + dx;
var height = size.height + dy;
if (!mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true))
{
var tmp = height;
height = width;
width = tmp;
}
if (this.gridEnabled)
{
width = this.snap(width + this.gridSize / 2);
height = this.snap(height + this.gridSize / 2);
}
result = new mxRectangle(0, 0, width, height);
}
else
{
var gs2 = 4 * this.gridSize;
result = new mxRectangle(0, 0, gs2, gs2);
}
}
}
return result;
};
mxGraph.prototype.resizeCell = function(cell, bounds, recurse)
{
return this.resizeCells([cell], [bounds], recurse)[0];
};
mxGraph.prototype.resizeCells = function(cells, bounds, recurse)
{
recurse = (recurse != null) ? recurse : this.isRecursiveResize();
this.model.beginUpdate();
try
{
var prev = this.cellsResized(cells, bounds, recurse);
this.fireEvent(new mxEventObject(mxEvent.RESIZE_CELLS,
'cells', cells, 'bounds', bounds, 'previous', prev));
}
finally
{
this.model.endUpdate();
}
return cells;
};
mxGraph.prototype.cellsResized = function(cells, bounds, recurse)
{
recurse = (recurse != null) ? recurse : false;
var prev = [];
if (cells != null && bounds != null && cells.length == bounds.length)
{
this.model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
prev.push(this.cellResized(cells[i], bounds[i], false, recurse));
if (this.isExtendParent(cells[i]))
{
this.extendParent(cells[i]);
}
this.constrainChild(cells[i]);
}
if (this.resetEdgesOnResize)
{
this.resetEdges(cells);
}
this.fireEvent(new mxEventObject(mxEvent.CELLS_RESIZED,
'cells', cells, 'bounds', bounds, 'previous', prev));
}
finally
{
this.model.endUpdate();
}
}
return prev;
};
mxGraph.prototype.cellResized = function(cell, bounds, ignoreRelative, recurse)
{
var prev = this.model.getGeometry(cell);
if (prev != null && (prev.x != bounds.x || prev.y != bounds.y ||
prev.width != bounds.width || prev.height != bounds.height))
{
var geo = prev.clone();
if (!ignoreRelative && geo.relative)
{
var offset = geo.offset;
if (offset != null)
{
offset.x += bounds.x - geo.x;
offset.y += bounds.y - geo.y;
}
}
else
{
geo.x = bounds.x;
geo.y = bounds.y;
}
geo.width = bounds.width;
geo.height = bounds.height;
if (!geo.relative && this.model.isVertex(cell) && !this.isAllowNegativeCoordinates())
{
geo.x = Math.max(0, geo.x);
geo.y = Math.max(0, geo.y);
}
this.model.beginUpdate();
try
{
if (recurse)
{
this.resizeChildCells(cell, geo);
}
this.model.setGeometry(cell, geo);
this.constrainChildCells(cell);
}
finally
{
this.model.endUpdate();
}
}
return prev;
};
mxGraph.prototype.resizeChildCells = function(cell, newGeo)
{
var geo = this.model.getGeometry(cell);
var dx = (geo.width != 0) ? newGeo.width / geo.width : 1;
var dy = (geo.height != 0) ? newGeo.height / geo.height : 1;
var childCount = this.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
this.scaleCell(this.model.getChildAt(cell, i), dx, dy, true);
}
};
mxGraph.prototype.constrainChildCells = function(cell)
{
var childCount = this.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
this.constrainChild(this.model.getChildAt(cell, i));
}
};
mxGraph.prototype.scaleCell = function(cell, dx, dy, recurse)
{
var geo = this.model.getGeometry(cell);
if (geo != null)
{
var style = this.getCurrentCellStyle(cell);
geo = geo.clone();
var x = geo.x;
var y = geo.y;
var w = geo.width;
var h = geo.height;
geo.scale(dx, dy, style[mxConstants.STYLE_ASPECT] == 'fixed');
if (style[mxConstants.STYLE_RESIZE_WIDTH] == '1')
{
geo.width = w * dx;
}
else if (style[mxConstants.STYLE_RESIZE_WIDTH] == '0')
{
geo.width = w;
}
if (style[mxConstants.STYLE_RESIZE_HEIGHT] == '1')
{
geo.height = h * dy;
}
else if (style[mxConstants.STYLE_RESIZE_HEIGHT] == '0')
{
geo.height = h;
}
if (!this.isCellMovable(cell))
{
geo.x = x;
geo.y = y;
}
if (!this.isCellResizable(cell))
{
geo.width = w;
geo.height = h;
}
if (this.model.isVertex(cell))
{
this.cellResized(cell, geo, true, recurse);
}
else
{
this.model.setGeometry(cell, geo);
}
}
};
mxGraph.prototype.extendParent = function(cell)
{
if (cell != null)
{
var parent = this.model.getParent(cell);
var p = this.getCellGeometry(parent);
if (parent != null && p != null && !this.isCellCollapsed(parent))
{
var geo = this.getCellGeometry(cell);
if (geo != null && !geo.relative &&
(p.width < geo.x + geo.width ||
p.height < geo.y + geo.height))
{
p = p.clone();
p.width = Math.max(p.width, geo.x + geo.width);
p.height = Math.max(p.height, geo.y + geo.height);
this.cellsResized([parent], [p], false);
}
}
}
};
mxGraph.prototype.importCells = function(cells, dx, dy, target, evt, mapping)
{
return this.moveCells(cells, dx, dy, true, target, evt, mapping);
};
mxGraph.prototype.moveCells = function(cells, dx, dy, clone, target, evt, mapping)
{
dx = (dx != null) ? dx : 0;
dy = (dy != null) ? dy : 0;
clone = (clone != null) ? clone : false;
if (cells != null && (dx != 0 || dy != 0 || clone || target != null))
{
cells = this.model.getTopmostCells(cells);
var origCells = cells;
this.model.beginUpdate();
try
{
var dict = new mxDictionary();
for (var i = 0; i < cells.length; i++)
{
dict.put(cells[i], true);
}
var isSelected = mxUtils.bind(this, function(cell)
{
while (cell != null)
{
if (dict.get(cell))
{
return true;
}
cell = this.model.getParent(cell);
}
return false;
});
var checked = [];
for (var i = 0; i < cells.length; i++)
{
var geo = this.getCellGeometry(cells[i]);
var parent = this.model.getParent(cells[i]);
if ((geo == null || !geo.relative) || !this.model.isEdge(parent) ||
(!isSelected(this.model.getTerminal(parent, true)) &&
!isSelected(this.model.getTerminal(parent, false))))
{
checked.push(cells[i]);
}
}
cells = checked;
if (clone)
{
cells = this.cloneCells(cells, this.isCloneInvalidEdges(), mapping);
if (target == null)
{
target = this.getDefaultParent();
}
}
var previous = this.isAllowNegativeCoordinates();
if (target != null)
{
this.setAllowNegativeCoordinates(true);
}
this.cellsMoved(cells, dx, dy, !clone && this.isDisconnectOnMove()
&& this.isAllowDanglingEdges(), target == null,
this.isExtendParentsOnMove() && target == null);
this.setAllowNegativeCoordinates(previous);
if (target != null)
{
var index = this.model.getChildCount(target);
this.cellsAdded(cells, target, index, null, null, true);
if (clone)
{
for (var i = 0; i < cells.length; i++)
{
var geo = this.getCellGeometry(cells[i]);
var parent = this.model.getParent(origCells[i]);
if (geo != null && geo.relative &&
this.model.isEdge(parent) &&
this.model.contains(parent))
{
this.model.add(parent, cells[i]);
}
}
}
}
this.fireEvent(new mxEventObject(mxEvent.MOVE_CELLS, 'cells', cells,
'dx', dx, 'dy', dy, 'clone', clone, 'target', target, 'event', evt));
}
finally
{
this.model.endUpdate();
}
}
return cells;
};
mxGraph.prototype.cellsMoved = function(cells, dx, dy, disconnect, constrain, extend)
{
if (cells != null && (dx != 0 || dy != 0))
{
extend = (extend != null) ? extend : false;
this.model.beginUpdate();
try
{
if (disconnect)
{
this.disconnectGraph(cells);
}
for (var i = 0; i < cells.length; i++)
{
this.translateCell(cells[i], dx, dy);
if (extend && this.isExtendParent(cells[i]))
{
this.extendParent(cells[i]);
}
else if (constrain)
{
this.constrainChild(cells[i]);
}
}
if (this.resetEdgesOnMove)
{
this.resetEdges(cells);
}
this.fireEvent(new mxEventObject(mxEvent.CELLS_MOVED,
'cells', cells, 'dx', dx, 'dy', dy, 'disconnect', disconnect));
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.translateCell = function(cell, dx, dy)
{
var geo = this.model.getGeometry(cell);
if (geo != null)
{
dx = parseFloat(dx);
dy = parseFloat(dy);
geo = geo.clone();
geo.translate(dx, dy);
if (!geo.relative && this.model.isVertex(cell) && !this.isAllowNegativeCoordinates())
{
geo.x = Math.max(0, parseFloat(geo.x));
geo.y = Math.max(0, parseFloat(geo.y));
}
if (geo.relative && !this.model.isEdge(cell))
{
var parent = this.model.getParent(cell);
var angle = 0;
if (this.model.isVertex(parent))
{
var style = this.getCurrentCellStyle(parent);
angle = mxUtils.getValue(style, mxConstants.STYLE_ROTATION, 0);
}
if (angle != 0)
{
var rad = mxUtils.toRadians(-angle);
var cos = Math.cos(rad);
var sin = Math.sin(rad);
var pt = mxUtils.getRotatedPoint(new mxPoint(dx, dy), cos, sin, new mxPoint(0, 0));
dx = pt.x;
dy = pt.y;
}
if (geo.offset == null)
{
geo.offset = new mxPoint(dx, dy);
}
else
{
geo.offset.x = parseFloat(geo.offset.x) + dx;
geo.offset.y = parseFloat(geo.offset.y) + dy;
}
}
this.model.setGeometry(cell, geo);
}
};
mxGraph.prototype.getCellContainmentArea = function(cell)
{
if (cell != null && !this.model.isEdge(cell))
{
var parent = this.model.getParent(cell);
if (parent != null && parent != this.getDefaultParent())
{
var g = this.model.getGeometry(parent);
if (g != null)
{
var x = 0;
var y = 0;
var w = g.width;
var h = g.height;
if (this.isSwimlane(parent))
{
var size = this.getStartSize(parent);
var style = this.getCurrentCellStyle(parent);
var dir = mxUtils.getValue(style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
var flipH = mxUtils.getValue(style, mxConstants.STYLE_FLIPH, 0) == 1;
var flipV = mxUtils.getValue(style, mxConstants.STYLE_FLIPV, 0) == 1;
if (dir == mxConstants.DIRECTION_SOUTH || dir == mxConstants.DIRECTION_NORTH)
{
var tmp = size.width;
size.width = size.height;
size.height = tmp;
}
if ((dir == mxConstants.DIRECTION_EAST && !flipV) || (dir == mxConstants.DIRECTION_NORTH && !flipH) ||
(dir == mxConstants.DIRECTION_WEST && flipV) || (dir == mxConstants.DIRECTION_SOUTH && flipH))
{
x = size.width;
y = size.height;
}
w -= size.width;
h -= size.height;
}
return new mxRectangle(x, y, w, h);
}
}
}
return null;
};
mxGraph.prototype.getMaximumGraphBounds = function()
{
return this.maximumGraphBounds;
};
mxGraph.prototype.constrainChild = function(cell, sizeFirst)
{
if (cell != null)
{
var geo = this.getCellGeometry(cell);
if (geo != null && (this.isConstrainRelativeChildren() || !geo.relative))
{
var parent = this.model.getParent(cell);
this.getCellGeometry(parent);
var max = this.getMaximumGraphBounds();
if (max != null)
{
var off = this.getBoundingBoxFromGeometry([parent], false);
if (off != null)
{
max = mxRectangle.fromRectangle(max);
max.x -= off.x;
max.y -= off.y;
}
}
if (this.isConstrainChild(cell))
{
var tmp = this.getCellContainmentArea(cell);
if (tmp != null)
{
var overlap = this.getOverlap(cell);
if (overlap > 0)
{
tmp = mxRectangle.fromRectangle(tmp);
tmp.x -= tmp.width * overlap;
tmp.y -= tmp.height * overlap;
tmp.width += 2 * tmp.width * overlap;
tmp.height += 2 * tmp.height * overlap;
}
if (max == null)
{
max = tmp;
}
else
{
max = mxRectangle.fromRectangle(max);
max.intersect(tmp);
}
}
}
if (max != null)
{
var cells = [cell];
if (!this.isCellCollapsed(cell))
{
var desc = this.model.getDescendants(cell);
for (var i = 0; i < desc.length; i++)
{
if (this.isCellVisible(desc[i]))
{
cells.push(desc[i]);
}
}
}
var bbox = this.getBoundingBoxFromGeometry(cells, false);
if (bbox != null)
{
geo = geo.clone();
var dx = 0;
if (geo.width > max.width)
{
dx = geo.width - max.width;
geo.width -= dx;
}
if (bbox.x + bbox.width > max.x + max.width)
{
dx -= bbox.x + bbox.width - max.x - max.width - dx;
}
var dy = 0;
if (geo.height > max.height)
{
dy = geo.height - max.height;
geo.height -= dy;
}
if (bbox.y + bbox.height > max.y + max.height)
{
dy -= bbox.y + bbox.height - max.y - max.height - dy;
}
if (bbox.x < max.x)
{
dx -= bbox.x - max.x;
}
if (bbox.y < max.y)
{
dy -= bbox.y - max.y;
}
if (dx != 0 || dy != 0)
{
if (geo.relative)
{
if (geo.offset == null)
{
geo.offset = new mxPoint();
}
geo.offset.x += dx;
geo.offset.y += dy;
}
else
{
geo.x += dx;
geo.y += dy;
}
}
this.model.setGeometry(cell, geo);
}
}
}
}
};
mxGraph.prototype.resetEdges = function(cells)
{
if (cells != null)
{
var dict = new mxDictionary();
for (var i = 0; i < cells.length; i++)
{
dict.put(cells[i], true);
}
this.model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
var edges = this.model.getEdges(cells[i]);
if (edges != null)
{
for (var j = 0; j < edges.length; j++)
{
var state = this.view.getState(edges[j]);
var source = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[j], true);
var target = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[j], false);
if (!dict.get(source) || !dict.get(target))
{
this.resetEdge(edges[j]);
}
}
}
this.resetEdges(this.model.getChildren(cells[i]));
}
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.resetEdge = function(edge)
{
var geo = this.model.getGeometry(edge);
if (geo != null && geo.points != null && geo.points.length > 0)
{
geo = geo.clone();
geo.points = [];
this.model.setGeometry(edge, geo);
}
return edge;
};
mxGraph.prototype.getOutlineConstraint = function(point, terminalState, me)
{
if (terminalState.shape != null)
{
var bounds = this.view.getPerimeterBounds(terminalState);
var direction = terminalState.style[mxConstants.STYLE_DIRECTION];
if (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH)
{
bounds.x += bounds.width / 2 - bounds.height / 2;
bounds.y += bounds.height / 2 - bounds.width / 2;
var tmp = bounds.width;
bounds.width = bounds.height;
bounds.height = tmp;
}
var alpha = mxUtils.toRadians(terminalState.shape.getShapeRotation());
if (alpha != 0)
{
var cos = Math.cos(-alpha);
var sin = Math.sin(-alpha);
var ct = new mxPoint(bounds.getCenterX(), bounds.getCenterY());
point = mxUtils.getRotatedPoint(point, cos, sin, ct);
}
var sx = 1;
var sy = 1;
var dx = 0;
var dy = 0;
if (this.getModel().isVertex(terminalState.cell))
{
var flipH = terminalState.style[mxConstants.STYLE_FLIPH];
var flipV = terminalState.style[mxConstants.STYLE_FLIPV];
if (terminalState.shape != null && terminalState.shape.stencil != null)
{
flipH = mxUtils.getValue(terminalState.style, 'stencilFlipH', 0) == 1 || flipH;
flipV = mxUtils.getValue(terminalState.style, 'stencilFlipV', 0) == 1 || flipV;
}
if (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH)
{
var tmp = flipH;
flipH = flipV;
flipV = tmp;
}
if (flipH)
{
sx = -1;
dx = -bounds.width;
}
if (flipV)
{
sy = -1;
dy = -bounds.height ;
}
}
point = new mxPoint((point.x - bounds.x) * sx - dx + bounds.x, (point.y - bounds.y) * sy - dy + bounds.y);
var x = (bounds.width == 0) ? 0 : Math.round((point.x - bounds.x) * 1000 / bounds.width) / 1000;
var y = (bounds.height == 0) ? 0 : Math.round((point.y - bounds.y) * 1000 / bounds.height) / 1000;
return new mxConnectionConstraint(new mxPoint(x, y), false);
}
return null;
};
mxGraph.prototype.getAllConnectionConstraints = function(terminal, source)
{
if (terminal != null && terminal.shape != null && terminal.shape.stencil != null)
{
return terminal.shape.stencil.constraints;
}
return null;
};
mxGraph.prototype.getConnectionConstraint = function(edge, terminal, source)
{
var point = null;
var x = edge.style[(source) ? mxConstants.STYLE_EXIT_X : mxConstants.STYLE_ENTRY_X];
if (x != null)
{
var y = edge.style[(source) ? mxConstants.STYLE_EXIT_Y : mxConstants.STYLE_ENTRY_Y];
if (y != null)
{
point = new mxPoint(parseFloat(x), parseFloat(y));
}
}
var perimeter = false;
var dx = 0, dy = 0;
if (point != null)
{
perimeter = mxUtils.getValue(edge.style, (source) ? mxConstants.STYLE_EXIT_PERIMETER :
mxConstants.STYLE_ENTRY_PERIMETER, true);
dx = parseFloat(edge.style[(source) ? mxConstants.STYLE_EXIT_DX : mxConstants.STYLE_ENTRY_DX]);
dy = parseFloat(edge.style[(source) ? mxConstants.STYLE_EXIT_DY : mxConstants.STYLE_ENTRY_DY]);
dx = isFinite(dx)? dx : 0;
dy = isFinite(dy)? dy : 0;
}
return new mxConnectionConstraint(point, perimeter, null, dx, dy);
};
mxGraph.prototype.setConnectionConstraint = function(edge, terminal, source, constraint)
{
if (constraint != null)
{
this.model.beginUpdate();
try
{
if (constraint == null || constraint.point == null)
{
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_X :
mxConstants.STYLE_ENTRY_X, null, [edge]);
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_Y :
mxConstants.STYLE_ENTRY_Y, null, [edge]);
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_DX :
mxConstants.STYLE_ENTRY_DX, null, [edge]);
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_DY :
mxConstants.STYLE_ENTRY_DY, null, [edge]);
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_PERIMETER :
mxConstants.STYLE_ENTRY_PERIMETER, null, [edge]);
}
else if (constraint.point != null)
{
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_X :
mxConstants.STYLE_ENTRY_X, constraint.point.x, [edge]);
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_Y :
mxConstants.STYLE_ENTRY_Y, constraint.point.y, [edge]);
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_DX :
mxConstants.STYLE_ENTRY_DX, constraint.dx, [edge]);
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_DY :
mxConstants.STYLE_ENTRY_DY, constraint.dy, [edge]);
if (!constraint.perimeter)
{
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_PERIMETER :
mxConstants.STYLE_ENTRY_PERIMETER, '0', [edge]);
}
else
{
this.setCellStyles((source) ? mxConstants.STYLE_EXIT_PERIMETER :
mxConstants.STYLE_ENTRY_PERIMETER, null, [edge]);
}
}
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.getConnectionPoint = function(vertex, constraint, round)
{
round = (round != null) ? round : true;
var point = null;
if (vertex != null && constraint.point != null)
{
var bounds = this.view.getPerimeterBounds(vertex);
var cx = new mxPoint(bounds.getCenterX(), bounds.getCenterY());
var direction = vertex.style[mxConstants.STYLE_DIRECTION];
var r1 = 0;
if (direction != null && mxUtils.getValue(vertex.style,
mxConstants.STYLE_ANCHOR_POINT_DIRECTION, 1) == 1)
{
if (direction == mxConstants.DIRECTION_NORTH)
{
r1 += 270;
}
else if (direction == mxConstants.DIRECTION_WEST)
{
r1 += 180;
}
else if (direction == mxConstants.DIRECTION_SOUTH)
{
r1 += 90;
}
if (direction == mxConstants.DIRECTION_NORTH ||
direction == mxConstants.DIRECTION_SOUTH)
{
bounds.rotate90();
}
}
var scale = this.view.scale;
point = new mxPoint(bounds.x + constraint.point.x * bounds.width + constraint.dx * scale,
bounds.y + constraint.point.y * bounds.height + constraint.dy * scale);
var r2 = vertex.style[mxConstants.STYLE_ROTATION] || 0;
if (constraint.perimeter)
{
if (r1 != 0)
{
var cos = 0;
var sin = 0;
if (r1 == 90)
{
sin = 1;
}
else if (r1 == 180)
{
cos = -1;
}
else if (r1 == 270)
{
sin = -1;
}
point = mxUtils.getRotatedPoint(point, cos, sin, cx);
}
point = this.view.getPerimeterPoint(vertex, point, false);
}
else
{
r2 += r1;
if (this.getModel().isVertex(vertex.cell))
{
var flipH = vertex.style[mxConstants.STYLE_FLIPH] == 1;
var flipV = vertex.style[mxConstants.STYLE_FLIPV] == 1;
if (vertex.shape != null && vertex.shape.stencil != null)
{
flipH = (mxUtils.getValue(vertex.style, 'stencilFlipH', 0) == 1) || flipH;
flipV = (mxUtils.getValue(vertex.style, 'stencilFlipV', 0) == 1) || flipV;
}
if (direction == mxConstants.DIRECTION_NORTH ||
direction == mxConstants.DIRECTION_SOUTH)
{
var temp = flipH;
flipH = flipV;
flipV = temp;
}
if (flipH)
{
point.x = 2 * bounds.getCenterX() - point.x;
}
if (flipV)
{
point.y = 2 * bounds.getCenterY() - point.y;
}
}
}
if (r2 != 0 && point != null)
{
var rad = mxUtils.toRadians(r2);
var cos = Math.cos(rad);
var sin = Math.sin(rad);
point = mxUtils.getRotatedPoint(point, cos, sin, cx);
}
}
if (round && point != null)
{
point.x = Math.round(point.x);
point.y = Math.round(point.y);
}
return point;
};
mxGraph.prototype.connectCell = function(edge, terminal, source, constraint)
{
this.model.beginUpdate();
try
{
var previous = this.model.getTerminal(edge, source);
this.cellConnected(edge, terminal, source, constraint);
this.fireEvent(new mxEventObject(mxEvent.CONNECT_CELL,
'edge', edge, 'terminal', terminal, 'source', source,
'previous', previous));
}
finally
{
this.model.endUpdate();
}
return edge;
};
mxGraph.prototype.cellConnected = function(edge, terminal, source, constraint)
{
if (edge != null)
{
this.model.beginUpdate();
try
{
var previous = this.model.getTerminal(edge, source);
this.setConnectionConstraint(edge, terminal, source, constraint);
if (this.isPortsEnabled())
{
var id = null;
if (this.isPort(terminal))
{
id = terminal.getId();
terminal = this.getTerminalForPort(terminal, source);
}
var key = (source) ? mxConstants.STYLE_SOURCE_PORT :
mxConstants.STYLE_TARGET_PORT;
this.setCellStyles(key, id, [edge]);
}
this.model.setTerminal(edge, terminal, source);
if (this.resetEdgesOnConnect)
{
this.resetEdge(edge);
}
this.fireEvent(new mxEventObject(mxEvent.CELL_CONNECTED,
'edge', edge, 'terminal', terminal, 'source', source,
'previous', previous));
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.disconnectGraph = function(cells)
{
if (cells != null)
{
this.model.beginUpdate();
try
{
var scale = this.view.scale;
var tr = this.view.translate;
var dict = new mxDictionary();
for (var i = 0; i < cells.length; i++)
{
dict.put(cells[i], true);
}
for (var i = 0; i < cells.length; i++)
{
if (this.model.isEdge(cells[i]))
{
var geo = this.model.getGeometry(cells[i]);
if (geo != null)
{
var state = this.view.getState(cells[i]);
var pstate = this.view.getState(
this.model.getParent(cells[i]));
if (state != null &&
pstate != null)
{
geo = geo.clone();
var dx = -pstate.origin.x;
var dy = -pstate.origin.y;
var pts = state.absolutePoints;
var src = this.model.getTerminal(cells[i], true);
if (src != null && this.isCellDisconnectable(cells[i], src, true))
{
while (src != null && !dict.get(src))
{
src = this.model.getParent(src);
}
if (src == null)
{
geo.setTerminalPoint(
new mxPoint(pts[0].x / scale - tr.x + dx,
pts[0].y / scale - tr.y + dy), true);
this.model.setTerminal(cells[i], null, true);
}
}
var trg = this.model.getTerminal(cells[i], false);
if (trg != null && this.isCellDisconnectable(cells[i], trg, false))
{
while (trg != null && !dict.get(trg))
{
trg = this.model.getParent(trg);
}
if (trg == null)
{
var n = pts.length - 1;
geo.setTerminalPoint(
new mxPoint(pts[n].x / scale - tr.x + dx,
pts[n].y / scale - tr.y + dy), false);
this.model.setTerminal(cells[i], null, false);
}
}
this.model.setGeometry(cells[i], geo);
}
}
}
}
}
finally
{
this.model.endUpdate();
}
}
};
mxGraph.prototype.getCurrentRoot = function()
{
return this.view.currentRoot;
};
mxGraph.prototype.getTranslateForRoot = function(cell)
{
return null;
};
mxGraph.prototype.isPort = function(cell)
{
return false;
};
mxGraph.prototype.getTerminalForPort = function(cell, source)
{
return this.model.getParent(cell);
};
mxGraph.prototype.getChildOffsetForCell = function(cell)
{
return null;
};
mxGraph.prototype.enterGroup = function(cell)
{
cell = cell || this.getSelectionCell();
if (cell != null && this.isValidRoot(cell))
{
this.view.setCurrentRoot(cell);
this.clearSelection();
}
};
mxGraph.prototype.exitGroup = function()
{
var root = this.model.getRoot();
var current = this.getCurrentRoot();
if (current != null)
{
var next = this.model.getParent(current);
while (next != root && !this.isValidRoot(next) &&
this.model.getParent(next) != root)
{
next = this.model.getParent(next);
}
if (next == root || this.model.getParent(next) == root)
{
this.view.setCurrentRoot(null);
}
else
{
this.view.setCurrentRoot(next);
}
var state = this.view.getState(current);
if (state != null)
{
this.setSelectionCell(current);
}
}
};
mxGraph.prototype.home = function()
{
var current = this.getCurrentRoot();
if (current != null)
{
this.view.setCurrentRoot(null);
var state = this.view.getState(current);
if (state != null)
{
this.setSelectionCell(current);
}
}
};
mxGraph.prototype.isValidRoot = function(cell)
{
return (cell != null);
};
mxGraph.prototype.getGraphBounds = function()
{
return this.view.getGraphBounds();
};
mxGraph.prototype.getCellBounds = function(cell, includeEdges, includeDescendants)
{
var cells = [cell];
if (includeEdges)
{
cells = cells.concat(this.model.getEdges(cell));
}
var result = this.view.getBounds(cells);
if (includeDescendants)
{
var childCount = this.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var tmp = this.getCellBounds(this.model.getChildAt(cell, i),
includeEdges, true);
if (result != null)
{
result.add(tmp);
}
else
{
result = tmp;
}
}
}
return result;
};
mxGraph.prototype.getBoundingBoxFromGeometry = function(cells, includeEdges)
{
includeEdges = (includeEdges != null) ? includeEdges : false;
var result = null;
if (cells != null)
{
for (var i = 0; i < cells.length; i++)
{
if (includeEdges || this.model.isVertex(cells[i]))
{
var geo = this.getCellGeometry(cells[i]);
if (geo != null)
{
var bbox = null;
if (this.model.isEdge(cells[i]))
{
var addPoint = function(pt)
{
if (pt != null)
{
if (tmp == null)
{
tmp = new mxRectangle(pt.x, pt.y, 0, 0);
}
else
{
tmp.add(new mxRectangle(pt.x, pt.y, 0, 0));
}
}
};
if (this.model.getTerminal(cells[i], true) == null)
{
addPoint(geo.getTerminalPoint(true));
}
if (this.model.getTerminal(cells[i], false) == null)
{
addPoint(geo.getTerminalPoint(false));
}
var pts = geo.points;
if (pts != null && pts.length > 0)
{
var tmp = new mxRectangle(pts[0].x, pts[0].y, 0, 0);
for (var j = 1; j < pts.length; j++)
{
addPoint(pts[j]);
}
}
bbox = tmp;
}
else
{
var parent = this.model.getParent(cells[i]);
if (geo.relative)
{
if (this.model.isVertex(parent) && parent != this.view.currentRoot)
{
var tmp = this.getBoundingBoxFromGeometry([parent], false);
if (tmp != null)
{
bbox = new mxRectangle(geo.x * tmp.width, geo.y * tmp.height, geo.width, geo.height);
if (mxUtils.indexOf(cells, parent) >= 0)
{
bbox.x += tmp.x;
bbox.y += tmp.y;
}
}
}
}
else
{
bbox = mxRectangle.fromRectangle(geo);
if (this.model.isVertex(parent) && mxUtils.indexOf(cells, parent) >= 0)
{
var tmp = this.getBoundingBoxFromGeometry([parent], false);
if (tmp != null)
{
bbox.x += tmp.x;
bbox.y += tmp.y;
}
}
}
if (bbox != null && geo.offset != null)
{
bbox.x += geo.offset.x;
bbox.y += geo.offset.y;
}
var style = this.getCurrentCellStyle(cells[i]);
if (bbox != null)
{
var angle = mxUtils.getValue(style, mxConstants.STYLE_ROTATION, 0);
if (angle != 0)
{
bbox = mxUtils.getBoundingBox(bbox, angle);
}
}
}
if (bbox != null)
{
if (result == null)
{
result = mxRectangle.fromRectangle(bbox);
}
else
{
result.add(bbox);
}
}
}
}
}
}
return result;
};
mxGraph.prototype.refresh = function(cell)
{
this.view.clear(cell, cell == null);
this.view.validate();
this.sizeDidChange();
this.fireEvent(new mxEventObject(mxEvent.REFRESH));
};
mxGraph.prototype.snap = function(value)
{
if (this.gridEnabled)
{
value = Math.round(value / this.gridSize ) * this.gridSize;
}
return value;
};
mxGraph.prototype.snapDelta = function(delta, bounds, ignoreGrid, ignoreHorizontal, ignoreVertical)
{
var t = this.view.translate;
var s = this.view.scale;
if (!ignoreGrid && this.gridEnabled)
{
var tol = this.gridSize * s * 0.5;
if (!ignoreHorizontal)
{
var tx = bounds.x - (this.snap(bounds.x / s - t.x) + t.x) * s;
if (Math.abs(delta.x- tx) < tol)
{
delta.x = 0;
}
else
{
delta.x = this.snap(delta.x / s) * s - tx;
}
}
if (!ignoreVertical)
{
var ty = bounds.y - (this.snap(bounds.y / s - t.y) + t.y) * s;
if (Math.abs(delta.y - ty) < tol)
{
delta.y = 0;
}
else
{
delta.y = this.snap(delta.y / s) * s - ty;
}
}
}
else
{
var tol = 0.5 * s;
if (!ignoreHorizontal)
{
var tx = bounds.x - (Math.round(bounds.x / s - t.x) + t.x) * s;
if (Math.abs(delta.x - tx) < tol)
{
delta.x = 0;
}
else
{
delta.x = Math.round(delta.x / s) * s - tx;
}
}
if (!ignoreVertical)
{
var ty = bounds.y - (Math.round(bounds.y / s - t.y) + t.y) * s;
if (Math.abs(delta.y - ty) < tol)
{
delta.y = 0;
}
else
{
delta.y = Math.round(delta.y / s) * s - ty;
}
}
}
return delta;
};
mxGraph.prototype.panGraph = function(dx, dy)
{
if (this.useScrollbarsForPanning && mxUtils.hasScrollbars(this.container))
{
this.container.scrollLeft = -dx;
this.container.scrollTop = -dy;
}
else
{
var canvas = this.view.getCanvas();
if (this.dialect == mxConstants.DIALECT_SVG)
{
if (dx == 0 && dy == 0)
{
if (mxClient.IS_IE)
{
canvas.setAttribute('transform', 'translate(' + dx + ',' + dy + ')');
}
else
{
canvas.removeAttribute('transform');
}
if (this.shiftPreview1 != null)
{
var child = this.shiftPreview1.firstChild;
while (child != null)
{
var next = child.nextSibling;
this.container.appendChild(child);
child = next;
}
if (this.shiftPreview1.parentNode != null)
{
this.shiftPreview1.parentNode.removeChild(this.shiftPreview1);
}
this.shiftPreview1 = null;
this.container.appendChild(canvas.parentNode);
child = this.shiftPreview2.firstChild;
while (child != null)
{
var next = child.nextSibling;
this.container.appendChild(child);
child = next;
}
if (this.shiftPreview2.parentNode != null)
{
this.shiftPreview2.parentNode.removeChild(this.shiftPreview2);
}
this.shiftPreview2 = null;
}
}
else
{
canvas.setAttribute('transform', 'translate(' + dx + ',' + dy + ')');
if (this.shiftPreview1 == null)
{
this.shiftPreview1 = document.createElement('div');
this.shiftPreview1.style.position = 'absolute';
this.shiftPreview1.style.overflow = 'visible';
this.shiftPreview2 = document.createElement('div');
this.shiftPreview2.style.position = 'absolute';
this.shiftPreview2.style.overflow = 'visible';
var current = this.shiftPreview1;
var child = this.container.firstChild;
while (child != null)
{
var next = child.nextSibling;
if (child != canvas.parentNode)
{
current.appendChild(child);
}
else
{
current = this.shiftPreview2;
}
child = next;
}
if (this.shiftPreview1.firstChild != null)
{
this.container.insertBefore(this.shiftPreview1, canvas.parentNode);
}
if (this.shiftPreview2.firstChild != null)
{
this.container.appendChild(this.shiftPreview2);
}
}
this.shiftPreview1.style.left = dx + 'px';
this.shiftPreview1.style.top = dy + 'px';
this.shiftPreview2.style.left = dx + 'px';
this.shiftPreview2.style.top = dy + 'px';
}
}
else
{
canvas.style.left = dx + 'px';
canvas.style.top = dy + 'px';
}
this.panDx = dx;
this.panDy = dy;
this.fireEvent(new mxEventObject(mxEvent.PAN));
}
};
mxGraph.prototype.zoomIn = function()
{
this.zoom(this.zoomFactor);
};
mxGraph.prototype.zoomOut = function()
{
this.zoom(1 / this.zoomFactor);
};
mxGraph.prototype.zoomActual = function()
{
if (this.view.scale == 1)
{
this.view.setTranslate(0, 0);
}
else
{
this.view.translate.x = 0;
this.view.translate.y = 0;
this.view.setScale(1);
}
};
mxGraph.prototype.zoomTo = function(scale, center)
{
this.zoom(scale / this.view.scale, center);
};
mxGraph.prototype.center = function(horizontal, vertical, cx, cy)
{
horizontal = (horizontal != null) ? horizontal : true;
vertical = (vertical != null) ? vertical : true;
cx = (cx != null) ? cx : 0.5;
cy = (cy != null) ? cy : 0.5;
var hasScrollbars = mxUtils.hasScrollbars(this.container);
var padding = 2 * this.getBorder();
var cw = this.container.clientWidth - padding;
var ch = this.container.clientHeight - padding;
var bounds = this.getGraphBounds();
var t = this.view.translate;
var s = this.view.scale;
var dx = (horizontal) ? cw - bounds.width : 0;
var dy = (vertical) ? ch - bounds.height : 0;
if (!hasScrollbars)
{
this.view.setTranslate((horizontal) ? Math.floor(t.x - bounds.x * s + dx * cx / s) : t.x,
(vertical) ? Math.floor(t.y - bounds.y * s + dy * cy / s) : t.y);
}
else
{
bounds.x -= t.x;
bounds.y -= t.y;
var sw = this.container.scrollWidth;
var sh = this.container.scrollHeight;
if (sw > cw)
{
dx = 0;
}
if (sh > ch)
{
dy = 0;
}
this.view.setTranslate(Math.floor(dx / 2 - bounds.x), Math.floor(dy / 2 - bounds.y));
this.container.scrollLeft = (sw - cw) / 2;
this.container.scrollTop = (sh - ch) / 2;
}
};
mxGraph.prototype.zoom = function(factor, center)
{
center = (center != null) ? center : this.centerZoom;
var scale = Math.round(this.view.scale * factor * 100) / 100;
var state = this.view.getState(this.getSelectionCell());
factor = scale / this.view.scale;
if (this.keepSelectionVisibleOnZoom && state != null)
{
var rect = new mxRectangle(state.x * factor, state.y * factor,
state.width * factor, state.height * factor);
this.view.scale = scale;
if (!this.scrollRectToVisible(rect))
{
this.view.revalidate();
this.view.setScale(scale);
}
}
else
{
var hasScrollbars = mxUtils.hasScrollbars(this.container);
if (center && !hasScrollbars)
{
var dx = this.container.offsetWidth;
var dy = this.container.offsetHeight;
if (factor > 1)
{
var f = (factor - 1) / (scale * 2);
dx *= -f;
dy *= -f;
}
else
{
var f = (1 / factor - 1) / (this.view.scale * 2);
dx *= f;
dy *= f;
}
this.view.scaleAndTranslate(scale,
this.view.translate.x + dx,
this.view.translate.y + dy);
}
else
{
var tx = this.view.translate.x;
var ty = this.view.translate.y;
var sl = this.container.scrollLeft;
var st = this.container.scrollTop;
this.view.setScale(scale);
if (hasScrollbars)
{
var dx = 0;
var dy = 0;
if (center)
{
dx = this.container.offsetWidth * (factor - 1) / 2;
dy = this.container.offsetHeight * (factor - 1) / 2;
}
this.container.scrollLeft = (this.view.translate.x - tx) * this.view.scale + Math.round(sl * factor + dx);
this.container.scrollTop = (this.view.translate.y - ty) * this.view.scale + Math.round(st * factor + dy);
}
}
}
};
mxGraph.prototype.zoomToRect = function(rect)
{
var scaleX = this.container.clientWidth / rect.width;
var scaleY = this.container.clientHeight / rect.height;
var aspectFactor = scaleX / scaleY;
rect.x = Math.max(0, rect.x);
rect.y = Math.max(0, rect.y);
var rectRight = Math.min(this.container.scrollWidth, rect.x + rect.width);
var rectBottom = Math.min(this.container.scrollHeight, rect.y + rect.height);
rect.width = rectRight - rect.x;
rect.height = rectBottom - rect.y;
if (aspectFactor < 1.0)
{
var newHeight = rect.height / aspectFactor;
var deltaHeightBuffer = (newHeight - rect.height) / 2.0;
rect.height = newHeight;
var upperBuffer = Math.min(rect.y , deltaHeightBuffer);
rect.y = rect.y - upperBuffer;
rectBottom = Math.min(this.container.scrollHeight, rect.y + rect.height);
rect.height = rectBottom - rect.y;
}
else
{
var newWidth = rect.width * aspectFactor;
var deltaWidthBuffer = (newWidth - rect.width) / 2.0;
rect.width = newWidth;
var leftBuffer = Math.min(rect.x , deltaWidthBuffer);
rect.x = rect.x - leftBuffer;
rectRight = Math.min(this.container.scrollWidth, rect.x + rect.width);
rect.width = rectRight - rect.x;
}
var scale = this.container.clientWidth / rect.width;
var newScale = this.view.scale * scale;
if (!mxUtils.hasScrollbars(this.container))
{
this.view.scaleAndTranslate(newScale, (this.view.translate.x - rect.x / this.view.scale), (this.view.translate.y - rect.y / this.view.scale));
}
else
{
this.view.setScale(newScale);
this.container.scrollLeft = Math.round(rect.x * scale);
this.container.scrollTop = Math.round(rect.y * scale);
}
};
mxGraph.prototype.scrollCellToVisible = function(cell, center)
{
var x = -this.view.translate.x;
var y = -this.view.translate.y;
var state = this.view.getState(cell);
if (state != null)
{
var bounds = new mxRectangle(x + state.x, y + state.y, state.width,
state.height);
if (center && this.container != null)
{
var w = this.container.clientWidth;
var h = this.container.clientHeight;
bounds.x = bounds.getCenterX() - w / 2;
bounds.width = w;
bounds.y = bounds.getCenterY() - h / 2;
bounds.height = h;
}
var tr = new mxPoint(this.view.translate.x, this.view.translate.y);
if (this.scrollRectToVisible(bounds))
{
var tr2 = new mxPoint(this.view.translate.x, this.view.translate.y);
this.view.translate.x = tr.x;
this.view.translate.y = tr.y;
this.view.setTranslate(tr2.x, tr2.y);
}
}
};
mxGraph.prototype.scrollRectToVisible = function(rect)
{
var isChanged = false;
if (rect != null)
{
var w = this.container.offsetWidth;
var h = this.container.offsetHeight;
var widthLimit = Math.min(w, rect.width);
var heightLimit = Math.min(h, rect.height);
if (mxUtils.hasScrollbars(this.container))
{
var c = this.container;
rect.x += this.view.translate.x;
rect.y += this.view.translate.y;
var dx = c.scrollLeft - rect.x;
var ddx = Math.max(dx - c.scrollLeft, 0);
if (dx > 0)
{
c.scrollLeft -= dx + 2;
}
else
{
dx = rect.x + widthLimit - c.scrollLeft - c.clientWidth;
if (dx > 0)
{
c.scrollLeft += dx + 2;
}
}
var dy = c.scrollTop - rect.y;
var ddy = Math.max(0, dy - c.scrollTop);
if (dy > 0)
{
c.scrollTop -= dy + 2;
}
else
{
dy = rect.y + heightLimit - c.scrollTop - c.clientHeight;
if (dy > 0)
{
c.scrollTop += dy + 2;
}
}
if (!this.useScrollbarsForPanning && (ddx != 0 || ddy != 0))
{
this.view.setTranslate(ddx, ddy);
}
}
else
{
var x = -this.view.translate.x;
var y = -this.view.translate.y;
var s = this.view.scale;
if (rect.x + widthLimit > x + w)
{
this.view.translate.x -= (rect.x + widthLimit - w - x) / s;
isChanged = true;
}
if (rect.y + heightLimit > y + h)
{
this.view.translate.y -= (rect.y + heightLimit - h - y) / s;
isChanged = true;
}
if (rect.x < x)
{
this.view.translate.x += (x - rect.x) / s;
isChanged = true;
}
if (rect.y < y)
{
this.view.translate.y += (y - rect.y) / s;
isChanged = true;
}
if (isChanged)
{
this.view.refresh();
if (this.selectionCellsHandler != null)
{
this.selectionCellsHandler.refresh();
}
}
}
}
return isChanged;
};
mxGraph.prototype.getCellGeometry = function(cell)
{
return this.model.getGeometry(cell);
};
mxGraph.prototype.isCellVisible = function(cell)
{
return this.model.isVisible(cell);
};
mxGraph.prototype.isCellCollapsed = function(cell)
{
return this.model.isCollapsed(cell);
};
mxGraph.prototype.isCellConnectable = function(cell)
{
return this.model.isConnectable(cell);
};
mxGraph.prototype.isOrthogonal = function(edge)
{
var orthogonal = edge.style[mxConstants.STYLE_ORTHOGONAL];
if (orthogonal != null)
{
return orthogonal;
}
var tmp = this.view.getEdgeStyle(edge);
return tmp == mxEdgeStyle.SegmentConnector ||
tmp == mxEdgeStyle.ElbowConnector ||
tmp == mxEdgeStyle.SideToSide ||
tmp == mxEdgeStyle.TopToBottom ||
tmp == mxEdgeStyle.EntityRelation ||
tmp == mxEdgeStyle.OrthConnector;
};
mxGraph.prototype.isLoop = function(state)
{
var src = state.getVisibleTerminalState(true);
var trg = state.getVisibleTerminalState(false);
return (src != null && src == trg);
};
mxGraph.prototype.isCloneEvent = function(evt)
{
return mxEvent.isControlDown(evt);
};
mxGraph.prototype.isTransparentClickEvent = function(evt)
{
return false;
};
mxGraph.prototype.isToggleEvent = function(evt)
{
return (mxClient.IS_MAC) ? mxEvent.isMetaDown(evt) : mxEvent.isControlDown(evt);
};
mxGraph.prototype.isGridEnabledEvent = function(evt)
{
return evt != null && !mxEvent.isAltDown(evt);
};
mxGraph.prototype.isConstrainedEvent = function(evt)
{
return mxEvent.isShiftDown(evt);
};
mxGraph.prototype.isIgnoreTerminalEvent = function(evt)
{
return false;
};
mxGraph.prototype.validationAlert = function(message)
{
mxUtils.alert(message);
};
mxGraph.prototype.isEdgeValid = function(edge, source, target)
{
return this.getEdgeValidationError(edge, source, target) == null;
};
mxGraph.prototype.getEdgeValidationError = function(edge, source, target)
{
if (edge != null && !this.isAllowDanglingEdges() && (source == null || target == null))
{
return '';
}
if (edge != null && this.model.getTerminal(edge, true) == null &&
this.model.getTerminal(edge, false) == null)
{
return null;
}
if (!this.allowLoops && source == target && source != null)
{
return '';
}
if (!this.isValidConnection(source, target))
{
return '';
}
if (source != null && target != null)
{
var error = '';
if (!this.multigraph)
{
var tmp = this.model.getEdgesBetween(source, target, true);
if (tmp.length > 1 || (tmp.length == 1 && tmp[0] != edge))
{
error += (mxResources.get(this.alreadyConnectedResource) ||
this.alreadyConnectedResource)+'\n';
}
}
var sourceOut = this.model.getDirectedEdgeCount(source, true, edge);
var targetIn = this.model.getDirectedEdgeCount(target, false, edge);
if (this.multiplicities != null)
{
for (var i = 0; i < this.multiplicities.length; i++)
{
var err = this.multiplicities[i].check(this, edge, source,
target, sourceOut, targetIn);
if (err != null)
{
error += err;
}
}
}
var err = this.validateEdge(edge, source, target);
if (err != null)
{
error += err;
}
return (error.length > 0) ? error : null;
}
return (this.allowDanglingEdges) ? null : '';
};
mxGraph.prototype.validateEdge = function(edge, source, target)
{
return null;
};
mxGraph.prototype.validateGraph = function(cell, context)
{
cell = (cell != null) ? cell : this.model.getRoot();
context = (context != null) ? context : new Object();
var isValid = true;
var childCount = this.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var tmp = this.model.getChildAt(cell, i);
var ctx = context;
if (this.isValidRoot(tmp))
{
ctx = new Object();
}
var warn = this.validateGraph(tmp, ctx);
if (warn != null)
{
this.setCellWarning(tmp, warn.replace(/\n/g, '<br>'));
}
else
{
this.setCellWarning(tmp, null);
}
isValid = isValid && warn == null;
}
var warning = '';
if (this.isCellCollapsed(cell) && !isValid)
{
warning += (mxResources.get(this.containsValidationErrorsResource) ||
this.containsValidationErrorsResource) + '\n';
}
if (this.model.isEdge(cell))
{
warning += this.getEdgeValidationError(cell,
this.model.getTerminal(cell, true),
this.model.getTerminal(cell, false)) || '';
}
else
{
warning += this.getCellValidationError(cell) || '';
}
var err = this.validateCell(cell, context);
if (err != null)
{
warning += err;
}
if (this.model.getParent(cell) == null)
{
this.view.validate();
}
return (warning.length > 0 || !isValid) ? warning : null;
};
mxGraph.prototype.getCellValidationError = function(cell)
{
var outCount = this.model.getDirectedEdgeCount(cell, true);
var inCount = this.model.getDirectedEdgeCount(cell, false);
var value = this.model.getValue(cell);
var error = '';
if (this.multiplicities != null)
{
for (var i = 0; i < this.multiplicities.length; i++)
{
var rule = this.multiplicities[i];
if (rule.source && mxUtils.isNode(value, rule.type,
rule.attr, rule.value) && (outCount > rule.max ||
outCount < rule.min))
{
error += rule.countError + '\n';
}
else if (!rule.source && mxUtils.isNode(value, rule.type,
rule.attr, rule.value) && (inCount > rule.max ||
inCount < rule.min))
{
error += rule.countError + '\n';
}
}
}
return (error.length > 0) ? error : null;
};
mxGraph.prototype.validateCell = function(cell, context)
{
return null;
};
mxGraph.prototype.getBackgroundImage = function()
{
return this.backgroundImage;
};
mxGraph.prototype.setBackgroundImage = function(image)
{
this.backgroundImage = image;
};
mxGraph.prototype.getFoldingImage = function(state)
{
if (state != null && this.foldingEnabled && !this.getModel().isEdge(state.cell))
{
var tmp = this.isCellCollapsed(state.cell);
if (this.isCellFoldable(state.cell, !tmp))
{
return (tmp) ? this.collapsedImage : this.expandedImage;
}
}
return null;
};
mxGraph.prototype.convertValueToString = function(cell)
{
var value = this.model.getValue(cell);
if (value != null)
{
if (mxUtils.isNode(value))
{
return value.nodeName;
}
else if (typeof(value.toString) == 'function')
{
return value.toString();
}
}
return '';
};
mxGraph.prototype.getLabel = function(cell)
{
var result = '';
if (this.labelsVisible && cell != null)
{
var style = this.getCurrentCellStyle(cell);
if (!mxUtils.getValue(style, mxConstants.STYLE_NOLABEL, false))
{
result = this.convertValueToString(cell);
}
}
return result;
};
mxGraph.prototype.isHtmlLabel = function(cell)
{
return this.isHtmlLabels();
};
mxGraph.prototype.isHtmlLabels = function()
{
return this.htmlLabels;
};
mxGraph.prototype.setHtmlLabels = function(value)
{
this.htmlLabels = value;
};
mxGraph.prototype.isWrapping = function(cell)
{
return this.getCurrentCellStyle(cell)[mxConstants.STYLE_WHITE_SPACE] == 'wrap';
};
mxGraph.prototype.isLabelClipped = function(cell)
{
return this.getCurrentCellStyle(cell)[mxConstants.STYLE_OVERFLOW] == 'hidden';
};
mxGraph.prototype.getTooltip = function(state, node, x, y)
{
var tip = null;
if (state != null)
{
if (state.control != null && (node == state.control.node ||
node.parentNode == state.control.node))
{
tip = this.collapseExpandResource;
tip = mxUtils.htmlEntities(mxResources.get(tip) || tip).replace(/\\n/g, '<br>');
}
if (tip == null && state.overlays != null)
{
state.overlays.visit(function(id, shape)
{
if (tip == null && (node == shape.node || node.parentNode == shape.node))
{
tip = shape.overlay.toString();
}
});
}
if (tip == null)
{
var handler = this.selectionCellsHandler.getHandler(state.cell);
if (handler != null && typeof(handler.getTooltipForNode) == 'function')
{
tip = handler.getTooltipForNode(node);
}
}
if (tip == null)
{
tip = this.getTooltipForCell(state.cell);
}
}
return tip;
};
mxGraph.prototype.getTooltipForCell = function(cell)
{
var tip = null;
if (cell != null && cell.getTooltip != null)
{
tip = cell.getTooltip();
}
else
{
tip = this.convertValueToString(cell);
}
return tip;
};
mxGraph.prototype.getLinkForCell = function(cell)
{
return null;
};
mxGraph.prototype.getCursorForMouseEvent = function(me)
{
return this.getCursorForCell(me.getCell());
};
mxGraph.prototype.getCursorForCell = function(cell)
{
return null;
};
mxGraph.prototype.getStartSize = function(swimlane, ignoreState)
{
var result = new mxRectangle();
var style = this.getCurrentCellStyle(swimlane, ignoreState);
var size = parseInt(mxUtils.getValue(style,
mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE));
if (mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true))
{
result.height = size;
}
else
{
result.width = size;
}
return result;
};
mxGraph.prototype.getSwimlaneDirection = function(style)
{
var dir = mxUtils.getValue(style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
var flipH = mxUtils.getValue(style, mxConstants.STYLE_FLIPH, 0) == 1;
var flipV = mxUtils.getValue(style, mxConstants.STYLE_FLIPV, 0) == 1;
var h = mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true);
var n = (h) ? 0 : 3;
if (dir == mxConstants.DIRECTION_NORTH)
{
n--;
}
else if (dir == mxConstants.DIRECTION_WEST)
{
n += 2;
}
else if (dir == mxConstants.DIRECTION_SOUTH)
{
n += 1;
}
var mod = mxUtils.mod(n, 2);
if (flipH && mod == 1)
{
n += 2;
}
if (flipV && mod == 0)
{
n += 2;
}
return [mxConstants.DIRECTION_NORTH, mxConstants.DIRECTION_EAST,
mxConstants.DIRECTION_SOUTH, mxConstants.DIRECTION_WEST]
[mxUtils.mod(n, 4)];
};
mxGraph.prototype.getActualStartSize = function(swimlane, ignoreState)
{
var result = new mxRectangle();
if (this.isSwimlane(swimlane, ignoreState))
{
var style = this.getCurrentCellStyle(swimlane, ignoreState);
var size = parseInt(mxUtils.getValue(style, mxConstants.STYLE_STARTSIZE,
mxConstants.DEFAULT_STARTSIZE));
var dir = this.getSwimlaneDirection(style);
if (dir == mxConstants.DIRECTION_NORTH)
{
result.y = size;
}
else if (dir == mxConstants.DIRECTION_WEST)
{
result.x = size;
}
else if (dir == mxConstants.DIRECTION_SOUTH)
{
result.height = size;
}
else
{
result.width = size;
}
}
return result;
};
mxGraph.prototype.getImage = function(state)
{
return (state != null && state.style != null) ? state.style[mxConstants.STYLE_IMAGE] : null;
};
mxGraph.prototype.isTransparentState = function(state)
{
var result = false;
if (state != null)
{
var stroke = mxUtils.getValue(state.style, mxConstants.STYLE_STROKECOLOR, mxConstants.NONE);
var fill = mxUtils.getValue(state.style, mxConstants.STYLE_FILLCOLOR, mxConstants.NONE);
result = stroke == mxConstants.NONE && fill == mxConstants.NONE && this.getImage(state) == null;
}
return result;
};
mxGraph.prototype.getVerticalAlign = function(state)
{
return (state != null && state.style != null) ?
(state.style[mxConstants.STYLE_VERTICAL_ALIGN] ||
mxConstants.ALIGN_MIDDLE) : null;
};
mxGraph.prototype.getIndicatorColor = function(state)
{
return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_COLOR] : null;
};
mxGraph.prototype.getIndicatorGradientColor = function(state)
{
return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_GRADIENTCOLOR] : null;
};
mxGraph.prototype.getIndicatorShape = function(state)
{
return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_SHAPE] : null;
};
mxGraph.prototype.getIndicatorImage = function(state)
{
return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_IMAGE] : null;
};
mxGraph.prototype.getBorder = function()
{
return this.border;
};
mxGraph.prototype.setBorder = function(value)
{
this.border = value;
};
mxGraph.prototype.isSwimlane = function(cell, ignoreState)
{
if (cell != null && this.model.getParent(cell) != this.model.getRoot() &&
!this.model.isEdge(cell))
{
return this.getCurrentCellStyle(cell, ignoreState)
[mxConstants.STYLE_SHAPE] == mxConstants.SHAPE_SWIMLANE;
}
return false;
};
mxGraph.prototype.isResizeContainer = function()
{
return this.resizeContainer;
};
mxGraph.prototype.setResizeContainer = function(value)
{
this.resizeContainer = value;
};
mxGraph.prototype.isEnabled = function()
{
return this.enabled;
};
mxGraph.prototype.setEnabled = function(value)
{
this.enabled = value;
};
mxGraph.prototype.isEscapeEnabled = function()
{
return this.escapeEnabled;
};
mxGraph.prototype.setEscapeEnabled = function(value)
{
this.escapeEnabled = value;
};
mxGraph.prototype.isInvokesStopCellEditing = function()
{
return this.invokesStopCellEditing;
};
mxGraph.prototype.setInvokesStopCellEditing = function(value)
{
this.invokesStopCellEditing = value;
};
mxGraph.prototype.isEnterStopsCellEditing = function()
{
return this.enterStopsCellEditing;
};
mxGraph.prototype.setEnterStopsCellEditing = function(value)
{
this.enterStopsCellEditing = value;
};
mxGraph.prototype.isCellLocked = function(cell)
{
var geometry = this.model.getGeometry(cell);
return this.isCellsLocked() || (geometry != null && this.model.isVertex(cell) && geometry.relative);
};
mxGraph.prototype.isCellsLocked = function()
{
return this.cellsLocked;
};
mxGraph.prototype.setCellsLocked = function(value)
{
this.cellsLocked = value;
};
mxGraph.prototype.getCloneableCells = function(cells)
{
return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
{
return this.isCellCloneable(cell);
}));
};
mxGraph.prototype.isCellCloneable = function(cell)
{
var style = this.getCurrentCellStyle(cell);
return this.isCellsCloneable() && style[mxConstants.STYLE_CLONEABLE] != 0;
};
mxGraph.prototype.isCellsCloneable = function()
{
return this.cellsCloneable;
};
mxGraph.prototype.setCellsCloneable = function(value)
{
this.cellsCloneable = value;
};
mxGraph.prototype.getExportableCells = function(cells)
{
return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
{
return this.canExportCell(cell);
}));
};
mxGraph.prototype.canExportCell = function(cell)
{
return this.exportEnabled;
};
mxGraph.prototype.getImportableCells = function(cells)
{
return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
{
return this.canImportCell(cell);
}));
};
mxGraph.prototype.canImportCell = function(cell)
{
return this.importEnabled;
};
mxGraph.prototype.isCellSelectable = function(cell)
{
return this.isCellsSelectable();
};
mxGraph.prototype.isCellsSelectable = function()
{
return this.cellsSelectable;
};
mxGraph.prototype.setCellsSelectable = function(value)
{
this.cellsSelectable = value;
};
mxGraph.prototype.getDeletableCells = function(cells)
{
return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
{
return this.isCellDeletable(cell);
}));
};
mxGraph.prototype.isCellDeletable = function(cell)
{
var style = this.getCurrentCellStyle(cell);
return this.isCellsDeletable() && style[mxConstants.STYLE_DELETABLE] != 0;
};
mxGraph.prototype.isCellsDeletable = function()
{
return this.cellsDeletable;
};
mxGraph.prototype.setCellsDeletable = function(value)
{
this.cellsDeletable = value;
};
mxGraph.prototype.isLabelMovable = function(cell)
{
return !this.isCellLocked(cell) &&
((this.model.isEdge(cell) && this.edgeLabelsMovable) ||
(this.model.isVertex(cell) && this.vertexLabelsMovable));
};
mxGraph.prototype.isCellRotatable = function(cell)
{
var style = this.getCurrentCellStyle(cell);
return style[mxConstants.STYLE_ROTATABLE] != 0;
};
mxGraph.prototype.getMovableCells = function(cells)
{
return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
{
return this.isCellMovable(cell);
}));
};
mxGraph.prototype.isCellMovable = function(cell)
{
var style = this.getCurrentCellStyle(cell);
return this.isCellsMovable() && !this.isCellLocked(cell) && style[mxConstants.STYLE_MOVABLE] != 0;
};
mxGraph.prototype.isCellsMovable = function()
{
return this.cellsMovable;
};
mxGraph.prototype.setCellsMovable = function(value)
{
this.cellsMovable = value;
};
mxGraph.prototype.isGridEnabled = function()
{
return this.gridEnabled;
};
mxGraph.prototype.setGridEnabled = function(value)
{
this.gridEnabled = value;
};
mxGraph.prototype.isPortsEnabled = function()
{
return this.portsEnabled;
};
mxGraph.prototype.setPortsEnabled = function(value)
{
this.portsEnabled = value;
};
mxGraph.prototype.getGridSize = function()
{
return this.gridSize;
};
mxGraph.prototype.setGridSize = function(value)
{
this.gridSize = value;
};
mxGraph.prototype.getTolerance = function()
{
return this.tolerance;
};
mxGraph.prototype.setTolerance = function(value)
{
this.tolerance = value;
};
mxGraph.prototype.isVertexLabelsMovable = function()
{
return this.vertexLabelsMovable;
};
mxGraph.prototype.setVertexLabelsMovable = function(value)
{
this.vertexLabelsMovable = value;
};
mxGraph.prototype.isEdgeLabelsMovable = function()
{
return this.edgeLabelsMovable;
};
mxGraph.prototype.setEdgeLabelsMovable = function(value)
{
this.edgeLabelsMovable = value;
};
mxGraph.prototype.isSwimlaneNesting = function()
{
return this.swimlaneNesting;
};
mxGraph.prototype.setSwimlaneNesting = function(value)
{
this.swimlaneNesting = value;
};
mxGraph.prototype.isSwimlaneSelectionEnabled = function()
{
return this.swimlaneSelectionEnabled;
};
mxGraph.prototype.setSwimlaneSelectionEnabled = function(value)
{
this.swimlaneSelectionEnabled = value;
};
mxGraph.prototype.isMultigraph = function()
{
return this.multigraph;
};
mxGraph.prototype.setMultigraph = function(value)
{
this.multigraph = value;
};
mxGraph.prototype.isAllowLoops = function()
{
return this.allowLoops;
};
mxGraph.prototype.setAllowDanglingEdges = function(value)
{
this.allowDanglingEdges = value;
};
mxGraph.prototype.isAllowDanglingEdges = function()
{
return this.allowDanglingEdges;
};
mxGraph.prototype.setConnectableEdges = function(value)
{
this.connectableEdges = value;
};
mxGraph.prototype.isConnectableEdges = function()
{
return this.connectableEdges;
};
mxGraph.prototype.setCloneInvalidEdges = function(value)
{
this.cloneInvalidEdges = value;
};
mxGraph.prototype.isCloneInvalidEdges = function()
{
return this.cloneInvalidEdges;
};
mxGraph.prototype.setAllowLoops = function(value)
{
this.allowLoops = value;
};
mxGraph.prototype.isDisconnectOnMove = function()
{
return this.disconnectOnMove;
};
mxGraph.prototype.setDisconnectOnMove = function(value)
{
this.disconnectOnMove = value;
};
mxGraph.prototype.isDropEnabled = function()
{
return this.dropEnabled;
};
mxGraph.prototype.setDropEnabled = function(value)
{
this.dropEnabled = value;
};
mxGraph.prototype.isSplitEnabled = function()
{
return this.splitEnabled;
};
mxGraph.prototype.setSplitEnabled = function(value)
{
this.splitEnabled = value;
};
mxGraph.prototype.isCellResizable = function(cell)
{
var style = this.getCurrentCellStyle(cell);
return this.isCellsResizable() && !this.isCellLocked(cell) &&
mxUtils.getValue(style, mxConstants.STYLE_RESIZABLE, '1') != '0';
};
mxGraph.prototype.isCellsResizable = function()
{
return this.cellsResizable;
};
mxGraph.prototype.setCellsResizable = function(value)
{
this.cellsResizable = value;
};
mxGraph.prototype.isTerminalPointMovable = function(cell, source)
{
return true;
};
mxGraph.prototype.isCellBendable = function(cell)
{
var style = this.getCurrentCellStyle(cell);
return this.isCellsBendable() && !this.isCellLocked(cell) && style[mxConstants.STYLE_BENDABLE] != 0;
};
mxGraph.prototype.isCellsBendable = function()
{
return this.cellsBendable;
};
mxGraph.prototype.setCellsBendable = function(value)
{
this.cellsBendable = value;
};
mxGraph.prototype.isCellEditable = function(cell)
{
var style = this.getCurrentCellStyle(cell);
return this.isCellsEditable() && !this.isCellLocked(cell) && style[mxConstants.STYLE_EDITABLE] != 0;
};
mxGraph.prototype.isCellsEditable = function()
{
return this.cellsEditable;
};
mxGraph.prototype.setCellsEditable = function(value)
{
this.cellsEditable = value;
};
mxGraph.prototype.isCellDisconnectable = function(cell, terminal, source)
{
return this.isCellsDisconnectable() && !this.isCellLocked(cell);
};
mxGraph.prototype.isCellsDisconnectable = function()
{
return this.cellsDisconnectable;
};
mxGraph.prototype.setCellsDisconnectable = function(value)
{
this.cellsDisconnectable = value;
};
mxGraph.prototype.isValidSource = function(cell)
{
return (cell == null && this.allowDanglingEdges) ||
(cell != null && (!this.model.isEdge(cell) ||
this.connectableEdges) && this.isCellConnectable(cell));
};
mxGraph.prototype.isValidTarget = function(cell)
{
return this.isValidSource(cell);
};
mxGraph.prototype.isValidConnection = function(source, target)
{
return this.isValidSource(source) && this.isValidTarget(target);
};
mxGraph.prototype.setConnectable = function(connectable)
{
this.connectionHandler.setEnabled(connectable);
};
mxGraph.prototype.isConnectable = function()
{
return this.connectionHandler.isEnabled();
};
mxGraph.prototype.setTooltips = function (enabled)
{
this.tooltipHandler.setEnabled(enabled);
};
mxGraph.prototype.setPanning = function(enabled)
{
this.panningHandler.panningEnabled = enabled;
};
mxGraph.prototype.isEditing = function(cell)
{
if (this.cellEditor != null)
{
var editingCell = this.cellEditor.getEditingCell();
return (cell == null) ? editingCell != null : cell == editingCell;
}
return false;
};
mxGraph.prototype.isAutoSizeCell = function(cell)
{
var style = this.getCurrentCellStyle(cell);
return this.isAutoSizeCells() || style[mxConstants.STYLE_AUTOSIZE] == 1;
};
mxGraph.prototype.isAutoSizeCells = function()
{
return this.autoSizeCells;
};
mxGraph.prototype.setAutoSizeCells = function(value)
{
this.autoSizeCells = value;
};
mxGraph.prototype.isExtendParent = function(cell)
{
return !this.getModel().isEdge(cell) && this.isExtendParents();
};
mxGraph.prototype.isExtendParents = function()
{
return this.extendParents;
};
mxGraph.prototype.setExtendParents = function(value)
{
this.extendParents = value;
};
mxGraph.prototype.isExtendParentsOnAdd = function(cell)
{
return this.extendParentsOnAdd;
};
mxGraph.prototype.setExtendParentsOnAdd = function(value)
{
this.extendParentsOnAdd = value;
};
mxGraph.prototype.isExtendParentsOnMove = function()
{
return this.extendParentsOnMove;
};
mxGraph.prototype.setExtendParentsOnMove = function(value)
{
this.extendParentsOnMove = value;
};
mxGraph.prototype.isRecursiveResize = function(state)
{
return this.recursiveResize;
};
mxGraph.prototype.setRecursiveResize = function(value)
{
this.recursiveResize = value;
};
mxGraph.prototype.isConstrainChild = function(cell)
{
return this.isConstrainChildren() && !this.getModel().isEdge(this.getModel().getParent(cell));
};
mxGraph.prototype.isConstrainChildren = function()
{
return this.constrainChildren;
};
mxGraph.prototype.setConstrainChildren = function(value)
{
this.constrainChildren = value;
};
mxGraph.prototype.isConstrainRelativeChildren = function()
{
return this.constrainRelativeChildren;
};
mxGraph.prototype.setConstrainRelativeChildren = function(value)
{
this.constrainRelativeChildren = value;
};
mxGraph.prototype.isAllowNegativeCoordinates = function()
{
return this.allowNegativeCoordinates;
};
mxGraph.prototype.setAllowNegativeCoordinates = function(value)
{
this.allowNegativeCoordinates = value;
};
mxGraph.prototype.getOverlap = function(cell)
{
return (this.isAllowOverlapParent(cell)) ? this.defaultOverlap : 0;
};
mxGraph.prototype.isAllowOverlapParent = function(cell)
{
return false;
};
mxGraph.prototype.getFoldableCells = function(cells, collapse)
{
return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
{
return this.isCellFoldable(cell, collapse);
}));
};
mxGraph.prototype.isCellFoldable = function(cell, collapse)
{
var style = this.getCurrentCellStyle(cell);
return this.model.getChildCount(cell) > 0 && style[mxConstants.STYLE_FOLDABLE] != 0;
};
mxGraph.prototype.isValidDropTarget = function(cell, cells, evt)
{
return cell != null && ((this.isSplitEnabled() &&
this.isSplitTarget(cell, cells, evt)) || (!this.model.isEdge(cell) &&
(this.isSwimlane(cell) || (this.model.getChildCount(cell) > 0 &&
!this.isCellCollapsed(cell)))));
};
mxGraph.prototype.isSplitTarget = function(target, cells, evt)
{
if (this.model.isEdge(target) && cells != null && cells.length == 1 &&
this.isCellConnectable(cells[0]) && this.getEdgeValidationError(target,
this.model.getTerminal(target, true), cells[0]) == null)
{
var src = this.model.getTerminal(target, true);
var trg = this.model.getTerminal(target, false);
return (!this.model.isAncestor(cells[0], src) &&
!this.model.isAncestor(cells[0], trg));
}
return false;
};
mxGraph.prototype.getDropTarget = function(cells, evt, cell, clone)
{
if (!this.isSwimlaneNesting())
{
for (var i = 0; i < cells.length; i++)
{
if (this.isSwimlane(cells[i]))
{
return null;
}
}
}
var pt = mxUtils.convertPoint(this.container,
mxEvent.getClientX(evt), mxEvent.getClientY(evt));
pt.x -= this.panDx;
pt.y -= this.panDy;
var swimlane = this.getSwimlaneAt(pt.x, pt.y);
if (cell == null)
{
cell = swimlane;
}
else if (swimlane != null)
{
var tmp = this.model.getParent(swimlane);
while (tmp != null && this.isSwimlane(tmp) && tmp != cell)
{
tmp = this.model.getParent(tmp);
}
if (tmp == cell)
{
cell = swimlane;
}
}
while (cell != null && !this.isValidDropTarget(cell, cells, evt) &&
!this.model.isLayer(cell))
{
cell = this.model.getParent(cell);
}
if (clone == null || !clone)
{
var parent = cell;
while (parent != null && mxUtils.indexOf(cells, parent) < 0)
{
parent = this.model.getParent(parent);
}
}
return (!this.model.isLayer(cell) && parent == null) ? cell : null;
};
mxGraph.prototype.getDefaultParent = function()
{
var parent = this.getCurrentRoot();
if (parent == null)
{
parent = this.defaultParent;
if (parent == null)
{
var root = this.model.getRoot();
parent = this.model.getChildAt(root, 0);
}
}
return parent;
};
mxGraph.prototype.setDefaultParent = function(cell)
{
this.defaultParent = cell;
};
mxGraph.prototype.getSwimlane = function(cell)
{
while (cell != null && !this.isSwimlane(cell))
{
cell = this.model.getParent(cell);
}
return cell;
};
mxGraph.prototype.getSwimlaneAt = function (x, y, parent)
{
if (parent == null)
{
parent = this.getCurrentRoot();
if (parent == null)
{
parent = this.model.getRoot();
}
}
if (parent != null)
{
var childCount = this.model.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
var child = this.model.getChildAt(parent, i);
if (child != null)
{
var result = this.getSwimlaneAt(x, y, child);
if (result != null)
{
return result;
}
else if (this.isCellVisible(child) && this.isSwimlane(child))
{
var state = this.view.getState(child);
if (this.intersects(state, x, y))
{
return child;
}
}
}
}
}
return null;
};
mxGraph.prototype.getCellAt = function(x, y, parent, vertices, edges, ignoreFn)
{
vertices = (vertices != null) ? vertices : true;
edges = (edges != null) ? edges : true;
if (parent == null)
{
parent = this.getCurrentRoot();
if (parent == null)
{
parent = this.getModel().getRoot();
}
}
if (parent != null)
{
var childCount = this.model.getChildCount(parent);
for (var i = childCount - 1; i >= 0; i--)
{
var cell = this.model.getChildAt(parent, i);
var result = this.getCellAt(x, y, cell, vertices, edges, ignoreFn);
if (result != null)
{
return result;
}
else if (this.isCellVisible(cell) && (edges && this.model.isEdge(cell) ||
vertices && this.model.isVertex(cell)))
{
var state = this.view.getState(cell);
if (state != null && (ignoreFn == null || !ignoreFn(state, x, y)) &&
this.intersects(state, x, y))
{
return cell;
}
}
}
}
return null;
};
mxGraph.prototype.intersects = function(state, x, y)
{
if (state != null)
{
var pts = state.absolutePoints;
if (pts != null)
{
var t2 = this.tolerance * this.tolerance;
var pt = pts[0];
for (var i = 1; i < pts.length; i++)
{
var next = pts[i];
var dist = mxUtils.ptSegDistSq(pt.x, pt.y, next.x, next.y, x, y);
if (dist <= t2)
{
return true;
}
pt = next;
}
}
else
{
var alpha = mxUtils.toRadians(mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0);
if (alpha != 0)
{
var cos = Math.cos(-alpha);
var sin = Math.sin(-alpha);
var cx = new mxPoint(state.getCenterX(), state.getCenterY());
var pt = mxUtils.getRotatedPoint(new mxPoint(x, y), cos, sin, cx);
x = pt.x;
y = pt.y;
}
if (mxUtils.contains(state, x, y))
{
return true;
}
}
}
return false;
};
mxGraph.prototype.hitsSwimlaneContent = function(swimlane, x, y)
{
var state = this.getView().getState(swimlane);
var size = this.getStartSize(swimlane);
if (state != null)
{
var scale = this.getView().getScale();
x -= state.x;
y -= state.y;
if (size.width > 0 && x > 0 && x > size.width * scale)
{
return true;
}
else if (size.height > 0 && y > 0 && y > size.height * scale)
{
return true;
}
}
return false;
};
mxGraph.prototype.getChildVertices = function(parent)
{
return this.getChildCells(parent, true, false);
};
mxGraph.prototype.getChildEdges = function(parent)
{
return this.getChildCells(parent, false, true);
};
mxGraph.prototype.getChildCells = function(parent, vertices, edges)
{
parent = (parent != null) ? parent : this.getDefaultParent();
vertices = (vertices != null) ? vertices : false;
edges = (edges != null) ? edges : false;
var cells = this.model.getChildCells(parent, vertices, edges);
var result = [];
for (var i = 0; i < cells.length; i++)
{
if (this.isCellVisible(cells[i]))
{
result.push(cells[i]);
}
}
return result;
};
mxGraph.prototype.getConnections = function(cell, parent)
{
return this.getEdges(cell, parent, true, true, false);
};
mxGraph.prototype.getIncomingEdges = function(cell, parent)
{
return this.getEdges(cell, parent, true, false, false);
};
mxGraph.prototype.getOutgoingEdges = function(cell, parent)
{
return this.getEdges(cell, parent, false, true, false);
};
mxGraph.prototype.getEdges = function(cell, parent, incoming, outgoing, includeLoops, recurse)
{
incoming = (incoming != null) ? incoming : true;
outgoing = (outgoing != null) ? outgoing : true;
includeLoops = (includeLoops != null) ? includeLoops : true;
recurse = (recurse != null) ? recurse : false;
var edges = [];
var isCollapsed = this.isCellCollapsed(cell);
var childCount = this.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var child = this.model.getChildAt(cell, i);
if (isCollapsed || !this.isCellVisible(child))
{
edges = edges.concat(this.model.getEdges(child, incoming, outgoing));
}
}
edges = edges.concat(this.model.getEdges(cell, incoming, outgoing));
var result = [];
for (var i = 0; i < edges.length; i++)
{
var state = this.view.getState(edges[i]);
var source = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[i], true);
var target = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[i], false);
if ((includeLoops && source == target) || ((source != target) && ((incoming &&
target == cell && (parent == null || this.isValidAncestor(source, parent, recurse))) ||
(outgoing && source == cell && (parent == null ||
this.isValidAncestor(target, parent, recurse))))))
{
result.push(edges[i]);
}
}
return result;
};
mxGraph.prototype.isValidAncestor = function(cell, parent, recurse)
{
return (recurse ? this.model.isAncestor(parent, cell) : this.model
.getParent(cell) == parent);
};
mxGraph.prototype.getOpposites = function(edges, terminal, sources, targets)
{
sources = (sources != null) ? sources : true;
targets = (targets != null) ? targets : true;
var terminals = [];
var dict = new mxDictionary();
if (edges != null)
{
for (var i = 0; i < edges.length; i++)
{
var state = this.view.getState(edges[i]);
var source = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[i], true);
var target = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[i], false);
if (source == terminal && target != null && target != terminal && targets)
{
if (!dict.get(target))
{
dict.put(target, true);
terminals.push(target);
}
}
else if (target == terminal && source != null && source != terminal && sources)
{
if (!dict.get(source))
{
dict.put(source, true);
terminals.push(source);
}
}
}
}
return terminals;
};
mxGraph.prototype.getEdgesBetween = function(source, target, directed)
{
directed = (directed != null) ? directed : false;
var edges = this.getEdges(source);
var result = [];
for (var i = 0; i < edges.length; i++)
{
var state = this.view.getState(edges[i]);
var src = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[i], true);
var trg = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[i], false);
if ((src == source && trg == target) || (!directed && src == target && trg == source))
{
result.push(edges[i]);
}
}
return result;
};
mxGraph.prototype.getPointForEvent = function(evt, addOffset)
{
var p = mxUtils.convertPoint(this.container,
mxEvent.getClientX(evt), mxEvent.getClientY(evt));
var s = this.view.scale;
var tr = this.view.translate;
var off = (addOffset != false) ? this.gridSize / 2 : 0;
p.x = this.snap(p.x / s - tr.x - off);
p.y = this.snap(p.y / s - tr.y - off);
return p;
};
mxGraph.prototype.getCells = function(x, y, width, height, parent, result, intersection, ignoreFn, includeDescendants)
{
result = (result != null) ? result : [];
if (width > 0 || height > 0 || intersection != null)
{
var model = this.getModel();
var right = x + width;
var bottom = y + height;
if (parent == null)
{
parent = this.getCurrentRoot();
if (parent == null)
{
parent = model.getRoot();
}
}
if (parent != null)
{
var childCount = model.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
var cell = model.getChildAt(parent, i);
var state = this.view.getState(cell);
if (state != null && this.isCellVisible(cell) &&
(ignoreFn == null || !ignoreFn(state)))
{
var deg = mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0;
var box = state;
if (deg != 0)
{
box = mxUtils.getBoundingBox(box, deg);
}
var hit = (intersection != null && model.isVertex(cell) && mxUtils.intersects(intersection, box)) ||
(intersection == null && (model.isEdge(cell) || model.isVertex(cell)) &&
box.x >= x && box.y + box.height <= bottom &&
box.y >= y && box.x + box.width <= right);
if (hit)
{
result.push(cell);
}
if (!hit || includeDescendants)
{
this.getCells(x, y, width, height, cell, result, intersection, ignoreFn, includeDescendants);
}
}
}
}
}
return result;
};
mxGraph.prototype.getCellsBeyond = function(x0, y0, parent, rightHalfpane, bottomHalfpane)
{
var result = [];
if (rightHalfpane || bottomHalfpane)
{
if (parent == null)
{
parent = this.getDefaultParent();
}
if (parent != null)
{
var childCount = this.model.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
var child = this.model.getChildAt(parent, i);
var state = this.view.getState(child);
if (this.isCellVisible(child) && state != null)
{
if ((!rightHalfpane || state.x >= x0) &&
(!bottomHalfpane || state.y >= y0))
{
result.push(child);
}
}
}
}
}
return result;
};
mxGraph.prototype.findTreeRoots = function(parent, isolate, invert)
{
isolate = (isolate != null) ? isolate : false;
invert = (invert != null) ? invert : false;
var roots = [];
if (parent != null)
{
var model = this.getModel();
var childCount = model.getChildCount(parent);
var best = null;
var maxDiff = 0;
for (var i=0; i<childCount; i++)
{
var cell = model.getChildAt(parent, i);
if (this.model.isVertex(cell) && this.isCellVisible(cell))
{
var conns = this.getConnections(cell, (isolate) ? parent : null);
var fanOut = 0;
var fanIn = 0;
for (var j = 0; j < conns.length; j++)
{
var src = this.view.getVisibleTerminal(conns[j], true);
if (src == cell)
{
fanOut++;
}
else
{
fanIn++;
}
}
if ((invert && fanOut == 0 && fanIn > 0) ||
(!invert && fanIn == 0 && fanOut > 0))
{
roots.push(cell);
}
var diff = (invert) ? fanIn - fanOut : fanOut - fanIn;
if (diff > maxDiff)
{
maxDiff = diff;
best = cell;
}
}
}
if (roots.length == 0 && best != null)
{
roots.push(best);
}
}
return roots;
};
mxGraph.prototype.traverse = function(vertex, directed, func, edge, visited, inverse)
{
if (func != null && vertex != null)
{
directed = (directed != null) ? directed : true;
inverse = (inverse != null) ? inverse : false;
visited = visited || new mxDictionary();
if (!visited.get(vertex))
{
visited.put(vertex, true);
var result = func(vertex, edge);
if (result == null || result)
{
var edgeCount = this.model.getEdgeCount(vertex);
if (edgeCount > 0)
{
for (var i = 0; i < edgeCount; i++)
{
var e = this.model.getEdgeAt(vertex, i);
var isSource = this.model.getTerminal(e, true) == vertex;
if (!directed || (!inverse == isSource))
{
var next = this.model.getTerminal(e, !isSource);
this.traverse(next, directed, func, e, visited, inverse);
}
}
}
}
}
}
};
mxGraph.prototype.isCellSelected = function(cell)
{
return this.getSelectionModel().isSelected(cell);
};
mxGraph.prototype.isSelectionEmpty = function()
{
return this.getSelectionModel().isEmpty();
};
mxGraph.prototype.clearSelection = function()
{
return this.getSelectionModel().clear();
};
mxGraph.prototype.getSelectionCount = function()
{
return this.getSelectionModel().cells.length;
};
mxGraph.prototype.getSelectionCell = function()
{
return this.getSelectionModel().cells[0];
};
mxGraph.prototype.getSelectionCells = function()
{
return this.getSelectionModel().cells.slice();
};
mxGraph.prototype.setSelectionCell = function(cell)
{
this.getSelectionModel().setCell(cell);
};
mxGraph.prototype.setSelectionCells = function(cells)
{
this.getSelectionModel().setCells(cells);
};
mxGraph.prototype.addSelectionCell = function(cell)
{
this.getSelectionModel().addCell(cell);
};
mxGraph.prototype.addSelectionCells = function(cells)
{
this.getSelectionModel().addCells(cells);
};
mxGraph.prototype.removeSelectionCell = function(cell)
{
this.getSelectionModel().removeCell(cell);
};
mxGraph.prototype.removeSelectionCells = function(cells)
{
this.getSelectionModel().removeCells(cells);
};
mxGraph.prototype.selectRegion = function(rect, evt)
{
var cells = this.getCells(rect.x, rect.y, rect.width, rect.height);
this.selectCellsForEvent(cells, evt);
return cells;
};
mxGraph.prototype.selectNextCell = function()
{
this.selectCell(true);
};
mxGraph.prototype.selectPreviousCell = function()
{
this.selectCell();
};
mxGraph.prototype.selectParentCell = function()
{
this.selectCell(false, true);
};
mxGraph.prototype.selectChildCell = function()
{
this.selectCell(false, false, true);
};
mxGraph.prototype.selectCell = function(isNext, isParent, isChild)
{
var sel = this.selectionModel;
var cell = (sel.cells.length > 0) ? sel.cells[0] : null;
if (sel.cells.length > 1)
{
sel.clear();
}
var parent = (cell != null) ?
this.model.getParent(cell) :
this.getDefaultParent();
var childCount = this.model.getChildCount(parent);
if (cell == null && childCount > 0)
{
var child = this.model.getChildAt(parent, 0);
this.setSelectionCell(child);
}
else if ((cell == null || isParent) &&
this.view.getState(parent) != null &&
this.model.getGeometry(parent) != null)
{
if (this.getCurrentRoot() != parent)
{
this.setSelectionCell(parent);
}
}
else if (cell != null && isChild)
{
var tmp = this.model.getChildCount(cell);
if (tmp > 0)
{
var child = this.model.getChildAt(cell, 0);
this.setSelectionCell(child);
}
}
else if (childCount > 0)
{
var i = parent.getIndex(cell);
if (isNext)
{
i++;
var child = this.model.getChildAt(parent, i % childCount);
this.setSelectionCell(child);
}
else
{
i--;
var index = (i < 0) ? childCount - 1 : i;
var child = this.model.getChildAt(parent, index);
this.setSelectionCell(child);
}
}
};
mxGraph.prototype.selectAll = function(parent, descendants)
{
parent = parent || this.getDefaultParent();
var cells = (descendants) ? this.model.filterDescendants(mxUtils.bind(this, function(cell)
{
return cell != parent && this.view.getState(cell) != null;
}), parent) : this.model.getChildren(parent);
if (cells != null)
{
this.setSelectionCells(cells);
}
};
mxGraph.prototype.selectVertices = function(parent, selectGroups)
{
this.selectCells(true, false, parent, selectGroups);
};
mxGraph.prototype.selectEdges = function(parent)
{
this.selectCells(false, true, parent);
};
mxGraph.prototype.selectCells = function(vertices, edges, parent, selectGroups)
{
parent = parent || this.getDefaultParent();
var filter = mxUtils.bind(this, function(cell)
{
return this.view.getState(cell) != null &&
(((selectGroups || this.model.getChildCount(cell) == 0) &&
this.model.isVertex(cell) && vertices
&& !this.model.isEdge(this.model.getParent(cell))) ||
(this.model.isEdge(cell) && edges));
});
var cells = this.model.filterDescendants(filter, parent);
if (cells != null)
{
this.setSelectionCells(cells);
}
};
mxGraph.prototype.selectCellForEvent = function(cell, evt)
{
var isSelected = this.isCellSelected(cell);
if (this.isToggleEvent(evt))
{
if (isSelected)
{
this.removeSelectionCell(cell);
}
else
{
this.addSelectionCell(cell);
}
}
else if (!isSelected || this.getSelectionCount() != 1)
{
this.setSelectionCell(cell);
}
};
mxGraph.prototype.selectCellsForEvent = function(cells, evt)
{
if (this.isToggleEvent(evt))
{
this.addSelectionCells(cells);
}
else
{
this.setSelectionCells(cells);
}
};
mxGraph.prototype.createHandler = function(state)
{
var result = null;
if (state != null)
{
if (this.model.isEdge(state.cell))
{
var source = state.getVisibleTerminalState(true);
var target = state.getVisibleTerminalState(false);
var geo = this.getCellGeometry(state.cell);
var edgeStyle = this.view.getEdgeStyle(state, (geo != null) ? geo.points : null, source, target);
result = this.createEdgeHandler(state, edgeStyle);
}
else
{
result = this.createVertexHandler(state);
}
}
return result;
};
mxGraph.prototype.createVertexHandler = function(state)
{
return new mxVertexHandler(state);
};
mxGraph.prototype.createEdgeHandler = function(state, edgeStyle)
{
var result = null;
if (edgeStyle == mxEdgeStyle.Loop ||
edgeStyle == mxEdgeStyle.ElbowConnector ||
edgeStyle == mxEdgeStyle.SideToSide ||
edgeStyle == mxEdgeStyle.TopToBottom)
{
result = this.createElbowEdgeHandler(state);
}
else if (edgeStyle == mxEdgeStyle.SegmentConnector ||
edgeStyle == mxEdgeStyle.OrthConnector)
{
result = this.createEdgeSegmentHandler(state);
}
else
{
result = new mxEdgeHandler(state);
}
return result;
};
mxGraph.prototype.createEdgeSegmentHandler = function(state)
{
return new mxEdgeSegmentHandler(state);
};
mxGraph.prototype.createElbowEdgeHandler = function(state)
{
return new mxElbowEdgeHandler(state);
};
mxGraph.prototype.addMouseListener = function(listener)
{
if (this.mouseListeners == null)
{
this.mouseListeners = [];
}
this.mouseListeners.push(listener);
};
mxGraph.prototype.removeMouseListener = function(listener)
{
if (this.mouseListeners != null)
{
for (var i = 0; i < this.mouseListeners.length; i++)
{
if (this.mouseListeners[i] == listener)
{
this.mouseListeners.splice(i, 1);
break;
}
}
}
};
mxGraph.prototype.updateMouseEvent = function(me, evtName)
{
if (me.graphX == null || me.graphY == null)
{
var pt = mxUtils.convertPoint(this.container, me.getX(), me.getY());
me.graphX = pt.x - this.panDx;
me.graphY = pt.y - this.panDy;
if (me.getCell() == null && this.isMouseDown && evtName == mxEvent.MOUSE_MOVE)
{
me.state = this.view.getState(this.getCellAt(pt.x, pt.y, null, null, null, function(state)
{
return state.shape == null || state.shape.paintBackground != mxRectangleShape.prototype.paintBackground ||
mxUtils.getValue(state.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1' ||
(state.shape.fill != null && state.shape.fill != mxConstants.NONE);
}));
}
}
return me;
};
mxGraph.prototype.getStateForTouchEvent = function(evt)
{
var x = mxEvent.getClientX(evt);
var y = mxEvent.getClientY(evt);
var pt = mxUtils.convertPoint(this.container, x, y);
return this.view.getState(this.getCellAt(pt.x, pt.y));
};
mxGraph.prototype.isEventIgnored = function(evtName, me, sender)
{
var mouseEvent = mxEvent.isMouseEvent(me.getEvent());
var result = false;
if (me.getEvent() == this.lastEvent)
{
result = true;
}
else
{
this.lastEvent = me.getEvent();
}
if (this.eventSource != null && evtName != mxEvent.MOUSE_MOVE)
{
mxEvent.removeGestureListeners(this.eventSource, null, this.mouseMoveRedirect, this.mouseUpRedirect);
this.mouseMoveRedirect = null;
this.mouseUpRedirect = null;
this.eventSource = null;
}
else if (!mxClient.IS_GC && this.eventSource != null && me.getSource() != this.eventSource)
{
result = true;
}
else if (mxClient.IS_TOUCH && evtName == mxEvent.MOUSE_DOWN &&
!mouseEvent && !mxEvent.isPenEvent(me.getEvent()))
{
this.eventSource = me.getSource();
this.mouseMoveRedirect = mxUtils.bind(this, function(evt)
{
this.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, this.getStateForTouchEvent(evt)));
});
this.mouseUpRedirect = mxUtils.bind(this, function(evt)
{
this.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, this.getStateForTouchEvent(evt)));
});
mxEvent.addGestureListeners(this.eventSource, null, this.mouseMoveRedirect, this.mouseUpRedirect);
}
if (this.isSyntheticEventIgnored(evtName, me, sender))
{
result = true;
}
if (!mxEvent.isPopupTrigger(this.lastEvent) && evtName != mxEvent.MOUSE_MOVE && this.lastEvent.detail == 2)
{
return true;
}
if (evtName == mxEvent.MOUSE_UP && this.isMouseDown)
{
this.isMouseDown = false;
}
else if (evtName == mxEvent.MOUSE_DOWN && !this.isMouseDown)
{
this.isMouseDown = true;
this.isMouseTrigger = mouseEvent;
}
else if (!result && (((!mxClient.IS_FF || evtName != mxEvent.MOUSE_MOVE) &&
this.isMouseDown && this.isMouseTrigger != mouseEvent) ||
(evtName == mxEvent.MOUSE_DOWN && this.isMouseDown) ||
(evtName == mxEvent.MOUSE_UP && !this.isMouseDown)))
{
result = true;
}
if (!result && evtName == mxEvent.MOUSE_DOWN)
{
this.lastMouseX = me.getX();
this.lastMouseY = me.getY();
}
return result;
};
mxGraph.prototype.isSyntheticEventIgnored = function(evtName, me, sender)
{
var result = false;
var mouseEvent = mxEvent.isMouseEvent(me.getEvent());
if (this.ignoreMouseEvents && mouseEvent && evtName != mxEvent.MOUSE_MOVE)
{
this.ignoreMouseEvents = evtName != mxEvent.MOUSE_UP;
result = true;
}
else if (mxClient.IS_FF && !mouseEvent && evtName == mxEvent.MOUSE_UP)
{
this.ignoreMouseEvents = true;
}
return result;
};
mxGraph.prototype.isEventSourceIgnored = function(evtName, me)
{
var source = me.getSource();
var name = (source.nodeName != null) ? source.nodeName.toLowerCase() : '';
var candidate = !mxEvent.isMouseEvent(me.getEvent()) || mxEvent.isLeftMouseButton(me.getEvent());
return evtName == mxEvent.MOUSE_DOWN && candidate && (name == 'select' || name == 'option' ||
(name == 'input' && source.type != 'checkbox' && source.type != 'radio' &&
source.type != 'button' && source.type != 'submit' && source.type != 'file'));
};
mxGraph.prototype.getEventState = function(state)
{
return state;
};
mxGraph.prototype.fireMouseEvent = function(evtName, me, sender)
{
if (this.isEventSourceIgnored(evtName, me))
{
if (this.tooltipHandler != null)
{
this.tooltipHandler.hide();
}
return;
}
if (sender == null)
{
sender = this;
}
me = this.updateMouseEvent(me, evtName);
if ((!this.nativeDblClickEnabled && !mxEvent.isPopupTrigger(me.getEvent())) || (this.doubleTapEnabled &&
mxClient.IS_TOUCH && (mxEvent.isTouchEvent(me.getEvent()) || mxEvent.isPenEvent(me.getEvent()))))
{
var currentTime = new Date().getTime();
if ((!mxClient.IS_QUIRKS && evtName == mxEvent.MOUSE_DOWN) || (mxClient.IS_QUIRKS && evtName == mxEvent.MOUSE_UP && !this.fireDoubleClick))
{
if (this.lastTouchEvent != null && this.lastTouchEvent != me.getEvent() &&
currentTime - this.lastTouchTime < this.doubleTapTimeout &&
Math.abs(this.lastTouchX - me.getX()) < this.doubleTapTolerance &&
Math.abs(this.lastTouchY - me.getY()) < this.doubleTapTolerance &&
this.doubleClickCounter < 2)
{
this.doubleClickCounter++;
var doubleClickFired = false;
if (evtName == mxEvent.MOUSE_UP)
{
if (me.getCell() == this.lastTouchCell && this.lastTouchCell != null)
{
this.lastTouchTime = 0;
var cell = this.lastTouchCell;
this.lastTouchCell = null;
if (mxClient.IS_QUIRKS)
{
me.getSource().fireEvent('ondblclick');
}
this.dblClick(me.getEvent(), cell);
doubleClickFired = true;
}
}
else
{
this.fireDoubleClick = true;
this.lastTouchTime = 0;
}
if (!mxClient.IS_QUIRKS || doubleClickFired)
{
mxEvent.consume(me.getEvent());
return;
}
}
else if (this.lastTouchEvent == null || this.lastTouchEvent != me.getEvent())
{
this.lastTouchCell = me.getCell();
this.lastTouchX = me.getX();
this.lastTouchY = me.getY();
this.lastTouchTime = currentTime;
this.lastTouchEvent = me.getEvent();
this.doubleClickCounter = 0;
}
}
else if ((this.isMouseDown || evtName == mxEvent.MOUSE_UP) && this.fireDoubleClick)
{
this.fireDoubleClick = false;
var cell = this.lastTouchCell;
this.lastTouchCell = null;
this.isMouseDown = false;
var valid = (cell != null) || ((mxEvent.isTouchEvent(me.getEvent()) || mxEvent.isPenEvent(me.getEvent())) &&
(mxClient.IS_GC || mxClient.IS_SF));
if (valid && Math.abs(this.lastTouchX - me.getX()) < this.doubleTapTolerance &&
Math.abs(this.lastTouchY - me.getY()) < this.doubleTapTolerance)
{
this.dblClick(me.getEvent(), cell);
}
else
{
mxEvent.consume(me.getEvent());
}
return;
}
}
if (!this.isEventIgnored(evtName, me, sender))
{
me.state = this.getEventState(me.getState());
this.fireEvent(new mxEventObject(mxEvent.FIRE_MOUSE_EVENT, 'eventName', evtName, 'event', me));
if ((mxClient.IS_OP || mxClient.IS_SF || mxClient.IS_GC || mxClient.IS_IE11 ||
(mxClient.IS_IE && mxClient.IS_SVG) || me.getEvent().target != this.container))
{
if (evtName == mxEvent.MOUSE_MOVE && this.isMouseDown && this.autoScroll && !mxEvent.isMultiTouchEvent(me.getEvent))
{
this.scrollPointToVisible(me.getGraphX(), me.getGraphY(), this.autoExtend);
}
else if (evtName == mxEvent.MOUSE_UP && this.ignoreScrollbars && this.translateToScrollPosition &&
(this.container.scrollLeft != 0 || this.container.scrollTop != 0))
{
var s = this.view.scale;
var tr = this.view.translate;
this.view.setTranslate(tr.x - this.container.scrollLeft / s, tr.y - this.container.scrollTop / s);
this.container.scrollLeft = 0;
this.container.scrollTop = 0;
}
if (this.mouseListeners != null)
{
var args = [sender, me];
if (!me.getEvent().preventDefault)
{
me.getEvent().returnValue = true;
}
for (var i = 0; i < this.mouseListeners.length; i++)
{
var l = this.mouseListeners[i];
if (evtName == mxEvent.MOUSE_DOWN)
{
l.mouseDown.apply(l, args);
}
else if (evtName == mxEvent.MOUSE_MOVE)
{
l.mouseMove.apply(l, args);
}
else if (evtName == mxEvent.MOUSE_UP)
{
l.mouseUp.apply(l, args);
}
}
}
if (evtName == mxEvent.MOUSE_UP)
{
this.click(me);
}
}
if ((mxEvent.isTouchEvent(me.getEvent()) || mxEvent.isPenEvent(me.getEvent())) &&
evtName == mxEvent.MOUSE_DOWN && this.tapAndHoldEnabled && !this.tapAndHoldInProgress)
{
this.tapAndHoldInProgress = true;
this.initialTouchX = me.getGraphX();
this.initialTouchY = me.getGraphY();
var handler = function()
{
if (this.tapAndHoldValid)
{
this.tapAndHold(me);
}
this.tapAndHoldInProgress = false;
this.tapAndHoldValid = false;
};
if (this.tapAndHoldThread)
{
window.clearTimeout(this.tapAndHoldThread);
}
this.tapAndHoldThread = window.setTimeout(mxUtils.bind(this, handler), this.tapAndHoldDelay);
this.tapAndHoldValid = true;
}
else if (evtName == mxEvent.MOUSE_UP)
{
this.tapAndHoldInProgress = false;
this.tapAndHoldValid = false;
}
else if (this.tapAndHoldValid)
{
this.tapAndHoldValid =
Math.abs(this.initialTouchX - me.getGraphX()) < this.tolerance &&
Math.abs(this.initialTouchY - me.getGraphY()) < this.tolerance;
}
if (evtName == mxEvent.MOUSE_DOWN && this.isEditing() && !this.cellEditor.isEventSource(me.getEvent()))
{
this.stopEditing(!this.isInvokesStopCellEditing());
}
this.consumeMouseEvent(evtName, me, sender);
}
};
mxGraph.prototype.consumeMouseEvent = function(evtName, me, sender)
{
if (evtName == mxEvent.MOUSE_DOWN && mxEvent.isTouchEvent(me.getEvent()))
{
me.consume(false);
}
};
mxGraph.prototype.fireGestureEvent = function(evt, cell)
{
this.lastTouchTime = 0;
this.fireEvent(new mxEventObject(mxEvent.GESTURE, 'event', evt, 'cell', cell));
};
mxGraph.prototype.destroy = function()
{
if (!this.destroyed)
{
this.destroyed = true;
if (this.tooltipHandler != null)
{
this.tooltipHandler.destroy();
}
if (this.selectionCellsHandler != null)
{
this.selectionCellsHandler.destroy();
}
if (this.panningHandler != null)
{
this.panningHandler.destroy();
}
if (this.popupMenuHandler != null)
{
this.popupMenuHandler.destroy();
}
if (this.connectionHandler != null)
{
this.connectionHandler.destroy();
}
if (this.graphHandler != null)
{
this.graphHandler.destroy();
}
if (this.cellEditor != null)
{
this.cellEditor.destroy();
}
if (this.view != null)
{
this.view.destroy();
}
if (this.model != null && this.graphModelChangeListener != null)
{
this.model.removeListener(this.graphModelChangeListener);
this.graphModelChangeListener = null;
}
this.container = null;
}
};
__mxOutput.mxGraph = typeof mxGraph !== 'undefined' ? mxGraph : undefined;
function mxCellOverlay(image, tooltip, align, verticalAlign, offset, cursor)
{
this.image = image;
this.tooltip = tooltip;
this.align = (align != null) ? align : this.align;
this.verticalAlign = (verticalAlign != null) ? verticalAlign : this.verticalAlign;
this.offset = (offset != null) ? offset : new mxPoint();
this.cursor = (cursor != null) ? cursor : 'help';
} mxCellOverlay.prototype = new mxEventSource();
mxCellOverlay.prototype.constructor = mxCellOverlay;
mxCellOverlay.prototype.image = null;
mxCellOverlay.prototype.tooltip = null;
mxCellOverlay.prototype.align = mxConstants.ALIGN_RIGHT;
mxCellOverlay.prototype.verticalAlign = mxConstants.ALIGN_BOTTOM;
mxCellOverlay.prototype.offset = null;
mxCellOverlay.prototype.cursor = null;
mxCellOverlay.prototype.defaultOverlap = 0.5;
mxCellOverlay.prototype.getBounds = function(state)
{
var isEdge = state.view.graph.getModel().isEdge(state.cell);
var s = state.view.scale;
var pt = null;
var w = this.image.width;
var h = this.image.height;
if (isEdge)
{
var pts = state.absolutePoints;
if (pts.length % 2 == 1)
{
pt = pts[Math.floor(pts.length / 2)];
}
else
{
var idx = pts.length / 2;
var p0 = pts[idx-1];
var p1 = pts[idx];
pt = new mxPoint(p0.x + (p1.x - p0.x) / 2,
p0.y + (p1.y - p0.y) / 2);
}
}
else
{
pt = new mxPoint();
if (this.align == mxConstants.ALIGN_LEFT)
{
pt.x = state.x;
}
else if (this.align == mxConstants.ALIGN_CENTER)
{
pt.x = state.x + state.width / 2;
}
else
{
pt.x = state.x + state.width;
}
if (this.verticalAlign == mxConstants.ALIGN_TOP)
{
pt.y = state.y;
}
else if (this.verticalAlign == mxConstants.ALIGN_MIDDLE)
{
pt.y = state.y + state.height / 2;
}
else
{
pt.y = state.y + state.height;
}
}
return new mxRectangle(Math.round(pt.x - (w * this.defaultOverlap - this.offset.x) * s),
Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * s);
};
mxCellOverlay.prototype.toString = function()
{
return this.tooltip;
};
__mxOutput.mxCellOverlay = typeof mxCellOverlay !== 'undefined' ? mxCellOverlay : undefined;
function mxOutline(source, container)
{
this.source = source;
if (container != null)
{
this.init(container);
}
} mxOutline.prototype.source = null;
mxOutline.prototype.outline = null;
mxOutline.prototype.graphRenderHint = mxConstants.RENDERING_HINT_FASTER;
mxOutline.prototype.enabled = true;
mxOutline.prototype.showViewport = true;
mxOutline.prototype.border = 10;
mxOutline.prototype.sizerSize = 8;
mxOutline.prototype.labelsVisible = false;
mxOutline.prototype.updateOnPan = false;
mxOutline.prototype.sizerImage = null;
mxOutline.prototype.minScale = 0.0001;
mxOutline.prototype.suspended = false;
mxOutline.prototype.forceVmlHandles = document.documentMode == 8;
mxOutline.prototype.createGraph = function(container)
{
var graph = new mxGraph(container, this.source.getModel(), this.graphRenderHint, this.source.getStylesheet());
graph.foldingEnabled = false;
graph.autoScroll = false;
return graph;
};
mxOutline.prototype.init = function(container)
{
this.outline = this.createGraph(container);
var outlineGraphModelChanged = this.outline.graphModelChanged;
this.outline.graphModelChanged = mxUtils.bind(this, function(changes)
{
if (!this.suspended && this.outline != null)
{
outlineGraphModelChanged.apply(this.outline, arguments);
}
});
if (mxClient.IS_SVG)
{
var node = this.outline.getView().getCanvas().parentNode;
node.setAttribute('shape-rendering', 'optimizeSpeed');
node.setAttribute('image-rendering', 'optimizeSpeed');
}
this.outline.labelsVisible = this.labelsVisible;
this.outline.setEnabled(false);
this.updateHandler = mxUtils.bind(this, function(sender, evt)
{
if (!this.suspended && !this.active)
{
this.update();
}
});
this.source.getModel().addListener(mxEvent.CHANGE, this.updateHandler);
this.outline.addMouseListener(this);
var view = this.source.getView();
view.addListener(mxEvent.SCALE, this.updateHandler);
view.addListener(mxEvent.TRANSLATE, this.updateHandler);
view.addListener(mxEvent.SCALE_AND_TRANSLATE, this.updateHandler);
view.addListener(mxEvent.DOWN, this.updateHandler);
view.addListener(mxEvent.UP, this.updateHandler);
mxEvent.addListener(this.source.container, 'scroll', this.updateHandler);
this.panHandler = mxUtils.bind(this, function(sender)
{
if (this.updateOnPan)
{
this.updateHandler.apply(this, arguments);
}
});
this.source.addListener(mxEvent.PAN, this.panHandler);
this.refreshHandler = mxUtils.bind(this, function(sender)
{
this.outline.setStylesheet(this.source.getStylesheet());
this.outline.refresh();
});
this.source.addListener(mxEvent.REFRESH, this.refreshHandler);
this.bounds = new mxRectangle(0, 0, 0, 0);
this.selectionBorder = new mxRectangleShape(this.bounds, null,
mxConstants.OUTLINE_COLOR, mxConstants.OUTLINE_STROKEWIDTH);
this.selectionBorder.dialect = this.outline.dialect;
if (this.forceVmlHandles)
{
this.selectionBorder.isHtmlAllowed = function()
{
return false;
};
}
this.selectionBorder.init(this.outline.getView().getOverlayPane());
var handler = mxUtils.bind(this, function(evt)
{
var t = mxEvent.getSource(evt);
var redirect = mxUtils.bind(this, function(evt)
{
this.outline.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt));
});
var redirect2 = mxUtils.bind(this, function(evt)
{
mxEvent.removeGestureListeners(t, null, redirect, redirect2);
this.outline.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
});
mxEvent.addGestureListeners(t, null, redirect, redirect2);
this.outline.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt));
});
mxEvent.addGestureListeners(this.selectionBorder.node, handler);
this.sizer = this.createSizer();
if (this.forceVmlHandles)
{
this.sizer.isHtmlAllowed = function()
{
return false;
};
}
this.sizer.init(this.outline.getView().getOverlayPane());
if (this.enabled)
{
this.sizer.node.style.cursor = 'nwse-resize';
}
mxEvent.addGestureListeners(this.sizer.node, handler);
this.selectionBorder.node.style.display = (this.showViewport) ? '' : 'none';
this.sizer.node.style.display = this.selectionBorder.node.style.display;
this.selectionBorder.node.style.cursor = 'move';
this.update(false);
};
mxOutline.prototype.isEnabled = function()
{
return this.enabled;
};
mxOutline.prototype.setEnabled = function(value)
{
this.enabled = value;
};
mxOutline.prototype.setZoomEnabled = function(value)
{
this.sizer.node.style.visibility = (value) ? 'visible' : 'hidden';
};
mxOutline.prototype.refresh = function()
{
this.update(true);
};
mxOutline.prototype.createSizer = function()
{
if (this.sizerImage != null)
{
var sizer = new mxImageShape(new mxRectangle(0, 0, this.sizerImage.width, this.sizerImage.height), this.sizerImage.src);
sizer.dialect = this.outline.dialect;
return sizer;
}
else
{
var sizer = new mxRectangleShape(new mxRectangle(0, 0, this.sizerSize, this.sizerSize),
mxConstants.OUTLINE_HANDLE_FILLCOLOR, mxConstants.OUTLINE_HANDLE_STROKECOLOR);
sizer.dialect = this.outline.dialect;
return sizer;
}
};
mxOutline.prototype.getSourceContainerSize = function()
{
return new mxRectangle(0, 0, this.source.container.scrollWidth, this.source.container.scrollHeight);
};
mxOutline.prototype.getOutlineOffset = function(scale)
{
return null;
};
mxOutline.prototype.getSourceGraphBounds = function()
{
return this.source.getGraphBounds();
};
mxOutline.prototype.update = function(revalidate)
{
if (this.source != null && this.source.container != null &&
this.outline != null && this.outline.container != null)
{
var sourceScale = this.source.view.scale;
var scaledGraphBounds = this.getSourceGraphBounds();
var unscaledGraphBounds = new mxRectangle(scaledGraphBounds.x / sourceScale + this.source.panDx,
scaledGraphBounds.y / sourceScale + this.source.panDy, scaledGraphBounds.width / sourceScale,
scaledGraphBounds.height / sourceScale);
var unscaledFinderBounds = new mxRectangle(0, 0,
this.source.container.clientWidth / sourceScale,
this.source.container.clientHeight / sourceScale);
var union = unscaledGraphBounds.clone();
union.add(unscaledFinderBounds);
var size = this.getSourceContainerSize();
var completeWidth = Math.max(size.width / sourceScale, union.width);
var completeHeight = Math.max(size.height / sourceScale, union.height);
var availableWidth = Math.max(0, this.outline.container.clientWidth - this.border);
var availableHeight = Math.max(0, this.outline.container.clientHeight - this.border);
var outlineScale = Math.min(availableWidth / completeWidth, availableHeight / completeHeight);
var scale = (isNaN(outlineScale)) ? this.minScale : Math.max(this.minScale, outlineScale);
if (scale > 0)
{
if (this.outline.getView().scale != scale)
{
this.outline.getView().scale = scale;
revalidate = true;
}
var navView = this.outline.getView();
if (navView.currentRoot != this.source.getView().currentRoot)
{
navView.setCurrentRoot(this.source.getView().currentRoot);
}
var t = this.source.view.translate;
var tx = t.x + this.source.panDx;
var ty = t.y + this.source.panDy;
var off = this.getOutlineOffset(scale);
if (off != null)
{
tx += off.x;
ty += off.y;
}
if (unscaledGraphBounds.x < 0)
{
tx = tx - unscaledGraphBounds.x;
}
if (unscaledGraphBounds.y < 0)
{
ty = ty - unscaledGraphBounds.y;
}
if (navView.translate.x != tx || navView.translate.y != ty)
{
navView.translate.x = tx;
navView.translate.y = ty;
revalidate = true;
}
var t2 = navView.translate;
scale = this.source.getView().scale;
var scale2 = scale / navView.scale;
var scale3 = 1.0 / navView.scale;
var container = this.source.container;
this.bounds = new mxRectangle(
(t2.x - t.x - this.source.panDx) / scale3,
(t2.y - t.y - this.source.panDy) / scale3,
(container.clientWidth / scale2),
(container.clientHeight / scale2));
this.bounds.x += this.source.container.scrollLeft * navView.scale / scale;
this.bounds.y += this.source.container.scrollTop * navView.scale / scale;
var b = this.selectionBorder.bounds;
if (b.x != this.bounds.x || b.y != this.bounds.y || b.width != this.bounds.width || b.height != this.bounds.height)
{
this.selectionBorder.bounds = this.bounds;
this.selectionBorder.redraw();
}
var b = this.sizer.bounds;
var b2 = new mxRectangle(this.bounds.x + this.bounds.width - b.width / 2,
this.bounds.y + this.bounds.height - b.height / 2, b.width, b.height);
if (b.x != b2.x || b.y != b2.y || b.width != b2.width || b.height != b2.height)
{
this.sizer.bounds = b2;
if (this.sizer.node.style.visibility != 'hidden')
{
this.sizer.redraw();
}
}
if (revalidate)
{
this.outline.view.revalidate();
}
}
}
};
mxOutline.prototype.mouseDown = function(sender, me)
{
if (this.enabled && this.showViewport)
{
var tol = (!mxEvent.isMouseEvent(me.getEvent())) ? this.source.tolerance : 0;
var hit = (this.source.allowHandleBoundsCheck && (mxClient.IS_IE || tol > 0)) ?
new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol) : null;
this.zoom = me.isSource(this.sizer) || (hit != null && mxUtils.intersects(shape.bounds, hit));
this.startX = me.getX();
this.startY = me.getY();
this.active = true;
if (this.source.useScrollbarsForPanning && mxUtils.hasScrollbars(this.source.container))
{
this.dx0 = this.source.container.scrollLeft;
this.dy0 = this.source.container.scrollTop;
}
else
{
this.dx0 = 0;
this.dy0 = 0;
}
}
me.consume();
};
mxOutline.prototype.mouseMove = function(sender, me)
{
if (this.active)
{
this.selectionBorder.node.style.display = (this.showViewport) ? '' : 'none';
this.sizer.node.style.display = this.selectionBorder.node.style.display;
var delta = this.getTranslateForEvent(me);
var dx = delta.x;
var dy = delta.y;
var bounds = null;
if (!this.zoom)
{
var scale = this.outline.getView().scale;
bounds = new mxRectangle(this.bounds.x + dx,
this.bounds.y + dy, this.bounds.width, this.bounds.height);
this.selectionBorder.bounds = bounds;
this.selectionBorder.redraw();
dx /= scale;
dx *= this.source.getView().scale;
dy /= scale;
dy *= this.source.getView().scale;
this.source.panGraph(-dx - this.dx0, -dy - this.dy0);
}
else
{
var container = this.source.container;
var viewRatio = container.clientWidth / container.clientHeight;
dy = dx / viewRatio;
bounds = new mxRectangle(this.bounds.x,
this.bounds.y,
Math.max(1, this.bounds.width + dx),
Math.max(1, this.bounds.height + dy));
this.selectionBorder.bounds = bounds;
this.selectionBorder.redraw();
}
var b = this.sizer.bounds;
this.sizer.bounds = new mxRectangle(
bounds.x + bounds.width - b.width / 2,
bounds.y + bounds.height - b.height / 2,
b.width, b.height);
if (this.sizer.node.style.visibility != 'hidden')
{
this.sizer.redraw();
}
me.consume();
}
};
mxOutline.prototype.getTranslateForEvent = function(me)
{
return new mxPoint(me.getX() - this.startX, me.getY() - this.startY);
};
mxOutline.prototype.mouseUp = function(sender, me)
{
if (this.active)
{
var delta = this.getTranslateForEvent(me);
var dx = delta.x;
var dy = delta.y;
if (Math.abs(dx) > 0 || Math.abs(dy) > 0)
{
if (!this.zoom)
{
if (!this.source.useScrollbarsForPanning ||
!mxUtils.hasScrollbars(this.source.container))
{
this.source.panGraph(0, 0);
dx /= this.outline.getView().scale;
dy /= this.outline.getView().scale;
var t = this.source.getView().translate;
this.source.getView().setTranslate(t.x - dx, t.y - dy);
}
}
else
{
var w = this.selectionBorder.bounds.width;
var scale = this.source.getView().scale;
this.source.zoomTo(Math.max(this.minScale, scale - (dx * scale) / w), false);
}
this.update();
me.consume();
}
this.index = null;
this.active = false;
}
};
mxOutline.prototype.destroy = function()
{
if (this.source != null)
{
this.source.removeListener(this.panHandler);
this.source.removeListener(this.refreshHandler);
this.source.getModel().removeListener(this.updateHandler);
this.source.getView().removeListener(this.updateHandler);
mxEvent.removeListener(this.source.container, 'scroll', this.updateHandler);
this.source = null;
}
if (this.outline != null)
{
this.outline.removeMouseListener(this);
this.outline.destroy();
this.outline = null;
}
if (this.selectionBorder != null)
{
this.selectionBorder.destroy();
this.selectionBorder = null;
}
if (this.sizer != null)
{
this.sizer.destroy();
this.sizer = null;
}
};
__mxOutput.mxOutline = typeof mxOutline !== 'undefined' ? mxOutline : undefined;
function mxMultiplicity(source, type, attr, value, min, max,
validNeighbors, countError, typeError, validNeighborsAllowed)
{
this.source = source;
this.type = type;
this.attr = attr;
this.value = value;
this.min = (min != null) ? min : 0;
this.max = (max != null) ? max : 'n';
this.validNeighbors = validNeighbors;
this.countError = mxResources.get(countError) || countError;
this.typeError = mxResources.get(typeError) || typeError;
this.validNeighborsAllowed = (validNeighborsAllowed != null) ?
validNeighborsAllowed : true;
} mxMultiplicity.prototype.type = null;
mxMultiplicity.prototype.attr = null;
mxMultiplicity.prototype.value = null;
mxMultiplicity.prototype.source = null;
mxMultiplicity.prototype.min = null;
mxMultiplicity.prototype.max = null;
mxMultiplicity.prototype.validNeighbors = null;
mxMultiplicity.prototype.validNeighborsAllowed = true;
mxMultiplicity.prototype.countError = null;
mxMultiplicity.prototype.typeError = null;
mxMultiplicity.prototype.check = function(graph, edge, source, target, sourceOut, targetIn)
{
var error = '';
if ((this.source && this.checkTerminal(graph, source, edge)) ||
(!this.source && this.checkTerminal(graph, target, edge)))
{
if (this.countError != null &&
((this.source && (this.max == 0 || (sourceOut >= this.max))) ||
(!this.source && (this.max == 0 || (targetIn >= this.max)))))
{
error += this.countError + '\n';
}
if (this.validNeighbors != null && this.typeError != null && this.validNeighbors.length > 0)
{
var isValid = this.checkNeighbors(graph, edge, source, target);
if (!isValid)
{
error += this.typeError + '\n';
}
}
}
return (error.length > 0) ? error : null;
};
mxMultiplicity.prototype.checkNeighbors = function(graph, edge, source, target)
{
var sourceValue = graph.model.getValue(source);
var targetValue = graph.model.getValue(target);
var isValid = !this.validNeighborsAllowed;
var valid = this.validNeighbors;
for (var j = 0; j < valid.length; j++)
{
if (this.source &&
this.checkType(graph, targetValue, valid[j]))
{
isValid = this.validNeighborsAllowed;
break;
}
else if (!this.source &&
this.checkType(graph, sourceValue, valid[j]))
{
isValid = this.validNeighborsAllowed;
break;
}
}
return isValid;
};
mxMultiplicity.prototype.checkTerminal = function(graph, terminal, edge)
{
var value = graph.model.getValue(terminal);
return this.checkType(graph, value, this.type, this.attr, this.value);
};
mxMultiplicity.prototype.checkType = function(graph, value, type, attr, attrValue)
{
if (value != null)
{
if (!isNaN(value.nodeType))
{
return mxUtils.isNode(value, type, attr, attrValue);
}
else
{
return value == type;
}
}
return false;
};
__mxOutput.mxMultiplicity = typeof mxMultiplicity !== 'undefined' ? mxMultiplicity : undefined;
function mxLayoutManager(graph)
{
this.undoHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.isEnabled())
{
this.beforeUndo(evt.getProperty('edit'));
}
});
this.moveHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.isEnabled())
{
this.cellsMoved(evt.getProperty('cells'), evt.getProperty('event'));
}
});
this.resizeHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.isEnabled())
{
this.cellsResized(evt.getProperty('cells'), evt.getProperty('bounds'),
evt.getProperty('previous'));
}
});
this.setGraph(graph);
} mxLayoutManager.prototype = new mxEventSource();
mxLayoutManager.prototype.constructor = mxLayoutManager;
mxLayoutManager.prototype.graph = null;
mxLayoutManager.prototype.bubbling = true;
mxLayoutManager.prototype.enabled = true;
mxLayoutManager.prototype.undoHandler = null;
mxLayoutManager.prototype.moveHandler = null;
mxLayoutManager.prototype.resizeHandler = null;
mxLayoutManager.prototype.isEnabled = function()
{
return this.enabled;
};
mxLayoutManager.prototype.setEnabled = function(enabled)
{
this.enabled = enabled;
};
mxLayoutManager.prototype.isBubbling = function()
{
return this.bubbling;
};
mxLayoutManager.prototype.setBubbling = function(value)
{
this.bubbling = value;
};
mxLayoutManager.prototype.getGraph = function()
{
return this.graph;
};
mxLayoutManager.prototype.setGraph = function(graph)
{
if (this.graph != null)
{
var model = this.graph.getModel();
model.removeListener(this.undoHandler);
this.graph.removeListener(this.moveHandler);
this.graph.removeListener(this.resizeHandler);
}
this.graph = graph;
if (this.graph != null)
{
var model = this.graph.getModel();
model.addListener(mxEvent.BEFORE_UNDO, this.undoHandler);
this.graph.addListener(mxEvent.MOVE_CELLS, this.moveHandler);
this.graph.addListener(mxEvent.RESIZE_CELLS, this.resizeHandler);
}
};
mxLayoutManager.prototype.hasLayout = function(cell)
{
return this.getLayout(cell, mxEvent.LAYOUT_CELLS);
};
mxLayoutManager.prototype.getLayout = function(cell, eventName)
{
return null;
};
mxLayoutManager.prototype.beforeUndo = function(undoableEdit)
{
this.executeLayoutForCells(this.getCellsForChanges(undoableEdit.changes));
};
mxLayoutManager.prototype.cellsMoved = function(cells, evt)
{
if (cells != null && evt != null)
{
var point = mxUtils.convertPoint(this.getGraph().container,
mxEvent.getClientX(evt), mxEvent.getClientY(evt));
var model = this.getGraph().getModel();
for (var i = 0; i < cells.length; i++)
{
var layout = this.getLayout(model.getParent(cells[i]), mxEvent.MOVE_CELLS);
if (layout != null)
{
layout.moveCell(cells[i], point.x, point.y);
}
}
}
};
mxLayoutManager.prototype.cellsResized = function(cells, bounds, prev)
{
if (cells != null && bounds != null)
{
var model = this.getGraph().getModel();
for (var i = 0; i < cells.length; i++)
{
var layout = this.getLayout(model.getParent(cells[i]), mxEvent.RESIZE_CELLS);
if (layout != null)
{
layout.resizeCell(cells[i], bounds[i], prev[i]);
}
}
}
};
mxLayoutManager.prototype.getCellsForChanges = function(changes)
{
var result = [];
for (var i = 0; i < changes.length; i++)
{
var change = changes[i];
if (change instanceof mxRootChange)
{
return [];
}
else
{
result = result.concat(this.getCellsForChange(change));
}
}
return result;
};
mxLayoutManager.prototype.getCellsForChange = function(change)
{
if (change instanceof mxChildChange)
{
return this.addCellsWithLayout(change.child,
this.addCellsWithLayout(change.previous));
}
else if (change instanceof mxTerminalChange ||
change instanceof mxGeometryChange)
{
return this.addCellsWithLayout(change.cell);
}
else if (change instanceof mxVisibleChange ||
change instanceof mxStyleChange)
{
return this.addCellsWithLayout(change.cell);
}
return [];
};
mxLayoutManager.prototype.addCellsWithLayout = function(cell, result)
{
return this.addDescendantsWithLayout(cell,
this.addAncestorsWithLayout(cell, result));
};
mxLayoutManager.prototype.addAncestorsWithLayout = function(cell, result)
{
result = (result != null) ? result : [];
if (cell != null)
{
var layout = this.hasLayout(cell);
if (layout != null)
{
result.push(cell);
}
if (this.isBubbling())
{
var model = this.getGraph().getModel();
this.addAncestorsWithLayout(
model.getParent(cell), result);
}
}
return result;
};
mxLayoutManager.prototype.addDescendantsWithLayout = function(cell, result)
{
result = (result != null) ? result : [];
if (cell != null && this.hasLayout(cell))
{
var model = this.getGraph().getModel();
for (var i = 0; i < model.getChildCount(cell); i++)
{
var child = model.getChildAt(cell, i);
if (this.hasLayout(child))
{
result.push(child);
this.addDescendantsWithLayout(child, result);
}
}
}
return result;
};
mxLayoutManager.prototype.executeLayoutForCells = function(cells)
{
var sorted = mxUtils.sortCells(cells, false);
this.layoutCells(sorted, true);
this.layoutCells(sorted.reverse(), false);
};
mxLayoutManager.prototype.layoutCells = function(cells, bubble)
{
if (cells.length > 0)
{
var model = this.getGraph().getModel();
model.beginUpdate();
try
{
var last = null;
for (var i = 0; i < cells.length; i++)
{
if (cells[i] != model.getRoot() && cells[i] != last)
{
this.executeLayout(cells[i], bubble);
last = cells[i];
}
}
this.fireEvent(new mxEventObject(mxEvent.LAYOUT_CELLS, 'cells', cells));
}
finally
{
model.endUpdate();
}
}
};
mxLayoutManager.prototype.executeLayout = function(cell, bubble)
{
var layout = this.getLayout(cell, (bubble) ?
mxEvent.BEGIN_UPDATE : mxEvent.END_UPDATE);
if (layout != null)
{
layout.execute(cell);
}
};
mxLayoutManager.prototype.destroy = function()
{
this.setGraph(null);
};
__mxOutput.mxLayoutManager = typeof mxLayoutManager !== 'undefined' ? mxLayoutManager : undefined;
function mxSwimlaneManager(graph, horizontal, addEnabled, resizeEnabled)
{
this.horizontal = (horizontal != null) ? horizontal : true;
this.addEnabled = (addEnabled != null) ? addEnabled : true;
this.resizeEnabled = (resizeEnabled != null) ? resizeEnabled : true;
this.addHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.isEnabled() && this.isAddEnabled())
{
this.cellsAdded(evt.getProperty('cells'));
}
});
this.resizeHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.isEnabled() && this.isResizeEnabled())
{
this.cellsResized(evt.getProperty('cells'));
}
});
this.setGraph(graph);
} mxSwimlaneManager.prototype = new mxEventSource();
mxSwimlaneManager.prototype.constructor = mxSwimlaneManager;
mxSwimlaneManager.prototype.graph = null;
mxSwimlaneManager.prototype.enabled = true;
mxSwimlaneManager.prototype.horizontal = true;
mxSwimlaneManager.prototype.addEnabled = true;
mxSwimlaneManager.prototype.resizeEnabled = true;
mxSwimlaneManager.prototype.addHandler = null;
mxSwimlaneManager.prototype.resizeHandler = null;
mxSwimlaneManager.prototype.isEnabled = function()
{
return this.enabled;
};
mxSwimlaneManager.prototype.setEnabled = function(value)
{
this.enabled = value;
};
mxSwimlaneManager.prototype.isHorizontal = function()
{
return this.horizontal;
};
mxSwimlaneManager.prototype.setHorizontal = function(value)
{
this.horizontal = value;
};
mxSwimlaneManager.prototype.isAddEnabled = function()
{
return this.addEnabled;
};
mxSwimlaneManager.prototype.setAddEnabled = function(value)
{
this.addEnabled = value;
};
mxSwimlaneManager.prototype.isResizeEnabled = function()
{
return this.resizeEnabled;
};
mxSwimlaneManager.prototype.setResizeEnabled = function(value)
{
this.resizeEnabled = value;
};
mxSwimlaneManager.prototype.getGraph = function()
{
return this.graph;
};
mxSwimlaneManager.prototype.setGraph = function(graph)
{
if (this.graph != null)
{
this.graph.removeListener(this.addHandler);
this.graph.removeListener(this.resizeHandler);
}
this.graph = graph;
if (this.graph != null)
{
this.graph.addListener(mxEvent.ADD_CELLS, this.addHandler);
this.graph.addListener(mxEvent.CELLS_RESIZED, this.resizeHandler);
}
};
mxSwimlaneManager.prototype.isSwimlaneIgnored = function(swimlane)
{
return !this.getGraph().isSwimlane(swimlane);
};
mxSwimlaneManager.prototype.isCellHorizontal = function(cell)
{
if (this.graph.isSwimlane(cell))
{
var style = this.graph.getCellStyle(cell);
return mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, 1) == 1;
}
return !this.isHorizontal();
};
mxSwimlaneManager.prototype.cellsAdded = function(cells)
{
if (cells != null)
{
var model = this.getGraph().getModel();
model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
if (!this.isSwimlaneIgnored(cells[i]))
{
this.swimlaneAdded(cells[i]);
}
}
}
finally
{
model.endUpdate();
}
}
};
mxSwimlaneManager.prototype.swimlaneAdded = function(swimlane)
{
var model = this.getGraph().getModel();
var parent = model.getParent(swimlane);
var childCount = model.getChildCount(parent);
var geo = null;
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(parent, i);
if (child != swimlane && !this.isSwimlaneIgnored(child))
{
geo = model.getGeometry(child);
if (geo != null)
{
break;
}
}
}
if (geo != null)
{
var parentHorizontal = (parent != null) ? this.isCellHorizontal(parent) : this.horizontal;
this.resizeSwimlane(swimlane, geo.width, geo.height, parentHorizontal);
}
};
mxSwimlaneManager.prototype.cellsResized = function(cells)
{
if (cells != null)
{
var model = this.getGraph().getModel();
model.beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
if (!this.isSwimlaneIgnored(cells[i]))
{
var geo = model.getGeometry(cells[i]);
if (geo != null)
{
var size = new mxRectangle(0, 0, geo.width, geo.height);
var top = cells[i];
var current = top;
while (current != null)
{
top = current;
current = model.getParent(current);
var tmp = (this.graph.isSwimlane(current)) ?
this.graph.getStartSize(current) :
new mxRectangle();
size.width += tmp.width;
size.height += tmp.height;
}
var parentHorizontal = (current != null) ? this.isCellHorizontal(current) : this.horizontal;
this.resizeSwimlane(top, size.width, size.height, parentHorizontal);
}
}
}
}
finally
{
model.endUpdate();
}
}
};
mxSwimlaneManager.prototype.resizeSwimlane = function(swimlane, w, h, parentHorizontal)
{
var model = this.getGraph().getModel();
model.beginUpdate();
try
{
var horizontal = this.isCellHorizontal(swimlane);
if (!this.isSwimlaneIgnored(swimlane))
{
var geo = model.getGeometry(swimlane);
if (geo != null)
{
if ((parentHorizontal && geo.height != h) || (!parentHorizontal && geo.width != w))
{
geo = geo.clone();
if (parentHorizontal)
{
geo.height = h;
}
else
{
geo.width = w;
}
model.setGeometry(swimlane, geo);
}
}
}
var tmp = (this.graph.isSwimlane(swimlane)) ?
this.graph.getStartSize(swimlane) :
new mxRectangle();
w -= tmp.width;
h -= tmp.height;
var childCount = model.getChildCount(swimlane);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(swimlane, i);
this.resizeSwimlane(child, w, h, horizontal);
}
}
finally
{
model.endUpdate();
}
};
mxSwimlaneManager.prototype.destroy = function()
{
this.setGraph(null);
};
__mxOutput.mxSwimlaneManager = typeof mxSwimlaneManager !== 'undefined' ? mxSwimlaneManager : undefined;
function mxTemporaryCellStates(view, scale, cells, isCellVisibleFn, getLinkForCellState)
{
scale = (scale != null) ? scale : 1;
this.view = view;
this.oldValidateCellState = view.validateCellState;
this.oldBounds = view.getGraphBounds();
this.oldStates = view.getStates();
this.oldScale = view.getScale();
this.oldDoRedrawShape = view.graph.cellRenderer.doRedrawShape;
var self = this;
if (getLinkForCellState != null)
{
view.graph.cellRenderer.doRedrawShape = function(state)
{
var oldPaint = state.shape.paint;
state.shape.paint = function(c)
{
var link = getLinkForCellState(state);
if (link != null)
{
c.setLink(link);
}
oldPaint.apply(this, arguments);
if (link != null)
{
c.setLink(null);
}
};
self.oldDoRedrawShape.apply(view.graph.cellRenderer, arguments);
state.shape.paint = oldPaint;
};
}
view.validateCellState = function(cell, resurse)
{
if (cell == null || isCellVisibleFn == null || isCellVisibleFn(cell))
{
return self.oldValidateCellState.apply(view, arguments);
}
return null;
};
view.setStates(new mxDictionary());
view.setScale(scale);
if (cells != null)
{
view.resetValidationState();
var bbox = null;
for (var i = 0; i < cells.length; i++)
{
var bounds = view.getBoundingBox(view.validateCellState(view.validateCell(cells[i])));
if (bbox == null)
{
bbox = bounds;
}
else
{
bbox.add(bounds);
}
}
view.setGraphBounds(bbox || new mxRectangle());
}
} mxTemporaryCellStates.prototype.view = null;
mxTemporaryCellStates.prototype.oldStates = null;
mxTemporaryCellStates.prototype.oldBounds = null;
mxTemporaryCellStates.prototype.oldScale = null;
mxTemporaryCellStates.prototype.destroy = function()
{
this.view.setScale(this.oldScale);
this.view.setStates(this.oldStates);
this.view.setGraphBounds(this.oldBounds);
this.view.validateCellState = this.oldValidateCellState;
this.view.graph.cellRenderer.doRedrawShape = this.oldDoRedrawShape;
};
__mxOutput.mxTemporaryCellStates = typeof mxTemporaryCellStates !== 'undefined' ? mxTemporaryCellStates : undefined;
function mxCellStatePreview(graph)
{
this.deltas = new mxDictionary();
this.graph = graph;
} mxCellStatePreview.prototype.graph = null;
mxCellStatePreview.prototype.deltas = null;
mxCellStatePreview.prototype.count = 0;
mxCellStatePreview.prototype.isEmpty = function()
{
return this.count == 0;
};
mxCellStatePreview.prototype.moveState = function(state, dx, dy, add, includeEdges)
{
add = (add != null) ? add : true;
includeEdges = (includeEdges != null) ? includeEdges : true;
var delta = this.deltas.get(state.cell);
if (delta == null)
{
delta = {point: new mxPoint(dx, dy), state: state};
this.deltas.put(state.cell, delta);
this.count++;
}
else if (add)
{
delta.point.x += dx;
delta.point.y += dy;
}
else
{
delta.point.x = dx;
delta.point.y = dy;
}
if (includeEdges)
{
this.addEdges(state);
}
return delta.point;
};
mxCellStatePreview.prototype.show = function(visitor)
{
this.deltas.visit(mxUtils.bind(this, function(key, delta)
{
this.translateState(delta.state, delta.point.x, delta.point.y);
}));
this.deltas.visit(mxUtils.bind(this, function(key, delta)
{
this.revalidateState(delta.state, delta.point.x, delta.point.y, visitor);
}));
};
mxCellStatePreview.prototype.translateState = function(state, dx, dy)
{
if (state != null)
{
var model = this.graph.getModel();
if (model.isVertex(state.cell))
{
state.view.updateCellState(state);
var geo = model.getGeometry(state.cell);
if ((dx != 0 || dy != 0) && geo != null && (!geo.relative || this.deltas.get(state.cell) != null))
{
state.x += dx;
state.y += dy;
}
}
var childCount = model.getChildCount(state.cell);
for (var i = 0; i < childCount; i++)
{
this.translateState(state.view.getState(model.getChildAt(state.cell, i)), dx, dy);
}
}
};
mxCellStatePreview.prototype.revalidateState = function(state, dx, dy, visitor)
{
if (state != null)
{
var model = this.graph.getModel();
if (model.isEdge(state.cell))
{
state.view.updateCellState(state);
}
var geo = this.graph.getCellGeometry(state.cell);
var pState = state.view.getState(model.getParent(state.cell));
if ((dx != 0 || dy != 0) && geo != null && geo.relative &&
model.isVertex(state.cell) && (pState == null ||
model.isVertex(pState.cell) || this.deltas.get(state.cell) != null))
{
state.x += dx;
state.y += dy;
}
this.graph.cellRenderer.redraw(state);
if (visitor != null)
{
visitor(state);
}
var childCount = model.getChildCount(state.cell);
for (var i = 0; i < childCount; i++)
{
this.revalidateState(this.graph.view.getState(model.getChildAt(state.cell, i)), dx, dy, visitor);
}
}
};
mxCellStatePreview.prototype.addEdges = function(state)
{
var model = this.graph.getModel();
var edgeCount = model.getEdgeCount(state.cell);
for (var i = 0; i < edgeCount; i++)
{
var s = state.view.getState(model.getEdgeAt(state.cell, i));
if (s != null)
{
this.moveState(s, 0, 0);
}
}
};
__mxOutput.mxCellStatePreview = typeof mxCellStatePreview !== 'undefined' ? mxCellStatePreview : undefined;
function mxConnectionConstraint(point, perimeter, name, dx, dy)
{
this.point = point;
this.perimeter = (perimeter != null) ? perimeter : true;
this.name = name;
this.dx = dx? dx : 0;
this.dy = dy? dy : 0;
} mxConnectionConstraint.prototype.point = null;
mxConnectionConstraint.prototype.perimeter = null;
mxConnectionConstraint.prototype.name = null;
mxConnectionConstraint.prototype.dx = null;
mxConnectionConstraint.prototype.dy = null;
__mxOutput.mxConnectionConstraint = typeof mxConnectionConstraint !== 'undefined' ? mxConnectionConstraint : undefined;
function mxGraphHandler(graph)
{
this.graph = graph;
this.graph.addMouseListener(this);
this.panHandler = mxUtils.bind(this, function()
{
if (!this.suspended)
{
this.updatePreview();
this.updateHint();
}
});
this.graph.addListener(mxEvent.PAN, this.panHandler);
this.escapeHandler = mxUtils.bind(this, function(sender, evt)
{
this.reset();
});
this.graph.addListener(mxEvent.ESCAPE, this.escapeHandler);
this.refreshHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.refreshThread)
{
window.clearTimeout(this.refreshThread);
}
this.refreshThread = window.setTimeout(mxUtils.bind(this, function()
{
this.refreshThread = null;
if (this.first != null && !this.suspended)
{
var dx = this.currentDx;
var dy = this.currentDy;
this.currentDx = 0;
this.currentDy = 0;
this.updatePreview();
this.bounds = this.graph.getView().getBounds(this.cells);
this.pBounds = this.getPreviewBounds(this.cells);
if (this.pBounds == null && !this.livePreviewUsed)
{
this.reset();
}
else
{
this.currentDx = dx;
this.currentDy = dy;
this.updatePreview();
this.updateHint();
if (this.livePreviewUsed)
{
this.setHandlesVisibleForCells(
this.graph.selectionCellsHandler.
getHandledSelectionCells(), false, true);
this.updatePreview();
}
}
}
}), 0);
});
this.graph.getModel().addListener(mxEvent.CHANGE, this.refreshHandler);
this.graph.addListener(mxEvent.REFRESH, this.refreshHandler);
this.keyHandler = mxUtils.bind(this, function(e)
{
if (this.graph.container != null && this.graph.container.style.visibility != 'hidden' &&
this.first != null && !this.suspended)
{
var clone = this.graph.isCloneEvent(e) &&
this.graph.isCellsCloneable() &&
this.isCloneEnabled();
if (clone != this.cloning)
{
this.cloning = clone;
this.checkPreview();
this.updatePreview();
}
}
});
mxEvent.addListener(document, 'keydown', this.keyHandler);
mxEvent.addListener(document, 'keyup', this.keyHandler);
} mxGraphHandler.prototype.graph = null;
mxGraphHandler.prototype.maxCells = (mxClient.IS_IE) ? 20 : 50;
mxGraphHandler.prototype.enabled = true;
mxGraphHandler.prototype.highlightEnabled = true;
mxGraphHandler.prototype.cloneEnabled = true;
mxGraphHandler.prototype.moveEnabled = true;
mxGraphHandler.prototype.guidesEnabled = false;
mxGraphHandler.prototype.handlesVisible = true;
mxGraphHandler.prototype.guide = null;
mxGraphHandler.prototype.currentDx = null;
mxGraphHandler.prototype.currentDy = null;
mxGraphHandler.prototype.updateCursor = true;
mxGraphHandler.prototype.selectEnabled = true;
mxGraphHandler.prototype.removeCellsFromParent = true;
mxGraphHandler.prototype.removeEmptyParents = false;
mxGraphHandler.prototype.connectOnDrop = false;
mxGraphHandler.prototype.scrollOnMove = true;
mxGraphHandler.prototype.minimumSize = 6;
mxGraphHandler.prototype.previewColor = 'black';
mxGraphHandler.prototype.htmlPreview = false;
mxGraphHandler.prototype.shape = null;
mxGraphHandler.prototype.scaleGrid = false;
mxGraphHandler.prototype.rotationEnabled = true;
mxGraphHandler.prototype.maxLivePreview = 0;
mxGraphHandler.prototype.allowLivePreview = mxClient.IS_SVG;
mxGraphHandler.prototype.isEnabled = function()
{
return this.enabled;
};
mxGraphHandler.prototype.setEnabled = function(value)
{
this.enabled = value;
};
mxGraphHandler.prototype.isCloneEnabled = function()
{
return this.cloneEnabled;
};
mxGraphHandler.prototype.setCloneEnabled = function(value)
{
this.cloneEnabled = value;
};
mxGraphHandler.prototype.isMoveEnabled = function()
{
return this.moveEnabled;
};
mxGraphHandler.prototype.setMoveEnabled = function(value)
{
this.moveEnabled = value;
};
mxGraphHandler.prototype.isSelectEnabled = function()
{
return this.selectEnabled;
};
mxGraphHandler.prototype.setSelectEnabled = function(value)
{
this.selectEnabled = value;
};
mxGraphHandler.prototype.isRemoveCellsFromParent = function()
{
return this.removeCellsFromParent;
};
mxGraphHandler.prototype.setRemoveCellsFromParent = function(value)
{
this.removeCellsFromParent = value;
};
mxGraphHandler.prototype.isPropagateSelectionCell = function(cell, immediate, me)
{
var parent = this.graph.model.getParent(cell);
if (immediate)
{
var geo = (this.graph.model.isEdge(cell)) ? null :
this.graph.getCellGeometry(cell);
return !this.graph.isSiblingSelected(cell) &&
((geo != null && geo.relative) ||
!this.graph.isSwimlane(parent));
}
else
{
return (!this.graph.isToggleEvent(me.getEvent()) ||
(!this.graph.isSiblingSelected(cell) &&
!this.graph.isCellSelected(cell) &&
(!this.graph.isSwimlane(parent)) ||
this.graph.isCellSelected(parent))) &&
(this.graph.isToggleEvent(me.getEvent()) ||
!this.graph.isCellSelected(parent));
}
};
mxGraphHandler.prototype.getInitialCellForEvent = function(me)
{
var state = me.getState();
if ((!this.graph.isToggleEvent(me.getEvent()) || !mxEvent.isAltDown(me.getEvent())) &&
state != null && !this.graph.isCellSelected(state.cell))
{
var model = this.graph.model;
var next = this.graph.view.getState(model.getParent(state.cell));
while (next != null && !this.graph.isCellSelected(next.cell) &&
(model.isVertex(next.cell) || model.isEdge(next.cell)) &&
this.isPropagateSelectionCell(state.cell, true, me))
{
state = next;
next = this.graph.view.getState(this.graph.getModel().getParent(state.cell));
}
}
return (state != null) ? state.cell : null;
};
mxGraphHandler.prototype.isDelayedSelection = function(cell, me)
{
if (!this.graph.isToggleEvent(me.getEvent()) || !mxEvent.isAltDown(me.getEvent()))
{
while (cell != null)
{
if (this.graph.selectionCellsHandler.isHandled(cell))
{
return this.graph.cellEditor.getEditingCell() != cell;
}
cell = this.graph.model.getParent(cell);
}
}
return this.graph.isToggleEvent(me.getEvent()) && !mxEvent.isAltDown(me.getEvent());
};
mxGraphHandler.prototype.selectDelayed = function(me)
{
if (!this.graph.popupMenuHandler.isPopupTrigger(me))
{
var cell = me.getCell();
if (cell == null)
{
cell = this.cell;
}
this.selectCellForEvent(cell, me);
}
};
mxGraphHandler.prototype.selectCellForEvent = function(cell, me)
{
var state = this.graph.view.getState(cell);
if (state != null)
{
if (me.isSource(state.control))
{
this.graph.selectCellForEvent(cell, me.getEvent());
}
else
{
if (!this.graph.isToggleEvent(me.getEvent()) ||
!mxEvent.isAltDown(me.getEvent()))
{
var model = this.graph.getModel();
var parent = model.getParent(cell);
while (this.graph.view.getState(parent) != null &&
(model.isVertex(parent) || model.isEdge(parent)) &&
this.isPropagateSelectionCell(cell, false, me))
{
cell = parent;
parent = model.getParent(cell);
}
}
this.graph.selectCellForEvent(cell, me.getEvent());
}
}
return cell;
};
mxGraphHandler.prototype.consumeMouseEvent = function(evtName, me)
{
me.consume();
};
mxGraphHandler.prototype.mouseDown = function(sender, me)
{
if (!me.isConsumed() && this.isEnabled() && this.graph.isEnabled() &&
me.getState() != null && !mxEvent.isMultiTouchEvent(me.getEvent()))
{
var cell = this.getInitialCellForEvent(me);
this.delayedSelection = this.isDelayedSelection(cell, me);
this.cell = null;
if (this.isSelectEnabled() && !this.delayedSelection)
{
this.graph.selectCellForEvent(cell, me.getEvent());
}
if (this.isMoveEnabled())
{
var model = this.graph.model;
var geo = model.getGeometry(cell);
if (this.graph.isCellMovable(cell) && ((!model.isEdge(cell) || this.graph.getSelectionCount() > 1 ||
(geo.points != null && geo.points.length > 0) || model.getTerminal(cell, true) == null ||
model.getTerminal(cell, false) == null) || this.graph.allowDanglingEdges ||
(this.graph.isCloneEvent(me.getEvent()) && this.graph.isCellsCloneable())))
{
this.start(cell, me.getX(), me.getY());
}
else if (this.delayedSelection)
{
this.cell = cell;
}
this.cellWasClicked = true;
this.consumeMouseEvent(mxEvent.MOUSE_DOWN, me);
}
}
};
mxGraphHandler.prototype.getGuideStates = function()
{
var parent = this.graph.getDefaultParent();
var model = this.graph.getModel();
var filter = mxUtils.bind(this, function(cell)
{
return this.graph.view.getState(cell) != null &&
model.isVertex(cell) &&
model.getGeometry(cell) != null &&
!model.getGeometry(cell).relative;
});
return this.graph.view.getCellStates(model.filterDescendants(filter, parent));
};
mxGraphHandler.prototype.getCells = function(initialCell)
{
if (!this.delayedSelection && this.graph.isCellMovable(initialCell))
{
return [initialCell];
}
else
{
return this.graph.getMovableCells(this.graph.getSelectionCells());
}
};
mxGraphHandler.prototype.getPreviewBounds = function(cells)
{
var bounds = this.getBoundingBox(cells);
if (bounds != null)
{
bounds.width = Math.max(0, bounds.width - 1);
bounds.height = Math.max(0, bounds.height - 1);
if (bounds.width < this.minimumSize)
{
var dx = this.minimumSize - bounds.width;
bounds.x -= dx / 2;
bounds.width = this.minimumSize;
}
else
{
bounds.x = Math.round(bounds.x);
bounds.width = Math.ceil(bounds.width);
}
this.graph.view.translate;
this.graph.view.scale;
if (bounds.height < this.minimumSize)
{
var dy = this.minimumSize - bounds.height;
bounds.y -= dy / 2;
bounds.height = this.minimumSize;
}
else
{
bounds.y = Math.round(bounds.y);
bounds.height = Math.ceil(bounds.height);
}
}
return bounds;
};
mxGraphHandler.prototype.getBoundingBox = function(cells)
{
var result = null;
if (cells != null && cells.length > 0)
{
var model = this.graph.getModel();
for (var i = 0; i < cells.length; i++)
{
if (model.isVertex(cells[i]) || model.isEdge(cells[i]))
{
var state = this.graph.view.getState(cells[i]);
if (state != null)
{
var bbox = state;
if (model.isVertex(cells[i]) && state.shape != null && state.shape.boundingBox != null)
{
bbox = state.shape.boundingBox;
}
if (result == null)
{
result = mxRectangle.fromRectangle(bbox);
}
else
{
result.add(bbox);
}
}
}
}
}
return result;
};
mxGraphHandler.prototype.createPreviewShape = function(bounds)
{
var shape = new mxRectangleShape(bounds, null, this.previewColor);
shape.isDashed = true;
if (this.htmlPreview)
{
shape.dialect = mxConstants.DIALECT_STRICTHTML;
shape.init(this.graph.container);
}
else
{
shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
shape.init(this.graph.getView().getOverlayPane());
shape.pointerEvents = false;
if (mxClient.IS_IOS)
{
shape.getSvgScreenOffset = function()
{
return 0;
};
}
}
return shape;
};
mxGraphHandler.prototype.start = function(cell, x, y, cells)
{
this.cell = cell;
this.first = mxUtils.convertPoint(this.graph.container, x, y);
this.cells = (cells != null) ? cells : this.getCells(this.cell);
this.bounds = this.graph.getView().getBounds(this.cells);
this.pBounds = this.getPreviewBounds(this.cells);
this.allCells = new mxDictionary();
this.cloning = false;
this.cellCount = 0;
for (var i = 0; i < this.cells.length; i++)
{
this.cellCount += this.addStates(this.cells[i], this.allCells);
}
if (this.guidesEnabled)
{
this.guide = new mxGuide(this.graph, this.getGuideStates());
var parent = this.graph.model.getParent(cell);
var ignore = this.graph.model.getChildCount(parent) < 2;
var connected = new mxDictionary();
var opps = this.graph.getOpposites(this.graph.getEdges(this.cell), this.cell);
for (var i = 0; i < opps.length; i++)
{
var state = this.graph.view.getState(opps[i]);
if (state != null && !connected.get(state))
{
connected.put(state, true);
}
}
this.guide.isStateIgnored = mxUtils.bind(this, function(state)
{
var p = this.graph.model.getParent(state.cell);
return state.cell != null && ((!this.cloning &&
this.isCellMoving(state.cell)) ||
(state.cell != (this.target || parent) && !ignore &&
!connected.get(state) &&
(this.target == null || this.graph.model.getChildCount(
this.target) >= 2) && p != (this.target || parent)));
});
}
};
mxGraphHandler.prototype.addStates = function(cell, dict)
{
var state = this.graph.view.getState(cell);
var count = 0;
if (state != null && dict.get(cell) == null)
{
dict.put(cell, state);
count++;
var childCount = this.graph.model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
count += this.addStates(this.graph.model.getChildAt(cell, i), dict);
}
}
return count;
};
mxGraphHandler.prototype.isCellMoving = function(cell)
{
return this.allCells.get(cell) != null;
};
mxGraphHandler.prototype.useGuidesForEvent = function(me)
{
return (this.guide != null) ? this.guide.isEnabledForEvent(me.getEvent()) &&
!this.graph.isConstrainedEvent(me.getEvent()) : true;
};
mxGraphHandler.prototype.snap = function(vector)
{
var scale = (this.scaleGrid) ? this.graph.view.scale : 1;
vector.x = this.graph.snap(vector.x / scale) * scale;
vector.y = this.graph.snap(vector.y / scale) * scale;
return vector;
};
mxGraphHandler.prototype.getDelta = function(me)
{
var point = mxUtils.convertPoint(this.graph.container, me.getX(), me.getY());
return new mxPoint(point.x - this.first.x - this.graph.panDx,
point.y - this.first.y - this.graph.panDy);
};
mxGraphHandler.prototype.updateHint = function(me) { };
mxGraphHandler.prototype.removeHint = function() { };
mxGraphHandler.prototype.roundLength = function(length)
{
return Math.round(length * 100) / 100;
};
mxGraphHandler.prototype.isValidDropTarget = function(target, me)
{
return this.graph.model.getParent(this.cell) != target;
};
mxGraphHandler.prototype.checkPreview = function()
{
if (this.livePreviewActive && this.cloning)
{
this.resetLivePreview();
this.livePreviewActive = false;
}
else if (this.maxLivePreview >= this.cellCount && !this.livePreviewActive && this.allowLivePreview)
{
if (!this.cloning || !this.livePreviewActive)
{
this.livePreviewActive = true;
this.livePreviewUsed = true;
}
}
else if (!this.livePreviewUsed && this.shape == null)
{
this.shape = this.createPreviewShape(this.bounds);
}
};
mxGraphHandler.prototype.mouseMove = function(sender, me)
{
var graph = this.graph;
if (!me.isConsumed() && graph.isMouseDown && this.cell != null &&
this.first != null && this.bounds != null && !this.suspended)
{
if (mxEvent.isMultiTouchEvent(me.getEvent()))
{
this.reset();
return;
}
var delta = this.getDelta(me);
var tol = graph.tolerance;
if (this.shape != null || this.livePreviewActive || Math.abs(delta.x) > tol || Math.abs(delta.y) > tol)
{
if (this.highlight == null)
{
this.highlight = new mxCellHighlight(this.graph,
mxConstants.DROP_TARGET_COLOR, 3);
}
var clone = graph.isCloneEvent(me.getEvent()) && graph.isCellsCloneable() && this.isCloneEnabled();
var gridEnabled = graph.isGridEnabledEvent(me.getEvent());
var cell = me.getCell();
var hideGuide = true;
var target = null;
this.cloning = clone;
if (graph.isDropEnabled() && this.highlightEnabled)
{
target = graph.getDropTarget(this.cells, me.getEvent(), cell, clone);
}
var state = graph.getView().getState(target);
var highlight = false;
if (state != null && (clone || this.isValidDropTarget(target, me)))
{
if (this.target != target)
{
this.target = target;
this.setHighlightColor(mxConstants.DROP_TARGET_COLOR);
}
highlight = true;
}
else
{
this.target = null;
if (this.connectOnDrop && cell != null && this.cells.length == 1 &&
graph.getModel().isVertex(cell) && graph.isCellConnectable(cell))
{
state = graph.getView().getState(cell);
if (state != null)
{
var error = graph.getEdgeValidationError(null, this.cell, cell);
var color = (error == null) ?
mxConstants.VALID_COLOR :
mxConstants.INVALID_CONNECT_TARGET_COLOR;
this.setHighlightColor(color);
highlight = true;
}
}
}
if (state != null && highlight)
{
this.highlight.highlight(state);
}
else
{
this.highlight.hide();
}
if (this.guide != null && this.useGuidesForEvent(me))
{
delta = this.guide.move(this.bounds, delta, gridEnabled, clone);
hideGuide = false;
}
else
{
delta = this.graph.snapDelta(delta, this.bounds, !gridEnabled, false, false);
}
if (this.guide != null && hideGuide)
{
this.guide.hide();
}
if (graph.isConstrainedEvent(me.getEvent()))
{
if (Math.abs(delta.x) > Math.abs(delta.y))
{
delta.y = 0;
}
else
{
delta.x = 0;
}
}
this.checkPreview();
if (this.currentDx != delta.x || this.currentDy != delta.y)
{
this.currentDx = delta.x;
this.currentDy = delta.y;
this.updatePreview();
}
}
this.updateHint(me);
this.consumeMouseEvent(mxEvent.MOUSE_MOVE, me);
mxEvent.consume(me.getEvent());
}
else if ((this.isMoveEnabled() || this.isCloneEnabled()) && this.updateCursor && !me.isConsumed() &&
(me.getState() != null || me.sourceState != null) && !graph.isMouseDown)
{
var cursor = graph.getCursorForMouseEvent(me);
if (cursor == null && graph.isEnabled() && graph.isCellMovable(me.getCell()))
{
if (graph.getModel().isEdge(me.getCell()))
{
cursor = mxConstants.CURSOR_MOVABLE_EDGE;
}
else
{
cursor = mxConstants.CURSOR_MOVABLE_VERTEX;
}
}
if (cursor != null && me.sourceState != null)
{
me.sourceState.setCursor(cursor);
}
}
};
mxGraphHandler.prototype.updatePreview = function(remote)
{
if (this.livePreviewUsed && !remote)
{
if (this.cells != null)
{
this.setHandlesVisibleForCells(
this.graph.selectionCellsHandler.
getHandledSelectionCells(), false);
this.updateLivePreview(this.currentDx, this.currentDy);
}
}
else
{
this.updatePreviewShape();
}
};
mxGraphHandler.prototype.updatePreviewShape = function()
{
if (this.shape != null && this.pBounds != null)
{
this.shape.bounds = new mxRectangle(Math.round(this.pBounds.x + this.currentDx),
Math.round(this.pBounds.y + this.currentDy), this.pBounds.width, this.pBounds.height);
this.shape.redraw();
}
};
mxGraphHandler.prototype.updateLivePreview = function(dx, dy)
{
if (!this.suspended)
{
var states = [];
if (this.allCells != null)
{
this.allCells.visit(mxUtils.bind(this, function(key, state)
{
var realState = this.graph.view.getState(state.cell);
if (realState != state)
{
state.destroy();
if (realState != null)
{
this.allCells.put(state.cell, realState);
}
else
{
this.allCells.remove(state.cell);
}
state = realState;
}
if (state != null)
{
var tempState = state.clone();
states.push([state, tempState]);
if (state.shape != null)
{
if (state.shape.originalPointerEvents == null)
{
state.shape.originalPointerEvents = state.shape.pointerEvents;
}
state.shape.pointerEvents = false;
if (state.text != null)
{
if (state.text.originalPointerEvents == null)
{
state.text.originalPointerEvents = state.text.pointerEvents;
}
state.text.pointerEvents = false;
}
}
if (this.graph.model.isVertex(state.cell))
{
state.x += dx;
state.y += dy;
if (!this.cloning)
{
state.view.graph.cellRenderer.redraw(state, true);
state.view.invalidate(state.cell);
state.invalid = false;
if (state.control != null && state.control.node != null)
{
state.control.node.style.visibility = 'hidden';
}
}
else if (state.text != null)
{
state.text.updateBoundingBox();
if (state.text.boundingBox != null)
{
state.text.boundingBox.x += dx;
state.text.boundingBox.y += dy;
}
if (state.text.unrotatedBoundingBox != null)
{
state.text.unrotatedBoundingBox.x += dx;
state.text.unrotatedBoundingBox.y += dy;
}
}
}
}
}));
}
if (states.length == 0)
{
this.reset();
}
else
{
var s = this.graph.view.scale;
for (var i = 0; i < states.length; i++)
{
var state = states[i][0];
if (this.graph.model.isEdge(state.cell))
{
var geometry = this.graph.getCellGeometry(state.cell);
var points = [];
if (geometry != null && geometry.points != null)
{
for (var j = 0; j < geometry.points.length; j++)
{
if (geometry.points[j] != null)
{
points.push(new mxPoint(
geometry.points[j].x + dx / s,
geometry.points[j].y + dy / s));
}
}
}
var source = state.visibleSourceState;
var target = state.visibleTargetState;
var pts = states[i][1].absolutePoints;
if (source == null || !this.isCellMoving(source.cell))
{
var pt0 = pts[0];
state.setAbsoluteTerminalPoint(new mxPoint(pt0.x + dx, pt0.y + dy), true);
source = null;
}
else
{
state.view.updateFixedTerminalPoint(state, source, true,
this.graph.getConnectionConstraint(state, source, true));
}
if (target == null || !this.isCellMoving(target.cell))
{
var ptn = pts[pts.length - 1];
state.setAbsoluteTerminalPoint(new mxPoint(ptn.x + dx, ptn.y + dy), false);
target = null;
}
else
{
state.view.updateFixedTerminalPoint(state, target, false,
this.graph.getConnectionConstraint(state, target, false));
}
state.view.updatePoints(state, points, source, target);
state.view.updateFloatingTerminalPoints(state, source, target);
state.view.updateEdgeLabelOffset(state);
state.invalid = false;
if (!this.cloning)
{
state.view.graph.cellRenderer.redraw(state, true);
}
}
}
this.graph.view.validate();
this.redrawHandles(states);
this.resetPreviewStates(states);
}
}
};
mxGraphHandler.prototype.redrawHandles = function(states)
{
for (var i = 0; i < states.length; i++)
{
var handler = this.graph.selectionCellsHandler.getHandler(states[i][0].cell);
if (handler != null)
{
handler.redraw(true);
}
}
};
mxGraphHandler.prototype.resetPreviewStates = function(states)
{
for (var i = 0; i < states.length; i++)
{
states[i][0].setState(states[i][1]);
}
};
mxGraphHandler.prototype.suspend = function()
{
if (!this.suspended)
{
if (this.livePreviewUsed)
{
this.updateLivePreview(0, 0);
}
if (this.shape != null)
{
this.shape.node.style.visibility = 'hidden';
}
if (this.guide != null)
{
this.guide.setVisible(false);
}
this.suspended = true;
}
};
mxGraphHandler.prototype.resume = function()
{
if (this.suspended)
{
this.suspended = null;
if (this.livePreviewUsed)
{
this.livePreviewActive = true;
}
if (this.shape != null)
{
this.shape.node.style.visibility = 'visible';
}
if (this.guide != null)
{
this.guide.setVisible(true);
}
}
};
mxGraphHandler.prototype.resetLivePreview = function()
{
if (this.allCells != null)
{
this.allCells.visit(mxUtils.bind(this, function(key, state)
{
if (state.shape != null && state.shape.originalPointerEvents != null)
{
state.shape.pointerEvents = state.shape.originalPointerEvents;
state.shape.originalPointerEvents = null;
state.shape.bounds = null;
if (state.text != null)
{
state.text.pointerEvents = state.text.originalPointerEvents;
state.text.originalPointerEvents = null;
}
}
if (state.control != null && state.control.node != null &&
state.control.node.style.visibility == 'hidden')
{
state.control.node.style.visibility = '';
}
if (!this.cloning)
{
if (state.text != null)
{
state.text.updateBoundingBox();
}
}
state.view.invalidate(state.cell);
}));
this.graph.view.validate();
}
};
mxGraphHandler.prototype.setHandlesVisibleForCells = function(cells, visible, force)
{
if (force || this.handlesVisible != visible)
{
this.handlesVisible = visible;
for (var i = 0; i < cells.length; i++)
{
var handler = this.graph.selectionCellsHandler.getHandler(cells[i]);
if (handler != null)
{
handler.setHandlesVisible(visible);
if (visible)
{
handler.redraw();
}
}
}
}
};
mxGraphHandler.prototype.setHighlightColor = function(color)
{
if (this.highlight != null)
{
this.highlight.setHighlightColor(color);
}
};
mxGraphHandler.prototype.mouseUp = function(sender, me)
{
if (!me.isConsumed())
{
if (this.livePreviewUsed)
{
this.resetLivePreview();
}
if (this.cell != null && this.first != null && (this.shape != null || this.livePreviewUsed) &&
this.currentDx != null && this.currentDy != null)
{
var graph = this.graph;
var cell = me.getCell();
if (this.connectOnDrop && this.target == null && cell != null && graph.getModel().isVertex(cell) &&
graph.isCellConnectable(cell) && graph.isEdgeValid(null, this.cell, cell))
{
graph.connectionHandler.connect(this.cell, cell, me.getEvent());
}
else
{
var clone = graph.isCloneEvent(me.getEvent()) && graph.isCellsCloneable() && this.isCloneEnabled();
var scale = graph.getView().scale;
var dx = this.roundLength(this.currentDx / scale);
var dy = this.roundLength(this.currentDy / scale);
var target = this.target;
if (graph.isSplitEnabled() && graph.isSplitTarget(target, this.cells, me.getEvent()))
{
graph.splitEdge(target, this.cells, null, dx, dy,
me.getGraphX(), me.getGraphY());
}
else
{
this.moveCells(this.cells, dx, dy, clone, this.target, me.getEvent());
}
}
}
else if (this.isSelectEnabled() && this.delayedSelection && this.cell != null)
{
this.selectDelayed(me);
}
}
if (this.cellWasClicked)
{
this.consumeMouseEvent(mxEvent.MOUSE_UP, me);
}
this.reset();
};
mxGraphHandler.prototype.reset = function()
{
if (this.livePreviewUsed)
{
this.resetLivePreview();
this.setHandlesVisibleForCells(
this.graph.selectionCellsHandler.
getHandledSelectionCells(), true);
}
this.destroyShapes();
this.removeHint();
this.delayedSelection = false;
this.livePreviewActive = null;
this.livePreviewUsed = null;
this.cellWasClicked = false;
this.suspended = null;
this.currentDx = null;
this.currentDy = null;
this.cellCount = null;
this.cloning = false;
this.allCells = null;
this.pBounds = null;
this.guides = null;
this.target = null;
this.first = null;
this.cells = null;
this.cell = null;
};
mxGraphHandler.prototype.shouldRemoveCellsFromParent = function(parent, cells, evt)
{
if (this.graph.getModel().isVertex(parent))
{
var pState = this.graph.getView().getState(parent);
if (pState != null)
{
var pt = mxUtils.convertPoint(this.graph.container,
mxEvent.getClientX(evt), mxEvent.getClientY(evt));
var alpha = mxUtils.toRadians(mxUtils.getValue(pState.style, mxConstants.STYLE_ROTATION) || 0);
if (alpha != 0)
{
var cos = Math.cos(-alpha);
var sin = Math.sin(-alpha);
var cx = new mxPoint(pState.getCenterX(), pState.getCenterY());
pt = mxUtils.getRotatedPoint(pt, cos, sin, cx);
}
return !mxUtils.contains(pState, pt.x, pt.y);
}
}
return false;
};
mxGraphHandler.prototype.moveCells = function(cells, dx, dy, clone, target, evt)
{
if (clone)
{
cells = this.graph.getCloneableCells(cells);
}
var parent = this.graph.getModel().getParent(this.cell);
if (target == null && this.isRemoveCellsFromParent() &&
this.shouldRemoveCellsFromParent(parent, cells, evt))
{
target = this.graph.getDefaultParent();
}
clone = clone && !this.graph.isCellLocked(target || this.graph.getDefaultParent());
this.graph.getModel().beginUpdate();
try
{
var parents = [];
if (!clone && target != null && this.removeEmptyParents)
{
var dict = new mxDictionary();
for (var i = 0; i < cells.length; i++)
{
dict.put(cells[i], true);
}
for (var i = 0; i < cells.length; i++)
{
var par = this.graph.model.getParent(cells[i]);
if (par != null && !dict.get(par))
{
dict.put(par, true);
parents.push(par);
}
}
}
cells = this.graph.moveCells(cells, dx, dy, clone, target, evt);
var temp = [];
for (var i = 0; i < parents.length; i++)
{
if (this.shouldRemoveParent(parents[i]))
{
temp.push(parents[i]);
}
}
this.graph.removeCells(temp, false);
}
finally
{
this.graph.getModel().endUpdate();
}
if (clone)
{
this.graph.setSelectionCells(cells);
}
if (this.isSelectEnabled() && this.scrollOnMove)
{
this.graph.scrollCellToVisible(cells[0]);
}
};
mxGraphHandler.prototype.shouldRemoveParent = function(parent)
{
var state = this.graph.view.getState(parent);
return state != null && (this.graph.model.isEdge(state.cell) || this.graph.model.isVertex(state.cell)) &&
this.graph.isCellDeletable(state.cell) && this.graph.model.getChildCount(state.cell) == 0 &&
this.graph.isTransparentState(state);
};
mxGraphHandler.prototype.destroyShapes = function()
{
if (this.shape != null)
{
this.shape.destroy();
this.shape = null;
}
if (this.guide != null)
{
this.guide.destroy();
this.guide = null;
}
if (this.highlight != null)
{
this.highlight.destroy();
this.highlight = null;
}
};
mxGraphHandler.prototype.destroy = function()
{
this.graph.removeMouseListener(this);
this.graph.removeListener(this.panHandler);
if (this.escapeHandler != null)
{
this.graph.removeListener(this.escapeHandler);
this.escapeHandler = null;
}
if (this.refreshHandler != null)
{
this.graph.getModel().removeListener(this.refreshHandler);
this.graph.removeListener(this.refreshHandler);
this.refreshHandler = null;
}
mxEvent.removeListener(document, 'keydown', this.keyHandler);
mxEvent.removeListener(document, 'keyup', this.keyHandler);
this.destroyShapes();
this.removeHint();
};
__mxOutput.mxGraphHandler = typeof mxGraphHandler !== 'undefined' ? mxGraphHandler : undefined;
function mxPanningHandler(graph)
{
if (graph != null)
{
this.graph = graph;
this.graph.addMouseListener(this);
this.forcePanningHandler = mxUtils.bind(this, function(sender, evt)
{
var evtName = evt.getProperty('eventName');
var me = evt.getProperty('event');
if (evtName == mxEvent.MOUSE_DOWN && this.isForcePanningEvent(me))
{
this.start(me);
this.active = true;
this.fireEvent(new mxEventObject(mxEvent.PAN_START, 'event', me));
me.consume();
}
});
this.graph.addListener(mxEvent.FIRE_MOUSE_EVENT, this.forcePanningHandler);
this.gestureHandler = mxUtils.bind(this, function(sender, eo)
{
if (this.isPinchEnabled())
{
var evt = eo.getProperty('event');
if (!mxEvent.isConsumed(evt) && evt.type == 'gesturestart')
{
this.initialScale = this.graph.view.scale;
if (!this.active && this.mouseDownEvent != null)
{
this.start(this.mouseDownEvent);
this.mouseDownEvent = null;
}
}
else if (evt.type == 'gestureend' && this.initialScale != null)
{
this.initialScale = null;
}
if (this.initialScale != null)
{
this.zoomGraph(evt);
}
}
});
this.graph.addListener(mxEvent.GESTURE, this.gestureHandler);
this.mouseUpListener = mxUtils.bind(this, function()
{
if (this.active)
{
this.reset();
}
});
mxEvent.addListener(document, 'mouseup', this.mouseUpListener);
}
} mxPanningHandler.prototype = new mxEventSource();
mxPanningHandler.prototype.constructor = mxPanningHandler;
mxPanningHandler.prototype.graph = null;
mxPanningHandler.prototype.useLeftButtonForPanning = false;
mxPanningHandler.prototype.usePopupTrigger = true;
mxPanningHandler.prototype.ignoreCell = false;
mxPanningHandler.prototype.previewEnabled = true;
mxPanningHandler.prototype.useGrid = false;
mxPanningHandler.prototype.panningEnabled = true;
mxPanningHandler.prototype.pinchEnabled = true;
mxPanningHandler.prototype.maxScale = 8;
mxPanningHandler.prototype.minScale = 0.01;
mxPanningHandler.prototype.dx = null;
mxPanningHandler.prototype.dy = null;
mxPanningHandler.prototype.startX = 0;
mxPanningHandler.prototype.startY = 0;
mxPanningHandler.prototype.isActive = function()
{
return this.active || this.initialScale != null;
};
mxPanningHandler.prototype.isPanningEnabled = function()
{
return this.panningEnabled;
};
mxPanningHandler.prototype.setPanningEnabled = function(value)
{
this.panningEnabled = value;
};
mxPanningHandler.prototype.isPinchEnabled = function()
{
return this.pinchEnabled;
};
mxPanningHandler.prototype.setPinchEnabled = function(value)
{
this.pinchEnabled = value;
};
mxPanningHandler.prototype.isPanningTrigger = function(me)
{
var evt = me.getEvent();
return (this.useLeftButtonForPanning && me.getState() == null &&
mxEvent.isLeftMouseButton(evt)) || (mxEvent.isControlDown(evt) &&
mxEvent.isShiftDown(evt)) || (this.usePopupTrigger && mxEvent.isPopupTrigger(evt));
};
mxPanningHandler.prototype.isForcePanningEvent = function(me)
{
return this.ignoreCell || mxEvent.isMultiTouchEvent(me.getEvent());
};
mxPanningHandler.prototype.mouseDown = function(sender, me)
{
this.mouseDownEvent = me;
if (!me.isConsumed() && this.isPanningEnabled() && !this.active && this.isPanningTrigger(me))
{
this.start(me);
this.consumePanningTrigger(me);
}
};
mxPanningHandler.prototype.start = function(me)
{
this.dx0 = -this.graph.container.scrollLeft;
this.dy0 = -this.graph.container.scrollTop;
this.startX = me.getX();
this.startY = me.getY();
this.dx = null;
this.dy = null;
this.panningTrigger = true;
};
mxPanningHandler.prototype.consumePanningTrigger = function(me)
{
me.consume();
};
mxPanningHandler.prototype.mouseMove = function(sender, me)
{
this.dx = me.getX() - this.startX;
this.dy = me.getY() - this.startY;
if (this.active)
{
if (this.previewEnabled)
{
if (this.useGrid)
{
this.dx = this.graph.snap(this.dx);
this.dy = this.graph.snap(this.dy);
}
this.graph.panGraph(this.dx + this.dx0, this.dy + this.dy0);
}
this.fireEvent(new mxEventObject(mxEvent.PAN, 'event', me));
}
else if (this.panningTrigger)
{
var tmp = this.active;
this.active = Math.abs(this.dx) > this.graph.tolerance || Math.abs(this.dy) > this.graph.tolerance;
if (!tmp && this.active)
{
this.fireEvent(new mxEventObject(mxEvent.PAN_START, 'event', me));
}
}
if (this.active || this.panningTrigger)
{
me.consume();
}
};
mxPanningHandler.prototype.mouseUp = function(sender, me)
{
if (this.active)
{
if (this.dx != null && this.dy != null)
{
if (!this.graph.useScrollbarsForPanning || !mxUtils.hasScrollbars(this.graph.container))
{
var scale = this.graph.getView().scale;
var t = this.graph.getView().translate;
this.graph.panGraph(0, 0);
this.panGraph(t.x + this.dx / scale, t.y + this.dy / scale);
}
me.consume();
}
this.fireEvent(new mxEventObject(mxEvent.PAN_END, 'event', me));
}
this.reset();
};
mxPanningHandler.prototype.zoomGraph = function(evt)
{
var value = Math.round(this.initialScale * evt.scale * 100) / 100;
if (this.minScale != null)
{
value = Math.max(this.minScale, value);
}
if (this.maxScale != null)
{
value = Math.min(this.maxScale, value);
}
if (this.graph.view.scale != value)
{
this.graph.zoomTo(value);
mxEvent.consume(evt);
}
};
mxPanningHandler.prototype.reset = function()
{
this.panningTrigger = false;
this.mouseDownEvent = null;
this.active = false;
this.dx = null;
this.dy = null;
};
mxPanningHandler.prototype.panGraph = function(dx, dy)
{
this.graph.getView().setTranslate(dx, dy);
};
mxPanningHandler.prototype.destroy = function()
{
this.graph.removeMouseListener(this);
this.graph.removeListener(this.forcePanningHandler);
this.graph.removeListener(this.gestureHandler);
mxEvent.removeListener(document, 'mouseup', this.mouseUpListener);
};
__mxOutput.mxPanningHandler = typeof mxPanningHandler !== 'undefined' ? mxPanningHandler : undefined;
function mxPopupMenuHandler(graph, factoryMethod)
{
if (graph != null)
{
this.graph = graph;
this.factoryMethod = factoryMethod;
this.graph.addMouseListener(this);
this.gestureHandler = mxUtils.bind(this, function(sender, eo)
{
this.inTolerance = false;
});
this.graph.addListener(mxEvent.GESTURE, this.gestureHandler);
this.init();
}
} mxPopupMenuHandler.prototype = new mxPopupMenu();
mxPopupMenuHandler.prototype.constructor = mxPopupMenuHandler;
mxPopupMenuHandler.prototype.graph = null;
mxPopupMenuHandler.prototype.selectOnPopup = true;
mxPopupMenuHandler.prototype.clearSelectionOnBackground = true;
mxPopupMenuHandler.prototype.triggerX = null;
mxPopupMenuHandler.prototype.triggerY = null;
mxPopupMenuHandler.prototype.screenX = null;
mxPopupMenuHandler.prototype.screenY = null;
mxPopupMenuHandler.prototype.init = function()
{
mxPopupMenu.prototype.init.apply(this);
mxEvent.addGestureListeners(this.div, mxUtils.bind(this, function(evt)
{
this.graph.tooltipHandler.hide();
}));
};
mxPopupMenuHandler.prototype.isSelectOnPopup = function(me)
{
return this.selectOnPopup;
};
mxPopupMenuHandler.prototype.mouseDown = function(sender, me)
{
if (this.isEnabled() && !mxEvent.isMultiTouchEvent(me.getEvent()))
{
this.hideMenu();
this.triggerX = me.getGraphX();
this.triggerY = me.getGraphY();
this.screenX = mxEvent.getMainEvent(me.getEvent()).screenX;
this.screenY = mxEvent.getMainEvent(me.getEvent()).screenY;
this.popupTrigger = this.isPopupTrigger(me);
this.inTolerance = true;
}
};
mxPopupMenuHandler.prototype.mouseMove = function(sender, me)
{
if (this.inTolerance && this.screenX != null && this.screenY != null)
{
if (Math.abs(mxEvent.getMainEvent(me.getEvent()).screenX - this.screenX) > this.graph.tolerance ||
Math.abs(mxEvent.getMainEvent(me.getEvent()).screenY - this.screenY) > this.graph.tolerance)
{
this.inTolerance = false;
}
}
};
mxPopupMenuHandler.prototype.mouseUp = function(sender, me)
{
if (this.popupTrigger && this.inTolerance && this.triggerX != null && this.triggerY != null)
{
var cell = this.getCellForPopupEvent(me);
if (this.graph.isEnabled() && this.isSelectOnPopup(me) &&
cell != null && !this.graph.isCellSelected(cell))
{
this.graph.setSelectionCell(cell);
}
else if (this.clearSelectionOnBackground && cell == null)
{
this.graph.clearSelection();
}
this.graph.tooltipHandler.hide();
var origin = mxUtils.getScrollOrigin();
this.popup(me.getX() + origin.x + 1, me.getY() + origin.y + 1, cell, me.getEvent());
me.consume();
}
this.popupTrigger = false;
this.inTolerance = false;
};
mxPopupMenuHandler.prototype.getCellForPopupEvent = function(me)
{
return me.getCell();
};
mxPopupMenuHandler.prototype.destroy = function()
{
this.graph.removeMouseListener(this);
this.graph.removeListener(this.gestureHandler);
mxPopupMenu.prototype.destroy.apply(this);
};
__mxOutput.mxPopupMenuHandler = typeof mxPopupMenuHandler !== 'undefined' ? mxPopupMenuHandler : undefined;
function mxCellMarker(graph, validColor, invalidColor, hotspot)
{
mxEventSource.call(this);
if (graph != null)
{
this.graph = graph;
this.validColor = (validColor != null) ? validColor : mxConstants.DEFAULT_VALID_COLOR;
this.invalidColor = (invalidColor != null) ? invalidColor : mxConstants.DEFAULT_INVALID_COLOR;
this.hotspot = (hotspot != null) ? hotspot : mxConstants.DEFAULT_HOTSPOT;
this.highlight = new mxCellHighlight(graph);
}
} mxUtils.extend(mxCellMarker, mxEventSource);
mxCellMarker.prototype.graph = null;
mxCellMarker.prototype.enabled = true;
mxCellMarker.prototype.hotspot = mxConstants.DEFAULT_HOTSPOT;
mxCellMarker.prototype.hotspotEnabled = false;
mxCellMarker.prototype.validColor = null;
mxCellMarker.prototype.invalidColor = null;
mxCellMarker.prototype.currentColor = null;
mxCellMarker.prototype.validState = null;
mxCellMarker.prototype.markedState = null;
mxCellMarker.prototype.setEnabled = function(enabled)
{
this.enabled = enabled;
};
mxCellMarker.prototype.isEnabled = function()
{
return this.enabled;
};
mxCellMarker.prototype.setHotspot = function(hotspot)
{
this.hotspot = hotspot;
};
mxCellMarker.prototype.getHotspot = function()
{
return this.hotspot;
};
mxCellMarker.prototype.setHotspotEnabled = function(enabled)
{
this.hotspotEnabled = enabled;
};
mxCellMarker.prototype.isHotspotEnabled = function()
{
return this.hotspotEnabled;
};
mxCellMarker.prototype.hasValidState = function()
{
return this.validState != null;
};
mxCellMarker.prototype.getValidState = function()
{
return this.validState;
};
mxCellMarker.prototype.getMarkedState = function()
{
return this.markedState;
};
mxCellMarker.prototype.reset = function()
{
this.validState = null;
if (this.markedState != null)
{
this.markedState = null;
this.unmark();
}
};
mxCellMarker.prototype.process = function(me)
{
var state = null;
if (this.isEnabled())
{
state = this.getState(me);
this.setCurrentState(state, me);
}
return state;
};
mxCellMarker.prototype.setCurrentState = function(state, me, color)
{
var isValid = (state != null) ? this.isValidState(state) : false;
color = (color != null) ? color : this.getMarkerColor(me.getEvent(), state, isValid);
if (isValid)
{
this.validState = state;
}
else
{
this.validState = null;
}
if (state != this.markedState || color != this.currentColor)
{
this.currentColor = color;
if (state != null && this.currentColor != null)
{
this.markedState = state;
this.mark();
}
else if (this.markedState != null)
{
this.markedState = null;
this.unmark();
}
}
};
mxCellMarker.prototype.markCell = function(cell, color)
{
var state = this.graph.getView().getState(cell);
if (state != null)
{
this.currentColor = (color != null) ? color : this.validColor;
this.markedState = state;
this.mark();
}
};
mxCellMarker.prototype.mark = function()
{
this.highlight.setHighlightColor(this.currentColor);
this.highlight.highlight(this.markedState);
this.fireEvent(new mxEventObject(mxEvent.MARK, 'state', this.markedState));
};
mxCellMarker.prototype.unmark = function()
{
this.mark();
};
mxCellMarker.prototype.isValidState = function(state)
{
return true;
};
mxCellMarker.prototype.getMarkerColor = function(evt, state, isValid)
{
return (isValid) ? this.validColor : this.invalidColor;
};
mxCellMarker.prototype.getState = function(me)
{
var view = this.graph.getView();
var cell = this.getCell(me);
var state = this.getStateToMark(view.getState(cell));
return (state != null && this.intersects(state, me)) ? state : null;
};
mxCellMarker.prototype.getCell = function(me)
{
return me.getCell();
};
mxCellMarker.prototype.getStateToMark = function(state)
{
return state;
};
mxCellMarker.prototype.intersects = function(state, me)
{
if (this.hotspotEnabled)
{
return mxUtils.intersectsHotspot(state, me.getGraphX(), me.getGraphY(),
this.hotspot, mxConstants.MIN_HOTSPOT_SIZE,
mxConstants.MAX_HOTSPOT_SIZE);
}
return true;
};
mxCellMarker.prototype.destroy = function()
{
this.graph.getView().removeListener(this.resetHandler);
this.graph.getModel().removeListener(this.resetHandler);
this.highlight.destroy();
};
__mxOutput.mxCellMarker = typeof mxCellMarker !== 'undefined' ? mxCellMarker : undefined;
function mxSelectionCellsHandler(graph)
{
mxEventSource.call(this);
this.graph = graph;
this.handlers = new mxDictionary();
this.graph.addMouseListener(this);
this.refreshHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.isEnabled())
{
this.refresh();
}
});
this.graph.getSelectionModel().addListener(mxEvent.CHANGE, this.refreshHandler);
this.graph.getModel().addListener(mxEvent.CHANGE, this.refreshHandler);
this.graph.getView().addListener(mxEvent.SCALE, this.refreshHandler);
this.graph.getView().addListener(mxEvent.TRANSLATE, this.refreshHandler);
this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.refreshHandler);
this.graph.getView().addListener(mxEvent.DOWN, this.refreshHandler);
this.graph.getView().addListener(mxEvent.UP, this.refreshHandler);
} mxUtils.extend(mxSelectionCellsHandler, mxEventSource);
mxSelectionCellsHandler.prototype.graph = null;
mxSelectionCellsHandler.prototype.enabled = true;
mxSelectionCellsHandler.prototype.refreshHandler = null;
mxSelectionCellsHandler.prototype.maxHandlers = 100;
mxSelectionCellsHandler.prototype.handlers = null;
mxSelectionCellsHandler.prototype.isEnabled = function()
{
return this.enabled;
};
mxSelectionCellsHandler.prototype.setEnabled = function(value)
{
this.enabled = value;
};
mxSelectionCellsHandler.prototype.getHandler = function(cell)
{
return this.handlers.get(cell);
};
mxSelectionCellsHandler.prototype.isHandled = function(cell)
{
return this.getHandler(cell) != null;
};
mxSelectionCellsHandler.prototype.reset = function()
{
this.handlers.visit(function(key, handler)
{
handler.reset.apply(handler);
});
};
mxSelectionCellsHandler.prototype.getHandledSelectionCells = function()
{
return this.graph.getSelectionCells();
};
mxSelectionCellsHandler.prototype.refresh = function()
{
var oldHandlers = this.handlers;
this.handlers = new mxDictionary();
var tmp = mxUtils.sortCells(this.getHandledSelectionCells(), false);
for (var i = 0; i < tmp.length; i++)
{
var state = this.graph.view.getState(tmp[i]);
if (state != null)
{
var handler = oldHandlers.remove(tmp[i]);
if (handler != null)
{
if (handler.state != state)
{
handler.destroy();
handler = null;
}
else if (!this.isHandlerActive(handler))
{
if (handler.refresh != null)
{
handler.refresh();
}
handler.redraw();
}
}
if (handler != null)
{
this.handlers.put(tmp[i], handler);
}
}
}
oldHandlers.visit(mxUtils.bind(this, function(key, handler)
{
this.fireEvent(new mxEventObject(mxEvent.REMOVE, 'state', handler.state));
handler.destroy();
}));
for (var i = 0; i < tmp.length; i++)
{
var state = this.graph.view.getState(tmp[i]);
if (state != null)
{
var handler = this.handlers.get(tmp[i]);
if (handler == null)
{
handler = this.graph.createHandler(state);
this.fireEvent(new mxEventObject(mxEvent.ADD, 'state', state));
this.handlers.put(tmp[i], handler);
}
else
{
handler.updateParentHighlight();
}
}
}
};
mxSelectionCellsHandler.prototype.isHandlerActive = function(handler)
{
return handler.index != null;
};
mxSelectionCellsHandler.prototype.updateHandler = function(state)
{
var handler = this.handlers.remove(state.cell);
if (handler != null)
{
var index = handler.index;
var x = handler.startX;
var y = handler.startY;
handler.destroy();
handler = this.graph.createHandler(state);
if (handler != null)
{
this.handlers.put(state.cell, handler);
if (index != null && x != null && y != null)
{
handler.start(x, y, index);
}
}
}
};
mxSelectionCellsHandler.prototype.mouseDown = function(sender, me)
{
if (this.graph.isEnabled() && this.isEnabled())
{
var args = [sender, me];
this.handlers.visit(function(key, handler)
{
handler.mouseDown.apply(handler, args);
});
}
};
mxSelectionCellsHandler.prototype.mouseMove = function(sender, me)
{
if (this.graph.isEnabled() && this.isEnabled())
{
var args = [sender, me];
this.handlers.visit(function(key, handler)
{
handler.mouseMove.apply(handler, args);
});
}
};
mxSelectionCellsHandler.prototype.mouseUp = function(sender, me)
{
if (this.graph.isEnabled() && this.isEnabled())
{
var args = [sender, me];
this.handlers.visit(function(key, handler)
{
handler.mouseUp.apply(handler, args);
});
}
};
mxSelectionCellsHandler.prototype.destroy = function()
{
this.graph.removeMouseListener(this);
if (this.refreshHandler != null)
{
this.graph.getSelectionModel().removeListener(this.refreshHandler);
this.graph.getModel().removeListener(this.refreshHandler);
this.graph.getView().removeListener(this.refreshHandler);
this.refreshHandler = null;
}
};
__mxOutput.mxSelectionCellsHandler = typeof mxSelectionCellsHandler !== 'undefined' ? mxSelectionCellsHandler : undefined;
function mxConnectionHandler(graph, factoryMethod)
{
mxEventSource.call(this);
if (graph != null)
{
this.graph = graph;
this.factoryMethod = factoryMethod;
this.init();
this.escapeHandler = mxUtils.bind(this, function(sender, evt)
{
this.reset();
});
this.graph.addListener(mxEvent.ESCAPE, this.escapeHandler);
}
} mxUtils.extend(mxConnectionHandler, mxEventSource);
mxConnectionHandler.prototype.graph = null;
mxConnectionHandler.prototype.factoryMethod = true;
mxConnectionHandler.prototype.moveIconFront = false;
mxConnectionHandler.prototype.moveIconBack = false;
mxConnectionHandler.prototype.connectImage = null;
mxConnectionHandler.prototype.targetConnectImage = false;
mxConnectionHandler.prototype.enabled = true;
mxConnectionHandler.prototype.select = true;
mxConnectionHandler.prototype.createTarget = false;
mxConnectionHandler.prototype.marker = null;
mxConnectionHandler.prototype.constraintHandler = null;
mxConnectionHandler.prototype.error = null;
mxConnectionHandler.prototype.waypointsEnabled = false;
mxConnectionHandler.prototype.ignoreMouseDown = false;
mxConnectionHandler.prototype.first = null;
mxConnectionHandler.prototype.connectIconOffset = new mxPoint(0, mxConstants.TOOLTIP_VERTICAL_OFFSET);
mxConnectionHandler.prototype.edgeState = null;
mxConnectionHandler.prototype.changeHandler = null;
mxConnectionHandler.prototype.drillHandler = null;
mxConnectionHandler.prototype.mouseDownCounter = 0;
mxConnectionHandler.prototype.movePreviewAway = mxClient.IS_VML;
mxConnectionHandler.prototype.outlineConnect = false;
mxConnectionHandler.prototype.livePreview = false;
mxConnectionHandler.prototype.cursor = null;
mxConnectionHandler.prototype.insertBeforeSource = false;
mxConnectionHandler.prototype.isEnabled = function()
{
return this.enabled;
};
mxConnectionHandler.prototype.setEnabled = function(enabled)
{
this.enabled = enabled;
};
mxConnectionHandler.prototype.isInsertBefore = function(edge, source, target, evt, dropTarget)
{
return this.insertBeforeSource && source != target;
};
mxConnectionHandler.prototype.isCreateTarget = function(evt)
{
return this.createTarget;
};
mxConnectionHandler.prototype.setCreateTarget = function(value)
{
this.createTarget = value;
};
mxConnectionHandler.prototype.createShape = function()
{
var shape = (this.livePreview && this.edgeState != null) ?
this.graph.cellRenderer.createShape(this.edgeState) :
new mxPolyline([], mxConstants.INVALID_COLOR);
shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
shape.scale = this.graph.view.scale;
shape.pointerEvents = false;
shape.isDashed = true;
shape.init(this.graph.getView().getOverlayPane());
mxEvent.redirectMouseEvents(shape.node, this.graph, null);
return shape;
};
mxConnectionHandler.prototype.init = function()
{
this.graph.addMouseListener(this);
this.marker = this.createMarker();
this.constraintHandler = new mxConstraintHandler(this.graph);
this.changeHandler = mxUtils.bind(this, function(sender)
{
if (this.iconState != null)
{
this.iconState = this.graph.getView().getState(this.iconState.cell);
}
if (this.iconState != null)
{
this.redrawIcons(this.icons, this.iconState);
this.constraintHandler.reset();
}
else if (this.previous != null && this.graph.view.getState(this.previous.cell) == null)
{
this.reset();
}
});
this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
this.graph.getView().addListener(mxEvent.SCALE, this.changeHandler);
this.graph.getView().addListener(mxEvent.TRANSLATE, this.changeHandler);
this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.changeHandler);
this.drillHandler = mxUtils.bind(this, function(sender)
{
this.reset();
});
this.graph.addListener(mxEvent.START_EDITING, this.drillHandler);
this.graph.getView().addListener(mxEvent.DOWN, this.drillHandler);
this.graph.getView().addListener(mxEvent.UP, this.drillHandler);
};
mxConnectionHandler.prototype.isConnectableCell = function(cell)
{
return true;
};
mxConnectionHandler.prototype.createMarker = function()
{
var marker = new mxCellMarker(this.graph);
marker.hotspotEnabled = true;
marker.getCell = mxUtils.bind(this, function(me)
{
var cell = mxCellMarker.prototype.getCell.apply(marker, arguments);
this.error = null;
if (cell == null && this.currentPoint != null)
{
cell = this.graph.getCellAt(this.currentPoint.x, this.currentPoint.y);
}
if (cell != null && !this.graph.isCellConnectable(cell))
{
var parent = this.graph.getModel().getParent(cell);
if (this.graph.getModel().isVertex(parent) && this.graph.isCellConnectable(parent))
{
cell = parent;
}
}
if ((this.graph.isSwimlane(cell) && this.currentPoint != null &&
this.graph.hitsSwimlaneContent(cell, this.currentPoint.x, this.currentPoint.y)) ||
!this.isConnectableCell(cell))
{
cell = null;
}
if (cell != null)
{
if (this.isConnecting())
{
if (this.previous != null)
{
this.error = this.validateConnection(this.previous.cell, cell);
if (this.error != null && this.error.length == 0)
{
cell = null;
if (this.isCreateTarget(me.getEvent()))
{
this.error = null;
}
}
}
}
else if (!this.isValidSource(cell, me))
{
cell = null;
}
}
else if (this.isConnecting() && !this.isCreateTarget(me.getEvent()) &&
!this.graph.allowDanglingEdges)
{
this.error = '';
}
return cell;
});
marker.isValidState = mxUtils.bind(this, function(state)
{
if (this.isConnecting())
{
return this.error == null;
}
else
{
return mxCellMarker.prototype.isValidState.apply(marker, arguments);
}
});
marker.getMarkerColor = mxUtils.bind(this, function(evt, state, isValid)
{
return (this.connectImage == null || this.isConnecting()) ?
mxCellMarker.prototype.getMarkerColor.apply(marker, arguments) :
null;
});
marker.intersects = mxUtils.bind(this, function(state, evt)
{
if (this.connectImage != null || this.isConnecting())
{
return true;
}
return mxCellMarker.prototype.intersects.apply(marker, arguments);
});
return marker;
};
mxConnectionHandler.prototype.start = function(state, x, y, edgeState)
{
this.previous = state;
this.first = new mxPoint(x, y);
this.edgeState = (edgeState != null) ? edgeState : this.createEdgeState(null);
this.marker.currentColor = this.marker.validColor;
this.marker.markedState = state;
this.marker.mark();
this.fireEvent(new mxEventObject(mxEvent.START, 'state', this.previous));
};
mxConnectionHandler.prototype.isConnecting = function()
{
return this.first != null && this.shape != null;
};
mxConnectionHandler.prototype.isValidSource = function(cell, me)
{
return this.graph.isValidSource(cell);
};
mxConnectionHandler.prototype.isValidTarget = function(cell)
{
return true;
};
mxConnectionHandler.prototype.validateConnection = function(source, target)
{
if (!this.isValidTarget(target))
{
return '';
}
return this.graph.getEdgeValidationError(null, source, target);
};
mxConnectionHandler.prototype.getConnectImage = function(state)
{
return this.connectImage;
};
mxConnectionHandler.prototype.isMoveIconToFrontForState = function(state)
{
if (state.text != null && state.text.node.parentNode == this.graph.container)
{
return true;
}
return this.moveIconFront;
};
mxConnectionHandler.prototype.createIcons = function(state)
{
var image = this.getConnectImage(state);
if (image != null && state != null)
{
this.iconState = state;
var icons = [];
var bounds = new mxRectangle(0, 0, image.width, image.height);
var icon = new mxImageShape(bounds, image.src, null, null, 0);
icon.preserveImageAspect = false;
if (this.isMoveIconToFrontForState(state))
{
icon.dialect = mxConstants.DIALECT_STRICTHTML;
icon.init(this.graph.container);
}
else
{
icon.dialect = (this.graph.dialect == mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_SVG : mxConstants.DIALECT_VML;
icon.init(this.graph.getView().getOverlayPane());
if (this.moveIconBack && icon.node.previousSibling != null)
{
icon.node.parentNode.insertBefore(icon.node, icon.node.parentNode.firstChild);
}
}
icon.node.style.cursor = mxConstants.CURSOR_CONNECT;
var getState = mxUtils.bind(this, function()
{
return (this.currentState != null) ? this.currentState : state;
});
var mouseDown = mxUtils.bind(this, function(evt)
{
if (!mxEvent.isConsumed(evt))
{
this.icon = icon;
this.graph.fireMouseEvent(mxEvent.MOUSE_DOWN,
new mxMouseEvent(evt, getState()));
}
});
mxEvent.redirectMouseEvents(icon.node, this.graph, getState, mouseDown);
icons.push(icon);
this.redrawIcons(icons, this.iconState);
return icons;
}
return null;
};
mxConnectionHandler.prototype.redrawIcons = function(icons, state)
{
if (icons != null && icons[0] != null && state != null)
{
var pos = this.getIconPosition(icons[0], state);
icons[0].bounds.x = pos.x;
icons[0].bounds.y = pos.y;
icons[0].redraw();
}
};
mxConnectionHandler.prototype.getIconPosition = function(icon, state)
{
var scale = this.graph.getView().scale;
var cx = state.getCenterX();
var cy = state.getCenterY();
if (this.graph.isSwimlane(state.cell))
{
var size = this.graph.getStartSize(state.cell);
cx = (size.width != 0) ? state.x + size.width * scale / 2 : cx;
cy = (size.height != 0) ? state.y + size.height * scale / 2 : cy;
var alpha = mxUtils.toRadians(mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0);
if (alpha != 0)
{
var cos = Math.cos(alpha);
var sin = Math.sin(alpha);
var ct = new mxPoint(state.getCenterX(), state.getCenterY());
var pt = mxUtils.getRotatedPoint(new mxPoint(cx, cy), cos, sin, ct);
cx = pt.x;
cy = pt.y;
}
}
return new mxPoint(cx - icon.bounds.width / 2,
cy - icon.bounds.height / 2);
};
mxConnectionHandler.prototype.destroyIcons = function()
{
if (this.icons != null)
{
for (var i = 0; i < this.icons.length; i++)
{
this.icons[i].destroy();
}
this.icons = null;
this.icon = null;
this.selectedIcon = null;
this.iconState = null;
}
};
mxConnectionHandler.prototype.isStartEvent = function(me)
{
return ((this.constraintHandler.currentFocus != null && this.constraintHandler.currentConstraint != null) ||
(this.previous != null && this.error == null && (this.icons == null || (this.icons != null &&
this.icon != null))));
};
mxConnectionHandler.prototype.mouseDown = function(sender, me)
{
this.mouseDownCounter++;
if (this.isEnabled() && this.graph.isEnabled() && !me.isConsumed() &&
!this.isConnecting() && this.isStartEvent(me))
{
if (this.constraintHandler.currentConstraint != null &&
this.constraintHandler.currentFocus != null &&
this.constraintHandler.currentPoint != null)
{
this.sourceConstraint = this.constraintHandler.currentConstraint;
this.previous = this.constraintHandler.currentFocus;
this.first = this.constraintHandler.currentPoint.clone();
}
else
{
this.first = new mxPoint(me.getGraphX(), me.getGraphY());
}
this.edgeState = this.createEdgeState(me);
this.mouseDownCounter = 1;
if (this.waypointsEnabled && this.shape == null)
{
this.waypoints = null;
this.shape = this.createShape();
if (this.edgeState != null)
{
this.shape.apply(this.edgeState);
}
}
if (this.previous == null && this.edgeState != null)
{
var pt = this.graph.getPointForEvent(me.getEvent());
this.edgeState.cell.geometry.setTerminalPoint(pt, true);
}
this.fireEvent(new mxEventObject(mxEvent.START, 'state', this.previous));
me.consume();
}
this.selectedIcon = this.icon;
this.icon = null;
};
mxConnectionHandler.prototype.isImmediateConnectSource = function(state)
{
return !this.graph.isCellMovable(state.cell);
};
mxConnectionHandler.prototype.createEdgeState = function(me)
{
return null;
};
mxConnectionHandler.prototype.isOutlineConnectEvent = function(me)
{
var offset = mxUtils.getOffset(this.graph.container);
var evt = me.getEvent();
var clientX = mxEvent.getClientX(evt);
var clientY = mxEvent.getClientY(evt);
var doc = document.documentElement;
var left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
var gridX = this.currentPoint.x - this.graph.container.scrollLeft + offset.x - left;
var gridY = this.currentPoint.y - this.graph.container.scrollTop + offset.y - top;
return this.outlineConnect && !mxEvent.isShiftDown(me.getEvent()) &&
(me.isSource(this.marker.highlight.shape) ||
(mxEvent.isAltDown(me.getEvent()) && me.getState() != null) ||
this.marker.highlight.isHighlightAt(clientX, clientY) ||
((gridX != clientX || gridY != clientY) && me.getState() == null &&
this.marker.highlight.isHighlightAt(gridX, gridY)));
};
mxConnectionHandler.prototype.updateCurrentState = function(me, point)
{
this.constraintHandler.update(me, this.first == null, false, (this.first == null ||
me.isSource(this.marker.highlight.shape)) ? null : point);
if (this.constraintHandler.currentFocus != null && this.constraintHandler.currentConstraint != null)
{
if (this.marker.highlight != null && this.marker.highlight.state != null &&
this.marker.highlight.state.cell == this.constraintHandler.currentFocus.cell)
{
if (this.marker.highlight.shape.stroke != 'transparent')
{
this.marker.highlight.shape.stroke = 'transparent';
this.marker.highlight.repaint();
}
}
else
{
this.marker.markCell(this.constraintHandler.currentFocus.cell, 'transparent');
}
if (this.previous != null)
{
this.error = this.validateConnection(this.previous.cell, this.constraintHandler.currentFocus.cell);
if (this.error == null)
{
this.currentState = this.constraintHandler.currentFocus;
}
if (this.error != null || (this.currentState != null &&
!this.isCellEnabled(this.currentState.cell)))
{
this.constraintHandler.reset();
}
}
}
else
{
if (this.graph.isIgnoreTerminalEvent(me.getEvent()))
{
this.marker.reset();
this.currentState = null;
}
else
{
this.marker.process(me);
this.currentState = this.marker.getValidState();
}
if (this.currentState != null && !this.isCellEnabled(this.currentState.cell))
{
this.constraintHandler.reset();
this.marker.reset();
this.currentState = null;
}
var outline = this.isOutlineConnectEvent(me);
if (this.currentState != null && outline)
{
if (me.isSource(this.marker.highlight.shape))
{
point = new mxPoint(me.getGraphX(), me.getGraphY());
}
var constraint = this.graph.getOutlineConstraint(point, this.currentState, me);
this.constraintHandler.setFocus(me, this.currentState, false);
this.constraintHandler.currentConstraint = constraint;
this.constraintHandler.currentPoint = point;
}
if (this.outlineConnect)
{
if (this.marker.highlight != null && this.marker.highlight.shape != null)
{
var s = this.graph.view.scale;
if (this.constraintHandler.currentConstraint != null &&
this.constraintHandler.currentFocus != null)
{
this.marker.highlight.shape.stroke = mxConstants.OUTLINE_HIGHLIGHT_COLOR;
this.marker.highlight.shape.strokewidth = mxConstants.OUTLINE_HIGHLIGHT_STROKEWIDTH / s / s;
this.marker.highlight.repaint();
}
else if (this.marker.hasValidState())
{
if (this.graph.isCellConnectable(me.getCell()) &&
this.marker.getValidState() != me.getState())
{
this.marker.highlight.shape.stroke = 'transparent';
this.currentState = null;
}
else
{
this.marker.highlight.shape.stroke = mxConstants.DEFAULT_VALID_COLOR;
}
this.marker.highlight.shape.strokewidth = mxConstants.HIGHLIGHT_STROKEWIDTH / s / s;
this.marker.highlight.repaint();
}
}
}
}
};
mxConnectionHandler.prototype.isCellEnabled = function(cell)
{
return true;
};
mxConnectionHandler.prototype.convertWaypoint = function(point)
{
var scale = this.graph.getView().getScale();
var tr = this.graph.getView().getTranslate();
point.x = point.x / scale - tr.x;
point.y = point.y / scale - tr.y;
};
mxConnectionHandler.prototype.snapToPreview = function(me, point)
{
if (!mxEvent.isAltDown(me.getEvent()) && this.previous != null)
{
var tol = this.graph.gridSize * this.graph.view.scale / 2;
var tmp = (this.sourceConstraint != null) ? this.first :
new mxPoint(this.previous.getCenterX(), this.previous.getCenterY());
if (Math.abs(tmp.x - me.getGraphX()) < tol)
{
point.x = tmp.x;
}
if (Math.abs(tmp.y - me.getGraphY()) < tol)
{
point.y = tmp.y;
}
}
};
mxConnectionHandler.prototype.mouseMove = function(sender, me)
{
if (!me.isConsumed() && (this.ignoreMouseDown || this.first != null || !this.graph.isMouseDown))
{
if (!this.isEnabled() && this.currentState != null)
{
this.destroyIcons();
this.currentState = null;
}
var view = this.graph.getView();
var scale = view.scale;
var tr = view.translate;
var point = new mxPoint(me.getGraphX(), me.getGraphY());
this.error = null;
if (this.graph.isGridEnabledEvent(me.getEvent()))
{
point = new mxPoint((this.graph.snap(point.x / scale - tr.x) + tr.x) * scale,
(this.graph.snap(point.y / scale - tr.y) + tr.y) * scale);
}
this.snapToPreview(me, point);
this.currentPoint = point;
if ((this.first != null || (this.isEnabled() && this.graph.isEnabled())) &&
(this.shape != null || this.first == null ||
Math.abs(me.getGraphX() - this.first.x) > this.graph.tolerance ||
Math.abs(me.getGraphY() - this.first.y) > this.graph.tolerance))
{
this.updateCurrentState(me, point);
}
if (this.first != null)
{
var constraint = null;
var current = point;
if (this.constraintHandler.currentConstraint != null &&
this.constraintHandler.currentFocus != null &&
this.constraintHandler.currentPoint != null)
{
constraint = this.constraintHandler.currentConstraint;
current = this.constraintHandler.currentPoint.clone();
}
else if (this.previous != null && !this.graph.isIgnoreTerminalEvent(me.getEvent()) &&
mxEvent.isShiftDown(me.getEvent()))
{
if (Math.abs(this.previous.getCenterX() - point.x) <
Math.abs(this.previous.getCenterY() - point.y))
{
point.x = this.previous.getCenterX();
}
else
{
point.y = this.previous.getCenterY();
}
}
var pt2 = this.first;
if (this.selectedIcon != null)
{
var w = this.selectedIcon.bounds.width;
var h = this.selectedIcon.bounds.height;
if (this.currentState != null && this.targetConnectImage)
{
var pos = this.getIconPosition(this.selectedIcon, this.currentState);
this.selectedIcon.bounds.x = pos.x;
this.selectedIcon.bounds.y = pos.y;
}
else
{
var bounds = new mxRectangle(me.getGraphX() + this.connectIconOffset.x,
me.getGraphY() + this.connectIconOffset.y, w, h);
this.selectedIcon.bounds = bounds;
}
this.selectedIcon.redraw();
}
if (this.edgeState != null)
{
this.updateEdgeState(current, constraint);
current = this.edgeState.absolutePoints[this.edgeState.absolutePoints.length - 1];
pt2 = this.edgeState.absolutePoints[0];
}
else
{
if (this.currentState != null)
{
if (this.constraintHandler.currentConstraint == null)
{
var tmp = this.getTargetPerimeterPoint(this.currentState, me);
if (tmp != null)
{
current = tmp;
}
}
}
if (this.sourceConstraint == null && this.previous != null)
{
var next = (this.waypoints != null && this.waypoints.length > 0) ?
this.waypoints[0] : current;
var tmp = this.getSourcePerimeterPoint(this.previous, next, me);
if (tmp != null)
{
pt2 = tmp;
}
}
}
if (this.currentState == null && this.movePreviewAway)
{
var tmp = pt2;
if (this.edgeState != null && this.edgeState.absolutePoints.length >= 2)
{
var tmp2 = this.edgeState.absolutePoints[this.edgeState.absolutePoints.length - 2];
if (tmp2 != null)
{
tmp = tmp2;
}
}
var dx = current.x - tmp.x;
var dy = current.y - tmp.y;
var len = Math.sqrt(dx * dx + dy * dy);
if (len == 0)
{
return;
}
this.originalPoint = current.clone();
current.x -= dx * 4 / len;
current.y -= dy * 4 / len;
}
else
{
this.originalPoint = null;
}
if (this.shape == null)
{
var dx = Math.abs(me.getGraphX() - this.first.x);
var dy = Math.abs(me.getGraphY() - this.first.y);
if (dx > this.graph.tolerance || dy > this.graph.tolerance)
{
this.shape = this.createShape();
if (this.edgeState != null)
{
this.shape.apply(this.edgeState);
}
this.updateCurrentState(me, point);
}
}
if (this.shape != null)
{
if (this.edgeState != null)
{
this.shape.points = this.edgeState.absolutePoints;
}
else
{
var pts = [pt2];
if (this.waypoints != null)
{
pts = pts.concat(this.waypoints);
}
pts.push(current);
this.shape.points = pts;
}
this.drawPreview();
}
if (this.cursor != null)
{
this.graph.container.style.cursor = this.cursor;
}
mxEvent.consume(me.getEvent());
me.consume();
}
else if (!this.isEnabled() || !this.graph.isEnabled())
{
this.constraintHandler.reset();
}
else if (this.previous != this.currentState && this.edgeState == null)
{
this.destroyIcons();
if (this.currentState != null && this.error == null && this.constraintHandler.currentConstraint == null)
{
this.icons = this.createIcons(this.currentState);
if (this.icons == null)
{
this.currentState.setCursor(mxConstants.CURSOR_CONNECT);
me.consume();
}
}
this.previous = this.currentState;
}
else if (this.previous == this.currentState && this.currentState != null && this.icons == null &&
!this.graph.isMouseDown)
{
me.consume();
}
if (!this.graph.isMouseDown && this.currentState != null && this.icons != null)
{
var hitsIcon = false;
var target = me.getSource();
for (var i = 0; i < this.icons.length && !hitsIcon; i++)
{
hitsIcon = target == this.icons[i].node || target.parentNode == this.icons[i].node;
}
if (!hitsIcon)
{
this.updateIcons(this.currentState, this.icons, me);
}
}
}
else
{
this.constraintHandler.reset();
}
};
mxConnectionHandler.prototype.updateEdgeState = function(current, constraint)
{
if (this.sourceConstraint != null && this.sourceConstraint.point != null)
{
this.edgeState.style[mxConstants.STYLE_EXIT_X] = this.sourceConstraint.point.x;
this.edgeState.style[mxConstants.STYLE_EXIT_Y] = this.sourceConstraint.point.y;
}
if (constraint != null && constraint.point != null)
{
this.edgeState.style[mxConstants.STYLE_ENTRY_X] = constraint.point.x;
this.edgeState.style[mxConstants.STYLE_ENTRY_Y] = constraint.point.y;
}
else
{
delete this.edgeState.style[mxConstants.STYLE_ENTRY_X];
delete this.edgeState.style[mxConstants.STYLE_ENTRY_Y];
}
this.edgeState.absolutePoints = [null, (this.currentState != null) ? null : current];
this.graph.view.updateFixedTerminalPoint(this.edgeState, this.previous, true, this.sourceConstraint);
if (this.currentState != null)
{
if (constraint == null)
{
constraint = this.graph.getConnectionConstraint(this.edgeState, this.previous, false);
}
this.edgeState.setAbsoluteTerminalPoint(null, false);
this.graph.view.updateFixedTerminalPoint(this.edgeState, this.currentState, false, constraint);
}
var realPoints = null;
if (this.waypoints != null)
{
realPoints = [];
for (var i = 0; i < this.waypoints.length; i++)
{
var pt = this.waypoints[i].clone();
this.convertWaypoint(pt);
realPoints[i] = pt;
}
}
this.graph.view.updatePoints(this.edgeState, realPoints, this.previous, this.currentState);
this.graph.view.updateFloatingTerminalPoints(this.edgeState, this.previous, this.currentState);
};
mxConnectionHandler.prototype.getTargetPerimeterPoint = function(state, me)
{
var result = null;
var view = state.view;
var targetPerimeter = view.getPerimeterFunction(state);
if (targetPerimeter != null)
{
var next = (this.waypoints != null && this.waypoints.length > 0) ?
this.waypoints[this.waypoints.length - 1] :
new mxPoint(this.previous.getCenterX(), this.previous.getCenterY());
var tmp = targetPerimeter(view.getPerimeterBounds(state),
this.edgeState, next, false);
if (tmp != null)
{
result = tmp;
}
}
else
{
result = new mxPoint(state.getCenterX(), state.getCenterY());
}
return result;
};
mxConnectionHandler.prototype.getSourcePerimeterPoint = function(state, next, me)
{
var result = null;
var view = state.view;
var sourcePerimeter = view.getPerimeterFunction(state);
var c = new mxPoint(state.getCenterX(), state.getCenterY());
if (sourcePerimeter != null)
{
var theta = mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION, 0);
var rad = -theta * (Math.PI / 180);
if (theta != 0)
{
next = mxUtils.getRotatedPoint(new mxPoint(next.x, next.y), Math.cos(rad), Math.sin(rad), c);
}
var tmp = sourcePerimeter(view.getPerimeterBounds(state), state, next, false);
if (tmp != null)
{
if (theta != 0)
{
tmp = mxUtils.getRotatedPoint(new mxPoint(tmp.x, tmp.y), Math.cos(-rad), Math.sin(-rad), c);
}
result = tmp;
}
}
else
{
result = c;
}
return result;
};
mxConnectionHandler.prototype.updateIcons = function(state, icons, me)
{
};
mxConnectionHandler.prototype.isStopEvent = function(me)
{
return me.getState() != null;
};
mxConnectionHandler.prototype.addWaypointForEvent = function(me)
{
var point = mxUtils.convertPoint(this.graph.container, me.getX(), me.getY());
var dx = Math.abs(point.x - this.first.x);
var dy = Math.abs(point.y - this.first.y);
var addPoint = this.waypoints != null || (this.mouseDownCounter > 1 &&
(dx > this.graph.tolerance || dy > this.graph.tolerance));
if (addPoint)
{
if (this.waypoints == null)
{
this.waypoints = [];
}
var scale = this.graph.view.scale;
var point = new mxPoint(this.graph.snap(me.getGraphX() / scale) * scale,
this.graph.snap(me.getGraphY() / scale) * scale);
this.waypoints.push(point);
}
};
mxConnectionHandler.prototype.checkConstraints = function(c1, c2)
{
return (c1 == null || c2 == null || c1.point == null || c2.point == null ||
!c1.point.equals(c2.point) || c1.dx != c2.dx || c1.dy != c2.dy ||
c1.perimeter != c2.perimeter);
};
mxConnectionHandler.prototype.mouseUp = function(sender, me)
{
if (!me.isConsumed() && this.isConnecting())
{
if (this.waypointsEnabled && !this.isStopEvent(me))
{
this.addWaypointForEvent(me);
me.consume();
return;
}
var c1 = this.sourceConstraint;
var c2 = this.constraintHandler.currentConstraint;
var source = (this.previous != null) ? this.previous.cell : null;
var target = null;
if (this.constraintHandler.currentConstraint != null &&
this.constraintHandler.currentFocus != null)
{
target = this.constraintHandler.currentFocus.cell;
}
if (target == null && this.currentState != null)
{
target = this.currentState.cell;
}
if (this.error == null && (source == null || target == null ||
source != target || this.checkConstraints(c1, c2)))
{
this.connect(source, target, me.getEvent(), me.getCell());
}
else
{
if (this.previous != null && this.marker.validState != null &&
this.previous.cell == this.marker.validState.cell)
{
this.graph.selectCellForEvent(this.marker.source, me.getEvent());
}
if (this.error != null && this.error.length > 0)
{
this.graph.validationAlert(this.error);
}
}
this.destroyIcons();
me.consume();
}
if (this.first != null)
{
this.reset();
}
};
mxConnectionHandler.prototype.reset = function()
{
if (this.shape != null)
{
this.shape.destroy();
this.shape = null;
}
if (this.cursor != null && this.graph.container != null)
{
this.graph.container.style.cursor = '';
}
this.destroyIcons();
this.marker.reset();
this.constraintHandler.reset();
this.originalPoint = null;
this.currentPoint = null;
this.edgeState = null;
this.previous = null;
this.error = null;
this.sourceConstraint = null;
this.mouseDownCounter = 0;
this.first = null;
this.fireEvent(new mxEventObject(mxEvent.RESET));
};
mxConnectionHandler.prototype.drawPreview = function()
{
this.updatePreview(this.error == null);
this.shape.redraw();
};
mxConnectionHandler.prototype.updatePreview = function(valid)
{
this.shape.strokewidth = this.getEdgeWidth(valid);
this.shape.stroke = this.getEdgeColor(valid);
};
mxConnectionHandler.prototype.getEdgeColor = function(valid)
{
return (valid) ? mxConstants.VALID_COLOR : mxConstants.INVALID_COLOR;
};
mxConnectionHandler.prototype.getEdgeWidth = function(valid)
{
return (valid) ? 3 : 1;
};
mxConnectionHandler.prototype.connect = function(source, target, evt, dropTarget)
{
if (target != null || this.isCreateTarget(evt) || this.graph.allowDanglingEdges)
{
var model = this.graph.getModel();
var terminalInserted = false;
var edge = null;
model.beginUpdate();
try
{
if (source != null && target == null && !this.graph.isIgnoreTerminalEvent(evt) && this.isCreateTarget(evt))
{
target = this.createTargetVertex(evt, source);
if (target != null)
{
dropTarget = this.graph.getDropTarget([target], evt, dropTarget);
terminalInserted = true;
if (dropTarget == null || !this.graph.getModel().isEdge(dropTarget))
{
var pstate = this.graph.getView().getState(dropTarget);
if (pstate != null)
{
var tmp = model.getGeometry(target);
tmp.x -= pstate.origin.x;
tmp.y -= pstate.origin.y;
}
}
else
{
dropTarget = this.graph.getDefaultParent();
}
this.graph.addCell(target, dropTarget);
}
}
var parent = this.graph.getDefaultParent();
if (source != null && target != null &&
model.getParent(source) == model.getParent(target) &&
model.getParent(model.getParent(source)) != model.getRoot())
{
parent = model.getParent(source);
if ((source.geometry != null && source.geometry.relative) &&
(target.geometry != null && target.geometry.relative))
{
parent = model.getParent(parent);
}
}
var value = null;
var style = null;
if (this.edgeState != null)
{
value = this.edgeState.cell.value;
style = this.edgeState.cell.style;
}
edge = this.insertEdge(parent, null, value, source, target, style);
if (edge != null)
{
this.graph.setConnectionConstraint(edge, source, true, this.sourceConstraint);
this.graph.setConnectionConstraint(edge, target, false, this.constraintHandler.currentConstraint);
if (this.edgeState != null)
{
model.setGeometry(edge, this.edgeState.cell.geometry);
}
var parent = model.getParent(source);
if (this.isInsertBefore(edge, source, target, evt, dropTarget))
{
var index = null;
var tmp = source;
while (tmp.parent != null && tmp.geometry != null &&
tmp.geometry.relative && tmp.parent != edge.parent)
{
tmp = this.graph.model.getParent(tmp);
}
if (tmp != null && tmp.parent != null && tmp.parent == edge.parent)
{
model.add(parent, edge, tmp.parent.getIndex(tmp));
}
}
var geo = model.getGeometry(edge);
if (geo == null)
{
geo = new mxGeometry();
geo.relative = true;
model.setGeometry(edge, geo);
}
if (this.waypoints != null && this.waypoints.length > 0)
{
var s = this.graph.view.scale;
var tr = this.graph.view.translate;
geo.points = [];
for (var i = 0; i < this.waypoints.length; i++)
{
var pt = this.waypoints[i];
geo.points.push(new mxPoint(pt.x / s - tr.x, pt.y / s - tr.y));
}
}
if (target == null)
{
var t = this.graph.view.translate;
var s = this.graph.view.scale;
var pt = (this.originalPoint != null) ?
new mxPoint(this.originalPoint.x / s - t.x, this.originalPoint.y / s - t.y) :
new mxPoint(this.currentPoint.x / s - t.x, this.currentPoint.y / s - t.y);
pt.x -= this.graph.panDx / this.graph.view.scale;
pt.y -= this.graph.panDy / this.graph.view.scale;
geo.setTerminalPoint(pt, false);
}
this.fireEvent(new mxEventObject(mxEvent.CONNECT, 'cell', edge, 'terminal', target,
'event', evt, 'target', dropTarget, 'terminalInserted', terminalInserted));
}
}
catch (e)
{
mxLog.show();
mxLog.debug(e.message);
}
finally
{
model.endUpdate();
}
if (this.select)
{
this.selectCells(edge, (terminalInserted) ? target : null);
}
}
};
mxConnectionHandler.prototype.selectCells = function(edge, target)
{
this.graph.setSelectionCell(edge);
};
mxConnectionHandler.prototype.insertEdge = function(parent, id, value, source, target, style)
{
if (this.factoryMethod == null)
{
return this.graph.insertEdge(parent, id, value, source, target, style);
}
else
{
var edge = this.createEdge(value, source, target, style);
edge = this.graph.addEdge(edge, parent, source, target);
return edge;
}
};
mxConnectionHandler.prototype.createTargetVertex = function(evt, source)
{
var geo = this.graph.getCellGeometry(source);
while (geo != null && geo.relative)
{
source = this.graph.getModel().getParent(source);
geo = this.graph.getCellGeometry(source);
}
var clone = this.graph.cloneCell(source);
var geo = this.graph.getModel().getGeometry(clone);
if (geo != null)
{
var t = this.graph.view.translate;
var s = this.graph.view.scale;
var point = new mxPoint(this.currentPoint.x / s - t.x, this.currentPoint.y / s - t.y);
geo.x = Math.round(point.x - geo.width / 2 - this.graph.panDx / s);
geo.y = Math.round(point.y - geo.height / 2 - this.graph.panDy / s);
var tol = this.getAlignmentTolerance();
if (tol > 0)
{
var sourceState = this.graph.view.getState(source);
if (sourceState != null)
{
var x = sourceState.x / s - t.x;
var y = sourceState.y / s - t.y;
if (Math.abs(x - geo.x) <= tol)
{
geo.x = Math.round(x);
}
if (Math.abs(y - geo.y) <= tol)
{
geo.y = Math.round(y);
}
}
}
}
return clone;
};
mxConnectionHandler.prototype.getAlignmentTolerance = function(evt)
{
return (this.graph.isGridEnabled()) ? this.graph.gridSize / 2 : this.graph.tolerance;
};
mxConnectionHandler.prototype.createEdge = function(value, source, target, style)
{
var edge = null;
if (this.factoryMethod != null)
{
edge = this.factoryMethod(source, target, style);
}
if (edge == null)
{
edge = new mxCell(value || '');
edge.setEdge(true);
edge.setStyle(style);
var geo = new mxGeometry();
geo.relative = true;
edge.setGeometry(geo);
}
return edge;
};
mxConnectionHandler.prototype.destroy = function()
{
this.graph.removeMouseListener(this);
if (this.shape != null)
{
this.shape.destroy();
this.shape = null;
}
if (this.marker != null)
{
this.marker.destroy();
this.marker = null;
}
if (this.constraintHandler != null)
{
this.constraintHandler.destroy();
this.constraintHandler = null;
}
if (this.changeHandler != null)
{
this.graph.getModel().removeListener(this.changeHandler);
this.graph.getView().removeListener(this.changeHandler);
this.changeHandler = null;
}
if (this.drillHandler != null)
{
this.graph.removeListener(this.drillHandler);
this.graph.getView().removeListener(this.drillHandler);
this.drillHandler = null;
}
if (this.escapeHandler != null)
{
this.graph.removeListener(this.escapeHandler);
this.escapeHandler = null;
}
};
__mxOutput.mxConnectionHandler = typeof mxConnectionHandler !== 'undefined' ? mxConnectionHandler : undefined;
function mxConstraintHandler(graph)
{
this.graph = graph;
this.resetHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.currentFocus != null && this.graph.view.getState(this.currentFocus.cell) == null)
{
this.reset();
}
else
{
this.redraw();
}
});
this.graph.model.addListener(mxEvent.CHANGE, this.resetHandler);
this.graph.view.addListener(mxEvent.SCALE_AND_TRANSLATE, this.resetHandler);
this.graph.view.addListener(mxEvent.TRANSLATE, this.resetHandler);
this.graph.view.addListener(mxEvent.SCALE, this.resetHandler);
this.graph.addListener(mxEvent.ROOT, this.resetHandler);
} mxConstraintHandler.prototype.pointImage = new mxImage(mxClient.imageBasePath + '/point.gif', 5, 5);
mxConstraintHandler.prototype.graph = null;
mxConstraintHandler.prototype.enabled = true;
mxConstraintHandler.prototype.highlightColor = mxConstants.DEFAULT_VALID_COLOR;
mxConstraintHandler.prototype.isEnabled = function()
{
return this.enabled;
};
mxConstraintHandler.prototype.setEnabled = function(enabled)
{
this.enabled = enabled;
};
mxConstraintHandler.prototype.reset = function()
{
if (this.focusIcons != null)
{
for (var i = 0; i < this.focusIcons.length; i++)
{
this.focusIcons[i].destroy();
}
this.focusIcons = null;
}
if (this.focusHighlight != null)
{
this.focusHighlight.destroy();
this.focusHighlight = null;
}
this.currentConstraint = null;
this.currentFocusArea = null;
this.currentPoint = null;
this.currentFocus = null;
this.focusPoints = null;
};
mxConstraintHandler.prototype.getTolerance = function(me)
{
return this.graph.getTolerance();
};
mxConstraintHandler.prototype.getImageForConstraint = function(state, constraint, point)
{
return this.pointImage;
};
mxConstraintHandler.prototype.isEventIgnored = function(me, source)
{
return false;
};
mxConstraintHandler.prototype.isStateIgnored = function(state, source)
{
return false;
};
mxConstraintHandler.prototype.destroyIcons = function()
{
if (this.focusIcons != null)
{
for (var i = 0; i < this.focusIcons.length; i++)
{
this.focusIcons[i].destroy();
}
this.focusIcons = null;
this.focusPoints = null;
}
};
mxConstraintHandler.prototype.destroyFocusHighlight = function()
{
if (this.focusHighlight != null)
{
this.focusHighlight.destroy();
this.focusHighlight = null;
}
};
mxConstraintHandler.prototype.isKeepFocusEvent = function(me)
{
return mxEvent.isShiftDown(me.getEvent());
};
mxConstraintHandler.prototype.getCellForEvent = function(me, point)
{
var cell = me.getCell();
if (cell == null && point != null && (me.getGraphX() != point.x || me.getGraphY() != point.y))
{
cell = this.graph.getCellAt(point.x, point.y);
}
if (cell != null && !this.graph.isCellConnectable(cell))
{
var parent = this.graph.getModel().getParent(cell);
if (this.graph.getModel().isVertex(parent) && this.graph.isCellConnectable(parent))
{
cell = parent;
}
}
return (this.graph.isCellLocked(cell)) ? null : cell;
};
mxConstraintHandler.prototype.update = function(me, source, existingEdge, point)
{
if (this.isEnabled() && !this.isEventIgnored(me))
{
if (this.mouseleaveHandler == null && this.graph.container != null)
{
this.mouseleaveHandler = mxUtils.bind(this, function()
{
this.reset();
});
mxEvent.addListener(this.graph.container, 'mouseleave', this.resetHandler);
}
var tol = this.getTolerance(me);
var x = (point != null) ? point.x : me.getGraphX();
var y = (point != null) ? point.y : me.getGraphY();
var grid = new mxRectangle(x - tol, y - tol, 2 * tol, 2 * tol);
var mouse = new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol);
var state = this.graph.view.getState(this.getCellForEvent(me, point));
if (!this.isKeepFocusEvent(me) && (this.currentFocusArea == null || this.currentFocus == null ||
(state != null) || !this.graph.getModel().isVertex(this.currentFocus.cell) ||
!mxUtils.intersects(this.currentFocusArea, mouse)) && (state != this.currentFocus))
{
this.currentFocusArea = null;
this.currentFocus = null;
this.setFocus(me, state, source);
}
this.currentConstraint = null;
this.currentPoint = null;
var minDistSq = null;
if (this.focusIcons != null && this.constraints != null &&
(state == null || this.currentFocus == state))
{
var cx = mouse.getCenterX();
var cy = mouse.getCenterY();
for (var i = 0; i < this.focusIcons.length; i++)
{
var dx = cx - this.focusIcons[i].bounds.getCenterX();
var dy = cy - this.focusIcons[i].bounds.getCenterY();
var tmp = dx * dx + dy * dy;
if ((this.intersects(this.focusIcons[i], mouse, source, existingEdge) || (point != null &&
this.intersects(this.focusIcons[i], grid, source, existingEdge))) &&
(minDistSq == null || tmp < minDistSq))
{
this.currentConstraint = this.constraints[i];
this.currentPoint = this.focusPoints[i];
minDistSq = tmp;
var tmp = this.focusIcons[i].bounds.clone();
tmp.grow(mxConstants.HIGHLIGHT_SIZE + 1);
tmp.width -= 1;
tmp.height -= 1;
if (this.focusHighlight == null)
{
var hl = this.createHighlightShape();
hl.dialect = (this.graph.dialect == mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_SVG : mxConstants.DIALECT_VML;
hl.pointerEvents = false;
hl.init(this.graph.getView().getOverlayPane());
this.focusHighlight = hl;
var getState = mxUtils.bind(this, function()
{
return (this.currentFocus != null) ? this.currentFocus : state;
});
mxEvent.redirectMouseEvents(hl.node, this.graph, getState);
}
this.focusHighlight.bounds = tmp;
this.focusHighlight.redraw();
}
}
}
if (this.currentConstraint == null)
{
this.destroyFocusHighlight();
}
}
else
{
this.currentConstraint = null;
this.currentFocus = null;
this.currentPoint = null;
}
};
mxConstraintHandler.prototype.redraw = function()
{
if (this.currentFocus != null && this.constraints != null && this.focusIcons != null)
{
var state = this.graph.view.getState(this.currentFocus.cell);
this.currentFocus = state;
this.currentFocusArea = new mxRectangle(state.x, state.y, state.width, state.height);
for (var i = 0; i < this.constraints.length; i++)
{
var cp = this.graph.getConnectionPoint(state, this.constraints[i]);
var img = this.getImageForConstraint(state, this.constraints[i], cp);
var bounds = new mxRectangle(Math.round(cp.x - img.width / 2),
Math.round(cp.y - img.height / 2), img.width, img.height);
this.focusIcons[i].bounds = bounds;
this.focusIcons[i].redraw();
this.currentFocusArea.add(this.focusIcons[i].bounds);
this.focusPoints[i] = cp;
}
}
};
mxConstraintHandler.prototype.setFocus = function(me, state, source)
{
this.constraints = (state != null && !this.isStateIgnored(state, source) &&
this.graph.isCellConnectable(state.cell)) ? ((this.isEnabled()) ?
(this.graph.getAllConnectionConstraints(state, source) || []) : []) : null;
if (this.constraints != null)
{
this.currentFocus = state;
this.currentFocusArea = new mxRectangle(state.x, state.y, state.width, state.height);
if (this.focusIcons != null)
{
for (var i = 0; i < this.focusIcons.length; i++)
{
this.focusIcons[i].destroy();
}
this.focusIcons = null;
this.focusPoints = null;
}
this.focusPoints = [];
this.focusIcons = [];
for (var i = 0; i < this.constraints.length; i++)
{
var cp = this.graph.getConnectionPoint(state, this.constraints[i]);
var img = this.getImageForConstraint(state, this.constraints[i], cp);
var src = img.src;
var bounds = new mxRectangle(Math.round(cp.x - img.width / 2),
Math.round(cp.y - img.height / 2), img.width, img.height);
var icon = new mxImageShape(bounds, src);
icon.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
icon.preserveImageAspect = false;
icon.init(this.graph.getView().getDecoratorPane());
if (mxClient.IS_QUIRKS || document.documentMode == 8)
{
mxEvent.addListener(icon.node, 'dragstart', function(evt)
{
mxEvent.consume(evt);
return false;
});
}
if (icon.node.previousSibling != null)
{
icon.node.parentNode.insertBefore(icon.node, icon.node.parentNode.firstChild);
}
var getState = mxUtils.bind(this, function()
{
return (this.currentFocus != null) ? this.currentFocus : state;
});
icon.redraw();
mxEvent.redirectMouseEvents(icon.node, this.graph, getState);
this.currentFocusArea.add(icon.bounds);
this.focusIcons.push(icon);
this.focusPoints.push(cp);
}
this.currentFocusArea.grow(this.getTolerance(me));
}
else
{
this.destroyIcons();
this.destroyFocusHighlight();
}
};
mxConstraintHandler.prototype.createHighlightShape = function()
{
var hl = new mxRectangleShape(null, this.highlightColor, this.highlightColor, mxConstants.HIGHLIGHT_STROKEWIDTH);
hl.opacity = mxConstants.HIGHLIGHT_OPACITY;
return hl;
};
mxConstraintHandler.prototype.intersects = function(icon, mouse, source, existingEdge)
{
return mxUtils.intersects(icon.bounds, mouse);
};
mxConstraintHandler.prototype.destroy = function()
{
this.reset();
if (this.resetHandler != null)
{
this.graph.model.removeListener(this.resetHandler);
this.graph.view.removeListener(this.resetHandler);
this.graph.removeListener(this.resetHandler);
this.resetHandler = null;
}
if (this.mouseleaveHandler != null && this.graph.container != null)
{
mxEvent.removeListener(this.graph.container, 'mouseleave', this.mouseleaveHandler);
this.mouseleaveHandler = null;
}
};
__mxOutput.mxConstraintHandler = typeof mxConstraintHandler !== 'undefined' ? mxConstraintHandler : undefined;
function mxRubberband(graph)
{
if (graph != null)
{
this.graph = graph;
this.graph.addMouseListener(this);
this.forceRubberbandHandler = mxUtils.bind(this, function(sender, evt)
{
var evtName = evt.getProperty('eventName');
var me = evt.getProperty('event');
if (evtName == mxEvent.MOUSE_DOWN && this.isForceRubberbandEvent(me))
{
var offset = mxUtils.getOffset(this.graph.container);
var origin = mxUtils.getScrollOrigin(this.graph.container);
origin.x -= offset.x;
origin.y -= offset.y;
this.start(me.getX() + origin.x, me.getY() + origin.y);
me.consume(false);
}
});
this.graph.addListener(mxEvent.FIRE_MOUSE_EVENT, this.forceRubberbandHandler);
this.panHandler = mxUtils.bind(this, function()
{
this.repaint();
});
this.graph.addListener(mxEvent.PAN, this.panHandler);
this.gestureHandler = mxUtils.bind(this, function(sender, eo)
{
if (this.first != null)
{
this.reset();
}
});
this.graph.addListener(mxEvent.GESTURE, this.gestureHandler);
if (mxClient.IS_IE)
{
mxEvent.addListener(window, 'unload',
mxUtils.bind(this, function()
{
this.destroy();
})
);
}
}
} mxRubberband.prototype.defaultOpacity = 20;
mxRubberband.prototype.enabled = true;
mxRubberband.prototype.div = null;
mxRubberband.prototype.sharedDiv = null;
mxRubberband.prototype.currentX = 0;
mxRubberband.prototype.currentY = 0;
mxRubberband.prototype.fadeOut = false;
mxRubberband.prototype.isEnabled = function()
{
return this.enabled;
};
mxRubberband.prototype.setEnabled = function(enabled)
{
this.enabled = enabled;
};
mxRubberband.prototype.isForceRubberbandEvent = function(me)
{
return mxEvent.isAltDown(me.getEvent());
};
mxRubberband.prototype.mouseDown = function(sender, me)
{
if (!me.isConsumed() && this.isEnabled() && this.graph.isEnabled() &&
me.getState() == null && !mxEvent.isMultiTouchEvent(me.getEvent()))
{
var offset = mxUtils.getOffset(this.graph.container);
var origin = mxUtils.getScrollOrigin(this.graph.container);
origin.x -= offset.x;
origin.y -= offset.y;
this.start(me.getX() + origin.x, me.getY() + origin.y);
me.consume(false);
}
};
mxRubberband.prototype.start = function(x, y)
{
this.first = new mxPoint(x, y);
var container = this.graph.container;
function createMouseEvent(evt)
{
var me = new mxMouseEvent(evt);
var pt = mxUtils.convertPoint(container, me.getX(), me.getY());
me.graphX = pt.x;
me.graphY = pt.y;
return me;
} this.dragHandler = mxUtils.bind(this, function(evt)
{
this.mouseMove(this.graph, createMouseEvent(evt));
});
this.dropHandler = mxUtils.bind(this, function(evt)
{
this.mouseUp(this.graph, createMouseEvent(evt));
});
if (mxClient.IS_FF)
{
mxEvent.addGestureListeners(document, null, this.dragHandler, this.dropHandler);
}
};
mxRubberband.prototype.mouseMove = function(sender, me)
{
if (!me.isConsumed() && this.first != null)
{
var origin = mxUtils.getScrollOrigin(this.graph.container);
var offset = mxUtils.getOffset(this.graph.container);
origin.x -= offset.x;
origin.y -= offset.y;
var x = me.getX() + origin.x;
var y = me.getY() + origin.y;
var dx = this.first.x - x;
var dy = this.first.y - y;
var tol = this.graph.tolerance;
if (this.div != null || Math.abs(dx) > tol || Math.abs(dy) > tol)
{
if (this.div == null)
{
this.div = this.createShape();
}
mxUtils.clearSelection();
this.update(x, y);
me.consume();
}
}
};
mxRubberband.prototype.createShape = function()
{
if (this.sharedDiv == null)
{
this.sharedDiv = document.createElement('div');
this.sharedDiv.className = 'mxRubberband';
mxUtils.setOpacity(this.sharedDiv, this.defaultOpacity);
}
this.graph.container.appendChild(this.sharedDiv);
var result = this.sharedDiv;
if (mxClient.IS_SVG && (!mxClient.IS_IE || document.documentMode >= 10) && this.fadeOut)
{
this.sharedDiv = null;
}
return result;
};
mxRubberband.prototype.isActive = function(sender, me)
{
return this.div != null && this.div.style.display != 'none';
};
mxRubberband.prototype.mouseUp = function(sender, me)
{
var active = this.isActive();
this.reset();
if (active)
{
this.execute(me.getEvent());
me.consume();
}
};
mxRubberband.prototype.execute = function(evt)
{
var rect = new mxRectangle(this.x, this.y, this.width, this.height);
this.graph.selectRegion(rect, evt);
};
mxRubberband.prototype.reset = function()
{
if (this.div != null)
{
if (mxClient.IS_SVG && (!mxClient.IS_IE || document.documentMode >= 10) && this.fadeOut)
{
var temp = this.div;
mxUtils.setPrefixedStyle(temp.style, 'transition', 'all 0.2s linear');
temp.style.pointerEvents = 'none';
temp.style.opacity = 0;
window.setTimeout(function()
{
temp.parentNode.removeChild(temp);
}, 200);
}
else
{
this.div.parentNode.removeChild(this.div);
}
}
mxEvent.removeGestureListeners(document, null, this.dragHandler, this.dropHandler);
this.dragHandler = null;
this.dropHandler = null;
this.currentX = 0;
this.currentY = 0;
this.first = null;
this.div = null;
};
mxRubberband.prototype.update = function(x, y)
{
this.currentX = x;
this.currentY = y;
this.repaint();
};
mxRubberband.prototype.repaint = function()
{
if (this.div != null)
{
var x = this.currentX - this.graph.panDx;
var y = this.currentY - this.graph.panDy;
this.x = Math.min(this.first.x, x);
this.y = Math.min(this.first.y, y);
this.width = Math.max(this.first.x, x) - this.x;
this.height = Math.max(this.first.y, y) - this.y;
var dx = (mxClient.IS_VML) ? this.graph.panDx : 0;
var dy = (mxClient.IS_VML) ? this.graph.panDy : 0;
this.div.style.left = (this.x + dx) + 'px';
this.div.style.top = (this.y + dy) + 'px';
this.div.style.width = Math.max(1, this.width) + 'px';
this.div.style.height = Math.max(1, this.height) + 'px';
}
};
mxRubberband.prototype.destroy = function()
{
if (!this.destroyed)
{
this.destroyed = true;
this.graph.removeMouseListener(this);
this.graph.removeListener(this.forceRubberbandHandler);
this.graph.removeListener(this.panHandler);
this.reset();
if (this.sharedDiv != null)
{
this.sharedDiv = null;
}
}
};
__mxOutput.mxRubberband = typeof mxRubberband !== 'undefined' ? mxRubberband : undefined;
function mxHandle(state, cursor, image, shape)
{
this.graph = state.view.graph;
this.state = state;
this.cursor = (cursor != null) ? cursor : this.cursor;
this.image = (image != null) ? image : this.image;
this.shape = (shape != null) ? shape : null;
this.init();
} mxHandle.prototype.cursor = 'default';
mxHandle.prototype.image = null;
mxHandle.prototype.ignoreGrid = false;
mxHandle.prototype.getPosition = function(bounds) { };
mxHandle.prototype.setPosition = function(bounds, pt, me) { };
mxHandle.prototype.execute = function(me) { };
mxHandle.prototype.copyStyle = function(key)
{
this.graph.setCellStyles(key, this.state.style[key], [this.state.cell]);
};
mxHandle.prototype.processEvent = function(me)
{
var scale = this.graph.view.scale;
var tr = this.graph.view.translate;
var pt = new mxPoint(me.getGraphX() / scale - tr.x, me.getGraphY() / scale - tr.y);
if (this.shape != null && this.shape.bounds != null)
{
pt.x -= this.shape.bounds.width / scale / 4;
pt.y -= this.shape.bounds.height / scale / 4;
}
var alpha1 = -mxUtils.toRadians(this.getRotation());
var alpha2 = -mxUtils.toRadians(this.getTotalRotation()) - alpha1;
pt = this.flipPoint(this.rotatePoint(this.snapPoint(this.rotatePoint(pt, alpha1),
this.ignoreGrid || !this.graph.isGridEnabledEvent(me.getEvent())), alpha2));
this.setPosition(this.state.getPaintBounds(), pt, me);
this.redraw();
};
mxHandle.prototype.positionChanged = function()
{
if (this.state.text != null)
{
this.state.text.apply(this.state);
}
if (this.state.shape != null)
{
this.state.shape.apply(this.state);
}
this.graph.cellRenderer.redraw(this.state, true);
};
mxHandle.prototype.getRotation = function()
{
if (this.state.shape != null)
{
return this.state.shape.getRotation();
}
return 0;
};
mxHandle.prototype.getTotalRotation = function()
{
if (this.state.shape != null)
{
return this.state.shape.getShapeRotation();
}
return 0;
};
mxHandle.prototype.init = function()
{
var html = this.isHtmlRequired();
if (this.image != null)
{
this.shape = new mxImageShape(new mxRectangle(0, 0, this.image.width, this.image.height), this.image.src);
this.shape.preserveImageAspect = false;
}
else if (this.shape == null)
{
this.shape = this.createShape(html);
}
this.initShape(html);
};
mxHandle.prototype.createShape = function(html)
{
var bounds = new mxRectangle(0, 0, mxConstants.HANDLE_SIZE, mxConstants.HANDLE_SIZE);
return new mxRectangleShape(bounds, mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
};
mxHandle.prototype.initShape = function(html)
{
if (html && this.shape.isHtmlAllowed())
{
this.shape.dialect = mxConstants.DIALECT_STRICTHTML;
this.shape.init(this.graph.container);
}
else
{
this.shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
if (this.cursor != null)
{
this.shape.init(this.graph.getView().getOverlayPane());
}
}
mxEvent.redirectMouseEvents(this.shape.node, this.graph, this.state);
this.shape.node.style.cursor = this.cursor;
};
mxHandle.prototype.redraw = function()
{
if (this.shape != null && this.state.shape != null)
{
var pt = this.getPosition(this.state.getPaintBounds());
if (pt != null)
{
var alpha = mxUtils.toRadians(this.getTotalRotation());
pt = this.rotatePoint(this.flipPoint(pt), alpha);
var scale = this.graph.view.scale;
var tr = this.graph.view.translate;
this.shape.bounds.x = Math.floor((pt.x + tr.x) * scale - this.shape.bounds.width / 2);
this.shape.bounds.y = Math.floor((pt.y + tr.y) * scale - this.shape.bounds.height / 2);
this.shape.redraw();
}
}
};
mxHandle.prototype.isHtmlRequired = function()
{
return this.state.text != null && this.state.text.node.parentNode == this.graph.container;
};
mxHandle.prototype.rotatePoint = function(pt, alpha)
{
var bounds = this.state.getCellBounds();
var cx = new mxPoint(bounds.getCenterX(), bounds.getCenterY());
var cos = Math.cos(alpha);
var sin = Math.sin(alpha);
return mxUtils.getRotatedPoint(pt, cos, sin, cx);
};
mxHandle.prototype.flipPoint = function(pt)
{
if (this.state.shape != null)
{
var bounds = this.state.getCellBounds();
if (this.state.shape.flipH)
{
pt.x = 2 * bounds.x + bounds.width - pt.x;
}
if (this.state.shape.flipV)
{
pt.y = 2 * bounds.y + bounds.height - pt.y;
}
}
return pt;
};
mxHandle.prototype.snapPoint = function(pt, ignore)
{
if (!ignore)
{
pt.x = this.graph.snap(pt.x);
pt.y = this.graph.snap(pt.y);
}
return pt;
};
mxHandle.prototype.setVisible = function(visible)
{
if (this.shape != null && this.shape.node != null)
{
this.shape.node.style.display = (visible) ? '' : 'none';
}
};
mxHandle.prototype.reset = function()
{
this.setVisible(true);
this.state.style = this.graph.getCellStyle(this.state.cell);
this.positionChanged();
};
mxHandle.prototype.destroy = function()
{
if (this.shape != null)
{
this.shape.destroy();
this.shape = null;
}
};
__mxOutput.mxHandle = typeof mxHandle !== 'undefined' ? mxHandle : undefined;
function mxVertexHandler(state)
{
if (state != null)
{
this.state = state;
this.init();
this.escapeHandler = mxUtils.bind(this, function(sender, evt)
{
if (this.livePreview && this.index != null)
{
this.state.view.graph.cellRenderer.redraw(this.state, true);
this.state.view.invalidate(this.state.cell);
this.state.invalid = false;
this.state.view.validate();
}
this.reset();
});
this.state.view.graph.addListener(mxEvent.ESCAPE, this.escapeHandler);
}
} mxVertexHandler.prototype.graph = null;
mxVertexHandler.prototype.state = null;
mxVertexHandler.prototype.singleSizer = false;
mxVertexHandler.prototype.index = null;
mxVertexHandler.prototype.allowHandleBoundsCheck = true;
mxVertexHandler.prototype.handleImage = null;
mxVertexHandler.prototype.handlesVisible = true;
mxVertexHandler.prototype.tolerance = 0;
mxVertexHandler.prototype.rotationEnabled = false;
mxVertexHandler.prototype.parentHighlightEnabled = false;
mxVertexHandler.prototype.rotationRaster = true;
mxVertexHandler.prototype.rotationCursor = 'crosshair';
mxVertexHandler.prototype.livePreview = false;
mxVertexHandler.prototype.movePreviewToFront = false;
mxVertexHandler.prototype.manageSizers = false;
mxVertexHandler.prototype.constrainGroupByChildren = false;
mxVertexHandler.prototype.rotationHandleVSpacing = -16;
mxVertexHandler.prototype.horizontalOffset = 0;
mxVertexHandler.prototype.verticalOffset = 0;
mxVertexHandler.prototype.init = function()
{
this.graph = this.state.view.graph;
this.selectionBounds = this.getSelectionBounds(this.state);
this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, this.selectionBounds.width, this.selectionBounds.height);
this.selectionBorder = this.createSelectionShape(this.bounds);
this.selectionBorder.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
this.selectionBorder.pointerEvents = false;
this.selectionBorder.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
this.selectionBorder.init(this.graph.getView().getOverlayPane());
mxEvent.redirectMouseEvents(this.selectionBorder.node, this.graph, this.state);
if (this.graph.isCellMovable(this.state.cell))
{
this.selectionBorder.setCursor(mxConstants.CURSOR_MOVABLE_VERTEX);
}
if (mxGraphHandler.prototype.maxCells <= 0 || this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells)
{
var resizable = this.graph.isCellResizable(this.state.cell);
this.sizers = [];
if (resizable || (this.graph.isLabelMovable(this.state.cell) &&
this.state.width >= 2 && this.state.height >= 2))
{
var i = 0;
if (resizable)
{
if (!this.singleSizer)
{
this.sizers.push(this.createSizer('nw-resize', i++));
this.sizers.push(this.createSizer('n-resize', i++));
this.sizers.push(this.createSizer('ne-resize', i++));
this.sizers.push(this.createSizer('w-resize', i++));
this.sizers.push(this.createSizer('e-resize', i++));
this.sizers.push(this.createSizer('sw-resize', i++));
this.sizers.push(this.createSizer('s-resize', i++));
}
this.sizers.push(this.createSizer('se-resize', i++));
}
var geo = this.graph.model.getGeometry(this.state.cell);
if (geo != null && !geo.relative && !this.graph.isSwimlane(this.state.cell) &&
this.graph.isLabelMovable(this.state.cell))
{
this.labelShape = this.createSizer(mxConstants.CURSOR_LABEL_HANDLE, mxEvent.LABEL_HANDLE,
mxConstants.LABEL_HANDLE_SIZE, mxConstants.LABEL_HANDLE_FILLCOLOR);
this.sizers.push(this.labelShape);
}
}
else if (this.graph.isCellMovable(this.state.cell) && !this.graph.isCellResizable(this.state.cell) &&
this.state.width < 2 && this.state.height < 2)
{
this.labelShape = this.createSizer(mxConstants.CURSOR_MOVABLE_VERTEX,
mxEvent.LABEL_HANDLE, null, mxConstants.LABEL_HANDLE_FILLCOLOR);
this.sizers.push(this.labelShape);
}
}
if (this.isRotationHandleVisible())
{
this.rotationShape = this.createSizer(this.rotationCursor, mxEvent.ROTATION_HANDLE,
mxConstants.HANDLE_SIZE + 3, mxConstants.HANDLE_FILLCOLOR);
this.sizers.push(this.rotationShape);
}
this.customHandles = this.createCustomHandles();
this.redraw();
if (this.constrainGroupByChildren)
{
this.updateMinBounds();
}
};
mxVertexHandler.prototype.isRotationHandleVisible = function()
{
return this.graph.isEnabled() && this.rotationEnabled && this.graph.isCellRotatable(this.state.cell) &&
(mxGraphHandler.prototype.maxCells <= 0 || this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells);
};
mxVertexHandler.prototype.isConstrainedEvent = function(me)
{
return mxEvent.isShiftDown(me.getEvent()) || this.state.style[mxConstants.STYLE_ASPECT] == 'fixed';
};
mxVertexHandler.prototype.isCenteredEvent = function(state, me)
{
return false;
};
mxVertexHandler.prototype.createCustomHandles = function()
{
return null;
};
mxVertexHandler.prototype.updateMinBounds = function()
{
var children = this.graph.getChildCells(this.state.cell);
if (children.length > 0)
{
this.minBounds = this.graph.view.getBounds(children);
if (this.minBounds != null)
{
var s = this.state.view.scale;
var t = this.state.view.translate;
this.minBounds.x -= this.state.x;
this.minBounds.y -= this.state.y;
this.minBounds.x /= s;
this.minBounds.y /= s;
this.minBounds.width /= s;
this.minBounds.height /= s;
this.x0 = this.state.x / s - t.x;
this.y0 = this.state.y / s - t.y;
}
}
};
mxVertexHandler.prototype.getSelectionBounds = function(state)
{
return new mxRectangle(Math.round(state.x), Math.round(state.y), Math.round(state.width), Math.round(state.height));
};
mxVertexHandler.prototype.createParentHighlightShape = function(bounds)
{
return this.createSelectionShape(bounds);
};
mxVertexHandler.prototype.createSelectionShape = function(bounds)
{
var shape = new mxRectangleShape(
mxRectangle.fromRectangle(bounds),
null, this.getSelectionColor());
shape.strokewidth = this.getSelectionStrokeWidth();
shape.isDashed = this.isSelectionDashed();
return shape;
};
mxVertexHandler.prototype.getSelectionColor = function()
{
return mxConstants.VERTEX_SELECTION_COLOR;
};
mxVertexHandler.prototype.getSelectionStrokeWidth = function()
{
return mxConstants.VERTEX_SELECTION_STROKEWIDTH;
};
mxVertexHandler.prototype.isSelectionDashed = function()
{
return mxConstants.VERTEX_SELECTION_DASHED;
};
mxVertexHandler.prototype.createSizer = function(cursor, index, size, fillColor)
{
size = size || mxConstants.HANDLE_SIZE;
var bounds = new mxRectangle(0, 0, size, size);
var sizer = this.createSizerShape(bounds, index, fillColor);
if (sizer.isHtmlAllowed() && this.state.text != null && this.state.text.node.parentNode == this.graph.container)
{
sizer.bounds.height -= 1;
sizer.bounds.width -= 1;
sizer.dialect = mxConstants.DIALECT_STRICTHTML;
sizer.init(this.graph.container);
}
else
{
sizer.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
sizer.init(this.graph.getView().getOverlayPane());
}
mxEvent.redirectMouseEvents(sizer.node, this.graph, this.state);
if (this.graph.isEnabled())
{
sizer.setCursor(cursor);
}
if (!this.isSizerVisible(index))
{
sizer.visible = false;
}
return sizer;
};
mxVertexHandler.prototype.isSizerVisible = function(index)
{
return true;
};
mxVertexHandler.prototype.createSizerShape = function(bounds, index, fillColor)
{
if (this.handleImage != null)
{
bounds = new mxRectangle(bounds.x, bounds.y, this.handleImage.width, this.handleImage.height);
var shape = new mxImageShape(bounds, this.handleImage.src);
shape.preserveImageAspect = false;
return shape;
}
else if (index == mxEvent.ROTATION_HANDLE)
{
return new mxEllipse(bounds, fillColor || mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
}
else
{
return new mxRectangleShape(bounds, fillColor || mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
}
};
mxVertexHandler.prototype.moveSizerTo = function(shape, x, y)
{
if (shape != null)
{
shape.bounds.x = Math.floor(x - shape.bounds.width / 2);
shape.bounds.y = Math.floor(y - shape.bounds.height / 2);
if (shape.node != null && shape.node.style.display != 'none')
{
shape.redraw();
}
}
};
mxVertexHandler.prototype.getHandleForEvent = function(me)
{
var tol = (!mxEvent.isMouseEvent(me.getEvent())) ? this.tolerance : 1;
var hit = (this.allowHandleBoundsCheck && (mxClient.IS_IE || tol > 0)) ?
new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol) : null;
var checkShape = mxUtils.bind(this, function(shape)
{
var st = (shape != null && shape.constructor != mxImageShape &&
this.allowHandleBoundsCheck) ? shape.strokewidth + shape.svgStrokeTolerance : null;
var real = (st != null) ? new mxRectangle(me.getGraphX() - Math.floor(st / 2),
me.getGraphY() - Math.floor(st / 2), st, st) : hit;
return shape != null && (me.isSource(shape) || (real != null && mxUtils.intersects(shape.bounds, real) &&
shape.node.style.display != 'none' && shape.node.style.visibility != 'hidden'));
});
if (checkShape(this.rotationShape))
{
return mxEvent.ROTATION_HANDLE;
}
else if (checkShape(this.labelShape))
{
return mxEvent.LABEL_HANDLE;
}
if (this.sizers != null)
{
for (var i = 0; i < this.sizers.length; i++)
{
if (checkShape(this.sizers[i]))
{
return i;
}
}
}
if (this.customHandles != null && this.isCustomHandleEvent(me))
{
for (var i = this.customHandles.length - 1; i >= 0; i--)
{
if (checkShape(this.customHandles[i].shape))
{
return mxEvent.CUSTOM_HANDLE - i;
}
}
}
return null;
};
mxVertexHandler.prototype.isCustomHandleEvent = function(me)
{
return true;
};
mxVertexHandler.prototype.mouseDown = function(sender, me)
{
if (!me.isConsumed() && this.graph.isEnabled())
{
var handle = this.getHandleForEvent(me);
if (handle != null)
{
this.start(me.getGraphX(), me.getGraphY(), handle);
me.consume();
}
}
};
mxVertexHandler.prototype.isLivePreviewBorder = function()
{
return this.state.shape != null && this.state.shape.fill == null && this.state.shape.stroke == null;
};
mxVertexHandler.prototype.start = function(x, y, index)
{
if (this.selectionBorder != null)
{
this.livePreviewActive = this.livePreview && this.graph.model.getChildCount(this.state.cell) == 0;
this.inTolerance = true;
this.childOffsetX = 0;
this.childOffsetY = 0;
this.index = index;
this.startX = x;
this.startY = y;
if (this.index <= mxEvent.CUSTOM_HANDLE && this.isGhostPreview())
{
this.ghostPreview = this.createGhostPreview();
}
else
{
var model = this.state.view.graph.model;
var parent = model.getParent(this.state.cell);
if (this.state.view.currentRoot != parent && (model.isVertex(parent) || model.isEdge(parent)))
{
this.parentState = this.state.view.graph.view.getState(parent);
}
this.selectionBorder.node.style.display = (index == mxEvent.ROTATION_HANDLE) ? 'inline' : 'none';
if (!this.livePreviewActive || this.isLivePreviewBorder())
{
this.preview = this.createSelectionShape(this.bounds);
if (!(mxClient.IS_SVG && Number(this.state.style[mxConstants.STYLE_ROTATION] || '0') != 0) &&
this.state.text != null && this.state.text.node.parentNode == this.graph.container)
{
this.preview.dialect = mxConstants.DIALECT_STRICTHTML;
this.preview.init(this.graph.container);
}
else
{
this.preview.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
this.preview.init(this.graph.view.getOverlayPane());
}
}
if (index == mxEvent.ROTATION_HANDLE)
{
var pos = this.getRotationHandlePosition();
var dx = pos.x - this.state.getCenterX();
var dy = pos.y - this.state.getCenterY();
this.startAngle = (dx != 0) ? Math.atan(dy / dx) * 180 / Math.PI + 90 : 0;
this.startDist = Math.sqrt(dx * dx + dy * dy);
}
if (this.livePreviewActive)
{
this.hideSizers();
if (index == mxEvent.ROTATION_HANDLE)
{
this.rotationShape.node.style.display = '';
}
else if (index == mxEvent.LABEL_HANDLE)
{
this.labelShape.node.style.display = '';
}
else if (this.sizers != null && this.sizers[index] != null)
{
this.sizers[index].node.style.display = '';
}
else if (index <= mxEvent.CUSTOM_HANDLE && this.customHandles != null)
{
this.customHandles[mxEvent.CUSTOM_HANDLE - index].setVisible(true);
}
var edges = this.graph.getEdges(this.state.cell);
this.edgeHandlers = [];
for (var i = 0; i < edges.length; i++)
{
var handler = this.graph.selectionCellsHandler.getHandler(edges[i]);
if (handler != null)
{
this.edgeHandlers.push(handler);
}
}
}
}
}
};
mxVertexHandler.prototype.createGhostPreview = function()
{
var shape = this.graph.cellRenderer.createShape(this.state);
shape.init(this.graph.view.getOverlayPane());
shape.scale = this.state.view.scale;
shape.bounds = this.bounds;
shape.outline = true;
return shape;
};
mxVertexHandler.prototype.setHandlesVisible = function(visible)
{
this.handlesVisible = visible;
if (this.sizers != null)
{
for (var i = 0; i < this.sizers.length; i++)
{
this.sizers[i].node.style.display = (visible) ? '' : 'none';
}
}
if (this.customHandles != null)
{
for (var i = 0; i < this.customHandles.length; i++)
{
this.customHandles[i].setVisible(visible);
}
}
};
mxVertexHandler.prototype.hideSizers = function()
{
this.setHandlesVisible(false);
};
mxVertexHandler.prototype.checkTolerance = function(me)
{
if (this.inTolerance && this.startX != null && this.startY != null)
{
if (mxEvent.isMouseEvent(me.getEvent()) ||
Math.abs(me.getGraphX() - this.startX) > this.graph.tolerance ||
Math.abs(me.getGraphY() - this.startY) > this.graph.tolerance)
{
this.inTolerance = false;
}
}
};
mxVertexHandler.prototype.updateHint = function(me) { };
mxVertexHandler.prototype.removeHint = function() { };
mxVertexHandler.prototype.roundAngle = function(angle)
{
return Math.round(angle * 10) / 10;
};
mxVertexHandler.prototype.roundLength = function(length)
{
return Math.round(length * 100) / 100;
};
mxVertexHandler.prototype.mouseMove = function(sender, me)
{
if (!me.isConsumed() && this.index != null)
{
this.checkTolerance(me);
if (!this.inTolerance)
{
if (this.index <= mxEvent.CUSTOM_HANDLE)
{
if (this.customHandles != null)
{
this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].processEvent(me);
this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].active = true;
if (this.ghostPreview != null)
{
this.ghostPreview.apply(this.state);
this.ghostPreview.strokewidth = this.getSelectionStrokeWidth() /
this.ghostPreview.scale / this.ghostPreview.scale;
this.ghostPreview.isDashed = this.isSelectionDashed();
this.ghostPreview.stroke = this.getSelectionColor();
this.ghostPreview.redraw();
if (this.selectionBounds != null)
{
this.selectionBorder.node.style.display = 'none';
}
}
else
{
if (this.movePreviewToFront)
{
this.moveToFront();
}
this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].positionChanged();
}
}
}
else if (this.index == mxEvent.LABEL_HANDLE)
{
this.moveLabel(me);
}
else
{
if (this.index == mxEvent.ROTATION_HANDLE)
{
this.rotateVertex(me);
}
else
{
this.resizeVertex(me);
}
this.updateHint(me);
}
}
me.consume();
}
else if (!this.graph.isMouseDown && this.getHandleForEvent(me) != null)
{
me.consume(false);
}
};
mxVertexHandler.prototype.isGhostPreview = function()
{
return this.state.view.graph.model.getChildCount(this.state.cell) > 0;
};
mxVertexHandler.prototype.moveLabel = function(me)
{
var point = new mxPoint(me.getGraphX(), me.getGraphY());
var tr = this.graph.view.translate;
var scale = this.graph.view.scale;
if (this.graph.isGridEnabledEvent(me.getEvent()))
{
point.x = (this.graph.snap(point.x / scale - tr.x) + tr.x) * scale;
point.y = (this.graph.snap(point.y / scale - tr.y) + tr.y) * scale;
}
var index = (this.rotationShape != null) ? this.sizers.length - 2 : this.sizers.length - 1;
this.moveSizerTo(this.sizers[index], point.x, point.y);
};
mxVertexHandler.prototype.rotateVertex = function(me)
{
var point = new mxPoint(me.getGraphX(), me.getGraphY());
var dx = this.state.x + this.state.width / 2 - point.x;
var dy = this.state.y + this.state.height / 2 - point.y;
this.currentAlpha = (dx != 0) ? Math.atan(dy / dx) * 180 / Math.PI + 90 : ((dy < 0) ? 180 : 0);
if (dx > 0)
{
this.currentAlpha -= 180;
}
this.currentAlpha -= this.startAngle;
if (this.rotationRaster && this.graph.isGridEnabledEvent(me.getEvent()))
{
var dx = point.x - this.state.getCenterX();
var dy = point.y - this.state.getCenterY();
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist - this.startDist < 2)
{
raster = 15;
}
else if (dist - this.startDist < 25)
{
raster = 5;
}
else
{
raster = 1;
}
this.currentAlpha = Math.round(this.currentAlpha / raster) * raster;
}
else
{
this.currentAlpha = this.roundAngle(this.currentAlpha);
}
this.selectionBorder.rotation = this.currentAlpha;
this.selectionBorder.redraw();
if (this.livePreviewActive)
{
this.redrawHandles();
}
};
mxVertexHandler.prototype.resizeVertex = function(me)
{
var ct = new mxPoint(this.state.getCenterX(), this.state.getCenterY());
var alpha = mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
var point = new mxPoint(me.getGraphX(), me.getGraphY());
var tr = this.graph.view.translate;
var scale = this.graph.view.scale;
var cos = Math.cos(-alpha);
var sin = Math.sin(-alpha);
var dx = point.x - this.startX;
var dy = point.y - this.startY;
var tx = cos * dx - sin * dy;
var ty = sin * dx + cos * dy;
dx = tx;
dy = ty;
var geo = this.graph.getCellGeometry(this.state.cell);
this.unscaledBounds = this.union(geo, dx / scale, dy / scale, this.index,
this.graph.isGridEnabledEvent(me.getEvent()), 1,
new mxPoint(0, 0), this.isConstrainedEvent(me),
this.isCenteredEvent(this.state, me));
if (!geo.relative)
{
var max = this.graph.getMaximumGraphBounds();
if (max != null && this.parentState != null)
{
max = mxRectangle.fromRectangle(max);
max.x -= (this.parentState.x - tr.x * scale) / scale;
max.y -= (this.parentState.y - tr.y * scale) / scale;
}
if (this.graph.isConstrainChild(this.state.cell))
{
var tmp = this.graph.getCellContainmentArea(this.state.cell);
if (tmp != null)
{
var overlap = this.graph.getOverlap(this.state.cell);
if (overlap > 0)
{
tmp = mxRectangle.fromRectangle(tmp);
tmp.x -= tmp.width * overlap;
tmp.y -= tmp.height * overlap;
tmp.width += 2 * tmp.width * overlap;
tmp.height += 2 * tmp.height * overlap;
}
if (max == null)
{
max = tmp;
}
else
{
max = mxRectangle.fromRectangle(max);
max.intersect(tmp);
}
}
}
if (max != null)
{
if (this.unscaledBounds.x < max.x)
{
this.unscaledBounds.width -= max.x - this.unscaledBounds.x;
this.unscaledBounds.x = max.x;
}
if (this.unscaledBounds.y < max.y)
{
this.unscaledBounds.height -= max.y - this.unscaledBounds.y;
this.unscaledBounds.y = max.y;
}
if (this.unscaledBounds.x + this.unscaledBounds.width > max.x + max.width)
{
this.unscaledBounds.width -= this.unscaledBounds.x +
this.unscaledBounds.width - max.x - max.width;
}
if (this.unscaledBounds.y + this.unscaledBounds.height > max.y + max.height)
{
this.unscaledBounds.height -= this.unscaledBounds.y +
this.unscaledBounds.height - max.y - max.height;
}
}
}
var old = this.bounds;
this.bounds = new mxRectangle(((this.parentState != null) ? this.parentState.x : tr.x * scale) +
(this.unscaledBounds.x) * scale, ((this.parentState != null) ? this.parentState.y : tr.y * scale) +
(this.unscaledBounds.y) * scale, this.unscaledBounds.width * scale, this.unscaledBounds.height * scale);
if (geo.relative && this.parentState != null)
{
this.bounds.x += this.state.x - this.parentState.x;
this.bounds.y += this.state.y - this.parentState.y;
}
cos = Math.cos(alpha);
sin = Math.sin(alpha);
var c2 = new mxPoint(this.bounds.getCenterX(), this.bounds.getCenterY());
var dx = c2.x - ct.x;
var dy = c2.y - ct.y;
var dx2 = cos * dx - sin * dy;
var dy2 = sin * dx + cos * dy;
var dx3 = dx2 - dx;
var dy3 = dy2 - dy;
var dx4 = this.bounds.x - this.state.x;
var dy4 = this.bounds.y - this.state.y;
var dx5 = cos * dx4 - sin * dy4;
var dy5 = sin * dx4 + cos * dy4;
this.bounds.x += dx3;
this.bounds.y += dy3;
this.unscaledBounds.x = this.roundLength(this.unscaledBounds.x + dx3 / scale);
this.unscaledBounds.y = this.roundLength(this.unscaledBounds.y + dy3 / scale);
this.unscaledBounds.width = this.roundLength(this.unscaledBounds.width);
this.unscaledBounds.height = this.roundLength(this.unscaledBounds.height);
if (!this.graph.isCellCollapsed(this.state.cell) && (dx3 != 0 || dy3 != 0))
{
this.childOffsetX = this.state.x - this.bounds.x + dx5;
this.childOffsetY = this.state.y - this.bounds.y + dy5;
}
else
{
this.childOffsetX = 0;
this.childOffsetY = 0;
}
if (!old.equals(this.bounds))
{
if (this.livePreviewActive)
{
this.updateLivePreview(me);
}
if (this.preview != null)
{
this.drawPreview();
}
else
{
this.updateParentHighlight();
}
}
};
mxVertexHandler.prototype.updateLivePreview = function(me)
{
var scale = this.graph.view.scale;
var tr = this.graph.view.translate;
var tempState = this.state.clone();
this.state.x = this.bounds.x;
this.state.y = this.bounds.y;
this.state.origin = new mxPoint(this.state.x / scale - tr.x, this.state.y / scale - tr.y);
this.state.width = this.bounds.width;
this.state.height = this.bounds.height;
var off = this.state.absoluteOffset;
off = new mxPoint(off.x, off.y);
this.state.absoluteOffset.x = 0;
this.state.absoluteOffset.y = 0;
var geo = this.graph.getCellGeometry(this.state.cell);
if (geo != null)
{
var offset = geo.offset || this.EMPTY_POINT;
if (offset != null && !geo.relative)
{
this.state.absoluteOffset.x = this.state.view.scale * offset.x;
this.state.absoluteOffset.y = this.state.view.scale * offset.y;
}
this.state.view.updateVertexLabelOffset(this.state);
}
this.state.view.graph.cellRenderer.redraw(this.state, true);
this.state.view.invalidate(this.state.cell);
this.state.invalid = false;
this.state.view.validate();
this.redrawHandles();
if (this.movePreviewToFront)
{
this.moveToFront();
}
if (this.state.control != null && this.state.control.node != null)
{
this.state.control.node.style.visibility = 'hidden';
}
this.state.setState(tempState);
};
mxVertexHandler.prototype.moveToFront = function()
{
if ((this.state.text != null && this.state.text.node != null &&
this.state.text.node.nextSibling != null) ||
(this.state.shape != null && this.state.shape.node != null &&
this.state.shape.node.nextSibling != null && (this.state.text == null ||
this.state.shape.node.nextSibling != this.state.text.node)))
{
if (this.state.shape != null && this.state.shape.node != null)
{
this.state.shape.node.parentNode.appendChild(this.state.shape.node);
}
if (this.state.text != null && this.state.text.node != null)
{
this.state.text.node.parentNode.appendChild(this.state.text.node);
}
}
};
mxVertexHandler.prototype.mouseUp = function(sender, me)
{
if (this.index != null && this.state != null)
{
var point = new mxPoint(me.getGraphX(), me.getGraphY());
var index = this.index;
this.index = null;
if (this.ghostPreview == null)
{
this.state.view.invalidate(this.state.cell, false, false);
this.state.view.validate();
}
this.graph.getModel().beginUpdate();
try
{
if (index <= mxEvent.CUSTOM_HANDLE)
{
if (this.customHandles != null)
{
var style = this.state.view.graph.getCellStyle(this.state.cell);
this.customHandles[mxEvent.CUSTOM_HANDLE - index].active = false;
this.customHandles[mxEvent.CUSTOM_HANDLE - index].execute(me);
if (this.customHandles != null &&
this.customHandles[mxEvent.CUSTOM_HANDLE - index] != null)
{
this.state.style = style;
this.customHandles[mxEvent.CUSTOM_HANDLE - index].positionChanged();
}
}
}
else if (index == mxEvent.ROTATION_HANDLE)
{
if (this.currentAlpha != null)
{
var delta = this.currentAlpha - (this.state.style[mxConstants.STYLE_ROTATION] || 0);
if (delta != 0)
{
this.rotateCell(this.state.cell, delta);
}
}
else
{
this.rotateClick();
}
}
else
{
var gridEnabled = this.graph.isGridEnabledEvent(me.getEvent());
var alpha = mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
var cos = Math.cos(-alpha);
var sin = Math.sin(-alpha);
var dx = point.x - this.startX;
var dy = point.y - this.startY;
var tx = cos * dx - sin * dy;
var ty = sin * dx + cos * dy;
dx = tx;
dy = ty;
var s = this.graph.view.scale;
var recurse = this.isRecursiveResize(this.state, me);
this.resizeCell(this.state.cell, this.roundLength(dx / s), this.roundLength(dy / s),
index, gridEnabled, this.isConstrainedEvent(me), recurse);
}
}
finally
{
this.graph.getModel().endUpdate();
}
me.consume();
this.reset();
this.redrawHandles();
}
};
mxVertexHandler.prototype.isRecursiveResize = function(state, me)
{
return this.graph.isRecursiveResize(this.state);
};
mxVertexHandler.prototype.rotateClick = function() { };
mxVertexHandler.prototype.rotateCell = function(cell, angle, parent)
{
if (angle != 0)
{
var model = this.graph.getModel();
if (model.isVertex(cell) || model.isEdge(cell))
{
if (!model.isEdge(cell))
{
var style = this.graph.getCurrentCellStyle(cell);
var total = (style[mxConstants.STYLE_ROTATION] || 0) + angle;
this.graph.setCellStyles(mxConstants.STYLE_ROTATION, total, [cell]);
}
var geo = this.graph.getCellGeometry(cell);
if (geo != null)
{
var pgeo = this.graph.getCellGeometry(parent);
if (pgeo != null && !model.isEdge(parent))
{
geo = geo.clone();
geo.rotate(angle, new mxPoint(pgeo.width / 2, pgeo.height / 2));
model.setGeometry(cell, geo);
}
if ((model.isVertex(cell) && !geo.relative) || model.isEdge(cell))
{
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
this.rotateCell(model.getChildAt(cell, i), angle, cell);
}
}
}
}
}
};
mxVertexHandler.prototype.reset = function()
{
if (this.sizers != null && this.index != null && this.sizers[this.index] != null &&
this.sizers[this.index].node.style.display == 'none')
{
this.sizers[this.index].node.style.display = '';
}
this.currentAlpha = null;
this.inTolerance = null;
this.index = null;
if (this.preview != null)
{
this.preview.destroy();
this.preview = null;
}
if (this.ghostPreview != null)
{
this.ghostPreview.destroy();
this.ghostPreview = null;
}
if (this.livePreviewActive && this.sizers != null)
{
for (var i = 0; i < this.sizers.length; i++)
{
if (this.sizers[i] != null)
{
this.sizers[i].node.style.display = '';
}
}
if (this.state.control != null && this.state.control.node != null)
{
this.state.control.node.style.visibility = '';
}
}
if (this.customHandles != null)
{
for (var i = 0; i < this.customHandles.length; i++)
{
if (this.customHandles[i].active)
{
this.customHandles[i].active = false;
this.customHandles[i].reset();
}
else
{
this.customHandles[i].setVisible(true);
}
}
}
if (this.selectionBorder != null)
{
this.selectionBorder.node.style.display = 'inline';
this.selectionBounds = this.getSelectionBounds(this.state);
this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y,
this.selectionBounds.width, this.selectionBounds.height);
this.drawPreview();
}
this.removeHint();
this.redrawHandles();
this.edgeHandlers = null;
this.handlesVisible = true;
this.unscaledBounds = null;
this.livePreviewActive = null;
};
mxVertexHandler.prototype.resizeCell = function(cell, dx, dy, index, gridEnabled, constrained, recurse)
{
var geo = this.graph.model.getGeometry(cell);
if (geo != null)
{
if (index == mxEvent.LABEL_HANDLE)
{
var alpha = -mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
var cos = Math.cos(alpha);
var sin = Math.sin(alpha);
var scale = this.graph.view.scale;
var pt = mxUtils.getRotatedPoint(new mxPoint(
Math.round((this.labelShape.bounds.getCenterX() - this.startX) / scale),
Math.round((this.labelShape.bounds.getCenterY() - this.startY) / scale)),
cos, sin);
geo = geo.clone();
if (geo.offset == null)
{
geo.offset = pt;
}
else
{
geo.offset.x += pt.x;
geo.offset.y += pt.y;
}
this.graph.model.setGeometry(cell, geo);
}
else if (this.unscaledBounds != null)
{
var scale = this.graph.view.scale;
if (this.childOffsetX != 0 || this.childOffsetY != 0)
{
this.moveChildren(cell, Math.round(this.childOffsetX / scale), Math.round(this.childOffsetY / scale));
}
this.graph.resizeCell(cell, this.unscaledBounds, recurse);
}
}
};
mxVertexHandler.prototype.moveChildren = function(cell, dx, dy)
{
var model = this.graph.getModel();
var childCount = model.getChildCount(cell);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(cell, i);
var geo = this.graph.getCellGeometry(child);
if (geo != null)
{
geo = geo.clone();
geo.translate(dx, dy);
model.setGeometry(child, geo);
}
}
};
mxVertexHandler.prototype.union = function(bounds, dx, dy, index, gridEnabled, scale, tr, constrained, centered)
{
gridEnabled = (gridEnabled != null) ? gridEnabled && this.graph.gridEnabled : this.graph.gridEnabled;
if (this.singleSizer)
{
var x = bounds.x + bounds.width + dx;
var y = bounds.y + bounds.height + dy;
if (gridEnabled)
{
x = this.graph.snap(x / scale) * scale;
y = this.graph.snap(y / scale) * scale;
}
var rect = new mxRectangle(bounds.x, bounds.y, 0, 0);
rect.add(new mxRectangle(x, y, 0, 0));
return rect;
}
else
{
var w0 = bounds.width;
var h0 = bounds.height;
var left = bounds.x - tr.x * scale;
var right = left + w0;
var top = bounds.y - tr.y * scale;
var bottom = top + h0;
var cx = left + w0 / 2;
var cy = top + h0 / 2;
if (index > 4 )
{
bottom = bottom + dy;
if (gridEnabled)
{
bottom = this.graph.snap(bottom / scale) * scale;
}
else
{
bottom = Math.round(bottom / scale) * scale;
}
}
else if (index < 3 )
{
top = top + dy;
if (gridEnabled)
{
top = this.graph.snap(top / scale) * scale;
}
else
{
top = Math.round(top / scale) * scale;
}
}
if (index == 0 || index == 3 || index == 5 )
{
left += dx;
if (gridEnabled)
{
left = this.graph.snap(left / scale) * scale;
}
else
{
left = Math.round(left / scale) * scale;
}
}
else if (index == 2 || index == 4 || index == 7 )
{
right += dx;
if (gridEnabled)
{
right = this.graph.snap(right / scale) * scale;
}
else
{
right = Math.round(right / scale) * scale;
}
}
var width = right - left;
var height = bottom - top;
if (constrained)
{
var geo = this.graph.getCellGeometry(this.state.cell);
if (geo != null)
{
var aspect = geo.width / geo.height;
if (index== 1 || index== 2 || index == 7 || index == 6)
{
width = height * aspect;
}
else
{
height = width / aspect;
}
if (index == 0)
{
left = right - width;
top = bottom - height;
}
}
}
if (centered)
{
width += (width - w0);
height += (height - h0);
var cdx = cx - (left + width / 2);
var cdy = cy - (top + height / 2);
left += cdx;
top += cdy;
right += cdx;
bottom += cdy;
}
if (width < 0)
{
left += width;
width = Math.abs(width);
}
if (height < 0)
{
top += height;
height = Math.abs(height);
}
var result = new mxRectangle(left + tr.x * scale, top + tr.y * scale, width, height);
if (this.minBounds != null)
{
result.width = Math.max(result.width, this.minBounds.x * scale + this.minBounds.width * scale +
Math.max(0, this.x0 * scale - result.x));
result.height = Math.max(result.height, this.minBounds.y * scale + this.minBounds.height * scale +
Math.max(0, this.y0 * scale - result.y));
}
return result;
}
};
mxVertexHandler.prototype.redraw = function(ignoreHandles)
{
this.selectionBounds = this.getSelectionBounds(this.state);
this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y,
this.selectionBounds.width, this.selectionBounds.height);
this.drawPreview();
if (!ignoreHandles)
{
this.redrawHandles();
}
};
mxVertexHandler.prototype.getHandlePadding = function()
{
var result = new mxPoint(0, 0);
var tol = this.tolerance;
if (this.sizers != null && this.sizers.length > 0 && this.sizers[0] != null &&
(this.bounds.width < 2 * this.sizers[0].bounds.width + 2 * tol ||
this.bounds.height < 2 * this.sizers[0].bounds.height + 2 * tol))
{
tol /= 2;
result.x = this.sizers[0].bounds.width + tol;
result.y = this.sizers[0].bounds.height + tol;
}
return result;
};
mxVertexHandler.prototype.getSizerBounds = function()
{
return this.bounds;
};
mxVertexHandler.prototype.redrawHandles = function()
{
var s = this.getSizerBounds();
var tol = this.tolerance;
this.horizontalOffset = 0;
this.verticalOffset = 0;
if (this.customHandles != null)
{
for (var i = 0; i < this.customHandles.length; i++)
{
var temp = this.customHandles[i].shape.node.style.display;
this.customHandles[i].redraw();
this.customHandles[i].shape.node.style.display = temp;
this.customHandles[i].shape.node.style.visibility =
(this.handlesVisible && this.isCustomHandleVisible(
this.customHandles[i])) ? '' : 'hidden';
}
}
if (this.sizers != null && this.sizers.length > 0 && this.sizers[0] != null)
{
if (this.index == null && this.manageSizers && this.sizers.length >= 8)
{
var padding = this.getHandlePadding();
this.horizontalOffset = padding.x;
this.verticalOffset = padding.y;
if (this.horizontalOffset != 0 || this.verticalOffset != 0)
{
s = new mxRectangle(s.x, s.y, s.width, s.height);
s.x -= this.horizontalOffset / 2;
s.width += this.horizontalOffset;
s.y -= this.verticalOffset / 2;
s.height += this.verticalOffset;
}
if (this.sizers.length >= 8)
{
if ((s.width < 2 * this.sizers[0].bounds.width + 2 * tol) ||
(s.height < 2 * this.sizers[0].bounds.height + 2 * tol))
{
this.sizers[0].node.style.display = 'none';
this.sizers[2].node.style.display = 'none';
this.sizers[5].node.style.display = 'none';
this.sizers[7].node.style.display = 'none';
}
else if (this.handlesVisible)
{
this.sizers[0].node.style.display = '';
this.sizers[2].node.style.display = '';
this.sizers[5].node.style.display = '';
this.sizers[7].node.style.display = '';
}
}
}
var r = s.x + s.width;
var b = s.y + s.height;
if (this.singleSizer)
{
this.moveSizerTo(this.sizers[0], r, b);
}
else
{
var cx = s.x + s.width / 2;
var cy = s.y + s.height / 2;
if (this.sizers.length >= 8)
{
var crs = ['nw-resize', 'n-resize', 'ne-resize', 'e-resize', 'se-resize', 's-resize', 'sw-resize', 'w-resize'];
var alpha = mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
var cos = Math.cos(alpha);
var sin = Math.sin(alpha);
var da = Math.round(alpha * 4 / Math.PI);
var ct = new mxPoint(s.getCenterX(), s.getCenterY());
var pt = mxUtils.getRotatedPoint(new mxPoint(s.x, s.y), cos, sin, ct);
this.moveSizerTo(this.sizers[0], pt.x, pt.y);
this.sizers[0].setCursor(crs[mxUtils.mod(0 + da, crs.length)]);
pt.x = cx;
pt.y = s.y;
pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
this.moveSizerTo(this.sizers[1], pt.x, pt.y);
this.sizers[1].setCursor(crs[mxUtils.mod(1 + da, crs.length)]);
pt.x = r;
pt.y = s.y;
pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
this.moveSizerTo(this.sizers[2], pt.x, pt.y);
this.sizers[2].setCursor(crs[mxUtils.mod(2 + da, crs.length)]);
pt.x = s.x;
pt.y = cy;
pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
this.moveSizerTo(this.sizers[3], pt.x, pt.y);
this.sizers[3].setCursor(crs[mxUtils.mod(7 + da, crs.length)]);
pt.x = r;
pt.y = cy;
pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
this.moveSizerTo(this.sizers[4], pt.x, pt.y);
this.sizers[4].setCursor(crs[mxUtils.mod(3 + da, crs.length)]);
pt.x = s.x;
pt.y = b;
pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
this.moveSizerTo(this.sizers[5], pt.x, pt.y);
this.sizers[5].setCursor(crs[mxUtils.mod(6 + da, crs.length)]);
pt.x = cx;
pt.y = b;
pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
this.moveSizerTo(this.sizers[6], pt.x, pt.y);
this.sizers[6].setCursor(crs[mxUtils.mod(5 + da, crs.length)]);
pt.x = r;
pt.y = b;
pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
this.moveSizerTo(this.sizers[7], pt.x, pt.y);
this.sizers[7].setCursor(crs[mxUtils.mod(4 + da, crs.length)]);
pt.x = cx + this.state.absoluteOffset.x;
pt.y = cy + this.state.absoluteOffset.y;
pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
this.moveSizerTo(this.sizers[8], pt.x, pt.y);
}
else if (this.state.width >= 2 && this.state.height >= 2)
{
this.moveSizerTo(this.sizers[0], cx + this.state.absoluteOffset.x, cy + this.state.absoluteOffset.y);
}
else
{
this.moveSizerTo(this.sizers[0], this.state.x, this.state.y);
}
}
}
if (this.rotationShape != null)
{
var alpha = mxUtils.toRadians((this.currentAlpha != null) ? this.currentAlpha : this.state.style[mxConstants.STYLE_ROTATION] || '0');
var cos = Math.cos(alpha);
var sin = Math.sin(alpha);
var ct = new mxPoint(this.state.getCenterX(), this.state.getCenterY());
var pt = mxUtils.getRotatedPoint(this.getRotationHandlePosition(), cos, sin, ct);
if (this.rotationShape.node != null)
{
this.moveSizerTo(this.rotationShape, pt.x, pt.y);
this.rotationShape.node.style.visibility = (this.state.view.graph.isEditing() ||
!this.handlesVisible) ? 'hidden' : '';
}
}
if (this.selectionBorder != null)
{
this.selectionBorder.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
}
if (this.edgeHandlers != null)
{
for (var i = 0; i < this.edgeHandlers.length; i++)
{
this.edgeHandlers[i].redraw();
}
}
};
mxVertexHandler.prototype.isCustomHandleVisible = function(handle)
{
return !this.graph.isEditing() && this.state.view.graph.getSelectionCount() == 1;
};
mxVertexHandler.prototype.getRotationHandlePosition = function()
{
return new mxPoint(this.bounds.x + this.bounds.width / 2, this.bounds.y + this.rotationHandleVSpacing)
};
mxVertexHandler.prototype.isParentHighlightVisible = function()
{
return !this.graph.isCellSelected(this.graph.model.getParent(this.state.cell));
};
mxVertexHandler.prototype.updateParentHighlight = function()
{
if (!this.isDestroyed())
{
var visible = this.isParentHighlightVisible();
var parent = this.graph.model.getParent(this.state.cell);
var pstate = this.graph.view.getState(parent);
if (this.parentHighlight != null)
{
if (this.graph.model.isVertex(parent) && visible)
{
var b = this.parentHighlight.bounds;
if (pstate != null && (b.x != pstate.x || b.y != pstate.y ||
b.width != pstate.width || b.height != pstate.height))
{
this.parentHighlight.bounds = mxRectangle.fromRectangle(pstate);
this.parentHighlight.redraw();
}
}
else
{
if (pstate != null && pstate.parentHighlight == this.parentHighlight)
{
pstate.parentHighlight = null;
}
this.parentHighlight.destroy();
this.parentHighlight = null;
}
}
else if (this.parentHighlightEnabled && visible)
{
if (this.graph.model.isVertex(parent) && pstate != null &&
pstate.parentHighlight == null)
{
this.parentHighlight = this.createParentHighlightShape(pstate);
this.parentHighlight.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
this.parentHighlight.pointerEvents = false;
this.parentHighlight.rotation = Number(pstate.style[mxConstants.STYLE_ROTATION] || '0');
this.parentHighlight.init(this.graph.getView().getOverlayPane());
this.parentHighlight.redraw();
pstate.parentHighlight = this.parentHighlight;
}
}
}
};
mxVertexHandler.prototype.drawPreview = function()
{
if (this.preview != null)
{
this.preview.bounds = this.bounds;
if (this.preview.node.parentNode == this.graph.container)
{
this.preview.bounds.width = Math.max(0, this.preview.bounds.width - 1);
this.preview.bounds.height = Math.max(0, this.preview.bounds.height - 1);
}
this.preview.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
this.preview.redraw();
}
this.selectionBorder.bounds = this.getSelectionBorderBounds();
this.selectionBorder.redraw();
this.updateParentHighlight();
};
mxVertexHandler.prototype.getSelectionBorderBounds = function()
{
return this.bounds;
};
mxVertexHandler.prototype.isDestroyed = function()
{
return this.selectionBorder == null;
};
mxVertexHandler.prototype.destroy = function()
{
if (this.escapeHandler != null)
{
this.state.view.graph.removeListener(this.escapeHandler);
this.escapeHandler = null;
}
if (this.preview != null)
{
this.preview.destroy();
this.preview = null;
}
if (this.parentHighlight != null)
{
var parent = this.graph.model.getParent(this.state.cell);
var pstate = this.graph.view.getState(parent);
if (pstate != null && pstate.parentHighlight == this.parentHighlight)
{
pstate.parentHighlight = null;
}
this.parentHighlight.destroy();
this.parentHighlight = null;
}
if (this.ghostPreview != null)
{
this.ghostPreview.destroy();
this.ghostPreview = null;
}
if (this.selectionBorder != null)
{
this.selectionBorder.destroy();
this.selectionBorder = null;
}
this.labelShape = null;
this.removeHint();
if (this.sizers != null)
{
for (var i = 0; i < this.sizers.length; i++)
{
this.sizers[i].destroy();
}
this.sizers = null;
}
if (this.customHandles != null)
{
for (var i = 0; i < this.customHandles.length; i++)
{
this.customHandles[i].destroy();
}
this.customHandles = null;
}
};
__mxOutput.mxVertexHandler = typeof mxVertexHandler !== 'undefined' ? mxVertexHandler : undefined;
function mxEdgeHandler(state)
{
if (state != null && state.shape != null)
{
this.state = state;
this.init();
this.escapeHandler = mxUtils.bind(this, function(sender, evt)
{
var dirty = this.index != null;
this.reset();
if (dirty)
{
this.graph.cellRenderer.redraw(this.state, false, state.view.isRendering());
}
});
this.state.view.graph.addListener(mxEvent.ESCAPE, this.escapeHandler);
}
} mxEdgeHandler.prototype.graph = null;
mxEdgeHandler.prototype.state = null;
mxEdgeHandler.prototype.marker = null;
mxEdgeHandler.prototype.constraintHandler = null;
mxEdgeHandler.prototype.error = null;
mxEdgeHandler.prototype.shape = null;
mxEdgeHandler.prototype.bends = null;
mxEdgeHandler.prototype.labelShape = null;
mxEdgeHandler.prototype.cloneEnabled = true;
mxEdgeHandler.prototype.addEnabled = false;
mxEdgeHandler.prototype.removeEnabled = false;
mxEdgeHandler.prototype.dblClickRemoveEnabled = false;
mxEdgeHandler.prototype.mergeRemoveEnabled = false;
mxEdgeHandler.prototype.straightRemoveEnabled = false;
mxEdgeHandler.prototype.virtualBendsEnabled = false;
mxEdgeHandler.prototype.virtualBendOpacity = 20;
mxEdgeHandler.prototype.parentHighlightEnabled = false;
mxEdgeHandler.prototype.preferHtml = false;
mxEdgeHandler.prototype.allowHandleBoundsCheck = true;
mxEdgeHandler.prototype.snapToTerminals = false;
mxEdgeHandler.prototype.handleImage = null;
mxEdgeHandler.prototype.tolerance = 0;
mxEdgeHandler.prototype.outlineConnect = false;
mxEdgeHandler.prototype.manageLabelHandle = false;
mxEdgeHandler.prototype.init = function()
{
this.graph = this.state.view.graph;
this.marker = this.createMarker();
this.constraintHandler = new mxConstraintHandler(this.graph);
this.points = [];
this.abspoints = this.getSelectionPoints(this.state);
this.shape = this.createSelectionShape(this.abspoints);
this.shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
this.shape.init(this.graph.getView().getOverlayPane());
this.shape.pointerEvents = false;
this.shape.setCursor(mxConstants.CURSOR_MOVABLE_EDGE);
mxEvent.redirectMouseEvents(this.shape.node, this.graph, this.state);
this.preferHtml = this.state.text != null &&
this.state.text.node.parentNode == this.graph.container;
if (!this.preferHtml)
{
var sourceState = this.state.getVisibleTerminalState(true);
if (sourceState != null)
{
this.preferHtml = sourceState.text != null &&
sourceState.text.node.parentNode == this.graph.container;
}
if (!this.preferHtml)
{
var targetState = this.state.getVisibleTerminalState(false);
if (targetState != null)
{
this.preferHtml = targetState.text != null &&
targetState.text.node.parentNode == this.graph.container;
}
}
}
if (this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells ||
mxGraphHandler.prototype.maxCells <= 0)
{
this.bends = this.createBends();
if (this.isVirtualBendsEnabled())
{
this.virtualBends = this.createVirtualBends();
}
}
this.label = new mxPoint(this.state.absoluteOffset.x, this.state.absoluteOffset.y);
this.labelShape = this.createLabelHandleShape();
this.initBend(this.labelShape);
this.labelShape.setCursor(mxConstants.CURSOR_LABEL_HANDLE);
this.customHandles = this.createCustomHandles();
this.updateParentHighlight();
this.redraw();
};
mxEdgeHandler.prototype.isParentHighlightVisible = mxVertexHandler.prototype.isParentHighlightVisible;
mxEdgeHandler.prototype.updateParentHighlight = mxVertexHandler.prototype.updateParentHighlight;
mxEdgeHandler.prototype.createCustomHandles = function()
{
return null;
};
mxEdgeHandler.prototype.isVirtualBendsEnabled = function(evt)
{
return this.virtualBendsEnabled && (this.state.style[mxConstants.STYLE_EDGE] == null ||
this.state.style[mxConstants.STYLE_EDGE] == mxConstants.NONE ||
this.state.style[mxConstants.STYLE_NOEDGESTYLE] == 1) &&
mxUtils.getValue(this.state.style, mxConstants.STYLE_SHAPE, null) != 'arrow';
};
mxEdgeHandler.prototype.isCellEnabled = function(cell)
{
return true;
};
mxEdgeHandler.prototype.isAddPointEvent = function(evt)
{
return mxEvent.isShiftDown(evt);
};
mxEdgeHandler.prototype.isRemovePointEvent = function(evt)
{
return mxEvent.isShiftDown(evt);
};
mxEdgeHandler.prototype.getSelectionPoints = function(state)
{
return state.absolutePoints;
};
mxEdgeHandler.prototype.createParentHighlightShape = function(bounds)
{
var shape = new mxRectangleShape(mxRectangle.fromRectangle(bounds),
null, this.getSelectionColor());
shape.strokewidth = this.getSelectionStrokeWidth();
shape.isDashed = this.isSelectionDashed();
return shape;
};
mxEdgeHandler.prototype.createSelectionShape = function(points)
{
var shape = new this.state.shape.constructor();
shape.outline = true;
shape.apply(this.state);
shape.isDashed = this.isSelectionDashed();
shape.stroke = this.getSelectionColor();
shape.isShadow = false;
return shape;
};
mxEdgeHandler.prototype.getSelectionColor = function()
{
return mxConstants.EDGE_SELECTION_COLOR;
};
mxEdgeHandler.prototype.getSelectionStrokeWidth = function()
{
return mxConstants.EDGE_SELECTION_STROKEWIDTH;
};
mxEdgeHandler.prototype.isSelectionDashed = function()
{
return mxConstants.EDGE_SELECTION_DASHED;
};
mxEdgeHandler.prototype.isConnectableCell = function(cell)
{
return true;
};
mxEdgeHandler.prototype.getCellAt = function(x, y)
{
return (!this.outlineConnect) ? this.graph.getCellAt(x, y) : null;
};
mxEdgeHandler.prototype.createMarker = function()
{
var marker = new mxCellMarker(this.graph);
var self = this;
marker.getCell = function(me)
{
var cell = mxCellMarker.prototype.getCell.apply(this, arguments);
if ((cell == self.state.cell || cell == null) && self.currentPoint != null)
{
cell = self.graph.getCellAt(self.currentPoint.x, self.currentPoint.y);
}
if (cell != null && !this.graph.isCellConnectable(cell))
{
var parent = this.graph.getModel().getParent(cell);
if (this.graph.getModel().isVertex(parent) && this.graph.isCellConnectable(parent))
{
cell = parent;
}
}
var model = self.graph.getModel();
if ((this.graph.isSwimlane(cell) && self.currentPoint != null &&
this.graph.hitsSwimlaneContent(cell, self.currentPoint.x, self.currentPoint.y)) ||
(!self.isConnectableCell(cell)) || (cell == self.state.cell ||
(cell != null && !self.graph.connectableEdges && model.isEdge(cell))) ||
model.isAncestor(self.state.cell, cell))
{
cell = null;
}
if (!this.graph.isCellConnectable(cell))
{
cell = null;
}
return cell;
};
marker.isValidState = function(state)
{
var model = self.graph.getModel();
var other = self.graph.view.getTerminalPort(state,
self.graph.view.getState(model.getTerminal(self.state.cell,
!self.isSource)), !self.isSource);
var otherCell = (other != null) ? other.cell : null;
var source = (self.isSource) ? state.cell : otherCell;
var target = (self.isSource) ? otherCell : state.cell;
self.error = self.validateConnection(source, target);
return self.error == null;
};
return marker;
};
mxEdgeHandler.prototype.validateConnection = function(source, target)
{
return this.graph.getEdgeValidationError(this.state.cell, source, target);
};
mxEdgeHandler.prototype.createBends = function()
{
var cell = this.state.cell;
var bends = [];
for (var i = 0; i < this.abspoints.length; i++)
{
if (this.isHandleVisible(i))
{
var source = i == 0;
var target = i == this.abspoints.length - 1;
var terminal = source || target;
if (terminal || this.graph.isCellBendable(cell))
{
(mxUtils.bind(this, function(index)
{
var bend = this.createHandleShape(index);
this.initBend(bend, mxUtils.bind(this, mxUtils.bind(this, function()
{
if (this.dblClickRemoveEnabled)
{
this.removePoint(this.state, index);
}
})));
if (this.isHandleEnabled(i))
{
bend.setCursor((terminal) ? mxConstants.CURSOR_TERMINAL_HANDLE : mxConstants.CURSOR_BEND_HANDLE);
}
bends.push(bend);
if (!terminal)
{
this.points.push(new mxPoint(0,0));
bend.node.style.visibility = 'hidden';
}
}))(i);
}
}
}
return bends;
};
mxEdgeHandler.prototype.createVirtualBends = function()
{
var cell = this.state.cell;
this.abspoints[0];
var bends = [];
if (this.graph.isCellBendable(cell))
{
for (var i = 1; i < this.abspoints.length; i++)
{
(mxUtils.bind(this, function(bend)
{
this.initBend(bend);
bend.setCursor(mxConstants.CURSOR_VIRTUAL_BEND_HANDLE);
bends.push(bend);
}))(this.createHandleShape());
}
}
return bends;
};
mxEdgeHandler.prototype.isHandleEnabled = function(index)
{
return true;
};
mxEdgeHandler.prototype.isHandleVisible = function(index)
{
var source = this.state.getVisibleTerminalState(true);
var target = this.state.getVisibleTerminalState(false);
var geo = this.graph.getCellGeometry(this.state.cell);
var edgeStyle = (geo != null) ? this.graph.view.getEdgeStyle(this.state, geo.points, source, target) : null;
return edgeStyle != mxEdgeStyle.EntityRelation || index == 0 || index == this.abspoints.length - 1;
};
mxEdgeHandler.prototype.createHandleShape = function(index)
{
if (this.handleImage != null)
{
var shape = new mxImageShape(new mxRectangle(0, 0, this.handleImage.width, this.handleImage.height), this.handleImage.src);
shape.preserveImageAspect = false;
return shape;
}
else
{
var s = mxConstants.HANDLE_SIZE;
if (this.preferHtml)
{
s -= 1;
}
return new mxRectangleShape(new mxRectangle(0, 0, s, s), mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
}
};
mxEdgeHandler.prototype.createLabelHandleShape = function()
{
if (this.labelHandleImage != null)
{
var shape = new mxImageShape(new mxRectangle(0, 0, this.labelHandleImage.width, this.labelHandleImage.height), this.labelHandleImage.src);
shape.preserveImageAspect = false;
return shape;
}
else
{
var s = mxConstants.LABEL_HANDLE_SIZE;
return new mxRectangleShape(new mxRectangle(0, 0, s, s), mxConstants.LABEL_HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
}
};
mxEdgeHandler.prototype.initBend = function(bend, dblClick)
{
if (this.preferHtml)
{
bend.dialect = mxConstants.DIALECT_STRICTHTML;
bend.init(this.graph.container);
}
else
{
bend.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
bend.init(this.graph.getView().getOverlayPane());
}
mxEvent.redirectMouseEvents(bend.node, this.graph, this.state,
null, null, null, dblClick);
if (mxClient.IS_QUIRKS || document.documentMode == 8)
{
mxEvent.addListener(bend.node, 'dragstart', function(evt)
{
mxEvent.consume(evt);
return false;
});
}
if (mxClient.IS_TOUCH)
{
bend.node.setAttribute('pointer-events', 'none');
}
};
mxEdgeHandler.prototype.getHandleForEvent = function(me)
{
var result = null;
if (this.state != null)
{
var tol = (!mxEvent.isMouseEvent(me.getEvent())) ? this.tolerance : 1;
var hit = (this.allowHandleBoundsCheck && (mxClient.IS_IE || tol > 0)) ?
new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol) : null;
var minDistSq = null;
function checkShape(shape)
{
if (shape != null && shape.node != null && shape.node.style.display != 'none' &&
shape.node.style.visibility != 'hidden' &&
(me.isSource(shape) || (hit != null && mxUtils.intersects(shape.bounds, hit))))
{
var dx = me.getGraphX() - shape.bounds.getCenterX();
var dy = me.getGraphY() - shape.bounds.getCenterY();
var tmp = dx * dx + dy * dy;
if (minDistSq == null || tmp <= minDistSq)
{
minDistSq = tmp;
return true;
}
}
return false;
}
if (this.customHandles != null && this.isCustomHandleEvent(me))
{
for (var i = this.customHandles.length - 1; i >= 0; i--)
{
if (checkShape(this.customHandles[i].shape))
{
return mxEvent.CUSTOM_HANDLE - i;
}
}
}
if (me.isSource(this.state.text) || checkShape(this.labelShape))
{
result = mxEvent.LABEL_HANDLE;
}
if (this.bends != null)
{
for (var i = 0; i < this.bends.length; i++)
{
if (checkShape(this.bends[i]))
{
result = i;
}
}
}
if (this.virtualBends != null && this.isAddVirtualBendEvent(me))
{
for (var i = 0; i < this.virtualBends.length; i++)
{
if (checkShape(this.virtualBends[i]))
{
result = mxEvent.VIRTUAL_HANDLE - i;
}
}
}
}
return result;
};
mxEdgeHandler.prototype.isAddVirtualBendEvent = function(me)
{
return true;
};
mxEdgeHandler.prototype.isCustomHandleEvent = function(me)
{
return true;
};
mxEdgeHandler.prototype.mouseDown = function(sender, me)
{
var handle = this.getHandleForEvent(me);
if (this.bends != null && this.bends[handle] != null)
{
var b = this.bends[handle].bounds;
this.snapPoint = new mxPoint(b.getCenterX(), b.getCenterY());
}
if (this.addEnabled && handle == null && this.isAddPointEvent(me.getEvent()))
{
this.addPoint(this.state, me.getEvent());
me.consume();
}
else if (handle != null && !me.isConsumed() && this.graph.isEnabled())
{
if (this.removeEnabled && this.isRemovePointEvent(me.getEvent()))
{
this.removePoint(this.state, handle);
}
else if (handle != mxEvent.LABEL_HANDLE || this.graph.isLabelMovable(me.getCell()))
{
if (handle <= mxEvent.VIRTUAL_HANDLE)
{
mxUtils.setOpacity(this.virtualBends[mxEvent.VIRTUAL_HANDLE - handle].node, 100);
}
this.start(me.getX(), me.getY(), handle);
}
me.consume();
}
};
mxEdgeHandler.prototype.start = function(x, y, index)
{
this.startX = x;
this.startY = y;
this.isSource = (this.bends == null) ? false : index == 0;
this.isTarget = (this.bends == null) ? false : index == this.bends.length - 1;
this.isLabel = index == mxEvent.LABEL_HANDLE;
if (this.isSource || this.isTarget)
{
var cell = this.state.cell;
var terminal = this.graph.model.getTerminal(cell, this.isSource);
if ((terminal == null && this.graph.isTerminalPointMovable(cell, this.isSource)) ||
(terminal != null && this.graph.isCellDisconnectable(cell, terminal, this.isSource)))
{
this.index = index;
}
}
else
{
this.index = index;
}
if (this.index <= mxEvent.CUSTOM_HANDLE && this.index > mxEvent.VIRTUAL_HANDLE)
{
if (this.customHandles != null)
{
for (var i = 0; i < this.customHandles.length; i++)
{
if (i != mxEvent.CUSTOM_HANDLE - this.index)
{
this.customHandles[i].setVisible(false);
}
}
}
}
};
mxEdgeHandler.prototype.clonePreviewState = function(point, terminal)
{
return this.state.clone();
};
mxEdgeHandler.prototype.getSnapToTerminalTolerance = function()
{
return this.graph.gridSize * this.graph.view.scale / 2;
};
mxEdgeHandler.prototype.updateHint = function(me, point) { };
mxEdgeHandler.prototype.removeHint = function() { };
mxEdgeHandler.prototype.roundLength = function(length)
{
return Math.round(length);
};
mxEdgeHandler.prototype.isSnapToTerminalsEvent = function(me)
{
return this.snapToTerminals && !mxEvent.isAltDown(me.getEvent());
};
mxEdgeHandler.prototype.getPointForEvent = function(me)
{
var view = this.graph.getView();
var scale = view.scale;
var point = new mxPoint(this.roundLength(me.getGraphX() / scale) * scale,
this.roundLength(me.getGraphY() / scale) * scale);
var tt = this.getSnapToTerminalTolerance();
var overrideX = false;
var overrideY = false;
if (tt > 0 && this.isSnapToTerminalsEvent(me))
{
function snapToPoint(pt)
{
if (pt != null)
{
var x = pt.x;
if (Math.abs(point.x - x) < tt)
{
point.x = x;
overrideX = true;
}
var y = pt.y;
if (Math.abs(point.y - y) < tt)
{
point.y = y;
overrideY = true;
}
}
}
function snapToTerminal(terminal)
{
if (terminal != null)
{
snapToPoint.call(this, new mxPoint(view.getRoutingCenterX(terminal),
view.getRoutingCenterY(terminal)));
}
} snapToTerminal.call(this, this.state.getVisibleTerminalState(true));
snapToTerminal.call(this, this.state.getVisibleTerminalState(false));
if (this.state.absolutePoints != null)
{
for (var i = 0; i < this.state.absolutePoints.length; i++)
{
snapToPoint.call(this, this.state.absolutePoints[i]);
}
}
}
if (this.graph.isGridEnabledEvent(me.getEvent()))
{
var tr = view.translate;
if (!overrideX)
{
point.x = (this.graph.snap(point.x / scale - tr.x) + tr.x) * scale;
}
if (!overrideY)
{
point.y = (this.graph.snap(point.y / scale - tr.y) + tr.y) * scale;
}
}
return point;
};
mxEdgeHandler.prototype.getPreviewTerminalState = function(me)
{
this.constraintHandler.update(me, this.isSource, true, me.isSource(this.marker.highlight.shape) ? null : this.currentPoint);
if (this.constraintHandler.currentFocus != null && this.constraintHandler.currentConstraint != null)
{
if (this.marker.highlight != null && this.marker.highlight.state != null &&
this.marker.highlight.state.cell == this.constraintHandler.currentFocus.cell)
{
if (this.marker.highlight.shape.stroke != 'transparent')
{
this.marker.highlight.shape.stroke = 'transparent';
this.marker.highlight.repaint();
}
}
else
{
this.marker.markCell(this.constraintHandler.currentFocus.cell, 'transparent');
}
var model = this.graph.getModel();
var other = this.graph.view.getTerminalPort(this.state,
this.graph.view.getState(model.getTerminal(this.state.cell,
!this.isSource)), !this.isSource);
var otherCell = (other != null) ? other.cell : null;
var source = (this.isSource) ? this.constraintHandler.currentFocus.cell : otherCell;
var target = (this.isSource) ? otherCell : this.constraintHandler.currentFocus.cell;
this.error = this.validateConnection(source, target);
var result = null;
if (this.error == null)
{
result = this.constraintHandler.currentFocus;
}
if (this.error != null || (result != null &&
!this.isCellEnabled(result.cell)))
{
this.constraintHandler.reset();
}
return result;
}
else if (!this.graph.isIgnoreTerminalEvent(me.getEvent()))
{
this.marker.process(me);
var state = this.marker.getValidState();
if (state != null && !this.isCellEnabled(state.cell))
{
this.constraintHandler.reset();
this.marker.reset();
}
return this.marker.getValidState();
}
else
{
this.marker.reset();
return null;
}
};
mxEdgeHandler.prototype.getPreviewPoints = function(pt, me)
{
var geometry = this.graph.getCellGeometry(this.state.cell);
var points = (geometry.points != null) ? geometry.points.slice() : null;
var point = new mxPoint(pt.x, pt.y);
var result = null;
if (!this.isSource && !this.isTarget)
{
this.convertPoint(point, false);
if (points == null)
{
points = [point];
}
else
{
if (this.index <= mxEvent.VIRTUAL_HANDLE)
{
points.splice(mxEvent.VIRTUAL_HANDLE - this.index, 0, point);
}
if (!this.isSource && !this.isTarget)
{
for (var i = 0; i < this.bends.length; i++)
{
if (i != this.index)
{
var bend = this.bends[i];
if (bend != null && mxUtils.contains(bend.bounds, pt.x, pt.y))
{
if (this.index <= mxEvent.VIRTUAL_HANDLE)
{
points.splice(mxEvent.VIRTUAL_HANDLE - this.index, 1);
}
else
{
points.splice(this.index - 1, 1);
}
result = points;
}
}
}
if (result == null && this.straightRemoveEnabled && (me == null || !mxEvent.isAltDown(me.getEvent())))
{
var tol = this.graph.tolerance * this.graph.tolerance;
var abs = this.state.absolutePoints.slice();
abs[this.index] = pt;
var src = this.state.getVisibleTerminalState(true);
if (src != null)
{
var c = this.graph.getConnectionConstraint(this.state, src, true);
if (c == null || this.graph.getConnectionPoint(src, c) == null)
{
abs[0] = new mxPoint(src.view.getRoutingCenterX(src), src.view.getRoutingCenterY(src));
}
}
var trg = this.state.getVisibleTerminalState(false);
if (trg != null)
{
var c = this.graph.getConnectionConstraint(this.state, trg, false);
if (c == null || this.graph.getConnectionPoint(trg, c) == null)
{
abs[abs.length - 1] = new mxPoint(trg.view.getRoutingCenterX(trg), trg.view.getRoutingCenterY(trg));
}
}
function checkRemove(idx, tmp)
{
if (idx > 0 && idx < abs.length - 1 &&
mxUtils.ptSegDistSq(abs[idx - 1].x, abs[idx - 1].y,
abs[idx + 1].x, abs[idx + 1].y, tmp.x, tmp.y) < tol)
{
points.splice(idx - 1, 1);
result = points;
}
} checkRemove(this.index, pt);
}
}
if (result == null && this.index > mxEvent.VIRTUAL_HANDLE)
{
points[this.index - 1] = point;
}
}
}
else if (this.graph.resetEdgesOnConnect)
{
points = null;
}
return (result != null) ? result : points;
};
mxEdgeHandler.prototype.isOutlineConnectEvent = function(me)
{
var offset = mxUtils.getOffset(this.graph.container);
var evt = me.getEvent();
var clientX = mxEvent.getClientX(evt);
var clientY = mxEvent.getClientY(evt);
var doc = document.documentElement;
var left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
var gridX = this.currentPoint.x - this.graph.container.scrollLeft + offset.x - left;
var gridY = this.currentPoint.y - this.graph.container.scrollTop + offset.y - top;
return this.outlineConnect && !mxEvent.isShiftDown(me.getEvent()) &&
(me.isSource(this.marker.highlight.shape) ||
(mxEvent.isAltDown(me.getEvent()) && me.getState() != null) ||
this.marker.highlight.isHighlightAt(clientX, clientY) ||
((gridX != clientX || gridY != clientY) && me.getState() == null &&
this.marker.highlight.isHighlightAt(gridX, gridY)));
};
mxEdgeHandler.prototype.updatePreviewState = function(edge, point, terminalState, me, outline)
{
var sourceState = (this.isSource) ? terminalState : this.state.getVisibleTerminalState(true);
var targetState = (this.isTarget) ? terminalState : this.state.getVisibleTerminalState(false);
var sourceConstraint = this.graph.getConnectionConstraint(edge, sourceState, true);
var targetConstraint = this.graph.getConnectionConstraint(edge, targetState, false);
var constraint = this.constraintHandler.currentConstraint;
if (constraint == null && outline)
{
if (terminalState != null)
{
if (me.isSource(this.marker.highlight.shape))
{
point = new mxPoint(me.getGraphX(), me.getGraphY());
}
constraint = this.graph.getOutlineConstraint(point, terminalState, me);
this.constraintHandler.setFocus(me, terminalState, this.isSource);
this.constraintHandler.currentConstraint = constraint;
this.constraintHandler.currentPoint = point;
}
else
{
constraint = new mxConnectionConstraint();
}
}
if (this.outlineConnect && this.marker.highlight != null && this.marker.highlight.shape != null)
{
var s = this.graph.view.scale;
if (this.constraintHandler.currentConstraint != null &&
this.constraintHandler.currentFocus != null)
{
this.marker.highlight.shape.stroke = (outline) ? mxConstants.OUTLINE_HIGHLIGHT_COLOR : 'transparent';
this.marker.highlight.shape.strokewidth = mxConstants.OUTLINE_HIGHLIGHT_STROKEWIDTH / s / s;
this.marker.highlight.repaint();
}
else if (this.marker.hasValidState())
{
this.marker.highlight.shape.stroke = (this.graph.isCellConnectable(me.getCell()) &&
this.marker.getValidState() != me.getState()) ?
'transparent' : mxConstants.DEFAULT_VALID_COLOR;
this.marker.highlight.shape.strokewidth = mxConstants.HIGHLIGHT_STROKEWIDTH / s / s;
this.marker.highlight.repaint();
}
}
if (this.isSource)
{
sourceConstraint = constraint;
}
else if (this.isTarget)
{
targetConstraint = constraint;
}
if (this.isSource || this.isTarget)
{
if (constraint != null && constraint.point != null)
{
edge.style[(this.isSource) ? mxConstants.STYLE_EXIT_X : mxConstants.STYLE_ENTRY_X] = constraint.point.x;
edge.style[(this.isSource) ? mxConstants.STYLE_EXIT_Y : mxConstants.STYLE_ENTRY_Y] = constraint.point.y;
}
else
{
delete edge.style[(this.isSource) ? mxConstants.STYLE_EXIT_X : mxConstants.STYLE_ENTRY_X];
delete edge.style[(this.isSource) ? mxConstants.STYLE_EXIT_Y : mxConstants.STYLE_ENTRY_Y];
}
}
edge.setVisibleTerminalState(sourceState, true);
edge.setVisibleTerminalState(targetState, false);
if (!this.isSource || sourceState != null)
{
edge.view.updateFixedTerminalPoint(edge, sourceState, true, sourceConstraint);
}
if (!this.isTarget || targetState != null)
{
edge.view.updateFixedTerminalPoint(edge, targetState, false, targetConstraint);
}
if ((this.isSource || this.isTarget) && terminalState == null)
{
edge.setAbsoluteTerminalPoint(point, this.isSource);
if (this.marker.getMarkedState() == null)
{
this.error = (this.graph.allowDanglingEdges) ? null : '';
}
}
edge.view.updatePoints(edge, this.points, sourceState, targetState);
edge.view.updateFloatingTerminalPoints(edge, sourceState, targetState);
};
mxEdgeHandler.prototype.mouseMove = function(sender, me)
{
if (this.index != null && this.marker != null)
{
this.currentPoint = this.getPointForEvent(me);
this.error = null;
if (!this.graph.isIgnoreTerminalEvent(me.getEvent()) && mxEvent.isShiftDown(me.getEvent()) && this.snapPoint != null)
{
if (Math.abs(this.snapPoint.x - this.currentPoint.x) < Math.abs(this.snapPoint.y - this.currentPoint.y))
{
this.currentPoint.x = this.snapPoint.x;
}
else
{
this.currentPoint.y = this.snapPoint.y;
}
}
if (this.index <= mxEvent.CUSTOM_HANDLE && this.index > mxEvent.VIRTUAL_HANDLE)
{
if (this.customHandles != null)
{
this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].processEvent(me);
this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].positionChanged();
if (this.shape != null && this.shape.node != null)
{
this.shape.node.style.display = 'none';
}
}
}
else if (this.isLabel)
{
this.label.x = this.currentPoint.x;
this.label.y = this.currentPoint.y;
}
else
{
this.points = this.getPreviewPoints(this.currentPoint, me);
var terminalState = (this.isSource || this.isTarget) ? this.getPreviewTerminalState(me) : null;
if (this.constraintHandler.currentConstraint != null &&
this.constraintHandler.currentFocus != null &&
this.constraintHandler.currentPoint != null)
{
this.currentPoint = this.constraintHandler.currentPoint.clone();
}
else if (this.outlineConnect)
{
var outline = (this.isSource || this.isTarget) ? this.isOutlineConnectEvent(me) : false;
if (outline)
{
terminalState = this.marker.highlight.state;
}
else if (terminalState != null && terminalState != me.getState() &&
this.graph.isCellConnectable(me.getCell()) &&
this.marker.highlight.shape != null)
{
this.marker.highlight.shape.stroke = 'transparent';
this.marker.highlight.repaint();
terminalState = null;
}
}
if (terminalState != null && !this.isCellEnabled(terminalState.cell))
{
terminalState = null;
this.marker.reset();
}
var clone = this.clonePreviewState(this.currentPoint, (terminalState != null) ? terminalState.cell : null);
this.updatePreviewState(clone, this.currentPoint, terminalState, me, outline);
var color = (this.error == null) ? this.marker.validColor : this.marker.invalidColor;
this.setPreviewColor(color);
this.abspoints = clone.absolutePoints;
this.active = true;
this.updateHint(me, this.currentPoint);
}
this.drawPreview();
mxEvent.consume(me.getEvent());
me.consume();
}
else if (mxClient.IS_IE && this.getHandleForEvent(me) != null)
{
me.consume(false);
}
};
mxEdgeHandler.prototype.mouseUp = function(sender, me)
{
if (this.index != null && this.marker != null)
{
if (this.shape != null && this.shape.node != null)
{
this.shape.node.style.display = '';
}
var edge = this.state.cell;
var index = this.index;
this.index = null;
if (me.getX() != this.startX || me.getY() != this.startY)
{
var clone = !this.graph.isIgnoreTerminalEvent(me.getEvent()) && this.graph.isCloneEvent(me.getEvent()) &&
this.cloneEnabled && this.graph.isCellsCloneable();
if (this.error != null)
{
if (this.error.length > 0)
{
this.graph.validationAlert(this.error);
}
}
else if (index <= mxEvent.CUSTOM_HANDLE && index > mxEvent.VIRTUAL_HANDLE)
{
if (this.customHandles != null)
{
var model = this.graph.getModel();
model.beginUpdate();
try
{
this.customHandles[mxEvent.CUSTOM_HANDLE - index].execute(me);
if (this.shape != null && this.shape.node != null)
{
this.shape.apply(this.state);
this.shape.redraw();
}
}
finally
{
model.endUpdate();
}
}
}
else if (this.isLabel)
{
this.moveLabel(this.state, this.label.x, this.label.y);
}
else if (this.isSource || this.isTarget)
{
var terminal = null;
if (this.constraintHandler.currentConstraint != null &&
this.constraintHandler.currentFocus != null)
{
terminal = this.constraintHandler.currentFocus.cell;
}
if (terminal == null && this.marker.hasValidState() && this.marker.highlight != null &&
this.marker.highlight.shape != null &&
this.marker.highlight.shape.stroke != 'transparent' &&
this.marker.highlight.shape.stroke != 'white')
{
terminal = this.marker.validState.cell;
}
if (terminal != null)
{
var model = this.graph.getModel();
var parent = model.getParent(edge);
model.beginUpdate();
try
{
if (clone)
{
var geo = model.getGeometry(edge);
var clone = this.graph.cloneCell(edge);
model.add(parent, clone, model.getChildCount(parent));
if (geo != null)
{
geo = geo.clone();
model.setGeometry(clone, geo);
}
var other = model.getTerminal(edge, !this.isSource);
this.graph.connectCell(clone, other, !this.isSource);
edge = clone;
}
edge = this.connect(edge, terminal, this.isSource, clone, me);
}
finally
{
model.endUpdate();
}
}
else if (this.graph.isAllowDanglingEdges())
{
var pt = this.abspoints[(this.isSource) ? 0 : this.abspoints.length - 1];
pt.x = this.roundLength(pt.x / this.graph.view.scale - this.graph.view.translate.x);
pt.y = this.roundLength(pt.y / this.graph.view.scale - this.graph.view.translate.y);
var pstate = this.graph.getView().getState(
this.graph.getModel().getParent(edge));
if (pstate != null)
{
pt.x -= pstate.origin.x;
pt.y -= pstate.origin.y;
}
pt.x -= this.graph.panDx / this.graph.view.scale;
pt.y -= this.graph.panDy / this.graph.view.scale;
edge = this.changeTerminalPoint(edge, pt, this.isSource, clone);
}
}
else if (this.active)
{
edge = this.changePoints(edge, this.points, clone);
}
else
{
this.graph.getView().invalidate(this.state.cell);
this.graph.getView().validate(this.state.cell);
}
}
else if (this.graph.isToggleEvent(me.getEvent()))
{
this.graph.selectCellForEvent(this.state.cell, me.getEvent());
}
if (this.marker != null)
{
this.reset();
if (edge != this.state.cell)
{
this.graph.setSelectionCell(edge);
}
}
me.consume();
}
};
mxEdgeHandler.prototype.reset = function()
{
if (this.active)
{
this.refresh();
}
this.error = null;
this.index = null;
this.label = null;
this.points = null;
this.snapPoint = null;
this.isLabel = false;
this.isSource = false;
this.isTarget = false;
this.active = false;
if (this.livePreview && this.sizers != null)
{
for (var i = 0; i < this.sizers.length; i++)
{
if (this.sizers[i] != null)
{
this.sizers[i].node.style.display = '';
}
}
}
if (this.marker != null)
{
this.marker.reset();
}
if (this.constraintHandler != null)
{
this.constraintHandler.reset();
}
if (this.customHandles != null)
{
for (var i = 0; i < this.customHandles.length; i++)
{
this.customHandles[i].reset();
}
}
this.setPreviewColor(mxConstants.EDGE_SELECTION_COLOR);
this.removeHint();
this.redraw();
};
mxEdgeHandler.prototype.setPreviewColor = function(color)
{
if (this.shape != null)
{
this.shape.stroke = color;
}
};
mxEdgeHandler.prototype.convertPoint = function(point, gridEnabled)
{
var scale = this.graph.getView().getScale();
var tr = this.graph.getView().getTranslate();
if (gridEnabled)
{
point.x = this.graph.snap(point.x);
point.y = this.graph.snap(point.y);
}
point.x = Math.round(point.x / scale - tr.x);
point.y = Math.round(point.y / scale - tr.y);
var pstate = this.graph.getView().getState(
this.graph.getModel().getParent(this.state.cell));
if (pstate != null)
{
point.x -= pstate.origin.x;
point.y -= pstate.origin.y;
}
return point;
};
mxEdgeHandler.prototype.moveLabel = function(edgeState, x, y)
{
var model = this.graph.getModel();
var geometry = model.getGeometry(edgeState.cell);
if (geometry != null)
{
var scale = this.graph.getView().scale;
geometry = geometry.clone();
if (geometry.relative)
{
var pt = this.graph.getView().getRelativePoint(edgeState, x, y);
geometry.x = Math.round(pt.x * 10000) / 10000;
geometry.y = Math.round(pt.y);
geometry.offset = new mxPoint(0, 0);
var pt = this.graph.view.getPoint(edgeState, geometry);
geometry.offset = new mxPoint(Math.round((x - pt.x) / scale), Math.round((y - pt.y) / scale));
}
else
{
var points = edgeState.absolutePoints;
var p0 = points[0];
var pe = points[points.length - 1];
if (p0 != null && pe != null)
{
var cx = p0.x + (pe.x - p0.x) / 2;
var cy = p0.y + (pe.y - p0.y) / 2;
geometry.offset = new mxPoint(Math.round((x - cx) / scale), Math.round((y - cy) / scale));
geometry.x = 0;
geometry.y = 0;
}
}
model.setGeometry(edgeState.cell, geometry);
}
};
mxEdgeHandler.prototype.connect = function(edge, terminal, isSource, isClone, me)
{
var model = this.graph.getModel();
model.getParent(edge);
model.beginUpdate();
try
{
var constraint = this.constraintHandler.currentConstraint;
if (constraint == null)
{
constraint = new mxConnectionConstraint();
}
this.graph.connectCell(edge, terminal, isSource, constraint);
}
finally
{
model.endUpdate();
}
return edge;
};
mxEdgeHandler.prototype.changeTerminalPoint = function(edge, point, isSource, clone)
{
var model = this.graph.getModel();
model.beginUpdate();
try
{
if (clone)
{
var parent = model.getParent(edge);
var terminal = model.getTerminal(edge, !isSource);
edge = this.graph.cloneCell(edge);
model.add(parent, edge, model.getChildCount(parent));
model.setTerminal(edge, terminal, !isSource);
}
var geo = model.getGeometry(edge);
if (geo != null)
{
geo = geo.clone();
geo.setTerminalPoint(point, isSource);
model.setGeometry(edge, geo);
this.graph.connectCell(edge, null, isSource, new mxConnectionConstraint());
}
}
finally
{
model.endUpdate();
}
return edge;
};
mxEdgeHandler.prototype.changePoints = function(edge, points, clone)
{
var model = this.graph.getModel();
model.beginUpdate();
try
{
if (clone)
{
var parent = model.getParent(edge);
var source = model.getTerminal(edge, true);
var target = model.getTerminal(edge, false);
edge = this.graph.cloneCell(edge);
model.add(parent, edge, model.getChildCount(parent));
model.setTerminal(edge, source, true);
model.setTerminal(edge, target, false);
}
var geo = model.getGeometry(edge);
if (geo != null)
{
geo = geo.clone();
geo.points = points;
model.setGeometry(edge, geo);
}
}
finally
{
model.endUpdate();
}
return edge;
};
mxEdgeHandler.prototype.addPoint = function(state, evt)
{
var pt = mxUtils.convertPoint(this.graph.container, mxEvent.getClientX(evt),
mxEvent.getClientY(evt));
var gridEnabled = this.graph.isGridEnabledEvent(evt);
this.convertPoint(pt, gridEnabled);
this.addPointAt(state, pt.x, pt.y);
mxEvent.consume(evt);
};
mxEdgeHandler.prototype.addPointAt = function(state, x, y)
{
var geo = this.graph.getCellGeometry(state.cell);
var pt = new mxPoint(x, y);
if (geo != null)
{
geo = geo.clone();
var t = this.graph.view.translate;
var s = this.graph.view.scale;
var offset = new mxPoint(t.x * s, t.y * s);
var parent = this.graph.model.getParent(this.state.cell);
if (this.graph.model.isVertex(parent))
{
var pState = this.graph.view.getState(parent);
offset = new mxPoint(pState.x, pState.y);
}
var index = mxUtils.findNearestSegment(state, pt.x * s + offset.x, pt.y * s + offset.y);
if (geo.points == null)
{
geo.points = [pt];
}
else
{
geo.points.splice(index, 0, pt);
}
this.graph.getModel().setGeometry(state.cell, geo);
this.refresh();
this.redraw();
}
};
mxEdgeHandler.prototype.removePoint = function(state, index)
{
if (index > 0 && index < this.abspoints.length - 1)
{
var geo = this.graph.getCellGeometry(this.state.cell);
if (geo != null && geo.points != null)
{
geo = geo.clone();
geo.points.splice(index - 1, 1);
this.graph.getModel().setGeometry(state.cell, geo);
this.refresh();
this.redraw();
}
}
};
mxEdgeHandler.prototype.getHandleFillColor = function(index)
{
var isSource = index == 0;
var cell = this.state.cell;
var terminal = this.graph.getModel().getTerminal(cell, isSource);
var color = mxConstants.HANDLE_FILLCOLOR;
if ((terminal != null && !this.graph.isCellDisconnectable(cell, terminal, isSource)) ||
(terminal == null && !this.graph.isTerminalPointMovable(cell, isSource)))
{
color = mxConstants.LOCKED_HANDLE_FILLCOLOR;
}
else if (terminal != null && this.graph.isCellDisconnectable(cell, terminal, isSource))
{
color = mxConstants.CONNECT_HANDLE_FILLCOLOR;
}
return color;
};
mxEdgeHandler.prototype.redraw = function(ignoreHandles)
{
if (this.state != null)
{
this.abspoints = this.state.absolutePoints.slice();
var g = this.graph.getModel().getGeometry(this.state.cell);
if (g != null)
{
var pts = g.points;
if (this.bends != null && this.bends.length > 0)
{
if (pts != null)
{
if (this.points == null)
{
this.points = [];
}
for (var i = 1; i < this.bends.length - 1; i++)
{
if (this.bends[i] != null && this.abspoints[i] != null)
{
this.points[i - 1] = pts[i - 1];
}
}
}
}
}
this.drawPreview();
if (!ignoreHandles)
{
this.redrawHandles();
}
}
};
mxEdgeHandler.prototype.redrawHandles = function()
{
var cell = this.state.cell;
var b = this.labelShape.bounds;
this.label = new mxPoint(this.state.absoluteOffset.x, this.state.absoluteOffset.y);
this.labelShape.bounds = new mxRectangle(Math.round(this.label.x - b.width / 2),
Math.round(this.label.y - b.height / 2), b.width, b.height);
var lab = this.graph.getLabel(cell);
this.labelShape.visible = (lab != null && lab.length > 0 && this.graph.isLabelMovable(cell));
if (this.bends != null && this.bends.length > 0)
{
var n = this.abspoints.length - 1;
var p0 = this.abspoints[0];
var x0 = p0.x;
var y0 = p0.y;
b = this.bends[0].bounds;
this.bends[0].bounds = new mxRectangle(Math.floor(x0 - b.width / 2),
Math.floor(y0 - b.height / 2), b.width, b.height);
this.bends[0].fill = this.getHandleFillColor(0);
this.bends[0].redraw();
if (this.manageLabelHandle)
{
this.checkLabelHandle(this.bends[0].bounds);
}
var pe = this.abspoints[n];
var xn = pe.x;
var yn = pe.y;
var bn = this.bends.length - 1;
b = this.bends[bn].bounds;
this.bends[bn].bounds = new mxRectangle(Math.floor(xn - b.width / 2),
Math.floor(yn - b.height / 2), b.width, b.height);
this.bends[bn].fill = this.getHandleFillColor(bn);
this.bends[bn].redraw();
if (this.manageLabelHandle)
{
this.checkLabelHandle(this.bends[bn].bounds);
}
this.redrawInnerBends(p0, pe);
}
if (this.abspoints != null && this.virtualBends != null && this.virtualBends.length > 0)
{
var last = this.abspoints[0];
for (var i = 0; i < this.virtualBends.length; i++)
{
if (this.virtualBends[i] != null && this.abspoints[i + 1] != null)
{
var pt = this.abspoints[i + 1];
var b = this.virtualBends[i];
var x = last.x + (pt.x - last.x) / 2;
var y = last.y + (pt.y - last.y) / 2;
b.bounds = new mxRectangle(Math.floor(x - b.bounds.width / 2),
Math.floor(y - b.bounds.height / 2), b.bounds.width, b.bounds.height);
b.redraw();
mxUtils.setOpacity(b.node, this.virtualBendOpacity);
last = pt;
if (this.manageLabelHandle)
{
this.checkLabelHandle(b.bounds);
}
}
}
}
if (this.labelShape != null)
{
this.labelShape.redraw();
}
if (this.customHandles != null)
{
for (var i = 0; i < this.customHandles.length; i++)
{
var temp = this.customHandles[i].shape.node.style.display;
this.customHandles[i].redraw();
this.customHandles[i].shape.node.style.display = temp;
this.customHandles[i].shape.node.style.visibility =
(this.isCustomHandleVisible(this.customHandles[i])) ?
'' : 'hidden';
}
}
};
mxEdgeHandler.prototype.isCustomHandleVisible = function(handle)
{
return !this.graph.isEditing() && this.state.view.graph.getSelectionCount() == 1;
};
mxEdgeHandler.prototype.setHandlesVisible = function(visible)
{
if (this.bends != null)
{
for (var i = 0; i < this.bends.length; i++)
{
this.bends[i].node.style.display = (visible) ? '' : 'none';
}
}
if (this.virtualBends != null)
{
for (var i = 0; i < this.virtualBends.length; i++)
{
this.virtualBends[i].node.style.display = (visible) ? '' : 'none';
}
}
if (this.labelShape != null)
{
this.labelShape.node.style.display = (visible) ? '' : 'none';
}
if (this.customHandles != null)
{
for (var i = 0; i < this.customHandles.length; i++)
{
this.customHandles[i].setVisible(visible);
}
}
};
mxEdgeHandler.prototype.redrawInnerBends = function(p0, pe)
{
for (var i = 1; i < this.bends.length - 1; i++)
{
if (this.bends[i] != null)
{
if (this.abspoints[i] != null)
{
var x = this.abspoints[i].x;
var y = this.abspoints[i].y;
var b = this.bends[i].bounds;
this.bends[i].node.style.visibility = 'visible';
this.bends[i].bounds = new mxRectangle(Math.round(x - b.width / 2),
Math.round(y - b.height / 2), b.width, b.height);
if (this.manageLabelHandle)
{
this.checkLabelHandle(this.bends[i].bounds);
}
else if (this.handleImage == null && this.labelShape.visible && mxUtils.intersects(this.bends[i].bounds, this.labelShape.bounds))
{
w = mxConstants.HANDLE_SIZE + 3;
h = mxConstants.HANDLE_SIZE + 3;
this.bends[i].bounds = new mxRectangle(Math.round(x - w / 2), Math.round(y - h / 2), w, h);
}
this.bends[i].redraw();
}
else
{
this.bends[i].destroy();
this.bends[i] = null;
}
}
}
};
mxEdgeHandler.prototype.checkLabelHandle = function(b)
{
if (this.labelShape != null)
{
var b2 = this.labelShape.bounds;
if (mxUtils.intersects(b, b2))
{
if (b.getCenterY() < b2.getCenterY())
{
b2.y = b.y + b.height;
}
else
{
b2.y = b.y - b2.height;
}
}
}
};
mxEdgeHandler.prototype.drawPreview = function()
{
try
{
if (this.isLabel)
{
var b = this.labelShape.bounds;
var bounds = new mxRectangle(Math.round(this.label.x - b.width / 2),
Math.round(this.label.y - b.height / 2), b.width, b.height);
if (!this.labelShape.bounds.equals(bounds))
{
this.labelShape.bounds = bounds;
this.labelShape.redraw();
}
}
if (this.shape != null && !mxUtils.equalPoints(this.shape.points, this.abspoints))
{
this.shape.apply(this.state);
this.shape.points = this.abspoints.slice();
this.shape.scale = this.state.view.scale;
this.shape.isDashed = this.isSelectionDashed();
this.shape.stroke = this.getSelectionColor();
this.shape.strokewidth = this.getSelectionStrokeWidth() / this.shape.scale / this.shape.scale;
this.shape.isShadow = false;
this.shape.redraw();
}
this.updateParentHighlight();
}
catch (e)
{
}
};
mxEdgeHandler.prototype.refresh = function()
{
if (this.state != null)
{
this.abspoints = this.getSelectionPoints(this.state);
this.points = [];
if (this.bends != null)
{
this.destroyBends(this.bends);
this.bends = this.createBends();
}
if (this.virtualBends != null)
{
this.destroyBends(this.virtualBends);
this.virtualBends = this.createVirtualBends();
}
if (this.customHandles != null)
{
this.destroyBends(this.customHandles);
this.customHandles = this.createCustomHandles();
}
if (this.labelShape != null && this.labelShape.node != null && this.labelShape.node.parentNode != null)
{
this.labelShape.node.parentNode.appendChild(this.labelShape.node);
}
}
};
mxEdgeHandler.prototype.isDestroyed = function()
{
return this.shape == null;
};
mxEdgeHandler.prototype.destroyBends = function(bends)
{
if (bends != null)
{
for (var i = 0; i < bends.length; i++)
{
if (bends[i] != null)
{
bends[i].destroy();
}
}
}
};
mxEdgeHandler.prototype.destroy = function()
{
if (this.escapeHandler != null)
{
this.state.view.graph.removeListener(this.escapeHandler);
this.escapeHandler = null;
}
if (this.marker != null)
{
this.marker.destroy();
this.marker = null;
}
if (this.shape != null)
{
this.shape.destroy();
this.shape = null;
}
if (this.parentHighlight != null)
{
var parent = this.graph.model.getParent(this.state.cell);
var pstate = this.graph.view.getState(parent);
if (pstate != null && pstate.parentHighlight == this.parentHighlight)
{
pstate.parentHighlight = null;
}
this.parentHighlight.destroy();
this.parentHighlight = null;
}
if (this.labelShape != null)
{
this.labelShape.destroy();
this.labelShape = null;
}
if (this.constraintHandler != null)
{
this.constraintHandler.destroy();
this.constraintHandler = null;
}
this.destroyBends(this.virtualBends);
this.virtualBends = null;
this.destroyBends(this.customHandles);
this.customHandles = null;
this.destroyBends(this.bends);
this.bends = null;
this.removeHint();
};
__mxOutput.mxEdgeHandler = typeof mxEdgeHandler !== 'undefined' ? mxEdgeHandler : undefined;
function mxElbowEdgeHandler(state)
{
mxEdgeHandler.call(this, state);
} mxUtils.extend(mxElbowEdgeHandler, mxEdgeHandler);
mxElbowEdgeHandler.prototype.flipEnabled = true;
mxElbowEdgeHandler.prototype.doubleClickOrientationResource =
(mxClient.language != 'none') ? 'doubleClickOrientation' : '';
mxElbowEdgeHandler.prototype.createBends = function()
{
var bends = [];
var bend = this.createHandleShape(0);
this.initBend(bend);
bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
bends.push(bend);
bends.push(this.createVirtualBend(mxUtils.bind(this, function(evt)
{
if (!mxEvent.isConsumed(evt) && this.flipEnabled)
{
this.graph.flipEdge(this.state.cell, evt);
mxEvent.consume(evt);
}
})));
this.points.push(new mxPoint(0,0));
bend = this.createHandleShape(2);
this.initBend(bend);
bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
bends.push(bend);
return bends;
};
mxElbowEdgeHandler.prototype.createVirtualBend = function(dblClickHandler)
{
var bend = this.createHandleShape();
this.initBend(bend, dblClickHandler);
bend.setCursor(this.getCursorForBend());
if (!this.graph.isCellBendable(this.state.cell))
{
bend.node.style.display = 'none';
}
return bend;
};
mxElbowEdgeHandler.prototype.getCursorForBend = function()
{
return (this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.TopToBottom ||
this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_TOPTOBOTTOM ||
((this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.ElbowConnector ||
this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_ELBOW)&&
this.state.style[mxConstants.STYLE_ELBOW] == mxConstants.ELBOW_VERTICAL)) ?
'row-resize' : 'col-resize';
};
mxElbowEdgeHandler.prototype.getTooltipForNode = function(node)
{
var tip = null;
if (this.bends != null && this.bends[1] != null && (node == this.bends[1].node ||
node.parentNode == this.bends[1].node))
{
tip = this.doubleClickOrientationResource;
tip = mxResources.get(tip) || tip;
}
return tip;
};
mxElbowEdgeHandler.prototype.convertPoint = function(point, gridEnabled)
{
var scale = this.graph.getView().getScale();
var tr = this.graph.getView().getTranslate();
var origin = this.state.origin;
if (gridEnabled)
{
point.x = this.graph.snap(point.x);
point.y = this.graph.snap(point.y);
}
point.x = Math.round(point.x / scale - tr.x - origin.x);
point.y = Math.round(point.y / scale - tr.y - origin.y);
return point;
};
mxElbowEdgeHandler.prototype.redrawInnerBends = function(p0, pe)
{
var g = this.graph.getModel().getGeometry(this.state.cell);
var pts = this.state.absolutePoints;
var pt = null;
if (pts.length > 1)
{
p0 = pts[1];
pe = pts[pts.length - 2];
}
else if (g.points != null && g.points.length > 0)
{
pt = pts[0];
}
if (pt == null)
{
pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2);
}
else
{
pt = new mxPoint(this.graph.getView().scale * (pt.x + this.graph.getView().translate.x + this.state.origin.x),
this.graph.getView().scale * (pt.y + this.graph.getView().translate.y + this.state.origin.y));
}
var b = this.bends[1].bounds;
var w = b.width;
var h = b.height;
var bounds = new mxRectangle(Math.round(pt.x - w / 2), Math.round(pt.y - h / 2), w, h);
if (this.manageLabelHandle)
{
this.checkLabelHandle(bounds);
}
else if (this.handleImage == null && this.labelShape.visible && mxUtils.intersects(bounds, this.labelShape.bounds))
{
w = mxConstants.HANDLE_SIZE + 3;
h = mxConstants.HANDLE_SIZE + 3;
bounds = new mxRectangle(Math.floor(pt.x - w / 2), Math.floor(pt.y - h / 2), w, h);
}
this.bends[1].bounds = bounds;
this.bends[1].redraw();
if (this.manageLabelHandle)
{
this.checkLabelHandle(this.bends[1].bounds);
}
};
__mxOutput.mxElbowEdgeHandler = typeof mxElbowEdgeHandler !== 'undefined' ? mxElbowEdgeHandler : undefined;
function mxEdgeSegmentHandler(state)
{
mxEdgeHandler.call(this, state);
} mxUtils.extend(mxEdgeSegmentHandler, mxElbowEdgeHandler);
mxEdgeSegmentHandler.prototype.getCurrentPoints = function()
{
var pts = this.state.absolutePoints;
if (pts != null)
{
var tol = Math.max(1, this.graph.view.scale);
if (pts.length == 2 || (pts.length == 3 &&
(Math.abs(pts[0].x - pts[1].x) < tol && Math.abs(pts[1].x - pts[2].x) < tol ||
Math.abs(pts[0].y - pts[1].y) < tol && Math.abs(pts[1].y - pts[2].y) < tol)))
{
var cx = pts[0].x + (pts[pts.length - 1].x - pts[0].x) / 2;
var cy = pts[0].y + (pts[pts.length - 1].y - pts[0].y) / 2;
pts = [pts[0], new mxPoint(cx, cy), new mxPoint(cx, cy), pts[pts.length - 1]];
}
}
return pts;
};
mxEdgeSegmentHandler.prototype.getPreviewPoints = function(point)
{
if (this.isSource || this.isTarget)
{
return mxElbowEdgeHandler.prototype.getPreviewPoints.apply(this, arguments);
}
else
{
var pts = this.getCurrentPoints();
var last = this.convertPoint(pts[0].clone(), false);
point = this.convertPoint(point.clone(), false);
var result = [];
for (var i = 1; i < pts.length; i++)
{
var pt = this.convertPoint(pts[i].clone(), false);
if (i == this.index)
{
if (Math.round(last.x - pt.x) == 0)
{
last.x = point.x;
pt.x = point.x;
}
if (Math.round(last.y - pt.y) == 0)
{
last.y = point.y;
pt.y = point.y;
}
}
if (i < pts.length - 1)
{
result.push(pt);
}
last = pt;
}
if (result.length == 1)
{
var source = this.state.getVisibleTerminalState(true);
var target = this.state.getVisibleTerminalState(false);
var scale = this.state.view.getScale();
var tr = this.state.view.getTranslate();
var x = result[0].x * scale + tr.x;
var y = result[0].y * scale + tr.y;
if ((source != null && mxUtils.contains(source, x, y)) ||
(target != null && mxUtils.contains(target, x, y)))
{
result = [point, point];
}
}
return result;
}
};
mxEdgeSegmentHandler.prototype.updatePreviewState = function(edge, point, terminalState, me)
{
mxEdgeHandler.prototype.updatePreviewState.apply(this, arguments);
if (!this.isSource && !this.isTarget)
{
point = this.convertPoint(point.clone(), false);
var pts = edge.absolutePoints;
var pt0 = pts[0];
var pt1 = pts[1];
var result = [];
for (var i = 2; i < pts.length; i++)
{
var pt2 = pts[i];
if ((Math.round(pt0.x - pt1.x) != 0 || Math.round(pt1.x - pt2.x) != 0) &&
(Math.round(pt0.y - pt1.y) != 0 || Math.round(pt1.y - pt2.y) != 0))
{
result.push(this.convertPoint(pt1.clone(), false));
}
pt0 = pt1;
pt1 = pt2;
}
var source = this.state.getVisibleTerminalState(true);
var target = this.state.getVisibleTerminalState(false);
var rpts = this.state.absolutePoints;
if (result.length == 0 && (Math.round(pts[0].x - pts[pts.length - 1].x) == 0 ||
Math.round(pts[0].y - pts[pts.length - 1].y) == 0))
{
result = [point, point];
}
else if (pts.length == 5 && result.length == 2 && source != null && target != null &&
rpts != null && Math.round(rpts[0].x - rpts[rpts.length - 1].x) == 0)
{
var view = this.graph.getView();
var scale = view.getScale();
var tr = view.getTranslate();
var y0 = view.getRoutingCenterY(source) / scale - tr.y;
var sc = this.graph.getConnectionConstraint(edge, source, true);
if (sc != null)
{
var pt = this.graph.getConnectionPoint(source, sc);
if (pt != null)
{
this.convertPoint(pt, false);
y0 = pt.y;
}
}
var ye = view.getRoutingCenterY(target) / scale - tr.y;
var tc = this.graph.getConnectionConstraint(edge, target, false);
if (tc)
{
var pt = this.graph.getConnectionPoint(target, tc);
if (pt != null)
{
this.convertPoint(pt, false);
ye = pt.y;
}
}
result = [new mxPoint(point.x, y0), new mxPoint(point.x, ye)];
}
this.points = result;
edge.view.updateFixedTerminalPoints(edge, source, target);
edge.view.updatePoints(edge, this.points, source, target);
edge.view.updateFloatingTerminalPoints(edge, source, target);
}
};
mxEdgeSegmentHandler.prototype.connect = function(edge, terminal, isSource, isClone, me)
{
var model = this.graph.getModel();
var geo = model.getGeometry(edge);
var result = null;
if (geo != null && geo.points != null && geo.points.length > 0)
{
var pts = this.abspoints;
var pt0 = pts[0];
var pt1 = pts[1];
result = [];
for (var i = 2; i < pts.length; i++)
{
var pt2 = pts[i];
if ((Math.round(pt0.x - pt1.x) != 0 || Math.round(pt1.x - pt2.x) != 0) &&
(Math.round(pt0.y - pt1.y) != 0 || Math.round(pt1.y - pt2.y) != 0))
{
result.push(this.convertPoint(pt1.clone(), false));
}
pt0 = pt1;
pt1 = pt2;
}
}
model.beginUpdate();
try
{
if (result != null)
{
var geo = model.getGeometry(edge);
if (geo != null)
{
geo = geo.clone();
geo.points = result;
model.setGeometry(edge, geo);
}
}
edge = mxEdgeHandler.prototype.connect.apply(this, arguments);
}
finally
{
model.endUpdate();
}
return edge;
};
mxEdgeSegmentHandler.prototype.getTooltipForNode = function(node)
{
return null;
};
mxEdgeSegmentHandler.prototype.start = function(x, y, index)
{
mxEdgeHandler.prototype.start.apply(this, arguments);
if (this.bends != null && this.bends[index] != null &&
!this.isSource && !this.isTarget)
{
mxUtils.setOpacity(this.bends[index].node, 100);
}
};
mxEdgeSegmentHandler.prototype.createBends = function()
{
var bends = [];
var bend = this.createHandleShape(0);
this.initBend(bend);
bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
bends.push(bend);
var pts = this.getCurrentPoints();
if (this.graph.isCellBendable(this.state.cell))
{
if (this.points == null)
{
this.points = [];
}
for (var i = 0; i < pts.length - 1; i++)
{
bend = this.createVirtualBend();
bends.push(bend);
var horizontal = Math.round(pts[i].x - pts[i + 1].x) == 0;
if (Math.round(pts[i].y - pts[i + 1].y) == 0 && i < pts.length - 2)
{
horizontal = Math.round(pts[i].x - pts[i + 2].x) == 0;
}
bend.setCursor((horizontal) ? 'col-resize' : 'row-resize');
this.points.push(new mxPoint(0,0));
}
}
var bend = this.createHandleShape(pts.length);
this.initBend(bend);
bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
bends.push(bend);
return bends;
};
mxEdgeSegmentHandler.prototype.redraw = function()
{
this.refresh();
mxEdgeHandler.prototype.redraw.apply(this, arguments);
};
mxEdgeSegmentHandler.prototype.redrawInnerBends = function(p0, pe)
{
if (this.graph.isCellBendable(this.state.cell))
{
var pts = this.getCurrentPoints();
if (pts != null && pts.length > 1)
{
var straight = false;
if (pts.length == 4 && Math.round(pts[1].x - pts[2].x) == 0 && Math.round(pts[1].y - pts[2].y) == 0)
{
straight = true;
if (Math.round(pts[0].y - pts[pts.length - 1].y) == 0)
{
var cx = pts[0].x + (pts[pts.length - 1].x - pts[0].x) / 2;
pts[1] = new mxPoint(cx, pts[1].y);
pts[2] = new mxPoint(cx, pts[2].y);
}
else
{
var cy = pts[0].y + (pts[pts.length - 1].y - pts[0].y) / 2;
pts[1] = new mxPoint(pts[1].x, cy);
pts[2] = new mxPoint(pts[2].x, cy);
}
}
for (var i = 0; i < pts.length - 1; i++)
{
if (this.bends[i + 1] != null)
{
var p0 = pts[i];
var pe = pts[i + 1];
var pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2);
var b = this.bends[i + 1].bounds;
this.bends[i + 1].bounds = new mxRectangle(Math.floor(pt.x - b.width / 2),
Math.floor(pt.y - b.height / 2), b.width, b.height);
this.bends[i + 1].redraw();
if (this.manageLabelHandle)
{
this.checkLabelHandle(this.bends[i + 1].bounds);
}
}
}
if (straight)
{
mxUtils.setOpacity(this.bends[1].node, this.virtualBendOpacity);
mxUtils.setOpacity(this.bends[3].node, this.virtualBendOpacity);
}
}
}
};
__mxOutput.mxEdgeSegmentHandler = typeof mxEdgeSegmentHandler !== 'undefined' ? mxEdgeSegmentHandler : undefined;
function mxKeyHandler(graph, target)
{
if (graph != null)
{
this.graph = graph;
this.target = target || document.documentElement;
this.normalKeys = [];
this.shiftKeys = [];
this.controlKeys = [];
this.controlShiftKeys = [];
this.keydownHandler = mxUtils.bind(this, function(evt)
{
this.keyDown(evt);
});
mxEvent.addListener(this.target, 'keydown', this.keydownHandler);
if (mxClient.IS_IE)
{
mxEvent.addListener(window, 'unload',
mxUtils.bind(this, function()
{
this.destroy();
})
);
}
}
} mxKeyHandler.prototype.graph = null;
mxKeyHandler.prototype.target = null;
mxKeyHandler.prototype.normalKeys = null;
mxKeyHandler.prototype.shiftKeys = null;
mxKeyHandler.prototype.controlKeys = null;
mxKeyHandler.prototype.controlShiftKeys = null;
mxKeyHandler.prototype.enabled = true;
mxKeyHandler.prototype.isEnabled = function()
{
return this.enabled;
};
mxKeyHandler.prototype.setEnabled = function(enabled)
{
this.enabled = enabled;
};
mxKeyHandler.prototype.bindKey = function(code, funct)
{
this.normalKeys[code] = funct;
};
mxKeyHandler.prototype.bindShiftKey = function(code, funct)
{
this.shiftKeys[code] = funct;
};
mxKeyHandler.prototype.bindControlKey = function(code, funct)
{
this.controlKeys[code] = funct;
};
mxKeyHandler.prototype.bindControlShiftKey = function(code, funct)
{
this.controlShiftKeys[code] = funct;
};
mxKeyHandler.prototype.isControlDown = function(evt)
{
return mxEvent.isControlDown(evt);
};
mxKeyHandler.prototype.getFunction = function(evt)
{
if (evt != null && !mxEvent.isAltDown(evt))
{
if (this.isControlDown(evt))
{
if (mxEvent.isShiftDown(evt))
{
return this.controlShiftKeys[evt.keyCode];
}
else
{
return this.controlKeys[evt.keyCode];
}
}
else
{
if (mxEvent.isShiftDown(evt))
{
return this.shiftKeys[evt.keyCode];
}
else
{
return this.normalKeys[evt.keyCode];
}
}
}
return null;
};
mxKeyHandler.prototype.isGraphEvent = function(evt)
{
var source = mxEvent.getSource(evt);
if ((source == this.target || source.parentNode == this.target) ||
(this.graph.cellEditor != null && this.graph.cellEditor.isEventSource(evt)))
{
return true;
}
return mxUtils.isAncestorNode(this.graph.container, source);
};
mxKeyHandler.prototype.keyDown = function(evt)
{
if (this.isEnabledForEvent(evt))
{
if (evt.keyCode == 27 )
{
this.escape(evt);
}
else if (!this.isEventIgnored(evt))
{
var boundFunction = this.getFunction(evt);
if (boundFunction != null)
{
boundFunction(evt);
mxEvent.consume(evt);
}
}
}
};
mxKeyHandler.prototype.isEnabledForEvent = function(evt)
{
return (this.graph.isEnabled() && !mxEvent.isConsumed(evt) &&
this.isGraphEvent(evt) && this.isEnabled());
};
mxKeyHandler.prototype.isEventIgnored = function(evt)
{
return this.graph.isEditing();
};
mxKeyHandler.prototype.escape = function(evt)
{
if (this.graph.isEscapeEnabled())
{
this.graph.escape(evt);
}
};
mxKeyHandler.prototype.destroy = function()
{
if (this.target != null && this.keydownHandler != null)
{
mxEvent.removeListener(this.target, 'keydown', this.keydownHandler);
this.keydownHandler = null;
}
this.target = null;
};
__mxOutput.mxKeyHandler = typeof mxKeyHandler !== 'undefined' ? mxKeyHandler : undefined;
function mxTooltipHandler(graph, delay)
{
if (graph != null)
{
this.graph = graph;
this.delay = delay || 500;
this.graph.addMouseListener(this);
}
} mxTooltipHandler.prototype.zIndex = 10005;
mxTooltipHandler.prototype.graph = null;
mxTooltipHandler.prototype.delay = null;
mxTooltipHandler.prototype.ignoreTouchEvents = true;
mxTooltipHandler.prototype.hideOnHover = false;
mxTooltipHandler.prototype.destroyed = false;
mxTooltipHandler.prototype.enabled = true;
mxTooltipHandler.prototype.isEnabled = function()
{
return this.enabled;
};
mxTooltipHandler.prototype.setEnabled = function(enabled)
{
this.enabled = enabled;
};
mxTooltipHandler.prototype.isHideOnHover = function()
{
return this.hideOnHover;
};
mxTooltipHandler.prototype.setHideOnHover = function(value)
{
this.hideOnHover = value;
};
mxTooltipHandler.prototype.init = function()
{
if (document.body != null)
{
this.div = document.createElement('div');
this.div.className = 'mxTooltip';
this.div.style.visibility = 'hidden';
document.body.appendChild(this.div);
mxEvent.addGestureListeners(this.div, mxUtils.bind(this, function(evt)
{
var source = mxEvent.getSource(evt);
if (source.nodeName != 'A')
{
this.hideTooltip();
}
}));
}
};
mxTooltipHandler.prototype.getStateForEvent = function(me)
{
return me.getState();
};
mxTooltipHandler.prototype.mouseDown = function(sender, me)
{
this.reset(me, false);
this.hideTooltip();
};
mxTooltipHandler.prototype.mouseMove = function(sender, me)
{
if (me.getX() != this.lastX || me.getY() != this.lastY)
{
this.reset(me, true);
var state = this.getStateForEvent(me);
if (this.isHideOnHover() || state != this.state || (me.getSource() != this.node &&
(!this.stateSource || (state != null && this.stateSource ==
(me.isSource(state.shape) || !me.isSource(state.text))))))
{
this.hideTooltip();
}
}
this.lastX = me.getX();
this.lastY = me.getY();
};
mxTooltipHandler.prototype.mouseUp = function(sender, me)
{
this.reset(me, true);
this.hideTooltip();
};
mxTooltipHandler.prototype.resetTimer = function()
{
if (this.thread != null)
{
window.clearTimeout(this.thread);
this.thread = null;
}
};
mxTooltipHandler.prototype.reset = function(me, restart, state)
{
if (!this.ignoreTouchEvents || mxEvent.isMouseEvent(me.getEvent()))
{
this.resetTimer();
state = (state != null) ? state : this.getStateForEvent(me);
if (restart && this.isEnabled() && state != null && (this.div == null ||
this.div.style.visibility == 'hidden'))
{
var node = me.getSource();
var x = me.getX();
var y = me.getY();
var stateSource = me.isSource(state.shape) || me.isSource(state.text);
this.thread = window.setTimeout(mxUtils.bind(this, function()
{
if (!this.graph.isEditing() && !this.graph.popupMenuHandler.isMenuShowing() && !this.graph.isMouseDown)
{
var tip = this.graph.getTooltip(state, node, x, y);
this.show(tip, x, y);
this.state = state;
this.node = node;
this.stateSource = stateSource;
}
}), this.delay);
}
}
};
mxTooltipHandler.prototype.hide = function()
{
this.resetTimer();
this.hideTooltip();
};
mxTooltipHandler.prototype.hideTooltip = function()
{
if (this.div != null)
{
this.div.style.visibility = 'hidden';
this.div.innerHTML = '';
}
};
mxTooltipHandler.prototype.show = function(tip, x, y)
{
if (!this.destroyed && tip != null && tip.length > 0)
{
if (this.div == null)
{
this.init();
}
var origin = mxUtils.getScrollOrigin();
this.div.style.zIndex = this.zIndex;
this.div.style.left = (x + origin.x) + 'px';
this.div.style.top = (y + mxConstants.TOOLTIP_VERTICAL_OFFSET +
origin.y) + 'px';
if (!mxUtils.isNode(tip))
{
this.div.innerHTML = tip.replace(/\n/g, '<br>');
}
else
{
this.div.innerHTML = '';
this.div.appendChild(tip);
}
this.div.style.visibility = '';
mxUtils.fit(this.div);
}
};
mxTooltipHandler.prototype.destroy = function()
{
if (!this.destroyed)
{
this.graph.removeMouseListener(this);
mxEvent.release(this.div);
if (this.div != null && this.div.parentNode != null)
{
this.div.parentNode.removeChild(this.div);
}
this.destroyed = true;
this.div = null;
}
};
__mxOutput.mxTooltipHandler = typeof mxTooltipHandler !== 'undefined' ? mxTooltipHandler : undefined;
function mxCellTracker(graph, color, funct)
{
mxCellMarker.call(this, graph, color);
this.graph.addMouseListener(this);
if (funct != null)
{
this.getCell = funct;
}
if (mxClient.IS_IE)
{
mxEvent.addListener(window, 'unload', mxUtils.bind(this, function()
{
this.destroy();
}));
}
} mxUtils.extend(mxCellTracker, mxCellMarker);
mxCellTracker.prototype.mouseDown = function(sender, me) { };
mxCellTracker.prototype.mouseMove = function(sender, me)
{
if (this.isEnabled())
{
this.process(me);
}
};
mxCellTracker.prototype.mouseUp = function(sender, me) { };
mxCellTracker.prototype.destroy = function()
{
if (!this.destroyed)
{
this.destroyed = true;
this.graph.removeMouseListener(this);
mxCellMarker.prototype.destroy.apply(this);
}
};
__mxOutput.mxCellTracker = typeof mxCellTracker !== 'undefined' ? mxCellTracker : undefined;
function mxCellHighlight(graph, highlightColor, strokeWidth, dashed)
{
if (graph != null)
{
this.graph = graph;
this.highlightColor = (highlightColor != null) ? highlightColor : mxConstants.DEFAULT_VALID_COLOR;
this.strokeWidth = (strokeWidth != null) ? strokeWidth : mxConstants.HIGHLIGHT_STROKEWIDTH;
this.dashed = (dashed != null) ? dashed : false;
this.opacity = mxConstants.HIGHLIGHT_OPACITY;
this.repaintHandler = mxUtils.bind(this, function()
{
if (this.state != null)
{
var tmp = this.graph.view.getState(this.state.cell);
if (tmp == null)
{
this.hide();
}
else
{
this.state = tmp;
this.repaint();
}
}
});
this.graph.getView().addListener(mxEvent.SCALE, this.repaintHandler);
this.graph.getView().addListener(mxEvent.TRANSLATE, this.repaintHandler);
this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.repaintHandler);
this.graph.getModel().addListener(mxEvent.CHANGE, this.repaintHandler);
this.resetHandler = mxUtils.bind(this, function()
{
this.hide();
});
this.graph.getView().addListener(mxEvent.DOWN, this.resetHandler);
this.graph.getView().addListener(mxEvent.UP, this.resetHandler);
}
} mxCellHighlight.prototype.keepOnTop = false;
mxCellHighlight.prototype.graph = null;
mxCellHighlight.prototype.state = null;
mxCellHighlight.prototype.spacing = 2;
mxCellHighlight.prototype.resetHandler = null;
mxCellHighlight.prototype.setHighlightColor = function(color)
{
this.highlightColor = color;
if (this.shape != null)
{
this.shape.stroke = color;
}
};
mxCellHighlight.prototype.drawHighlight = function()
{
this.shape = this.createShape();
this.repaint();
if (!this.keepOnTop && this.shape.node.parentNode.firstChild != this.shape.node)
{
this.shape.node.parentNode.insertBefore(this.shape.node, this.shape.node.parentNode.firstChild);
}
};
mxCellHighlight.prototype.createShape = function()
{
var shape = this.graph.cellRenderer.createShape(this.state);
shape.svgStrokeTolerance = this.graph.tolerance;
shape.points = this.state.absolutePoints;
shape.apply(this.state);
shape.stroke = this.highlightColor;
shape.opacity = this.opacity;
shape.isDashed = this.dashed;
shape.isShadow = false;
shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
shape.init(this.graph.getView().getOverlayPane());
mxEvent.redirectMouseEvents(shape.node, this.graph, this.state);
if (this.graph.dialect != mxConstants.DIALECT_SVG)
{
shape.pointerEvents = false;
}
else
{
shape.svgPointerEvents = 'stroke';
}
return shape;
};
mxCellHighlight.prototype.getStrokeWidth = function(state)
{
return this.strokeWidth;
};
mxCellHighlight.prototype.repaint = function()
{
if (this.state != null && this.shape != null)
{
this.shape.scale = this.state.view.scale;
if (this.graph.model.isEdge(this.state.cell))
{
this.shape.strokewidth = this.getStrokeWidth();
this.shape.points = this.state.absolutePoints;
this.shape.outline = false;
}
else
{
this.shape.bounds = new mxRectangle(this.state.x - this.spacing, this.state.y - this.spacing,
this.state.width + 2 * this.spacing, this.state.height + 2 * this.spacing);
this.shape.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
this.shape.strokewidth = this.getStrokeWidth() / this.state.view.scale;
this.shape.outline = true;
}
if (this.state.shape != null)
{
this.shape.setCursor(this.state.shape.getCursor());
}
if (mxClient.IS_QUIRKS || document.documentMode == 8)
{
if (this.shape.stroke == 'transparent')
{
this.shape.stroke = 'white';
this.shape.opacity = 1;
}
else
{
this.shape.opacity = this.opacity;
}
}
this.shape.redraw();
}
};
mxCellHighlight.prototype.hide = function()
{
this.highlight(null);
};
mxCellHighlight.prototype.highlight = function(state)
{
if (this.state != state)
{
if (this.shape != null)
{
this.shape.destroy();
this.shape = null;
}
this.state = state;
if (this.state != null)
{
this.drawHighlight();
}
}
};
mxCellHighlight.prototype.isHighlightAt = function(x, y)
{
var hit = false;
if (this.shape != null && document.elementFromPoint != null && !mxClient.IS_QUIRKS)
{
var elt = document.elementFromPoint(x, y);
while (elt != null)
{
if (elt == this.shape.node)
{
hit = true;
break;
}
elt = elt.parentNode;
}
}
return hit;
};
mxCellHighlight.prototype.destroy = function()
{
this.graph.getView().removeListener(this.resetHandler);
this.graph.getView().removeListener(this.repaintHandler);
this.graph.getModel().removeListener(this.repaintHandler);
if (this.shape != null)
{
this.shape.destroy();
this.shape = null;
}
};
__mxOutput.mxCellHighlight = typeof mxCellHighlight !== 'undefined' ? mxCellHighlight : undefined;
function mxDefaultKeyHandler(editor)
{
if (editor != null)
{
this.editor = editor;
this.handler = new mxKeyHandler(editor.graph);
var old = this.handler.escape;
this.handler.escape = function(evt)
{
old.apply(this, arguments);
editor.hideProperties();
editor.fireEvent(new mxEventObject(mxEvent.ESCAPE, 'event', evt));
};
}
} mxDefaultKeyHandler.prototype.editor = null;
mxDefaultKeyHandler.prototype.handler = null;
mxDefaultKeyHandler.prototype.bindAction = function (code, action, control)
{
var keyHandler = mxUtils.bind(this, function()
{
this.editor.execute(action);
});
if (control)
{
this.handler.bindControlKey(code, keyHandler);
}
else
{
this.handler.bindKey(code, keyHandler);
}
};
mxDefaultKeyHandler.prototype.destroy = function ()
{
this.handler.destroy();
this.handler = null;
};
__mxOutput.mxDefaultKeyHandler = typeof mxDefaultKeyHandler !== 'undefined' ? mxDefaultKeyHandler : undefined;
function mxDefaultPopupMenu(config)
{
this.config = config;
} mxDefaultPopupMenu.prototype.imageBasePath = null;
mxDefaultPopupMenu.prototype.config = null;
mxDefaultPopupMenu.prototype.createMenu = function(editor, menu, cell, evt)
{
if (this.config != null)
{
var conditions = this.createConditions(editor, cell, evt);
var item = this.config.firstChild;
this.addItems(editor, menu, cell, evt, conditions, item, null);
}
};
mxDefaultPopupMenu.prototype.addItems = function(editor, menu, cell, evt, conditions, item, parent)
{
var addSeparator = false;
while (item != null)
{
if (item.nodeName == 'add')
{
var condition = item.getAttribute('if');
if (condition == null || conditions[condition])
{
var as = item.getAttribute('as');
as = mxResources.get(as) || as;
var funct = mxUtils.eval(mxUtils.getTextContent(item));
var action = item.getAttribute('action');
var icon = item.getAttribute('icon');
var iconCls = item.getAttribute('iconCls');
var enabledCond = item.getAttribute('enabled-if');
var enabled = enabledCond == null || conditions[enabledCond];
if (addSeparator)
{
menu.addSeparator(parent);
addSeparator = false;
}
if (icon != null && this.imageBasePath)
{
icon = this.imageBasePath + icon;
}
var row = this.addAction(menu, editor, as, icon, funct, action, cell, parent, iconCls, enabled);
this.addItems(editor, menu, cell, evt, conditions, item.firstChild, row);
}
}
else if (item.nodeName == 'separator')
{
addSeparator = true;
}
item = item.nextSibling;
}
};
mxDefaultPopupMenu.prototype.addAction = function(menu, editor, lab, icon, funct, action, cell, parent, iconCls, enabled)
{
var clickHandler = function(evt)
{
if (typeof(funct) == 'function')
{
funct.call(editor, editor, cell, evt);
}
if (action != null)
{
editor.execute(action, cell, evt);
}
};
return menu.addItem(lab, icon, clickHandler, parent, iconCls, enabled);
};
mxDefaultPopupMenu.prototype.createConditions = function(editor, cell, evt)
{
var model = editor.graph.getModel();
var childCount = model.getChildCount(cell);
var conditions = [];
conditions['nocell'] = cell == null;
conditions['ncells'] = editor.graph.getSelectionCount() > 1;
conditions['notRoot'] = model.getRoot() !=
model.getParent(editor.graph.getDefaultParent());
conditions['cell'] = cell != null;
var isCell = cell != null && editor.graph.getSelectionCount() == 1;
conditions['nonEmpty'] = isCell && childCount > 0;
conditions['expandable'] = isCell && editor.graph.isCellFoldable(cell, false);
conditions['collapsable'] = isCell && editor.graph.isCellFoldable(cell, true);
conditions['validRoot'] = isCell && editor.graph.isValidRoot(cell);
conditions['emptyValidRoot'] = conditions['validRoot'] && childCount == 0;
conditions['swimlane'] = isCell && editor.graph.isSwimlane(cell);
var condNodes = this.config.getElementsByTagName('condition');
for (var i=0; i<condNodes.length; i++)
{
var funct = mxUtils.eval(mxUtils.getTextContent(condNodes[i]));
var name = condNodes[i].getAttribute('name');
if (name != null && typeof(funct) == 'function')
{
conditions[name] = funct(editor, cell, evt);
}
}
return conditions;
};
__mxOutput.mxDefaultPopupMenu = typeof mxDefaultPopupMenu !== 'undefined' ? mxDefaultPopupMenu : undefined;
function mxDefaultToolbar(container, editor)
{
this.editor = editor;
if (container != null && editor != null)
{
this.init(container);
}
} mxDefaultToolbar.prototype.editor = null;
mxDefaultToolbar.prototype.toolbar = null;
mxDefaultToolbar.prototype.resetHandler = null;
mxDefaultToolbar.prototype.spacing = 4;
mxDefaultToolbar.prototype.connectOnDrop = false;
mxDefaultToolbar.prototype.init = function(container)
{
if (container != null)
{
this.toolbar = new mxToolbar(container);
this.toolbar.addListener(mxEvent.SELECT, mxUtils.bind(this, function(sender, evt)
{
var funct = evt.getProperty('function');
if (funct != null)
{
this.editor.insertFunction = mxUtils.bind(this, function()
{
funct.apply(this, arguments);
this.toolbar.resetMode();
});
}
else
{
this.editor.insertFunction = null;
}
}));
this.resetHandler = mxUtils.bind(this, function()
{
if (this.toolbar != null)
{
this.toolbar.resetMode(true);
}
});
this.editor.graph.addListener(mxEvent.DOUBLE_CLICK, this.resetHandler);
this.editor.addListener(mxEvent.ESCAPE, this.resetHandler);
}
};
mxDefaultToolbar.prototype.addItem = function(title, icon, action, pressed)
{
var clickHandler = mxUtils.bind(this, function()
{
if (action != null && action.length > 0)
{
this.editor.execute(action);
}
});
return this.toolbar.addItem(title, icon, clickHandler, pressed);
};
mxDefaultToolbar.prototype.addSeparator = function(icon)
{
icon = icon || mxClient.imageBasePath + '/separator.gif';
this.toolbar.addSeparator(icon);
};
mxDefaultToolbar.prototype.addCombo = function()
{
return this.toolbar.addCombo();
};
mxDefaultToolbar.prototype.addActionCombo = function(title)
{
return this.toolbar.addActionCombo(title);
};
mxDefaultToolbar.prototype.addActionOption = function(combo, title, action)
{
var clickHandler = mxUtils.bind(this, function()
{
this.editor.execute(action);
});
this.addOption(combo, title, clickHandler);
};
mxDefaultToolbar.prototype.addOption = function(combo, title, value)
{
return this.toolbar.addOption(combo, title, value);
};
mxDefaultToolbar.prototype.addMode = function(title, icon, mode, pressed, funct)
{
var clickHandler = mxUtils.bind(this, function()
{
this.editor.setMode(mode);
if (funct != null)
{
funct(this.editor);
}
});
return this.toolbar.addSwitchMode(title, icon, clickHandler, pressed);
};
mxDefaultToolbar.prototype.addPrototype = function(title, icon, ptype, pressed, insert, toggle)
{
var factory = mxUtils.bind(this, function()
{
if (typeof(ptype) == 'function')
{
return ptype();
}
else if (ptype != null)
{
return this.editor.graph.cloneCell(ptype);
}
return null;
});
var clickHandler = mxUtils.bind(this, function(evt, cell)
{
if (typeof(insert) == 'function')
{
insert(this.editor, factory(), evt, cell);
}
else
{
this.drop(factory(), evt, cell);
}
this.toolbar.resetMode();
mxEvent.consume(evt);
});
var img = this.toolbar.addMode(title, icon, clickHandler, pressed, null, toggle);
var dropHandler = function(graph, evt, cell)
{
clickHandler(evt, cell);
};
this.installDropHandler(img, dropHandler);
return img;
};
mxDefaultToolbar.prototype.drop = function(vertex, evt, target)
{
var graph = this.editor.graph;
var model = graph.getModel();
if (target == null ||
model.isEdge(target) ||
!this.connectOnDrop ||
!graph.isCellConnectable(target))
{
while (target != null &&
!graph.isValidDropTarget(target, [vertex], evt))
{
target = model.getParent(target);
}
this.insert(vertex, evt, target);
}
else
{
this.connect(vertex, evt, target);
}
};
mxDefaultToolbar.prototype.insert = function(vertex, evt, target)
{
var graph = this.editor.graph;
if (graph.canImportCell(vertex))
{
var x = mxEvent.getClientX(evt);
var y = mxEvent.getClientY(evt);
var pt = mxUtils.convertPoint(graph.container, x, y);
if (graph.isSplitEnabled() &&
graph.isSplitTarget(target, [vertex], evt))
{
return graph.splitEdge(target, [vertex], null, pt.x, pt.y);
}
else
{
return this.editor.addVertex(target, vertex, pt.x, pt.y);
}
}
return null;
};
mxDefaultToolbar.prototype.connect = function(vertex, evt, source)
{
var graph = this.editor.graph;
var model = graph.getModel();
if (source != null &&
graph.isCellConnectable(vertex) &&
graph.isEdgeValid(null, source, vertex))
{
var edge = null;
model.beginUpdate();
try
{
var geo = model.getGeometry(source);
var g = model.getGeometry(vertex).clone();
g.x = geo.x + (geo.width - g.width) / 2;
g.y = geo.y + (geo.height - g.height) / 2;
var step = this.spacing * graph.gridSize;
var dist = model.getDirectedEdgeCount(source, true) * 20;
if (this.editor.horizontalFlow)
{
g.x += (g.width + geo.width) / 2 + step + dist;
}
else
{
g.y += (g.height + geo.height) / 2 + step + dist;
}
vertex.setGeometry(g);
var parent = model.getParent(source);
graph.addCell(vertex, parent);
graph.constrainChild(vertex);
edge = this.editor.createEdge(source, vertex);
if (model.getGeometry(edge) == null)
{
var edgeGeometry = new mxGeometry();
edgeGeometry.relative = true;
model.setGeometry(edge, edgeGeometry);
}
graph.addEdge(edge, parent, source, vertex);
}
finally
{
model.endUpdate();
}
graph.setSelectionCells([vertex, edge]);
graph.scrollCellToVisible(vertex);
}
};
mxDefaultToolbar.prototype.installDropHandler = function (img, dropHandler)
{
var sprite = document.createElement('img');
sprite.setAttribute('src', img.getAttribute('src'));
var loader = mxUtils.bind(this, function(evt)
{
sprite.style.width = (2 * img.offsetWidth) + 'px';
sprite.style.height = (2 * img.offsetHeight) + 'px';
mxUtils.makeDraggable(img, this.editor.graph, dropHandler,
sprite);
mxEvent.removeListener(sprite, 'load', loader);
});
if (mxClient.IS_IE)
{
loader();
}
else
{
mxEvent.addListener(sprite, 'load', loader);
}
};
mxDefaultToolbar.prototype.destroy = function ()
{
if (this.resetHandler != null)
{
this.editor.graph.removeListener('dblclick', this.resetHandler);
this.editor.removeListener('escape', this.resetHandler);
this.resetHandler = null;
}
if (this.toolbar != null)
{
this.toolbar.destroy();
this.toolbar = null;
}
};
__mxOutput.mxDefaultToolbar = typeof mxDefaultToolbar !== 'undefined' ? mxDefaultToolbar : undefined;
function mxEditor(config)
{
this.actions = [];
this.addActions();
if (document.body != null)
{
this.cycleAttributeValues = [];
this.popupHandler = new mxDefaultPopupMenu();
this.undoManager = new mxUndoManager();
this.graph = this.createGraph();
this.toolbar = this.createToolbar();
this.keyHandler = new mxDefaultKeyHandler(this);
this.configure(config);
this.graph.swimlaneIndicatorColorAttribute = this.cycleAttributeName;
if (this.onInit != null)
{
this.onInit();
}
if (mxClient.IS_IE)
{
mxEvent.addListener(window, 'unload', mxUtils.bind(this, function()
{
this.destroy();
}));
}
}
} if (mxLoadResources)
{
mxResources.add(mxClient.basePath + '/resources/editor');
}
else
{
mxClient.defaultBundles.push(mxClient.basePath + '/resources/editor');
}
mxEditor.prototype = new mxEventSource();
mxEditor.prototype.constructor = mxEditor;
mxEditor.prototype.askZoomResource = (mxClient.language != 'none') ? 'askZoom' : '';
mxEditor.prototype.lastSavedResource = (mxClient.language != 'none') ? 'lastSaved' : '';
mxEditor.prototype.currentFileResource = (mxClient.language != 'none') ? 'currentFile' : '';
mxEditor.prototype.propertiesResource = (mxClient.language != 'none') ? 'properties' : '';
mxEditor.prototype.tasksResource = (mxClient.language != 'none') ? 'tasks' : '';
mxEditor.prototype.helpResource = (mxClient.language != 'none') ? 'help' : '';
mxEditor.prototype.outlineResource = (mxClient.language != 'none') ? 'outline' : '';
mxEditor.prototype.outline = null;
mxEditor.prototype.graph = null;
mxEditor.prototype.graphRenderHint = null;
mxEditor.prototype.toolbar = null;
mxEditor.prototype.status = null;
mxEditor.prototype.popupHandler = null;
mxEditor.prototype.undoManager = null;
mxEditor.prototype.keyHandler = null;
mxEditor.prototype.actions = null;
mxEditor.prototype.dblClickAction = 'edit';
mxEditor.prototype.swimlaneRequired = false;
mxEditor.prototype.disableContextMenu = true;
mxEditor.prototype.insertFunction = null;
mxEditor.prototype.forcedInserting = false;
mxEditor.prototype.templates = null;
mxEditor.prototype.defaultEdge = null;
mxEditor.prototype.defaultEdgeStyle = null;
mxEditor.prototype.defaultGroup = null;
mxEditor.prototype.groupBorderSize = null;
mxEditor.prototype.filename = null;
mxEditor.prototype.linefeed = '
';
mxEditor.prototype.postParameterName = 'xml';
mxEditor.prototype.escapePostData = true;
mxEditor.prototype.urlPost = null;
mxEditor.prototype.urlImage = null;
mxEditor.prototype.horizontalFlow = false;
mxEditor.prototype.layoutDiagram = false;
mxEditor.prototype.swimlaneSpacing = 0;
mxEditor.prototype.maintainSwimlanes = false;
mxEditor.prototype.layoutSwimlanes = false;
mxEditor.prototype.cycleAttributeValues = null;
mxEditor.prototype.cycleAttributeIndex = 0;
mxEditor.prototype.cycleAttributeName = 'fillColor';
mxEditor.prototype.tasks = null;
mxEditor.prototype.tasksWindowImage = null;
mxEditor.prototype.tasksTop = 20;
mxEditor.prototype.help = null;
mxEditor.prototype.helpWindowImage = null;
mxEditor.prototype.urlHelp = null;
mxEditor.prototype.helpWidth = 300;
mxEditor.prototype.helpHeight = 260;
mxEditor.prototype.propertiesWidth = 240;
mxEditor.prototype.propertiesHeight = null;
mxEditor.prototype.movePropertiesDialog = false;
mxEditor.prototype.validating = false;
mxEditor.prototype.modified = false;
mxEditor.prototype.isModified = function ()
{
return this.modified;
};
mxEditor.prototype.setModified = function (value)
{
this.modified = value;
};
mxEditor.prototype.addActions = function ()
{
this.addAction('save', function(editor)
{
editor.save();
});
this.addAction('print', function(editor)
{
var preview = new mxPrintPreview(editor.graph, 1);
preview.open();
});
this.addAction('show', function(editor)
{
mxUtils.show(editor.graph, null, 10, 10);
});
this.addAction('exportImage', function(editor)
{
var url = editor.getUrlImage();
if (url == null || mxClient.IS_LOCAL)
{
editor.execute('show');
}
else
{
var node = mxUtils.getViewXml(editor.graph, 1);
var xml = mxUtils.getXml(node, '\n');
mxUtils.submit(url, editor.postParameterName + '=' +
encodeURIComponent(xml), document, '_blank');
}
});
this.addAction('refresh', function(editor)
{
editor.graph.refresh();
});
this.addAction('cut', function(editor)
{
if (editor.graph.isEnabled())
{
mxClipboard.cut(editor.graph);
}
});
this.addAction('copy', function(editor)
{
if (editor.graph.isEnabled())
{
mxClipboard.copy(editor.graph);
}
});
this.addAction('paste', function(editor)
{
if (editor.graph.isEnabled())
{
mxClipboard.paste(editor.graph);
}
});
this.addAction('delete', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.removeCells();
}
});
this.addAction('group', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.setSelectionCell(editor.groupCells());
}
});
this.addAction('ungroup', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.setSelectionCells(editor.graph.ungroupCells());
}
});
this.addAction('removeFromParent', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.removeCellsFromParent();
}
});
this.addAction('undo', function(editor)
{
if (editor.graph.isEnabled())
{
editor.undo();
}
});
this.addAction('redo', function(editor)
{
if (editor.graph.isEnabled())
{
editor.redo();
}
});
this.addAction('zoomIn', function(editor)
{
editor.graph.zoomIn();
});
this.addAction('zoomOut', function(editor)
{
editor.graph.zoomOut();
});
this.addAction('actualSize', function(editor)
{
editor.graph.zoomActual();
});
this.addAction('fit', function(editor)
{
editor.graph.fit();
});
this.addAction('showProperties', function(editor, cell)
{
editor.showProperties(cell);
});
this.addAction('selectAll', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.selectAll();
}
});
this.addAction('selectNone', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.clearSelection();
}
});
this.addAction('selectVertices', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.selectVertices();
}
});
this.addAction('selectEdges', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.selectEdges();
}
});
this.addAction('edit', function(editor, cell)
{
if (editor.graph.isEnabled() &&
editor.graph.isCellEditable(cell))
{
editor.graph.startEditingAtCell(cell);
}
});
this.addAction('toBack', function(editor, cell)
{
if (editor.graph.isEnabled())
{
editor.graph.orderCells(true);
}
});
this.addAction('toFront', function(editor, cell)
{
if (editor.graph.isEnabled())
{
editor.graph.orderCells(false);
}
});
this.addAction('enterGroup', function(editor, cell)
{
editor.graph.enterGroup(cell);
});
this.addAction('exitGroup', function(editor)
{
editor.graph.exitGroup();
});
this.addAction('home', function(editor)
{
editor.graph.home();
});
this.addAction('selectPrevious', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.selectPreviousCell();
}
});
this.addAction('selectNext', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.selectNextCell();
}
});
this.addAction('selectParent', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.selectParentCell();
}
});
this.addAction('selectChild', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.selectChildCell();
}
});
this.addAction('collapse', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.foldCells(true);
}
});
this.addAction('collapseAll', function(editor)
{
if (editor.graph.isEnabled())
{
var cells = editor.graph.getChildVertices();
editor.graph.foldCells(true, false, cells);
}
});
this.addAction('expand', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.foldCells(false);
}
});
this.addAction('expandAll', function(editor)
{
if (editor.graph.isEnabled())
{
var cells = editor.graph.getChildVertices();
editor.graph.foldCells(false, false, cells);
}
});
this.addAction('bold', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.toggleCellStyleFlags(
mxConstants.STYLE_FONTSTYLE,
mxConstants.FONT_BOLD);
}
});
this.addAction('italic', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.toggleCellStyleFlags(
mxConstants.STYLE_FONTSTYLE,
mxConstants.FONT_ITALIC);
}
});
this.addAction('underline', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.toggleCellStyleFlags(
mxConstants.STYLE_FONTSTYLE,
mxConstants.FONT_UNDERLINE);
}
});
this.addAction('alignCellsLeft', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.alignCells(mxConstants.ALIGN_LEFT);
}
});
this.addAction('alignCellsCenter', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.alignCells(mxConstants.ALIGN_CENTER);
}
});
this.addAction('alignCellsRight', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.alignCells(mxConstants.ALIGN_RIGHT);
}
});
this.addAction('alignCellsTop', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.alignCells(mxConstants.ALIGN_TOP);
}
});
this.addAction('alignCellsMiddle', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.alignCells(mxConstants.ALIGN_MIDDLE);
}
});
this.addAction('alignCellsBottom', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.alignCells(mxConstants.ALIGN_BOTTOM);
}
});
this.addAction('alignFontLeft', function(editor)
{
editor.graph.setCellStyles(
mxConstants.STYLE_ALIGN,
mxConstants.ALIGN_LEFT);
});
this.addAction('alignFontCenter', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.setCellStyles(
mxConstants.STYLE_ALIGN,
mxConstants.ALIGN_CENTER);
}
});
this.addAction('alignFontRight', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.setCellStyles(
mxConstants.STYLE_ALIGN,
mxConstants.ALIGN_RIGHT);
}
});
this.addAction('alignFontTop', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.setCellStyles(
mxConstants.STYLE_VERTICAL_ALIGN,
mxConstants.ALIGN_TOP);
}
});
this.addAction('alignFontMiddle', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.setCellStyles(
mxConstants.STYLE_VERTICAL_ALIGN,
mxConstants.ALIGN_MIDDLE);
}
});
this.addAction('alignFontBottom', function(editor)
{
if (editor.graph.isEnabled())
{
editor.graph.setCellStyles(
mxConstants.STYLE_VERTICAL_ALIGN,
mxConstants.ALIGN_BOTTOM);
}
});
this.addAction('zoom', function(editor)
{
var current = editor.graph.getView().scale*100;
var scale = parseFloat(mxUtils.prompt(
mxResources.get(editor.askZoomResource) ||
editor.askZoomResource,
current))/100;
if (!isNaN(scale))
{
editor.graph.getView().setScale(scale);
}
});
this.addAction('toggleTasks', function(editor)
{
if (editor.tasks != null)
{
editor.tasks.setVisible(!editor.tasks.isVisible());
}
else
{
editor.showTasks();
}
});
this.addAction('toggleHelp', function(editor)
{
if (editor.help != null)
{
editor.help.setVisible(!editor.help.isVisible());
}
else
{
editor.showHelp();
}
});
this.addAction('toggleOutline', function(editor)
{
if (editor.outline == null)
{
editor.showOutline();
}
else
{
editor.outline.setVisible(!editor.outline.isVisible());
}
});
this.addAction('toggleConsole', function(editor)
{
mxLog.setVisible(!mxLog.isVisible());
});
};
mxEditor.prototype.configure = function (node)
{
if (node != null)
{
var dec = new mxCodec(node.ownerDocument);
dec.decode(node, this);
this.resetHistory();
}
};
mxEditor.prototype.resetFirstTime = function ()
{
document.cookie =
'mxgraph=seen; expires=Fri, 27 Jul 2001 02:47:11 UTC; path=/';
};
mxEditor.prototype.resetHistory = function ()
{
this.lastSnapshot = new Date().getTime();
this.undoManager.clear();
this.ignoredChanges = 0;
this.setModified(false);
};
mxEditor.prototype.addAction = function (actionname, funct)
{
this.actions[actionname] = funct;
};
mxEditor.prototype.execute = function (actionname, cell, evt)
{
var action = this.actions[actionname];
if (action != null)
{
try
{
var args = arguments;
args[0] = this;
action.apply(this, args);
}
catch (e)
{
mxUtils.error('Cannot execute ' + actionname +
': ' + e.message, 280, true);
throw e;
}
}
else
{
mxUtils.error('Cannot find action '+actionname, 280, true);
}
};
mxEditor.prototype.addTemplate = function (name, template)
{
this.templates[name] = template;
};
mxEditor.prototype.getTemplate = function (name)
{
return this.templates[name];
};
mxEditor.prototype.createGraph = function ()
{
var graph = new mxGraph(null, null, this.graphRenderHint);
graph.setTooltips(true);
graph.setPanning(true);
this.installDblClickHandler(graph);
this.installUndoHandler(graph);
this.installDrillHandler(graph);
this.installChangeHandler(graph);
this.installInsertHandler(graph);
graph.popupMenuHandler.factoryMethod =
mxUtils.bind(this, function(menu, cell, evt)
{
return this.createPopupMenu(menu, cell, evt);
});
graph.connectionHandler.factoryMethod =
mxUtils.bind(this, function(source, target)
{
return this.createEdge(source, target);
});
this.createSwimlaneManager(graph);
this.createLayoutManager(graph);
return graph;
};
mxEditor.prototype.createSwimlaneManager = function (graph)
{
var swimlaneMgr = new mxSwimlaneManager(graph, false);
swimlaneMgr.isHorizontal = mxUtils.bind(this, function()
{
return this.horizontalFlow;
});
swimlaneMgr.isEnabled = mxUtils.bind(this, function()
{
return this.maintainSwimlanes;
});
return swimlaneMgr;
};
mxEditor.prototype.createLayoutManager = function (graph)
{
var layoutMgr = new mxLayoutManager(graph);
var self = this;
layoutMgr.getLayout = function(cell)
{
var layout = null;
var model = self.graph.getModel();
if (model.getParent(cell) != null)
{
if (self.layoutSwimlanes &&
graph.isSwimlane(cell))
{
if (self.swimlaneLayout == null)
{
self.swimlaneLayout = self.createSwimlaneLayout();
}
layout = self.swimlaneLayout;
}
else if (self.layoutDiagram &&
(graph.isValidRoot(cell) ||
model.getParent(model.getParent(cell)) == null))
{
if (self.diagramLayout == null)
{
self.diagramLayout = self.createDiagramLayout();
}
layout = self.diagramLayout;
}
}
return layout;
};
return layoutMgr;
};
mxEditor.prototype.setGraphContainer = function (container)
{
if (this.graph.container == null)
{
this.graph.init(container);
this.rubberband = new mxRubberband(this.graph);
if (this.disableContextMenu)
{
mxEvent.disableContextMenu(container);
}
if (mxClient.IS_QUIRKS)
{
new mxDivResizer(container);
}
}
};
mxEditor.prototype.installDblClickHandler = function (graph)
{
graph.addListener(mxEvent.DOUBLE_CLICK,
mxUtils.bind(this, function(sender, evt)
{
var cell = evt.getProperty('cell');
if (cell != null &&
graph.isEnabled() &&
this.dblClickAction != null)
{
this.execute(this.dblClickAction, cell);
evt.consume();
}
})
);
};
mxEditor.prototype.installUndoHandler = function (graph)
{
var listener = mxUtils.bind(this, function(sender, evt)
{
var edit = evt.getProperty('edit');
this.undoManager.undoableEditHappened(edit);
});
graph.getModel().addListener(mxEvent.UNDO, listener);
graph.getView().addListener(mxEvent.UNDO, listener);
var undoHandler = function(sender, evt)
{
var changes = evt.getProperty('edit').changes;
graph.setSelectionCells(graph.getSelectionCellsForChanges(changes));
};
this.undoManager.addListener(mxEvent.UNDO, undoHandler);
this.undoManager.addListener(mxEvent.REDO, undoHandler);
};
mxEditor.prototype.installDrillHandler = function (graph)
{
var listener = mxUtils.bind(this, function(sender)
{
this.fireEvent(new mxEventObject(mxEvent.ROOT));
});
graph.getView().addListener(mxEvent.DOWN, listener);
graph.getView().addListener(mxEvent.UP, listener);
};
mxEditor.prototype.installChangeHandler = function (graph)
{
var listener = mxUtils.bind(this, function(sender, evt)
{
this.setModified(true);
if (this.validating == true)
{
graph.validateGraph();
}
var changes = evt.getProperty('edit').changes;
for (var i = 0; i < changes.length; i++)
{
var change = changes[i];
if (change instanceof mxRootChange ||
(change instanceof mxValueChange &&
change.cell == this.graph.model.root) ||
(change instanceof mxCellAttributeChange &&
change.cell == this.graph.model.root))
{
this.fireEvent(new mxEventObject(mxEvent.ROOT));
break;
}
}
});
graph.getModel().addListener(mxEvent.CHANGE, listener);
};
mxEditor.prototype.installInsertHandler = function (graph)
{
var self = this;
var insertHandler =
{
mouseDown: function(sender, me)
{
if (self.insertFunction != null &&
!me.isPopupTrigger() &&
(self.forcedInserting ||
me.getState() == null))
{
self.graph.clearSelection();
self.insertFunction(me.getEvent(), me.getCell());
this.isActive = true;
me.consume();
}
},
mouseMove: function(sender, me)
{
if (this.isActive)
{
me.consume();
}
},
mouseUp: function(sender, me)
{
if (this.isActive)
{
this.isActive = false;
me.consume();
}
}
};
graph.addMouseListener(insertHandler);
};
mxEditor.prototype.createDiagramLayout = function ()
{
var gs = this.graph.gridSize;
var layout = new mxStackLayout(this.graph, !this.horizontalFlow,
this.swimlaneSpacing, 2*gs, 2*gs);
layout.isVertexIgnored = function(cell)
{
return !layout.graph.isSwimlane(cell);
};
return layout;
};
mxEditor.prototype.createSwimlaneLayout = function ()
{
return new mxCompactTreeLayout(this.graph, this.horizontalFlow);
};
mxEditor.prototype.createToolbar = function ()
{
return new mxDefaultToolbar(null, this);
};
mxEditor.prototype.setToolbarContainer = function (container)
{
this.toolbar.init(container);
if (mxClient.IS_QUIRKS)
{
new mxDivResizer(container);
}
};
mxEditor.prototype.setStatusContainer = function (container)
{
if (this.status == null)
{
this.status = container;
this.addListener(mxEvent.SAVE, mxUtils.bind(this, function()
{
var tstamp = new Date().toLocaleString();
this.setStatus((mxResources.get(this.lastSavedResource) ||
this.lastSavedResource)+': '+tstamp);
}));
this.addListener(mxEvent.OPEN, mxUtils.bind(this, function()
{
this.setStatus((mxResources.get(this.currentFileResource) ||
this.currentFileResource)+': '+this.filename);
}));
if (mxClient.IS_QUIRKS)
{
new mxDivResizer(container);
}
}
};
mxEditor.prototype.setStatus = function (message)
{
if (this.status != null && message != null)
{
this.status.innerHTML = message;
}
};
mxEditor.prototype.setTitleContainer = function (container)
{
this.addListener(mxEvent.ROOT, mxUtils.bind(this, function(sender)
{
container.innerHTML = this.getTitle();
}));
if (mxClient.IS_QUIRKS)
{
new mxDivResizer(container);
}
};
mxEditor.prototype.treeLayout = function (cell, horizontal)
{
if (cell != null)
{
var layout = new mxCompactTreeLayout(this.graph, horizontal);
layout.execute(cell);
}
};
mxEditor.prototype.getTitle = function ()
{
var title = '';
var graph = this.graph;
var cell = graph.getCurrentRoot();
while (cell != null &&
graph.getModel().getParent(
graph.getModel().getParent(cell)) != null)
{
if (graph.isValidRoot(cell))
{
title = ' > ' +
graph.convertValueToString(cell) + title;
}
cell = graph.getModel().getParent(cell);
}
var prefix = this.getRootTitle();
return prefix + title;
};
mxEditor.prototype.getRootTitle = function ()
{
var root = this.graph.getModel().getRoot();
return this.graph.convertValueToString(root);
};
mxEditor.prototype.undo = function ()
{
this.undoManager.undo();
};
mxEditor.prototype.redo = function ()
{
this.undoManager.redo();
};
mxEditor.prototype.groupCells = function ()
{
var border = (this.groupBorderSize != null) ?
this.groupBorderSize :
this.graph.gridSize;
return this.graph.groupCells(this.createGroup(), border);
};
mxEditor.prototype.createGroup = function ()
{
var model = this.graph.getModel();
return model.cloneCell(this.defaultGroup);
};
mxEditor.prototype.open = function (filename)
{
if (filename != null)
{
var xml = mxUtils.load(filename).getXml();
this.readGraphModel(xml.documentElement);
this.filename = filename;
this.fireEvent(new mxEventObject(mxEvent.OPEN, 'filename', filename));
}
};
mxEditor.prototype.readGraphModel = function (node)
{
var dec = new mxCodec(node.ownerDocument);
dec.decode(node, this.graph.getModel());
this.resetHistory();
};
mxEditor.prototype.save = function (url, linefeed)
{
url = url || this.getUrlPost();
if (url != null && url.length > 0)
{
var data = this.writeGraphModel(linefeed);
this.postDiagram(url, data);
this.setModified(false);
}
this.fireEvent(new mxEventObject(mxEvent.SAVE, 'url', url));
};
mxEditor.prototype.postDiagram = function (url, data)
{
if (this.escapePostData)
{
data = encodeURIComponent(data);
}
mxUtils.post(url, this.postParameterName+'='+data,
mxUtils.bind(this, function(req)
{
this.fireEvent(new mxEventObject(mxEvent.POST,
'request', req, 'url', url, 'data', data));
})
);
};
mxEditor.prototype.writeGraphModel = function (linefeed)
{
linefeed = (linefeed != null) ? linefeed : this.linefeed;
var enc = new mxCodec();
var node = enc.encode(this.graph.getModel());
return mxUtils.getXml(node, linefeed);
};
mxEditor.prototype.getUrlPost = function ()
{
return this.urlPost;
};
mxEditor.prototype.getUrlImage = function ()
{
return this.urlImage;
};
mxEditor.prototype.swapStyles = function (first, second)
{
var style = this.graph.getStylesheet().styles[second];
this.graph.getView().getStylesheet().putCellStyle(
second, this.graph.getStylesheet().styles[first]);
this.graph.getStylesheet().putCellStyle(first, style);
this.graph.refresh();
};
mxEditor.prototype.showProperties = function (cell)
{
cell = cell || this.graph.getSelectionCell();
if (cell == null)
{
cell = this.graph.getCurrentRoot();
if (cell == null)
{
cell = this.graph.getModel().getRoot();
}
}
if (cell != null)
{
this.graph.stopEditing(true);
var offset = mxUtils.getOffset(this.graph.container);
var x = offset.x+10;
var y = offset.y;
if (this.properties != null && !this.movePropertiesDialog)
{
x = this.properties.getX();
y = this.properties.getY();
}
else
{
var bounds = this.graph.getCellBounds(cell);
if (bounds != null)
{
x += bounds.x+Math.min(200, bounds.width);
y += bounds.y;
}
}
this.hideProperties();
var node = this.createProperties(cell);
if (node != null)
{
this.properties = new mxWindow(mxResources.get(this.propertiesResource) ||
this.propertiesResource, node, x, y, this.propertiesWidth, this.propertiesHeight, false);
this.properties.setVisible(true);
}
}
};
mxEditor.prototype.isPropertiesVisible = function ()
{
return this.properties != null;
};
mxEditor.prototype.createProperties = function (cell)
{
var model = this.graph.getModel();
var value = model.getValue(cell);
if (mxUtils.isNode(value))
{
var form = new mxForm('properties');
var id = form.addText('ID', cell.getId());
id.setAttribute('readonly', 'true');
var geo = null;
var yField = null;
var xField = null;
var widthField = null;
var heightField = null;
if (model.isVertex(cell))
{
geo = model.getGeometry(cell);
if (geo != null)
{
yField = form.addText('top', geo.y);
xField = form.addText('left', geo.x);
widthField = form.addText('width', geo.width);
heightField = form.addText('height', geo.height);
}
}
var tmp = model.getStyle(cell);
var style = form.addText('Style', tmp || '');
var attrs = value.attributes;
var texts = [];
for (var i = 0; i < attrs.length; i++)
{
var val = attrs[i].value;
texts[i] = form.addTextarea(attrs[i].nodeName, val,
(attrs[i].nodeName == 'label') ? 4 : 2);
}
var okFunction = mxUtils.bind(this, function()
{
this.hideProperties();
model.beginUpdate();
try
{
if (geo != null)
{
geo = geo.clone();
geo.x = parseFloat(xField.value);
geo.y = parseFloat(yField.value);
geo.width = parseFloat(widthField.value);
geo.height = parseFloat(heightField.value);
model.setGeometry(cell, geo);
}
if (style.value.length > 0)
{
model.setStyle(cell, style.value);
}
else
{
model.setStyle(cell, null);
}
for (var i=0; i<attrs.length; i++)
{
var edit = new mxCellAttributeChange(
cell, attrs[i].nodeName,
texts[i].value);
model.execute(edit);
}
if (this.graph.isAutoSizeCell(cell))
{
this.graph.updateCellSize(cell);
}
}
finally
{
model.endUpdate();
}
});
var cancelFunction = mxUtils.bind(this, function()
{
this.hideProperties();
});
form.addButtons(okFunction, cancelFunction);
return form.table;
}
return null;
};
mxEditor.prototype.hideProperties = function ()
{
if (this.properties != null)
{
this.properties.destroy();
this.properties = null;
}
};
mxEditor.prototype.showTasks = function ()
{
if (this.tasks == null)
{
var div = document.createElement('div');
div.style.padding = '4px';
div.style.paddingLeft = '20px';
var w = document.body.clientWidth;
var wnd = new mxWindow(
mxResources.get(this.tasksResource) ||
this.tasksResource,
div, w - 220, this.tasksTop, 200);
wnd.setClosable(true);
wnd.destroyOnClose = false;
var funct = mxUtils.bind(this, function(sender)
{
mxEvent.release(div);
div.innerHTML = '';
this.createTasks(div);
});
this.graph.getModel().addListener(mxEvent.CHANGE, funct);
this.graph.getSelectionModel().addListener(mxEvent.CHANGE, funct);
this.graph.addListener(mxEvent.ROOT, funct);
if (this.tasksWindowImage != null)
{
wnd.setImage(this.tasksWindowImage);
}
this.tasks = wnd;
this.createTasks(div);
}
this.tasks.setVisible(true);
};
mxEditor.prototype.refreshTasks = function (div)
{
if (this.tasks != null)
{
var div = this.tasks.content;
mxEvent.release(div);
div.innerHTML = '';
this.createTasks(div);
}
};
mxEditor.prototype.createTasks = function (div)
{
};
mxEditor.prototype.showHelp = function (tasks)
{
if (this.help == null)
{
var frame = document.createElement('iframe');
frame.setAttribute('src', mxResources.get('urlHelp') || this.urlHelp);
frame.setAttribute('height', '100%');
frame.setAttribute('width', '100%');
frame.setAttribute('frameBorder', '0');
frame.style.backgroundColor = 'white';
var w = document.body.clientWidth;
var h = (document.body.clientHeight || document.documentElement.clientHeight);
var wnd = new mxWindow(mxResources.get(this.helpResource) || this.helpResource,
frame, (w-this.helpWidth)/2, (h-this.helpHeight)/3, this.helpWidth, this.helpHeight);
wnd.setMaximizable(true);
wnd.setClosable(true);
wnd.destroyOnClose = false;
wnd.setResizable(true);
if (this.helpWindowImage != null)
{
wnd.setImage(this.helpWindowImage);
}
if (mxClient.IS_NS)
{
var handler = function(sender)
{
var h = wnd.div.offsetHeight;
frame.setAttribute('height', (h-26)+'px');
};
wnd.addListener(mxEvent.RESIZE_END, handler);
wnd.addListener(mxEvent.MAXIMIZE, handler);
wnd.addListener(mxEvent.NORMALIZE, handler);
wnd.addListener(mxEvent.SHOW, handler);
}
this.help = wnd;
}
this.help.setVisible(true);
};
mxEditor.prototype.showOutline = function ()
{
var create = this.outline == null;
if (create)
{
var div = document.createElement('div');
div.style.overflow = 'hidden';
div.style.position = 'relative';
div.style.width = '100%';
div.style.height = '100%';
div.style.background = 'white';
div.style.cursor = 'move';
if (document.documentMode == 8)
{
div.style.filter = 'progid:DXImageTransform.Microsoft.alpha(opacity=100)';
}
var wnd = new mxWindow(
mxResources.get(this.outlineResource) ||
this.outlineResource,
div, 600, 480, 200, 200, false);
var outline = new mxOutline(this.graph, div);
wnd.setClosable(true);
wnd.setResizable(true);
wnd.destroyOnClose = false;
wnd.addListener(mxEvent.RESIZE_END, function()
{
outline.update();
});
this.outline = wnd;
this.outline.outline = outline;
}
this.outline.setVisible(true);
this.outline.outline.update(true);
};
mxEditor.prototype.setMode = function(modename)
{
if (modename == 'select')
{
this.graph.panningHandler.useLeftButtonForPanning = false;
this.graph.setConnectable(false);
}
else if (modename == 'connect')
{
this.graph.panningHandler.useLeftButtonForPanning = false;
this.graph.setConnectable(true);
}
else if (modename == 'pan')
{
this.graph.panningHandler.useLeftButtonForPanning = true;
this.graph.setConnectable(false);
}
};
mxEditor.prototype.createPopupMenu = function (menu, cell, evt)
{
this.popupHandler.createMenu(this, menu, cell, evt);
};
mxEditor.prototype.createEdge = function (source, target)
{
var e = null;
if (this.defaultEdge != null)
{
var model = this.graph.getModel();
e = model.cloneCell(this.defaultEdge);
}
else
{
e = new mxCell('');
e.setEdge(true);
var geo = new mxGeometry();
geo.relative = true;
e.setGeometry(geo);
}
var style = this.getEdgeStyle();
if (style != null)
{
e.setStyle(style);
}
return e;
};
mxEditor.prototype.getEdgeStyle = function ()
{
return this.defaultEdgeStyle;
};
mxEditor.prototype.consumeCycleAttribute = function (cell)
{
return (this.cycleAttributeValues != null &&
this.cycleAttributeValues.length > 0 &&
this.graph.isSwimlane(cell)) ?
this.cycleAttributeValues[this.cycleAttributeIndex++ %
this.cycleAttributeValues.length] : null;
};
mxEditor.prototype.cycleAttribute = function (cell)
{
if (this.cycleAttributeName != null)
{
var value = this.consumeCycleAttribute(cell);
if (value != null)
{
cell.setStyle(cell.getStyle()+';'+
this.cycleAttributeName+'='+value);
}
}
};
mxEditor.prototype.addVertex = function (parent, vertex, x, y)
{
var model = this.graph.getModel();
while (parent != null && !this.graph.isValidDropTarget(parent))
{
parent = model.getParent(parent);
}
parent = (parent != null) ? parent : this.graph.getSwimlaneAt(x, y);
var scale = this.graph.getView().scale;
var geo = model.getGeometry(vertex);
var pgeo = model.getGeometry(parent);
if (this.graph.isSwimlane(vertex) &&
!this.graph.swimlaneNesting)
{
parent = null;
}
else if (parent == null && this.swimlaneRequired)
{
return null;
}
else if (parent != null && pgeo != null)
{
var state = this.graph.getView().getState(parent);
if (state != null)
{
x -= state.origin.x * scale;
y -= state.origin.y * scale;
if (this.graph.isConstrainedMoving)
{
var width = geo.width;
var height = geo.height;
var tmp = state.x+state.width;
if (x+width > tmp)
{
x -= x+width - tmp;
}
tmp = state.y+state.height;
if (y+height > tmp)
{
y -= y+height - tmp;
}
}
}
else if (pgeo != null)
{
x -= pgeo.x*scale;
y -= pgeo.y*scale;
}
}
geo = geo.clone();
geo.x = this.graph.snap(x / scale -
this.graph.getView().translate.x -
this.graph.gridSize/2);
geo.y = this.graph.snap(y / scale -
this.graph.getView().translate.y -
this.graph.gridSize/2);
vertex.setGeometry(geo);
if (parent == null)
{
parent = this.graph.getDefaultParent();
}
this.cycleAttribute(vertex);
this.fireEvent(new mxEventObject(mxEvent.BEFORE_ADD_VERTEX,
'vertex', vertex, 'parent', parent));
model.beginUpdate();
try
{
vertex = this.graph.addCell(vertex, parent);
if (vertex != null)
{
this.graph.constrainChild(vertex);
this.fireEvent(new mxEventObject(mxEvent.ADD_VERTEX, 'vertex', vertex));
}
}
finally
{
model.endUpdate();
}
if (vertex != null)
{
this.graph.setSelectionCell(vertex);
this.graph.scrollCellToVisible(vertex);
this.fireEvent(new mxEventObject(mxEvent.AFTER_ADD_VERTEX, 'vertex', vertex));
}
return vertex;
};
mxEditor.prototype.destroy = function ()
{
if (!this.destroyed)
{
this.destroyed = true;
if (this.tasks != null)
{
this.tasks.destroy();
}
if (this.outline != null)
{
this.outline.destroy();
}
if (this.properties != null)
{
this.properties.destroy();
}
if (this.keyHandler != null)
{
this.keyHandler.destroy();
}
if (this.rubberband != null)
{
this.rubberband.destroy();
}
if (this.toolbar != null)
{
this.toolbar.destroy();
}
if (this.graph != null)
{
this.graph.destroy();
}
this.status = null;
this.templates = null;
}
};
__mxOutput.mxEditor = typeof mxEditor !== 'undefined' ? mxEditor : undefined;
var mxCodecRegistry =
{
codecs: [],
aliases: [],
register: function(codec)
{
if (codec != null)
{
var name = codec.getName();
mxCodecRegistry.codecs[name] = codec;
var classname = mxUtils.getFunctionName(codec.template.constructor);
if (classname != name)
{
mxCodecRegistry.addAlias(classname, name);
}
}
return codec;
},
addAlias: function(classname, codecname)
{
mxCodecRegistry.aliases[classname] = codecname;
},
getCodec: function(ctor)
{
var codec = null;
if (ctor != null)
{
var name = mxUtils.getFunctionName(ctor);
var tmp = mxCodecRegistry.aliases[name];
if (tmp != null)
{
name = tmp;
}
codec = mxCodecRegistry.codecs[name];
if (codec == null)
{
try
{
codec = new mxObjectCodec(new ctor());
mxCodecRegistry.register(codec);
}
catch (e)
{
}
}
}
return codec;
}
};
__mxOutput.mxCodecRegistry = typeof mxCodecRegistry !== 'undefined' ? mxCodecRegistry : undefined;
function mxCodec(document)
{
this.document = document || mxUtils.createXmlDocument();
this.objects = [];
} mxCodec.prototype.document = null;
mxCodec.prototype.objects = null;
mxCodec.prototype.elements = null;
mxCodec.prototype.encodeDefaults = false;
mxCodec.prototype.putObject = function(id, obj)
{
this.objects[id] = obj;
return obj;
};
mxCodec.prototype.getObject = function(id)
{
var obj = null;
if (id != null)
{
obj = this.objects[id];
if (obj == null)
{
obj = this.lookup(id);
if (obj == null)
{
var node = this.getElementById(id);
if (node != null)
{
obj = this.decode(node);
}
}
}
}
return obj;
};
mxCodec.prototype.lookup = function(id)
{
return null;
};
mxCodec.prototype.getElementById = function(id)
{
this.updateElements();
return this.elements[id];
};
mxCodec.prototype.updateElements = function()
{
if (this.elements == null)
{
this.elements = new Object();
if (this.document.documentElement != null)
{
this.addElement(this.document.documentElement);
}
}
};
mxCodec.prototype.addElement = function(node)
{
if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
{
var id = node.getAttribute('id');
if (id != null)
{
if (this.elements[id] == null)
{
this.elements[id] = node;
}
else if (this.elements[id] != node)
{
throw new Error(id + ': Duplicate ID');
}
}
}
node = node.firstChild;
while (node != null)
{
this.addElement(node);
node = node.nextSibling;
}
};
mxCodec.prototype.getId = function(obj)
{
var id = null;
if (obj != null)
{
id = this.reference(obj);
if (id == null && obj instanceof mxCell)
{
id = obj.getId();
if (id == null)
{
id = mxCellPath.create(obj);
if (id.length == 0)
{
id = 'root';
}
}
}
}
return id;
};
mxCodec.prototype.reference = function(obj)
{
return null;
};
mxCodec.prototype.encode = function(obj)
{
var node = null;
if (obj != null && obj.constructor != null)
{
var enc = mxCodecRegistry.getCodec(obj.constructor);
if (enc != null)
{
node = enc.encode(this, obj);
}
else
{
if (mxUtils.isNode(obj))
{
node = mxUtils.importNode(this.document, obj, true);
}
else
{
mxLog.warn('mxCodec.encode: No codec for ' + mxUtils.getFunctionName(obj.constructor));
}
}
}
return node;
};
mxCodec.prototype.decode = function(node, into)
{
this.updateElements();
var obj = null;
if (node != null && node.nodeType == mxConstants.NODETYPE_ELEMENT)
{
var ctor = null;
try
{
ctor = window[node.nodeName];
}
catch (err)
{
}
var dec = mxCodecRegistry.getCodec(ctor);
if (dec != null)
{
obj = dec.decode(this, node, into);
}
else
{
obj = node.cloneNode(true);
obj.removeAttribute('as');
}
}
return obj;
};
mxCodec.prototype.encodeCell = function(cell, node, includeChildren)
{
node.appendChild(this.encode(cell));
if (includeChildren == null || includeChildren)
{
var childCount = cell.getChildCount();
for (var i = 0; i < childCount; i++)
{
this.encodeCell(cell.getChildAt(i), node);
}
}
};
mxCodec.prototype.isCellCodec = function(codec)
{
if (codec != null && typeof(codec.isCellCodec) == 'function')
{
return codec.isCellCodec();
}
return false;
};
mxCodec.prototype.decodeCell = function(node, restoreStructures)
{
restoreStructures = (restoreStructures != null) ? restoreStructures : true;
var cell = null;
if (node != null && node.nodeType == mxConstants.NODETYPE_ELEMENT)
{
var decoder = mxCodecRegistry.getCodec(node.nodeName);
if (!this.isCellCodec(decoder))
{
var child = node.firstChild;
while (child != null && !this.isCellCodec(decoder))
{
decoder = mxCodecRegistry.getCodec(child.nodeName);
child = child.nextSibling;
}
}
if (!this.isCellCodec(decoder))
{
decoder = mxCodecRegistry.getCodec(mxCell);
}
cell = decoder.decode(this, node);
if (restoreStructures)
{
this.insertIntoGraph(cell);
}
}
return cell;
};
mxCodec.prototype.insertIntoGraph = function(cell)
{
var parent = cell.parent;
var source = cell.getTerminal(true);
var target = cell.getTerminal(false);
cell.setTerminal(null, false);
cell.setTerminal(null, true);
cell.parent = null;
if (parent != null)
{
if (parent == cell)
{
throw new Error(parent.id + ': Self Reference');
}
else
{
parent.insert(cell);
}
}
if (source != null)
{
source.insertEdge(cell, true);
}
if (target != null)
{
target.insertEdge(cell, false);
}
};
mxCodec.prototype.setAttribute = function(node, attribute, value)
{
if (attribute != null && value != null)
{
node.setAttribute(attribute, value);
}
};
__mxOutput.mxCodec = typeof mxCodec !== 'undefined' ? mxCodec : undefined;
function mxObjectCodec(template, exclude, idrefs, mapping)
{
this.template = template;
this.exclude = (exclude != null) ? exclude : [];
this.idrefs = (idrefs != null) ? idrefs : [];
this.mapping = (mapping != null) ? mapping : [];
this.reverse = new Object();
for (var i in this.mapping)
{
this.reverse[this.mapping[i]] = i;
}
} mxObjectCodec.allowEval = false;
mxObjectCodec.prototype.template = null;
mxObjectCodec.prototype.exclude = null;
mxObjectCodec.prototype.idrefs = null;
mxObjectCodec.prototype.mapping = null;
mxObjectCodec.prototype.reverse = null;
mxObjectCodec.prototype.getName = function()
{
return mxUtils.getFunctionName(this.template.constructor);
};
mxObjectCodec.prototype.cloneTemplate = function()
{
return new this.template.constructor();
};
mxObjectCodec.prototype.getFieldName = function(attributename)
{
if (attributename != null)
{
var mapped = this.reverse[attributename];
if (mapped != null)
{
attributename = mapped;
}
}
return attributename;
};
mxObjectCodec.prototype.getAttributeName = function(fieldname)
{
if (fieldname != null)
{
var mapped = this.mapping[fieldname];
if (mapped != null)
{
fieldname = mapped;
}
}
return fieldname;
};
mxObjectCodec.prototype.isExcluded = function(obj, attr, value, write)
{
return attr == mxObjectIdentity.FIELD_NAME ||
mxUtils.indexOf(this.exclude, attr) >= 0;
};
mxObjectCodec.prototype.isReference = function(obj, attr, value, write)
{
return mxUtils.indexOf(this.idrefs, attr) >= 0;
};
mxObjectCodec.prototype.encode = function(enc, obj)
{
var node = enc.document.createElement(this.getName());
obj = this.beforeEncode(enc, obj, node);
this.encodeObject(enc, obj, node);
return this.afterEncode(enc, obj, node);
};
mxObjectCodec.prototype.encodeObject = function(enc, obj, node)
{
enc.setAttribute(node, 'id', enc.getId(obj));
for (var i in obj)
{
var name = i;
var value = obj[name];
if (value != null && !this.isExcluded(obj, name, value, true))
{
if (mxUtils.isInteger(name))
{
name = null;
}
this.encodeValue(enc, obj, name, value, node);
}
}
};
mxObjectCodec.prototype.encodeValue = function(enc, obj, name, value, node)
{
if (value != null)
{
if (this.isReference(obj, name, value, true))
{
var tmp = enc.getId(value);
if (tmp == null)
{
mxLog.warn('mxObjectCodec.encode: No ID for ' +
this.getName() + '.' + name + '=' + value);
return;
}
value = tmp;
}
var defaultValue = this.template[name];
if (name == null || enc.encodeDefaults || defaultValue != value)
{
name = this.getAttributeName(name);
this.writeAttribute(enc, obj, name, value, node);
}
}
};
mxObjectCodec.prototype.writeAttribute = function(enc, obj, name, value, node)
{
if (typeof(value) != 'object' )
{
this.writePrimitiveAttribute(enc, obj, name, value, node);
}
else
{
this.writeComplexAttribute(enc, obj, name, value, node);
}
};
mxObjectCodec.prototype.writePrimitiveAttribute = function(enc, obj, name, value, node)
{
value = this.convertAttributeToXml(enc, obj, name, value, node);
if (name == null)
{
var child = enc.document.createElement('add');
if (typeof(value) == 'function')
{
child.appendChild(enc.document.createTextNode(value));
}
else
{
enc.setAttribute(child, 'value', value);
}
node.appendChild(child);
}
else if (typeof(value) != 'function')
{
enc.setAttribute(node, name, value);
}
};
mxObjectCodec.prototype.writeComplexAttribute = function(enc, obj, name, value, node)
{
var child = enc.encode(value);
if (child != null)
{
if (name != null)
{
child.setAttribute('as', name);
}
node.appendChild(child);
}
else
{
mxLog.warn('mxObjectCodec.encode: No node for ' + this.getName() + '.' + name + ': ' + value);
}
};
mxObjectCodec.prototype.convertAttributeToXml = function(enc, obj, name, value)
{
if (this.isBooleanAttribute(enc, obj, name, value))
{
value = (value == true) ? '1' : '0';
}
return value;
};
mxObjectCodec.prototype.isBooleanAttribute = function(enc, obj, name, value)
{
return (typeof(value.length) == 'undefined' && (value == true || value == false));
};
mxObjectCodec.prototype.convertAttributeFromXml = function(dec, attr, obj)
{
var value = attr.value;
if (this.isNumericAttribute(dec, attr, obj))
{
value = parseFloat(value);
if (isNaN(value) || !isFinite(value))
{
value = 0;
}
}
return value;
};
mxObjectCodec.prototype.isNumericAttribute = function(dec, attr, obj)
{
var result = (obj.constructor == mxGeometry &&
(attr.name == 'x' || attr.name == 'y' ||
attr.name == 'width' || attr.name == 'height')) ||
(obj.constructor == mxPoint &&
(attr.name == 'x' || attr.name == 'y')) ||
mxUtils.isNumeric(attr.value);
return result;
};
mxObjectCodec.prototype.beforeEncode = function(enc, obj, node)
{
return obj;
};
mxObjectCodec.prototype.afterEncode = function(enc, obj, node)
{
return node;
};
mxObjectCodec.prototype.decode = function(dec, node, into)
{
var id = node.getAttribute('id');
var obj = dec.objects[id];
if (obj == null)
{
obj = into || this.cloneTemplate();
if (id != null)
{
dec.putObject(id, obj);
}
}
node = this.beforeDecode(dec, node, obj);
this.decodeNode(dec, node, obj);
return this.afterDecode(dec, node, obj);
};
mxObjectCodec.prototype.decodeNode = function(dec, node, obj)
{
if (node != null)
{
this.decodeAttributes(dec, node, obj);
this.decodeChildren(dec, node, obj);
}
};
mxObjectCodec.prototype.decodeAttributes = function(dec, node, obj)
{
var attrs = node.attributes;
if (attrs != null)
{
for (var i = 0; i < attrs.length; i++)
{
this.decodeAttribute(dec, attrs[i], obj);
}
}
};
mxObjectCodec.prototype.isIgnoredAttribute = function(dec, attr, obj)
{
return attr.nodeName == 'as' || attr.nodeName == 'id';
};
mxObjectCodec.prototype.decodeAttribute = function(dec, attr, obj)
{
if (!this.isIgnoredAttribute(dec, attr, obj))
{
var name = attr.nodeName;
var value = this.convertAttributeFromXml(dec, attr, obj);
var fieldname = this.getFieldName(name);
if (this.isReference(obj, fieldname, value, false))
{
var tmp = dec.getObject(value);
if (tmp == null)
{
mxLog.warn('mxObjectCodec.decode: No object for ' +
this.getName() + '.' + name + '=' + value);
return;
}
value = tmp;
}
if (!this.isExcluded(obj, name, value, false))
{
obj[name] = value;
}
}
};
mxObjectCodec.prototype.decodeChildren = function(dec, node, obj)
{
var child = node.firstChild;
while (child != null)
{
var tmp = child.nextSibling;
if (child.nodeType == mxConstants.NODETYPE_ELEMENT &&
!this.processInclude(dec, child, obj))
{
this.decodeChild(dec, child, obj);
}
child = tmp;
}
};
mxObjectCodec.prototype.decodeChild = function(dec, child, obj)
{
var fieldname = this.getFieldName(child.getAttribute('as'));
if (fieldname == null || !this.isExcluded(obj, fieldname, child, false))
{
var template = this.getFieldTemplate(obj, fieldname, child);
var value = null;
if (child.nodeName == 'add')
{
value = child.getAttribute('value');
if (value == null && mxObjectCodec.allowEval)
{
value = mxUtils.eval(mxUtils.getTextContent(child));
}
}
else
{
value = dec.decode(child, template);
}
try
{
this.addObjectValue(obj, fieldname, value, template);
}
catch (e)
{
throw new Error(e.message + ' for ' + child.nodeName);
}
}
};
mxObjectCodec.prototype.getFieldTemplate = function(obj, fieldname, child)
{
var template = obj[fieldname];
if (template instanceof Array && template.length > 0)
{
template = null;
}
return template;
};
mxObjectCodec.prototype.addObjectValue = function(obj, fieldname, value, template)
{
if (value != null && value != template)
{
if (fieldname != null && fieldname.length > 0)
{
obj[fieldname] = value;
}
else
{
obj.push(value);
}
}
};
mxObjectCodec.prototype.processInclude = function(dec, node, into)
{
if (node.nodeName == 'include')
{
var name = node.getAttribute('name');
if (name != null)
{
try
{
var xml = mxUtils.load(name).getDocumentElement();
if (xml != null)
{
dec.decode(xml, into);
}
}
catch (e)
{
}
}
return true;
}
return false;
};
mxObjectCodec.prototype.beforeDecode = function(dec, node, obj)
{
return node;
};
mxObjectCodec.prototype.afterDecode = function(dec, node, obj)
{
return obj;
};
__mxOutput.mxObjectCodec = typeof mxObjectCodec !== 'undefined' ? mxObjectCodec : undefined;
mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxCell(),
['children', 'edges', 'overlays', 'mxTransient'],
['parent', 'source', 'target']);
codec.isCellCodec = function()
{
return true;
};
codec.isNumericAttribute = function(dec, attr, obj)
{
return attr.nodeName !== 'value' && mxObjectCodec.prototype.isNumericAttribute.apply(this, arguments);
};
codec.isExcluded = function(obj, attr, value, isWrite)
{
return mxObjectCodec.prototype.isExcluded.apply(this, arguments) ||
(isWrite && attr == 'value' &&
value.nodeType == mxConstants.NODETYPE_ELEMENT);
};
codec.afterEncode = function(enc, obj, node)
{
if (obj.value != null && obj.value.nodeType == mxConstants.NODETYPE_ELEMENT)
{
var tmp = node;
node = mxUtils.importNode(enc.document, obj.value, true);
node.appendChild(tmp);
var id = tmp.getAttribute('id');
node.setAttribute('id', id);
tmp.removeAttribute('id');
}
return node;
};
codec.beforeDecode = function(dec, node, obj)
{
var inner = node.cloneNode(true);
var classname = this.getName();
if (node.nodeName != classname)
{
var tmp = node.getElementsByTagName(classname)[0];
if (tmp != null && tmp.parentNode == node)
{
mxUtils.removeWhitespace(tmp, true);
mxUtils.removeWhitespace(tmp, false);
tmp.parentNode.removeChild(tmp);
inner = tmp;
}
else
{
inner = null;
}
obj.value = node.cloneNode(true);
var id = obj.value.getAttribute('id');
if (id != null)
{
obj.setId(id);
obj.value.removeAttribute('id');
}
}
else
{
obj.setId(node.getAttribute('id'));
}
if (inner != null)
{
for (var i = 0; i < this.idrefs.length; i++)
{
var attr = this.idrefs[i];
var ref = inner.getAttribute(attr);
if (ref != null)
{
inner.removeAttribute(attr);
var object = dec.objects[ref] || dec.lookup(ref);
if (object == null)
{
var element = dec.getElementById(ref);
if (element != null)
{
var decoder = mxCodecRegistry.codecs[element.nodeName] || this;
object = decoder.decode(dec, element);
}
}
obj[attr] = object;
}
}
}
return inner;
};
return codec;
}());
__mxOutput.mxCellCodec = typeof mxCellCodec !== 'undefined' ? mxCellCodec : undefined;
mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxGraphModel());
codec.encodeObject = function(enc, obj, node)
{
var rootNode = enc.document.createElement('root');
enc.encodeCell(obj.getRoot(), rootNode);
node.appendChild(rootNode);
};
codec.decodeChild = function(dec, child, obj)
{
if (child.nodeName == 'root')
{
this.decodeRoot(dec, child, obj);
}
else
{
mxObjectCodec.prototype.decodeChild.apply(this, arguments);
}
};
codec.decodeRoot = function(dec, root, model)
{
var rootCell = null;
var tmp = root.firstChild;
while (tmp != null)
{
var cell = dec.decodeCell(tmp);
if (cell != null && cell.getParent() == null)
{
rootCell = cell;
}
tmp = tmp.nextSibling;
}
if (rootCell != null)
{
model.setRoot(rootCell);
}
};
return codec;
}());
__mxOutput.mxModelCodec = typeof mxModelCodec !== 'undefined' ? mxModelCodec : undefined;
mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxRootChange(),
['model', 'previous', 'root']);
codec.afterEncode = function(enc, obj, node)
{
enc.encodeCell(obj.root, node);
return node;
};
codec.beforeDecode = function(dec, node, obj)
{
if (node.firstChild != null &&
node.firstChild.nodeType == mxConstants.NODETYPE_ELEMENT)
{
node = node.cloneNode(true);
var tmp = node.firstChild;
obj.root = dec.decodeCell(tmp, false);
var tmp2 = tmp.nextSibling;
tmp.parentNode.removeChild(tmp);
tmp = tmp2;
while (tmp != null)
{
tmp2 = tmp.nextSibling;
dec.decodeCell(tmp);
tmp.parentNode.removeChild(tmp);
tmp = tmp2;
}
}
return node;
};
codec.afterDecode = function(dec, node, obj)
{
obj.previous = obj.root;
return obj;
};
return codec;
}());
__mxOutput.mxRootChangeCodec = typeof mxRootChangeCodec !== 'undefined' ? mxRootChangeCodec : undefined;
mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxChildChange(),
['model', 'child', 'previousIndex'],
['parent', 'previous']);
codec.isReference = function(obj, attr, value, isWrite)
{
if (attr == 'child' && (!isWrite || obj.model.contains(obj.previous)))
{
return true;
}
return mxUtils.indexOf(this.idrefs, attr) >= 0;
};
codec.isExcluded = function(obj, attr, value, write)
{
return mxObjectCodec.prototype.isExcluded.apply(this, arguments) ||
(write && value != null && (attr == 'previous' ||
attr == 'parent') && !obj.model.contains(value));
};
codec.afterEncode = function(enc, obj, node)
{
if (this.isReference(obj, 'child', obj.child, true))
{
node.setAttribute('child', enc.getId(obj.child));
}
else
{
enc.encodeCell(obj.child, node);
}
return node;
};
codec.beforeDecode = function(dec, node, obj)
{
if (node.firstChild != null &&
node.firstChild.nodeType == mxConstants.NODETYPE_ELEMENT)
{
node = node.cloneNode(true);
var tmp = node.firstChild;
obj.child = dec.decodeCell(tmp, false);
var tmp2 = tmp.nextSibling;
tmp.parentNode.removeChild(tmp);
tmp = tmp2;
while (tmp != null)
{
tmp2 = tmp.nextSibling;
if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT)
{
var id = tmp.getAttribute('id');
if (dec.lookup(id) == null)
{
dec.decodeCell(tmp);
}
}
tmp.parentNode.removeChild(tmp);
tmp = tmp2;
}
}
else
{
var childRef = node.getAttribute('child');
obj.child = dec.getObject(childRef);
}
return node;
};
codec.afterDecode = function(dec, node, obj)
{
if (obj.child != null)
{
if (obj.child.parent != null && obj.previous != null &&
obj.child.parent != obj.previous)
{
obj.previous = obj.child.parent;
}
obj.child.parent = obj.previous;
obj.previous = obj.parent;
obj.previousIndex = obj.index;
}
return obj;
};
return codec;
}());
__mxOutput.mxChildChangeCodec = typeof mxChildChangeCodec !== 'undefined' ? mxChildChangeCodec : undefined;
mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxTerminalChange(),
['model', 'previous'], ['cell', 'terminal']);
codec.afterDecode = function(dec, node, obj)
{
obj.previous = obj.terminal;
return obj;
};
return codec;
}());
__mxOutput.mxTerminalChangeCodec = typeof mxTerminalChangeCodec !== 'undefined' ? mxTerminalChangeCodec : undefined;
var mxGenericChangeCodec = function(obj, variable)
{
var codec = new mxObjectCodec(obj, ['model', 'previous'], ['cell']);
codec.afterDecode = function(dec, node, obj)
{
if (mxUtils.isNode(obj.cell))
{
obj.cell = dec.decodeCell(obj.cell, false);
}
obj.previous = obj[variable];
return obj;
};
return codec;
};
mxCodecRegistry.register(mxGenericChangeCodec(new mxValueChange(), 'value'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxStyleChange(), 'style'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxGeometryChange(), 'geometry'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxCollapseChange(), 'collapsed'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxVisibleChange(), 'visible'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxCellAttributeChange(), 'value'));
__mxOutput.mxGenericChangeCodec = typeof mxGenericChangeCodec !== 'undefined' ? mxGenericChangeCodec : undefined;
mxCodecRegistry.register(function()
{
return new mxObjectCodec(new mxGraph(),
['graphListeners', 'eventListeners', 'view', 'container',
'cellRenderer', 'editor', 'selection']);
}());
__mxOutput.mxGraphCodec = typeof mxGraphCodec !== 'undefined' ? mxGraphCodec : undefined;
mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxGraphView());
codec.encode = function(enc, view)
{
return this.encodeCell(enc, view,
view.graph.getModel().getRoot());
};
codec.encodeCell = function(enc, view, cell)
{
var model = view.graph.getModel();
var state = view.getState(cell);
var parent = model.getParent(cell);
if (parent == null || state != null)
{
var childCount = model.getChildCount(cell);
var geo = view.graph.getCellGeometry(cell);
var name = null;
if (parent == model.getRoot())
{
name = 'layer';
}
else if (parent == null)
{
name = 'graph';
}
else if (model.isEdge(cell))
{
name = 'edge';
}
else if (childCount > 0 && geo != null)
{
name = 'group';
}
else if (model.isVertex(cell))
{
name = 'vertex';
}
if (name != null)
{
var node = enc.document.createElement(name);
var lab = view.graph.getLabel(cell);
if (lab != null)
{
node.setAttribute('label', view.graph.getLabel(cell));
if (view.graph.isHtmlLabel(cell))
{
node.setAttribute('html', true);
}
}
if (parent == null)
{
var bounds = view.getGraphBounds();
if (bounds != null)
{
node.setAttribute('x', Math.round(bounds.x));
node.setAttribute('y', Math.round(bounds.y));
node.setAttribute('width', Math.round(bounds.width));
node.setAttribute('height', Math.round(bounds.height));
}
node.setAttribute('scale', view.scale);
}
else if (state != null && geo != null)
{
for (var i in state.style)
{
var value = state.style[i];
if (typeof(value) == 'function' &&
typeof(value) == 'object')
{
value = mxStyleRegistry.getName(value);
}
if (value != null &&
typeof(value) != 'function' &&
typeof(value) != 'object')
{
node.setAttribute(i, value);
}
}
var abs = state.absolutePoints;
if (abs != null && abs.length > 0)
{
var pts = Math.round(abs[0].x) + ',' + Math.round(abs[0].y);
for (var i=1; i<abs.length; i++)
{
pts += ' ' + Math.round(abs[i].x) + ',' +
Math.round(abs[i].y);
}
node.setAttribute('points', pts);
}
else
{
node.setAttribute('x', Math.round(state.x));
node.setAttribute('y', Math.round(state.y));
node.setAttribute('width', Math.round(state.width));
node.setAttribute('height', Math.round(state.height));
}
var offset = state.absoluteOffset;
if (offset != null)
{
if (offset.x != 0)
{
node.setAttribute('dx', Math.round(offset.x));
}
if (offset.y != 0)
{
node.setAttribute('dy', Math.round(offset.y));
}
}
}
for (var i=0; i<childCount; i++)
{
var childNode = this.encodeCell(enc,
view, model.getChildAt(cell, i));
if (childNode != null)
{
node.appendChild(childNode);
}
}
}
}
return node;
};
return codec;
}());
__mxOutput.mxGraphViewCodec = typeof mxGraphViewCodec !== 'undefined' ? mxGraphViewCodec : undefined;
var mxStylesheetCodec = mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxStylesheet());
codec.encode = function(enc, obj)
{
var node = enc.document.createElement(this.getName());
for (var i in obj.styles)
{
var style = obj.styles[i];
var styleNode = enc.document.createElement('add');
if (i != null)
{
styleNode.setAttribute('as', i);
for (var j in style)
{
var value = this.getStringValue(j, style[j]);
if (value != null)
{
var entry = enc.document.createElement('add');
entry.setAttribute('value', value);
entry.setAttribute('as', j);
styleNode.appendChild(entry);
}
}
if (styleNode.childNodes.length > 0)
{
node.appendChild(styleNode);
}
}
}
return node;
};
codec.getStringValue = function(key, value)
{
var type = typeof(value);
if (type == 'function')
{
value = mxStyleRegistry.getName(value);
}
else if (type == 'object')
{
value = null;
}
return value;
};
codec.decode = function(dec, node, into)
{
var obj = into || new this.template.constructor();
var id = node.getAttribute('id');
if (id != null)
{
dec.objects[id] = obj;
}
node = node.firstChild;
while (node != null)
{
if (!this.processInclude(dec, node, obj) && node.nodeName == 'add')
{
var as = node.getAttribute('as');
if (as != null)
{
var extend = node.getAttribute('extend');
var style = (extend != null) ? mxUtils.clone(obj.styles[extend]) : null;
if (style == null)
{
if (extend != null)
{
mxLog.warn('mxStylesheetCodec.decode: stylesheet ' +
extend + ' not found to extend');
}
style = new Object();
}
var entry = node.firstChild;
while (entry != null)
{
if (entry.nodeType == mxConstants.NODETYPE_ELEMENT)
{
var key = entry.getAttribute('as');
if (entry.nodeName == 'add')
{
var text = mxUtils.getTextContent(entry);
var value = null;
if (text != null && text.length > 0 && mxStylesheetCodec.allowEval)
{
value = mxUtils.eval(text);
}
else
{
value = entry.getAttribute('value');
if (mxUtils.isNumeric(value))
{
value = parseFloat(value);
}
}
if (value != null)
{
style[key] = value;
}
}
else if (entry.nodeName == 'remove')
{
delete style[key];
}
}
entry = entry.nextSibling;
}
obj.putCellStyle(as, style);
}
}
node = node.nextSibling;
}
return obj;
};
return codec;
}());
mxStylesheetCodec.allowEval = true;
__mxOutput.mxStylesheetCodec = typeof mxStylesheetCodec !== 'undefined' ? mxStylesheetCodec : undefined;
mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxDefaultKeyHandler());
codec.encode = function(enc, obj)
{
return null;
};
codec.decode = function(dec, node, into)
{
if (into != null)
{
into.editor;
node = node.firstChild;
while (node != null)
{
if (!this.processInclude(dec, node, into) &&
node.nodeName == 'add')
{
var as = node.getAttribute('as');
var action = node.getAttribute('action');
var control = node.getAttribute('control');
into.bindAction(as, action, control);
}
node = node.nextSibling;
}
}
return into;
};
return codec;
}());
__mxOutput.mxDefaultKeyHandlerCodec = typeof mxDefaultKeyHandlerCodec !== 'undefined' ? mxDefaultKeyHandlerCodec : undefined;
var mxDefaultToolbarCodec = mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxDefaultToolbar());
codec.encode = function(enc, obj)
{
return null;
};
codec.decode = function(dec, node, into)
{
if (into != null)
{
var editor = into.editor;
node = node.firstChild;
while (node != null)
{
if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
{
if (!this.processInclude(dec, node, into))
{
if (node.nodeName == 'separator')
{
into.addSeparator();
}
else if (node.nodeName == 'br')
{
into.toolbar.addBreak();
}
else if (node.nodeName == 'hr')
{
into.toolbar.addLine();
}
else if (node.nodeName == 'add')
{
var as = node.getAttribute('as');
as = mxResources.get(as) || as;
var icon = node.getAttribute('icon');
var pressedIcon = node.getAttribute('pressedIcon');
var action = node.getAttribute('action');
var mode = node.getAttribute('mode');
var template = node.getAttribute('template');
var toggle = node.getAttribute('toggle') != '0';
var text = mxUtils.getTextContent(node);
var elt = null;
if (action != null)
{
elt = into.addItem(as, icon, action, pressedIcon);
}
else if (mode != null)
{
var funct = (mxDefaultToolbarCodec.allowEval) ? mxUtils.eval(text) : null;
elt = into.addMode(as, icon, mode, pressedIcon, funct);
}
else if (template != null || (text != null && text.length > 0))
{
var cell = editor.templates[template];
var style = node.getAttribute('style');
if (cell != null && style != null)
{
cell = editor.graph.cloneCell(cell);
cell.setStyle(style);
}
var insertFunction = null;
if (text != null && text.length > 0 && mxDefaultToolbarCodec.allowEval)
{
insertFunction = mxUtils.eval(text);
}
elt = into.addPrototype(as, icon, cell, pressedIcon, insertFunction, toggle);
}
else
{
var children = mxUtils.getChildNodes(node);
if (children.length > 0)
{
if (icon == null)
{
var combo = into.addActionCombo(as);
for (var i=0; i<children.length; i++)
{
var child = children[i];
if (child.nodeName == 'separator')
{
into.addOption(combo, '---');
}
else if (child.nodeName == 'add')
{
var lab = child.getAttribute('as');
var act = child.getAttribute('action');
into.addActionOption(combo, lab, act);
}
}
}
else
{
var select = null;
var create = function()
{
var template = editor.templates[select.value];
if (template != null)
{
var clone = template.clone();
var style = select.options[select.selectedIndex].cellStyle;
if (style != null)
{
clone.setStyle(style);
}
return clone;
}
else
{
mxLog.warn('Template '+template+' not found');
}
return null;
};
var img = into.addPrototype(as, icon, create, null, null, toggle);
select = into.addCombo();
mxEvent.addListener(select, 'change', function()
{
into.toolbar.selectMode(img, function(evt)
{
var pt = mxUtils.convertPoint(editor.graph.container,
mxEvent.getClientX(evt), mxEvent.getClientY(evt));
return editor.addVertex(null, funct(), pt.x, pt.y);
});
into.toolbar.noReset = false;
});
for (var i=0; i<children.length; i++)
{
var child = children[i];
if (child.nodeName == 'separator')
{
into.addOption(select, '---');
}
else if (child.nodeName == 'add')
{
var lab = child.getAttribute('as');
var tmp = child.getAttribute('template');
var option = into.addOption(select, lab, tmp || template);
option.cellStyle = child.getAttribute('style');
}
}
}
}
}
if (elt != null)
{
var id = node.getAttribute('id');
if (id != null && id.length > 0)
{
elt.setAttribute('id', id);
}
}
}
}
}
node = node.nextSibling;
}
}
return into;
};
return codec;
}());
mxDefaultToolbarCodec.allowEval = true;
__mxOutput.mxDefaultToolbarCodec = typeof mxDefaultToolbarCodec !== 'undefined' ? mxDefaultToolbarCodec : undefined;
mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxDefaultPopupMenu());
codec.encode = function(enc, obj)
{
return null;
};
codec.decode = function(dec, node, into)
{
var inc = node.getElementsByTagName('include')[0];
if (inc != null)
{
this.processInclude(dec, inc, into);
}
else if (into != null)
{
into.config = node;
}
return into;
};
return codec;
}());
__mxOutput.mxDefaultPopupMenuCodec = typeof mxDefaultPopupMenuCodec !== 'undefined' ? mxDefaultPopupMenuCodec : undefined;
mxCodecRegistry.register(function()
{
var codec = new mxObjectCodec(new mxEditor(),
['modified', 'lastSnapshot', 'ignoredChanges',
'undoManager', 'graphContainer', 'toolbarContainer']);
codec.afterDecode = function(dec, node, obj)
{
var defaultEdge = node.getAttribute('defaultEdge');
if (defaultEdge != null)
{
node.removeAttribute('defaultEdge');
obj.defaultEdge = obj.templates[defaultEdge];
}
var defaultGroup = node.getAttribute('defaultGroup');
if (defaultGroup != null)
{
node.removeAttribute('defaultGroup');
obj.defaultGroup = obj.templates[defaultGroup];
}
return obj;
};
codec.decodeChild = function(dec, child, obj)
{
if (child.nodeName == 'Array')
{
var role = child.getAttribute('as');
if (role == 'templates')
{
this.decodeTemplates(dec, child, obj);
return;
}
}
else if (child.nodeName == 'ui')
{
this.decodeUi(dec, child, obj);
return;
}
mxObjectCodec.prototype.decodeChild.apply(this, arguments);
};
codec.decodeUi = function(dec, node, editor)
{
var tmp = node.firstChild;
while (tmp != null)
{
if (tmp.nodeName == 'add')
{
var as = tmp.getAttribute('as');
var elt = tmp.getAttribute('element');
var style = tmp.getAttribute('style');
var element = null;
if (elt != null)
{
element = document.getElementById(elt);
if (element != null && style != null)
{
element.style.cssText += ';' + style;
}
}
else
{
var x = parseInt(tmp.getAttribute('x'));
var y = parseInt(tmp.getAttribute('y'));
var width = tmp.getAttribute('width');
var height = tmp.getAttribute('height');
element = document.createElement('div');
element.style.cssText = style;
var wnd = new mxWindow(mxResources.get(as) || as,
element, x, y, width, height, false, true);
wnd.setVisible(true);
}
if (as == 'graph')
{
editor.setGraphContainer(element);
}
else if (as == 'toolbar')
{
editor.setToolbarContainer(element);
}
else if (as == 'title')
{
editor.setTitleContainer(element);
}
else if (as == 'status')
{
editor.setStatusContainer(element);
}
else if (as == 'map')
{
editor.setMapContainer(element);
}
}
else if (tmp.nodeName == 'resource')
{
mxResources.add(tmp.getAttribute('basename'));
}
else if (tmp.nodeName == 'stylesheet')
{
mxClient.link('stylesheet', tmp.getAttribute('name'));
}
tmp = tmp.nextSibling;
}
};
codec.decodeTemplates = function(dec, node, editor)
{
if (editor.templates == null)
{
editor.templates = [];
}
var children = mxUtils.getChildNodes(node);
for (var j=0; j<children.length; j++)
{
var name = children[j].getAttribute('as');
var child = children[j].firstChild;
while (child != null && child.nodeType != 1)
{
child = child.nextSibling;
}
if (child != null)
{
editor.templates[name] = dec.decodeCell(child);
}
}
};
return codec;
}());
__mxOutput.mxEditorCodec = typeof mxEditorCodec !== 'undefined' ? mxEditorCodec : undefined;
return __mxOutput;
};
}));
} (build$1));
return build$1.exports;
}
var buildExports = requireBuild();
var factory = /*@__PURE__*/getDefaultExportFromCjs(buildExports);
const mxgraph = initialize();
const mxCellRenderer = mxgraph.mxCellRenderer;
const mxClient = mxgraph.mxClient;
const mxConstants = mxgraph.mxConstants;
const mxEvent = mxgraph.mxEvent;
const mxPerimeter = mxgraph.mxPerimeter;
const mxPoint = mxgraph.mxPoint;
const mxRectangle = mxgraph.mxRectangle;
const mxRectangleShape = mxgraph.mxRectangleShape;
const mxSvgCanvas2D = mxgraph.mxSvgCanvas2D;
const mxUtils = mxgraph.mxUtils;
function initialize() {
window.mxForceIncludes = false;
window.mxLoadResources = false;
window.mxLoadStylesheets = false;
window.mxResourceExtension = '.txt';
return factory({});
}
class CoordinatesTranslator {
constructor(graph) {
Object.defineProperty(this, "graph", {
enumerable: true,
configurable: true,
writable: true,
value: graph
});
}
computeRelativeCoordinates(parent, absoluteCoordinate) {
const translateForRoot = this.getTranslateForRoot(parent);
const relativeX = absoluteCoordinate.x + translateForRoot.x;
const relativeY = absoluteCoordinate.y + translateForRoot.y;
return new mxPoint(relativeX, relativeY);
}
getTranslateForRoot(cell) {
const model = this.graph.getModel();
const offset = new mxPoint(0, 0);
while (cell != null) {
const geo = model.getGeometry(cell);
if (geo != null) {
offset.x -= geo.x;
offset.y -= geo.y;
}
cell = model.getParent(cell);
}
return offset;
}
computeEdgeCenter(edge) {
const points = edge.geometry.points;
const p0 = points[0];
const pe = points.at(-1);
const dx = pe.x - p0.x;
const dy = pe.y - p0.y;
return new mxPoint(p0.x + dx / 2, p0.y + dy / 2);
}
}
class Shape {
constructor(id, bpmnElement, bounds, label, isHorizontal) {
Object.defineProperty(this, "id", {
enumerable: true,
configurable: true,
writable: true,
value: id
});
Object.defineProperty(this, "bpmnElement", {
enumerable: true,
configurable: true,
writable: true,
value: bpmnElement
});
Object.defineProperty(this, "bounds", {
enumerable: true,
configurable: true,
writable: true,
value: bounds
});
Object.defineProperty(this, "label", {
enumerable: true,
configurable: true,
writable: true,
value: label
});
Object.defineProperty(this, "isHorizontal", {
enumerable: true,
configurable: true,
writable: true,
value: isHorizontal
});
Object.defineProperty(this, "extensions", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
}
}
class ShapeBpmnElement {
constructor(id, name, kind, parentId, instantiate = false) {
Object.defineProperty(this, "id", {
enumerable: true,
configurable: true,
writable: true,
value: id
});
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: name
});
Object.defineProperty(this, "kind", {
enumerable: true,
configurable: true,
writable: true,
value: kind
});
Object.defineProperty(this, "parentId", {
enumerable: true,
configurable: true,
writable: true,
value: parentId
});
Object.defineProperty(this, "instantiate", {
enumerable: true,
configurable: true,
writable: true,
value: instantiate
});
Object.defineProperty(this, "incomingIds", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "outgoingIds", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
}
}
class ShapeBpmnActivity extends ShapeBpmnElement {
constructor(id, name, kind, parentId, instantiate, markers = []) {
super(id, name, kind, parentId, instantiate);
Object.defineProperty(this, "markers", {
enumerable: true,
configurable: true,
writable: true,
value: markers
});
}
}
class ShapeBpmnCallActivity extends ShapeBpmnActivity {
constructor(id, name, callActivityKind, parentId, markers, globalTaskKind) {
super(id, name, exports.ShapeBpmnElementKind.CALL_ACTIVITY, parentId, undefined, markers);
Object.defineProperty(this, "callActivityKind", {
enumerable: true,
configurable: true,
writable: true,
value: callActivityKind
});
Object.defineProperty(this, "globalTaskKind", {
enumerable: true,
configurable: true,
writable: true,
value: globalTaskKind
});
}
}
class ShapeBpmnSubProcess extends ShapeBpmnActivity {
constructor(id, name, subProcessKind, parentId, markers) {
subProcessKind == exports.ShapeBpmnSubProcessKind.AD_HOC && !markers.includes(exports.ShapeBpmnMarkerKind.ADHOC) && markers.push(exports.ShapeBpmnMarkerKind.ADHOC);
super(id, name, exports.ShapeBpmnElementKind.SUB_PROCESS, parentId, undefined, markers);
Object.defineProperty(this, "subProcessKind", {
enumerable: true,
configurable: true,
writable: true,
value: subProcessKind
});
}
}
class ShapeBpmnEvent extends ShapeBpmnElement {
constructor(id, name, elementKind, eventDefinitionKind, parentId) {
super(id, name, elementKind, parentId);
Object.defineProperty(this, "eventDefinitionKind", {
enumerable: true,
configurable: true,
writable: true,
value: eventDefinitionKind
});
}
}
class ShapeBpmnIntermediateCatchEvent extends ShapeBpmnEvent {
constructor(id, name, eventDefinitionKind, parentId) {
super(id, name, exports.ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, eventDefinitionKind, parentId);
Object.defineProperty(this, "sourceIds", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
}
}
class ShapeBpmnIntermediateThrowEvent extends ShapeBpmnEvent {
constructor(id, name, eventDefinitionKind, parentId) {
super(id, name, exports.ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW, eventDefinitionKind, parentId);
Object.defineProperty(this, "targetId", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
}
}
class ShapeBpmnStartEvent extends ShapeBpmnEvent {
constructor(id, name, eventDefinitionKind, parentId, isInterrupting) {
super(id, name, exports.ShapeBpmnElementKind.EVENT_START, eventDefinitionKind, parentId);
Object.defineProperty(this, "isInterrupting", {
enumerable: true,
configurable: true,
writable: true,
value: isInterrupting
});
}
}
class ShapeBpmnBoundaryEvent extends ShapeBpmnEvent {
constructor(id, name, eventDefinitionKind, parentId, isInterrupting = true) {
super(id, name, exports.ShapeBpmnElementKind.EVENT_BOUNDARY, eventDefinitionKind, parentId);
Object.defineProperty(this, "isInterrupting", {
enumerable: true,
configurable: true,
writable: true,
value: isInterrupting
});
}
}
class ShapeBpmnEventBasedGateway extends ShapeBpmnElement {
constructor(id, name, parentId, instantiate, gatewayKind = exports.ShapeBpmnEventBasedGatewayKind.None) {
super(id, name, exports.ShapeBpmnElementKind.GATEWAY_EVENT_BASED, parentId, instantiate);
Object.defineProperty(this, "gatewayKind", {
enumerable: true,
configurable: true,
writable: true,
value: gatewayKind
});
}
}
function ensureInRange(value, min, max, defaultValue) {
const inRangeValue = value !== null && value !== void 0 ? value : defaultValue;
return Math.min(Math.max(inRangeValue, min), max);
}
function ensurePositiveValue(input) {
return Math.max(input !== null && input !== void 0 ? input : 0, 0);
}
function ensureValidZoomConfiguration(config) {
const validatedConfig = config !== null && config !== void 0 ? config : {};
validatedConfig.debounceDelay = ensureInRange(validatedConfig.debounceDelay, 0, 100, 50);
validatedConfig.throttleDelay = ensureInRange(validatedConfig.throttleDelay, 0, 100, 50);
return validatedConfig;
}
function ensureOpacityValue(opacity) {
return opacity == 'default' ? undefined : ensureInRange(opacity, 0, 100, 100);
}
function ensureStrokeWidthValue(strokeWidth) {
return strokeWidth == 'default' ? undefined : ensureInRange(strokeWidth, 1, 50, 1);
}
const BpmnStyleIdentifier = {
EDGE: 'bpmn.edge',
EDGE_START_FILL_COLOR: 'bpmn.edge.startFillColor',
EDGE_END_FILL_COLOR: 'bpmn.edge.endFillColor',
EVENT_BASED_GATEWAY_KIND: 'bpmn.gatewayKind',
EVENT_DEFINITION_KIND: 'bpmn.eventDefinitionKind',
GLOBAL_TASK_KIND: 'bpmn.globalTaskKind',
SUB_PROCESS_KIND: 'bpmn.subProcessKind',
IS_INITIATING: 'bpmn.isInitiating',
IS_INSTANTIATING: 'bpmn.isInstantiating',
IS_INTERRUPTING: 'bpmn.isInterrupting',
EXTRA_CSS_CLASSES: 'bpmn.extra.css.classes',
MARKERS: 'bpmn.markers',
MESSAGE_FLOW_ICON: 'bpmn.messageFlowIcon',
};
const MarkerIdentifier = {
ARROW_DASH: 'bpmn.dash',
};
const StyleDefault = {
STROKE_WIDTH_THIN: 2,
STROKE_WIDTH_THICK: 5,
SHAPE_ACTIVITY_BOTTOM_MARGIN: 7,
SHAPE_ACTIVITY_TOP_MARGIN: 7,
SHAPE_ACTIVITY_LEFT_MARGIN: 7,
SHAPE_ACTIVITY_MARKER_ICON_MARGIN: 5,
SHAPE_ACTIVITY_MARKER_ICON_SIZE: 20,
POOL_LABEL_SIZE: 30,
POOL_LABEL_FILL_COLOR: 'none',
LANE_LABEL_SIZE: 30,
LANE_LABEL_FILL_COLOR: 'none',
SUB_PROCESS_TRANSACTION_INNER_RECT_OFFSET: 4,
SUB_PROCESS_TRANSACTION_INNER_RECT_ARC_SIZE: 6,
TEXT_ANNOTATION_BORDER_LENGTH: 10,
TEXT_ANNOTATION_FILL_COLOR: 'none',
GROUP_FILL_COLOR: 'none',
DEFAULT_FILL_COLOR: 'White',
DEFAULT_STROKE_COLOR: 'Black',
DEFAULT_FONT_FAMILY: 'Arial, Helvetica, sans-serif',
DEFAULT_FONT_SIZE: 11,
DEFAULT_FONT_COLOR: 'Black',
DEFAULT_MARGIN: 0,
SHAPE_ARC_SIZE: 20,
DEFAULT_OVERLAY_FILL_COLOR: 'White',
DEFAULT_OVERLAY_FILL_OPACITY: 100,
DEFAULT_OVERLAY_STROKE_COLOR: 'Black',
DEFAULT_OVERLAY_STROKE_WIDTH: 1,
DEFAULT_OVERLAY_FONT_SIZE: 11,
DEFAULT_OVERLAY_FONT_COLOR: 'Black',
SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR: 'White',
MESSAGE_FLOW_MARKER_START_FILL_COLOR: 'White',
MESSAGE_FLOW_MARKER_END_FILL_COLOR: 'White',
};
const getBpmnIsInstantiating = (style) => mxUtils.getValue(style, BpmnStyleIdentifier.IS_INSTANTIATING, 'false') == 'true';
const convertDefaultValue = (value) => (value == 'default' ? undefined : value);
const updateStroke = (cellStyle, stroke) => {
if (stroke) {
cellStyle = setStyle(cellStyle, mxConstants.STYLE_STROKECOLOR, stroke.color, convertDefaultValue);
cellStyle = setStyle(cellStyle, mxConstants.STYLE_STROKE_OPACITY, stroke.opacity, ensureOpacityValue);
cellStyle = setStyle(cellStyle, mxConstants.STYLE_STROKEWIDTH, stroke.width, ensureStrokeWidthValue);
}
return cellStyle;
};
const setStyle = (cellStyle, key, value, converter = (value) => value) => {
return value == undefined ? cellStyle : mxUtils.setStyle(cellStyle, key, converter(value));
};
const setStyleFlag = (cellStyle, key, flag, value) => value == undefined ? cellStyle : mxUtils.setStyleFlag(cellStyle, key, flag, value);
const updateFont = (cellStyle, font) => {
if (font) {
cellStyle = setStyle(cellStyle, mxConstants.STYLE_FONTCOLOR, font.color, convertDefaultValue);
cellStyle = setStyle(cellStyle, mxConstants.STYLE_FONTSIZE, font.size);
cellStyle = setStyle(cellStyle, mxConstants.STYLE_FONTFAMILY, font.family);
cellStyle = setStyleFlag(cellStyle, mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD, font.isBold);
cellStyle = setStyleFlag(cellStyle, mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_ITALIC, font.isItalic);
cellStyle = setStyleFlag(cellStyle, mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_UNDERLINE, font.isUnderline);
cellStyle = setStyleFlag(cellStyle, mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_STRIKETHROUGH, font.isStrikeThrough);
cellStyle = setStyle(cellStyle, mxConstants.STYLE_TEXT_OPACITY, font.opacity, ensureOpacityValue);
}
return cellStyle;
};
const getStyleValue = (cellStyle, key, defaultValue) => {
var _a;
return (_a = cellStyle === null || cellStyle === void 0 ? void 0 : cellStyle.split(';').map(entry => entry.split('=')).filter(([k]) => k === key).map(([, v]) => v)[0]) !== null && _a !== void 0 ? _a : defaultValue;
};
const convertDirection = (direction) => {
switch (direction) {
case 'right-to-left': {
return mxConstants.DIRECTION_WEST;
}
case 'bottom-to-top': {
return mxConstants.DIRECTION_NORTH;
}
case 'top-to-bottom': {
return mxConstants.DIRECTION_SOUTH;
}
default: {
return mxConstants.DIRECTION_EAST;
}
}
};
const updateFill = (cellStyle, fill) => {
const color = fill.color;
if (color) {
const isGradient = isFillColorGradient(color);
const fillColor = isGradient ? color.startColor : color;
cellStyle = setStyle(cellStyle, mxConstants.STYLE_FILLCOLOR, fillColor, convertDefaultValue);
if (isGradient) {
cellStyle = mxUtils.setStyle(cellStyle, mxConstants.STYLE_GRADIENTCOLOR, color.endColor);
cellStyle = mxUtils.setStyle(cellStyle, mxConstants.STYLE_GRADIENT_DIRECTION, convertDirection(color.direction));
}
else if (color === 'default') {
cellStyle = mxUtils.setStyle(cellStyle, mxConstants.STYLE_GRADIENTCOLOR, undefined);
cellStyle = mxUtils.setStyle(cellStyle, mxConstants.STYLE_GRADIENT_DIRECTION, undefined);
}
if (cellStyle.includes(exports.ShapeBpmnElementKind.POOL) || cellStyle.includes(exports.ShapeBpmnElementKind.LANE)) {
cellStyle = setStyle(cellStyle, mxConstants.STYLE_SWIMLANE_FILLCOLOR, fillColor, convertDefaultValue);
}
}
cellStyle = setStyle(cellStyle, mxConstants.STYLE_FILL_OPACITY, fill.opacity, ensureOpacityValue);
return cellStyle;
};
const isShapeStyleUpdate = (style) => {
return style && typeof style === 'object' && 'fill' in style;
};
const isFillColorGradient = (color) => {
return color && typeof color === 'object';
};
class StyleComputer {
constructor(options) {
var _a;
Object.defineProperty(this, "ignoreBpmnColors", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.ignoreBpmnColors = (_a = options === null || options === void 0 ? void 0 : options.ignoreBpmnColors) !== null && _a !== void 0 ? _a : true;
}
computeStyle(bpmnCell, labelBounds) {
const styles = [bpmnCell.bpmnElement.kind];
let mainStyleValues;
if (bpmnCell instanceof Shape) {
mainStyleValues = this.computeShapeStyleValues(bpmnCell);
}
else {
styles.push(...computeEdgeBaseStyles(bpmnCell));
mainStyleValues = this.computeEdgeStyleValues(bpmnCell);
}
const fontStyleValues = this.computeFontStyleValues(bpmnCell);
const labelStyleValues = computeLabelStyleValues(bpmnCell, labelBounds);
styles.push(...toArrayOfMxGraphStyleEntries([...mainStyleValues, ...fontStyleValues, ...labelStyleValues]));
return styles.join(';');
}
computeShapeStyleValues(shape) {
const styleValues = new Map();
const bpmnElement = shape.bpmnElement;
if (bpmnElement instanceof ShapeBpmnEvent) {
computeEventShapeStyle(bpmnElement, styleValues);
}
else if (bpmnElement instanceof ShapeBpmnActivity) {
computeActivityShapeStyle(bpmnElement, styleValues);
}
else if (ShapeUtil.isPoolOrLane(bpmnElement.kind)) {
styleValues.set(mxConstants.STYLE_HORIZONTAL, shape.isHorizontal ? '0' : '1');
}
else if (bpmnElement instanceof ShapeBpmnEventBasedGateway) {
styleValues.set(BpmnStyleIdentifier.IS_INSTANTIATING, String(bpmnElement.instantiate));
styleValues.set(BpmnStyleIdentifier.EVENT_BASED_GATEWAY_KIND, String(bpmnElement.gatewayKind));
}
if (!this.ignoreBpmnColors) {
const extensions = shape.extensions;
const fillColor = extensions.fillColor;
if (fillColor) {
styleValues.set(mxConstants.STYLE_FILLCOLOR, fillColor);
if (ShapeUtil.isPoolOrLane(bpmnElement.kind)) {
styleValues.set(mxConstants.STYLE_SWIMLANE_FILLCOLOR, fillColor);
}
}
extensions.strokeColor && styleValues.set(mxConstants.STYLE_STROKECOLOR, extensions.strokeColor);
}
return styleValues;
}
computeEdgeStyleValues(edge) {
const styleValues = new Map();
if (!this.ignoreBpmnColors) {
const extensions = edge.extensions;
extensions.strokeColor && styleValues.set(mxConstants.STYLE_STROKECOLOR, extensions.strokeColor);
}
return styleValues;
}
computeFontStyleValues(bpmnCell) {
var _a, _b;
const styleValues = new Map();
const font = (_a = bpmnCell.label) === null || _a === void 0 ? void 0 : _a.font;
if (font) {
styleValues.set(mxConstants.STYLE_FONTFAMILY, font.name);
styleValues.set(mxConstants.STYLE_FONTSIZE, font.size);
styleValues.set(mxConstants.STYLE_FONTSTYLE, getFontStyleValue(font));
}
if (!this.ignoreBpmnColors) {
const extensions = (_b = bpmnCell.label) === null || _b === void 0 ? void 0 : _b.extensions;
(extensions === null || extensions === void 0 ? void 0 : extensions.color) && styleValues.set(mxConstants.STYLE_FONTCOLOR, extensions.color);
}
return styleValues;
}
computeMessageFlowIconStyle(edge) {
const styleValues = [];
styleValues.push(['shape', BpmnStyleIdentifier.MESSAGE_FLOW_ICON], [BpmnStyleIdentifier.IS_INITIATING, String(edge.messageVisibleKind === exports.MessageVisibleKind.INITIATING)]);
if (!this.ignoreBpmnColors) {
edge.extensions.strokeColor && styleValues.push([mxConstants.STYLE_STROKECOLOR, edge.extensions.strokeColor]);
}
return toArrayOfMxGraphStyleEntries(styleValues).join(';');
}
}
function computeEventShapeStyle(bpmnElement, styleValues) {
styleValues.set(BpmnStyleIdentifier.EVENT_DEFINITION_KIND, bpmnElement.eventDefinitionKind);
if (bpmnElement instanceof ShapeBpmnBoundaryEvent || (bpmnElement instanceof ShapeBpmnStartEvent && bpmnElement.isInterrupting !== undefined)) {
styleValues.set(BpmnStyleIdentifier.IS_INTERRUPTING, String(bpmnElement.isInterrupting));
}
}
function computeActivityShapeStyle(bpmnElement, styleValues) {
if (bpmnElement instanceof ShapeBpmnSubProcess) {
styleValues.set(BpmnStyleIdentifier.SUB_PROCESS_KIND, bpmnElement.subProcessKind);
}
else if (bpmnElement.kind === exports.ShapeBpmnElementKind.TASK_RECEIVE) {
styleValues.set(BpmnStyleIdentifier.IS_INSTANTIATING, String(bpmnElement.instantiate));
}
else if (bpmnElement instanceof ShapeBpmnCallActivity) {
styleValues.set(BpmnStyleIdentifier.GLOBAL_TASK_KIND, bpmnElement.globalTaskKind);
}
const markers = bpmnElement.markers;
if (markers.length > 0) {
styleValues.set(BpmnStyleIdentifier.MARKERS, markers.join(','));
}
}
function computeEdgeBaseStyles(edge) {
const styles = [];
const bpmnElement = edge.bpmnElement;
if (bpmnElement instanceof SequenceFlow) {
styles.push(bpmnElement.sequenceFlowKind);
}
if (bpmnElement instanceof AssociationFlow) {
styles.push(bpmnElement.associationDirectionKind);
}
return styles;
}
function computeLabelStyleValues(bpmnCell, labelBounds) {
const styleValues = new Map();
const bpmnElement = bpmnCell.bpmnElement;
if (labelBounds) {
styleValues.set(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP);
if (bpmnCell.bpmnElement.kind != exports.ShapeBpmnElementKind.TEXT_ANNOTATION) {
styleValues.set(mxConstants.STYLE_ALIGN, mxConstants.ALIGN_CENTER);
}
if (bpmnCell instanceof Shape) {
styleValues.set(mxConstants.STYLE_LABEL_WIDTH, labelBounds.width + 1);
styleValues.set(mxConstants.STYLE_LABEL_POSITION, 'ignore');
styleValues.set(mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
}
}
else if (bpmnCell instanceof Shape &&
(bpmnElement instanceof ShapeBpmnSubProcess || (bpmnElement instanceof ShapeBpmnCallActivity && bpmnElement.callActivityKind === exports.ShapeBpmnCallActivityKind.CALLING_PROCESS)) &&
!bpmnElement.markers.includes(exports.ShapeBpmnMarkerKind.EXPAND)) {
styleValues.set(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP);
}
return styleValues;
}
function getFontStyleValue(font) {
let value = 0;
if (font.isBold) {
value += mxConstants.FONT_BOLD;
}
if (font.isItalic) {
value += mxConstants.FONT_ITALIC;
}
if (font.isStrikeThrough) {
value += mxConstants.FONT_STRIKETHROUGH;
}
if (font.isUnderline) {
value += mxConstants.FONT_UNDERLINE;
}
return value;
}
function toArrayOfMxGraphStyleEntries(styleValues) {
return styleValues.filter(([, v]) => v && v != 'undefined').map(([key, value]) => `${key}=${value}`);
}
class BpmnRenderer {
constructor(graph, coordinatesTranslator, styleComputer) {
Object.defineProperty(this, "graph", {
enumerable: true,
configurable: true,
writable: true,
value: graph
});
Object.defineProperty(this, "coordinatesTranslator", {
enumerable: true,
configurable: true,
writable: true,
value: coordinatesTranslator
});
Object.defineProperty(this, "styleComputer", {
enumerable: true,
configurable: true,
writable: true,
value: styleComputer
});
}
render(renderedModel, fitOptions) {
this.insertShapesAndEdges(renderedModel);
this.graph.customFit(fitOptions);
}
insertShapesAndEdges({ pools, lanes, subprocesses, otherFlowNodes, boundaryEvents, edges }) {
this.graph.batchUpdate(() => {
this.graph.getModel().clear();
this.insertShapes(pools);
this.insertShapes(lanes);
this.insertShapes(subprocesses);
this.insertShapes(otherFlowNodes);
this.insertShapes(boundaryEvents);
this.insertEdges(edges);
});
}
insertShapes(shapes) {
for (const shape of shapes)
this.insertShape(shape);
}
getParent(bpmnElement) {
const bpmnElementParent = this.getCell(bpmnElement.parentId);
return bpmnElementParent !== null && bpmnElementParent !== void 0 ? bpmnElementParent : this.graph.getDefaultParent();
}
insertShape(shape) {
var _a;
const bpmnElement = shape.bpmnElement;
const parent = this.getParent(bpmnElement);
const bounds = shape.bounds;
let labelBounds = (_a = shape.label) === null || _a === void 0 ? void 0 : _a.bounds;
labelBounds = ShapeUtil.isPoolOrLane(bpmnElement.kind) ? undefined : labelBounds;
const style = this.styleComputer.computeStyle(shape, labelBounds);
this.insertVertex(parent, bpmnElement.id, bpmnElement.name, bounds, labelBounds, style);
}
insertEdges(edges) {
var _a;
for (const internalEdge of edges) {
const bpmnElement = internalEdge.bpmnElement;
const parent = this.graph.getDefaultParent();
const source = this.getCell(bpmnElement.sourceReferenceId);
const target = this.getCell(bpmnElement.targetReferenceId);
const labelBounds = (_a = internalEdge.label) === null || _a === void 0 ? void 0 : _a.bounds;
const style = this.styleComputer.computeStyle(internalEdge, labelBounds);
const edge = this.graph.insertEdge(parent, bpmnElement.id, bpmnElement.name, source, target, style);
this.insertWaypoints(internalEdge.waypoints, edge);
if (labelBounds) {
edge.geometry.width = labelBounds.width;
edge.geometry.height = labelBounds.height;
const edgeCenterCoordinate = this.coordinatesTranslator.computeEdgeCenter(edge);
edge.geometry.relative = false;
const labelBoundsRelativeCoordinateFromParent = this.coordinatesTranslator.computeRelativeCoordinates(edge.parent, new mxPoint(labelBounds.x, labelBounds.y));
const relativeLabelX = labelBoundsRelativeCoordinateFromParent.x + labelBounds.width / 2 - edgeCenterCoordinate.x;
const relativeLabelY = labelBoundsRelativeCoordinateFromParent.y - edgeCenterCoordinate.y;
edge.geometry.offset = new mxPoint(relativeLabelX, relativeLabelY);
}
this.insertMessageFlowIconIfNeeded(internalEdge, edge);
}
}
insertMessageFlowIconIfNeeded(internalEdge, edge) {
if (internalEdge.bpmnElement instanceof MessageFlow && internalEdge.messageVisibleKind !== exports.MessageVisibleKind.NONE) {
const cell = this.graph.insertVertex(edge, messageFlowIconId(edge.id), undefined, 0, 0, 20, 14, this.styleComputer.computeMessageFlowIconStyle(internalEdge));
cell.geometry.relative = true;
cell.geometry.offset = new mxPoint(-10, -7);
}
}
insertWaypoints(waypoints, edge) {
if (waypoints) {
edge.geometry.points = waypoints.map(waypoint => this.coordinatesTranslator.computeRelativeCoordinates(edge.parent, new mxPoint(waypoint.x, waypoint.y)));
}
}
getCell(id) {
return this.graph.getModel().getCell(id);
}
insertVertex(parent, id, value, bounds, labelBounds, style) {
const vertexCoordinates = this.coordinatesTranslator.computeRelativeCoordinates(parent, new mxPoint(bounds.x, bounds.y));
const cell = this.graph.insertVertex(parent, id, value, vertexCoordinates.x, vertexCoordinates.y, bounds.width, bounds.height, style);
if (labelBounds) {
const relativeLabelX = labelBounds.x - bounds.x;
const relativeLabelY = labelBounds.y - bounds.y;
cell.geometry.offset = new mxPoint(relativeLabelX, relativeLabelY);
}
return cell;
}
}
function newBpmnRenderer(graph, options) {
return new BpmnRenderer(graph, new CoordinatesTranslator(graph), new StyleComputer(options));
}
function messageFlowIconId(messageFlowId) {
return `messageFlowIcon_of_${messageFlowId}`;
}
function debounce(func, debounceMs, { signal, edges } = {}) {
let pendingThis = undefined;
let pendingArgs = null;
const leading = edges != null && edges.includes('leading');
const trailing = edges == null || edges.includes('trailing');
const invoke = () => {
if (pendingArgs !== null) {
func.apply(pendingThis, pendingArgs);
pendingThis = undefined;
pendingArgs = null;
}
};
const onTimerEnd = () => {
if (trailing) {
invoke();
}
cancel();
};
let timeoutId = null;
const schedule = () => {
if (timeoutId != null) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(() => {
timeoutId = null;
onTimerEnd();
}, debounceMs);
};
const cancelTimer = () => {
if (timeoutId !== null) {
clearTimeout(timeoutId);
timeoutId = null;
}
};
const cancel = () => {
cancelTimer();
pendingThis = undefined;
pendingArgs = null;
};
const flush = () => {
cancelTimer();
invoke();
};
const debounced = function (...args) {
if (signal?.aborted) {
return;
}
pendingThis = this;
pendingArgs = args;
const isFirstCall = timeoutId == null;
schedule();
if (leading && isFirstCall) {
invoke();
}
};
debounced.schedule = schedule;
debounced.cancel = cancel;
debounced.flush = flush;
signal?.addEventListener('abort', cancel, { once: true });
return debounced;
}
function throttle(func, throttleMs, { signal, edges = ['leading', 'trailing'] } = {}) {
let pendingAt = null;
const debounced = debounce(func, throttleMs, { signal, edges });
const throttled = function (...args) {
if (pendingAt == null) {
pendingAt = Date.now();
}
else {
if (Date.now() - pendingAt >= throttleMs) {
pendingAt = Date.now();
debounced.cancel();
debounced(...args);
}
}
debounced(...args);
};
throttled.cancel = debounced.cancel;
throttled.flush = debounced.flush;
return throttled;
}
class MxGraphCustomOverlay extends mxgraph.mxCellOverlay {
constructor(label, options) {
super(null, '', options.position.horizontalAlign, options.position.verticalAlign, null, 'default');
Object.defineProperty(this, "label", {
enumerable: true,
configurable: true,
writable: true,
value: label
});
Object.defineProperty(this, "style", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.style = options.style;
}
getBounds(state) {
const isEdge = state.view.graph.getModel().isEdge(state.cell);
const s = state.view.scale;
let pt;
const w = 0;
const h = 0;
if (isEdge) {
pt = this.computeEdgeBounds(state);
}
else {
pt = new mxPoint();
if (this.align == mxConstants.ALIGN_LEFT) {
pt.x = state.x;
}
else if (this.align == mxConstants.ALIGN_CENTER) {
pt.x = state.x + state.width / 2;
}
else {
pt.x = state.x + state.width;
}
if (this.verticalAlign == mxConstants.ALIGN_TOP) {
pt.y = state.y;
}
else if (this.verticalAlign == mxConstants.ALIGN_MIDDLE) {
pt.y = state.y + state.height / 2;
}
else {
pt.y = state.y + state.height;
}
}
return new mxRectangle(Math.round(pt.x - (w * this.defaultOverlap - this.offset.x) * s), Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * s);
}
computeEdgeBounds(state) {
const pts = state.absolutePoints;
if (this.align == mxConstants.ALIGN_LEFT) {
return pts[0];
}
else if (this.align == mxConstants.ALIGN_CENTER) {
if (pts.length % 2 == 1) {
return pts[Math.floor(pts.length / 2)];
}
else {
const index = pts.length / 2;
const p0 = pts[index - 1];
const p1 = pts[index];
return new mxPoint(p0.x + (p1.x - p0.x) / 2, p0.y + (p1.y - p0.y) / 2);
}
}
else {
return pts.at(-1);
}
}
}
class OverlayBadgeShape extends mxgraph.mxText {
constructor(value, bounds, style) {
super(value, bounds, undefined, undefined, style.font.color, undefined, style.font.size, undefined, undefined, undefined, undefined, undefined, undefined, undefined, style.fill.color, style.stroke.color);
this.fillOpacity = style.fill.opacity;
this.strokewidth = style.stroke.width;
}
}
function isFlowKind(kind) {
return Object.values(exports.FlowKind)
.map(value => value)
.includes(kind);
}
function computeAllBpmnClassNamesOfCell(cell, isLabel) {
return computeAllBpmnClassNames(cell.style, isLabel);
}
function computeAllBpmnClassNames(style, isLabel) {
const classes = [];
const styleElements = style.split(';');
const pseudoBpmnElementKind = styleElements[0];
const bpmnElementKind = pseudoBpmnElementKind.replace(/shape=bpmn./g, '');
const typeClasses = new Map();
typeClasses.set('bpmn-type-activity', ShapeUtil.isActivity(bpmnElementKind));
typeClasses.set('bpmn-type-container', ShapeUtil.isPoolOrLane(bpmnElementKind));
typeClasses.set('bpmn-type-event', ShapeUtil.isEvent(bpmnElementKind));
typeClasses.set('bpmn-type-flow', isFlowKind(bpmnElementKind));
typeClasses.set('bpmn-type-gateway', ShapeUtil.isGateway(bpmnElementKind));
typeClasses.set('bpmn-type-task', ShapeUtil.isTask(bpmnElementKind));
for (const [className] of [...typeClasses].filter(([, isType]) => isType))
classes.push(className);
classes.push(computeBpmnBaseClassName(bpmnElementKind));
for (const [key, value] of styleElements.map(entry => {
const elements = entry.split('=');
return [elements[0], elements[1]];
})) {
switch (key) {
case BpmnStyleIdentifier.EVENT_DEFINITION_KIND: {
classes.push(`bpmn-event-def-${value}`);
break;
}
case BpmnStyleIdentifier.EVENT_BASED_GATEWAY_KIND: {
classes.push(`bpmn-gateway-kind-${value.toLowerCase()}`);
break;
}
case BpmnStyleIdentifier.IS_INITIATING: {
classes.push(value == 'true' ? 'bpmn-icon-initiating' : 'bpmn-icon-non-initiating');
break;
}
case BpmnStyleIdentifier.SUB_PROCESS_KIND: {
classes.push(`bpmn-sub-process-${value.toLowerCase()}`);
break;
}
case BpmnStyleIdentifier.GLOBAL_TASK_KIND: {
classes.push(computeBpmnBaseClassName(value));
break;
}
}
}
if (isLabel) {
classes.push('bpmn-label');
}
return classes;
}
function computeBpmnBaseClassName(bpmnElementKind) {
return bpmnElementKind ? 'bpmn-' + bpmnElementKind.replace(/([A-Z])/g, g => '-' + g[0].toLowerCase()) : '';
}
const overrideCreateSvgCanvas = function (shape) {
const originalShapeCreateSvgCanvas = shape.createSvgCanvas;
shape.createSvgCanvas = function () {
var _a;
const canvas = originalShapeCreateSvgCanvas.bind(this)();
const originalCanvasGetTextCss = canvas.getTextCss;
canvas.getTextCss = function () {
const originalPointerEvents = this.pointerEvents;
this.pointerEvents = false;
const textCss = originalCanvasGetTextCss.bind(this)();
this.pointerEvents = originalPointerEvents;
return textCss;
};
if ((_a = this.state) === null || _a === void 0 ? void 0 : _a.cell) {
const cell = this.state.cell;
const allBpmnClassNames = computeAllBpmnClassNamesOfCell(cell, this.dialect === mxConstants.DIALECT_STRICTHTML);
const extraCssClasses = this.state.style[BpmnStyleIdentifier.EXTRA_CSS_CLASSES];
if (typeof extraCssClasses == 'string') {
allBpmnClassNames.push(...extraCssClasses.split(','));
}
this.node.setAttribute('class', allBpmnClassNames.join(' '));
this.node.dataset.bpmnId = this.state.cell.id;
}
return canvas;
};
};
class BpmnCellRenderer extends mxgraph.mxCellRenderer {
constructor(iconPainter) {
super();
Object.defineProperty(this, "iconPainter", {
enumerable: true,
configurable: true,
writable: true,
value: iconPainter
});
}
createCellOverlays(state) {
const graph = state.view.graph;
const overlays = graph.getCellOverlays(state.cell);
let dict = null;
if (overlays != null) {
dict = new mxgraph.mxDictionary();
for (const currentOverlay of overlays) {
const shape = state.overlays == null ? null : state.overlays.remove(currentOverlay);
if (shape != null) {
dict.put(currentOverlay, shape);
continue;
}
let overlayShape;
if (currentOverlay instanceof MxGraphCustomOverlay) {
overlayShape = new OverlayBadgeShape(currentOverlay.label, new mxRectangle(0, 0, 0, 0), currentOverlay.style);
}
else {
overlayShape = new mxgraph.mxImageShape(new mxRectangle(0, 0, 0, 0), currentOverlay.image.src);
overlayShape.preserveImageAspect = false;
}
overlayShape.dialect = state.view.graph.dialect;
overlayShape.overlay = currentOverlay;
this.initializeOverlay(state, overlayShape);
this.installCellOverlayListeners(state, currentOverlay, overlayShape);
if (currentOverlay.cursor != null) {
overlayShape.node.style.cursor = currentOverlay.cursor;
}
if (overlayShape instanceof OverlayBadgeShape) {
overlayShape.node.classList.add('overlay-badge');
overlayShape.node.dataset.bpmnId = state.cell.id;
}
dict.put(currentOverlay, overlayShape);
}
}
if (state.overlays != null) {
state.overlays.visit(function (_id, shape) {
shape.destroy();
});
}
state.overlays = dict;
}
createShape(state) {
const shape = super.createShape(state);
if ('iconPainter' in shape) {
shape.iconPainter = this.iconPainter;
}
overrideCreateSvgCanvas(shape);
return shape;
}
createLabel(state, value) {
super.createLabel(state, value);
overrideCreateSvgCanvas(state.text);
}
}
function computeScaledIconSize(initialIconSize, iconStyleConfiguration, shapeConfiguration, ratioFromShape) {
let iconWidthProportionalToShape;
let iconHeightProportionalToShape;
if (initialIconSize.height < initialIconSize.width || (initialIconSize.height == initialIconSize.width && shapeConfiguration.width <= shapeConfiguration.height)) {
iconWidthProportionalToShape = shapeConfiguration.width;
iconHeightProportionalToShape = (shapeConfiguration.width * initialIconSize.height) / initialIconSize.width;
}
else {
iconWidthProportionalToShape = (shapeConfiguration.height * initialIconSize.width) / initialIconSize.height;
iconHeightProportionalToShape = shapeConfiguration.height;
}
const inset = iconStyleConfiguration.strokeWidth ? (iconStyleConfiguration.strokeWidth - 1) * 2 : 0;
const paintIconWidth = iconWidthProportionalToShape * ratioFromShape - inset;
const paintIconHeight = iconHeightProportionalToShape * ratioFromShape - inset;
return { width: paintIconWidth, height: paintIconHeight };
}
class BpmnCanvas {
constructor({ canvas, shapeConfig, iconConfig }) {
Object.defineProperty(this, "canvas", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "iconOriginalSize", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "scaleX", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "scaleY", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "iconPaintingOriginX", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "iconPaintingOriginY", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "shapeConfiguration", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.canvas = canvas;
this.shapeConfiguration = shapeConfig;
this.iconOriginalSize = iconConfig.originalSize;
const ratioFromShape = iconConfig.ratioFromParent;
if (ratioFromShape) {
const scaledIconSize = computeScaledIconSize(this.iconOriginalSize, iconConfig.styleConfig, this.shapeConfiguration, ratioFromShape);
this.scaleX = scaledIconSize.width / this.iconOriginalSize.width;
this.scaleY = scaledIconSize.height / this.iconOriginalSize.height;
}
else {
this.scaleX = 1;
this.scaleY = 1;
}
this.updateCanvasStyle(iconConfig.styleConfig);
iconConfig.setIconOriginFunct(this);
}
setIconOriginToShapeTopLeftProportionally(shapeDimensionProportion) {
const shape = this.shapeConfiguration;
this.iconPaintingOriginX = shape.x + shape.width / shapeDimensionProportion;
this.iconPaintingOriginY = shape.y + shape.height / shapeDimensionProportion;
}
setIconOriginToShapeTopLeft(topMargin = StyleDefault.SHAPE_ACTIVITY_TOP_MARGIN, leftMargin = StyleDefault.SHAPE_ACTIVITY_LEFT_MARGIN) {
const shape = this.shapeConfiguration;
this.iconPaintingOriginX = shape.x + leftMargin;
this.iconPaintingOriginY = shape.y + topMargin;
}
setIconOriginForIconCentered() {
const shape = this.shapeConfiguration;
this.iconPaintingOriginX = shape.x + (shape.width - this.iconOriginalSize.width * this.scaleX) / 2;
this.iconPaintingOriginY = shape.y + (shape.height - this.iconOriginalSize.height * this.scaleY) / 2;
}
setIconOriginForIconBottomCentered(bottomMargin = StyleDefault.SHAPE_ACTIVITY_BOTTOM_MARGIN) {
const shape = this.shapeConfiguration;
this.iconPaintingOriginX = shape.x + (shape.width - this.iconOriginalSize.width * this.scaleX) / 2;
this.iconPaintingOriginY = shape.y + (shape.height - this.iconOriginalSize.height * this.scaleY - bottomMargin);
}
translateIconOrigin(dx, dy) {
this.iconPaintingOriginX += this.scaleX * dx;
this.iconPaintingOriginY += this.scaleY * dy;
}
computeScaleFromOriginX(x) {
return this.iconPaintingOriginX + x * this.scaleX;
}
computeScaleFromOriginY(y) {
return this.iconPaintingOriginY + y * this.scaleY;
}
updateCanvasStyle({ isFilled, strokeColor, fillColor, strokeWidth }) {
if (isFilled) {
this.canvas.setFillColor(strokeColor);
}
else {
this.canvas.setFillColor(fillColor);
}
this.canvas.setStrokeWidth(strokeWidth);
}
arcTo(rx, ry, angle, largeArcFlag, sweepFlag, x, y) {
this.canvas.arcTo(rx * this.scaleX, ry * this.scaleY, angle, largeArcFlag, sweepFlag, this.computeScaleFromOriginX(x), this.computeScaleFromOriginY(y));
}
begin() {
this.canvas.begin();
}
close() {
this.canvas.close();
}
curveTo(x1, y1, x2, y2, x3, y3) {
this.canvas.curveTo(this.computeScaleFromOriginX(x1), this.computeScaleFromOriginY(y1), this.computeScaleFromOriginX(x2), this.computeScaleFromOriginY(y2), this.computeScaleFromOriginX(x3), this.computeScaleFromOriginY(y3));
}
fill() {
this.canvas.fill();
}
fillAndStroke() {
this.canvas.fillAndStroke();
}
setFillColor(fillColor) {
this.canvas.setFillColor(fillColor);
}
stroke() {
this.canvas.stroke();
}
setStrokeColor(color) {
this.canvas.setStrokeColor(color);
}
setRoundLineJoin() {
this.canvas.setLineJoin('round');
}
lineTo(x, y) {
this.canvas.lineTo(this.computeScaleFromOriginX(x), this.computeScaleFromOriginY(y));
}
moveTo(x, y) {
this.canvas.moveTo(this.computeScaleFromOriginX(x), this.computeScaleFromOriginY(y));
}
rect(x, y, w, h) {
this.canvas.rect(this.computeScaleFromOriginX(x), this.computeScaleFromOriginY(y), w * this.scaleX, h * this.scaleY);
}
roundrect(x, y, w, h, dx, dy) {
this.canvas.roundrect(this.computeScaleFromOriginX(x), this.computeScaleFromOriginY(y), w * this.scaleX, h * this.scaleY, dx, dy);
}
ellipse(x, y, w, h) {
this.canvas.ellipse(this.computeScaleFromOriginX(x), this.computeScaleFromOriginY(y), w * this.scaleX, h * this.scaleY);
}
rotateOnIconCenter(theta) {
const rotationCenterX = this.iconPaintingOriginX + (this.iconOriginalSize.width / 2) * this.scaleX;
const rotationCenterY = this.iconPaintingOriginY + (this.iconOriginalSize.height / 2) * this.scaleY;
this.canvas.rotate(theta, false, false, rotationCenterX, rotationCenterY);
}
}
function buildPaintParameter({ canvas, x, y, width, height, shape, ratioFromParent, isFilled, iconStrokeWidth, }) {
const shapeStrokeWidth = mxUtils.getValue(shape.style, mxConstants.STYLE_STROKEWIDTH, StyleDefault.STROKE_WIDTH_THIN);
const fillColor = mxUtils.getValue(shape.style, mxConstants.STYLE_FILLCOLOR, StyleDefault.DEFAULT_FILL_COLOR);
const strokeColor = mxUtils.getValue(shape.style, mxConstants.STYLE_STROKECOLOR, StyleDefault.DEFAULT_STROKE_COLOR);
const margin = mxUtils.getValue(shape.style, mxConstants.STYLE_MARGIN, StyleDefault.DEFAULT_MARGIN);
ratioFromParent !== null && ratioFromParent !== void 0 ? ratioFromParent : (ratioFromParent = 0.25);
isFilled !== null && isFilled !== void 0 ? isFilled : (isFilled = false);
iconStrokeWidth !== null && iconStrokeWidth !== void 0 ? iconStrokeWidth : (iconStrokeWidth = 0);
return {
canvas,
ratioFromParent,
setIconOriginFunct: (internalCanvas) => internalCanvas.setIconOriginForIconCentered(),
shapeConfig: { x, y, width, height, strokeWidth: shapeStrokeWidth },
iconStyleConfig: { isFilled, fillColor, strokeColor, strokeWidth: iconStrokeWidth, margin },
};
}
class IconPainter {
newBpmnCanvas({ canvas, ratioFromParent, setIconOriginFunct, shapeConfig, iconStyleConfig }, originalIconSize) {
return new BpmnCanvas({
canvas,
shapeConfig,
iconConfig: {
originalSize: originalIconSize,
styleConfig: iconStyleConfig,
ratioFromParent,
setIconOriginFunct,
},
});
}
paintEnvelopeIcon(paintParameter) {
const originalIconSize = { width: 485.41, height: 321.76 };
const canvas = this.newBpmnCanvas(paintParameter, originalIconSize);
const w = originalIconSize.width;
const h = originalIconSize.height;
canvas.rect(0, 0, w, h);
canvas.fillAndStroke();
const { iconStyleConfig } = paintParameter;
if (iconStyleConfig.isFilled) {
canvas.setStrokeColor(iconStyleConfig.fillColor);
}
canvas.begin();
canvas.moveTo(0, 0);
canvas.lineTo(w * 0.5, h * 0.6);
canvas.lineTo(w, 0);
canvas.moveTo(0, h);
canvas.lineTo(w / 3, h * 0.45);
canvas.moveTo(w, h);
canvas.lineTo((w * 2) / 3, h * 0.45);
canvas.stroke();
}
paintCircleIcon(paintParameter) {
const originalIconSize = { width: paintParameter.shapeConfig.width, height: paintParameter.shapeConfig.height };
const canvas = this.newBpmnCanvas(paintParameter, originalIconSize);
const w = originalIconSize.width;
const h = originalIconSize.height;
if (w > 0 && h > 0) {
canvas.ellipse(0, 0, w, h);
}
if (paintParameter.iconStyleConfig.isFilled) {
canvas.fillAndStroke();
}
else {
canvas.stroke();
}
}
paintClockIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { height: 152, width: 152 });
canvas.begin();
canvas.moveTo(184, 60);
canvas.curveTo(188.4, 60, 192, 56.4, 192, 52);
canvas.lineTo(192, 48);
canvas.curveTo(192, 40, 188.4, 40, 184, 40);
canvas.curveTo(179.6, 40, 176, 43.6, 176, 48);
canvas.lineTo(176, 52);
canvas.curveTo(176, 56.4, 179.6, 60, 184, 60);
canvas.close();
canvas.moveTo(184, 308);
canvas.curveTo(179.6, 308, 176, 311.6, 176, 316);
canvas.lineTo(176, 320);
canvas.curveTo(176, 324.4, 179.6, 328, 184, 328);
canvas.curveTo(188.4, 328, 192, 324.4, 192, 320);
canvas.lineTo(192, 316);
canvas.curveTo(192, 311.6, 188.4, 308, 184, 308);
canvas.close();
canvas.moveTo(52, 176);
canvas.lineTo(48, 176);
canvas.curveTo(43.6, 176, 40, 179.6, 40, 184);
canvas.curveTo(40, 188.4, 43.6, 192, 48, 192);
canvas.lineTo(52, 192);
canvas.curveTo(56.4, 192, 69, 188.4, 60, 184);
canvas.curveTo(60, 179.6, 56.4, 176, 52, 176);
canvas.close();
canvas.moveTo(320, 176);
canvas.lineTo(316, 176);
canvas.curveTo(311.6, 176, 308, 179.6, 308, 184);
canvas.curveTo(308, 188.4, 311.6, 192, 316, 192);
canvas.lineTo(320, 192);
canvas.curveTo(324.4, 192, 328, 188.4, 328, 184);
canvas.curveTo(328, 179.6, 324.4, 176, 320, 176);
canvas.moveTo(93.6, 82.4);
canvas.curveTo(90.4, 79.2, 85.6, 79.2, 82.4, 82.4);
canvas.curveTo(79.2, 85.6, 79.2, 90.4, 82.4, 93.6);
canvas.lineTo(85.2, 96.4);
canvas.curveTo(86.8, 98, 88.8, 98.8, 90.8, 98.8);
canvas.curveTo(92.8, 98.8, 94.4, 98, 96.4, 96.4);
canvas.curveTo(99.6, 93.2, 99.6, 88.4, 96.4, 85.2);
canvas.lineTo(93.6, 82.4);
canvas.moveTo(85.2, 271.6);
canvas.lineTo(82.4, 274.4);
canvas.curveTo(79.2, 277.6, 79.2, 282.4, 82.4, 285.6);
canvas.curveTo(84, 287.2, 86, 288, 88, 288);
canvas.curveTo(90, 288, 92, 287.2, 93.6, 285.6);
canvas.lineTo(96.4, 282.8);
canvas.curveTo(99.6, 279.6, 99.6, 274.8, 96.4, 271.6);
canvas.curveTo(93.2, 268.4, 88.4, 268.4, 85.2, 271.6);
canvas.moveTo(274.4, 82.4);
canvas.lineTo(271.6, 85.2);
canvas.curveTo(268.4, 88.4, 268.4, 93.2, 271.6, 96.4);
canvas.curveTo(273.298, 98, 275.2, 98.8, 277.2, 98.8);
canvas.curveTo(279.2, 98.8, 281.2, 98, 282.8, 96.4);
canvas.lineTo(285.6, 93.6);
canvas.curveTo(288.8, 90.4, 288.8, 85.6, 285.6, 82.4);
canvas.curveTo(282.4, 79.2, 277.6, 79.2, 274.4, 82.4);
canvas.moveTo(192, 180.8);
canvas.lineTo(192, 108);
canvas.curveTo(192, 103.6, 188.4, 100, 184, 100);
canvas.curveTo(179.6, 100, 176, 103.6, 176, 108);
canvas.lineTo(176, 184);
canvas.curveTo(176, 186, 176.8, 188, 178.4, 189.6);
canvas.lineTo(266, 277.2);
canvas.curveTo(267.6, 278.8, 269.6, 279.6, 271.6, 279.6);
canvas.curveTo(273.6, 279.6, 275.6, 278.8, 277.2, 277.2);
canvas.curveTo(280.4, 274, 280.4, 269.2, 277.2, 266);
canvas.lineTo(192, 180.8);
canvas.moveTo(184, 0);
canvas.curveTo(82.4, 0, 0, 82.4, 0, 184);
canvas.curveTo(0, 285.6, 82.4, 368, 184, 368);
canvas.curveTo(285.6, 368, 368, 285.6, 368, 184);
canvas.curveTo(368, 82.4, 285.6, 0, 184, 0);
canvas.moveTo(184, 352);
canvas.curveTo(91.2, 352, 16, 276.8, 16, 184);
canvas.curveTo(16, 91.2, 91.2, 16, 184, 16);
canvas.curveTo(276.8, 16, 352, 91.2, 352, 184);
canvas.curveTo(352, 276.8, 276.8, 352, 184, 352);
canvas.fillAndStroke();
}
paintTriangleIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { height: 735, width: 849 });
canvas.begin();
canvas.moveTo(497, 55);
canvas.lineTo(817, 609);
canvas.curveTo(849, 665, 808, 735, 744, 735);
canvas.lineTo(105, 735);
canvas.curveTo(40, 735, 0, 665, 32, 609);
canvas.lineTo(352, 55);
canvas.curveTo(384, 0, 465, 0, 497, 55);
canvas.close();
canvas.fillAndStroke();
}
paintUpArrowheadIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { height: 50, width: 40 });
canvas.begin();
canvas.moveTo(0, 49.5);
canvas.lineTo(19.5, 1);
canvas.curveTo(19.75, 0.25, 20, 0, 20.25, 0.25);
canvas.lineTo(40, 49.5);
canvas.curveTo(40, 49.5, 39.75, 50, 39.6, 49.75);
canvas.lineTo(20, 30);
canvas.lineTo(0.4, 49.75);
canvas.curveTo(0.4, 49.75, 0.25, 50, 0, 49.5);
canvas.close();
canvas.fillAndStroke();
}
paintDoubleLeftArrowheadsIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { height: 53.5, width: 105 });
canvas.begin();
canvas.moveTo(91.4, 0);
canvas.curveTo(91.4, 0, 91.2, 0, 91, 0.2);
canvas.lineTo(50, 25);
canvas.curveTo(47.9, 25.8, 46.7, 26.6, 46.4, 27.3);
canvas.lineTo(46.4, 0);
canvas.curveTo(46.4, 0, 46.2, 0, 46, 0.2);
canvas.lineTo(4.9, 25);
canvas.curveTo(2, 26.2, 0, 27.3, 4.9, 28.5);
canvas.lineTo(45.8, 53);
canvas.curveTo(46, 53.3, 46.2, 53.5, 46.4, 53.5);
canvas.lineTo(46.4, 27);
canvas.curveTo(46.6, 27.3, 47.8, 28.1, 49.9, 29.9);
canvas.lineTo(90.8, 53.3);
canvas.curveTo(91, 53.3, 91.2, 53.5, 91.4, 53.5);
canvas.lineTo(91.4, 0);
canvas.close();
canvas.fillAndStroke();
}
drawCrossIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { height: 1, width: 1 });
canvas.begin();
canvas.moveTo(0.38, 0);
canvas.lineTo(0.62, 0);
canvas.lineTo(0.62, 0.38);
canvas.lineTo(1, 0.38);
canvas.lineTo(1, 0.62);
canvas.lineTo(0.62, 0.62);
canvas.lineTo(0.62, 1);
canvas.lineTo(0.38, 1);
canvas.lineTo(0.38, 0.62);
canvas.lineTo(0, 0.62);
canvas.lineTo(0, 0.38);
canvas.lineTo(0.38, 0.38);
canvas.close();
return canvas;
}
paintListIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { height: 60, width: 60 });
canvas.begin();
canvas.moveTo(0, 0);
canvas.lineTo(60, 0);
canvas.lineTo(60, 60);
canvas.lineTo(0, 60);
canvas.lineTo(0, 0);
canvas.close();
canvas.moveTo(5, 5);
canvas.lineTo(55, 5);
canvas.close();
canvas.moveTo(5, 21.6);
canvas.lineTo(55, 21.6);
canvas.close();
canvas.moveTo(5, 38.3);
canvas.lineTo(55, 38.3);
canvas.close();
canvas.moveTo(5, 55);
canvas.lineTo(55, 55);
canvas.close();
canvas.fillAndStroke();
}
paintXCrossIcon(paintParameter) {
const canvas = this.drawCrossIcon(paintParameter);
canvas.rotateOnIconCenter(45);
canvas.fillAndStroke();
}
paintPlusCrossIcon(paintParameter) {
this.drawCrossIcon(paintParameter).fillAndStroke();
}
paintAsteriskIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { height: 1, width: 1 });
drawVerticalLine(canvas);
canvas.fillAndStroke();
drawVerticalLine(canvas);
canvas.rotateOnIconCenter(60);
canvas.fillAndStroke();
drawVerticalLine(canvas);
canvas.rotateOnIconCenter(240);
canvas.fillAndStroke();
}
paintPersonIcon(paintParameter) {
const canvas = this.newBpmnCanvas(Object.assign(Object.assign({}, paintParameter), { iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { isFilled: true }) }), { height: 239.68, width: 143.61 });
canvas.begin();
canvas.moveTo(124.31, 150.29);
canvas.lineTo(99.66, 141.03);
canvas.arcTo(6.43, 6.43, 0, 0, 1, 95.51, 135.03);
canvas.lineTo(95.51, 130.66);
canvas.arcTo(47.75, 47.75, 0, 0, 0, 119.51, 89.25);
canvas.lineTo(119.51, 71.25);
canvas.arcTo(47.62, 47.62, 0, 0, 0, 101.18, 33.64);
canvas.arcTo(29.35, 29.35, 0, 0, 0, 101.52, 29.14);
canvas.arcTo(29.68, 29.68, 0, 0, 0, 42.17, 29.14);
canvas.arcTo(29.24, 29.24, 0, 0, 0, 42.53, 33.63);
canvas.arcTo(47.65, 47.65, 0, 0, 0, 24.14, 71.23);
canvas.lineTo(24.14, 89.23);
canvas.arcTo(47.7, 47.7, 0, 0, 0, 48.19, 130.63);
canvas.lineTo(48.19, 135.03);
canvas.arcTo(6.43, 6.43, 0, 0, 1, 44.03, 141.03);
canvas.lineTo(19.31, 150.29);
canvas.arcTo(29.81, 29.81, 0, 0, 0, 0.09, 178.03);
canvas.lineTo(0.09, 233.51);
canvas.arcTo(5.63, 5.63, 0, 1, 0, 11.34, 233.51);
canvas.lineTo(11.34, 178.03);
canvas.arcTo(18.19, 18.19, 0, 0, 1, 11.57, 175.17);
canvas.lineTo(20.5, 184.11);
canvas.arcTo(12.32, 12.32, 0, 0, 1, 24.14, 192.89);
canvas.lineTo(24.14, 233.51);
canvas.arcTo(5.63, 5.63, 0, 1, 0, 35.39, 233.51);
canvas.lineTo(35.39, 192.93);
canvas.arcTo(23.5, 23.5, 0, 0, 0, 28.46, 176.2);
canvas.lineTo(17.04, 164.78);
canvas.arcTo(18.34, 18.34, 0, 0, 1, 23.29, 160.78);
canvas.lineTo(43.65, 153.15);
canvas.lineTo(66.22, 175.72);
canvas.lineTo(66.22, 233.51);
canvas.arcTo(5.63, 5.63, 0, 1, 0, 77.47, 233.51);
canvas.lineTo(77.47, 175.76);
canvas.lineTo(100.04, 153.19);
canvas.lineTo(120.4, 160.82);
canvas.arcTo(18.39, 18.39, 0, 0, 1, 126.65, 164.82);
canvas.lineTo(115.24, 176.24);
canvas.arcTo(23.5, 23.5, 0, 0, 0, 108.31, 192.93);
canvas.lineTo(108.31, 233.55);
canvas.arcTo(5.63, 5.63, 0, 1, 0, 119.56, 233.55);
canvas.lineTo(119.56, 192.93);
canvas.arcTo(12.35, 12.35, 0, 0, 1, 123.19, 184.15);
canvas.lineTo(132.13, 175.22);
canvas.arcTo(18, 18, 0, 0, 1, 132.36, 178.08);
canvas.lineTo(132.36, 233.56);
canvas.arcTo(5.63, 5.63, 0, 0, 0, 143.61, 233.56);
canvas.lineTo(143.61, 178.03);
canvas.arcTo(29.81, 29.81, 0, 0, 0, 124.31, 150.29);
canvas.close();
canvas.moveTo(71.85, 10.72);
canvas.arcTo(18.46, 18.46, 0, 0, 1, 90.17, 27.18);
canvas.arcTo(47.68, 47.68, 0, 0, 0, 53.53, 27.18);
canvas.arcTo(18.44, 18.44, 0, 0, 1, 71.85, 10.72);
canvas.close();
canvas.moveTo(35.39, 71.23);
canvas.arcTo(36.46, 36.46, 0, 0, 1, 108.31, 71.23);
canvas.lineTo(108.31, 77.4);
canvas.curveTo(82.12, 75.4, 56.97, 60.55, 56.71, 60.4);
canvas.arcTo(5.62, 5.62, 0, 0, 0, 48.78, 62.71);
canvas.curveTo(46.24, 67.79, 40.45, 71.89, 35.39, 74.62);
canvas.close();
canvas.moveTo(35.39, 89.23);
canvas.lineTo(35.39, 87.08);
canvas.curveTo(40.55, 84.85, 49.73, 80.08, 55.67, 72.66);
canvas.curveTo(64.83, 77.46, 85.92, 87.21, 108.31, 88.66);
canvas.lineTo(108.31, 89.24);
canvas.arcTo(36.46, 36.46, 0, 1, 1, 35.39, 89.24);
canvas.close();
canvas.moveTo(71.85, 165.45);
canvas.lineTo(54.06, 147.69);
canvas.arcTo(17.7, 17.7, 0, 0, 0, 59.43, 135.32);
canvas.arcTo(47.57, 47.57, 0, 0, 0, 84.27, 135.32);
canvas.arcTo(17.7, 17.7, 0, 0, 0, 89.64, 147.69);
canvas.close();
canvas.fill();
}
paintGearIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { height: 100, width: 100 });
paintGearIconBackground(canvas);
canvas.translateIconOrigin(14, 14);
paintGearIconForeground(canvas);
}
paintExpandIcon(paintParameter) {
const originalIconSize = { width: 16, height: 16 };
const canvas = this.newBpmnCanvas(paintParameter, originalIconSize);
const w = originalIconSize.width;
const h = originalIconSize.height;
canvas.roundrect(0, 0, w, h, 2, 2);
canvas.stroke();
canvas.begin();
canvas.moveTo(w / 2, h / 4);
canvas.lineTo(w / 2, (h * 3) / 4);
canvas.close();
canvas.moveTo(w / 4, h / 2);
canvas.lineTo((w * 3) / 4, h / 2);
canvas.close();
canvas.fillAndStroke();
}
paintLoopIcon(paintParameter) {
const { iconStyleConfig } = paintParameter;
iconStyleConfig.fillColor = iconStyleConfig.strokeColor;
const canvas = this.newBpmnCanvas(paintParameter, { width: 22.49, height: 21.62 });
canvas.begin();
canvas.moveTo(5.5, 19.08);
canvas.arcTo(8, 8, 0, 1, 1, 10.5, 21.08);
canvas.stroke();
canvas.begin();
canvas.moveTo(7.5, 14.08);
canvas.lineTo(5.75, 19.08);
canvas.lineTo(0, 17.08);
canvas.close();
canvas.fillAndStroke();
}
paintSequentialMultiInstanceIcon(paintParameter) {
const originalIconSize = { width: 16, height: 16 };
const bpmnCanvas = this.newBpmnCanvas(paintParameter, originalIconSize);
const { canvas, iconStyleConfig } = paintParameter;
canvas.setFillColor(iconStyleConfig.strokeColor);
const barWidth = originalIconSize.width;
const barHeight = originalIconSize.height / 5;
bpmnCanvas.rect(0, 0, barWidth, barHeight);
bpmnCanvas.fill();
bpmnCanvas.rect(0, 2 * barHeight, barWidth, barHeight);
bpmnCanvas.fill();
bpmnCanvas.rect(0, 4 * barHeight, barWidth, barHeight);
bpmnCanvas.fill();
}
paintParallelMultiInstanceIcon(paintParameter) {
const originalIconSize = { width: 16, height: 16 };
const bpmnCanvas = this.newBpmnCanvas(paintParameter, originalIconSize);
const { canvas, iconStyleConfig } = paintParameter;
canvas.setFillColor(iconStyleConfig.strokeColor);
const barWidth = originalIconSize.width / 5;
const barHeight = originalIconSize.height;
bpmnCanvas.begin();
bpmnCanvas.rect(0, 0, barWidth, barHeight);
bpmnCanvas.fill();
bpmnCanvas.rect(2 * barWidth, 0, barWidth, barHeight);
bpmnCanvas.fill();
bpmnCanvas.rect(4 * barWidth, 0, barWidth, barHeight);
bpmnCanvas.fill();
}
paintRightArrowIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { width: 512, height: 415.23 });
canvas.setRoundLineJoin();
canvas.begin();
canvas.moveTo(512, 207.61);
canvas.lineTo(304.38, 0);
canvas.lineTo(304.38, 135.39);
canvas.lineTo(0, 135.39);
canvas.lineTo(0, 279.84);
canvas.lineTo(304.38, 279.84);
canvas.lineTo(304.38, 415.23);
canvas.lineTo(512, 207.61);
canvas.close();
canvas.fillAndStroke();
}
paintErrorIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { width: 72.44, height: 71.82 });
canvas.begin();
canvas.moveTo(0, 53.32);
canvas.lineTo(19.48, 0);
canvas.lineTo(19.48, 0);
canvas.lineTo(50.85, 40.07);
canvas.lineTo(72.44, 18.21);
canvas.lineTo(53.12, 71.82);
canvas.lineTo(22.5, 31.37);
canvas.close();
canvas.fillAndStroke();
}
paintHandIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { width: 343.65, height: 354.12 });
canvas.begin();
canvas.moveTo(231.66, 336.39);
canvas.curveTo(240.84, 316.9, 220.53, 306.92, 220.53, 306.92);
canvas.curveTo(215.2, 303.67, 188.58, 287.43, 140.67, 258.19);
canvas.lineTo(146.33, 248.39);
canvas.curveTo(223.98, 269.38, 267.12, 281.04, 275.75, 283.38);
canvas.curveTo(275.75, 283.38, 297.25, 288, 301.42, 267.77);
canvas.curveTo(306.34, 245.29, 288.32, 238.63, 288.32, 238.63);
canvas.curveTo(279.91, 236.44, 237.86, 225.48, 162.18, 205.75);
canvas.lineTo(165.2, 194.8);
canvas.curveTo(255.88, 204.4, 306.27, 209.73, 316.34, 210.8);
canvas.curveTo(316.34, 210.8, 339.89, 212.16, 341.76, 189.55);
canvas.curveTo(343.65, 166.93, 320.5, 164.13, 320.5, 164.13);
canvas.curveTo(310.43, 163.1, 260.04, 157.99, 169.35, 148.77);
canvas.lineTo(169.35, 138.97);
canvas.curveTo(253.41, 132.12, 300.11, 128.32, 309.45, 127.56);
canvas.curveTo(309.45, 127.56, 332.27, 122.38, 332.27, 102.61);
canvas.curveTo(332.27, 82.85, 305.48, 81.87, 305.48, 81.87);
canvas.curveTo(293.99, 82.2, 236.54, 83.88, 133.13, 86.9);
canvas.lineTo(127.61, 81.87);
canvas.curveTo(145.3, 59.39, 155.12, 46.9, 157.09, 44.41);
canvas.curveTo(157.09, 44.41, 171.12, 26.8, 156.78, 12.72);
canvas.curveTo(143.83, 0, 124.08, 14.49, 124.08, 14.49);
canvas.curveTo(116.45, 19.41, 78.35, 44.06, 9.77, 88.43);
canvas.lineTo(0, 251.94);
canvas.curveTo(122.84, 308.79, 191.09, 340.37, 204.74, 346.69);
canvas.curveTo(204.74, 346.69, 222.91, 354.12, 231.66, 336.39);
canvas.fillAndStroke();
}
paintScriptIcon(paintParameter) {
paintParameter.iconStyleConfig.fillColor = paintParameter.iconStyleConfig.strokeColor;
const canvas = this.newBpmnCanvas(paintParameter, { width: 458.75, height: 461.64 });
canvas.begin();
canvas.moveTo(67.85, 0.57);
canvas.curveTo(50.73, 0, 33.26, 8.86, 22.35, 18.84);
canvas.curveTo(8.11, 32.15, 0, 50.77, 0, 70.26);
canvas.curveTo(0, 73.15, 0, 87.59, 0, 113.6);
canvas.curveTo(55.4, 113.6, 86.18, 113.6, 92.33, 113.6);
canvas.curveTo(94.92, 150.46, 85.64, 180.4, 74.22, 211.27);
canvas.curveTo(40.16, 298.07, 30.77, 339.83, 55.56, 410.87);
canvas.curveTo(63.72, 438.26, 87.59, 457.85, 114.91, 461.09);
canvas.curveTo(216.96, 460.85, 294.9, 461.64, 388.41, 461.2);
canvas.curveTo(407.2, 461.09, 425.14, 453.55, 438.3, 440.13);
canvas.curveTo(451.46, 426.71, 458.75, 403.06, 458.46, 384.26);
canvas.curveTo(458.43, 382.23, 458.18, 365.93, 458.15, 363.89);
canvas.curveTo(432.12, 364.24, 406.09, 364.04, 380.06, 364.04);
canvas.curveTo(377.61, 347.52, 377.24, 337.58, 378.28, 324.48);
canvas.curveTo(380.5, 296.47, 389.08, 273.36, 398.59, 247.1);
canvas.curveTo(408.11, 220.83, 418.41, 191.47, 420.86, 154.24);
canvas.curveTo(422.11, 135.34, 421.4, 110.24, 417.77, 86.75);
canvas.curveTo(417.76, 86.71, 417.73, 86.54, 417.69, 86.22);
canvas.curveTo(417.64, 85.95, 417.61, 85.79, 417.6, 85.76);
canvas.curveTo(414.03, 68.13, 410.49, 48.84, 399.79, 31.47);
canvas.curveTo(389.09, 14.11, 366.95, 0.59, 341.75, 0.59);
canvas.curveTo(286.97, 0.59, 122.63, 0.57, 67.85, 0.57);
canvas.close();
canvas.moveTo(85.04, 72.68);
canvas.curveTo(80.63, 72.68, 45.33, 72.68, 40.92, 72.68);
canvas.curveTo(40.46, 58.4, 47.15, 51.87, 50.27, 48.75);
canvas.curveTo(55.8, 44.28, 59.84, 41, 73.82, 41);
canvas.curveTo(78.45, 52.13, 82.23, 62.71, 85.04, 72.68);
canvas.close();
canvas.moveTo(364.94, 52.9);
canvas.curveTo(370, 61.11, 373.9, 76.44, 377.38, 93.51);
canvas.curveTo(380.35, 113.1, 381.01, 136.42, 380.02, 151.57);
canvas.curveTo(377.97, 182.76, 369.51, 207.12, 360.1, 233.1);
canvas.curveTo(350.69, 259.09, 340.27, 286.77, 337.53, 321.27);
canvas.curveTo(336.38, 335.86, 336.72, 346.69, 338.87, 364.01);
canvas.curveTo(326.35, 364.01, 263.75, 364.01, 151.06, 364.01);
canvas.curveTo(151.06, 382.2, 151.06, 392.31, 151.06, 394.33);
canvas.curveTo(147.77, 404.8, 138.9, 418.2, 127.43, 419.94);
canvas.curveTo(111.49, 422.35, 97.86, 411.8, 94.75, 399.19);
canvas.curveTo(65.14, 321.99, 94.93, 275.54, 112.57, 225.47);
canvas.curveTo(130.14, 177.95, 137.92, 117.41, 112.71, 42.09);
canvas.curveTo(192.88, 41.9, 274.33, 42.21, 342.89, 41.98);
canvas.curveTo(357.15, 42.03, 359.83, 44.61, 364.94, 52.9);
canvas.close();
canvas.moveTo(409.96, 399.48);
canvas.curveTo(409.96, 408.42, 398.54, 425.67, 392.02, 425.67);
canvas.curveTo(325.19, 425.79, 252.29, 425.67, 185.23, 425.67);
canvas.curveTo(189.88, 424.43, 194.66, 405.64, 194.66, 399.48);
canvas.curveTo(237.72, 399.48, 388.43, 399.48, 409.96, 399.48);
canvas.close();
canvas.fill();
canvas.begin();
canvas.moveTo(182.1, 131.2);
canvas.lineTo(182.1, 151.68);
canvas.lineTo(321.89, 151.68);
canvas.lineTo(321.89, 131.2);
canvas.lineTo(182.1, 131.2);
canvas.close();
canvas.moveTo(162.25, 251.09);
canvas.lineTo(162.25, 271.49);
canvas.lineTo(301.96, 271.49);
canvas.lineTo(301.96, 251.09);
canvas.lineTo(162.25, 251.09);
canvas.close();
canvas.fill();
}
paintTableIcon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { width: 640, height: 640 });
canvas.begin();
canvas.moveTo(0.19, 0.1);
canvas.lineTo(298.78, 0.1);
canvas.lineTo(298.78, 198.88);
canvas.lineTo(0.19, 198.88);
canvas.lineTo(0.19, 0.1);
canvas.close();
canvas.fillAndStroke();
canvas.begin();
canvas.moveTo(0, 0);
canvas.lineTo(298.78, 0);
canvas.lineTo(298.78, 48.88);
canvas.lineTo(0, 48.88);
canvas.lineTo(0, 0);
canvas.close();
canvas.fillAndStroke();
canvas.begin();
canvas.moveTo(0, 48.88);
canvas.lineTo(98.78, 48.88);
canvas.lineTo(98.78, 198.88);
canvas.lineTo(0, 198.88);
canvas.lineTo(0, 48.88);
canvas.close();
canvas.fillAndStroke();
canvas.begin();
canvas.moveTo(1.09, 122.69);
canvas.lineTo(298.78, 122.69);
canvas.close();
canvas.fillAndStroke();
canvas.setFillColor(paintParameter.iconStyleConfig.strokeColor);
canvas.begin();
canvas.moveTo(0, 0);
canvas.lineTo(298.78, 0);
canvas.lineTo(298.78, 48.88);
canvas.lineTo(0, 48.88);
canvas.lineTo(0, 0);
canvas.close();
canvas.fillAndStroke();
}
paintPentagon(paintParameter) {
const canvas = this.newBpmnCanvas(paintParameter, { width: 16, height: 16 });
canvas.begin();
canvas.moveTo(16, 6.5);
canvas.lineTo(8, 0);
canvas.lineTo(0, 6.5);
canvas.lineTo(3, 16);
canvas.lineTo(13, 16);
canvas.lineTo(16, 6.5);
canvas.lineTo(8, 0);
canvas.stroke();
}
}
function drawVerticalLine(canvas) {
canvas.begin();
canvas.moveTo(0.38, 0);
canvas.lineTo(0.62, 0);
canvas.lineTo(0.62, 1);
canvas.lineTo(0.38, 1);
canvas.close();
}
function paintGearIconBackground(canvas) {
canvas.begin();
canvas.moveTo(2.06, 24.62);
canvas.lineTo(10.17, 30.95);
canvas.lineTo(9.29, 37.73);
canvas.lineTo(0, 41.42);
canvas.lineTo(2.95, 54.24);
canvas.lineTo(13.41, 52.92);
canvas.lineTo(17.39, 58.52);
canvas.lineTo(13.56, 67.66);
canvas.lineTo(24.47, 74.44);
canvas.lineTo(30.81, 66.33);
canvas.lineTo(37.88, 67.21);
canvas.lineTo(41.57, 76.5);
canvas.lineTo(54.24, 73.55);
canvas.lineTo(53.06, 62.94);
canvas.lineTo(58.52, 58.52);
canvas.lineTo(67.21, 63.09);
canvas.lineTo(74.58, 51.88);
canvas.lineTo(66.03, 45.25);
canvas.lineTo(66.92, 38.62);
canvas.lineTo(76.5, 34.93);
canvas.lineTo(73.7, 22.26);
canvas.lineTo(62.64, 23.44);
canvas.lineTo(58.81, 18.42);
canvas.lineTo(62.79, 8.7);
canvas.lineTo(51.74, 2.21);
canvas.lineTo(44.81, 10.47);
canvas.lineTo(38.03, 9.43);
canvas.lineTo(33.75, 0);
canvas.lineTo(21.52, 3.24);
canvas.lineTo(22.7, 13.56);
canvas.lineTo(18.13, 17.54);
canvas.lineTo(8.7, 13.56);
canvas.close();
const arcStartX = 24.8;
const arcStartY = 39;
paintGearInnerCircle(canvas, arcStartX, arcStartY);
}
function paintGearIconForeground(canvas) {
canvas.begin();
canvas.moveTo(16.46, 41.42);
canvas.lineTo(24.57, 47.75);
canvas.lineTo(23.69, 54.53);
canvas.lineTo(14.4, 58.22);
canvas.lineTo(17.35, 71.04);
canvas.lineTo(27.81, 69.72);
canvas.lineTo(31.79, 75.32);
canvas.lineTo(27.96, 84.46);
canvas.lineTo(38.87, 91.24);
canvas.lineTo(45.21, 83.13);
canvas.lineTo(52.28, 84.01);
canvas.lineTo(55.97, 93.3);
canvas.lineTo(68.64, 90.35);
canvas.lineTo(67.46, 79.74);
canvas.lineTo(72.92, 75.32);
canvas.lineTo(81.61, 79.89);
canvas.lineTo(88.98, 68.68);
canvas.lineTo(80.43, 62.05);
canvas.lineTo(81.32, 55.42);
canvas.lineTo(90.9, 51.73);
canvas.lineTo(88.1, 39.06);
canvas.lineTo(77.04, 40.24);
canvas.lineTo(73.21, 35.22);
canvas.lineTo(77.19, 25.5);
canvas.lineTo(66.14, 19.01);
canvas.lineTo(59.21, 27.27);
canvas.lineTo(52.43, 26.23);
canvas.lineTo(48.15, 16.8);
canvas.lineTo(35.92, 20.04);
canvas.lineTo(37.1, 30.36);
canvas.lineTo(32.53, 34.34);
canvas.lineTo(23.1, 30.36);
canvas.close();
const arcStartX = 39.2;
const arcStartY = 55.8;
paintGearInnerCircle(canvas, arcStartX, arcStartY);
canvas.begin();
paintGearInnerCircle(canvas, arcStartX, arcStartY);
}
function paintGearInnerCircle(canvas, arcStartX, arcStartY) {
const arcRay = 13.5;
canvas.moveTo(arcStartX, arcStartY);
canvas.arcTo(arcRay, arcRay, 0, 1, 1, arcStartX + 2 * arcRay, arcStartY);
canvas.arcTo(arcRay, arcRay, 0, 0, 1, arcStartX, arcStartY);
canvas.close();
canvas.fillAndStroke();
}
class IconPainterProvider {
static get() {
return this.instance;
}
static set(painter) {
this.instance = painter;
}
}
Object.defineProperty(IconPainterProvider, "instance", {
enumerable: true,
configurable: true,
writable: true,
value: new IconPainter()
});
const zoomFactorIn = 1.25;
const zoomFactorOut = 1 / zoomFactorIn;
class BpmnGraph extends mxgraph.mxGraph {
constructor(container) {
super(container);
Object.defineProperty(this, "currentZoomLevel", {
enumerable: true,
configurable: true,
writable: true,
value: 1
});
this.zoomFactor = zoomFactorIn;
if (this.container) {
this.container.style.cursor = 'default';
}
}
createGraphView() {
return new BpmnGraphView(this);
}
createCellRenderer() {
return new BpmnCellRenderer(IconPainterProvider.get());
}
batchUpdate(callbackFunction) {
this.model.beginUpdate();
try {
callbackFunction();
}
finally {
this.model.endUpdate();
}
}
fit(border, keepOrigin, margin, enabled, ignoreWidth, ignoreHeight, maxHeight) {
const scale = super.fit(border, keepOrigin, margin, enabled, ignoreWidth, ignoreHeight, maxHeight);
this.setCurrentZoomLevel(scale);
return scale;
}
setCurrentZoomLevel(scale) {
this.currentZoomLevel = scale !== null && scale !== void 0 ? scale : this.view.scale;
}
zoomActual() {
super.zoomActual();
this.setCurrentZoomLevel();
}
zoomIn() {
super.zoomIn();
this.setCurrentZoomLevel();
}
zoomOut() {
super.zoomOut();
this.setCurrentZoomLevel();
}
customFit(fitOptions) {
this.zoomActual();
const type = fitOptions === null || fitOptions === void 0 ? void 0 : fitOptions.type;
if (type == undefined || type == exports.FitType.None) {
return;
}
const margin = ensurePositiveValue(fitOptions === null || fitOptions === void 0 ? void 0 : fitOptions.margin);
if (type == exports.FitType.Center) {
const maxScale = 3;
const bounds = this.getGraphBounds();
const clientWidth = this.container.clientWidth - margin;
const clientHeight = this.container.clientHeight - margin;
const width = bounds.width / this.view.scale;
const height = bounds.height / this.view.scale;
const scale = Math.min(maxScale, Math.min(clientWidth / width, clientHeight / height));
this.setCurrentZoomLevel(scale);
this.view.scaleAndTranslate(scale, (margin + clientWidth - width * scale) / (2 * scale) - bounds.x / this.view.scale, (margin + clientHeight - height * scale) / (2 * scale) - bounds.y / this.view.scale);
}
else {
let ignoreWidth = false;
let ignoreHeight = false;
switch (type) {
case exports.FitType.Horizontal: {
ignoreHeight = true;
break;
}
case exports.FitType.Vertical: {
ignoreWidth = true;
break;
}
}
this.fit(this.border, false, margin, true, ignoreWidth, ignoreHeight);
}
}
registerMouseWheelZoomListeners(config) {
config = ensureValidZoomConfiguration(config);
mxEvent.addMouseWheelListener(debounce(this.createMouseWheelZoomListener(true), config.debounceDelay), this.container);
mxEvent.addMouseWheelListener(throttle(this.createMouseWheelZoomListener(false), config.throttleDelay), this.container);
}
manageMouseWheelZoomEvent(up, event, performScaling) {
if (performScaling) {
const [offsetX, offsetY] = this.getEventRelativeCoordinates(event);
const [newScale, dx, dy] = this.getScaleAndTranslationDeltas(offsetX, offsetY);
this.view.scaleAndTranslate(newScale, this.view.translate.x + dx, this.view.translate.y + dy);
mxEvent.consume(event);
}
else {
this.currentZoomLevel *= up ? zoomFactorIn : zoomFactorOut;
}
}
createMouseWheelZoomListener(performScaling) {
return (event, up) => {
if (mxEvent.isConsumed(event) || !(event instanceof MouseEvent)) {
return;
}
const isZoomWheelEvent = event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey;
if (isZoomWheelEvent) {
this.manageMouseWheelZoomEvent(up, event, performScaling);
}
};
}
getEventRelativeCoordinates(event) {
const rect = this.container.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
return [x, y];
}
getScaleAndTranslationDeltas(offsetX, offsetY) {
const [factor, scale] = this.calculateFactorAndScale();
const [dx, dy] = this.calculateTranslationDeltas(factor, scale, offsetX * 2, offsetY * 2);
return [scale, dx, dy];
}
calculateTranslationDeltas(factor, scale, dx, dy) {
if (factor > 1) {
const f = (factor - 1) / (scale * 2);
dx *= -f;
dy *= -f;
}
else {
const f = (1 / factor - 1) / (this.view.scale * 2);
dx *= f;
dy *= f;
}
return [dx, dy];
}
calculateFactorAndScale() {
const scale = Math.round(this.currentZoomLevel * 100) / 100;
const factor = scale / this.view.scale;
return [factor, scale];
}
}
class BpmnGraphView extends mxgraph.mxGraphView {
getFloatingTerminalPoint(edge, start, end, source) {
const edgePoints = edge.absolutePoints.filter(Boolean);
const needsFloatingTerminalPoint = edgePoints.length < 2;
if (needsFloatingTerminalPoint) {
return super.getFloatingTerminalPoint(edge, start, end, source);
}
const pts = edge.absolutePoints;
return source ? pts[1] : pts.at(-2);
}
}
class MarkerConfigurator {
configureMarkers() {
this.registerArrowDashMarker();
}
registerArrowDashMarker() {
const createMarker = (c, _shape, _type, pe, unitX, unitY, size, _source, strokewidth) => {
const nx = unitX * (size + strokewidth + 4);
const ny = unitY * (size + strokewidth + 4);
return function () {
c.begin();
c.moveTo(pe.x - nx / 2 - ny / 2, pe.y - ny / 2 + nx / 2);
c.lineTo(pe.x + ny / 2 - (3 * nx) / 2, pe.y - (3 * ny) / 2 - nx / 2);
c.stroke();
};
};
mxgraph.mxMarker.addMarker(MarkerIdentifier.ARROW_DASH, createMarker);
}
}
const referenceOrderedMarkers = [
exports.ShapeBpmnMarkerKind.LOOP,
exports.ShapeBpmnMarkerKind.MULTI_INSTANCE_PARALLEL,
exports.ShapeBpmnMarkerKind.MULTI_INSTANCE_SEQUENTIAL,
exports.ShapeBpmnMarkerKind.COMPENSATION,
exports.ShapeBpmnMarkerKind.EXPAND,
exports.ShapeBpmnMarkerKind.ADHOC,
];
function orderActivityMarkers(markers) {
const orderedMarkers = referenceOrderedMarkers.filter(marker => markers.includes(marker));
for (const marker of markers.filter(marker => !orderedMarkers.includes(marker)))
orderedMarkers.push(marker);
return orderedMarkers;
}
function getMarkerIconOriginFunction(numberOfMarkers, markerPosition) {
return numberOfMarkers === 1
? (canvas) => canvas.setIconOriginForIconBottomCentered()
: (canvas) => {
canvas.setIconOriginForIconBottomCentered();
const xTranslation = (Math.pow(-1, markerPosition) * (StyleDefault.SHAPE_ACTIVITY_MARKER_ICON_SIZE + StyleDefault.SHAPE_ACTIVITY_MARKER_ICON_MARGIN)) / 2;
canvas.translateIconOrigin(xTranslation, 0);
};
}
class BaseActivityShape extends mxRectangleShape {
constructor() {
super(undefined, undefined, undefined);
Object.defineProperty(this, "iconPainter", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
Object.defineProperty(this, "markerPainterFunctions", {
enumerable: true,
configurable: true,
writable: true,
value: new Map([
[exports.ShapeBpmnMarkerKind.EXPAND, (paintParameter) => this.iconPainter.paintExpandIcon(paintParameter)],
[exports.ShapeBpmnMarkerKind.LOOP, (paintParameter) => this.iconPainter.paintLoopIcon(paintParameter)],
[exports.ShapeBpmnMarkerKind.MULTI_INSTANCE_PARALLEL, (paintParameter) => this.iconPainter.paintParallelMultiInstanceIcon(paintParameter)],
[exports.ShapeBpmnMarkerKind.MULTI_INSTANCE_SEQUENTIAL, (paintParameter) => this.iconPainter.paintSequentialMultiInstanceIcon(paintParameter)],
])
});
}
paintForeground(c, x, y, w, h) {
super.paintForeground(c, x, y, w, h);
this.paintMarkerIcons(buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this, ratioFromParent: 0, iconStrokeWidth: 1.5 }));
}
paintMarkerIcons(paintParameter) {
var _a;
const markers = mxUtils.getValue(this.style, BpmnStyleIdentifier.MARKERS, undefined);
if (markers) {
const orderedMarkers = orderActivityMarkers(markers.split(','));
for (const [index, marker] of orderedMarkers.entries()) {
paintParameter = Object.assign(Object.assign({}, paintParameter), { setIconOriginFunct: getMarkerIconOriginFunction(orderedMarkers.length, index + 1) });
paintParameter.canvas.save();
(_a = this.markerPainterFunctions.get(marker)) === null || _a === void 0 ? void 0 : _a(paintParameter);
paintParameter.canvas.restore();
}
}
}
paintEnvelopeIcon(paintParameter, isFilled) {
this.iconPainter.paintEnvelopeIcon(Object.assign(Object.assign({}, paintParameter), { setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeft(), ratioFromParent: 0.2, iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { isFilled: isFilled }) }));
}
}
class BaseTaskShape extends BaseActivityShape {
paintForeground(c, x, y, w, h) {
super.paintForeground(c, x, y, w, h);
this.paintTaskIcon(buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this }));
}
}
class TaskShape extends BaseTaskShape {
paintTaskIcon(_paintParameter) {
}
}
class ServiceTaskShape extends BaseTaskShape {
paintTaskIcon(paintParameter) {
this.iconPainter.paintGearIcon(Object.assign(Object.assign({}, paintParameter), { setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(20) }));
}
}
class UserTaskShape extends BaseTaskShape {
paintTaskIcon(paintParameter) {
this.iconPainter.paintPersonIcon(Object.assign(Object.assign({}, paintParameter), { setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(20) }));
}
}
class ReceiveTaskShape extends BaseTaskShape {
paintTaskIcon(paintParameter) {
if (!getBpmnIsInstantiating(this.style)) {
this.paintEnvelopeIcon(paintParameter, false);
return;
}
const leftMargin = 4;
const topMargin = 4;
const circleShapeConfig = Object.assign(Object.assign({}, paintParameter.shapeConfig), { width: 20, height: 20 });
this.iconPainter.paintCircleIcon({
canvas: paintParameter.canvas,
shapeConfig: circleShapeConfig,
iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { isFilled: false }),
ratioFromParent: undefined,
setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeft(topMargin, leftMargin),
});
circleShapeConfig.x += leftMargin;
circleShapeConfig.y += topMargin;
this.iconPainter.paintEnvelopeIcon(Object.assign(Object.assign({}, paintParameter), { shapeConfig: circleShapeConfig, ratioFromParent: 0.65, setIconOriginFunct: (canvas) => canvas.setIconOriginForIconCentered() }));
}
}
class SendTaskShape extends BaseTaskShape {
paintTaskIcon(paintParameter) {
this.paintEnvelopeIcon(paintParameter, true);
}
}
class ManualTaskShape extends BaseTaskShape {
paintTaskIcon(paintParameter) {
this.iconPainter.paintHandIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.18, setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(20) }));
}
}
class ScriptTaskShape extends BaseTaskShape {
paintTaskIcon(paintParameter) {
this.iconPainter.paintScriptIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.22, setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(20) }));
}
}
class CallActivityShape extends BaseActivityShape {
paintForeground(c, x, y, w, h) {
super.paintForeground(c, x, y, w, h);
const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this });
switch (mxUtils.getValue(this.style, BpmnStyleIdentifier.GLOBAL_TASK_KIND, undefined)) {
case exports.ShapeBpmnElementKind.GLOBAL_TASK_MANUAL: {
this.iconPainter.paintHandIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.18, setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(20) }));
break;
}
case exports.ShapeBpmnElementKind.GLOBAL_TASK_SCRIPT: {
this.iconPainter.paintScriptIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.22, setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(20) }));
break;
}
case exports.ShapeBpmnElementKind.GLOBAL_TASK_USER: {
this.iconPainter.paintPersonIcon(Object.assign(Object.assign({}, paintParameter), { setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(20) }));
break;
}
case exports.ShapeBpmnElementKind.GLOBAL_TASK_BUSINESS_RULE: {
this.iconPainter.paintTableIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.6, setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(15) }));
break;
}
}
}
}
class SubProcessShape extends BaseActivityShape {
paintBackground(c, x, y, w, h) {
const subProcessKind = mxUtils.getValue(this.style, BpmnStyleIdentifier.SUB_PROCESS_KIND, undefined);
c.save();
if (subProcessKind === exports.ShapeBpmnSubProcessKind.EVENT) {
c.setDashed(true, false);
c.setDashPattern('1 2');
}
super.paintBackground(c, x, y, w, h);
if (subProcessKind === exports.ShapeBpmnSubProcessKind.TRANSACTION) {
const innerOffset = StyleDefault.SUB_PROCESS_TRANSACTION_INNER_RECT_OFFSET;
const innerArcSize = StyleDefault.SUB_PROCESS_TRANSACTION_INNER_RECT_ARC_SIZE;
c.roundrect(x + innerOffset, y + innerOffset, w - 2 * innerOffset, h - 2 * innerOffset, innerArcSize, innerArcSize);
c.stroke();
}
c.restore();
}
}
class BusinessRuleTaskShape extends BaseTaskShape {
paintTaskIcon(paintParameter) {
this.iconPainter.paintTableIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.6, setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(15) }));
}
}
class BpmnConnector extends mxgraph.mxConnector {
paintEdgeShape(c, pts) {
const sourceMarker = this.createMarker(c, pts, true);
const targetMarker = this.createMarker(c, pts, false);
this.paintEdgeLine(c, pts);
c.setShadow(false);
c.setDashed(false, false);
if (sourceMarker != null) {
c.setFillColor(mxUtils.getValue(this.style, BpmnStyleIdentifier.EDGE_START_FILL_COLOR, this.stroke));
sourceMarker();
}
if (targetMarker != null) {
c.setFillColor(mxUtils.getValue(this.style, BpmnStyleIdentifier.EDGE_END_FILL_COLOR, this.stroke));
targetMarker();
}
}
paintEdgeLine(c, pts) {
const previous = getPointerEventsValue(c);
setPointerEventsValue(c, 'stroke');
this.paintLine(c, pts, this.isRounded);
setPointerEventsValue(c, previous);
}
}
function getPointerEventsValue(c) {
return c instanceof mxSvgCanvas2D ? c.pointerEventsValue : null;
}
function setPointerEventsValue(c, value) {
if (c instanceof mxSvgCanvas2D) {
c.pointerEventsValue = value;
}
}
class EventShape extends mxgraph.mxEllipse {
constructor() {
super(undefined, undefined, undefined);
Object.defineProperty(this, "iconPainter", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
Object.defineProperty(this, "iconPainters", {
enumerable: true,
configurable: true,
writable: true,
value: new Map([
[exports.ShapeBpmnEventDefinitionKind.MESSAGE, (paintParameter) => this.iconPainter.paintEnvelopeIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.5 }))],
[exports.ShapeBpmnEventDefinitionKind.TERMINATE, (paintParameter) => this.iconPainter.paintCircleIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.6 }))],
[
exports.ShapeBpmnEventDefinitionKind.TIMER,
(paintParameter) => this.iconPainter.paintClockIcon(Object.assign(Object.assign({}, paintParameter), { setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(5) })),
],
[
exports.ShapeBpmnEventDefinitionKind.SIGNAL,
(paintParameter) => this.iconPainter.paintTriangleIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.55, iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { strokeWidth: StyleDefault.STROKE_WIDTH_THIN.valueOf() }), setIconOriginFunct: (canvas) => canvas.setIconOriginToShapeTopLeftProportionally(4) })),
],
[
exports.ShapeBpmnEventDefinitionKind.LINK,
(paintParameter) => this.iconPainter.paintRightArrowIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.55, iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { strokeWidth: 1.5 }) })),
],
[
exports.ShapeBpmnEventDefinitionKind.ERROR,
(paintParameter) => this.iconPainter.paintErrorIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.55, iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { strokeWidth: 1.5 }) })),
],
[
exports.ShapeBpmnEventDefinitionKind.COMPENSATION,
(paintParameter) => this.iconPainter.paintDoubleLeftArrowheadsIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.7, iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { strokeWidth: 1.5 }) })),
],
[exports.ShapeBpmnEventDefinitionKind.CANCEL, (paintParameter) => this.iconPainter.paintXCrossIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.78 }))],
[
exports.ShapeBpmnEventDefinitionKind.ESCALATION,
(paintParameter) => this.iconPainter.paintUpArrowheadIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.55, iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { strokeWidth: StyleDefault.STROKE_WIDTH_THIN.valueOf() }) })),
],
[
exports.ShapeBpmnEventDefinitionKind.CONDITIONAL,
(paintParameter) => this.iconPainter.paintListIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.6, iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { strokeWidth: 1.5 }) })),
],
])
});
Object.defineProperty(this, "withFilledIcon", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
}
paintVertexShape(c, x, y, w, h) {
const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this, isFilled: this.withFilledIcon });
setDashedOuterShapePattern(paintParameter, mxUtils.getValue(this.style, BpmnStyleIdentifier.IS_INTERRUPTING, undefined));
this.paintOuterShape(paintParameter);
restoreOriginalOuterShapePattern(paintParameter);
this.paintInnerShape(paintParameter);
}
paintOuterShape({ canvas, shapeConfig: { x, y, width, height } }) {
super.paintVertexShape(canvas, x, y, width, height);
}
paintInnerShape(paintParameter) {
const paintIcon = this.iconPainters.get(mxUtils.getValue(this.style, BpmnStyleIdentifier.EVENT_DEFINITION_KIND, exports.ShapeBpmnEventDefinitionKind.NONE));
paintIcon === null || paintIcon === void 0 ? void 0 : paintIcon(paintParameter);
}
}
function setDashedOuterShapePattern(paintParameter, isInterrupting) {
paintParameter.canvas.save();
if (isInterrupting === 'false') {
paintParameter.canvas.setDashed(true, false);
paintParameter.canvas.setDashPattern('3 2');
}
}
function restoreOriginalOuterShapePattern(paintParameter) {
paintParameter.canvas.restore();
}
class EndEventShape extends EventShape {
constructor() {
super();
this.withFilledIcon = true;
}
}
class IntermediateEventShape extends EventShape {
paintOuterShape({ canvas, shapeConfig: { x, y, width, height, strokeWidth } }) {
canvas.ellipse(x, y, width, height);
canvas.fillAndStroke();
const inset = strokeWidth * 1.5;
canvas.ellipse(width * 0.02 + inset + x, height * 0.02 + inset + y, width * 0.96 - 2 * inset, height * 0.96 - 2 * inset);
canvas.stroke();
}
}
class ThrowIntermediateEventShape extends IntermediateEventShape {
constructor() {
super();
this.withFilledIcon = true;
}
}
class MessageFlowIconShape extends mxRectangleShape {
constructor() {
super(...arguments);
Object.defineProperty(this, "iconPainter", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
}
paintVertexShape(c, x, y, w, h) {
const paintParameter = buildPaintParameter({
canvas: c,
x,
y,
width: w,
height: h,
shape: this,
ratioFromParent: 1,
isFilled: mxUtils.getValue(this.style, BpmnStyleIdentifier.IS_INITIATING, 'true') == 'false',
});
this.iconPainter.paintEnvelopeIcon(paintParameter);
}
}
class GatewayShape extends mxgraph.mxRhombus {
constructor() {
super(...arguments);
Object.defineProperty(this, "iconPainter", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
}
paintVertexShape(c, x, y, w, h) {
const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this });
this.paintOuterShape(paintParameter);
this.paintInnerShape(paintParameter);
}
paintOuterShape({ canvas, shapeConfig: { x, y, width, height } }) {
super.paintVertexShape(canvas, x, y, width, height);
}
}
class ExclusiveGatewayShape extends GatewayShape {
paintInnerShape(paintParameter) {
this.iconPainter.paintXCrossIcon(Object.assign(Object.assign({}, paintParameter), { iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { isFilled: true }), ratioFromParent: 0.5 }));
}
}
class ParallelGatewayShape extends GatewayShape {
paintInnerShape(paintParameter) {
this.iconPainter.paintPlusCrossIcon(Object.assign(Object.assign({}, paintParameter), { iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { isFilled: true }), ratioFromParent: 0.5 }));
}
}
class InclusiveGatewayShape extends GatewayShape {
paintInnerShape(paintParameter) {
this.iconPainter.paintCircleIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.62, iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { isFilled: false, strokeWidth: StyleDefault.STROKE_WIDTH_THICK.valueOf() }) }));
}
}
class ComplexGatewayShape extends GatewayShape {
paintInnerShape(paintParameter) {
this.iconPainter.paintAsteriskIcon(Object.assign(Object.assign({}, paintParameter), { iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { isFilled: true }), ratioFromParent: 0.5 }));
}
}
class EventBasedGatewayShape extends GatewayShape {
paintInnerShape(paintParameter) {
paintParameter = Object.assign(Object.assign({}, paintParameter), { iconStyleConfig: Object.assign(Object.assign({}, paintParameter.iconStyleConfig), { strokeWidth: 1 }) });
this.iconPainter.paintCircleIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.55 }));
if (!getBpmnIsInstantiating(this.style)) {
this.iconPainter.paintCircleIcon(Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.45 }));
}
const innerIconPaintParameter = Object.assign(Object.assign({}, paintParameter), { ratioFromParent: 0.3 });
if (mxUtils.getValue(this.style, BpmnStyleIdentifier.EVENT_BASED_GATEWAY_KIND, exports.ShapeBpmnEventBasedGatewayKind.Exclusive) == exports.ShapeBpmnEventBasedGatewayKind.Parallel) {
this.iconPainter.paintPlusCrossIcon(innerIconPaintParameter);
}
else {
this.iconPainter.paintPentagon(innerIconPaintParameter);
}
}
}
class TextAnnotationShape extends mxRectangleShape {
paintForeground(c, x, y, _w, h) {
c.begin();
c.moveTo(x + StyleDefault.TEXT_ANNOTATION_BORDER_LENGTH, y);
c.lineTo(x, y);
c.lineTo(x, y + h);
c.lineTo(x + StyleDefault.TEXT_ANNOTATION_BORDER_LENGTH, y + h);
c.stroke();
}
paintBackground(c, x, y, w, h) {
c.save();
c.setStrokeColor('none');
super.paintBackground(c, x, y, w, h);
c.restore();
}
}
const registerShapes = () => {
const shapesToRegister = [
[exports.ShapeBpmnElementKind.EVENT_END, EndEventShape],
[exports.ShapeBpmnElementKind.EVENT_START, EventShape],
[exports.ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW, ThrowIntermediateEventShape],
[exports.ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, IntermediateEventShape],
[exports.ShapeBpmnElementKind.EVENT_BOUNDARY, IntermediateEventShape],
[exports.ShapeBpmnElementKind.GATEWAY_COMPLEX, ComplexGatewayShape],
[exports.ShapeBpmnElementKind.GATEWAY_EVENT_BASED, EventBasedGatewayShape],
[exports.ShapeBpmnElementKind.GATEWAY_EXCLUSIVE, ExclusiveGatewayShape],
[exports.ShapeBpmnElementKind.GATEWAY_INCLUSIVE, InclusiveGatewayShape],
[exports.ShapeBpmnElementKind.GATEWAY_PARALLEL, ParallelGatewayShape],
[exports.ShapeBpmnElementKind.SUB_PROCESS, SubProcessShape],
[exports.ShapeBpmnElementKind.CALL_ACTIVITY, CallActivityShape],
[exports.ShapeBpmnElementKind.TASK, TaskShape],
[exports.ShapeBpmnElementKind.TASK_SERVICE, ServiceTaskShape],
[exports.ShapeBpmnElementKind.TASK_USER, UserTaskShape],
[exports.ShapeBpmnElementKind.TASK_RECEIVE, ReceiveTaskShape],
[exports.ShapeBpmnElementKind.TASK_SEND, SendTaskShape],
[exports.ShapeBpmnElementKind.TASK_MANUAL, ManualTaskShape],
[exports.ShapeBpmnElementKind.TASK_SCRIPT, ScriptTaskShape],
[exports.ShapeBpmnElementKind.TASK_BUSINESS_RULE, BusinessRuleTaskShape],
[exports.ShapeBpmnElementKind.TEXT_ANNOTATION, TextAnnotationShape],
[BpmnStyleIdentifier.EDGE, BpmnConnector],
[BpmnStyleIdentifier.MESSAGE_FLOW_ICON, MessageFlowIconShape],
];
for (const [shapeName, shapeClass] of shapesToRegister) {
mxCellRenderer.registerShape(shapeName, shapeClass);
}
};
class ShapeConfigurator {
configureShapes() {
registerShapes();
}
}
const arrowDefaultSize = 12;
class MapWithDefault extends Map {
get(key) {
var _a;
return ((_a = super.get(key)) !== null && _a !== void 0 ? _a : (() => {
}));
}
}
const specificFlowStyles = new MapWithDefault([
[
exports.FlowKind.SEQUENCE_FLOW,
(style) => {
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_BLOCK_THIN;
},
],
[
exports.FlowKind.MESSAGE_FLOW,
(style) => {
style[mxConstants.STYLE_DASHED] = true;
style[mxConstants.STYLE_DASH_PATTERN] = '8 5';
style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_OVAL;
style[mxConstants.STYLE_STARTSIZE] = 8;
style[mxConstants.STYLE_STARTFILL] = true;
style[BpmnStyleIdentifier.EDGE_START_FILL_COLOR] = StyleDefault.MESSAGE_FLOW_MARKER_START_FILL_COLOR;
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_BLOCK_THIN;
style[mxConstants.STYLE_ENDFILL] = true;
style[BpmnStyleIdentifier.EDGE_END_FILL_COLOR] = StyleDefault.MESSAGE_FLOW_MARKER_END_FILL_COLOR;
},
],
[
exports.FlowKind.ASSOCIATION_FLOW,
(style) => {
style[mxConstants.STYLE_DASHED] = true;
style[mxConstants.STYLE_DASH_PATTERN] = '1 2';
style[mxConstants.STYLE_STARTSIZE] = arrowDefaultSize;
},
],
]);
const specificSequenceFlowStyles = new MapWithDefault([
[
exports.SequenceFlowKind.DEFAULT,
(style) => {
style[mxConstants.STYLE_STARTARROW] = MarkerIdentifier.ARROW_DASH;
},
],
[
exports.SequenceFlowKind.CONDITIONAL_FROM_ACTIVITY,
(style) => {
style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_DIAMOND_THIN;
style[mxConstants.STYLE_STARTSIZE] = 18;
style[mxConstants.STYLE_STARTFILL] = true;
style[BpmnStyleIdentifier.EDGE_START_FILL_COLOR] = StyleDefault.SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR;
},
],
]);
const specificAssociationFlowStyles = new MapWithDefault([
[
exports.AssociationDirectionKind.NONE,
(_style) => {
},
],
[
exports.AssociationDirectionKind.ONE,
(style) => {
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_OPEN_THIN;
},
],
[
exports.AssociationDirectionKind.BOTH,
(style) => {
style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_OPEN_THIN;
style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_OPEN_THIN;
},
],
]);
class StyleConfigurator {
constructor(graph) {
Object.defineProperty(this, "graph", {
enumerable: true,
configurable: true,
writable: true,
value: graph
});
}
configureStyles() {
this.configureDefaultVertexStyle();
this.configurePoolStyle();
this.configureLaneStyle();
this.configureTextAnnotationStyle();
this.configureGroupStyle();
this.configureActivityStyles();
this.configureEventStyles();
this.configureGatewayStyles();
this.configureDefaultEdgeStyle();
this.configureFlowStyles();
}
getStylesheet() {
return this.graph.getStylesheet();
}
putCellStyle(name, style) {
this.getStylesheet().putCellStyle(name, style);
}
configureDefaultVertexStyle() {
const style = this.getStylesheet().getDefaultVertexStyle();
configureCommonDefaultStyle(style);
style[mxConstants.STYLE_ABSOLUTE_ARCSIZE] = true;
style[mxConstants.STYLE_ARCSIZE] = StyleDefault.SHAPE_ARC_SIZE;
}
configurePoolStyle() {
const style = {};
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_SWIMLANE;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_STARTSIZE] = StyleDefault.POOL_LABEL_SIZE;
style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.POOL_LABEL_FILL_COLOR;
this.graph.getStylesheet().putCellStyle(exports.ShapeBpmnElementKind.POOL, style);
}
configureLaneStyle() {
const style = {};
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_SWIMLANE;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_SWIMLANE_LINE] = 0;
style[mxConstants.STYLE_STARTSIZE] = StyleDefault.LANE_LABEL_SIZE;
style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.LANE_LABEL_FILL_COLOR;
this.graph.getStylesheet().putCellStyle(exports.ShapeBpmnElementKind.LANE, style);
}
configureEventStyles() {
for (const kind of ShapeUtil.eventKinds()) {
const style = {};
style[mxConstants.STYLE_SHAPE] = kind;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.EllipsePerimeter;
style[mxConstants.STYLE_STROKEWIDTH] = kind == exports.ShapeBpmnElementKind.EVENT_END ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN;
style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = mxConstants.ALIGN_BOTTOM;
this.putCellStyle(kind, style);
}
}
configureTextAnnotationStyle() {
const style = {};
style[mxConstants.STYLE_SHAPE] = exports.ShapeBpmnElementKind.TEXT_ANNOTATION;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_LEFT;
style[mxConstants.STYLE_SPACING_LEFT] = 5;
style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.TEXT_ANNOTATION_FILL_COLOR;
style[mxConstants.STYLE_STROKEWIDTH] = StyleDefault.STROKE_WIDTH_THIN;
this.putCellStyle(exports.ShapeBpmnElementKind.TEXT_ANNOTATION, style);
}
configureGroupStyle() {
const style = {};
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_DASHED] = true;
style[mxConstants.STYLE_DASH_PATTERN] = '7 4 1 4';
style[mxConstants.STYLE_STROKEWIDTH] = StyleDefault.STROKE_WIDTH_THIN;
style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.GROUP_FILL_COLOR;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_TOP;
this.putCellStyle(exports.ShapeBpmnElementKind.GROUP, style);
}
configureActivityStyles() {
for (const kind of ShapeUtil.activityKinds()) {
const style = {};
style[mxConstants.STYLE_SHAPE] = kind;
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_STROKEWIDTH] = kind == exports.ShapeBpmnElementKind.CALL_ACTIVITY ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN;
this.putCellStyle(kind, style);
}
}
configureGatewayStyles() {
for (const kind of ShapeUtil.gatewayKinds()) {
const style = {};
style[mxConstants.STYLE_SHAPE] = kind;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RhombusPerimeter;
style[mxConstants.STYLE_STROKEWIDTH] = StyleDefault.STROKE_WIDTH_THIN;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_TOP;
style[mxConstants.STYLE_LABEL_POSITION] = mxConstants.ALIGN_LEFT;
style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = mxConstants.ALIGN_TOP;
this.putCellStyle(kind, style);
}
}
configureDefaultEdgeStyle() {
const style = this.getStylesheet().getDefaultEdgeStyle();
configureCommonDefaultStyle(style);
style[mxConstants.STYLE_SHAPE] = BpmnStyleIdentifier.EDGE;
style[mxConstants.STYLE_ENDSIZE] = arrowDefaultSize;
style[mxConstants.STYLE_STROKEWIDTH] = 1.5;
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_ARCSIZE] = 5;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_BOTTOM;
delete style[mxConstants.STYLE_ENDARROW];
}
configureEdgeStyles(styleKinds, specificStyles) {
for (const kind of styleKinds) {
const style = {};
specificStyles.get(kind)(style);
this.graph.getStylesheet().putCellStyle(kind.toString(), style);
}
}
configureFlowStyles() {
this.configureEdgeStyles(Object.values(exports.FlowKind), specificFlowStyles);
this.configureEdgeStyles(Object.values(exports.SequenceFlowKind), specificSequenceFlowStyles);
this.configureEdgeStyles(Object.values(exports.AssociationDirectionKind), specificAssociationFlowStyles);
}
}
function configureCommonDefaultStyle(style) {
style[mxConstants.STYLE_FONTFAMILY] = StyleDefault.DEFAULT_FONT_FAMILY;
style[mxConstants.STYLE_FONTSIZE] = StyleDefault.DEFAULT_FONT_SIZE;
style[mxConstants.STYLE_FONTCOLOR] = StyleDefault.DEFAULT_FONT_COLOR;
style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.DEFAULT_FILL_COLOR;
style[mxConstants.STYLE_STROKECOLOR] = StyleDefault.DEFAULT_STROKE_COLOR;
style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR] = mxConstants.NONE;
style[mxConstants.STYLE_WHITE_SPACE] = 'wrap';
}
class GraphConfigurator {
constructor(container) {
Object.defineProperty(this, "graph", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.graph = new BpmnGraph(container);
}
configure(options) {
this.configureGraph();
this.configureNavigationSupport(options);
new StyleConfigurator(this.graph).configureStyles();
new ShapeConfigurator().configureShapes();
new MarkerConfigurator().configureMarkers();
return this.graph;
}
configureGraph() {
this.graph.setCellsLocked(true);
this.graph.setCellsSelectable(false);
this.graph.setEdgeLabelsMovable(false);
this.graph.setHtmlLabels(true);
this.graph.setConstrainChildren(false);
this.graph.setExtendParents(false);
this.graph.foldingEnabled = false;
}
configureNavigationSupport(options) {
var _a;
const panningHandler = this.graph.panningHandler;
if ((_a = options === null || options === void 0 ? void 0 : options.navigation) === null || _a === void 0 ? void 0 : _a.enabled) {
panningHandler.addListener(mxEvent.PAN_START, setContainerCursor(this.graph, 'grab'));
panningHandler.addListener(mxEvent.PAN_END, setContainerCursor(this.graph, 'default'));
panningHandler.usePopupTrigger = false;
panningHandler.isForcePanningEvent = (me) => mxEvent.isLeftMouseButton(me.getEvent()) || mxEvent.isMultiTouchEvent(me.getEvent());
this.graph.setPanning(true);
this.graph.registerMouseWheelZoomListeners(options.navigation.zoom);
}
else {
this.graph.setPanning(false);
panningHandler.setPinchEnabled(false);
panningHandler.isForcePanningEvent = (_me) => false;
}
}
}
function setContainerCursor(graph, cursor) {
return () => {
graph.container.style.cursor = cursor;
};
}
class Navigation {
constructor(graph) {
Object.defineProperty(this, "graph", {
enumerable: true,
configurable: true,
writable: true,
value: graph
});
}
fit(options) {
this.graph.customFit(options);
}
zoom(type) {
type == 'in' ? this.graph.zoomIn() : this.graph.zoomOut();
}
}
class CategoryConverter {
constructor(convertedElements) {
Object.defineProperty(this, "convertedElements", {
enumerable: true,
configurable: true,
writable: true,
value: convertedElements
});
}
deserialize(definitions) {
const categoryValues = ensureIsArray(definitions.category).flatMap(category => ensureIsArray(category.categoryValue));
for (const categoryValue of categoryValues) {
this.convertedElements.registerCategoryValue(categoryValue.id, categoryValue.value);
}
}
}
class JsonParsingWarning {
}
class ParsingMessageCollector {
constructor(options) {
Object.defineProperty(this, "options", {
enumerable: true,
configurable: true,
writable: true,
value: options
});
}
warning(warning) {
var _a;
if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.disableConsoleLog) {
return;
}
const message = warning.getMessage();
console.warn(`[bv-parser] ${message.template}`, ...message.arguments);
}
}
class GroupUnknownCategoryValueWarning extends JsonParsingWarning {
constructor(groupBpmnElementId, categoryValueReference) {
super();
Object.defineProperty(this, "groupBpmnElementId", {
enumerable: true,
configurable: true,
writable: true,
value: groupBpmnElementId
});
Object.defineProperty(this, "categoryValueReference", {
enumerable: true,
configurable: true,
writable: true,
value: categoryValueReference
});
}
getMessage() {
return {
arguments: [this.categoryValueReference, this.groupBpmnElementId],
template: 'Group json deserialization: unable to find category value ref %s for bpmn element %s',
};
}
}
class ShapeUnknownBpmnElementWarning extends JsonParsingWarning {
constructor(bpmnElementId) {
super();
Object.defineProperty(this, "bpmnElementId", {
enumerable: true,
configurable: true,
writable: true,
value: bpmnElementId
});
}
getMessage() {
return {
arguments: [this.bpmnElementId],
template: 'Shape json deserialization: unable to find bpmn element with id %s',
};
}
}
class EdgeUnknownBpmnElementWarning extends JsonParsingWarning {
constructor(bpmnElementId) {
super();
Object.defineProperty(this, "bpmnElementId", {
enumerable: true,
configurable: true,
writable: true,
value: bpmnElementId
});
}
getMessage() {
return {
arguments: [this.bpmnElementId],
template: 'Edge json deserialization: unable to find bpmn element with id %s',
};
}
}
class LabelStyleMissingFontWarning extends JsonParsingWarning {
constructor(shapeOrEdgeId, labelStyleId) {
super();
Object.defineProperty(this, "shapeOrEdgeId", {
enumerable: true,
configurable: true,
writable: true,
value: shapeOrEdgeId
});
Object.defineProperty(this, "labelStyleId", {
enumerable: true,
configurable: true,
writable: true,
value: labelStyleId
});
}
getMessage() {
return {
arguments: [this.labelStyleId, this.shapeOrEdgeId],
template: 'Unable to assign font from style %s to shape/edge %s',
};
}
}
class LaneUnknownFlowNodeReferenceWarning extends JsonParsingWarning {
constructor(laneId, flowNodeReference) {
super();
Object.defineProperty(this, "laneId", {
enumerable: true,
configurable: true,
writable: true,
value: laneId
});
Object.defineProperty(this, "flowNodeReference", {
enumerable: true,
configurable: true,
writable: true,
value: flowNodeReference
});
}
getMessage() {
return {
arguments: [this.flowNodeReference, this.laneId],
template: 'Unable to assign lane %s as parent: flow node %s is not found',
};
}
}
class BoundaryEventNotAttachedToActivityWarning extends JsonParsingWarning {
constructor(bpmnElementId, attachedToReference, attachedToKind) {
super();
Object.defineProperty(this, "bpmnElementId", {
enumerable: true,
configurable: true,
writable: true,
value: bpmnElementId
});
Object.defineProperty(this, "attachedToReference", {
enumerable: true,
configurable: true,
writable: true,
value: attachedToReference
});
Object.defineProperty(this, "attachedToKind", {
enumerable: true,
configurable: true,
writable: true,
value: attachedToKind
});
}
getMessage() {
return {
arguments: [this.bpmnElementId, this.attachedToReference, this.attachedToKind],
template: 'The boundary event %s must be attached to an activity, and not to %s of kind %s',
};
}
}
class ConvertedElements {
constructor() {
Object.defineProperty(this, "poolsById", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "poolsByProcessRef", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "messageFlows", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "flowNodes", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "lanes", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "sequenceFlows", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "associationFlows", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "eventDefinitionsOfDefinitions", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "globalTasks", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "categoryValues", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
}
getFlows() {
return [...this.messageFlows.values(), ...this.sequenceFlows.values(), ...this.associationFlows.values()];
}
findPoolById(id) {
return this.poolsById.get(id);
}
findPoolByProcessRef(processReference) {
return this.poolsByProcessRef.get(processReference);
}
registerPool(pool, processReference) {
this.poolsById.set(pool.id, pool);
if (processReference) {
this.poolsByProcessRef.set(processReference, pool);
}
}
findMessageFlow(id) {
return this.messageFlows.get(id);
}
registerMessageFlow(messageFlow) {
this.messageFlows.set(messageFlow.id, messageFlow);
}
findFlowNode(id) {
return this.flowNodes.get(id);
}
registerFlowNode(flowNode) {
this.flowNodes.set(flowNode.id, flowNode);
}
findLane(id) {
return this.lanes.get(id);
}
registerLane(lane) {
this.lanes.set(lane.id, lane);
}
findSequenceFlow(id) {
return this.sequenceFlows.get(id);
}
registerSequenceFlow(sequenceFlow) {
this.sequenceFlows.set(sequenceFlow.id, sequenceFlow);
}
findAssociationFlow(id) {
return this.associationFlows.get(id);
}
registerAssociationFlow(associationFlow) {
this.associationFlows.set(associationFlow.id, associationFlow);
}
findEventDefinitionOfDefinition(id) {
return this.eventDefinitionsOfDefinitions.get(id);
}
registerEventDefinitionsOfDefinition(id, eventDefinition) {
this.eventDefinitionsOfDefinitions.set(id, eventDefinition);
}
findGlobalTask(id) {
return this.globalTasks.get(id);
}
registerGlobalTask(id, kind) {
this.globalTasks.set(id, kind);
}
findCategoryValue(categoryValue) {
return this.categoryValues.get(categoryValue);
}
registerCategoryValue(id, value) {
this.categoryValues.set(id, { value });
}
}
const buildShapeBpmnGroup = (convertedElements, parsingMessageCollector, groupBpmnElement, processId) => {
const categoryValueData = convertedElements.findCategoryValue(groupBpmnElement.categoryValueRef);
if (categoryValueData) {
return new ShapeBpmnElement(groupBpmnElement.id, categoryValueData.value, exports.ShapeBpmnElementKind.GROUP, processId);
}
parsingMessageCollector.warning(new GroupUnknownCategoryValueWarning(groupBpmnElement.id, groupBpmnElement.categoryValueRef));
return undefined;
};
const convertAndRegisterAssociationFlows = (convertedElements, bpmnElements) => {
for (const association of ensureIsArray(bpmnElements)) {
const direction = association.associationDirection;
convertedElements.registerAssociationFlow(new AssociationFlow(association.id, undefined, association.sourceRef, association.targetRef, direction));
}
};
class CollaborationConverter {
constructor(convertedElements, parsingMessageCollector) {
Object.defineProperty(this, "convertedElements", {
enumerable: true,
configurable: true,
writable: true,
value: convertedElements
});
Object.defineProperty(this, "parsingMessageCollector", {
enumerable: true,
configurable: true,
writable: true,
value: parsingMessageCollector
});
}
deserialize(collaborations) {
for (const collaboration of ensureIsArray(collaborations))
this.parseCollaboration(collaboration);
}
parseCollaboration(collaboration) {
this.buildParticipant(collaboration.participant);
this.buildMessageFlows(collaboration.messageFlow);
convertAndRegisterAssociationFlows(this.convertedElements, collaboration.association);
this.buildGroups(collaboration.group);
this.buildTextAnnotation(collaboration.textAnnotation);
}
buildParticipant(bpmnElements) {
for (const participant of ensureIsArray(bpmnElements))
this.convertedElements.registerPool(new ShapeBpmnElement(participant.id, participant.name, exports.ShapeBpmnElementKind.POOL), participant.processRef);
}
buildMessageFlows(bpmnElements) {
for (const messageFlow of ensureIsArray(bpmnElements))
this.convertedElements.registerMessageFlow(new MessageFlow(messageFlow.id, messageFlow.name, messageFlow.sourceRef, messageFlow.targetRef));
}
buildGroups(bpmnElements) {
for (const groupBpmnElement of ensureIsArray(bpmnElements)) {
const shapeBpmnElement = buildShapeBpmnGroup(this.convertedElements, this.parsingMessageCollector, groupBpmnElement);
shapeBpmnElement && this.convertedElements.registerFlowNode(shapeBpmnElement);
}
}
buildTextAnnotation(bpmnElements) {
for (const textAnnotation of ensureIsArray(bpmnElements)) {
this.convertedElements.registerFlowNode(new ShapeBpmnElement(textAnnotation.id, textAnnotation.text, exports.ShapeBpmnElementKind.TEXT_ANNOTATION));
}
}
}
class Bounds {
constructor(x, y, width, height) {
Object.defineProperty(this, "x", {
enumerable: true,
configurable: true,
writable: true,
value: x
});
Object.defineProperty(this, "y", {
enumerable: true,
configurable: true,
writable: true,
value: y
});
Object.defineProperty(this, "width", {
enumerable: true,
configurable: true,
writable: true,
value: width
});
Object.defineProperty(this, "height", {
enumerable: true,
configurable: true,
writable: true,
value: height
});
}
}
class Edge {
constructor(id, bpmnElement, waypoints, label, messageVisibleKind = exports.MessageVisibleKind.NONE) {
Object.defineProperty(this, "id", {
enumerable: true,
configurable: true,
writable: true,
value: id
});
Object.defineProperty(this, "bpmnElement", {
enumerable: true,
configurable: true,
writable: true,
value: bpmnElement
});
Object.defineProperty(this, "waypoints", {
enumerable: true,
configurable: true,
writable: true,
value: waypoints
});
Object.defineProperty(this, "label", {
enumerable: true,
configurable: true,
writable: true,
value: label
});
Object.defineProperty(this, "messageVisibleKind", {
enumerable: true,
configurable: true,
writable: true,
value: messageVisibleKind
});
Object.defineProperty(this, "extensions", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
}
}
class Waypoint {
constructor(x, y) {
Object.defineProperty(this, "x", {
enumerable: true,
configurable: true,
writable: true,
value: x
});
Object.defineProperty(this, "y", {
enumerable: true,
configurable: true,
writable: true,
value: y
});
}
}
class Label {
constructor(font, bounds) {
Object.defineProperty(this, "font", {
enumerable: true,
configurable: true,
writable: true,
value: font
});
Object.defineProperty(this, "bounds", {
enumerable: true,
configurable: true,
writable: true,
value: bounds
});
Object.defineProperty(this, "extensions", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
}
}
class Font {
constructor(name, size, isBold, isItalic, isUnderline, isStrikeThrough) {
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: name
});
Object.defineProperty(this, "size", {
enumerable: true,
configurable: true,
writable: true,
value: size
});
Object.defineProperty(this, "isBold", {
enumerable: true,
configurable: true,
writable: true,
value: isBold
});
Object.defineProperty(this, "isItalic", {
enumerable: true,
configurable: true,
writable: true,
value: isItalic
});
Object.defineProperty(this, "isUnderline", {
enumerable: true,
configurable: true,
writable: true,
value: isUnderline
});
Object.defineProperty(this, "isStrikeThrough", {
enumerable: true,
configurable: true,
writable: true,
value: isStrikeThrough
});
}
}
class DiagramConverter {
constructor(convertedElements, parsingMessageCollector) {
Object.defineProperty(this, "convertedElements", {
enumerable: true,
configurable: true,
writable: true,
value: convertedElements
});
Object.defineProperty(this, "parsingMessageCollector", {
enumerable: true,
configurable: true,
writable: true,
value: parsingMessageCollector
});
Object.defineProperty(this, "convertedFonts", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
}
deserialize(bpmnDiagrams) {
const flowNodes = [];
const lanes = [];
const pools = [];
const edges = [];
const bpmnDiagram = ensureIsArray(bpmnDiagrams)[0];
if (bpmnDiagram) {
this.deserializeFonts(bpmnDiagram.BPMNLabelStyle);
const plane = bpmnDiagram.BPMNPlane;
const convertedEdges = this.deserializeEdges(plane.BPMNEdge);
const convertedShapes = this.deserializeShapes(plane.BPMNShape);
flowNodes.push(...convertedShapes.flowNodes);
lanes.push(...convertedShapes.lanes);
pools.push(...convertedShapes.pools);
edges.push(...convertedEdges);
}
return { flowNodes, lanes, pools, edges };
}
deserializeFonts(bpmnLabelStyle) {
for (const labelStyle of ensureIsArray(bpmnLabelStyle))
for (const font of ensureIsArray(labelStyle.Font))
this.convertedFonts.set(labelStyle.id, new Font(font.name, font.size, font.isBold, font.isItalic, font.isUnderline, font.isStrikeThrough));
}
deserializeShapes(shapes) {
const convertedShapes = { flowNodes: [], lanes: [], pools: [] };
for (const shape of ensureIsArray(shapes)) {
if (this.deserializeShapeAndStoreIfFound(shape, convertedShapes.flowNodes, (bpmnElementId) => this.convertedElements.findFlowNode(bpmnElementId))) {
continue;
}
if (this.deserializeShapeAndStoreIfFound(shape, convertedShapes.lanes, (bpmnElementId) => this.convertedElements.findLane(bpmnElementId))) {
continue;
}
if (this.deserializeShapeAndStoreIfFound(shape, convertedShapes.pools, (bpmnElementId) => this.convertedElements.findPoolById(bpmnElementId))) {
continue;
}
this.parsingMessageCollector.warning(new ShapeUnknownBpmnElementWarning(shape.bpmnElement));
}
return convertedShapes;
}
deserializeShapeAndStoreIfFound(shape, storage, findShapeElement) {
const element = this.deserializeShape(shape, findShapeElement);
if (element) {
storage.push(element);
return true;
}
return false;
}
deserializeShape(bpmnShape, findShapeElement) {
var _a;
const bpmnElement = findShapeElement(bpmnShape.bpmnElement);
if (bpmnElement) {
const bounds = deserializeBounds(bpmnShape);
if ((bpmnElement instanceof ShapeBpmnSubProcess ||
(bpmnElement instanceof ShapeBpmnCallActivity && bpmnElement.callActivityKind === exports.ShapeBpmnCallActivityKind.CALLING_PROCESS)) &&
!bpmnShape.isExpanded) {
bpmnElement.markers.push(exports.ShapeBpmnMarkerKind.EXPAND);
}
let isHorizontal;
if (ShapeUtil.isPoolOrLane(bpmnElement.kind)) {
isHorizontal = (_a = bpmnShape.isHorizontal) !== null && _a !== void 0 ? _a : true;
}
const bpmnLabel = bpmnShape.BPMNLabel;
const label = this.deserializeLabel(bpmnLabel, bpmnShape.id);
const shape = new Shape(bpmnShape.id, bpmnElement, bounds, label, isHorizontal);
setColorExtensionsOnShape(shape, bpmnShape);
return shape;
}
}
deserializeEdges(edges) {
return ensureIsArray(edges)
.map(bpmnEdge => {
const flow = this.convertedElements.findSequenceFlow(bpmnEdge.bpmnElement) ||
this.convertedElements.findMessageFlow(bpmnEdge.bpmnElement) ||
this.convertedElements.findAssociationFlow(bpmnEdge.bpmnElement);
if (!flow) {
this.parsingMessageCollector.warning(new EdgeUnknownBpmnElementWarning(bpmnEdge.bpmnElement));
return;
}
const waypoints = this.deserializeWaypoints(bpmnEdge.waypoint);
const label = this.deserializeLabel(bpmnEdge.BPMNLabel, bpmnEdge.id);
const messageVisibleKind = bpmnEdge.messageVisibleKind ? bpmnEdge.messageVisibleKind : exports.MessageVisibleKind.NONE;
const edge = new Edge(bpmnEdge.id, flow, waypoints, label, messageVisibleKind);
setColorExtensionsOnEdge(edge, bpmnEdge);
return edge;
})
.filter(Boolean);
}
deserializeWaypoints(waypoints) {
return ensureIsArray(waypoints).map(waypoint => new Waypoint(waypoint.x, waypoint.y));
}
deserializeLabel(bpmnLabel, id) {
if (bpmnLabel && typeof bpmnLabel === 'object') {
const font = this.findFont(bpmnLabel.labelStyle, id);
const bounds = deserializeBounds(bpmnLabel);
const label = new Label(font, bounds);
if ('color' in bpmnLabel) {
label.extensions.color = bpmnLabel.color;
return label;
}
if (font || bounds) {
return label;
}
}
}
findFont(labelStyle, id) {
let font;
if (labelStyle) {
font = this.convertedFonts.get(labelStyle);
if (!font) {
this.parsingMessageCollector.warning(new LabelStyleMissingFontWarning(id, labelStyle));
}
}
return font;
}
}
function setColorExtensionsOnShape(shape, bpmnShape) {
if ('background-color' in bpmnShape) {
shape.extensions.fillColor = bpmnShape['background-color'];
}
else if ('fill' in bpmnShape) {
shape.extensions.fillColor = bpmnShape.fill;
}
if ('border-color' in bpmnShape) {
shape.extensions.strokeColor = bpmnShape['border-color'];
}
else if ('stroke' in bpmnShape) {
shape.extensions.strokeColor = bpmnShape.stroke;
}
}
function deserializeBounds(boundedElement) {
const bounds = boundedElement.Bounds;
if (bounds) {
return new Bounds(bounds.x, bounds.y, bounds.width, bounds.height);
}
}
function setColorExtensionsOnEdge(edge, bpmnEdge) {
if ('border-color' in bpmnEdge) {
edge.extensions.strokeColor = bpmnEdge['border-color'];
}
else if ('stroke' in bpmnEdge) {
edge.extensions.strokeColor = bpmnEdge.stroke;
}
}
const isTLinkEventDefinition = (eventDefinition) => 'source' in eventDefinition || 'target' in eventDefinition;
class EventDefinitionConverter {
constructor(convertedElements) {
Object.defineProperty(this, "convertedElements", {
enumerable: true,
configurable: true,
writable: true,
value: convertedElements
});
}
deserialize(definitions) {
for (const eventDefinitionKind of eventDefinitionKinds) {
const eventDefinitions = definitions[(eventDefinitionKind + 'EventDefinition')];
for (const eventDefinition of ensureIsArray(eventDefinitions, true)) {
this.convertedElements.registerEventDefinitionsOfDefinition(eventDefinition.id, Object.assign({ id: eventDefinition.id, kind: eventDefinitionKind }, (isTLinkEventDefinition(eventDefinition)
? {
source: eventDefinition.source,
target: eventDefinition.target,
}
: {})));
}
}
}
}
class GlobalTaskConverter {
constructor(convertedElements) {
Object.defineProperty(this, "convertedElements", {
enumerable: true,
configurable: true,
writable: true,
value: convertedElements
});
}
deserialize(definitions) {
this.parseGlobalTasks(definitions.globalTask, exports.ShapeBpmnElementKind.GLOBAL_TASK);
this.parseGlobalTasks(definitions.globalBusinessRuleTask, exports.ShapeBpmnElementKind.GLOBAL_TASK_BUSINESS_RULE);
this.parseGlobalTasks(definitions.globalManualTask, exports.ShapeBpmnElementKind.GLOBAL_TASK_MANUAL);
this.parseGlobalTasks(definitions.globalScriptTask, exports.ShapeBpmnElementKind.GLOBAL_TASK_SCRIPT);
this.parseGlobalTasks(definitions.globalUserTask, exports.ShapeBpmnElementKind.GLOBAL_TASK_USER);
}
parseGlobalTasks(globalTasks, kind) {
for (const globalTask of ensureIsArray(globalTasks))
this.convertedElements.registerGlobalTask(globalTask.id, kind);
}
}
const computeSubProcessKind = (processedSemanticType, bpmnElement) => {
switch (processedSemanticType) {
case 'adHocSubProcess': {
return exports.ShapeBpmnSubProcessKind.AD_HOC;
}
case 'transaction': {
return exports.ShapeBpmnSubProcessKind.TRANSACTION;
}
default: {
return bpmnElement.triggeredByEvent ? exports.ShapeBpmnSubProcessKind.EVENT : exports.ShapeBpmnSubProcessKind.EMBEDDED;
}
}
};
const orderedFlowNodeBpmnTypes = [
'adHocSubProcess',
'transaction',
...ShapeUtil.flowNodeKinds().filter(kind => kind !== exports.ShapeBpmnElementKind.EVENT_BOUNDARY),
exports.ShapeBpmnElementKind.EVENT_BOUNDARY,
];
function getShapeBpmnElementKind(bpmnSemanticType) {
return ['adHocSubProcess', 'transaction'].includes(bpmnSemanticType) ? exports.ShapeBpmnElementKind.SUB_PROCESS : bpmnSemanticType;
}
class ProcessConverter {
constructor(convertedElements, parsingMessageCollector) {
Object.defineProperty(this, "convertedElements", {
enumerable: true,
configurable: true,
writable: true,
value: convertedElements
});
Object.defineProperty(this, "parsingMessageCollector", {
enumerable: true,
configurable: true,
writable: true,
value: parsingMessageCollector
});
Object.defineProperty(this, "defaultSequenceFlowIds", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "elementsWithoutParentByProcessId", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "callActivitiesCallingProcess", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "eventsByLinkEventDefinition", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
}
deserialize(processes) {
for (const process of ensureIsArray(processes))
this.parseProcess(process);
for (const process of ensureIsArray(processes))
this.assignParentOfProcessElementsCalledByCallActivity(process.id);
this.assignIncomingAndOutgoingIdsFromFlows();
this.assignSourceAndTargetIdsToLinkEvents();
}
assignParentOfProcessElementsCalledByCallActivity(processId) {
const callActivity = this.callActivitiesCallingProcess.get(processId);
if (callActivity) {
const pool = this.convertedElements.findPoolByProcessRef(processId);
if (pool) {
pool.parentId = callActivity.id;
}
for (const element of this.elementsWithoutParentByProcessId.get(processId)) {
element.parentId = callActivity.id;
}
}
}
assignIncomingAndOutgoingIdsFromFlows() {
const fillShapeBpmnElementAttribute = (shapeBpmnElementId, shapeBpmnElementAttributeName, valueToAdd) => {
var _a, _b;
const shapeBpmnElement = (_b = (_a = this.convertedElements.findFlowNode(shapeBpmnElementId)) !== null && _a !== void 0 ? _a : this.convertedElements.findLane(shapeBpmnElementId)) !== null && _b !== void 0 ? _b : this.convertedElements.findPoolById(shapeBpmnElementId);
if (shapeBpmnElement && !shapeBpmnElement[shapeBpmnElementAttributeName].includes(valueToAdd)) {
shapeBpmnElement[shapeBpmnElementAttributeName].push(valueToAdd);
}
};
for (const flow of this.convertedElements.getFlows()) {
fillShapeBpmnElementAttribute(flow.sourceReferenceId, 'outgoingIds', flow.id);
fillShapeBpmnElementAttribute(flow.targetReferenceId, 'incomingIds', flow.id);
}
}
assignSourceAndTargetIdsToLinkEvents() {
var _a;
const linkEventDefinitions = [...this.eventsByLinkEventDefinition.entries()].filter(([targetEventDefinition]) => targetEventDefinition.id);
for (const [eventDefinition, bpmnEvent] of this.eventsByLinkEventDefinition) {
if (bpmnEvent instanceof ShapeBpmnIntermediateThrowEvent) {
const target = linkEventDefinitions.find(([targetEventDefinition]) => eventDefinition.target === targetEventDefinition.id);
bpmnEvent.targetId = (_a = target === null || target === void 0 ? void 0 : target[1]) === null || _a === void 0 ? void 0 : _a.id;
}
else if (bpmnEvent instanceof ShapeBpmnIntermediateCatchEvent) {
bpmnEvent.sourceIds = linkEventDefinitions
.filter(([sourceEventDefinition]) => Array.isArray(eventDefinition.source) ? eventDefinition.source.includes(sourceEventDefinition.id) : eventDefinition.source === sourceEventDefinition.id)
.map(([, sourceEvent]) => sourceEvent.id);
}
}
}
parseProcess(process) {
const processReference = process.id;
const pool = this.convertedElements.findPoolByProcessRef(processReference);
if (pool && !pool.name) {
this.convertedElements.registerPool(new ShapeBpmnElement(pool.id, process.name, exports.ShapeBpmnElementKind.POOL), processReference);
}
this.buildProcessInnerElements(process, pool === null || pool === void 0 ? void 0 : pool.id);
}
buildProcessInnerElements(process, parentId) {
this.elementsWithoutParentByProcessId.set(process.id, []);
for (const bpmnType of orderedFlowNodeBpmnTypes)
this.buildFlowNodeBpmnElements(process[bpmnType], getShapeBpmnElementKind(bpmnType), parentId, process.id, bpmnType);
this.buildLaneSetBpmnElements(process.laneSet, parentId, process.id);
this.buildSequenceFlows(process.sequenceFlow);
convertAndRegisterAssociationFlows(this.convertedElements, process.association);
}
buildFlowNodeBpmnElements(bpmnElements, kind, parentId, processId, processedSemanticType) {
for (const bpmnElement of ensureIsArray(bpmnElements)) {
const shapeBpmnElement = this.buildFlowNodeBpmnElement(kind, bpmnElement, parentId, processedSemanticType);
if ('default' in bpmnElement && ShapeUtil.isWithDefaultSequenceFlow(kind)) {
this.defaultSequenceFlowIds.push(bpmnElement.default);
}
if (shapeBpmnElement) {
this.convertedElements.registerFlowNode(shapeBpmnElement);
if (!parentId) {
this.elementsWithoutParentByProcessId.get(processId).push(shapeBpmnElement);
}
}
}
}
buildFlowNodeBpmnElement(kind, bpmnElement, parentId, processedSemanticType) {
if (ShapeUtil.isEvent(kind)) {
return this.buildShapeBpmnEvent(bpmnElement, kind, parentId);
}
else if (ShapeUtil.isActivity(kind)) {
return this.buildShapeBpmnActivity(bpmnElement, kind, parentId, processedSemanticType);
}
else if (kind == exports.ShapeBpmnElementKind.GATEWAY_EVENT_BASED) {
const eventBasedGatewayBpmnElement = bpmnElement;
return new ShapeBpmnEventBasedGateway(eventBasedGatewayBpmnElement.id, eventBasedGatewayBpmnElement.name, parentId, eventBasedGatewayBpmnElement.instantiate, exports.ShapeBpmnEventBasedGatewayKind[eventBasedGatewayBpmnElement.eventGatewayType]);
}
else if (kind == exports.ShapeBpmnElementKind.GROUP) {
return buildShapeBpmnGroup(this.convertedElements, this.parsingMessageCollector, bpmnElement, parentId);
}
else {
const name = kind === exports.ShapeBpmnElementKind.TEXT_ANNOTATION ? bpmnElement.text : bpmnElement.name;
return new ShapeBpmnElement(bpmnElement.id, name, kind, parentId, bpmnElement.instantiate);
}
}
buildShapeBpmnActivity(bpmnElement, kind, parentId, processedSemanticType) {
const markers = buildMarkers(bpmnElement);
if (ShapeUtil.isSubProcess(kind)) {
return this.buildShapeBpmnSubProcess(bpmnElement, parentId, computeSubProcessKind(processedSemanticType, bpmnElement), markers);
}
if (!ShapeUtil.isCallActivity(kind)) {
return new ShapeBpmnActivity(bpmnElement.id, bpmnElement.name, kind, parentId, bpmnElement.instantiate, markers);
}
return this.buildShapeBpmnCallActivity(bpmnElement, parentId, markers);
}
buildShapeBpmnCallActivity(bpmnElement, parentId, markers) {
const globalTaskKind = this.convertedElements.findGlobalTask(bpmnElement.calledElement);
if (!globalTaskKind) {
const shapeBpmnCallActivity = new ShapeBpmnCallActivity(bpmnElement.id, bpmnElement.name, exports.ShapeBpmnCallActivityKind.CALLING_PROCESS, parentId, markers);
this.callActivitiesCallingProcess.set(bpmnElement.calledElement, shapeBpmnCallActivity);
return shapeBpmnCallActivity;
}
return new ShapeBpmnCallActivity(bpmnElement.id, bpmnElement.name, exports.ShapeBpmnCallActivityKind.CALLING_GLOBAL_TASK, parentId, markers, globalTaskKind);
}
buildShapeBpmnEvent(bpmnElement, elementKind, parentId) {
const eventDefinitionsByKind = this.getEventDefinitions(bpmnElement);
const numberOfEventDefinitions = [...eventDefinitionsByKind.entries()]
.map(([, registeredEventDefinitions]) => registeredEventDefinitions.length)
.reduce((counter, it) => counter + it, 0);
if (numberOfEventDefinitions == 0 && ShapeUtil.canHaveNoneEvent(elementKind)) {
return new ShapeBpmnEvent(bpmnElement.id, bpmnElement.name, elementKind, exports.ShapeBpmnEventDefinitionKind.NONE, parentId);
}
if (numberOfEventDefinitions == 1) {
const [eventDefinitionKind, eventDefinitions] = [...eventDefinitionsByKind.entries()][0];
const bpmnEvent = ShapeUtil.isCatchEvent(elementKind)
? this.buildShapeBpmnCatchEvent(bpmnElement, elementKind, eventDefinitionKind, parentId)
: this.buildShapeBpmnThrowEvent(bpmnElement, elementKind, eventDefinitionKind, parentId);
if (eventDefinitionKind === exports.ShapeBpmnEventDefinitionKind.LINK && (eventDefinitions[0].id || eventDefinitions[0].target || eventDefinitions[0].source)) {
this.eventsByLinkEventDefinition.set(eventDefinitions[0], bpmnEvent);
}
return bpmnEvent;
}
}
buildShapeBpmnCatchEvent(bpmnElement, elementKind, eventDefinitionKind, parentId) {
if (ShapeUtil.isBoundaryEvent(elementKind)) {
return this.buildShapeBpmnBoundaryEvent(bpmnElement, eventDefinitionKind);
}
if (ShapeUtil.isStartEvent(elementKind)) {
return new ShapeBpmnStartEvent(bpmnElement.id, bpmnElement.name, eventDefinitionKind, parentId, bpmnElement.isInterrupting);
}
return new ShapeBpmnIntermediateCatchEvent(bpmnElement.id, bpmnElement.name, eventDefinitionKind, parentId);
}
buildShapeBpmnThrowEvent(bpmnElement, elementKind, eventDefinitionKind, parentId) {
if (ShapeUtil.isIntermediateThrowEvent(elementKind)) {
return new ShapeBpmnIntermediateThrowEvent(bpmnElement.id, bpmnElement.name, eventDefinitionKind, parentId);
}
return new ShapeBpmnEvent(bpmnElement.id, bpmnElement.name, elementKind, eventDefinitionKind, parentId);
}
buildShapeBpmnBoundaryEvent(bpmnElement, eventDefinitionKind) {
const parent = this.convertedElements.findFlowNode(bpmnElement.attachedToRef);
if (ShapeUtil.isActivity(parent === null || parent === void 0 ? void 0 : parent.kind)) {
return new ShapeBpmnBoundaryEvent(bpmnElement.id, bpmnElement.name, eventDefinitionKind, bpmnElement.attachedToRef, bpmnElement.cancelActivity);
}
else {
this.parsingMessageCollector.warning(new BoundaryEventNotAttachedToActivityWarning(bpmnElement.id, bpmnElement.attachedToRef, parent === null || parent === void 0 ? void 0 : parent.kind));
}
}
getEventDefinitions(bpmnElement) {
const eventDefinitionsByKind = new Map();
for (const eventDefinitionKind of eventDefinitionKinds) {
const eventDefinition = bpmnElement[`${eventDefinitionKind}EventDefinition`];
eventDefinitionsByKind.set(eventDefinitionKind, ensureIsArray(eventDefinition, true));
}
for (const eventDefinitionReference of ensureIsArray(bpmnElement.eventDefinitionRef)) {
const eventDefinition = this.convertedElements.findEventDefinitionOfDefinition(eventDefinitionReference);
eventDefinition && eventDefinitionsByKind.get(eventDefinition.kind).push(eventDefinition);
}
for (const [kind] of [...eventDefinitionsByKind.entries()].filter(([, registeredEventDefinitions]) => registeredEventDefinitions.length === 0)) {
eventDefinitionsByKind.delete(kind);
}
return eventDefinitionsByKind;
}
buildShapeBpmnSubProcess(bpmnElement, parentId, subProcessKind, markers) {
const convertedSubProcess = new ShapeBpmnSubProcess(bpmnElement.id, bpmnElement.name, subProcessKind, parentId, markers);
this.buildProcessInnerElements(bpmnElement, bpmnElement.id);
return convertedSubProcess;
}
buildLaneSetBpmnElements(laneSets, parentId, processId) {
for (const laneSet of ensureIsArray(laneSets))
this.buildLaneBpmnElements(laneSet.lane, parentId, processId);
}
buildLaneBpmnElements(lanes, parentId, processId) {
var _a;
for (const lane of ensureIsArray(lanes)) {
const shapeBpmnElement = new ShapeBpmnElement(lane.id, lane.name, exports.ShapeBpmnElementKind.LANE, parentId);
this.convertedElements.registerLane(shapeBpmnElement);
if (!parentId) {
this.elementsWithoutParentByProcessId.get(processId).push(shapeBpmnElement);
}
this.assignParentOfLaneFlowNodes(lane);
if ((_a = lane.childLaneSet) === null || _a === void 0 ? void 0 : _a.lane) {
this.buildLaneBpmnElements(lane.childLaneSet.lane, lane.id, processId);
}
}
}
assignParentOfLaneFlowNodes(lane) {
for (const flowNodeReference of ensureIsArray(lane.flowNodeRef)) {
const shapeBpmnElement = this.convertedElements.findFlowNode(flowNodeReference);
const laneId = lane.id;
if (shapeBpmnElement) {
if (!ShapeUtil.isBoundaryEvent(shapeBpmnElement.kind)) {
shapeBpmnElement.parentId = laneId;
}
}
else {
this.parsingMessageCollector.warning(new LaneUnknownFlowNodeReferenceWarning(laneId, flowNodeReference));
}
}
}
buildSequenceFlows(bpmnElements) {
for (const sequenceFlow of ensureIsArray(bpmnElements)) {
const kind = this.getSequenceFlowKind(sequenceFlow);
this.convertedElements.registerSequenceFlow(new SequenceFlow(sequenceFlow.id, sequenceFlow.name, sequenceFlow.sourceRef, sequenceFlow.targetRef, kind));
}
}
getSequenceFlowKind(sequenceFlow) {
if (this.defaultSequenceFlowIds.includes(sequenceFlow.id)) {
return exports.SequenceFlowKind.DEFAULT;
}
else {
const sourceShapeBpmnElement = this.convertedElements.findFlowNode(sequenceFlow.sourceRef);
if (sourceShapeBpmnElement && ShapeUtil.isWithDefaultSequenceFlow(sourceShapeBpmnElement.kind) && sequenceFlow.conditionExpression) {
return ShapeUtil.isActivity(sourceShapeBpmnElement.kind) ? exports.SequenceFlowKind.CONDITIONAL_FROM_ACTIVITY : exports.SequenceFlowKind.CONDITIONAL_FROM_GATEWAY;
}
}
return exports.SequenceFlowKind.NORMAL;
}
}
const buildMarkers = (bpmnElement) => {
const markers = [];
const standardLoopCharacteristics = bpmnElement.standardLoopCharacteristics;
const multiInstanceLoopCharacteristics = ensureIsArray(bpmnElement.multiInstanceLoopCharacteristics, true)[0];
if (standardLoopCharacteristics !== undefined) {
markers.push(exports.ShapeBpmnMarkerKind.LOOP);
}
else if (multiInstanceLoopCharacteristics) {
markers.push(multiInstanceLoopCharacteristics.isSequential ? exports.ShapeBpmnMarkerKind.MULTI_INSTANCE_SEQUENTIAL : exports.ShapeBpmnMarkerKind.MULTI_INSTANCE_PARALLEL);
}
return markers;
};
class BpmnJsonParser {
constructor(categoryConverter, collaborationConverter, eventDefinitionConverter, globalTaskConverter, processConverter, diagramConverter) {
Object.defineProperty(this, "categoryConverter", {
enumerable: true,
configurable: true,
writable: true,
value: categoryConverter
});
Object.defineProperty(this, "collaborationConverter", {
enumerable: true,
configurable: true,
writable: true,
value: collaborationConverter
});
Object.defineProperty(this, "eventDefinitionConverter", {
enumerable: true,
configurable: true,
writable: true,
value: eventDefinitionConverter
});
Object.defineProperty(this, "globalTaskConverter", {
enumerable: true,
configurable: true,
writable: true,
value: globalTaskConverter
});
Object.defineProperty(this, "processConverter", {
enumerable: true,
configurable: true,
writable: true,
value: processConverter
});
Object.defineProperty(this, "diagramConverter", {
enumerable: true,
configurable: true,
writable: true,
value: diagramConverter
});
}
parse(json) {
const definitions = json.definitions;
this.categoryConverter.deserialize(definitions);
this.collaborationConverter.deserialize(definitions.collaboration);
this.eventDefinitionConverter.deserialize(definitions);
this.globalTaskConverter.deserialize(definitions);
this.processConverter.deserialize(definitions.process);
return this.diagramConverter.deserialize(definitions.BPMNDiagram);
}
}
function newBpmnJsonParser(parsingMessageCollector) {
const convertedElements = new ConvertedElements();
return new BpmnJsonParser(new CategoryConverter(convertedElements), new CollaborationConverter(convertedElements, parsingMessageCollector), new EventDefinitionConverter(convertedElements), new GlobalTaskConverter(convertedElements), new ProcessConverter(convertedElements, parsingMessageCollector), new DiagramConverter(convertedElements, parsingMessageCollector));
}
const nameStartChar = ':A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';
const nameChar = nameStartChar + '\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';
const regexName = new RegExp('^' + nameRegexp + '$');
function getAllMatches(string, regex) {
const matches = [];
let match = regex.exec(string);
while (match) {
const allmatches = [];
allmatches.startIndex = regex.lastIndex - match[0].length;
const len = match.length;
for (let index = 0; index < len; index++) {
allmatches.push(match[index]);
}
matches.push(allmatches);
match = regex.exec(string);
}
return matches;
}
const isName = function(string) {
const match = regexName.exec(string);
return !(match === null || typeof match === 'undefined');
};
function isExist(v) {
return typeof v !== 'undefined';
}
const defaultOptions$1 = {
allowBooleanAttributes: false,
unpairedTags: []
};
function validate(xmlData, options) {
options = Object.assign({}, defaultOptions$1, options);
const tags = [];
let tagFound = false;
let reachedRoot = false;
if (xmlData[0] === '\ufeff') {
xmlData = xmlData.substr(1);
}
for (let i = 0; i < xmlData.length; i++) {
if (xmlData[i] === '<' && xmlData[i+1] === '?') {
i+=2;
i = readPI(xmlData,i);
if (i.err) return i;
}else if (xmlData[i] === '<') {
let tagStartPos = i;
i++;
if (xmlData[i] === '!') {
i = readCommentAndCDATA(xmlData, i);
continue;
} else {
let closingTag = false;
if (xmlData[i] === '/') {
closingTag = true;
i++;
}
let tagName = '';
for (; i < xmlData.length &&
xmlData[i] !== '>' &&
xmlData[i] !== ' ' &&
xmlData[i] !== '\t' &&
xmlData[i] !== '\n' &&
xmlData[i] !== '\r'; i++
) {
tagName += xmlData[i];
}
tagName = tagName.trim();
if (tagName[tagName.length - 1] === '/') {
tagName = tagName.substring(0, tagName.length - 1);
i--;
}
if (!validateTagName(tagName)) {
let msg;
if (tagName.trim().length === 0) {
msg = "Invalid space after '<'.";
} else {
msg = "Tag '"+tagName+"' is an invalid name.";
}
return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i));
}
const result = readAttributeStr(xmlData, i);
if (result === false) {
return getErrorObject('InvalidAttr', "Attributes for '"+tagName+"' have open quote.", getLineNumberForPosition(xmlData, i));
}
let attrStr = result.value;
i = result.index;
if (attrStr[attrStr.length - 1] === '/') {
const attrStrStart = i - attrStr.length;
attrStr = attrStr.substring(0, attrStr.length - 1);
const isValid = validateAttributeString(attrStr, options);
if (isValid === true) {
tagFound = true;
} else {
return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));
}
} else if (closingTag) {
if (!result.tagClosed) {
return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' doesn't have proper closing.", getLineNumberForPosition(xmlData, i));
} else if (attrStr.trim().length > 0) {
return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' can't have attributes or invalid starting.", getLineNumberForPosition(xmlData, tagStartPos));
} else if (tags.length === 0) {
return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' has not been opened.", getLineNumberForPosition(xmlData, tagStartPos));
} else {
const otg = tags.pop();
if (tagName !== otg.tagName) {
let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);
return getErrorObject('InvalidTag',
"Expected closing tag '"+otg.tagName+"' (opened in line "+openPos.line+", col "+openPos.col+") instead of closing tag '"+tagName+"'.",
getLineNumberForPosition(xmlData, tagStartPos));
}
if (tags.length == 0) {
reachedRoot = true;
}
}
} else {
const isValid = validateAttributeString(attrStr, options);
if (isValid !== true) {
return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));
}
if (reachedRoot === true) {
return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));
} else if(options.unpairedTags.indexOf(tagName) !== -1); else {
tags.push({tagName, tagStartPos});
}
tagFound = true;
}
for (i++; i < xmlData.length; i++) {
if (xmlData[i] === '<') {
if (xmlData[i + 1] === '!') {
i++;
i = readCommentAndCDATA(xmlData, i);
continue;
} else if (xmlData[i+1] === '?') {
i = readPI(xmlData, ++i);
if (i.err) return i;
} else {
break;
}
} else if (xmlData[i] === '&') {
const afterAmp = validateAmpersand(xmlData, i);
if (afterAmp == -1)
return getErrorObject('InvalidChar', "char '&' is not expected.", getLineNumberForPosition(xmlData, i));
i = afterAmp;
}else {
if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {
return getErrorObject('InvalidXml', "Extra text at the end", getLineNumberForPosition(xmlData, i));
}
}
}
if (xmlData[i] === '<') {
i--;
}
}
} else {
if ( isWhiteSpace(xmlData[i])) {
continue;
}
return getErrorObject('InvalidChar', "char '"+xmlData[i]+"' is not expected.", getLineNumberForPosition(xmlData, i));
}
}
if (!tagFound) {
return getErrorObject('InvalidXml', 'Start tag expected.', 1);
}else if (tags.length == 1) {
return getErrorObject('InvalidTag', "Unclosed tag '"+tags[0].tagName+"'.", getLineNumberForPosition(xmlData, tags[0].tagStartPos));
}else if (tags.length > 0) {
return getErrorObject('InvalidXml', "Invalid '"+
JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\r?\n/g, '')+
"' found.", {line: 1, col: 1});
}
return true;
}function isWhiteSpace(char){
return char === ' ' || char === '\t' || char === '\n' || char === '\r';
}
function readPI(xmlData, i) {
const start = i;
for (; i < xmlData.length; i++) {
if (xmlData[i] == '?' || xmlData[i] == ' ') {
const tagname = xmlData.substr(start, i - start);
if (i > 5 && tagname === 'xml') {
return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i));
} else if (xmlData[i] == '?' && xmlData[i + 1] == '>') {
i++;
break;
} else {
continue;
}
}
}
return i;
}
function readCommentAndCDATA(xmlData, i) {
if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') {
for (i += 3; i < xmlData.length; i++) {
if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') {
i += 2;
break;
}
}
} else if (
xmlData.length > i + 8 &&
xmlData[i + 1] === 'D' &&
xmlData[i + 2] === 'O' &&
xmlData[i + 3] === 'C' &&
xmlData[i + 4] === 'T' &&
xmlData[i + 5] === 'Y' &&
xmlData[i + 6] === 'P' &&
xmlData[i + 7] === 'E'
) {
let angleBracketsCount = 1;
for (i += 8; i < xmlData.length; i++) {
if (xmlData[i] === '<') {
angleBracketsCount++;
} else if (xmlData[i] === '>') {
angleBracketsCount--;
if (angleBracketsCount === 0) {
break;
}
}
}
} else if (
xmlData.length > i + 9 &&
xmlData[i + 1] === '[' &&
xmlData[i + 2] === 'C' &&
xmlData[i + 3] === 'D' &&
xmlData[i + 4] === 'A' &&
xmlData[i + 5] === 'T' &&
xmlData[i + 6] === 'A' &&
xmlData[i + 7] === '['
) {
for (i += 8; i < xmlData.length; i++) {
if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') {
i += 2;
break;
}
}
}
return i;
}
const doubleQuote = '"';
const singleQuote = "'";
function readAttributeStr(xmlData, i) {
let attrStr = '';
let startChar = '';
let tagClosed = false;
for (; i < xmlData.length; i++) {
if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {
if (startChar === '') {
startChar = xmlData[i];
} else if (startChar !== xmlData[i]) ; else {
startChar = '';
}
} else if (xmlData[i] === '>') {
if (startChar === '') {
tagClosed = true;
break;
}
}
attrStr += xmlData[i];
}
if (startChar !== '') {
return false;
}
return {
value: attrStr,
index: i,
tagClosed: tagClosed
};
}
const validAttrStrRegxp = new RegExp('(\\s*)([^\\s=]+)(\\s*=)?(\\s*([\'"])(([\\s\\S])*?)\\5)?', 'g');
function validateAttributeString(attrStr, options) {
const matches = getAllMatches(attrStr, validAttrStrRegxp);
const attrNames = {};
for (let i = 0; i < matches.length; i++) {
if (matches[i][1].length === 0) {
return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' has no space in starting.", getPositionFromMatch(matches[i]))
} else if (matches[i][3] !== undefined && matches[i][4] === undefined) {
return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' is without value.", getPositionFromMatch(matches[i]));
} else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {
return getErrorObject('InvalidAttr', "boolean attribute '"+matches[i][2]+"' is not allowed.", getPositionFromMatch(matches[i]));
}
const attrName = matches[i][2];
if (!validateAttrName(attrName)) {
return getErrorObject('InvalidAttr', "Attribute '"+attrName+"' is an invalid name.", getPositionFromMatch(matches[i]));
}
if (!attrNames.hasOwnProperty(attrName)) {
attrNames[attrName] = 1;
} else {
return getErrorObject('InvalidAttr', "Attribute '"+attrName+"' is repeated.", getPositionFromMatch(matches[i]));
}
}
return true;
}
function validateNumberAmpersand(xmlData, i) {
let re = /\d/;
if (xmlData[i] === 'x') {
i++;
re = /[\da-fA-F]/;
}
for (; i < xmlData.length; i++) {
if (xmlData[i] === ';')
return i;
if (!xmlData[i].match(re))
break;
}
return -1;
}
function validateAmpersand(xmlData, i) {
i++;
if (xmlData[i] === ';')
return -1;
if (xmlData[i] === '#') {
i++;
return validateNumberAmpersand(xmlData, i);
}
let count = 0;
for (; i < xmlData.length; i++, count++) {
if (xmlData[i].match(/\w/) && count < 20)
continue;
if (xmlData[i] === ';')
break;
return -1;
}
return i;
}
function getErrorObject(code, message, lineNumber) {
return {
err: {
code: code,
msg: message,
line: lineNumber.line || lineNumber,
col: lineNumber.col,
},
};
}
function validateAttrName(attrName) {
return isName(attrName);
}
function validateTagName(tagname) {
return isName(tagname) ;
}
function getLineNumberForPosition(xmlData, index) {
const lines = xmlData.substring(0, index).split(/\r?\n/);
return {
line: lines.length,
col: lines[lines.length - 1].length + 1
};
}
function getPositionFromMatch(match) {
return match.startIndex + match[1].length;
}
const defaultOptions = {
preserveOrder: false,
attributeNamePrefix: '@_',
attributesGroupName: false,
textNodeName: '#text',
ignoreAttributes: true,
removeNSPrefix: false,
allowBooleanAttributes: false,
parseTagValue: true,
parseAttributeValue: false,
trimValues: true,
cdataPropName: false,
numberParseOptions: {
hex: true,
leadingZeros: true,
eNotation: true
},
tagValueProcessor: function(tagName, val) {
return val;
},
attributeValueProcessor: function(attrName, val) {
return val;
},
stopNodes: [],
alwaysCreateTextNode: false,
isArray: () => false,
commentPropName: false,
unpairedTags: [],
processEntities: true,
htmlEntities: false,
ignoreDeclaration: false,
ignorePiTags: false,
transformTagName: false,
transformAttributeName: false,
updateTag: function(tagName, jPath, attrs){
return tagName
},
};
const buildOptions = function(options) {
return Object.assign({}, defaultOptions, options);
};
class XmlNode{
constructor(tagname) {
this.tagname = tagname;
this.child = [];
this[":@"] = {};
}
add(key,val){
if(key === "__proto__") key = "#__proto__";
this.child.push( {[key]: val });
}
addChild(node) {
if(node.tagname === "__proto__") node.tagname = "#__proto__";
if(node[":@"] && Object.keys(node[":@"]).length > 0){
this.child.push( { [node.tagname]: node.child, [":@"]: node[":@"] });
}else {
this.child.push( { [node.tagname]: node.child });
}
}
}
function readDocType(xmlData, i){
const entities = {};
if( xmlData[i + 3] === 'O' &&
xmlData[i + 4] === 'C' &&
xmlData[i + 5] === 'T' &&
xmlData[i + 6] === 'Y' &&
xmlData[i + 7] === 'P' &&
xmlData[i + 8] === 'E')
{
i = i+9;
let angleBracketsCount = 1;
let hasBody = false, comment = false;
let exp = "";
for(;i<xmlData.length;i++){
if (xmlData[i] === '<' && !comment) {
if( hasBody && isEntity(xmlData, i)){
i += 7;
let entityName, val;
[entityName, val,i] = readEntityExp(xmlData,i+1);
if(val.indexOf("&") === -1)
entities[ validateEntityName(entityName) ] = {
regx : RegExp( `&${entityName};`,"g"),
val: val
};
}
else if( hasBody && isElement(xmlData, i)) i += 8;
else if( hasBody && isAttlist(xmlData, i)) i += 8;
else if( hasBody && isNotation(xmlData, i)) i += 9;
else if( isComment) comment = true;
else throw new Error("Invalid DOCTYPE");
angleBracketsCount++;
exp = "";
} else if (xmlData[i] === '>') {
if(comment){
if( xmlData[i - 1] === "-" && xmlData[i - 2] === "-"){
comment = false;
angleBracketsCount--;
}
}else {
angleBracketsCount--;
}
if (angleBracketsCount === 0) {
break;
}
}else if( xmlData[i] === '['){
hasBody = true;
}else {
exp += xmlData[i];
}
}
if(angleBracketsCount !== 0){
throw new Error(`Unclosed DOCTYPE`);
}
}else {
throw new Error(`Invalid Tag instead of DOCTYPE`);
}
return {entities, i};
}
function readEntityExp(xmlData,i){
let entityName = "";
for (; i < xmlData.length && (xmlData[i] !== "'" && xmlData[i] !== '"' ); i++) {
entityName += xmlData[i];
}
entityName = entityName.trim();
if(entityName.indexOf(" ") !== -1) throw new Error("External entites are not supported");
const startChar = xmlData[i++];
let val = "";
for (; i < xmlData.length && xmlData[i] !== startChar ; i++) {
val += xmlData[i];
}
return [entityName, val, i];
}
function isComment(xmlData, i){
if(xmlData[i+1] === '!' &&
xmlData[i+2] === '-' &&
xmlData[i+3] === '-') return true
return false
}
function isEntity(xmlData, i){
if(xmlData[i+1] === '!' &&
xmlData[i+2] === 'E' &&
xmlData[i+3] === 'N' &&
xmlData[i+4] === 'T' &&
xmlData[i+5] === 'I' &&
xmlData[i+6] === 'T' &&
xmlData[i+7] === 'Y') return true
return false
}
function isElement(xmlData, i){
if(xmlData[i+1] === '!' &&
xmlData[i+2] === 'E' &&
xmlData[i+3] === 'L' &&
xmlData[i+4] === 'E' &&
xmlData[i+5] === 'M' &&
xmlData[i+6] === 'E' &&
xmlData[i+7] === 'N' &&
xmlData[i+8] === 'T') return true
return false
}
function isAttlist(xmlData, i){
if(xmlData[i+1] === '!' &&
xmlData[i+2] === 'A' &&
xmlData[i+3] === 'T' &&
xmlData[i+4] === 'T' &&
xmlData[i+5] === 'L' &&
xmlData[i+6] === 'I' &&
xmlData[i+7] === 'S' &&
xmlData[i+8] === 'T') return true
return false
}
function isNotation(xmlData, i){
if(xmlData[i+1] === '!' &&
xmlData[i+2] === 'N' &&
xmlData[i+3] === 'O' &&
xmlData[i+4] === 'T' &&
xmlData[i+5] === 'A' &&
xmlData[i+6] === 'T' &&
xmlData[i+7] === 'I' &&
xmlData[i+8] === 'O' &&
xmlData[i+9] === 'N') return true
return false
}
function validateEntityName(name){
if (isName(name))
return name;
else
throw new Error(`Invalid entity name ${name}`);
}
const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;
const numRegex = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/;
const consider = {
hex : true,
leadingZeros: true,
decimalPoint: "\.",
eNotation: true,
};
function toNumber(str, options = {}){
options = Object.assign({}, consider, options );
if(!str || typeof str !== "string" ) return str;
let trimmedStr = str.trim();
if(options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;
else if(str==="0") return 0;
else if (options.hex && hexRegex.test(trimmedStr)) {
return parse_int(trimmedStr, 16);
}else if (trimmedStr.search(/[eE]/)!== -1) {
const notation = trimmedStr.match(/^([-\+])?(0*)([0-9]*(\.[0-9]*)?[eE][-\+]?[0-9]+)$/);
if(notation){
if(options.leadingZeros){
trimmedStr = (notation[1] || "") + notation[3];
}else {
if(notation[2] === "0" && notation[3][0]=== ".");else {
return str;
}
}
return options.eNotation ? Number(trimmedStr) : str;
}else {
return str;
}
}else {
const match = numRegex.exec(trimmedStr);
if(match){
const sign = match[1];
const leadingZeros = match[2];
let numTrimmedByZeros = trimZeros(match[3]);
if(!options.leadingZeros && leadingZeros.length > 0 && sign && trimmedStr[2] !== ".") return str;
else if(!options.leadingZeros && leadingZeros.length > 0 && !sign && trimmedStr[1] !== ".") return str;
else if(options.leadingZeros && leadingZeros===str) return 0;
else {
const num = Number(trimmedStr);
const numStr = "" + num;
if(numStr.search(/[eE]/) !== -1){
if(options.eNotation) return num;
else return str;
}else if(trimmedStr.indexOf(".") !== -1){
if(numStr === "0" && (numTrimmedByZeros === "") ) return num;
else if(numStr === numTrimmedByZeros) return num;
else if( sign && numStr === "-"+numTrimmedByZeros) return num;
else return str;
}
if(leadingZeros){
return (numTrimmedByZeros === numStr) || (sign+numTrimmedByZeros === numStr) ? num : str
}else {
return (trimmedStr === numStr) || (trimmedStr === sign+numStr) ? num : str
}
}
}else {
return str;
}
}
}
function trimZeros(numStr){
if(numStr && numStr.indexOf(".") !== -1){
numStr = numStr.replace(/0+$/, "");
if(numStr === ".") numStr = "0";
else if(numStr[0] === ".") numStr = "0"+numStr;
else if(numStr[numStr.length-1] === ".") numStr = numStr.substr(0,numStr.length-1);
return numStr;
}
return numStr;
}
function parse_int(numStr, base){
if(parseInt) return parseInt(numStr, base);
else if(Number.parseInt) return Number.parseInt(numStr, base);
else if(window && window.parseInt) return window.parseInt(numStr, base);
else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")
}
function getIgnoreAttributesFn(ignoreAttributes) {
if (typeof ignoreAttributes === 'function') {
return ignoreAttributes
}
if (Array.isArray(ignoreAttributes)) {
return (attrName) => {
for (const pattern of ignoreAttributes) {
if (typeof pattern === 'string' && attrName === pattern) {
return true
}
if (pattern instanceof RegExp && pattern.test(attrName)) {
return true
}
}
}
}
return () => false
}
class OrderedObjParser{
constructor(options){
this.options = options;
this.currentNode = null;
this.tagsNodeStack = [];
this.docTypeEntities = {};
this.lastEntities = {
"apos" : { regex: /&(apos|#39|#x27);/g, val : "'"},
"gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"},
"lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"},
"quot" : { regex: /&(quot|#34|#x22);/g, val : "\""},
};
this.ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"};
this.htmlEntities = {
"space": { regex: /&(nbsp|#160);/g, val: " " },
"cent" : { regex: /&(cent|#162);/g, val: "¢" },
"pound" : { regex: /&(pound|#163);/g, val: "£" },
"yen" : { regex: /&(yen|#165);/g, val: "¥" },
"euro" : { regex: /&(euro|#8364);/g, val: "€" },
"copyright" : { regex: /&(copy|#169);/g, val: "©" },
"reg" : { regex: /&(reg|#174);/g, val: "®" },
"inr" : { regex: /&(inr|#8377);/g, val: "₹" },
"num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 10)) },
"num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 16)) },
};
this.addExternalEntities = addExternalEntities;
this.parseXml = parseXml;
this.parseTextData = parseTextData;
this.resolveNameSpace = resolveNameSpace;
this.buildAttributesMap = buildAttributesMap;
this.isItStopNode = isItStopNode;
this.replaceEntitiesValue = replaceEntitiesValue;
this.readStopNodeData = readStopNodeData;
this.saveTextToParentTag = saveTextToParentTag;
this.addChild = addChild;
this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes);
}
}
function addExternalEntities(externalEntities){
const entKeys = Object.keys(externalEntities);
for (let i = 0; i < entKeys.length; i++) {
const ent = entKeys[i];
this.lastEntities[ent] = {
regex: new RegExp("&"+ent+";","g"),
val : externalEntities[ent]
};
}
}
function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {
if (val !== undefined) {
if (this.options.trimValues && !dontTrim) {
val = val.trim();
}
if(val.length > 0){
if(!escapeEntities) val = this.replaceEntitiesValue(val);
const newval = this.options.tagValueProcessor(tagName, val, jPath, hasAttributes, isLeafNode);
if(newval === null || newval === undefined){
return val;
}else if(typeof newval !== typeof val || newval !== val){
return newval;
}else if(this.options.trimValues){
return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);
}else {
const trimmedVal = val.trim();
if(trimmedVal === val){
return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);
}else {
return val;
}
}
}
}
}
function resolveNameSpace(tagname) {
if (this.options.removeNSPrefix) {
const tags = tagname.split(':');
const prefix = tagname.charAt(0) === '/' ? '/' : '';
if (tags[0] === 'xmlns') {
return '';
}
if (tags.length === 2) {
tagname = prefix + tags[1];
}
}
return tagname;
}
const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm');
function buildAttributesMap(attrStr, jPath, tagName) {
if (this.options.ignoreAttributes !== true && typeof attrStr === 'string') {
const matches = getAllMatches(attrStr, attrsRegx);
const len = matches.length;
const attrs = {};
for (let i = 0; i < len; i++) {
const attrName = this.resolveNameSpace(matches[i][1]);
if (this.ignoreAttributesFn(attrName, jPath)) {
continue
}
let oldVal = matches[i][4];
let aName = this.options.attributeNamePrefix + attrName;
if (attrName.length) {
if (this.options.transformAttributeName) {
aName = this.options.transformAttributeName(aName);
}
if(aName === "__proto__") aName = "#__proto__";
if (oldVal !== undefined) {
if (this.options.trimValues) {
oldVal = oldVal.trim();
}
oldVal = this.replaceEntitiesValue(oldVal);
const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPath);
if(newVal === null || newVal === undefined){
attrs[aName] = oldVal;
}else if(typeof newVal !== typeof oldVal || newVal !== oldVal){
attrs[aName] = newVal;
}else {
attrs[aName] = parseValue(
oldVal,
this.options.parseAttributeValue,
this.options.numberParseOptions
);
}
} else if (this.options.allowBooleanAttributes) {
attrs[aName] = true;
}
}
}
if (!Object.keys(attrs).length) {
return;
}
if (this.options.attributesGroupName) {
const attrCollection = {};
attrCollection[this.options.attributesGroupName] = attrs;
return attrCollection;
}
return attrs
}
}
const parseXml = function(xmlData) {
xmlData = xmlData.replace(/\r\n?/g, "\n");
const xmlObj = new XmlNode('!xml');
let currentNode = xmlObj;
let textData = "";
let jPath = "";
for(let i=0; i< xmlData.length; i++){
const ch = xmlData[i];
if(ch === '<'){
if( xmlData[i+1] === '/') {
const closeIndex = findClosingIndex(xmlData, ">", i, "Closing Tag is not closed.");
let tagName = xmlData.substring(i+2,closeIndex).trim();
if(this.options.removeNSPrefix){
const colonIndex = tagName.indexOf(":");
if(colonIndex !== -1){
tagName = tagName.substr(colonIndex+1);
}
}
if(this.options.transformTagName) {
tagName = this.options.transformTagName(tagName);
}
if(currentNode){
textData = this.saveTextToParentTag(textData, currentNode, jPath);
}
const lastTagName = jPath.substring(jPath.lastIndexOf(".")+1);
if(tagName && this.options.unpairedTags.indexOf(tagName) !== -1 ){
throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
}
let propIndex = 0;
if(lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1 ){
propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.')-1);
this.tagsNodeStack.pop();
}else {
propIndex = jPath.lastIndexOf(".");
}
jPath = jPath.substring(0, propIndex);
currentNode = this.tagsNodeStack.pop();
textData = "";
i = closeIndex;
} else if( xmlData[i+1] === '?') {
let tagData = readTagExp(xmlData,i, false, "?>");
if(!tagData) throw new Error("Pi Tag is not closed.");
textData = this.saveTextToParentTag(textData, currentNode, jPath);
if( (this.options.ignoreDeclaration && tagData.tagName === "?xml") || this.options.ignorePiTags);else {
const childNode = new XmlNode(tagData.tagName);
childNode.add(this.options.textNodeName, "");
if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath, tagData.tagName);
}
this.addChild(currentNode, childNode, jPath);
}
i = tagData.closeIndex + 1;
} else if(xmlData.substr(i + 1, 3) === '!--') {
const endIndex = findClosingIndex(xmlData, "-->", i+4, "Comment is not closed.");
if(this.options.commentPropName){
const comment = xmlData.substring(i + 4, endIndex - 2);
textData = this.saveTextToParentTag(textData, currentNode, jPath);
currentNode.add(this.options.commentPropName, [ { [this.options.textNodeName] : comment } ]);
}
i = endIndex;
} else if( xmlData.substr(i + 1, 2) === '!D') {
const result = readDocType(xmlData, i);
this.docTypeEntities = result.entities;
i = result.i;
}else if(xmlData.substr(i + 1, 2) === '![') {
const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2;
const tagExp = xmlData.substring(i + 9,closeIndex);
textData = this.saveTextToParentTag(textData, currentNode, jPath);
let val = this.parseTextData(tagExp, currentNode.tagname, jPath, true, false, true, true);
if(val == undefined) val = "";
if(this.options.cdataPropName){
currentNode.add(this.options.cdataPropName, [ { [this.options.textNodeName] : tagExp } ]);
}else {
currentNode.add(this.options.textNodeName, val);
}
i = closeIndex + 2;
}else {
let result = readTagExp(xmlData,i, this.options.removeNSPrefix);
let tagName= result.tagName;
const rawTagName = result.rawTagName;
let tagExp = result.tagExp;
let attrExpPresent = result.attrExpPresent;
let closeIndex = result.closeIndex;
if (this.options.transformTagName) {
tagName = this.options.transformTagName(tagName);
}
if (currentNode && textData) {
if(currentNode.tagname !== '!xml'){
textData = this.saveTextToParentTag(textData, currentNode, jPath, false);
}
}
const lastTag = currentNode;
if(lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1 ){
currentNode = this.tagsNodeStack.pop();
jPath = jPath.substring(0, jPath.lastIndexOf("."));
}
if(tagName !== xmlObj.tagname){
jPath += jPath ? "." + tagName : tagName;
}
if (this.isItStopNode(this.options.stopNodes, jPath, tagName)) {
let tagContent = "";
if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){
if(tagName[tagName.length - 1] === "/"){
tagName = tagName.substr(0, tagName.length - 1);
jPath = jPath.substr(0, jPath.length - 1);
tagExp = tagName;
}else {
tagExp = tagExp.substr(0, tagExp.length - 1);
}
i = result.closeIndex;
}
else if(this.options.unpairedTags.indexOf(tagName) !== -1){
i = result.closeIndex;
}
else {
const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);
if(!result) throw new Error(`Unexpected end of ${rawTagName}`);
i = result.i;
tagContent = result.tagContent;
}
const childNode = new XmlNode(tagName);
if(tagName !== tagExp && attrExpPresent){
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
}
if(tagContent) {
tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true);
}
jPath = jPath.substr(0, jPath.lastIndexOf("."));
childNode.add(this.options.textNodeName, tagContent);
this.addChild(currentNode, childNode, jPath);
}else {
if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){
if(tagName[tagName.length - 1] === "/"){
tagName = tagName.substr(0, tagName.length - 1);
jPath = jPath.substr(0, jPath.length - 1);
tagExp = tagName;
}else {
tagExp = tagExp.substr(0, tagExp.length - 1);
}
if(this.options.transformTagName) {
tagName = this.options.transformTagName(tagName);
}
const childNode = new XmlNode(tagName);
if(tagName !== tagExp && attrExpPresent){
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
}
this.addChild(currentNode, childNode, jPath);
jPath = jPath.substr(0, jPath.lastIndexOf("."));
}
else {
const childNode = new XmlNode( tagName);
this.tagsNodeStack.push(currentNode);
if(tagName !== tagExp && attrExpPresent){
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
}
this.addChild(currentNode, childNode, jPath);
currentNode = childNode;
}
textData = "";
i = closeIndex;
}
}
}else {
textData += xmlData[i];
}
}
return xmlObj.child;
};
function addChild(currentNode, childNode, jPath){
const result = this.options.updateTag(childNode.tagname, jPath, childNode[":@"]);
if(result === false);else if(typeof result === "string"){
childNode.tagname = result;
currentNode.addChild(childNode);
}else {
currentNode.addChild(childNode);
}
}
const replaceEntitiesValue = function(val){
if(this.options.processEntities){
for(let entityName in this.docTypeEntities){
const entity = this.docTypeEntities[entityName];
val = val.replace( entity.regx, entity.val);
}
for(let entityName in this.lastEntities){
const entity = this.lastEntities[entityName];
val = val.replace( entity.regex, entity.val);
}
if(this.options.htmlEntities){
for(let entityName in this.htmlEntities){
const entity = this.htmlEntities[entityName];
val = val.replace( entity.regex, entity.val);
}
}
val = val.replace( this.ampEntity.regex, this.ampEntity.val);
}
return val;
};
function saveTextToParentTag(textData, currentNode, jPath, isLeafNode) {
if (textData) {
if(isLeafNode === undefined) isLeafNode = currentNode.child.length === 0;
textData = this.parseTextData(textData,
currentNode.tagname,
jPath,
false,
currentNode[":@"] ? Object.keys(currentNode[":@"]).length !== 0 : false,
isLeafNode);
if (textData !== undefined && textData !== "")
currentNode.add(this.options.textNodeName, textData);
textData = "";
}
return textData;
}
function isItStopNode(stopNodes, jPath, currentTagName){
const allNodesExp = "*." + currentTagName;
for (const stopNodePath in stopNodes) {
const stopNodeExp = stopNodes[stopNodePath];
if( allNodesExp === stopNodeExp || jPath === stopNodeExp ) return true;
}
return false;
}
function tagExpWithClosingIndex(xmlData, i, closingChar = ">"){
let attrBoundary;
let tagExp = "";
for (let index = i; index < xmlData.length; index++) {
let ch = xmlData[index];
if (attrBoundary) {
if (ch === attrBoundary) attrBoundary = "";
} else if (ch === '"' || ch === "'") {
attrBoundary = ch;
} else if (ch === closingChar[0]) {
if(closingChar[1]){
if(xmlData[index + 1] === closingChar[1]){
return {
data: tagExp,
index: index
}
}
}else {
return {
data: tagExp,
index: index
}
}
} else if (ch === '\t') {
ch = " ";
}
tagExp += ch;
}
}
function findClosingIndex(xmlData, str, i, errMsg){
const closingIndex = xmlData.indexOf(str, i);
if(closingIndex === -1){
throw new Error(errMsg)
}else {
return closingIndex + str.length - 1;
}
}
function readTagExp(xmlData,i, removeNSPrefix, closingChar = ">"){
const result = tagExpWithClosingIndex(xmlData, i+1, closingChar);
if(!result) return;
let tagExp = result.data;
const closeIndex = result.index;
const separatorIndex = tagExp.search(/\s/);
let tagName = tagExp;
let attrExpPresent = true;
if(separatorIndex !== -1){
tagName = tagExp.substring(0, separatorIndex);
tagExp = tagExp.substring(separatorIndex + 1).trimStart();
}
const rawTagName = tagName;
if(removeNSPrefix){
const colonIndex = tagName.indexOf(":");
if(colonIndex !== -1){
tagName = tagName.substr(colonIndex+1);
attrExpPresent = tagName !== result.data.substr(colonIndex + 1);
}
}
return {
tagName: tagName,
tagExp: tagExp,
closeIndex: closeIndex,
attrExpPresent: attrExpPresent,
rawTagName: rawTagName,
}
}
function readStopNodeData(xmlData, tagName, i){
const startIndex = i;
let openTagCount = 1;
for (; i < xmlData.length; i++) {
if( xmlData[i] === "<"){
if (xmlData[i+1] === "/") {
const closeIndex = findClosingIndex(xmlData, ">", i, `${tagName} is not closed`);
let closeTagName = xmlData.substring(i+2,closeIndex).trim();
if(closeTagName === tagName){
openTagCount--;
if (openTagCount === 0) {
return {
tagContent: xmlData.substring(startIndex, i),
i : closeIndex
}
}
}
i=closeIndex;
} else if(xmlData[i+1] === '?') {
const closeIndex = findClosingIndex(xmlData, "?>", i+1, "StopNode is not closed.");
i=closeIndex;
} else if(xmlData.substr(i + 1, 3) === '!--') {
const closeIndex = findClosingIndex(xmlData, "-->", i+3, "StopNode is not closed.");
i=closeIndex;
} else if(xmlData.substr(i + 1, 2) === '![') {
const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
i=closeIndex;
} else {
const tagData = readTagExp(xmlData, i, '>');
if (tagData) {
const openTagName = tagData && tagData.tagName;
if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length-1] !== "/") {
openTagCount++;
}
i=tagData.closeIndex;
}
}
}
}
}
function parseValue(val, shouldParse, options) {
if (shouldParse && typeof val === 'string') {
const newval = val.trim();
if(newval === 'true' ) return true;
else if(newval === 'false' ) return false;
else return toNumber(val, options);
} else {
if (isExist(val)) {
return val;
} else {
return '';
}
}
}
function prettify(node, options){
return compress( node, options);
}
function compress(arr, options, jPath){
let text;
const compressedObj = {};
for (let i = 0; i < arr.length; i++) {
const tagObj = arr[i];
const property = propName(tagObj);
let newJpath = "";
if(jPath === undefined) newJpath = property;
else newJpath = jPath + "." + property;
if(property === options.textNodeName){
if(text === undefined) text = tagObj[property];
else text += "" + tagObj[property];
}else if(property === undefined){
continue;
}else if(tagObj[property]){
let val = compress(tagObj[property], options, newJpath);
const isLeaf = isLeafTag(val, options);
if(tagObj[":@"]){
assignAttributes( val, tagObj[":@"], newJpath, options);
}else if(Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode){
val = val[options.textNodeName];
}else if(Object.keys(val).length === 0){
if(options.alwaysCreateTextNode) val[options.textNodeName] = "";
else val = "";
}
if(compressedObj[property] !== undefined && compressedObj.hasOwnProperty(property)) {
if(!Array.isArray(compressedObj[property])) {
compressedObj[property] = [ compressedObj[property] ];
}
compressedObj[property].push(val);
}else {
if (options.isArray(property, newJpath, isLeaf )) {
compressedObj[property] = [val];
}else {
compressedObj[property] = val;
}
}
}
}
if(typeof text === "string"){
if(text.length > 0) compressedObj[options.textNodeName] = text;
}else if(text !== undefined) compressedObj[options.textNodeName] = text;
return compressedObj;
}
function propName(obj){
const keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if(key !== ":@") return key;
}
}
function assignAttributes(obj, attrMap, jpath, options){
if (attrMap) {
const keys = Object.keys(attrMap);
const len = keys.length;
for (let i = 0; i < len; i++) {
const atrrName = keys[i];
if (options.isArray(atrrName, jpath + "." + atrrName, true, true)) {
obj[atrrName] = [ attrMap[atrrName] ];
} else {
obj[atrrName] = attrMap[atrrName];
}
}
}
}
function isLeafTag(obj, options){
const { textNodeName } = options;
const propCount = Object.keys(obj).length;
if (propCount === 0) {
return true;
}
if (
propCount === 1 &&
(obj[textNodeName] || typeof obj[textNodeName] === "boolean" || obj[textNodeName] === 0)
) {
return true;
}
return false;
}
class XMLParser{
constructor(options){
this.externalEntities = {};
this.options = buildOptions(options);
}
parse(xmlData,validationOption){
if(typeof xmlData === "string");else if( xmlData.toString){
xmlData = xmlData.toString();
}else {
throw new Error("XML data is accepted in String or Bytes[] form.")
}
if( validationOption){
if(validationOption === true) validationOption = {};
const result = validate(xmlData, validationOption);
if (result !== true) {
throw Error( `${result.err.msg}:${result.err.line}:${result.err.col}` )
}
}
const orderedObjParser = new OrderedObjParser(this.options);
orderedObjParser.addExternalEntities(this.externalEntities);
const orderedResult = orderedObjParser.parseXml(xmlData);
if(this.options.preserveOrder || orderedResult === undefined) return orderedResult;
else return prettify(orderedResult, this.options);
}
addEntity(key, value){
if(value.indexOf("&") !== -1){
throw new Error("Entity value can't have '&'")
}else if(key.indexOf("&") !== -1 || key.indexOf(";") !== -1){
throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for '
'")
}else if(value === "&"){
throw new Error("An entity with value '&' is not permitted");
}else {
this.externalEntities[key] = value;
}
}
}
const entitiesReplacements = [
{ regex: /&(amp|#38|#x26);/g, val: '&' },
{ regex: /&(apos|#39|#x27);/g, val: "'" },
{ regex: /&#(xa|xA|10);/g, val: '\n' },
{ regex: /&(gt|#62|#x3e|#x3E);/g, val: '>' },
{ regex: /&(lt|#60|#x3c|#x3C);/g, val: '<' },
{ regex: /&(quot|#34|#x22);/g, val: '"' },
];
const nodesWithNumericAttributes = new Set(['BPMNShape.Bounds', 'BPMNShape.BPMNLabel.Bounds', 'BPMNEdge.BPMNLabel.Bounds', 'BPMNEdge.waypoint'].map(element => `definitions.BPMNDiagram.BPMNPlane.${element}`));
const numericAttributes = new Set(['x', 'y', 'width', 'height']);
const isNumeric = (attributeName, nodePath) => {
return nodesWithNumericAttributes.has(nodePath) && numericAttributes.has(attributeName);
};
class BpmnXmlParser {
constructor(options) {
Object.defineProperty(this, "options", {
enumerable: true,
configurable: true,
writable: true,
value: options
});
Object.defineProperty(this, "x2jOptions", {
enumerable: true,
configurable: true,
writable: true,
value: {
attributeNamePrefix: '',
removeNSPrefix: true,
ignoreAttributes: false,
parseAttributeValue: true,
processEntities: false,
attributeValueProcessor: (name, value, nodePath) => {
if (isNumeric(name, nodePath)) {
return Number(value);
}
return this.processAttribute(value);
},
}
});
Object.defineProperty(this, "xmlParser", {
enumerable: true,
configurable: true,
writable: true,
value: new XMLParser(this.x2jOptions)
});
}
parse(xml) {
let model;
try {
model = this.xmlParser.parse(xml);
}
catch (_a) {
throw new Error('XML parsing failed. Invalid BPMN source.');
}
if (!model.definitions) {
throw new Error(`XML parsing failed. Unable to retrieve 'definitions' from the BPMN source.`);
}
return model;
}
processAttribute(value) {
var _a;
for (const replacement of entitiesReplacements) {
value = value.replace(replacement.regex, replacement.val);
}
if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.additionalXmlAttributeProcessor) {
value = this.options.additionalXmlAttributeProcessor(value);
}
return value;
}
}
class BpmnParser {
constructor(jsonParser, xmlParser) {
Object.defineProperty(this, "jsonParser", {
enumerable: true,
configurable: true,
writable: true,
value: jsonParser
});
Object.defineProperty(this, "xmlParser", {
enumerable: true,
configurable: true,
writable: true,
value: xmlParser
});
}
parse(bpmnAsXml) {
const json = this.xmlParser.parse(bpmnAsXml);
return this.jsonParser.parse(json);
}
}
function newBpmnParser(options) {
return new BpmnParser(newBpmnJsonParser(new ParsingMessageCollector(options)), new BpmnXmlParser(options));
}
function createNewCssClassesUpdater(graph) {
return new CssClassesUpdater(graph);
}
class CssClassesUpdater {
constructor(graph) {
Object.defineProperty(this, "graph", {
enumerable: true,
configurable: true,
writable: true,
value: graph
});
}
updateAndRefreshCssClassesOfCell(bpmnElementId, cssClasses) {
this.updateAndRefreshCssClassesOfElement(bpmnElementId, cssClasses);
this.updateAndRefreshCssClassesOfElement(messageFlowIconId(bpmnElementId), cssClasses);
}
updateAndRefreshCssClassesOfElement(elementId, cssClasses) {
const model = this.graph.getModel();
const cell = model.getCell(elementId);
if (!cell) {
return;
}
let cellStyle = cell.getStyle();
cellStyle = setStyle(cellStyle, BpmnStyleIdentifier.EXTRA_CSS_CLASSES, cssClasses.join(','));
model.setStyle(cell, cellStyle);
}
}
function createNewCssRegistry(graph) {
return new CssClassesRegistryImpl(createNewCssClassesUpdater(graph), new CssClassesCache());
}
class CssClassesRegistryImpl {
constructor(cssClassesUpdater, cssClassesCache) {
Object.defineProperty(this, "cssClassesUpdater", {
enumerable: true,
configurable: true,
writable: true,
value: cssClassesUpdater
});
Object.defineProperty(this, "cssClassesCache", {
enumerable: true,
configurable: true,
writable: true,
value: cssClassesCache
});
}
clearCache() {
this.cssClassesCache.clear();
}
addCssClasses(bpmnElementIds, classNames) {
this.updateCssClasses(bpmnElementIds, classNames, this.cssClassesCache.addClassNames);
}
removeCssClasses(bpmnElementIds, classNames) {
this.updateCssClasses(bpmnElementIds, classNames, this.cssClassesCache.removeClassNames);
}
removeAllCssClasses(bpmnElementIds) {
if (bpmnElementIds || bpmnElementIds == '') {
for (const bpmnElementId of ensureIsArray(bpmnElementIds)) {
const isChanged = this.cssClassesCache.removeAllClassNames(bpmnElementId);
this.updateCellIfChanged(isChanged, bpmnElementId);
}
}
else {
const bpmnIds = this.cssClassesCache.getBpmnIds();
this.cssClassesCache.clear();
for (const bpmnElementId of bpmnIds)
this.updateCellIfChanged(true, bpmnElementId);
}
}
toggleCssClasses(bpmnElementIds, classNames) {
this.updateCssClasses(bpmnElementIds, classNames, this.cssClassesCache.toggleClassNames);
}
updateCssClasses(bpmnElementIds, classNames, updateClassNames) {
const arrayClassNames = ensureIsArray(classNames);
for (const bpmnElementId of ensureIsArray(bpmnElementIds))
this.updateCellIfChanged(updateClassNames(bpmnElementId, arrayClassNames), bpmnElementId);
}
updateCellIfChanged(updateCell, bpmnElementId) {
if (updateCell) {
const allClassNames = this.cssClassesCache.getClassNames(bpmnElementId);
this.cssClassesUpdater.updateAndRefreshCssClassesOfCell(bpmnElementId, allClassNames);
}
}
}
class CssClassesCache {
constructor() {
Object.defineProperty(this, "classNamesByBpmnId", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
Object.defineProperty(this, "clear", {
enumerable: true,
configurable: true,
writable: true,
value: () => {
this.classNamesByBpmnId.clear();
}
});
Object.defineProperty(this, "addClassNames", {
enumerable: true,
configurable: true,
writable: true,
value: (bpmnElementId, classNames) => this.updateClassNames(bpmnElementId, classNames, (currentClassNames, className) => currentClassNames.add(className))
});
Object.defineProperty(this, "removeClassNames", {
enumerable: true,
configurable: true,
writable: true,
value: (bpmnElementId, classNames) => this.updateClassNames(bpmnElementId, classNames, (currentClassNames, className) => currentClassNames.delete(className))
});
Object.defineProperty(this, "toggleClassNames", {
enumerable: true,
configurable: true,
writable: true,
value: (bpmnElementId, classNames) => {
this.updateClassNames(bpmnElementId, classNames, (currentClassNames, className) => currentClassNames.has(className) ? currentClassNames.delete(className) : currentClassNames.add(className));
return classNames && classNames.length > 0;
}
});
}
getClassNames(bpmnElementId) {
return this.classNamesByBpmnId.has(bpmnElementId) ? [...this.classNamesByBpmnId.get(bpmnElementId)] : [];
}
getBpmnIds() {
return [...this.classNamesByBpmnId.keys()];
}
removeAllClassNames(bpmnElementId) {
const currentClassNames = this.getOrInitializeClassNames(bpmnElementId);
const initialClassNamesNumber = currentClassNames.size;
currentClassNames.clear();
return currentClassNames.size < initialClassNamesNumber;
}
updateClassNames(bpmnElementId, classNames, manageClassNames) {
const currentClassNames = this.getOrInitializeClassNames(bpmnElementId);
const initialClassNamesNumber = currentClassNames.size;
for (const className of ensureIsArray(classNames))
manageClassNames(currentClassNames, className);
return currentClassNames.size != initialClassNamesNumber;
}
getOrInitializeClassNames(bpmnElementId) {
let classNames = this.classNamesByBpmnId.get(bpmnElementId);
if (classNames == null) {
classNames = new Set();
this.classNamesByBpmnId.set(bpmnElementId, classNames);
}
return classNames;
}
}
const overlayPositions = new Map([
['start', { horizontalAlign: 'left', verticalAlign: 'top' }],
['middle', { horizontalAlign: 'center', verticalAlign: 'top' }],
['end', { horizontalAlign: 'right', verticalAlign: 'top' }],
['top-left', { horizontalAlign: 'left', verticalAlign: 'top' }],
['top-right', { horizontalAlign: 'right', verticalAlign: 'top' }],
['top-center', { horizontalAlign: 'center', verticalAlign: 'top' }],
['bottom-left', { horizontalAlign: 'left', verticalAlign: 'bottom' }],
['bottom-right', { horizontalAlign: 'right', verticalAlign: 'bottom' }],
['bottom-center', { horizontalAlign: 'center', verticalAlign: 'bottom' }],
['middle-left', { horizontalAlign: 'left', verticalAlign: 'middle' }],
['middle-right', { horizontalAlign: 'right', verticalAlign: 'middle' }],
]);
const convertPosition = (overlay) => overlayPositions.get(overlay.position);
const convertFill = (convertedStyle, apiFill) => {
var _a, _b;
if (apiFill) {
convertedStyle.fill.color = (_a = apiFill.color) !== null && _a !== void 0 ? _a : convertedStyle.fill.color;
convertedStyle.fill.opacity = (_b = apiFill.opacity) !== null && _b !== void 0 ? _b : convertedStyle.fill.opacity;
}
};
const convertStroke = (convertedStyle, apiStroke) => {
var _a, _b;
if (apiStroke) {
convertedStyle.stroke.color = (_a = apiStroke.color) !== null && _a !== void 0 ? _a : convertedStyle.stroke.color;
convertedStyle.stroke.width = (_b = apiStroke.width) !== null && _b !== void 0 ? _b : convertedStyle.stroke.width;
}
};
const convertFont = (convertedStyle, apiFont) => {
var _a, _b;
if (apiFont) {
convertedStyle.font.color = (_a = apiFont.color) !== null && _a !== void 0 ? _a : convertedStyle.font.color;
convertedStyle.font.size = (_b = apiFont.size) !== null && _b !== void 0 ? _b : convertedStyle.font.size;
}
};
const convertStyle = (overlay) => {
const defaultStyle = {
fill: { color: StyleDefault.DEFAULT_OVERLAY_FILL_COLOR.valueOf(), opacity: StyleDefault.DEFAULT_OVERLAY_FILL_OPACITY.valueOf() },
stroke: { color: StyleDefault.DEFAULT_OVERLAY_STROKE_COLOR.valueOf(), width: StyleDefault.DEFAULT_OVERLAY_STROKE_WIDTH.valueOf() },
font: { color: StyleDefault.DEFAULT_OVERLAY_FONT_COLOR.valueOf(), size: StyleDefault.DEFAULT_OVERLAY_FONT_SIZE.valueOf() },
};
const style = overlay.style;
const convertedStyle = Object.assign({}, defaultStyle);
if (!style) {
return convertedStyle;
}
convertFill(convertedStyle, style.fill);
convertStroke(convertedStyle, style.stroke);
convertFont(convertedStyle, style.font);
return convertedStyle;
};
class OverlayConverter {
convert(overlay) {
const position = convertPosition(overlay);
const style = convertStyle(overlay);
return { position, style };
}
}
function createNewOverlaysUpdater(graph) {
return new OverlaysUpdater(graph, new OverlayConverter());
}
class OverlaysUpdater {
constructor(graph, overlayConverter) {
Object.defineProperty(this, "graph", {
enumerable: true,
configurable: true,
writable: true,
value: graph
});
Object.defineProperty(this, "overlayConverter", {
enumerable: true,
configurable: true,
writable: true,
value: overlayConverter
});
}
addOverlays(bpmnElementId, overlays) {
const cell = this.graph.getModel().getCell(bpmnElementId);
if (!cell) {
return;
}
for (const overlay of ensureIsArray(overlays)) {
const bpmnOverlay = new MxGraphCustomOverlay(overlay.label, this.overlayConverter.convert(overlay));
this.graph.addCellOverlay(cell, bpmnOverlay);
}
}
removeAllOverlays(bpmnElementId) {
const cell = this.graph.getModel().getCell(bpmnElementId);
if (!cell) {
return;
}
this.graph.removeCellOverlays(cell);
}
}
function createNewOverlaysRegistry(graph) {
return new OverlaysRegistryImpl(createNewOverlaysUpdater(graph));
}
class OverlaysRegistryImpl {
constructor(overlaysUpdater) {
Object.defineProperty(this, "overlaysUpdater", {
enumerable: true,
configurable: true,
writable: true,
value: overlaysUpdater
});
}
addOverlays(bpmnElementId, overlays) {
this.overlaysUpdater.addOverlays(bpmnElementId, overlays);
}
removeAllOverlays(bpmnElementId) {
this.overlaysUpdater.removeAllOverlays(bpmnElementId);
}
}
class BpmnQuerySelectors {
element(bpmnElementId) {
return `svg > g > g > g[data-bpmn-id="${bpmnElementId}"]`;
}
elementsOfKind(bpmnKindCssClassname) {
return `svg > g > g > g.${bpmnKindCssClassname}:not(.bpmn-label)`;
}
}
function createNewStyleUpdater(graph) {
return new StyleUpdater(graph, new StyleManager(graph.getModel()));
}
const withCellIdsOfMessageFlowIcons = (bpmnElementIds) => {
const cellIds = ensureIsArray(bpmnElementIds);
cellIds.push(...cellIds.map(id => messageFlowIconId(id)));
return cellIds;
};
class StyleUpdater {
constructor(graph, styleManager) {
Object.defineProperty(this, "graph", {
enumerable: true,
configurable: true,
writable: true,
value: graph
});
Object.defineProperty(this, "styleManager", {
enumerable: true,
configurable: true,
writable: true,
value: styleManager
});
}
clear() {
this.styleManager.clear();
}
updateStyle(bpmnElementIds, styleUpdate) {
if (!styleUpdate) {
return;
}
const model = this.graph.getModel();
const cells = withCellIdsOfMessageFlowIcons(bpmnElementIds)
.map(id => model.getCell(id))
.filter(Boolean);
if (cells.length === 0) {
return;
}
this.graph.batchUpdate(() => {
for (const cell of cells) {
this.styleManager.ensureStyleIsStored(cell);
let cellStyle = cell.getStyle();
cellStyle = setStyle(cellStyle, mxConstants.STYLE_OPACITY, styleUpdate.opacity, ensureOpacityValue);
cellStyle = updateStroke(cellStyle, styleUpdate.stroke);
cellStyle = updateFont(cellStyle, styleUpdate.font);
if (isShapeStyleUpdate(styleUpdate)) {
cellStyle = updateFill(cellStyle, styleUpdate.fill);
}
model.setStyle(cell, cellStyle);
}
});
}
resetStyle(bpmnElementIds) {
this.graph.batchUpdate(() => {
if (bpmnElementIds || bpmnElementIds == '') {
for (const id of withCellIdsOfMessageFlowIcons(bpmnElementIds)) {
this.styleManager.resetStyleIfIsStored(id);
}
}
else {
this.styleManager.resetAllStyles();
}
});
}
}
const cssClassesStyleIdentifier = BpmnStyleIdentifier.EXTRA_CSS_CLASSES;
class StyleManager {
constructor(model) {
Object.defineProperty(this, "model", {
enumerable: true,
configurable: true,
writable: true,
value: model
});
Object.defineProperty(this, "stylesCache", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
}
clear() {
this.stylesCache.clear();
}
resetAllStyles() {
for (const cellId of this.stylesCache.keys()) {
this.resetStyle(cellId, this.stylesCache.get(cellId));
}
}
resetStyleIfIsStored(cellId) {
const style = this.stylesCache.get(cellId);
if (style) {
this.resetStyle(cellId, style);
}
}
resetStyle(cellId, initialStyle) {
const cell = this.model.getCell(cellId);
const cssClasses = getStyleValue(cell.getStyle(), cssClassesStyleIdentifier, '');
const styleWithCssClasses = setStyle(initialStyle, cssClassesStyleIdentifier, cssClasses);
this.model.setStyle(cell, styleWithCssClasses);
this.stylesCache.delete(cellId);
}
ensureStyleIsStored(cell) {
const cellId = cell.getId();
if (!this.stylesCache.has(cellId)) {
this.stylesCache.set(cellId, cell.getStyle());
}
}
}
function createNewStyleRegistry(graph) {
return new StyleRegistryImpl(createNewStyleUpdater(graph));
}
class StyleRegistryImpl {
constructor(styleUpdater) {
Object.defineProperty(this, "styleUpdater", {
enumerable: true,
configurable: true,
writable: true,
value: styleUpdater
});
}
clearCache() {
this.styleUpdater.clear();
}
updateStyle(bpmnElementIds, styleUpdate) {
this.styleUpdater.updateStyle(bpmnElementIds, styleUpdate);
}
resetStyle(bpmnElementIds) {
this.styleUpdater.resetStyle(bpmnElementIds);
}
}
function createNewBpmnElementsRegistry(bpmnModelRegistry, graph) {
return new BpmnElementsRegistry(bpmnModelRegistry, new HtmlElementRegistry(graph.container, new BpmnQuerySelectors()), createNewCssRegistry(graph), createNewOverlaysRegistry(graph), createNewStyleRegistry(graph));
}
class BpmnElementsRegistry {
constructor(bpmnModelRegistry, htmlElementRegistry, cssClassesRegistry, overlaysRegistry, styleRegistry) {
Object.defineProperty(this, "bpmnModelRegistry", {
enumerable: true,
configurable: true,
writable: true,
value: bpmnModelRegistry
});
Object.defineProperty(this, "htmlElementRegistry", {
enumerable: true,
configurable: true,
writable: true,
value: htmlElementRegistry
});
Object.defineProperty(this, "cssClassesRegistry", {
enumerable: true,
configurable: true,
writable: true,
value: cssClassesRegistry
});
Object.defineProperty(this, "overlaysRegistry", {
enumerable: true,
configurable: true,
writable: true,
value: overlaysRegistry
});
Object.defineProperty(this, "styleRegistry", {
enumerable: true,
configurable: true,
writable: true,
value: styleRegistry
});
this.bpmnModelRegistry.registerOnLoadCallback(() => {
this.cssClassesRegistry.clearCache();
this.styleRegistry.clearCache();
});
}
getModelElementsByIds(bpmnElementIds) {
return filterDuplicates(bpmnElementIds)
.map(id => this.bpmnModelRegistry.getBpmnSemantic(id))
.filter(Boolean);
}
getElementsByIds(bpmnElementIds) {
return this.getModelElementsByIds(bpmnElementIds).map(bpmnSemantic => ({
bpmnSemantic: bpmnSemantic,
htmlElement: this.htmlElementRegistry.getBpmnHtmlElement(bpmnSemantic.id),
}));
}
getModelElementsByKinds(bpmnKinds) {
return filterDuplicates(bpmnKinds)
.flatMap(kind => this.htmlElementRegistry.getBpmnHtmlElements(kind))
.map(htmlElement => this.getRelatedBpmnSemantic(htmlElement));
}
getElementsByKinds(bpmnKinds) {
return filterDuplicates(bpmnKinds)
.flatMap(kind => this.htmlElementRegistry.getBpmnHtmlElements(kind))
.map(htmlElement => ({ htmlElement, bpmnSemantic: this.getRelatedBpmnSemantic(htmlElement) }));
}
getRelatedBpmnSemantic(htmlElement) {
return this.bpmnModelRegistry.getBpmnSemantic(htmlElement.dataset.bpmnId);
}
addCssClasses(bpmnElementIds, classNames) {
this.cssClassesRegistry.addCssClasses(bpmnElementIds, classNames);
}
removeCssClasses(bpmnElementIds, classNames) {
this.cssClassesRegistry.removeCssClasses(bpmnElementIds, classNames);
}
removeAllCssClasses(bpmnElementIds) {
this.cssClassesRegistry.removeAllCssClasses(bpmnElementIds);
}
toggleCssClasses(bpmnElementIds, classNames) {
this.cssClassesRegistry.toggleCssClasses(bpmnElementIds, classNames);
}
addOverlays(bpmnElementId, overlays) {
this.overlaysRegistry.addOverlays(bpmnElementId, overlays);
}
removeAllOverlays(bpmnElementId) {
this.overlaysRegistry.removeAllOverlays(bpmnElementId);
}
updateStyle(bpmnElementIds, styleUpdate) {
this.styleRegistry.updateStyle(bpmnElementIds, styleUpdate);
}
resetStyle(bpmnElementIds) {
this.styleRegistry.resetStyle(bpmnElementIds);
}
}
class HtmlElementRegistry {
constructor(container, querySelectors) {
Object.defineProperty(this, "container", {
enumerable: true,
configurable: true,
writable: true,
value: container
});
Object.defineProperty(this, "querySelectors", {
enumerable: true,
configurable: true,
writable: true,
value: querySelectors
});
}
getBpmnHtmlElement(bpmnElementId) {
return this.container.querySelector(this.querySelectors.element(bpmnElementId));
}
getBpmnHtmlElements(bpmnElementKind) {
const selectors = this.querySelectors.elementsOfKind(computeBpmnBaseClassName(bpmnElementKind));
return [...this.container.querySelectorAll(selectors)];
}
}
const filterDuplicates = (ids) => [...new Set(ensureIsArray(ids))];
class ModelFiltering {
filter(bpmnModel, modelFilter) {
const poolIdsFilter = [];
const poolNamesFilter = [];
for (const filter of ensureIsArray(modelFilter === null || modelFilter === void 0 ? void 0 : modelFilter.pools).filter(p => p && Object.keys(p).length > 0))
filter.id ? poolIdsFilter.push(filter.id) : filter.name && poolNamesFilter.push(filter.name);
if (poolIdsFilter.length === 0 && poolNamesFilter.length === 0) {
return bpmnModel;
}
const { filteredPools, filteredPoolIds } = filterPools(bpmnModel, poolIdsFilter, poolNamesFilter);
const filteredPoolAndBlackPoolIds = [...poolIdsFilter, ...filteredPoolIds];
const { filteredLanes, filteredLaneIds, filteredFlowNodes, filteredFlowNodeIds } = filterLanesAndFlowNodes(bpmnModel.lanes, bpmnModel.flowNodes, filteredPoolAndBlackPoolIds);
const filteredEdges = filterEdges(bpmnModel.edges, [...filteredPoolAndBlackPoolIds, ...filteredLaneIds, ...filteredFlowNodeIds]);
if (filteredPools.length === 0 && filteredLanes.length === 0 && filteredFlowNodes.length === 0 && filteredEdges.length === 0) {
let errorMessageSuffix = poolIdsFilter.length > 0 ? ` for ids [${poolIdsFilter}]` : '';
const messageSeparator = errorMessageSuffix ? ' and' : '';
errorMessageSuffix += poolNamesFilter.length > 0 ? `${messageSeparator} for names [${poolNamesFilter}]` : '';
throw new Error('No matching pools' + errorMessageSuffix);
}
return { lanes: filteredLanes, flowNodes: filteredFlowNodes, pools: filteredPools, edges: filteredEdges };
}
}
function filterPools(bpmnModel, poolIdsFilter, poolNamesFilter) {
const filteredPools = bpmnModel.pools.filter(pool => poolIdsFilter.includes(pool.bpmnElement.id) || poolNamesFilter.includes(pool.bpmnElement.name));
const filteredPoolIds = filteredPools.map(shape => shape.bpmnElement.id);
return { filteredPools, filteredPoolIds };
}
function filterLanesAndFlowNodes(lanes, flowNodes, parentIdsToFilter) {
const { filteredLanes, filteredLaneIds } = filterLanes(lanes, parentIdsToFilter);
const { filteredLanes: filteredSubLanes, filteredLaneIds: filteredSubLanesIds, filteredFlowNodes, filteredFlowNodeIds, } = filterFlowNodes(flowNodes, [...parentIdsToFilter, ...filteredLaneIds], lanes);
filteredLanes.push(...filteredSubLanes);
filteredLaneIds.push(...filteredSubLanesIds);
return { filteredLanes, filteredLaneIds, filteredFlowNodes, filteredFlowNodeIds };
}
function filterLanes(lanes, parentIdsToFilter) {
const filteredLanes = lanes.filter(shape => parentIdsToFilter.includes(shape.bpmnElement.parentId));
const filteredLaneIds = filteredLanes.map(shape => shape.bpmnElement.id);
if (filteredLanes.length > 0) {
const { filteredLanes: filteredSubLanes, filteredLaneIds: filteredSubLaneIds } = filterLanes(lanes, filteredLaneIds);
filteredLanes.push(...filteredSubLanes);
filteredLaneIds.push(...filteredSubLaneIds);
}
return { filteredLanes, filteredLaneIds };
}
function filterFlowNodes(flowNodes, parentIdsToFilter, lanes) {
const filteredFlowNodes = flowNodes.filter(shape => parentIdsToFilter.includes(shape.bpmnElement.parentId));
if (filteredFlowNodes.length === 0) {
return { filteredLanes: [], filteredLaneIds: [], filteredFlowNodes: [], filteredFlowNodeIds: [] };
}
const filteredFlowNodeIds = filteredFlowNodes.map(shape => shape.bpmnElement.id);
const { filteredLanes, filteredLaneIds, filteredFlowNodes: filteredChildFlowNodes, filteredFlowNodeIds: filteredChildFlowNodeIds, } = filterLanesAndFlowNodes(lanes, flowNodes, filteredFlowNodeIds);
filteredFlowNodes.push(...filteredChildFlowNodes);
filteredFlowNodeIds.push(...filteredChildFlowNodeIds);
return { filteredLanes, filteredLaneIds, filteredFlowNodes, filteredFlowNodeIds };
}
function filterEdges(edges, filteredElementIds) {
return edges.filter(edge => filteredElementIds.includes(edge.bpmnElement.sourceReferenceId) && filteredElementIds.includes(edge.bpmnElement.targetReferenceId));
}
class BpmnModelRegistry {
constructor() {
Object.defineProperty(this, "searchableModel", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "onLoadCallback", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
}
load(bpmnModel, modelFilter) {
var _a;
const filteredModel = new ModelFiltering().filter(bpmnModel, modelFilter);
this.searchableModel = new SearchableModel(filteredModel);
(_a = this.onLoadCallback) === null || _a === void 0 ? void 0 : _a.call(this);
return toRenderedModel(filteredModel);
}
registerOnLoadCallback(callback) {
this.onLoadCallback = callback;
}
getBpmnSemantic(bpmnElementId) {
var _a;
const element = (_a = this.searchableModel) === null || _a === void 0 ? void 0 : _a.elementById(bpmnElementId);
if (!element) {
return undefined;
}
const bpmnElement = element.bpmnElement;
const isShape = bpmnElement instanceof ShapeBpmnElement;
return Object.assign({ id: bpmnElementId, isShape: isShape, kind: bpmnElement.kind, name: bpmnElement.name }, (bpmnElement instanceof Flow
? {
sourceRefId: bpmnElement.sourceReferenceId,
targetRefId: bpmnElement.targetReferenceId,
}
: {
callActivityGlobalTaskKind: bpmnElement instanceof ShapeBpmnCallActivity ? bpmnElement.globalTaskKind : undefined,
callActivityKind: bpmnElement instanceof ShapeBpmnCallActivity ? bpmnElement.callActivityKind : undefined,
eventDefinitionKind: bpmnElement instanceof ShapeBpmnEvent ? bpmnElement.eventDefinitionKind : undefined,
linkEventSourceIds: bpmnElement instanceof ShapeBpmnIntermediateCatchEvent && bpmnElement.eventDefinitionKind == exports.ShapeBpmnEventDefinitionKind.LINK ? bpmnElement.sourceIds : undefined,
linkEventTargetId: bpmnElement instanceof ShapeBpmnIntermediateThrowEvent ? bpmnElement.targetId : undefined,
incomingIds: bpmnElement.incomingIds,
outgoingIds: bpmnElement.outgoingIds,
parentId: bpmnElement.parentId,
subProcessKind: bpmnElement instanceof ShapeBpmnSubProcess ? bpmnElement.subProcessKind : undefined,
}));
}
}
function toRenderedModel(bpmnModel) {
const collapsedSubProcessIds = new Set(bpmnModel.flowNodes
.filter(shape => {
const bpmnElement = shape.bpmnElement;
return ShapeUtil.isSubProcess(bpmnElement.kind) && bpmnElement.markers.includes(exports.ShapeBpmnMarkerKind.EXPAND);
})
.map(shape => shape.bpmnElement.id));
const subprocesses = [];
const boundaryEvents = [];
const otherFlowNodes = [];
for (const shape of bpmnModel.flowNodes) {
const kind = shape.bpmnElement.kind;
if (ShapeUtil.isSubProcess(kind)) {
subprocesses.push(shape);
}
else if (ShapeUtil.isBoundaryEvent(kind)) {
boundaryEvents.push(shape);
}
else if (!collapsedSubProcessIds.has(shape.bpmnElement.parentId)) {
otherFlowNodes.push(shape);
}
}
return { boundaryEvents: boundaryEvents, edges: bpmnModel.edges, lanes: bpmnModel.lanes, otherFlowNodes: otherFlowNodes, pools: bpmnModel.pools, subprocesses: subprocesses };
}
class SearchableModel {
constructor(bpmnModel) {
Object.defineProperty(this, "elements", {
enumerable: true,
configurable: true,
writable: true,
value: new Map()
});
for (const shapeOrEdge of [...bpmnModel.pools, ...bpmnModel.lanes, ...bpmnModel.flowNodes, ...bpmnModel.edges]) {
this.elements.set(shapeOrEdge.bpmnElement.id, shapeOrEdge);
}
}
elementById(id) {
return this.elements.get(id);
}
}
class BpmnVisualization {
constructor(options) {
Object.defineProperty(this, "graph", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "navigation", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "bpmnElementsRegistry", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "bpmnModelRegistry", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "parserOptions", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "rendererOptions", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.rendererOptions = options === null || options === void 0 ? void 0 : options.renderer;
const configurator = new GraphConfigurator(htmlElement(options === null || options === void 0 ? void 0 : options.container));
this.graph = configurator.configure(options);
this.navigation = new Navigation(this.graph);
this.bpmnModelRegistry = new BpmnModelRegistry();
this.bpmnElementsRegistry = createNewBpmnElementsRegistry(this.bpmnModelRegistry, this.graph);
this.parserOptions = options === null || options === void 0 ? void 0 : options.parser;
}
load(xml, options) {
const bpmnModel = newBpmnParser(this.parserOptions).parse(xml);
const renderedModel = this.bpmnModelRegistry.load(bpmnModel, options === null || options === void 0 ? void 0 : options.modelFilter);
newBpmnRenderer(this.graph, this.rendererOptions).render(renderedModel, options === null || options === void 0 ? void 0 : options.fit);
}
}
const libraryVersion = '0.46.0';
const getVersion = () => {
return { lib: libraryVersion, dependencies: new Map([['mxGraph', mxClient.VERSION]]) };
};
exports.BpmnCanvas = BpmnCanvas;
exports.BpmnElementsRegistry = BpmnElementsRegistry;
exports.BpmnStyleIdentifier = BpmnStyleIdentifier;
exports.BpmnVisualization = BpmnVisualization;
exports.IconPainter = IconPainter;
exports.IconPainterProvider = IconPainterProvider;
exports.MarkerIdentifier = MarkerIdentifier;
exports.ShapeUtil = ShapeUtil;
exports.StyleConfigurator = StyleConfigurator;
exports.StyleDefault = StyleDefault;
exports.getVersion = getVersion;
exports.mxgraph = mxgraph;
return exports;
})({});