UNPKG

ngx-diagrams

Version:

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0.

5,721 lines 197 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('rxjs/operators'), require('lodash'), require('@angular/common'), require('dagre')) :
    typeof define === 'function' && define.amd ? define('ngx-diagrams', ['exports', '@angular/core', 'rxjs', 'rxjs/operators', 'lodash', '@angular/common', 'dagre'], factory) :
    (global = global || self, factory(global['ngx-diagrams'] = {}, global.ng.core, global.rxjs, global.rxjs.operators, global._, global.ng.common, global.dagre));
}(this, (function (exports, core, rxjs, operators, lodash, common, dagre) { 'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    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

    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.

    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    /* global Reflect, Promise */

    var extendStatics = function(d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };

    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    var __assign = function() {
        __assign = Object.assign || function __assign(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };

    function __rest(s, e) {
        var t = {};
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
            t[p] = s[p];
        if (s != null && typeof Object.getOwnPropertySymbols === "function")
            for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
                if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                    t[p[i]] = s[p[i]];
            }
        return t;
    }

    function __decorate(decorators, target, key, desc) {
        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
        if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
        else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
        return c > 3 && r && Object.defineProperty(target, key, r), r;
    }

    function __param(paramIndex, decorator) {
        return function (target, key) { decorator(target, key, paramIndex); }
    }

    function __metadata(metadataKey, metadataValue) {
        if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
    }

    function __awaiter(thisArg, _arguments, P, generator) {
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    }

    function __generator(thisArg, body) {
        var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
        return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
        function verb(n) { return function (v) { return step([n, v]); }; }
        function step(op) {
            if (f) throw new TypeError("Generator is already executing.");
            while (_) try {
                if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
                if (y = 0, t) op = [op[0] & 2, t.value];
                switch (op[0]) {
                    case 0: case 1: t = op; break;
                    case 4: _.label++; return { value: op[1], done: false };
                    case 5: _.label++; y = op[1]; op = [0]; continue;
                    case 7: op = _.ops.pop(); _.trys.pop(); continue;
                    default:
                        if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                        if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                        if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                        if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                        if (t[2]) _.ops.pop();
                        _.trys.pop(); continue;
                }
                op = body.call(thisArg, _);
            } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
            if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
        }
    }

    function __exportStar(m, exports) {
        for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
    }

    function __values(o) {
        var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
        if (m) return m.call(o);
        return {
            next: function () {
                if (o && i >= o.length) o = void 0;
                return { value: o && o[i++], done: !o };
            }
        };
    }

    function __read(o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
        }
        catch (error) { e = { error: error }; }
        finally {
            try {
                if (r && !r.done && (m = i["return"])) m.call(i);
            }
            finally { if (e) throw e.error; }
        }
        return ar;
    }

    function __spread() {
        for (var ar = [], i = 0; i < arguments.length; i++)
            ar = ar.concat(__read(arguments[i]));
        return ar;
    }

    function __spreadArrays() {
        for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
        for (var r = Array(s), k = 0, i = 0; i < il; i++)
            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
                r[k] = a[j];
        return r;
    };

    function __await(v) {
        return this instanceof __await ? (this.v = v, this) : new __await(v);
    }

    function __asyncGenerator(thisArg, _arguments, generator) {
        if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
        var g = generator.apply(thisArg, _arguments || []), i, q = [];
        return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
        function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
        function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
        function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
        function fulfill(value) { resume("next", value); }
        function reject(value) { resume("throw", value); }
        function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
    }

    function __asyncDelegator(o) {
        var i, p;
        return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
        function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
    }

    function __asyncValues(o) {
        if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
        var m = o[Symbol.asyncIterator], i;
        return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
        function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
        function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
    }

    function __makeTemplateObject(cooked, raw) {
        if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
        return cooked;
    };

    function __importStar(mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
        result.default = mod;
        return result;
    }

    function __importDefault(mod) {
        return (mod && mod.__esModule) ? mod : { default: mod };
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/utils/tool-kit.util.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @enum {number} */
    var LOG_LEVEL = {
        'LOG': 0,
        'ERROR': 1,
    };
    LOG_LEVEL[LOG_LEVEL['LOG']] = 'LOG';
    LOG_LEVEL[LOG_LEVEL['ERROR']] = 'ERROR';
    // @internal
    /** @type {?} */
    exports.__DEV__ = true;
    // @internal
    /** @type {?} */
    exports.__LOG__ = LOG_LEVEL.ERROR;
    /**
     * @return {?}
     */
    function enableDiagramProdMode() {
        exports.__DEV__ = false;
    }
    // @internal
    /**
     * @param {?} level
     * @return {?}
     */
    function setLogLevel(level) {
        exports.__LOG__ = level;
    }
    // @internal
    /**
     * @return {?}
     */
    function isDev() {
        return exports.__DEV__;
    }
    // @internal
    /**
     * @param {?} message
     * @param {?=} level
     * @param {...?} args
     * @return {?}
     */
    function log(message, level) {
        if (level === void 0) { level = LOG_LEVEL.LOG; }
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        if (isDev() && exports.__LOG__ === level) {
            if (exports.__LOG__ === LOG_LEVEL.ERROR) {
                console.error.apply(console, __spread([message], args));
            }
            console.log.apply(console, __spread([message], args));
        }
    }
    /**
     * rxjs log operator
     * \@internal
     * @param {?} message
     * @param {?=} level
     * @param {...?} args
     * @return {?}
     */
    function withLog(message, level) {
        if (level === void 0) { level = LOG_LEVEL.LOG; }
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        return (/**
         * @template T
         * @param {?} source
         * @return {?}
         */
        function (source) { return (isDev() ? source.pipe(operators.tap((/**
         * @param {?} val
         * @return {?}
         */
        function (val) { return log.apply(void 0, __spread([message, level, val], args)); }))) : source); });
    }
    /**
     * Generates a unique ID
     * @return {?}
     */
    function UID() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (/**
         * @param {?} c
         * @return {?}
         */
        function (c) {
            /** @type {?} */
            var r = (Math.random() * 16) | 0;
            /** @type {?} */
            var v = c === 'x' ? r : (r & 0x3) | 0x8;
            return v.toString(16);
        }));
    }
    /**
     * @template T
     * @param {?} val
     * @return {?}
     */
    function isArray(val) {
        return Array.isArray(val);
    }
    /**
     * @param {?} val
     * @return {?}
     */
    function isString(val) {
        return typeof val === 'string';
    }
    /**
     * @param {?} val
     * @return {?}
     */
    function isFunction(val) {
        return typeof val === 'function';
    }
    // @internal
    /**
     * @param {?} v
     * @return {?}
     */
    function isNil(v) {
        return v === null || v === undefined;
    }
    /**
     * @template T
     * @param {?} value
     * @return {?}
     */
    function coerceArray(value) {
        if (isNil(value)) {
            return [];
        }
        return Array.isArray(value) ? value : [value];
    }
    /**
     * @template T
     * @param {?} map
     * @return {?}
     */
    function mapToArray(map) {
        /** @type {?} */
        var result = [];
        for (var key in map) {
            if (!isNil(map[key])) {
                result.push(map[key]);
            }
        }
        return result;
    }
    /**
     * @template T
     * @param {?} arr
     * @return {?}
     */
    function arrayToMap(arr) {
        var e_1, _a;
        /** @type {?} */
        var result = {};
        try {
            for (var arr_1 = __values(arr), arr_1_1 = arr_1.next(); !arr_1_1.done; arr_1_1 = arr_1.next()) {
                var val = arr_1_1.value;
                if (!isNil(val)) {
                    result[val.id] = val;
                }
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) _a.call(arr_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        return result;
    }
    /**
     * @param {?} firstPoint
     * @param {?} lastPoint
     * @return {?}
     */
    function generateLinePath(firstPoint, lastPoint) {
        return "M" + firstPoint.x$ + "," + firstPoint.y + " L " + lastPoint.x$ + "," + lastPoint.y;
    }
    /**
     * @param {?} firstPoint
     * @param {?} lastPoint
     * @param {?=} curvy
     * @return {?}
     */
    function generateCurvePath(firstPoint, lastPoint, curvy) {
        if (curvy === void 0) { curvy = 0; }
        /** @type {?} */
        var isHorizontal = Math.abs(firstPoint.x - lastPoint.x) > Math.abs(firstPoint.y - lastPoint.y);
        /** @type {?} */
        var curvyX = isHorizontal ? curvy : 0;
        /** @type {?} */
        var curvyY = isHorizontal ? 0 : curvy;
        return "M" + firstPoint.x + "," + firstPoint.y + " C " + (firstPoint.x + curvyX) + "," + (firstPoint.y + curvyY) + "\n    " + (lastPoint.x - curvyX) + "," + (lastPoint.y - curvyY) + " " + lastPoint.x + "," + lastPoint.y;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/interfaces/event.interface.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    // region events
    /**
     * @template T
     */
    var   
    // region events
    /**
     * @template T
     */
    BaseEvent = /** @class */ (function () {
        function BaseEvent(entity) {
            var _this = this;
            this.id = UID();
            this.entity = entity;
            this.entityId = entity.id;
            this.firing = true;
            this.stopPropagation = (/**
             * @return {?}
             */
            function () { return (_this.firing = false); });
        }
        return BaseEvent;
    }());
    if (false) {
        /** @type {?} */
        BaseEvent.prototype.entity;
        /** @type {?} */
        BaseEvent.prototype.entityId;
        /** @type {?} */
        BaseEvent.prototype.stopPropagation;
        /** @type {?} */
        BaseEvent.prototype.firing;
        /** @type {?} */
        BaseEvent.prototype.id;
    }
    /**
     * @template T
     */
    var   /**
     * @template T
     */
    LockEvent = /** @class */ (function (_super) {
        __extends(LockEvent, _super);
        function LockEvent(entity, locked) {
            if (locked === void 0) { locked = false; }
            var _this = _super.call(this, entity) || this;
            _this.locked = locked;
            return _this;
        }
        return LockEvent;
    }(BaseEvent));
    if (false) {
        /** @type {?} */
        LockEvent.prototype.locked;
    }
    /**
     * @template P, T
     */
    var   /**
     * @template P, T
     */
    ParentChangeEvent = /** @class */ (function (_super) {
        __extends(ParentChangeEvent, _super);
        function ParentChangeEvent(entity, parent) {
            var _this = _super.call(this, entity) || this;
            _this.parent = parent;
            return _this;
        }
        return ParentChangeEvent;
    }(BaseEvent));
    if (false) {
        /** @type {?} */
        ParentChangeEvent.prototype.parent;
    }
    /**
     * @template T
     */
    var   /**
     * @template T
     */
    SelectionEvent = /** @class */ (function (_super) {
        __extends(SelectionEvent, _super);
        function SelectionEvent(entity, selected) {
            var _this = _super.call(this, entity) || this;
            _this.isSelected = selected;
            return _this;
        }
        return SelectionEvent;
    }(BaseEvent));
    if (false) {
        /** @type {?} */
        SelectionEvent.prototype.isSelected;
    }
    /**
     * @template T
     */
    var   /**
     * @template T
     */
    PaintedEvent = /** @class */ (function (_super) {
        __extends(PaintedEvent, _super);
        function PaintedEvent(entity, painted) {
            if (painted === void 0) { painted = false; }
            var _this = _super.call(this, entity) || this;
            _this.isPainted = painted;
            return _this;
        }
        return PaintedEvent;
    }(BaseEvent));
    if (false) {
        /** @type {?} */
        PaintedEvent.prototype.isPainted;
    }
    /**
     * @record
     */
    function DestroyOptions() { }
    if (false) {
        /** @type {?|undefined} */
        DestroyOptions.prototype.propagate;
        /** @type {?|undefined} */
        DestroyOptions.prototype.emit;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/base.entity.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var BaseEntity = /** @class */ (function () {
        function BaseEntity(id, logPrefix) {
            if (logPrefix === void 0) { logPrefix = ''; }
            this._destroyed = new rxjs.Subject();
            this._destroyed$ = this._destroyed.asObservable();
            this._locked = new rxjs.BehaviorSubject(false);
            this._locked$ = this._locked.asObservable();
            this._id = id || UID();
            this._logPrefix = "" + logPrefix;
        }
        Object.defineProperty(BaseEntity.prototype, "id", {
            get: /**
             * @return {?}
             */
            function () {
                return this._id;
            },
            set: /**
             * @param {?} id
             * @return {?}
             */
            function (id) {
                this._id = id;
            },
            enumerable: true,
            configurable: true
        });
        /**
         * @param {?} message
         * @param {...?} args
         * @return {?}
         */
        BaseEntity.prototype.log = /**
         * @param {?} message
         * @param {...?} args
         * @return {?}
         */
        function (message) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            log.apply(void 0, __spread([this._logPrefix + " " + message + ": ", LOG_LEVEL.LOG], args));
        };
        /**
         * @param {?} message
         * @param {...?} args
         * @return {?}
         */
        BaseEntity.prototype.withLog = /**
         * @param {?} message
         * @param {...?} args
         * @return {?}
         */
        function (message) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            return withLog.apply(void 0, __spread([this._logPrefix + " " + message + ": ", LOG_LEVEL.LOG], args));
        };
        /**
         * @return {?}
         */
        BaseEntity.prototype.getLocked = /**
         * @return {?}
         */
        function () {
            return this._locked.getValue();
        };
        /**
         * @param {?=} locked
         * @return {?}
         */
        BaseEntity.prototype.setLocked = /**
         * @param {?=} locked
         * @return {?}
         */
        function (locked) {
            if (locked === void 0) { locked = true; }
            this._locked.next(locked);
        };
        // tslint:disable-next-line
        // tslint:disable-next-line
        /**
         * @param {?=} lookupTable
         * @param {?=} clone
         * @return {?}
         */
        BaseEntity.prototype.doClone = 
        // tslint:disable-next-line
        /**
         * @param {?=} lookupTable
         * @param {?=} clone
         * @return {?}
         */
        function (lookupTable, clone) {
            if (lookupTable === void 0) { lookupTable = {}; }
            /*noop*/
        };
        /**
         * @param {?=} lookupTable
         * @return {?}
         */
        BaseEntity.prototype.clone = /**
         * @param {?=} lookupTable
         * @return {?}
         */
        function (lookupTable) {
            if (lookupTable === void 0) { lookupTable = {}; }
            // try and use an existing clone first
            if (lookupTable[this.id]) {
                return lookupTable[this.id];
            }
            /** @type {?} */
            var clone = __assign({}, this);
            clone.id = UID();
            // clone.clearListeners();
            lookupTable[this.id] = clone;
            this.doClone(lookupTable, clone);
            return clone;
        };
        /**
         * @return {?}
         */
        BaseEntity.prototype.lockChanges = /**
         * @return {?}
         */
        function () {
            var _this = this;
            return this._locked$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.map((/**
             * @param {?} locked
             * @return {?}
             */
            function (locked) { return new LockEvent(_this, locked); })), this.withLog('lockChanges'));
        };
        /**
         * @param {?=} options
         * @return {?}
         */
        BaseEntity.prototype.destroy = /**
         * @param {?=} options
         * @return {?}
         */
        function (options) {
            /** @type {?} */
            var defaultOptions = __assign({ emit: true, propagate: true }, options);
            this.log('entity destroyed');
            this._destroyed.next(defaultOptions);
            this._destroyed.complete();
        };
        /**
         * @return {?}
         */
        BaseEntity.prototype.onEntityDestroy = /**
         * @return {?}
         */
        function () {
            return this._destroyed$.pipe(operators.filter((/**
             * @param {?} opts
             * @return {?}
             */
            function (opts) { return opts.emit; })), operators.mapTo(new BaseEvent(this)));
        };
        return BaseEntity;
    }());
    if (false) {
        /**
         * @type {?}
         * @private
         */
        BaseEntity.prototype._id;
        /**
         * a prefix to make logs more easier
         * @type {?}
         * @private
         */
        BaseEntity.prototype._logPrefix;
        /**
         * @type {?}
         * @private
         */
        BaseEntity.prototype._destroyed;
        /**
         * @type {?}
         * @private
         */
        BaseEntity.prototype._destroyed$;
        /**
         * @type {?}
         * @private
         */
        BaseEntity.prototype._locked;
        /**
         * @type {?}
         * @private
         */
        BaseEntity.prototype._locked$;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/models/base.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @template X
     */
    var   /**
     * @template X
     */
    BaseModel = /** @class */ (function (_super) {
        __extends(BaseModel, _super);
        function BaseModel(type, id, logPrefix) {
            if (logPrefix === void 0) { logPrefix = '[Base]'; }
            var _this = _super.call(this, id, logPrefix) || this;
            _this._parent = new rxjs.BehaviorSubject(null);
            _this._parent$ = _this._parent.asObservable();
            _this._selected = new rxjs.BehaviorSubject(false);
            _this._selected$ = _this._selected.asObservable();
            _this._painted = new rxjs.BehaviorSubject(false);
            _this._painted$ = _this._painted.asObservable();
            _this._type = type;
            return _this;
        }
        /**
         * @return {?}
         */
        BaseModel.prototype.getParent = /**
         * @return {?}
         */
        function () {
            return this._parent.getValue();
        };
        /**
         * @param {?} parent
         * @return {?}
         */
        BaseModel.prototype.setParent = /**
         * @param {?} parent
         * @return {?}
         */
        function (parent) {
            this._parent.next(parent);
        };
        /**
         * @return {?}
         */
        BaseModel.prototype.parentChanges = /**
         * @return {?}
         */
        function () {
            var _this = this;
            return this._parent$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.map((/**
             * @param {?} p
             * @return {?}
             */
            function (p) { return new ParentChangeEvent(_this, p); })));
        };
        /**
         * @return {?}
         */
        BaseModel.prototype.getPainted = /**
         * @return {?}
         */
        function () {
            return this._painted.getValue();
        };
        /**
         * @param {?=} painted
         * @return {?}
         */
        BaseModel.prototype.setPainted = /**
         * @param {?=} painted
         * @return {?}
         */
        function (painted) {
            if (painted === void 0) { painted = true; }
            this._painted.next(painted);
        };
        /**
         * @return {?}
         */
        BaseModel.prototype.paintChanges = /**
         * @return {?}
         */
        function () {
            var _this = this;
            return this._painted$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.map((/**
             * @param {?} p
             * @return {?}
             */
            function (p) { return new PaintedEvent(_this, p); })));
        };
        /**
         * @return {?}
         */
        BaseModel.prototype.getType = /**
         * @return {?}
         */
        function () {
            return this._type;
        };
        /**
         * @return {?}
         */
        BaseModel.prototype.getSelected = /**
         * @return {?}
         */
        function () {
            return this._selected.getValue();
        };
        /**
         * @return {?}
         */
        BaseModel.prototype.selectSelected = /**
         * @return {?}
         */
        function () {
            return this._selected.asObservable();
        };
        /**
         * @param {?=} selected
         * @return {?}
         */
        BaseModel.prototype.setSelected = /**
         * @param {?=} selected
         * @return {?}
         */
        function (selected) {
            if (selected === void 0) { selected = true; }
            this._selected.next(selected);
        };
        /**
         * @return {?}
         */
        BaseModel.prototype.selectionChanges = /**
         * @return {?}
         */
        function () {
            var _this = this;
            return this._selected$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.map((/**
             * @param {?} s
             * @return {?}
             */
            function (s) { return new SelectionEvent(_this, s); })), this.withLog('selectionChanges'));
        };
        /**
         * @return {?}
         */
        BaseModel.prototype.getSelectedEntities = /**
         * @return {?}
         */
        function () {
            return this._selected.value ? [this] : [];
        };
        return BaseModel;
    }(BaseEntity));
    if (false) {
        /**
         * @type {?}
         * @private
         */
        BaseModel.prototype._type;
        /**
         * @type {?}
         * @private
         */
        BaseModel.prototype._parent;
        /**
         * @type {?}
         * @private
         */
        BaseModel.prototype._parent$;
        /**
         * @type {?}
         * @private
         */
        BaseModel.prototype._selected;
        /**
         * @type {?}
         * @private
         */
        BaseModel.prototype._selected$;
        /**
         * @type {?}
         * @private
         */
        BaseModel.prototype._painted;
        /**
         * @type {?}
         * @private
         */
        BaseModel.prototype._painted$;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/models/node.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @template P
     */
    var   /**
     * @template P
     */
    NodeModel = /** @class */ (function (_super) {
        __extends(NodeModel, _super);
        function NodeModel(nodeType, id, extras, x, y, width, height, logPrefix) {
            if (nodeType === void 0) { nodeType = 'default'; }
            if (extras === void 0) { extras = {}; }
            if (x === void 0) { x = 0; }
            if (y === void 0) { y = 0; }
            if (width === void 0) { width = 0; }
            if (height === void 0) { height = 0; }
            if (logPrefix === void 0) { logPrefix = '[Node]'; }
            var _this = _super.call(this, nodeType, id, logPrefix) || this;
            _this._extras = new rxjs.BehaviorSubject(extras);
            _this._ports = new rxjs.BehaviorSubject({});
            _this._dimensions = new rxjs.BehaviorSubject({ width: width, height: height });
            _this._coords = new rxjs.BehaviorSubject({ x: x, y: y });
            _this.extras$ = _this._extras.asObservable();
            _this.ports$ = _this._ports.asObservable();
            _this.coords$ = _this._coords.asObservable();
            _this.dimensions$ = _this._dimensions.asObservable();
            return _this;
        }
        /**
         * @return {?}
         */
        NodeModel.prototype.getCoords = /**
         * @return {?}
         */
        function () {
            return this._coords.getValue();
        };
        /**
         * @param {?} __0
         * @return {?}
         */
        NodeModel.prototype.setCoords = /**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var x = _a.x, y = _a.y;
            var _b = this.getCoords(), oldX = _b.x, oldY = _b.y;
            Object.values(this._ports.getValue()).forEach((/**
             * @param {?} port
             * @return {?}
             */
            function (port) {
                Object.values(port.getLinks()).forEach((/**
                 * @param {?} link
                 * @return {?}
                 */
                function (link) {
                    /** @type {?} */
                    var point = link.getPointForPort(port);
                    var _a = point.getCoords(), pointX = _a.x, pointY = _a.y;
                    point.setCoords({ x: pointX + x - oldX, y: pointY + y - oldY });
                }));
            }));
            this._coords.next({ x: x, y: y });
        };
        // TODO: implement better transition on auto arrange!
        // TODO: implement better transition on auto arrange!
        /**
         * @param {?} __0
         * @return {?}
         */
        NodeModel.prototype.transitionToCoords = 
        // TODO: implement better transition on auto arrange!
        /**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var x = _a.x, y = _a.y;
            // const transitionCompleted = new ReplaySubject(1);
            // let { x: oldX, y: oldY } = this.getCoords();
            // console.log(x, y, oldX, oldY);
            // interval(0)
            // 	.pipe(takeUntil(transitionCompleted))
            // 	.subscribe(
            // 		() => {
            // 			if (oldX < x) {
            // 				oldX++;
            // 			} else if (oldX > x) {
            // 				oldX--;
            // 			}
            // 			if (y > oldY) {
            // 				oldY++;
            // 			} else if (y < oldY) {
            // 				oldY--;
            // 			}
            // 			Object.values(this._ports.getValue()).forEach(port => {
            // 				Object.values(port.getLinks()).forEach(link => {
            // 					const point = link.getPointForPort(port);
            // 					const { x: pointX, y: pointY } = point.getCoords();
            // 					point.setCoords({ x: pointX + x - oldX, y: pointY + y - oldY });
            // 				});
            // 			});
            // 			this._coords.next({ x: oldX, y: oldY });
            // 			if (x === oldX && y === oldY) {
            // 				transitionCompleted.next(true);
            // 				transitionCompleted.complete();
            // 			}
            // 		},
            // 		err => {
            // 			console.error(err);
            // 		},
            // 		() => {
            // 			console.log('finished transition');
            // 		}
            // 	);
        };
        // TODO: override selectionChanges and replace this with it (convert to rx)
        // TODO: override selectionChanges and replace this with it (convert to rx)
        /**
         * @return {?}
         */
        NodeModel.prototype.getSelectedEntities = 
        // TODO: override selectionChanges and replace this with it (convert to rx)
        /**
         * @return {?}
         */
        function () {
            /** @type {?} */
            var entities = _super.prototype.getSelectedEntities.call(this);
            // add the points of each link that are selected here
            if (this.getSelected()) {
                Object.values(this._ports.getValue()).forEach((/**
                 * @param {?} port
                 * @return {?}
                 */
                function (port) {
                    /** @type {?} */
                    var links = Object.values(port.getLinks());
                    entities = entities.concat(links.map((/**
                     * @param {?} link
                     * @return {?}
                     */
                    function (link) {
                        return link.getPointForPort(port);
                    })));
                }));
            }
            this.log('selectedEntities', entities);
            return entities;
        };
        // TODO: map to BaseEvent
        // TODO: map to BaseEvent
        /**
         * @return {?}
         */
        NodeModel.prototype.coordsChanges = 
        // TODO: map to BaseEvent
        /**
         * @return {?}
         */
        function () {
            return this.coords$.pipe(operators.takeUntil(this.onEntityDestroy()));
        };
        /**
         * @return {?}
         */
        NodeModel.prototype.selectCoords = /**
         * @return {?}
         */
        function () {
            return this.coords$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.distinctUntilChanged());
        };
        /**
         * @return {?}
         */
        NodeModel.prototype.selectX = /**
         * @return {?}
         */
        function () {
            return this.selectCoords().pipe(operators.map((/**
             * @param {?} c
             * @return {?}
             */
            function (c) { return c.x; })), this.withLog('selectX'), operators.distinctUntilChanged());
        };
        /**
         * @return {?}
         */
        NodeModel.prototype.selectY = /**
         * @return {?}
         */
        function () {
            return this.selectCoords().pipe(operators.map((/**
             * @param {?} c
             * @return {?}
             */
            function (c) { return c.y; })), this.withLog('selectY'), operators.distinctUntilChanged());
        };
        /**
         * Assign a port to the node and set the node as its getParent
         * @returns the inserted port
         */
        /**
         * Assign a port to the node and set the node as its getParent
         * @param {?} port
         * @return {?} the inserted port
         */
        NodeModel.prototype.addPort = /**
         * Assign a port to the node and set the node as its getParent
         * @param {?} port
         * @return {?} the inserted port
         */
        function (port) {
            var _a;
            port.setParent(this);
            this._ports.next(__assign({}, this._ports.value, (_a = {}, _a[port.id] = port, _a)));
            return port;
        };
        /**
         * @param {?} id
         * @return {?}
         */
        NodeModel.prototype.getPort = /**
         * @param {?} id
         * @return {?}
         */
        function (id) {
            return this._ports.value[id];
        };
        /**
         * @param {?=} selector
         * @return {?}
         */
        NodeModel.prototype.selectPorts = /**
         * @param {?=} selector
         * @return {?}
         */
        function (selector) {
            // TODO: implement selector
            // TODO: create coerce func
            return this.ports$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.distinctUntilChanged(), operators.map((/**
             * @param {?} ports
             * @return {?}
             */
            function (ports) { return mapToArray(ports); })), this.withLog('selectPorts'));
        };
        /**
         * @param {?=} ids
         * @return {?}
         */
        NodeModel.prototype.getPorts = /**
         * @param {?=} ids
         * @return {?}
         */
        function (ids) {
            return this._ports.getValue();
        };
        /**
         * @param {?} __0
         * @return {?}
         */
        NodeModel.prototype.setDimensions = /**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var width = _a.width, height = _a.height;
            this._dimensions.next({ width: width, height: height });
        };
        /**
         * @return {?}
         */
        NodeModel.prototype.getDimensions = /**
         * @return {?}
         */
        function () {
            return this._dimensions.getValue();
        };
        // TODO: return BaseEvent extension
        // TODO: return BaseEvent extension
        /**
         * @return {?}
         */
        NodeModel.prototype.dimensionChanges = 
        // TODO: return BaseEvent extension
        /**
         * @return {?}
         */
        function () {
            return this.dimensions$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.distinctUntilChanged(), this.withLog('DimensionChanges'));
        };
        /**
         * @return {?}
         */
        NodeModel.prototype.getHeight = /**
         * @return {?}
         */
        function () {
            return this._dimensions.getValue().height;
        };
        /**
         * @return {?}
         */
        NodeModel.prototype.getWidth = /**
         * @return {?}
         */
        function () {
            return this._dimensions.getValue().width;
        };
        /**
         * @return {?}
         */
        NodeModel.prototype.selectWidth = /**
         * @return {?}
         */
        function () {
            return this.dimensions$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.map((/**
             * @param {?} d
             * @return {?}
             */
            function (d) { return d.width; })), operators.distinctUntilChanged(), this.withLog('selectWidth'));
        };
        /**
         * @return {?}
         */
        NodeModel.prototype.selectHeight = /**
         * @return {?}
         */
        function () {
            return this.dimensions$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.map((/**
             * @param {?} d
             * @return {?}
             */
            function (d) { return d.width; })), operators.distinctUntilChanged(), this.withLog('selectHeight'));
        };
        /**
         * @param {?} extras
         * @return {?}
         */
        NodeModel.prototype.setExtras = /**
         * @param {?} extras
         * @return {?}
         */
        function (extras) {
            this._extras.next(extras);
        };
        /**
         * @return {?}
         */
        NodeModel.prototype.getExtras = /**
         * @return {?}
         */
        function () {
            return this._extras.getValue();
        };
        /**
         * @template E
         * @param {?=} selector
         * @return {?}
         */
        NodeModel.prototype.selectExtras = /**
         * @template E
         * @param {?=} selector
         * @return {?}
         */
        function (selector) {
            // TODO: impl selector
            return this.extras$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.distinctUntilChanged());
        };
        return NodeModel;
    }(BaseModel));
    if (false) {
        /** @type {?} */
        NodeModel.prototype.id;
        /** @type {?} */
        NodeModel.prototype.diagramEngine;
        /**
         * @type {?}
         * @private
         */
        NodeModel.prototype._extras;
        /**
         * @type {?}
         * @private
         */
        NodeModel.prototype._ports;
        /**
         * @type {?}
         * @private
         */
        NodeModel.prototype._coords;
        /**
         * @type {?}
         * @private
         */
        NodeModel.prototype._dimensions;
        /**
         * @type {?}
         * @private
         */
        NodeModel.prototype.extras$;
        /**
         * @type {?}
         * @private
         */
        NodeModel.prototype.ports$;
        /**
         * @type {?}
         * @private
         */
        NodeModel.prototype.coords$;
        /**
         * @type {?}
         * @private
         */
        NodeModel.prototype.dimensions$;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/models/point.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var PointModel = /** @class */ (function (_super) {
        __extends(PointModel, _super);
        function PointModel(link, _a) {
            var x = _a.x, y = _a.y;
            var _this = _super.call(this) || this;
            _this._coords = new rxjs.BehaviorSubject({ x: x, y: y });
            _this.coords$ = _this._coords.asObservable();
            _this.setParent(link);
            return _this;
        }
        /**
         * @return {?}
         */
        PointModel.prototype.isConnectedToPort = /**
         * @return {?}
         */
        function () {
            return this.getParent().getPortForPoint(this) !== null;
        };
        /**
         * @return {?}
         */
        PointModel.prototype.getLink = /**
         * @return {?}
         */
        function () {
            return this.getParent();
        };
        /**
         * @param {?=} options
         * @return {?}
         */
        PointModel.prototype.destroy = /**
         * @param {?=} options
         * @return {?}
         */
        function (options) {
            if (this.getParent) {
                this.getParent().removePoint(this);
            }
            _super.prototype.destroy.call(this, options);
        };
        /**
         * @param {?} newCoords
         * @return {?}
         */
        PointModel.prototype.setCoords = /**
         * @param {?} newCoords
         * @return {?}
         */
        function (newCoords) {
            this._coords.next(__assign({}, this._coords.getValue(), newCoords));
        };
        /**
         * @return {?}
         */
        PointModel.prototype.selectCoords = /**
         * @return {?}
         */
        function () {
            return this.coords$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.distinctUntilChanged());
        };
        /**
         * @return {?}
         */
        PointModel.prototype.getCoords = /**
         * @return {?}
         */
        function () {
            return this._coords.getValue();
        };
        /**
         * @return {?}
         */
        PointModel.prototype.selectX = /**
         * @return {?}
         */
        function () {
            return this.selectCoords().pipe(operators.map((/**
             * @param {?} c
             * @return {?}
             */
            function (c) { return c.x; })), operators.distinctUntilChanged());
        };
        /**
         * @return {?}
         */
        PointModel.prototype.selectY = /**
         * @return {?}
         */
        function () {
            return this.selectCoords().pipe(operators.map((/**
             * @param {?} c
             * @return {?}
             */
            function (c) { return c.y; })), operators.distinctUntilChanged());
        };
        return PointModel;
    }(BaseModel));
    if (false) {
        /**
         * @type {?}
         * @private
         */
        PointModel.prototype._coords;
        /**
         * @type {?}
         * @private
         */
        PointModel.prototype.coords$;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/models/link.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var LinkModel = /** @class */ (function (_super) {
        __extends(LinkModel, _super);
        function LinkModel(linkType, id) {
            if (linkType === void 0) { linkType = 'default'; }
            var _this = _super.call(this, linkType, id) || this;
            _this.label = new rxjs.BehaviorSubject(null);
            _this.points = [new PointModel(_this, { x: 0, y: 0 }), new PointModel(_this, { x: 0, y: 0 })];
            _this.extras = {};
            _this.sourcePort = null;
            _this.targetPort = null;
            return _this;
        }
        /**
         * @param {?} name
         * @return {?}
         */
        LinkModel.prototype.setName = /**
         * @param {?} name
         * @return {?}
         */
        function (name) {
            this.name = name;
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.getName = /**
         * @return {?}
         */
        function () {
            return this.name;
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.getExtras = /**
         * @return {?}
         */
        function () {
            return this.extras;
        };
        /**
         * @param {?} extras
         * @return {?}
         */
        LinkModel.prototype.setExtras = /**
         * @param {?} extras
         * @return {?}
         */
        function (extras) {
            this.extras = extras;
        };
        /**
         * @param {?=} options
         * @return {?}
         */
        LinkModel.prototype.destroy = /**
         * @param {?=} options
         * @return {?}
         */
        function (options) {
            if (this.sourcePort) {
                this.sourcePort.removeLink(this);
            }
            if (this.targetPort) {
                this.targetPort.removeLink(this);
            }
            _super.prototype.destroy.call(this, options);
        };
        /**
         * @param {?=} lookupTable
         * @param {?=} clone
         * @return {?}
         */
        LinkModel.prototype.doClone = /**
         * @param {?=} lookupTable
         * @param {?=} clone
         * @return {?}
         */
        function (lookupTable, clone) {
            if (lookupTable === void 0) { lookupTable = {}; }
            clone.setPoints(this.getPoints().map((/**
             * @param {?} point
             * @return {?}
             */
            function (point) {
                return point.clone(lookupTable);
            })));
            if (this.sourcePort) {
                clone.setSourcePort(this.sourcePort.clone(lookupTable));
            }
            if (this.targetPort) {
                clone.setTargetPort(this.targetPort.clone(lookupTable));
            }
        };
        /**
         * @param {?} point
         * @return {?}
         */
        LinkModel.prototype.isLastPoint = /**
         * @param {?} point
         * @return {?}
         */
        function (point) {
            /** @type {?} */
            var index = this.getPointIndex(point);
            return index === this.points.length - 1;
        };
        /**
         * @param {?} point
         * @return {?}
         */
        LinkModel.prototype.getPointIndex = /**
         * @param {?} point
         * @return {?}
         */
        function (point) {
            return this.points.indexOf(point);
        };
        /**
         * @param {?} id
         * @return {?}
         */
        LinkModel.prototype.getPointModel = /**
         * @param {?} id
         * @return {?}
         */
        function (id) {
            var e_1, _a;
            try {
                for (var _b = __values(this.points), _c = _b.next(); !_c.done; _c = _b.next()) {
                    var point = _c.value;
                    if (point.id === id) {
                        return point;
                    }
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
                }
                finally { if (e_1) throw e_1.error; }
            }
            return null;
        };
        /**
         * @param {?} point
         * @return {?}
         */
        LinkModel.prototype.getPortForPoint = /**
         * @param {?} point
         * @return {?}
         */
        function (point) {
            if (this.sourcePort !== null && this.getFirstPoint().id === point.id) {
                return this.sourcePort;
            }
            if (this.targetPort !== null && this.getLastPoint().id === point.id) {
                return this.targetPort;
            }
            return null;
        };
        /**
         * @param {?} port
         * @return {?}
         */
        LinkModel.prototype.getPointForPort = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            if (this.sourcePort !== null && this.sourcePort.id === port.id) {
                return this.getFirstPoint();
            }
            if (this.targetPort !== null && this.targetPort.id === port.id) {
                return this.getLastPoint();
            }
            return null;
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.getFirstPoint = /**
         * @return {?}
         */
        function () {
            return this.points[0];
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.getLastPoint = /**
         * @return {?}
         */
        function () {
            return this.points[this.points.length - 1];
        };
        /**
         * @param {?} port
         * @return {?}
         */
        LinkModel.prototype.setSourcePort = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            if (port !== null) {
                port.addLink(this);
            }
            if (this.sourcePort !== null) {
                this.sourcePort.removeLink(this);
            }
            this.sourcePort = port;
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.getSourcePort = /**
         * @return {?}
         */
        function () {
            return this.sourcePort;
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.getTargetPort = /**
         * @return {?}
         */
        function () {
            return this.targetPort;
        };
        /**
         * @param {?} port
         * @return {?}
         */
        LinkModel.prototype.setTargetPort = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            if (port !== null) {
                port.addLink(this);
            }
            if (this.targetPort !== null) {
                this.targetPort.removeLink(this);
            }
            this.targetPort = port;
        };
        /**
         * @param {?} __0
         * @return {?}
         */
        LinkModel.prototype.point = /**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var x = _a.x, y = _a.y;
            return this.addPoint(this.generatePoint({ x: x, y: y }));
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.getPoints = /**
         * @return {?}
         */
        function () {
            return this.points;
        };
        /**
         * @param {?} points
         * @return {?}
         */
        LinkModel.prototype.setPoints = /**
         * @param {?} points
         * @return {?}
         */
        function (points) {
            var _this = this;
            points.forEach((/**
             * @param {?} point
             * @return {?}
             */
            function (point) {
                point.setParent(_this);
            }));
            this.points = points;
        };
        /**
         * @param {?} label
         * @return {?}
         */
        LinkModel.prototype.setLabel = /**
         * @param {?} label
         * @return {?}
         */
        function (label) {
            label.setParent(this);
            this.label.next(label);
            label.setPainted();
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.selectLabel = /**
         * @return {?}
         */
        function () {
            return this.label.asObservable();
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.getLabel = /**
         * @return {?}
         */
        function () {
            return this.label.getValue();
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.resetLabel = /**
         * @return {?}
         */
        function () {
            /** @type {?} */
            var currentLabel = this.label.getValue();
            if (currentLabel) {
                currentLabel.setParent(null);
                currentLabel.setPainted(false);
            }
            this.label.next(null);
        };
        /**
         * @param {?} pointModel
         * @return {?}
         */
        LinkModel.prototype.removePoint = /**
         * @param {?} pointModel
         * @return {?}
         */
        function (pointModel) {
            this.points.splice(this.getPointIndex(pointModel), 1);
        };
        /**
         * @param {?} pointModel
         * @return {?}
         */
        LinkModel.prototype.removePointsBefore = /**
         * @param {?} pointModel
         * @return {?}
         */
        function (pointModel) {
            this.points.splice(0, this.getPointIndex(pointModel));
        };
        /**
         * @param {?} pointModel
         * @return {?}
         */
        LinkModel.prototype.removePointsAfter = /**
         * @param {?} pointModel
         * @return {?}
         */
        function (pointModel) {
            this.points.splice(this.getPointIndex(pointModel) + 1);
        };
        /**
         * @return {?}
         */
        LinkModel.prototype.removeMiddlePoints = /**
         * @return {?}
         */
        function () {
            if (this.points.length > 2) {
                this.points.splice(0, this.points.length - 2);
            }
        };
        /**
         * @template P
         * @param {?} pointModel
         * @param {?=} index
         * @return {?}
         */
        LinkModel.prototype.addPoint = /**
         * @template P
         * @param {?} pointModel
         * @param {?=} index
         * @return {?}
         */
        function (pointModel, index) {
            if (index === void 0) { index = 1; }
            pointModel.setParent(this);
            this.points.splice(index, 0, pointModel);
            return pointModel;
        };
        /**
         * @param {?} __0
         * @return {?}
         */
        LinkModel.prototype.generatePoint = /**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var _b = _a.x, x = _b === void 0 ? 0 : _b, _c = _a.y, y = _c === void 0 ? 0 : _c;
            return new PointModel(this, { x: x, y: y });
        };
        return LinkModel;
    }(BaseModel));
    if (false) {
        /** @type {?} */
        LinkModel.prototype.diagramEngine;
        /**
         * @type {?}
         * @private
         */
        LinkModel.prototype.name;
        /**
         * @type {?}
         * @private
         */
        LinkModel.prototype.sourcePort;
        /**
         * @type {?}
         * @private
         */
        LinkModel.prototype.targetPort;
        /**
         * @type {?}
         * @private
         */
        LinkModel.prototype.points;
        /**
         * @type {?}
         * @private
         */
        LinkModel.prototype.extras;
        /**
         * @type {?}
         * @private
         */
        LinkModel.prototype.label;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/models/port.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var PortModel = /** @class */ (function (_super) {
        __extends(PortModel, _super);
        function PortModel(name, type, id, maximumLinks, linkType) {
            var _this = _super.call(this, type, id) || this;
            _this.name = name;
            _this.links$ = new rxjs.BehaviorSubject({});
            _this.maximumLinks = maximumLinks;
            _this.x$ = new rxjs.BehaviorSubject(0);
            _this.y$ = new rxjs.BehaviorSubject(0);
            _this.height$ = new rxjs.BehaviorSubject(0);
            _this.width$ = new rxjs.BehaviorSubject(0);
            _this.linkType = linkType;
            return _this;
        }
        /**
         * @return {?}
         */
        PortModel.prototype.getNode = /**
         * @return {?}
         */
        function () {
            return this.getParent();
        };
        /**
         * @return {?}
         */
        PortModel.prototype.getName = /**
         * @return {?}
         */
        function () {
            return this.name;
        };
        /**
         * @return {?}
         */
        PortModel.prototype.selectX = /**
         * @return {?}
         */
        function () {
            return this.x$.asObservable();
        };
        /**
         * @return {?}
         */
        PortModel.prototype.selectY = /**
         * @return {?}
         */
        function () {
            return this.y$.asObservable();
        };
        /**
         * @return {?}
         */
        PortModel.prototype.getY = /**
         * @return {?}
         */
        function () {
            return this.y$.getValue();
        };
        /**
         * @return {?}
         */
        PortModel.prototype.getX = /**
         * @return {?}
         */
        function () {
            return this.x$.getValue();
        };
        /**
         * @return {?}
         */
        PortModel.prototype.getHeight = /**
         * @return {?}
         */
        function () {
            return this.height$.getValue();
        };
        /**
         * @return {?}
         */
        PortModel.prototype.getWidth = /**
         * @return {?}
         */
        function () {
            return this.width$.getValue();
        };
        /**
         * @return {?}
         */
        PortModel.prototype.getMaximumLinks = /**
         * @return {?}
         */
        function () {
            return this.maximumLinks;
        };
        /**
         * @param {?} maximumLinks
         * @return {?}
         */
        PortModel.prototype.setMaximumLinks = /**
         * @param {?} maximumLinks
         * @return {?}
         */
        function (maximumLinks) {
            this.maximumLinks = maximumLinks;
        };
        /**
         * @return {?}
         */
        PortModel.prototype.getLinkType = /**
         * @return {?}
         */
        function () {
            return this.linkType;
        };
        /**
         * @param {?} type
         * @return {?}
         */
        PortModel.prototype.setLinkType = /**
         * @param {?} type
         * @return {?}
         */
        function (type) {
            this.linkType = type;
        };
        /**
         * @param {?} link
         * @return {?}
         */
        PortModel.prototype.removeLink = /**
         * @param {?} link
         * @return {?}
         */
        function (link) {
            /** @type {?} */
            var links = this.links$.getValue();
            delete links[link.id];
            this.links$.next(__assign({}, links));
        };
        /**
         * @param {?} link
         * @return {?}
         */
        PortModel.prototype.addLink = /**
         * @param {?} link
         * @return {?}
         */
        function (link) {
            var _a;
            this.links$.next(__assign({}, this.links$.value, (_a = {}, _a[link.id] = link, _a)));
        };
        /**
         * @return {?}
         */
        PortModel.prototype.getLinks = /**
         * @return {?}
         */
        function () {
            return this.links$.getValue();
        };
        /**
         * @return {?}
         */
        PortModel.prototype.selectLinks = /**
         * @return {?}
         */
        function () {
            return this.links$.asObservable();
        };
        /**
         * @param {?} __0
         * @return {?}
         */
        PortModel.prototype.updateCoords = /**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
            this.x$.next(x);
            this.y$.next(y);
            this.width$.next(width);
            this.height$.next(height);
        };
        /**
         * @param {?} port
         * @return {?}
         */
        PortModel.prototype.canLinkToPort = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            return true;
        };
        /**
         * @return {?}
         */
        PortModel.prototype.isLocked = /**
         * @return {?}
         */
        function () {
            return _super.prototype.getLocked.call(this);
        };
        /**
         * @return {?}
         */
        PortModel.prototype.createLinkModel = /**
         * @return {?}
         */
        function () {
            /** @type {?} */
            var numberOfLinks = Object.keys(this.links$.getValue()).length;
            if (this.maximumLinks === 1 && numberOfLinks >= 1) {
                /** @type {?} */
                var linkToRemove = Object.values(this.links$.getValue())[0];
                linkToRemove.destroy();
                return null;
            }
            else if (numberOfLinks >= this.maximumLinks) {
                // for the moment we will remove the first link by default
                /** @type {?} */
                var linkToRemove = Object.values(this.links$.getValue())[0];
                linkToRemove.destroy();
                return null;
            }
            return null;
        };
        return PortModel;
    }(BaseModel));
    if (false) {
        /**
         * @type {?}
         * @private
         */
        PortModel.prototype.name;
        /**
         * @type {?}
         * @private
         */
        PortModel.prototype.links$;
        /**
         * @type {?}
         * @private
         */
        PortModel.prototype.maximumLinks;
        /**
         * @type {?}
         * @private
         */
        PortModel.prototype.linkType;
        /**
         * @type {?}
         * @private
         */
        PortModel.prototype.x$;
        /**
         * @type {?}
         * @private
         */
        PortModel.prototype.y$;
        /**
         * @type {?}
         * @private
         */
        PortModel.prototype.width$;
        /**
         * @type {?}
         * @private
         */
        PortModel.prototype.height$;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/models/diagram.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DiagramModel = /** @class */ (function (_super) {
        __extends(DiagramModel, _super);
        function DiagramModel(diagramEngine, id) {
            var _this = _super.call(this, id) || this;
            _this.diagramEngine = diagramEngine;
            _this.nodes$ = new rxjs.BehaviorSubject({});
            _this.links$ = new rxjs.BehaviorSubject({});
            _this.zoom$ = new rxjs.BehaviorSubject(100);
            _this.offsetX$ = new rxjs.BehaviorSubject(0);
            _this.offsetY$ = new rxjs.BehaviorSubject(0);
            _this.gridSize$ = new rxjs.BehaviorSubject(0);
            return _this;
        }
        // TODO: support the following events for links and nodes
        // removed, updated<positionChanged/dataChanged>, added
        // TODO: support the following events for links and nodes
        // removed, updated<positionChanged/dataChanged>, added
        /**
         * @return {?}
         */
        DiagramModel.prototype.getNodes = 
        // TODO: support the following events for links and nodes
        // removed, updated<positionChanged/dataChanged>, added
        /**
         * @return {?}
         */
        function () {
            return this.nodes$.getValue();
        };
        /**
         * @param {?} id
         * @return {?}
         */
        DiagramModel.prototype.getNode = /**
         * @param {?} id
         * @return {?}
         */
        function (id) {
            return this.nodes$.getValue()[id];
        };
        /**
         * @param {?} id
         * @return {?}
         */
        DiagramModel.prototype.getLink = /**
         * @param {?} id
         * @return {?}
         */
        function (id) {
            return this.links$.getValue()[id];
        };
        /**
         * @return {?}
         */
        DiagramModel.prototype.getLinks = /**
         * @return {?}
         */
        function () {
            return this.links$.getValue();
        };
        /**
         * Add a node to the diagram
         * @returns Inserted Node
         */
        /**
         * Add a node to the diagram
         * @param {?} node
         * @return {?} Inserted Node
         */
        DiagramModel.prototype.addNode = /**
         * Add a node to the diagram
         * @param {?} node
         * @return {?} Inserted Node
         */
        function (node) {
            var _a;
            this.nodes$.next(__assign({}, this.nodes$.value, (_a = {}, _a[node.id] = node, _a)));
            return node;
        };
        /**
         * Delete a node from the diagram
         */
        /**
         * Delete a node from the diagram
         * @param {?} nodeOrId
         * @return {?}
         */
        DiagramModel.prototype.deleteNode = /**
         * Delete a node from the diagram
         * @param {?} nodeOrId
         * @return {?}
         */
        function (nodeOrId) {
            /** @type {?} */
            var nodeID = typeof nodeOrId === 'string' ? nodeOrId : nodeOrId.id;
            // TODO: delete all related links
            /** @type {?} */
            var updNodes = __assign({}, this.nodes$.value);
            delete updNodes[nodeID];
            this.nodes$.next(updNodes);
        };
        /**
         * Get nodes behaviour subject, use `.getValue()` for snapshot
         */
        /**
         * Get nodes behaviour subject, use `.getValue()` for snapshot
         * @return {?}
         */
        DiagramModel.prototype.selectNodes = /**
         * Get nodes behaviour subject, use `.getValue()` for snapshot
         * @return {?}
         */
        function () {
            return this.nodes$.asObservable();
        };
        /**
         * Add link
         * @returns Newly created link
         */
        /**
         * Add link
         * @param {?} link
         * @return {?} Newly created link
         */
        DiagramModel.prototype.addLink = /**
         * Add link
         * @param {?} link
         * @return {?} Newly created link
         */
        function (link) {
            var _a;
            this.links$.next(__assign({}, this.links$.value, (_a = {}, _a[link.id] = link, _a)));
            return link;
        };
        /**
         * Delete link
         */
        /**
         * Delete link
         * @param {?} linkOrId
         * @return {?}
         */
        DiagramModel.prototype.deleteLink = /**
         * Delete link
         * @param {?} linkOrId
         * @return {?}
         */
        function (linkOrId) {
            /** @type {?} */
            var linkID = typeof linkOrId === 'string' ? linkOrId : linkOrId.id;
            /** @type {?} */
            var updLinks = __assign({}, this.links$.value);
            delete updLinks[linkID];
            this.links$.next(updLinks);
        };
        /**
         * Get links behaviour subject, use `.getValue()` for snapshot
         */
        /**
         * Get links behaviour subject, use `.getValue()` for snapshot
         * @return {?}
         */
        DiagramModel.prototype.selectLinks = /**
         * Get links behaviour subject, use `.getValue()` for snapshot
         * @return {?}
         */
        function () {
            return this.links$.asObservable();
        };
        /**
         * Serialize the diagram model
         * @returns diagram model as a string
         */
        // serialize(): string {
        // 	return JSON.stringify(this.model);
        // }
        /**
         * Load into the diagram model a serialized diagram
         */
        // deserialize(serializedModel: string) {
        // 	this.model = JSON.parse(serializedModel);
        // }
        /**
             * Serialize the diagram model
             * @returns diagram model as a string
             */
        // serialize(): string {
        // 	return JSON.stringify(this.model);
        // }
        /**
         * Load into the diagram model a serialized diagram
         * @param {?} x
         * @param {?} y
         * @return {?}
         */
        // deserialize(serializedModel: string) {
        // 	this.model = JSON.parse(serializedModel);
        // }
        DiagramModel.prototype.setOffset = /**
             * Serialize the diagram model
             * @returns diagram model as a string
             */
        // serialize(): string {
        // 	return JSON.stringify(this.model);
        // }
        /**
         * Load into the diagram model a serialized diagram
         * @param {?} x
         * @param {?} y
         * @return {?}
         */
        // deserialize(serializedModel: string) {
        // 	this.model = JSON.parse(serializedModel);
        // }
        function (x, y) {
            this.offsetX$.next(x);
            this.offsetY$.next(y);
        };
        /**
         * @param {?} x
         * @return {?}
         */
        DiagramModel.prototype.setOffsetX = /**
         * @param {?} x
         * @return {?}
         */
        function (x) {
            this.offsetX$.next(x);
        };
        /**
         * @return {?}
         */
        DiagramModel.prototype.getOffsetX = /**
         * @return {?}
         */
        function () {
            return this.offsetX$.getValue();
        };
        /**
         * @return {?}
         */
        DiagramModel.prototype.selectOffsetX = /**
         * @return {?}
         */
        function () {
            return this.offsetX$.asObservable();
        };
        /**
         * @param {?} y
         * @return {?}
         */
        DiagramModel.prototype.setOffsetY = /**
         * @param {?} y
         * @return {?}
         */
        function (y) {
            this.offsetY$.next(y);
        };
        /**
         * @return {?}
         */
        DiagramModel.prototype.getOffsetY = /**
         * @return {?}
         */
        function () {
            return this.offsetY$.getValue();
        };
        /**
         * @return {?}
         */
        DiagramModel.prototype.selectOffsetY = /**
         * @return {?}
         */
        function () {
            return this.offsetY$.asObservable();
        };
        /**
         * @param {?} z
         * @return {?}
         */
        DiagramModel.prototype.setZoomLevel = /**
         * @param {?} z
         * @return {?}
         */
        function (z) {
            this.zoom$.next(z);
        };
        /**
         * @return {?}
         */
        DiagramModel.prototype.getZoomLevel = /**
         * @return {?}
         */
        function () {
            return this.zoom$.getValue();
        };
        /**
         * @return {?}
         */
        DiagramModel.prototype.selectZoomLevel = /**
         * @return {?}
         */
        function () {
            return this.zoom$.asObservable();
        };
        /**
         * @return {?}
         */
        DiagramModel.prototype.getDiagramEngine = /**
         * @return {?}
         */
        function () {
            return this.diagramEngine;
        };
        /**
         * @param {?=} ignore
         * @return {?}
         */
        DiagramModel.prototype.clearSelection = /**
         * @param {?=} ignore
         * @return {?}
         */
        function (ignore) {
            if (ignore === void 0) { ignore = null; }
            this.getSelectedItems().forEach((/**
             * @param {?} element
             * @return {?}
             */
            function (element) {
                if (ignore && ignore.id === element.id) {
                    return;
                }
                element.setSelected(false);
            }));
        };
        /**
         * @param {?} __0
         * @return {?}
         */
        DiagramModel.prototype.getGridPosition = /**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var x = _a.x, y = _a.y;
            /** @type {?} */
            var gridSize = this.gridSize$.getValue();
            if (gridSize === 0) {
                return { x: x, y: y };
            }
            return {
                x: gridSize * Math.floor((x + gridSize / 2) / gridSize),
                y: gridSize * Math.floor((y + gridSize / 2) / gridSize)
            };
        };
        /**
         * @param {...?} filters
         * @return {?}
         */
        DiagramModel.prototype.getSelectedItems = /**
         * @param {...?} filters
         * @return {?}
         */
        function () {
            var filters = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                filters[_i] = arguments[_i];
            }
            if (!Array.isArray(filters)) {
                filters = [filters];
            }
            /** @type {?} */
            var items = [];
            // run through nodes
            items = items.concat(lodash.flatMap(this.nodes$.getValue(), (/**
             * @param {?} node
             * @return {?}
             */
            function (node) {
                return node.getSelectedEntities();
            })));
            // find all the links
            items = items.concat(lodash.flatMap(this.links$.getValue(), (/**
             * @param {?} link
             * @return {?}
             */
            function (link) {
                return link.getSelectedEntities();
            })));
            // find all points
            items = items.concat(lodash.flatMap(this.links$.getValue(), (/**
             * @param {?} link
             * @return {?}
             */
            function (link) {
                return lodash.flatMap(link.getPoints(), (/**
                 * @param {?} point
                 * @return {?}
                 */
                function (point) {
                    return point.getSelectedEntities();
                }));
            })));
            items = lodash.uniq(items);
            if (filters.length > 0) {
                items = lodash.uniq(items).filter((/**
                 * @param {?} item
                 * @return {?}
                 */
                function (item) {
                    if (filters.includes('node') && item instanceof NodeModel) {
                        return true;
                    }
                    if (filters.includes('link') && item instanceof LinkModel) {
                        return true;
                    }
                    if (filters.includes('port') && item instanceof PortModel) {
                        return true;
                    }
                    if (filters.includes('point') && item instanceof PointModel) {
                        return true;
                    }
                    return false;
                }));
            }
            return items;
        };
        /**
         * @param {...?} models
         * @return {?}
         */
        DiagramModel.prototype.addAll = /**
         * @param {...?} models
         * @return {?}
         */
        function () {
            var _this = this;
            var models = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                models[_i] = arguments[_i];
            }
            models.forEach((/**
             * @param {?} model
             * @return {?}
             */
            function (model) {
                if (model instanceof LinkModel) {
                    _this.addLink(model);
                }
                else if (model instanceof NodeModel) {
                    _this.addNode(model);
                }
            }));
            return models;
        };
        return DiagramModel;
    }(BaseEntity));
    if (false) {
        /** @type {?} */
        DiagramModel.prototype.links$;
        /** @type {?} */
        DiagramModel.prototype.nodes$;
        /** @type {?} */
        DiagramModel.prototype.zoom$;
        /** @type {?} */
        DiagramModel.prototype.offsetX$;
        /** @type {?} */
        DiagramModel.prototype.offsetY$;
        /** @type {?} */
        DiagramModel.prototype.gridSize$;
        /**
         * @type {?}
         * @private
         */
        DiagramModel.prototype.diagramEngine;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/actions/base.action.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var BaseAction = /** @class */ (function () {
        function BaseAction(mouseX, mouseY) {
            this.mouseX = mouseX;
            this.mouseY = mouseY;
            this.ms = new Date().getTime();
        }
        return BaseAction;
    }());
    if (false) {
        /** @type {?} */
        BaseAction.prototype.mouseX;
        /** @type {?} */
        BaseAction.prototype.mouseY;
        /** @type {?} */
        BaseAction.prototype.ms;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/actions/move-canvas.action.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var MoveCanvasAction = /** @class */ (function (_super) {
        __extends(MoveCanvasAction, _super);
        function MoveCanvasAction(mouseX, mouseY, diagramModel) {
            var _this = _super.call(this, mouseX, mouseY) || this;
            _this.initialOffsetX = diagramModel.getOffsetX();
            _this.initialOffsetY = diagramModel.getOffsetY();
            return _this;
        }
        return MoveCanvasAction;
    }(BaseAction));
    if (false) {
        /** @type {?} */
        MoveCanvasAction.prototype.initialOffsetX;
        /** @type {?} */
        MoveCanvasAction.prototype.initialOffsetY;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/actions/selecting.action.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var SelectingAction = /** @class */ (function (_super) {
        __extends(SelectingAction, _super);
        function SelectingAction(mouseX, mouseY) {
            var _this = _super.call(this, mouseX, mouseY) || this;
            _this.mouseX2 = mouseX;
            _this.mouseY2 = mouseY;
            return _this;
        }
        /**
         * @return {?}
         */
        SelectingAction.prototype.getBoxDimensions = /**
         * @return {?}
         */
        function () {
            this.dimensions = {
                left: this.mouseX2 > this.mouseX ? this.mouseX : this.mouseX2,
                top: this.mouseY2 > this.mouseY ? this.mouseY : this.mouseY2,
                width: Math.abs(this.mouseX2 - this.mouseX),
                height: Math.abs(this.mouseY2 - this.mouseY),
                right: this.mouseX2 < this.mouseX ? this.mouseX : this.mouseX2,
                bottom: this.mouseY2 < this.mouseY ? this.mouseY : this.mouseY2
            };
            return this.dimensions;
        };
        /**
         * @param {?} __0
         * @param {?} diagramModel
         * @return {?}
         */
        SelectingAction.prototype.containsElement = /**
         * @param {?} __0
         * @param {?} diagramModel
         * @return {?}
         */
        function (_a, diagramModel) {
            var x = _a.x, y = _a.y;
            /** @type {?} */
            var z = diagramModel.getZoomLevel() / 100.0;
            /** @type {?} */
            var dimensions = this.getBoxDimensions();
            return (x * z + diagramModel.getOffsetX() > dimensions.left &&
                x * z + diagramModel.getOffsetX() < dimensions.right &&
                y * z + diagramModel.getOffsetY() > dimensions.top &&
                y * z + diagramModel.getOffsetY() < dimensions.bottom);
        };
        return SelectingAction;
    }(BaseAction));
    if (false) {
        /** @type {?} */
        SelectingAction.prototype.mouseX2;
        /** @type {?} */
        SelectingAction.prototype.mouseY2;
        /** @type {?} */
        SelectingAction.prototype.dimensions;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/actions/move-items.action.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var MoveItemsAction = /** @class */ (function (_super) {
        __extends(MoveItemsAction, _super);
        function MoveItemsAction(mouseX, mouseY, diagramEngine) {
            var _this = _super.call(this, mouseX, mouseY) || this;
            _this.moved = false;
            /** @type {?} */
            var selectedItems = diagramEngine.getDiagramModel().getSelectedItems();
            // dont allow items which are locked to move and links which generate their position based on points.
            selectedItems = selectedItems.filter((/**
             * @param {?} item
             * @return {?}
             */
            function (item) {
                return !diagramEngine.isModelLocked(item) && !(item instanceof LinkModel);
            }));
            _this.selectionModels = selectedItems.map((/**
             * @param {?} item
             * @return {?}
             */
            function (item) {
                var _a = item.getCoords(), initialX = _a.x, initialY = _a.y;
                return {
                    model: item,
                    initialX: initialX,
                    initialY: initialY
                };
            }));
            return _this;
        }
        return MoveItemsAction;
    }(BaseAction));
    if (false) {
        /** @type {?} */
        MoveItemsAction.prototype.selectionModels;
        /** @type {?} */
        MoveItemsAction.prototype.moved;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/actions/links-created.action.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    // TODO: refactor into entity-created.action, and fire every time a new entity is created!
    var   
    // TODO: refactor into entity-created.action, and fire every time a new entity is created!
    LinkCreatedAction = /** @class */ (function (_super) {
        __extends(LinkCreatedAction, _super);
        function LinkCreatedAction(mouseX, mouseY, link) {
            var _this = _super.call(this, mouseX, mouseY) || this;
            _this.sourcePort = link.getSourcePort();
            _this.targetPort = link.getTargetPort();
            _this.link = link;
            return _this;
        }
        /**
         * @return {?}
         */
        LinkCreatedAction.prototype.getOutPortNode = /**
         * @return {?}
         */
        function () {
            return this.sourcePort.getParent();
        };
        /**
         * @return {?}
         */
        LinkCreatedAction.prototype.getInPortNode = /**
         * @return {?}
         */
        function () {
            return this.targetPort.getParent();
        };
        return LinkCreatedAction;
    }(BaseAction));
    if (false) {
        /** @type {?} */
        LinkCreatedAction.prototype.sourcePort;
        /** @type {?} */
        LinkCreatedAction.prototype.targetPort;
        /** @type {?} */
        LinkCreatedAction.prototype.link;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/actions/index.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/containers/diagram/diagram.component.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var NgxDiagramComponent = /** @class */ (function () {
        function NgxDiagramComponent(renderer, cdRef) {
            var _this = this;
            this.renderer = renderer;
            this.cdRef = cdRef;
            this.allowCanvasZoon = true;
            this.allowCanvasTranslation = true;
            this.inverseZoom = true;
            this.allowLooseLinks = true;
            this.actionStartedFiring = new core.EventEmitter();
            this.actionStillFiring = new core.EventEmitter();
            this.actionStoppedFiring = new core.EventEmitter();
            this.action$ = new rxjs.BehaviorSubject(null);
            this.destroyed$ = new rxjs.ReplaySubject(1);
            this.mouseUpListener = (/**
             * @return {?}
             */
            function () { });
            this.mouseMoveListener = (/**
             * @return {?}
             */
            function () { });
            this.onMouseUp = (/**
             * @param {?} event
             * @return {?}
             */
            function (event) {
                /** @type {?} */
                var diagramEngine = _this.diagramModel.getDiagramEngine();
                /** @type {?} */
                var action = _this.action$.getValue();
                // are we going to connect a link to something?
                if (action instanceof MoveItemsAction) {
                    /** @type {?} */
                    var element_1 = _this.getMouseElement(event);
                    action.selectionModels.forEach((/**
                     * @param {?} model
                     * @return {?}
                     */
                    function (model) {
                        // only care about points connecting to things
                        if (!(model.model instanceof PointModel)) {
                            return;
                        }
                        if (element_1 && element_1.model instanceof PortModel && !diagramEngine.isModelLocked(element_1.model)) {
                            /** @type {?} */
                            var link = model.model.getLink();
                            if (link.getTargetPort() !== null) {
                                // if this was a valid link already and we are adding a node in the middle, create 2 links from the original
                                if (link.getTargetPort() !== element_1.model && link.getSourcePort() !== element_1.model) {
                                    /** @type {?} */
                                    var targetPort = link.getTargetPort();
                                    /** @type {?} */
                                    var newLink = link.clone({});
                                    newLink.setSourcePort(element_1.model);
                                    newLink.setTargetPort(targetPort);
                                    link.setTargetPort(element_1.model);
                                    targetPort.removeLink(link);
                                    newLink.removePointsBefore(newLink.getPoints()[link.getPointIndex(model.model)]);
                                    link.removePointsAfter(model.model);
                                    diagramEngine.getDiagramModel().addLink(newLink);
                                    // if we are connecting to the same target or source, destroy tweener points
                                }
                                else if (link.getTargetPort() === element_1.model) {
                                    link.removePointsAfter(model.model);
                                }
                                else if (link.getSourcePort() === element_1.model) {
                                    link.removePointsBefore(model.model);
                                }
                            }
                            else {
                                link.setTargetPort(element_1.model);
                                /** @type {?} */
                                var targetPort = link.getTargetPort();
                                /** @type {?} */
                                var srcPort = link.getSourcePort();
                                if (targetPort.id !== srcPort.id) {
                                    // link is valid, fire the event
                                    _this.startFiringAction(new LinkCreatedAction(event.clientX, event.clientY, link));
                                }
                            }
                        }
                    }));
                    // check for / destroy any loose links in any models which have been moved
                    if (!_this.allowLooseLinks) {
                        action.selectionModels.forEach((/**
                         * @param {?} model
                         * @return {?}
                         */
                        function (model) {
                            // only care about points connecting to things
                            if (!(model.model instanceof PointModel)) {
                                return;
                            }
                            /** @type {?} */
                            var selectedPoint = model.model;
                            /** @type {?} */
                            var link = selectedPoint.getLink();
                            if (link.getSourcePort() === null || link.getTargetPort() === null) {
                                link.destroy();
                            }
                        }));
                    }
                    // destroy any invalid links
                    action.selectionModels.forEach((/**
                     * @param {?} model
                     * @return {?}
                     */
                    function (model) {
                        // only care about points connecting to things
                        if (!(model.model instanceof PointModel)) {
                            return;
                        }
                        /** @type {?} */
                        var link = model.model.getLink();
                        /** @type {?} */
                        var sourcePort = link.getSourcePort();
                        /** @type {?} */
                        var targetPort = link.getTargetPort();
                        if (sourcePort !== null && targetPort !== null) {
                            if (!sourcePort.canLinkToPort(targetPort)) {
                                // link not allowed
                                link.destroy();
                            }
                            else if (lodash.some(Object.values(targetPort.getLinks()), (/**
                             * @param {?} l
                             * @return {?}
                             */
                            function (l) { return l !== link && (l.getSourcePort() === sourcePort || l.getTargetPort() === sourcePort); }))) {
                                // link is a duplicate
                                link.destroy();
                            }
                        }
                    }));
                    _this.stopFiringAction();
                }
                else {
                    _this.stopFiringAction();
                }
                _this.mouseUpListener();
                _this.mouseMoveListener();
                _this.action$.next(null);
            });
            this.onMouseMove = (/**
             * @param {?} event
             * @return {?}
             */
            function (event) {
                /** @type {?} */
                var action = _this.action$.getValue();
                if (action === null || action === undefined) {
                    return;
                }
                if (action instanceof SelectingAction) {
                    /** @type {?} */
                    var relative = _this.diagramModel.getDiagramEngine().getRelativePoint(event.clientX, event.clientY);
                    Object.values(_this.diagramModel.getNodes()).forEach((/**
                     * @param {?} node
                     * @return {?}
                     */
                    function (node) {
                        if (((/** @type {?} */ (action))).containsElement(node.getCoords(), _this.diagramModel)) {
                            node.setSelected();
                        }
                        else {
                            node.setSelected(false);
                        }
                    }));
                    Object.values(_this.diagramModel.getLinks()).forEach((/**
                     * @param {?} link
                     * @return {?}
                     */
                    function (link) {
                        /** @type {?} */
                        var allSelected = true;
                        link.getPoints().forEach((/**
                         * @param {?} point
                         * @return {?}
                         */
                        function (point) {
                            if (((/** @type {?} */ (action))).containsElement(point.getCoords(), _this.diagramModel)) {
                                point.setSelected();
                            }
                            else {
                                point.setSelected(false);
                                allSelected = false;
                            }
                        }));
                        if (allSelected) {
                            link.setSelected();
                        }
                    }));
                    action.mouseX2 = relative.x;
                    action.mouseY2 = relative.y;
                    _this.fireAction();
                    _this.action$.next(action);
                    return;
                }
                else if (action instanceof MoveItemsAction) {
                    /** @type {?} */
                    var coords_1 = {
                        x: event.clientX - action.mouseX,
                        y: event.clientY - action.mouseY
                    };
                    /** @type {?} */
                    var amountZoom_1 = _this.diagramModel.getZoomLevel() / 100;
                    action.selectionModels.forEach((/**
                     * @param {?} model
                     * @return {?}
                     */
                    function (model) {
                        // in this case we need to also work out the relative grid position
                        if (model.model instanceof NodeModel || (model.model instanceof PointModel && !model.model.isConnectedToPort())) {
                            /** @type {?} */
                            var newCoords = { x: model.initialX + coords_1.x / amountZoom_1, y: model.initialY + coords_1.y / amountZoom_1 };
                            model.model.setCoords(_this.diagramModel.getGridPosition(newCoords));
                            if (model.model instanceof NodeModel) {
                                // update port coordinates as well
                                Object.values(model.model.getPorts()).forEach((/**
                                 * @param {?} port
                                 * @return {?}
                                 */
                                function (port) {
                                    /** @type {?} */
                                    var portCoords = _this.diagramModel.getDiagramEngine().getPortCoords(port);
                                    port.updateCoords(portCoords);
                                }));
                            }
                        }
                        else if (model.model instanceof PointModel) {
                            // we want points that are connected to ports, to not necessarily snap to grid
                            // this stuff needs to be pixel perfect, dont touch it
                            /** @type {?} */
                            var newCoords = _this.diagramModel.getGridPosition({ x: coords_1.x / amountZoom_1, y: coords_1.y / amountZoom_1 });
                            model.model.setCoords({ x: model.initialX + newCoords.x, y: model.initialY + newCoords.y });
                        }
                    }));
                    _this.fireAction();
                }
                else if (action instanceof MoveCanvasAction) {
                    if (_this.allowCanvasTranslation) {
                        _this.diagramModel.setOffset(action.initialOffsetX + (event.clientX - action.mouseX), action.initialOffsetY + (event.clientY - action.mouseY));
                        _this.fireAction();
                    }
                }
            });
        }
        // TODO: handle destruction of container, resseting all observables to avoid memory leaks!
        // TODO: handle destruction of container, resseting all observables to avoid memory leaks!
        /**
         * @return {?}
         */
        NgxDiagramComponent.prototype.ngOnInit = 
        // TODO: handle destruction of container, resseting all observables to avoid memory leaks!
        /**
         * @return {?}
         */
        function () {
            var _this = this;
            if (this.diagramModel) {
                this.diagramModel.getDiagramEngine().setCanvas(this.canvas.nativeElement);
                this.nodes$ = this.diagramModel.selectNodes();
                this.links$ = this.diagramModel.selectLinks();
                this.nodesRendered$ = new rxjs.BehaviorSubject(false);
                this.nodes$.pipe(operators.takeUntil(this.destroyed$)).subscribe((/**
                 * @param {?} nodes
                 * @return {?}
                 */
                function (nodes) {
                    _this.nodesRendered$.next(false);
                    Object.values(nodes).forEach((/**
                     * @param {?} node
                     * @return {?}
                     */
                    function (node) {
                        if (!node.getPainted()) {
                            _this.diagramModel.getDiagramEngine().generateWidgetForNode(node, _this.nodesLayer);
                            node.setPainted();
                            _this.cdRef.detectChanges();
                        }
                    }));
                    _this.nodesRendered$.next(true);
                }));
            }
        };
        /**
         * @return {?}
         */
        NgxDiagramComponent.prototype.ngOnDestroy = /**
         * @return {?}
         */
        function () {
            this.destroyed$.next(true);
            this.destroyed$.complete();
        };
        /**
         * @return {?}
         */
        NgxDiagramComponent.prototype.ngAfterViewInit = /**
         * @return {?}
         */
        function () {
            var _this = this;
            rxjs.combineLatest([this.nodesRendered$, this.links$])
                .pipe(operators.takeUntil(this.destroyed$), operators.filter((/**
             * @param {?} __0
             * @return {?}
             */
            function (_a) {
                var _b = __read(_a, 2), nodesRendered = _b[0], _ = _b[1];
                return !!nodesRendered;
            })))
                .subscribe((/**
             * @param {?} __0
             * @return {?}
             */
            function (_a) {
                var _b = __read(_a, 2), _ = _b[0], links = _b[1];
                Object.values(links).forEach((/**
                 * @param {?} link
                 * @return {?}
                 */
                function (link) {
                    if (!link.getPainted()) {
                        if (link.getSourcePort() !== null) {
                            /** @type {?} */
                            var portCenter = _this.diagramModel.getDiagramEngine().getPortCenter(link.getSourcePort());
                            link.getPoints()[0].setCoords(portCenter);
                            /** @type {?} */
                            var portCoords = _this.diagramModel.getDiagramEngine().getPortCoords(link.getSourcePort());
                            link.getSourcePort().updateCoords(portCoords);
                        }
                        if (link.getTargetPort() !== null) {
                            /** @type {?} */
                            var portCenter = _this.diagramModel.getDiagramEngine().getPortCenter(link.getTargetPort());
                            link.getPoints()[link.getPoints().length - 1].setCoords(portCenter);
                            /** @type {?} */
                            var portCoords = _this.diagramModel.getDiagramEngine().getPortCoords(link.getTargetPort());
                            link.getTargetPort().updateCoords(portCoords);
                        }
                        _this.diagramModel.getDiagramEngine().generateWidgetForLink(link, _this.linksLayer);
                        link.setPainted();
                        _this.cdRef.detectChanges();
                    }
                }));
            }));
        };
        /**
         * fire the action registered and notify subscribers
         */
        /**
         * fire the action registered and notify subscribers
         * @return {?}
         */
        NgxDiagramComponent.prototype.fireAction = /**
         * fire the action registered and notify subscribers
         * @return {?}
         */
        function () {
            if (this.action$.value) {
                this.actionStillFiring.emit(this.action$.value);
            }
        };
        /**
         * Unregister the action, post firing and notify subscribers
         */
        /**
         * Unregister the action, post firing and notify subscribers
         * @param {?=} shouldSkipEvent
         * @return {?}
         */
        NgxDiagramComponent.prototype.stopFiringAction = /**
         * Unregister the action, post firing and notify subscribers
         * @param {?=} shouldSkipEvent
         * @return {?}
         */
        function (shouldSkipEvent) {
            if (!shouldSkipEvent) {
                this.actionStoppedFiring.emit(this.action$.value);
            }
            this.action$.next(null);
        };
        /**
         * Register the new action, pre firing and notify subscribers
         */
        /**
         * Register the new action, pre firing and notify subscribers
         * @param {?} action
         * @return {?}
         */
        NgxDiagramComponent.prototype.startFiringAction = /**
         * Register the new action, pre firing and notify subscribers
         * @param {?} action
         * @return {?}
         */
        function (action) {
            this.action$.next(action);
            this.actionStartedFiring.emit(action);
        };
        /**
         * @return {?}
         */
        NgxDiagramComponent.prototype.selectAction = /**
         * @return {?}
         */
        function () {
            return this.action$;
        };
        /**
         * @return {?}
         */
        NgxDiagramComponent.prototype.shouldDrawSelectionBox = /**
         * @return {?}
         */
        function () {
            /** @type {?} */
            var action = this.action$.getValue();
            if (action instanceof SelectingAction) {
                action.getBoxDimensions();
                return true;
            }
            return false;
        };
        /**
         * @param {?} event
         * @return {?}
         */
        NgxDiagramComponent.prototype.getMouseElement = /**
         * @param {?} event
         * @return {?}
         */
        function (event) {
            /** @type {?} */
            var target = (/** @type {?} */ (event.target));
            // is it a port?
            /** @type {?} */
            var element = target.closest('[data-portid]');
            if (element) {
                // get the relevant node and return the port.
                /** @type {?} */
                var nodeEl = target.closest('[data-nodeid]');
                return {
                    model: this.diagramModel.getNode(nodeEl.getAttribute('data-nodeid')).getPort(element.getAttribute('data-portid')),
                    element: element
                };
            }
            // look for a point
            element = target.closest('[data-pointid]');
            if (element) {
                return {
                    model: this.diagramModel.getLink(element.getAttribute('data-linkid')).getPointModel(element.getAttribute('data-pointid')),
                    element: element
                };
            }
            // look for a link
            element = target.closest('[data-linkid]');
            if (element) {
                return {
                    model: this.diagramModel.getLink(element.getAttribute('data-linkid')),
                    element: element
                };
            }
            // a node maybe
            element = target.closest('[data-nodeid]');
            if (element) {
                return {
                    model: this.diagramModel.getNode(element.getAttribute('data-nodeid')),
                    element: element
                };
            }
            // just the canvas
            return null;
        };
        /**
         * @param {?} event
         * @return {?}
         */
        NgxDiagramComponent.prototype.onMouseDown = /**
         * @param {?} event
         * @return {?}
         */
        function (event) {
            if (event.button === 3) {
                return;
            }
            /** @type {?} */
            var selectedModel = this.getMouseElement(event);
            // canvas selected
            if (selectedModel === null) {
                // multiple selection
                if (event.shiftKey) {
                    // initiate multiple selection selector
                    /** @type {?} */
                    var relative = this.diagramModel.getDiagramEngine().getRelativePoint(event.clientX, event.clientY);
                    this.startFiringAction(new SelectingAction(relative.x, relative.y));
                }
                else {
                    // drag canvas action
                    this.diagramModel.clearSelection();
                    this.startFiringAction(new MoveCanvasAction(event.clientX, event.clientY, this.diagramModel));
                }
            }
            else if (selectedModel.model instanceof PortModel) {
                // its a port element, we want to drag a link
                if (!this.diagramModel.getDiagramEngine().isModelLocked(selectedModel.model)) {
                    /** @type {?} */
                    var relative = this.diagramModel.getDiagramEngine().getRelativeMousePoint(event);
                    /** @type {?} */
                    var sourcePort = selectedModel.model;
                    /** @type {?} */
                    var link = sourcePort.createLinkModel();
                    link.setSourcePort(sourcePort);
                    if (link) {
                        link.removeMiddlePoints();
                        if (link.getSourcePort() !== sourcePort) {
                            link.setSourcePort(sourcePort);
                        }
                        link.setTargetPort(null);
                        link.getFirstPoint().setCoords(relative);
                        link.getLastPoint().setCoords(relative);
                        this.diagramModel.clearSelection();
                        link.getLastPoint().setSelected();
                        this.diagramModel.addLink(link);
                        this.startFiringAction(new MoveItemsAction(event.clientX, event.clientY, this.diagramModel.getDiagramEngine()));
                    }
                }
                else {
                    this.diagramModel.clearSelection();
                }
            }
            else {
                // its some other element, probably want to move it
                if (!event.shiftKey && !selectedModel.model.getSelected()) {
                    this.diagramModel.clearSelection();
                }
                selectedModel.model.setSelected();
                this.startFiringAction(new MoveItemsAction(event.clientX, event.clientY, this.diagramModel.getDiagramEngine()));
            }
            // create mouseMove and mouseUp listeners
            this.mouseMoveListener = this.renderer.listen(document, 'mousemove', this.onMouseMove);
            this.mouseUpListener = this.renderer.listen(document, 'mouseup', this.onMouseUp);
        };
        /**
         * @param {?} event
         * @return {?}
         */
        NgxDiagramComponent.prototype.onMouseWheel = /**
         * @param {?} event
         * @return {?}
         */
        function (event) {
            if (this.allowCanvasZoon) {
                event.preventDefault();
                event.stopPropagation();
                /** @type {?} */
                var currentZoomLevel = this.diagramModel.getZoomLevel();
                /** @type {?} */
                var oldZoomFactor = currentZoomLevel / 100;
                /** @type {?} */
                var scrollDelta = this.inverseZoom ? -event.deltaY : event.deltaY;
                // check if it is pinch gesture
                if (event.ctrlKey && scrollDelta % 1 !== 0) {
                    /* Chrome and Firefox sends wheel event with deltaY that
                       have fractional part, also `ctrlKey` prop of the event is true
                       though ctrl isn't pressed
                    */
                    scrollDelta /= 3;
                }
                else {
                    scrollDelta /= 60;
                }
                if (currentZoomLevel + scrollDelta > 10) {
                    this.diagramModel.setZoomLevel(currentZoomLevel + scrollDelta);
                }
                /** @type {?} */
                var zoomFactor = this.diagramModel.getZoomLevel() / 100;
                /** @type {?} */
                var boundingRect = ((/** @type {?} */ (event.currentTarget))).getBoundingClientRect();
                /** @type {?} */
                var clientWidth = boundingRect.width;
                /** @type {?} */
                var clientHeight = boundingRect.height;
                // compute difference between rect before and after scroll
                /** @type {?} */
                var widthDiff = clientWidth * zoomFactor - clientWidth * oldZoomFactor;
                /** @type {?} */
                var heightDiff = clientHeight * zoomFactor - clientHeight * oldZoomFactor;
                // compute mouse coords relative to canvas
                /** @type {?} */
                var clientX = event.clientX - boundingRect.left;
                /** @type {?} */
                var clientY = event.clientY - boundingRect.top;
                // compute width and height increment factor
                /** @type {?} */
                var xFactor = (clientX - this.diagramModel.getOffsetX()) / oldZoomFactor / clientWidth;
                /** @type {?} */
                var yFactor = (clientY - this.diagramModel.getOffsetY()) / oldZoomFactor / clientHeight;
                this.diagramModel.setOffset(this.diagramModel.getOffsetX() - widthDiff * xFactor, this.diagramModel.getOffsetY() - heightDiff * yFactor);
            }
        };
        NgxDiagramComponent.decorators = [
            { type: core.Component, args: [{
                        selector: 'ngdx-diagram',
                        template: "<div class=\"ngdx-diagram\" #canvas (mousedown)=\"onMouseDown($event)\" (wheel)=\"onMouseWheel($event)\">\n\t<!-- Nodes Layer -->\n\t<div\n\t\tclass=\"ngdx-nodes-layer\"\n\t\t[ngStyle]=\"{\n\t\t\ttransform:\n\t\t\t\t'translate(' +\n\t\t\t\t(diagramModel.selectOffsetX() | async) +\n\t\t\t\t'px, ' +\n\t\t\t\t(diagramModel.selectOffsetY() | async) +\n\t\t\t\t'px) scale(' +\n\t\t\t\t(diagramModel.selectZoomLevel() | async) / 100.0 +\n\t\t\t\t')'\n\t\t}\"\n\t>\n\t\t<ng-template #nodesLayer></ng-template>\n\t</div>\n\n\t<!-- Links Layer -->\n\t<div\n\t\tclass=\"ngdx-links-layer\"\n\t\t[ngStyle]=\"{\n\t\t\ttransform:\n\t\t\t\t'translate(' +\n\t\t\t\t(diagramModel.selectOffsetX() | async) +\n\t\t\t\t'px, ' +\n\t\t\t\t(diagramModel.selectOffsetY() | async) +\n\t\t\t\t'px) scale(' +\n\t\t\t\t(diagramModel.selectZoomLevel() | async) / 100.0 +\n\t\t\t\t')'\n\t\t}\"\n\t>\n\t\t<ng-template #linksLayer></ng-template>\n\t</div>\n\n\t<!-- Selection Box -->\n\t<div\n\t\t*ngIf=\"shouldDrawSelectionBox() && selectAction() | async as action\"\n\t\tclass=\"selector\"\n\t\t[ngStyle]=\"{\n\t\t\ttop: action.dimensions.top + 'px',\n\t\t\tleft: action.dimensions.left + 'px',\n\t\t\twidth: action.dimensions.width + 'px',\n\t\t\theight: action.dimensions.height + 'px'\n\t\t}\"\n\t></div>\n</div>\n",
                        changeDetection: core.ChangeDetectionStrategy.OnPush,
                        styles: [".ngdx-diagram{position:relative;flex-grow:1;display:flex;cursor:move;overflow:hidden}.ngdx-diagram .selector{position:absolute;background-color:rgba(0,192,255,.2);border:2px solid #00c0ff}.ngdx-diagram .ngdx-nodes-layer{position:absolute;height:100%;width:100%;transform-origin:0 0;overflow:visible!important;pointer-events:none;z-index:150;top:0;bottom:0;left:0;right:0}.ngdx-diagram .ngdx-links-layer{position:absolute;height:100%;width:100%;transform-origin:0 0;overflow:visible!important;pointer-events:none;z-index:100;top:0;bottom:0;left:0;right:0}"]
                    }] }
        ];
        /** @nocollapse */
        NgxDiagramComponent.ctorParameters = function () { return [
            { type: core.Renderer2 },
            { type: core.ChangeDetectorRef }
        ]; };
        NgxDiagramComponent.propDecorators = {
            diagramModel: [{ type: core.Input, args: ['model',] }],
            allowCanvasZoon: [{ type: core.Input }],
            allowCanvasTranslation: [{ type: core.Input }],
            inverseZoom: [{ type: core.Input }],
            allowLooseLinks: [{ type: core.Input }],
            actionStartedFiring: [{ type: core.Output }],
            actionStillFiring: [{ type: core.Output }],
            actionStoppedFiring: [{ type: core.Output }],
            nodesLayer: [{ type: core.ViewChild, args: ['nodesLayer', { read: core.ViewContainerRef, static: true },] }],
            linksLayer: [{ type: core.ViewChild, args: ['linksLayer', { read: core.ViewContainerRef, static: true },] }],
            canvas: [{ type: core.ViewChild, args: ['canvas', { read: core.ElementRef, static: true },] }]
        };
        return NgxDiagramComponent;
    }());
    if (false) {
        /** @type {?} */
        NgxDiagramComponent.prototype.diagramModel;
        /** @type {?} */
        NgxDiagramComponent.prototype.allowCanvasZoon;
        /** @type {?} */
        NgxDiagramComponent.prototype.allowCanvasTranslation;
        /** @type {?} */
        NgxDiagramComponent.prototype.inverseZoom;
        /** @type {?} */
        NgxDiagramComponent.prototype.allowLooseLinks;
        /** @type {?} */
        NgxDiagramComponent.prototype.actionStartedFiring;
        /** @type {?} */
        NgxDiagramComponent.prototype.actionStillFiring;
        /** @type {?} */
        NgxDiagramComponent.prototype.actionStoppedFiring;
        /** @type {?} */
        NgxDiagramComponent.prototype.nodesLayer;
        /** @type {?} */
        NgxDiagramComponent.prototype.linksLayer;
        /** @type {?} */
        NgxDiagramComponent.prototype.canvas;
        /**
         * @type {?}
         * @private
         */
        NgxDiagramComponent.prototype.nodes$;
        /**
         * @type {?}
         * @private
         */
        NgxDiagramComponent.prototype.links$;
        /**
         * @type {?}
         * @private
         */
        NgxDiagramComponent.prototype.action$;
        /**
         * @type {?}
         * @private
         */
        NgxDiagramComponent.prototype.nodesRendered$;
        /**
         * @type {?}
         * @private
         */
        NgxDiagramComponent.prototype.destroyed$;
        /**
         * @type {?}
         * @private
         */
        NgxDiagramComponent.prototype.mouseUpListener;
        /**
         * @type {?}
         * @private
         */
        NgxDiagramComponent.prototype.mouseMoveListener;
        /** @type {?} */
        NgxDiagramComponent.prototype.onMouseUp;
        /** @type {?} */
        NgxDiagramComponent.prototype.onMouseMove;
        /**
         * @type {?}
         * @private
         */
        NgxDiagramComponent.prototype.renderer;
        /**
         * @type {?}
         * @private
         */
        NgxDiagramComponent.prototype.cdRef;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/models/default-link.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultLinkModel = /** @class */ (function (_super) {
        __extends(DefaultLinkModel, _super);
        function DefaultLinkModel(type) {
            if (type === void 0) { type = 'default'; }
            var _this = _super.call(this, type) || this;
            _this.color = 'rgba(255,255,255,0.5)';
            _this.width = 3;
            _this.curvyness = 50;
            return _this;
        }
        /**
         * @param {?} width
         * @return {?}
         */
        DefaultLinkModel.prototype.setWidth = /**
         * @param {?} width
         * @return {?}
         */
        function (width) {
            this.width = width;
        };
        /**
         * @param {?} color
         * @return {?}
         */
        DefaultLinkModel.prototype.setColor = /**
         * @param {?} color
         * @return {?}
         */
        function (color) {
            this.color = color;
        };
        return DefaultLinkModel;
    }(LinkModel));
    if (false) {
        /** @type {?} */
        DefaultLinkModel.prototype.width;
        /** @type {?} */
        DefaultLinkModel.prototype.color;
        /** @type {?} */
        DefaultLinkModel.prototype.curvyness;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/models/default-port.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @record
     */
    function DefaultPortModelConfig() { }
    if (false) {
        /** @type {?|undefined} */
        DefaultPortModelConfig.prototype.id;
        /** @type {?|undefined} */
        DefaultPortModelConfig.prototype.isInput;
        /** @type {?|undefined} */
        DefaultPortModelConfig.prototype.name;
        /** @type {?|undefined} */
        DefaultPortModelConfig.prototype.type;
        /** @type {?|undefined} */
        DefaultPortModelConfig.prototype.label;
        /** @type {?|undefined} */
        DefaultPortModelConfig.prototype.linkType;
    }
    var DefaultPortModel = /** @class */ (function (_super) {
        __extends(DefaultPortModel, _super);
        function DefaultPortModel(_a) {
            var _b = _a === void 0 ? {} : _a, _c = _b.isInput, isInput = _c === void 0 ? true : _c, _d = _b.name, name = _d === void 0 ? 'port' : _d, _e = _b.type, type = _e === void 0 ? 'default' : _e, _f = _b.id, id = _f === void 0 ? null : _f, _g = _b.label, label = _g === void 0 ? null : _g, _h = _b.linkType, linkType = _h === void 0 ? 'default' : _h;
            var _this = _super.call(this, name, type, id, null, linkType) || this;
            _this.in = isInput;
            _this.label = label || name;
            return _this;
        }
        /**
         * @param {?} port
         * @return {?}
         */
        DefaultPortModel.prototype.link = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            /** @type {?} */
            var link = this.createLinkModel();
            link.setSourcePort(this);
            link.setTargetPort(port);
            return link;
        };
        /**
         * @param {?} port
         * @return {?}
         */
        DefaultPortModel.prototype.canLinkToPort = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            if (port instanceof DefaultPortModel) {
                return this.in !== port.in;
            }
            return true;
        };
        /**
         * @return {?}
         */
        DefaultPortModel.prototype.createLinkModel = /**
         * @return {?}
         */
        function () {
            /** @type {?} */
            var link = _super.prototype.createLinkModel.call(this);
            return link || new DefaultLinkModel(this.getLinkType());
        };
        return DefaultPortModel;
    }(PortModel));
    if (false) {
        /** @type {?} */
        DefaultPortModel.prototype.in;
        /** @type {?} */
        DefaultPortModel.prototype.label;
        /** @type {?} */
        DefaultPortModel.prototype.links;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/models/default-node.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultNodeModel = /** @class */ (function (_super) {
        __extends(DefaultNodeModel, _super);
        function DefaultNodeModel(name, type, id, color) {
            if (name === void 0) { name = 'Untitled'; }
            if (type === void 0) { type = 'default'; }
            if (color === void 0) { color = 'rgb(0, 192, 255)'; }
            var _this = _super.call(this, type, id) || this;
            _this.name = name;
            _this.color = color;
            _this.height$ = _this.selectHeight();
            _this.width$ = _this.selectWidth();
            return _this;
        }
        /**
         * @param {?} __0
         * @return {?}
         */
        DefaultNodeModel.prototype.addInPort = /**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var name = _a.name, _b = _a.type, type = _b === void 0 ? 'default' : _b, id = _a.id, _c = _a.linkType, linkType = _c === void 0 ? 'default' : _c;
            /** @type {?} */
            var port = new DefaultPortModel({ isInput: true, name: name, type: type, id: id, label: null, linkType: linkType });
            this.addPort(port);
            return port;
        };
        /**
         * @param {?} __0
         * @return {?}
         */
        DefaultNodeModel.prototype.addOutPort = /**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var name = _a.name, _b = _a.type, type = _b === void 0 ? 'default' : _b, id = _a.id, _c = _a.linkType, linkType = _c === void 0 ? 'default' : _c;
            /** @type {?} */
            var port = new DefaultPortModel({ isInput: false, name: name, type: type, id: id, label: null, linkType: linkType });
            this.addPort(port);
            return port;
        };
        return DefaultNodeModel;
    }(NodeModel));
    if (false) {
        /** @type {?} */
        DefaultNodeModel.prototype.name;
        /** @type {?} */
        DefaultNodeModel.prototype.color;
        /** @type {?} */
        DefaultNodeModel.prototype.height$;
        /** @type {?} */
        DefaultNodeModel.prototype.width$;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/components/default-node/default-node.component.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultNodeComponent = /** @class */ (function (_super) {
        __extends(DefaultNodeComponent, _super);
        function DefaultNodeComponent() {
            return _super.call(this, 'ngdx-default-node') || this;
        }
        /**
         * @return {?}
         */
        DefaultNodeComponent.prototype.ngOnInit = /**
         * @return {?}
         */
        function () {
            var _this = this;
            this.selectPorts().subscribe((/**
             * @param {?} ports
             * @return {?}
             */
            function (ports) {
                ports.forEach((/**
                 * @param {?} port
                 * @return {?}
                 */
                function (port) {
                    if (!port.getPainted()) {
                        _this.generatePort(port);
                        port.setPainted();
                    }
                }));
            }));
        };
        /**
         * @param {?} port
         * @return {?}
         */
        DefaultNodeComponent.prototype.generatePort = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            this.diagramEngine.generateWidgetForPort(port, this.portsLayer);
        };
        DefaultNodeComponent.decorators = [
            { type: core.Component, args: [{
                        selector: 'ngdx-default-node',
                        template: "<div\n\tclass=\"default-node\"\n\t[ngStyle]=\"{\n\t\t'height.px': height$ | async,\n\t\t'width.px': width$ | async,\n\t\t'background-color': color\n\t}\"\n>\n\t<div class=\"ports\">\n\t\t<ng-template #portsLayer></ng-template>\n\t</div>\n</div>\n",
                        styles: [":host.selected .default-node{background-color:#fff!important;border-color:#00f}:host .default-node{pointer-events:all;width:100%;border-radius:10px;transition:.3s ease-in-out;cursor:auto}:host .default-node .title{padding:10px;text-align:center;border-bottom:1px solid #00f}"]
                    }] }
        ];
        /** @nocollapse */
        DefaultNodeComponent.ctorParameters = function () { return []; };
        DefaultNodeComponent.propDecorators = {
            portsLayer: [{ type: core.ViewChild, args: ['portsLayer', { read: core.ViewContainerRef, static: true },] }]
        };
        return DefaultNodeComponent;
    }(DefaultNodeModel));
    if (false) {
        /** @type {?} */
        DefaultNodeComponent.prototype.portsLayer;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/factories/base.factory.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @abstract
     * @template T
     */
    var   /**
     * @abstract
     * @template T
     */
    AbstractFactory = /** @class */ (function () {
        function AbstractFactory(name) {
            this._type = name;
        }
        Object.defineProperty(AbstractFactory.prototype, "type", {
            get: /**
             * @return {?}
             */
            function () {
                return this._type;
            },
            enumerable: true,
            configurable: true
        });
        return AbstractFactory;
    }());
    if (false) {
        /**
         * @type {?}
         * @protected
         */
        AbstractFactory.prototype._type;
        /**
         * @abstract
         * @param {?=} initialConfig
         * @return {?}
         */
        AbstractFactory.prototype.getNewInstance = function (initialConfig) { };
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/factories/node.factory.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @abstract
     * @template T
     */
    var   /**
     * @abstract
     * @template T
     */
    AbstractNodeFactory = /** @class */ (function (_super) {
        __extends(AbstractNodeFactory, _super);
        function AbstractNodeFactory() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return AbstractNodeFactory;
    }(AbstractFactory));
    if (false) {
        /**
         * @abstract
         * @param {?} diagramEngine
         * @param {?} node
         * @param {?} nodeHost
         * @return {?}
         */
        AbstractNodeFactory.prototype.generateWidget = function (diagramEngine, node, nodeHost) { };
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/factories/default-node.factory.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultNodeFactory = /** @class */ (function (_super) {
        __extends(DefaultNodeFactory, _super);
        function DefaultNodeFactory(resolver, renderer) {
            var _this = _super.call(this, 'default') || this;
            _this.resolver = resolver;
            _this.renderer = renderer;
            return _this;
        }
        /**
         * @param {?} diagramEngine
         * @param {?} node
         * @param {?} nodesHost
         * @return {?}
         */
        DefaultNodeFactory.prototype.generateWidget = /**
         * @param {?} diagramEngine
         * @param {?} node
         * @param {?} nodesHost
         * @return {?}
         */
        function (diagramEngine, node, nodesHost) {
            var _this = this;
            /** @type {?} */
            var componentRef = nodesHost.createComponent(this.getRecipe());
            // attach coordinates and default positional behaviour to the generated component host
            /** @type {?} */
            var rootNode = componentRef.location.nativeElement;
            // default style for node
            this.renderer.setStyle(rootNode, 'position', 'absolute');
            this.renderer.setStyle(rootNode, 'display', 'block');
            // data attributes
            this.renderer.setAttribute(rootNode, 'data-nodeid', node.id);
            // subscribe to node coordinates
            node.selectCoords().subscribe((/**
             * @param {?} __0
             * @return {?}
             */
            function (_a) {
                var x = _a.x, y = _a.y;
                _this.renderer.setStyle(rootNode, 'left', x + "px");
                _this.renderer.setStyle(rootNode, 'top', y + "px");
            }));
            node.selectionChanges().subscribe((/**
             * @param {?} e
             * @return {?}
             */
            function (e) {
                e.isSelected ? _this.renderer.addClass(rootNode, 'selected') : _this.renderer.removeClass(rootNode, 'selected');
            }));
            node.onEntityDestroy().subscribe((/**
             * @return {?}
             */
            function ( /** e */) {
                componentRef.destroy();
            }));
            // assign all passed properties to node initialization.
            Object.entries(node).forEach((/**
             * @param {?} __0
             * @return {?}
             */
            function (_a) {
                var _b = __read(_a, 2), key = _b[0], value = _b[1];
                componentRef.instance[key] = value;
            }));
            componentRef.instance.diagramEngine = diagramEngine;
            return componentRef;
        };
        /**
         * @return {?}
         */
        DefaultNodeFactory.prototype.getRecipe = /**
         * @return {?}
         */
        function () {
            return this.resolver.resolveComponentFactory(DefaultNodeComponent);
        };
        /**
         * @param {?=} initialConfig
         * @return {?}
         */
        DefaultNodeFactory.prototype.getNewInstance = /**
         * @param {?=} initialConfig
         * @return {?}
         */
        function (initialConfig) {
            return new (DefaultNodeModel.bind.apply(DefaultNodeModel, __spread([void 0, 'default'], initialConfig)))();
        };
        return DefaultNodeFactory;
    }(AbstractNodeFactory));
    if (false) {
        /**
         * @type {?}
         * @private
         */
        DefaultNodeFactory.prototype.resolver;
        /**
         * @type {?}
         * @private
         */
        DefaultNodeFactory.prototype.renderer;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/factories/port.factory.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @abstract
     * @template T
     */
    var   /**
     * @abstract
     * @template T
     */
    AbstractPortFactory = /** @class */ (function (_super) {
        __extends(AbstractPortFactory, _super);
        function AbstractPortFactory() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return AbstractPortFactory;
    }(AbstractFactory));
    if (false) {
        /**
         * @abstract
         * @param {?} port
         * @param {?} portHost
         * @return {?}
         */
        AbstractPortFactory.prototype.generateWidget = function (port, portHost) { };
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/components/default-port/default-port.component.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultPortComponent = /** @class */ (function (_super) {
        __extends(DefaultPortComponent, _super);
        function DefaultPortComponent() {
            return _super.call(this) || this;
        }
        DefaultPortComponent.decorators = [
            { type: core.Component, args: [{
                        selector: 'ngdx-default-port',
                        template: "<div [ngClass]=\"in ? 'in' : 'out'\"></div>\n",
                        styles: [":host{position:absolute;width:10px;height:10px;border-radius:60px;border:1px solid violet;background-color:#d3d3d3;margin:10px 0}:host:hover{background-color:green}:host.out{right:-5px}:host.in{left:-5px}"]
                    }] }
        ];
        /** @nocollapse */
        DefaultPortComponent.ctorParameters = function () { return []; };
        return DefaultPortComponent;
    }(DefaultPortModel));

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/factories/default-port.factory.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultPortFactory = /** @class */ (function (_super) {
        __extends(DefaultPortFactory, _super);
        function DefaultPortFactory(resolver, renderer) {
            var _this = _super.call(this, 'default') || this;
            _this.resolver = resolver;
            _this.renderer = renderer;
            return _this;
        }
        /**
         * @param {?} port
         * @param {?} portsHost
         * @return {?}
         */
        DefaultPortFactory.prototype.generateWidget = /**
         * @param {?} port
         * @param {?} portsHost
         * @return {?}
         */
        function (port, portsHost) {
            /** @type {?} */
            var componentRef = portsHost.createComponent(this.getRecipe());
            // attach coordinates and default positional behaviour to the generated component host
            /** @type {?} */
            var rootNode = (/** @type {?} */ (componentRef.location.nativeElement));
            // data attributes
            this.renderer.setAttribute(rootNode, 'data-portid', port.id);
            this.renderer.setAttribute(rootNode, 'data-name', port.getName());
            port.in ? this.renderer.addClass(rootNode, 'in') : this.renderer.addClass(rootNode, 'out');
            // assign all passed properties to node initialization.
            Object.entries(port).forEach((/**
             * @param {?} __0
             * @return {?}
             */
            function (_a) {
                var _b = __read(_a, 2), key = _b[0], value = _b[1];
                componentRef.instance[key] = value;
            }));
            port.onEntityDestroy().subscribe((/**
             * @return {?}
             */
            function ( /** e */) {
                componentRef.destroy();
            }));
            return componentRef;
        };
        /**
         * @return {?}
         */
        DefaultPortFactory.prototype.getRecipe = /**
         * @return {?}
         */
        function () {
            return this.resolver.resolveComponentFactory(DefaultPortComponent);
        };
        /**
         * @param {?=} initialConfig
         * @return {?}
         */
        DefaultPortFactory.prototype.getNewInstance = /**
         * @param {?=} initialConfig
         * @return {?}
         */
        function (initialConfig) {
            return new DefaultPortModel(__assign({ isInput: true, name: 'unknown' }, initialConfig));
        };
        return DefaultPortFactory;
    }(AbstractPortFactory));
    if (false) {
        /**
         * @type {?}
         * @private
         */
        DefaultPortFactory.prototype.resolver;
        /**
         * @type {?}
         * @private
         */
        DefaultPortFactory.prototype.renderer;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/factories/link.factory.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @abstract
     * @template T
     */
    var   /**
     * @abstract
     * @template T
     */
    AbstractLinkFactory = /** @class */ (function (_super) {
        __extends(AbstractLinkFactory, _super);
        function AbstractLinkFactory() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return AbstractLinkFactory;
    }(AbstractFactory));
    if (false) {
        /**
         * @abstract
         * @param {?} diagramEngine
         * @param {?} link
         * @param {?} linksHost
         * @return {?}
         */
        AbstractLinkFactory.prototype.generateWidget = function (diagramEngine, link, linksHost) { };
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/components/default-link/default-link.component.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultLinkComponent = /** @class */ (function (_super) {
        __extends(DefaultLinkComponent, _super);
        function DefaultLinkComponent(cdRef) {
            var _this = _super.call(this, 'ngdx-default-link') || this;
            _this.cdRef = cdRef;
            _this._path$ = new rxjs.BehaviorSubject(null);
            _this.path$ = _this._path$.asObservable();
            _this.points$ = new rxjs.BehaviorSubject([]);
            return _this;
        }
        /**
         * @return {?}
         */
        DefaultLinkComponent.prototype.ngAfterViewInit = /**
         * @return {?}
         */
        function () {
            var _this = this;
            /** @type {?} */
            var firstPCoords$ = this.getFirstPoint().selectCoords();
            /** @type {?} */
            var lastPCoords$ = this.getLastPoint().selectCoords();
            // Observe link coords and update drawing accordingly
            rxjs.combineLatest([firstPCoords$, lastPCoords$])
                .pipe(operators.takeUntil(this.onEntityDestroy()))
                .subscribe((/**
             * @param {?} __0
             * @return {?}
             */
            function (_a) {
                var _b = __read(_a, 2), firstPCoords = _b[0], lastPCoords = _b[1];
                /** @type {?} */
                var points = [firstPCoords, lastPCoords];
                /** @type {?} */
                var isHorizontal = Math.abs(firstPCoords.x - lastPCoords.x) > Math.abs(firstPCoords.y - lastPCoords.y);
                /** @type {?} */
                var xOrY = isHorizontal ? 'x' : 'y';
                // draw the smoothing
                // if the points are too close, just draw a straight line
                /** @type {?} */
                var isStraight = false;
                if (Math.abs(points[0][xOrY] - points[1][xOrY]) < 50) {
                    isStraight = true;
                }
                /** @type {?} */
                var path = generateCurvePath(firstPCoords, lastPCoords, isStraight ? 0 : _this.curvyness);
                _this._path$.next(path);
                if (!_this.getTargetPort()) {
                    /** @type {?} */
                    var danglingPoint = _this.generatePoint(lastPCoords);
                    _this.points$.next([danglingPoint]);
                }
                /** @type {?} */
                var label = _this.getLabel();
                // update label position
                if (label) {
                    label.setCoords(_this.calcCenterOfPath(firstPCoords, lastPCoords));
                    // TODO: check whether we want the label to rotate along with the line
                    // label.setRotation(this.calcLabelIncline(firstPCoords, lastPCoords));
                }
                // TODO: handle the multiple lines in between the points
                // https://github.com/projectstorm/react-diagrams/blob/master/src/defaults/widgets/DefaultLinkWidget.tsx#L344-L371
                _this.cdRef.detectChanges();
            }));
            // observe link label and draw/remove accordingly
            this.selectLabel()
                .pipe(operators.filter(Boolean))
                .subscribe((/**
             * @param {?} label
             * @return {?}
             */
            function (label) {
                _this.diagramEngine.generateWidgetForLabel(label, _this.labelLayer);
                _this.cdRef.detectChanges();
            }));
        };
        /**
         * @param {?} firstPoint
         * @param {?} secondPoint
         * @return {?}
         */
        DefaultLinkComponent.prototype.calcLabelIncline = /**
         * @param {?} firstPoint
         * @param {?} secondPoint
         * @return {?}
         */
        function (firstPoint, secondPoint) {
            /** @type {?} */
            var dy = secondPoint.y - firstPoint.y;
            /** @type {?} */
            var dx = secondPoint.x - firstPoint.x;
            if (dx === 0) {
                return 0;
            }
            /** @type {?} */
            var inclineAngel = (Math.atan(dy / dx) * 180) / Math.PI;
            if (inclineAngel < 0) {
                inclineAngel += 180;
            }
            return inclineAngel;
        };
        /**
         * @param {?} firstPoint
         * @param {?} secondPoint
         * @return {?}
         */
        DefaultLinkComponent.prototype.calcCenterOfPath = /**
         * @param {?} firstPoint
         * @param {?} secondPoint
         * @return {?}
         */
        function (firstPoint, secondPoint) {
            return { x: (firstPoint.x + secondPoint.x) / 2 + 20, y: (firstPoint.y + secondPoint.y) / 2 + 20 };
        };
        DefaultLinkComponent.decorators = [
            { type: core.Component, args: [{
                        selector: 'ngdx-default-link',
                        template: "<!-- Label Host -->\n<ng-template #labelLayer></ng-template>\n\n<!-- Link -->\n<svg class=\"default-link\">\n\t<g>\n\t\t<path [attr.stroke-width]=\"width\" [attr.stroke]=\"color\" [attr.d]=\"path$ | async\"></path>\n\t\t<path\n\t\t\t(mouseleave)=\"setSelected(false)\"\n\t\t\t(mouseenter)=\"setSelected()\"\n\t\t\t[attr.stroke-width]=\"20\"\n\t\t\t[attr.stroke]=\"color\"\n\t\t\t[attr.stroke-linecap]=\"'round'\"\n\t\t\t[attr.data-linkid]=\"id\"\n\t\t\t[attr.stroke-opacity]=\"(selectSelected() | async) ? '0.1' : '0'\"\n\t\t\t[attr.d]=\"path$ | async\"\n\t\t></path>\n\t</g>\n\t<g *ngFor=\"let point of points$ | async\">\n\t\t<circle [attr.cx]=\"point.selectX() | async\" [attr.cy]=\"point.selectY() | async\" r=\"5\" class=\"default-point\" />\n\n\t\t<circle\n\t\t\t(mouseleave)=\"setSelected(false)\"\n\t\t\t(mouseenter)=\"setSelected()\"\n\t\t\t[attr.data-id]=\"point.id\"\n\t\t\t[attr.data-linkid]=\"id\"\n\t\t\t[attr.cx]=\"point.selectX() | async\"\n\t\t\t[attr.cy]=\"point.selectY() | async\"\n\t\t\tr=\"15\"\n\t\t\t[attr.opacity]=\"0\"\n\t\t\tclass=\"default-point\"\n\t\t\t[ngClass]=\"{ 'default-point': true, selected: point.selectSelected() | async }\"\n\t\t/>\n\t\t{{ point.selectSelected() | async }}\n\t</g>\n</svg>\n",
                        styles: [".default-link{fill:none;overflow:visible}.default-link .default-point{fill:rgba(255,255,255,.5)}.default-link .default-point.selected{fill:rgba(0,0,255,.5)}@-webkit-keyframes dash{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}@keyframes dash{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}.default-link path{fill:none;pointer-events:all}.default-link.path-selected{stroke:#00c0ff!important;stroke-dasharray:10,2;-webkit-animation:1s linear infinite dash;animation:1s linear infinite dash}"]
                    }] }
        ];
        /** @nocollapse */
        DefaultLinkComponent.ctorParameters = function () { return [
            { type: core.ChangeDetectorRef }
        ]; };
        DefaultLinkComponent.propDecorators = {
            labelLayer: [{ type: core.ViewChild, args: ['labelLayer', { read: core.ViewContainerRef, static: true },] }]
        };
        return DefaultLinkComponent;
    }(DefaultLinkModel));
    if (false) {
        /** @type {?} */
        DefaultLinkComponent.prototype.labelLayer;
        /** @type {?} */
        DefaultLinkComponent.prototype._path$;
        /** @type {?} */
        DefaultLinkComponent.prototype.path$;
        /** @type {?} */
        DefaultLinkComponent.prototype.points$;
        /** @type {?} */
        DefaultLinkComponent.prototype.label$;
        /**
         * @type {?}
         * @private
         */
        DefaultLinkComponent.prototype.cdRef;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/factories/default-link.factory.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultLinkFactory = /** @class */ (function (_super) {
        __extends(DefaultLinkFactory, _super);
        function DefaultLinkFactory(resolver, renderer) {
            var _this = _super.call(this, 'default') || this;
            _this.resolver = resolver;
            _this.renderer = renderer;
            return _this;
        }
        /**
         * @param {?} diagramEngine
         * @param {?} link
         * @param {?} linksHost
         * @return {?}
         */
        DefaultLinkFactory.prototype.generateWidget = /**
         * @param {?} diagramEngine
         * @param {?} link
         * @param {?} linksHost
         * @return {?}
         */
        function (diagramEngine, link, linksHost) {
            /** @type {?} */
            var componentRef = linksHost.createComponent(this.getRecipe());
            // attach coordinates and default positional behaviour to the generated component host
            /** @type {?} */
            var rootNode = componentRef.location.nativeElement;
            // default style for link
            this.renderer.setStyle(rootNode, 'position', 'absolute');
            this.renderer.addClass(rootNode, 'label');
            // data attributes
            this.renderer.setAttribute(rootNode, 'data-linkid', link.id);
            // on destroy make sure to destroy the componentRef
            link.onEntityDestroy().subscribe((/**
             * @return {?}
             */
            function () {
                componentRef.destroy();
            }));
            // assign all passed properties to link initialization.
            Object.entries(link).forEach((/**
             * @param {?} __0
             * @return {?}
             */
            function (_a) {
                var _b = __read(_a, 2), key = _b[0], value = _b[1];
                componentRef.instance[key] = value;
            }));
            componentRef.instance.diagramEngine = diagramEngine;
            return componentRef;
        };
        /**
         * @return {?}
         */
        DefaultLinkFactory.prototype.getRecipe = /**
         * @return {?}
         */
        function () {
            return this.resolver.resolveComponentFactory(DefaultLinkComponent);
        };
        /**
         * @return {?}
         */
        DefaultLinkFactory.prototype.getNewInstance = /**
         * @return {?}
         */
        function () {
            return new DefaultLinkModel();
        };
        return DefaultLinkFactory;
    }(AbstractLinkFactory));
    if (false) {
        /**
         * @type {?}
         * @private
         */
        DefaultLinkFactory.prototype.resolver;
        /**
         * @type {?}
         * @private
         */
        DefaultLinkFactory.prototype.renderer;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/ngx-diagrams.module.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var NgxDiagramsModule = /** @class */ (function () {
        function NgxDiagramsModule() {
        }
        NgxDiagramsModule.decorators = [
            { type: core.NgModule, args: [{
                        declarations: [NgxDiagramComponent],
                        imports: [common.CommonModule],
                        providers: [],
                        exports: [NgxDiagramComponent],
                        entryComponents: []
                    },] }
        ];
        return NgxDiagramsModule;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/factories/label.factory.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @abstract
     * @template T
     */
    var   /**
     * @abstract
     * @template T
     */
    AbstractLabelFactory = /** @class */ (function (_super) {
        __extends(AbstractLabelFactory, _super);
        function AbstractLabelFactory() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return AbstractLabelFactory;
    }(AbstractFactory));
    if (false) {
        /**
         * @abstract
         * @param {?} label
         * @param {?} labelsHost
         * @return {?}
         */
        AbstractLabelFactory.prototype.generateWidget = function (label, labelsHost) { };
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/models/label.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var LabelModel = /** @class */ (function (_super) {
        __extends(LabelModel, _super);
        function LabelModel(type, id) {
            var _this = _super.call(this, type, id) || this;
            _this._coords = new rxjs.BehaviorSubject({ x: 0, y: 0 });
            _this.coords$ = _this._coords.asObservable();
            _this._rotation = new rxjs.BehaviorSubject(0);
            _this.rotation$ = _this._rotation.asObservable();
            return _this;
        }
        /**
         * @param {?=} options
         * @return {?}
         */
        LabelModel.prototype.destroy = /**
         * @param {?=} options
         * @return {?}
         */
        function (options) {
            _super.prototype.destroy.call(this, options);
        };
        /**
         * @param {?} angle
         * @return {?}
         */
        LabelModel.prototype.setRotation = /**
         * @param {?} angle
         * @return {?}
         */
        function (angle) {
            this._rotation.next(angle);
        };
        /**
         * @return {?}
         */
        LabelModel.prototype.selectRotation = /**
         * @return {?}
         */
        function () {
            return this.rotation$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.distinctUntilChanged());
        };
        /**
         * @param {?} newCoords
         * @return {?}
         */
        LabelModel.prototype.setCoords = /**
         * @param {?} newCoords
         * @return {?}
         */
        function (newCoords) {
            this._coords.next(__assign({}, this._coords.getValue(), newCoords));
        };
        /**
         * @return {?}
         */
        LabelModel.prototype.selectCoords = /**
         * @return {?}
         */
        function () {
            return this.coords$.pipe(operators.takeUntil(this.onEntityDestroy()), operators.distinctUntilChanged());
        };
        return LabelModel;
    }(BaseModel));
    if (false) {
        /**
         * @type {?}
         * @private
         */
        LabelModel.prototype._coords;
        /**
         * @type {?}
         * @private
         */
        LabelModel.prototype.coords$;
        /**
         * @type {?}
         * @private
         */
        LabelModel.prototype._rotation;
        /**
         * @type {?}
         * @private
         */
        LabelModel.prototype.rotation$;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/models/default-label.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultLabelModel = /** @class */ (function (_super) {
        __extends(DefaultLabelModel, _super);
        function DefaultLabelModel(label, type) {
            if (label === void 0) { label = 'NO LABEL'; }
            if (type === void 0) { type = 'default'; }
            var _this = _super.call(this, type) || this;
            _this._label = new rxjs.BehaviorSubject('');
            _this.label$ = _this._label.asObservable();
            _this.setLabel(label);
            return _this;
        }
        /**
         * @param {?} label
         * @return {?}
         */
        DefaultLabelModel.prototype.setLabel = /**
         * @param {?} label
         * @return {?}
         */
        function (label) {
            this._label.next(label);
        };
        /**
         * @return {?}
         */
        DefaultLabelModel.prototype.getLabel = /**
         * @return {?}
         */
        function () {
            return this._label.getValue();
        };
        /**
         * @return {?}
         */
        DefaultLabelModel.prototype.selectLabel = /**
         * @return {?}
         */
        function () {
            return this.label$;
        };
        return DefaultLabelModel;
    }(LabelModel));
    if (false) {
        /**
         * @type {?}
         * @private
         */
        DefaultLabelModel.prototype._label;
        /** @type {?} */
        DefaultLabelModel.prototype.label$;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/components/default-label/default-label.component.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultLabelComponent = /** @class */ (function (_super) {
        __extends(DefaultLabelComponent, _super);
        function DefaultLabelComponent() {
            return _super.call(this, 'ngdx-default-label') || this;
        }
        DefaultLabelComponent.decorators = [
            { type: core.Component, args: [{
                        selector: 'ngdx-default-label',
                        template: "<div\n\tclass=\"default-label\"\n\t[ngStyle]=\"{\n\t\ttransform:\n\t\t\t'translate(' +\n\t\t\t(selectCoords() | async).x +\n\t\t\t'px, ' +\n\t\t\t(selectCoords() | async).y +\n\t\t\t'px)' +\n\t\t\t'rotate(' +\n\t\t\t(selectRotation() | async) +\n\t\t\t'deg)'\n\t}\"\n>\n\t{{ label$ | async }}\n</div>\n",
                        styles: [".default-label{color:#fff;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}"]
                    }] }
        ];
        /** @nocollapse */
        DefaultLabelComponent.ctorParameters = function () { return []; };
        return DefaultLabelComponent;
    }(DefaultLabelModel));

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/factories/default-label.factory.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultLabelFactory = /** @class */ (function (_super) {
        __extends(DefaultLabelFactory, _super);
        function DefaultLabelFactory(resolver, renderer) {
            var _this = _super.call(this, 'default') || this;
            _this.resolver = resolver;
            _this.renderer = renderer;
            return _this;
        }
        /**
         * @param {?} label
         * @param {?} labelHost
         * @return {?}
         */
        DefaultLabelFactory.prototype.generateWidget = /**
         * @param {?} label
         * @param {?} labelHost
         * @return {?}
         */
        function (label, labelHost) {
            /** @type {?} */
            var componentRef = labelHost.createComponent(this.getRecipe());
            // attach coordinates and default positional behaviour to the generated component host
            /** @type {?} */
            var rootNode = componentRef.location.nativeElement;
            // default style for link
            this.renderer.setStyle(rootNode, 'position', 'absolute');
            // data attributes
            this.renderer.setAttribute(rootNode, 'data-labelid', label.id);
            // on destroy make sure to destroy the componentRef
            label.onEntityDestroy().subscribe((/**
             * @return {?}
             */
            function () {
                componentRef.destroy();
            }));
            // assign all passed properties to node initialization.
            Object.entries(label).forEach((/**
             * @param {?} __0
             * @return {?}
             */
            function (_a) {
                var _b = __read(_a, 2), key = _b[0], value = _b[1];
                componentRef.instance[key] = value;
            }));
            return componentRef;
        };
        /**
         * @return {?}
         */
        DefaultLabelFactory.prototype.getRecipe = /**
         * @return {?}
         */
        function () {
            return this.resolver.resolveComponentFactory(DefaultLabelComponent);
        };
        /**
         * @return {?}
         */
        DefaultLabelFactory.prototype.getNewInstance = /**
         * @return {?}
         */
        function () {
            return new DefaultLabelModel();
        };
        return DefaultLabelFactory;
    }(AbstractLabelFactory));
    if (false) {
        /**
         * @type {?}
         * @private
         */
        DefaultLabelFactory.prototype.resolver;
        /**
         * @type {?}
         * @private
         */
        DefaultLabelFactory.prototype.renderer;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/services/engine.service.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DiagramEngine = /** @class */ (function () {
        function DiagramEngine(resolver, rendererFactory) {
            this.resolver = resolver;
            this.rendererFactory = rendererFactory;
            this._renderer = this.rendererFactory.createRenderer(null, null);
            this.nodeFactories = {};
            this.linkFactories = {};
            this.portFactories = {};
            this.labelFactories = {};
            this.canvas$ = new rxjs.BehaviorSubject(null);
        }
        /**
         * @return {?}
         */
        DiagramEngine.prototype.createDiagram = /**
         * @return {?}
         */
        function () {
            this.diagramModel = new DiagramModel(this);
            return this.diagramModel;
        };
        /**
         * @return {?}
         */
        DiagramEngine.prototype.registerDefaultFactories = /**
         * @return {?}
         */
        function () {
            this.registerNodeFactory(new DefaultNodeFactory(this.resolver, this._renderer));
            this.registerPortFactory(new DefaultPortFactory(this.resolver, this._renderer));
            this.registerLinkFactory(new DefaultLinkFactory(this.resolver, this._renderer));
            this.registerLabelFactory(new DefaultLabelFactory(this.resolver, this._renderer));
        };
        //#region Factories
        // LABELS
        //#region Factories
        // LABELS
        /**
         * @param {?} labelFactory
         * @return {?}
         */
        DiagramEngine.prototype.registerLabelFactory = 
        //#region Factories
        // LABELS
        /**
         * @param {?} labelFactory
         * @return {?}
         */
        function (labelFactory) {
            this.labelFactories[labelFactory.type] = labelFactory;
        };
        /**
         * @return {?}
         */
        DiagramEngine.prototype.getLabelFactories = /**
         * @return {?}
         */
        function () {
            return this.labelFactories;
        };
        /**
         * @param {?} type
         * @return {?}
         */
        DiagramEngine.prototype.getLabelFactory = /**
         * @param {?} type
         * @return {?}
         */
        function (type) {
            if (this.labelFactories[type]) {
                return this.labelFactories[type];
            }
            throw new Error("cannot find factory for node of type: [" + type + "]");
        };
        /**
         * @param {?} label
         * @return {?}
         */
        DiagramEngine.prototype.getFactoryForLabel = /**
         * @param {?} label
         * @return {?}
         */
        function (label) {
            return this.getLabelFactory(label.getType());
        };
        /**
         * @param {?} label
         * @param {?} labelHost
         * @return {?}
         */
        DiagramEngine.prototype.generateWidgetForLabel = /**
         * @param {?} label
         * @param {?} labelHost
         * @return {?}
         */
        function (label, labelHost) {
            /** @type {?} */
            var labelFactory = this.getFactoryForLabel(label);
            if (!labelFactory) {
                throw new Error("Cannot find widget factory for node: " + label.getType());
            }
            return labelFactory.generateWidget(label, labelHost);
        };
        // NODES
        // NODES
        /**
         * @param {?} nodeFactory
         * @return {?}
         */
        DiagramEngine.prototype.registerNodeFactory = 
        // NODES
        /**
         * @param {?} nodeFactory
         * @return {?}
         */
        function (nodeFactory) {
            this.nodeFactories[nodeFactory.type] = nodeFactory;
        };
        /**
         * @return {?}
         */
        DiagramEngine.prototype.getNodeFactories = /**
         * @return {?}
         */
        function () {
            return this.nodeFactories;
        };
        /**
         * @param {?} type
         * @return {?}
         */
        DiagramEngine.prototype.getNodeFactory = /**
         * @param {?} type
         * @return {?}
         */
        function (type) {
            if (this.nodeFactories[type]) {
                return this.nodeFactories[type];
            }
            throw new Error("cannot find factory for node of type: [" + type + "]");
        };
        /**
         * @param {?} node
         * @return {?}
         */
        DiagramEngine.prototype.getFactoryForNode = /**
         * @param {?} node
         * @return {?}
         */
        function (node) {
            return this.getNodeFactory(node.getType());
        };
        /**
         * @param {?} node
         * @param {?} nodesHost
         * @return {?}
         */
        DiagramEngine.prototype.generateWidgetForNode = /**
         * @param {?} node
         * @param {?} nodesHost
         * @return {?}
         */
        function (node, nodesHost) {
            /** @type {?} */
            var nodeFactory = this.getFactoryForNode(node);
            if (!nodeFactory) {
                throw new Error("Cannot find widget factory for node: " + node.getType());
            }
            return nodeFactory.generateWidget(this, node, nodesHost);
        };
        // PORTS
        // PORTS
        /**
         * @param {?} factory
         * @return {?}
         */
        DiagramEngine.prototype.registerPortFactory = 
        // PORTS
        /**
         * @param {?} factory
         * @return {?}
         */
        function (factory) {
            this.portFactories[factory.type] = factory;
        };
        /**
         * @return {?}
         */
        DiagramEngine.prototype.getPortFactories = /**
         * @return {?}
         */
        function () {
            return this.portFactories;
        };
        /**
         * @param {?} type
         * @return {?}
         */
        DiagramEngine.prototype.getPortFactory = /**
         * @param {?} type
         * @return {?}
         */
        function (type) {
            if (this.portFactories[type]) {
                return this.portFactories[type];
            }
            throw new Error("cannot find factory for port of type: [" + type + "]");
        };
        /**
         * @param {?} port
         * @return {?}
         */
        DiagramEngine.prototype.getFactoryForPort = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            return this.getPortFactory(port.getType());
        };
        /**
         * @param {?} port
         * @param {?} portsHost
         * @return {?}
         */
        DiagramEngine.prototype.generateWidgetForPort = /**
         * @param {?} port
         * @param {?} portsHost
         * @return {?}
         */
        function (port, portsHost) {
            /** @type {?} */
            var portFactory = this.getFactoryForPort(port);
            if (!portFactory) {
                throw new Error("Cannot find widget factory for port: " + port.getType());
            }
            return portFactory.generateWidget(port, portsHost);
        };
        // LINKS
        // LINKS
        /**
         * @return {?}
         */
        DiagramEngine.prototype.getLinkFactories = 
        // LINKS
        /**
         * @return {?}
         */
        function () {
            return this.linkFactories;
        };
        /**
         * @param {?} factory
         * @return {?}
         */
        DiagramEngine.prototype.registerLinkFactory = /**
         * @param {?} factory
         * @return {?}
         */
        function (factory) {
            this.linkFactories[factory.type] = factory;
        };
        /**
         * @param {?} type
         * @return {?}
         */
        DiagramEngine.prototype.getLinkFactory = /**
         * @param {?} type
         * @return {?}
         */
        function (type) {
            if (this.linkFactories[type]) {
                return this.linkFactories[type];
            }
            throw new Error("cannot find factory for link of type: [" + type + "]");
        };
        /**
         * @param {?} link
         * @return {?}
         */
        DiagramEngine.prototype.getFactoryForLink = /**
         * @param {?} link
         * @return {?}
         */
        function (link) {
            return this.getLinkFactory(link.getType());
        };
        /**
         * @param {?} link
         * @param {?} linksHost
         * @return {?}
         */
        DiagramEngine.prototype.generateWidgetForLink = /**
         * @param {?} link
         * @param {?} linksHost
         * @return {?}
         */
        function (link, linksHost) {
            /** @type {?} */
            var linkFactory = this.getFactoryForLink(link);
            if (!linkFactory) {
                throw new Error("Cannot find link factory for link: " + link.getType());
            }
            return linkFactory.generateWidget(this, link, linksHost);
        };
        //#endregion
        //#endregion
        /**
         * @param {?} node
         * @return {?}
         */
        DiagramEngine.prototype.getNodeElement = 
        //#endregion
        /**
         * @param {?} node
         * @return {?}
         */
        function (node) {
            /** @type {?} */
            var selector = this.canvas$.getValue().querySelector("[data-nodeid=\"" + node.id + "\"]");
            if (selector === null) {
                throw new Error('Cannot find Node element with node id: [' + node.id + ']');
            }
            return (/** @type {?} */ (selector));
        };
        /**
         * @param {?} port
         * @return {?}
         */
        DiagramEngine.prototype.getNodePortElement = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            /** @type {?} */
            var selector = this.canvas$.getValue().querySelector("[data-nodeid=\"" + port.getParent().id + "\"] [data-portid=\"" + port.id + "\"]");
            if (selector === null) {
                throw new Error('Cannot find Node Port element with node id: [' + port.getParent().id + '] and port id: [' + port.id + ']');
            }
            return (/** @type {?} */ (selector));
        };
        /**
         * @param {?} port
         * @return {?}
         */
        DiagramEngine.prototype.getPortCenter = /**
         * @param {?} port
         * @return {?}
         */
        function (port) {
            /** @type {?} */
            var sourceElement = this.getNodePortElement(port);
            /** @type {?} */
            var sourceRect = sourceElement.getBoundingClientRect();
            /** @type {?} */
            var rel = this.getRelativePoint(sourceRect.left, sourceRect.top);
            return {
                x: sourceElement.offsetWidth / 2 + (rel.x - this.diagramModel.getOffsetX()) / (this.diagramModel.getZoomLevel() / 100.0),
                y: sourceElement.offsetHeight / 2 + (rel.y - this.diagramModel.getOffsetY()) / (this.diagramModel.getZoomLevel() / 100.0)
            };
        };
        /**
         * Calculate rectangular coordinates of the port passed in.
         */
        /**
         * Calculate rectangular coordinates of the port passed in.
         * @param {?} port
         * @return {?}
         */
        DiagramEngine.prototype.getPortCoords = /**
         * Calculate rectangular coordinates of the port passed in.
         * @param {?} port
         * @return {?}
         */
        function (port) {
            /** @type {?} */
            var sourceElement = this.getNodePortElement(port);
            /** @type {?} */
            var sourceRect = (/** @type {?} */ (sourceElement.getBoundingClientRect()));
            /** @type {?} */
            var canvasRect = (/** @type {?} */ (this.canvas$.getValue().getBoundingClientRect()));
            return {
                x: (sourceRect.x - this.diagramModel.getOffsetX()) / (this.diagramModel.getZoomLevel() / 100.0) - canvasRect.left,
                y: (sourceRect.y - this.diagramModel.getOffsetY()) / (this.diagramModel.getZoomLevel() / 100.0) - canvasRect.top,
                width: sourceRect.width,
                height: sourceRect.height
            };
        };
        /**
         * Determine the width and height of the node passed in.
         * It currently assumes nodes have a rectangular shape, can be overriden for customised shapes.
         */
        /**
         * Determine the width and height of the node passed in.
         * It currently assumes nodes have a rectangular shape, can be overriden for customised shapes.
         * @param {?} node
         * @return {?}
         */
        DiagramEngine.prototype.getNodeDimensions = /**
         * Determine the width and height of the node passed in.
         * It currently assumes nodes have a rectangular shape, can be overriden for customised shapes.
         * @param {?} node
         * @return {?}
         */
        function (node) {
            if (!this.canvas$.getValue()) {
                return {
                    width: 0,
                    height: 0
                };
            }
            /** @type {?} */
            var nodeElement = this.getNodeElement(node);
            /** @type {?} */
            var nodeRect = nodeElement.getBoundingClientRect();
            return {
                width: nodeRect.width,
                height: nodeRect.height
            };
        };
        /**
         * @param {?} canvas
         * @return {?}
         */
        DiagramEngine.prototype.setCanvas = /**
         * @param {?} canvas
         * @return {?}
         */
        function (canvas) {
            this.canvas$.next(canvas);
        };
        /**
         * @param {?} event
         * @return {?}
         */
        DiagramEngine.prototype.getRelativeMousePoint = /**
         * @param {?} event
         * @return {?}
         */
        function (event) {
            /** @type {?} */
            var point = this.getRelativePoint(event.clientX, event.clientY);
            return {
                x: (point.x - this.diagramModel.getOffsetX()) / (this.diagramModel.getZoomLevel() / 100.0),
                y: (point.y - this.diagramModel.getOffsetY()) / (this.diagramModel.getZoomLevel() / 100.0)
            };
        };
        /**
         * @param {?} x
         * @param {?} y
         * @return {?}
         */
        DiagramEngine.prototype.getRelativePoint = /**
         * @param {?} x
         * @param {?} y
         * @return {?}
         */
        function (x, y) {
            /** @type {?} */
            var canvasRect = this.canvas$.getValue().getBoundingClientRect();
            return { x: x - canvasRect.left, y: y - canvasRect.top };
        };
        /**
         * @return {?}
         */
        DiagramEngine.prototype.getDiagramModel = /**
         * @return {?}
         */
        function () {
            return this.diagramModel;
        };
        /**
         * @param {?} model
         * @return {?}
         */
        DiagramEngine.prototype.isModelLocked = /**
         * @param {?} model
         * @return {?}
         */
        function (model) {
            if (this.diagramModel.getLocked()) {
                return true;
            }
            return model.getLocked();
        };
        /**
         * auto arrange the graph
         */
        /**
         * auto arrange the graph
         * @return {?}
         */
        DiagramEngine.prototype.autoArrange = /**
         * auto arrange the graph
         * @return {?}
         */
        function () { };
        /**
         * fit the canvas zoom levels to the elements contained.
         * @param additionalZoomFactor allow for further zooming out to make sure edges doesn't cut
         */
        /**
         * fit the canvas zoom levels to the elements contained.
         * @param {?=} additionalZoomFactor allow for further zooming out to make sure edges doesn't cut
         * @return {?}
         */
        DiagramEngine.prototype.zoomToFit = /**
         * fit the canvas zoom levels to the elements contained.
         * @param {?=} additionalZoomFactor allow for further zooming out to make sure edges doesn't cut
         * @return {?}
         */
        function (additionalZoomFactor) {
            var _this = this;
            if (additionalZoomFactor === void 0) { additionalZoomFactor = 0.005; }
            this.canvas$
                .pipe(operators.filter(Boolean), operators.take(1), operators.delay(0))
                .subscribe((/**
             * @param {?} canvas
             * @return {?}
             */
            function (canvas) {
                /** @type {?} */
                var xFactor = canvas.clientWidth / canvas.scrollWidth;
                /** @type {?} */
                var yFactor = canvas.clientHeight / canvas.scrollHeight;
                /** @type {?} */
                var zoomFactor = xFactor < yFactor ? xFactor : yFactor;
                _this.diagramModel.setZoomLevel(_this.diagramModel.getZoomLevel() * (zoomFactor - additionalZoomFactor));
                _this.diagramModel.setOffset(0, 0);
            }));
        };
        DiagramEngine.decorators = [
            { type: core.Injectable, args: [{ providedIn: NgxDiagramsModule },] }
        ];
        /** @nocollapse */
        DiagramEngine.ctorParameters = function () { return [
            { type: core.ComponentFactoryResolver },
            { type: core.RendererFactory2 }
        ]; };
        /** @nocollapse */ DiagramEngine.ngInjectableDef = core.ɵɵdefineInjectable({ factory: function DiagramEngine_Factory() { return new DiagramEngine(core.ɵɵinject(core.ComponentFactoryResolver), core.ɵɵinject(core.RendererFactory2)); }, token: DiagramEngine, providedIn: NgxDiagramsModule });
        return DiagramEngine;
    }());
    if (false) {
        /**
         * @type {?}
         * @private
         */
        DiagramEngine.prototype._renderer;
        /**
         * @type {?}
         * @private
         */
        DiagramEngine.prototype.nodeFactories;
        /**
         * @type {?}
         * @private
         */
        DiagramEngine.prototype.labelFactories;
        /**
         * @type {?}
         * @private
         */
        DiagramEngine.prototype.linkFactories;
        /**
         * @type {?}
         * @private
         */
        DiagramEngine.prototype.portFactories;
        /**
         * @type {?}
         * @private
         */
        DiagramEngine.prototype.canvas$;
        /** @type {?} */
        DiagramEngine.prototype.diagramModel;
        /**
         * @type {?}
         * @private
         */
        DiagramEngine.prototype.resolver;
        /**
         * @type {?}
         * @private
         */
        DiagramEngine.prototype.rendererFactory;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/components/default-link/default-link.module.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultLinkModule = /** @class */ (function () {
        function DefaultLinkModule() {
        }
        DefaultLinkModule.decorators = [
            { type: core.NgModule, args: [{
                        declarations: [DefaultLinkComponent],
                        imports: [common.CommonModule],
                        providers: [],
                        exports: [DefaultLinkComponent],
                        entryComponents: [DefaultLinkComponent]
                    },] }
        ];
        return DefaultLinkModule;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/components/default-node/default-node.module.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultNodeModule = /** @class */ (function () {
        function DefaultNodeModule() {
        }
        DefaultNodeModule.decorators = [
            { type: core.NgModule, args: [{
                        declarations: [DefaultNodeComponent],
                        imports: [common.CommonModule],
                        providers: [],
                        exports: [DefaultNodeComponent],
                        entryComponents: [DefaultNodeComponent]
                    },] }
        ];
        return DefaultNodeModule;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/components/default-port/default-port.module.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultPortModule = /** @class */ (function () {
        function DefaultPortModule() {
        }
        DefaultPortModule.decorators = [
            { type: core.NgModule, args: [{
                        declarations: [DefaultPortComponent],
                        imports: [common.CommonModule],
                        providers: [],
                        exports: [DefaultPortComponent],
                        entryComponents: [DefaultPortComponent]
                    },] }
        ];
        return DefaultPortModule;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/components/default-label/default-label.module.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var DefaultLabelModule = /** @class */ (function () {
        function DefaultLabelModule() {
        }
        DefaultLabelModule.decorators = [
            { type: core.NgModule, args: [{
                        declarations: [DefaultLabelComponent],
                        imports: [common.CommonModule],
                        providers: [],
                        exports: [DefaultLabelComponent],
                        entryComponents: [DefaultLabelComponent]
                    },] }
        ];
        return DefaultLabelModule;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/components/index.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/models/index.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/factories/index.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/defaults/index.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/models/move-selection.model.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @record
     */
    function SelectionModel() { }
    if (false) {
        /** @type {?} */
        SelectionModel.prototype.model;
        /** @type {?} */
        SelectionModel.prototype.initialX;
        /** @type {?} */
        SelectionModel.prototype.initialY;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/models/index.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/interfaces/coords.interface.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @record
     */
    function Coords() { }
    if (false) {
        /** @type {?} */
        Coords.prototype.x;
        /** @type {?} */
        Coords.prototype.y;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/interfaces/dimensions.interface.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @record
     */
    function Dimensions() { }
    if (false) {
        /** @type {?} */
        Dimensions.prototype.width;
        /** @type {?} */
        Dimensions.prototype.height;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/interfaces/index.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/factories/index.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/utils/path-finding.util.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    // import * as PF from 'pathfinding';
    // import { DiagramEngine } from '../services/engine.service';
    /** @type {?} */
    var ROUTING_SCALING_FACTOR = 5;
    var PathFinding = /** @class */ (function () {
        function PathFinding() {
        }
        return PathFinding;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/utils/index.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * Generated from: lib/services/dagre-engine.service.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @record
     */
    function DagreEngineOptions() { }
    if (false) {
        /** @type {?|undefined} */
        DagreEngineOptions.prototype.graph;
        /** @type {?|undefined} */
        DagreEngineOptions.prototype.layout;
        /**
         * Will also layout links
         * @type {?|undefined}
         */
        DagreEngineOptions.prototype.includeLinks;
    }
    var DagreEngine = /** @class */ (function () {
        function DagreEngine() {
        }
        /**
         * @param {?} model
         * @param {?=} options
         * @return {?}
         */
        DagreEngine.prototype.redistribute = /**
         * @param {?} model
         * @param {?=} options
         * @return {?}
         */
        function (model, options) {
            if (options === void 0) { options = {}; }
            /** @type {?} */
            var g = new dagre.graphlib.Graph({ multigraph: true });
            g.setGraph(options.graph || {});
            g.setDefaultEdgeLabel((/**
             * @return {?}
             */
            function () {
                return {};
            }));
            /** @type {?} */
            var processedlinks = {};
            // set nodes
            Object.values(model.getNodes()).forEach((/**
             * @param {?} node
             * @return {?}
             */
            function (node) {
                g.setNode(node.id, { width: node.getWidth(), height: node.getHeight() });
            }));
            Object.values(model.getLinks()).forEach((/**
             * @param {?} link
             * @return {?}
             */
            function (link) {
                // set edges
                if (link.getSourcePort() && link.getTargetPort()) {
                    processedlinks[link.id] = true;
                    g.setEdge({
                        v: link.getSourcePort().getNode().id,
                        w: link.getTargetPort().getNode().id,
                        name: link.id
                    });
                }
            }));
            // layout the graph
            dagre.layout(g, options.layout);
            g.nodes().forEach((/**
             * @param {?} v
             * @return {?}
             */
            function (v) {
                var _a = g.node(v), x = _a.x, y = _a.y;
                model.getNode(v).setCoords({ x: x, y: y });
            }));
            // also include links?
            if (options.includeLinks) {
                g.edges().forEach((/**
                 * @param {?} e
                 * @return {?}
                 */
                function (e) {
                    /** @type {?} */
                    var edge = g.edge(e);
                    /** @type {?} */
                    var link = model.getLink(e.name);
                    /** @type {?} */
                    var points = [link.getFirstPoint()];
                    for (var i = 1; i < edge.points.length - 2; i++) {
                        points.push(new PointModel(link, { x: edge.points[i].x, y: edge.points[i].y }));
                    }
                    link.setPoints(points.concat(link.getLastPoint()));
                }));
            }
        };
        DagreEngine.decorators = [
            { type: core.Injectable }
        ];
        /** @nocollapse */
        DagreEngine.ctorParameters = function () { return []; };
        return DagreEngine;
    }());

    exports.AbstractFactory = AbstractFactory;
    exports.AbstractLabelFactory = AbstractLabelFactory;
    exports.AbstractLinkFactory = AbstractLinkFactory;
    exports.AbstractNodeFactory = AbstractNodeFactory;
    exports.AbstractPortFactory = AbstractPortFactory;
    exports.BaseAction = BaseAction;
    exports.BaseEvent = BaseEvent;
    exports.BaseModel = BaseModel;
    exports.DagreEngine = DagreEngine;
    exports.DefaultLabelFactory = DefaultLabelFactory;
    exports.DefaultLabelModel = DefaultLabelModel;
    exports.DefaultLabelModule = DefaultLabelModule;
    exports.DefaultLinkFactory = DefaultLinkFactory;
    exports.DefaultLinkModel = DefaultLinkModel;
    exports.DefaultLinkModule = DefaultLinkModule;
    exports.DefaultNodeFactory = DefaultNodeFactory;
    exports.DefaultNodeModel = DefaultNodeModel;
    exports.DefaultNodeModule = DefaultNodeModule;
    exports.DefaultPortFactory = DefaultPortFactory;
    exports.DefaultPortModel = DefaultPortModel;
    exports.DefaultPortModule = DefaultPortModule;
    exports.DiagramEngine = DiagramEngine;
    exports.DiagramModel = DiagramModel;
    exports.LOG_LEVEL = LOG_LEVEL;
    exports.LabelModel = LabelModel;
    exports.LinkCreatedAction = LinkCreatedAction;
    exports.LinkModel = LinkModel;
    exports.LockEvent = LockEvent;
    exports.MoveCanvasAction = MoveCanvasAction;
    exports.MoveItemsAction = MoveItemsAction;
    exports.NgxDiagramComponent = NgxDiagramComponent;
    exports.NgxDiagramsModule = NgxDiagramsModule;
    exports.NodeModel = NodeModel;
    exports.PaintedEvent = PaintedEvent;
    exports.ParentChangeEvent = ParentChangeEvent;
    exports.PathFinding = PathFinding;
    exports.PointModel = PointModel;
    exports.PortModel = PortModel;
    exports.ROUTING_SCALING_FACTOR = ROUTING_SCALING_FACTOR;
    exports.SelectingAction = SelectingAction;
    exports.SelectionEvent = SelectionEvent;
    exports.UID = UID;
    exports.arrayToMap = arrayToMap;
    exports.coerceArray = coerceArray;
    exports.enableDiagramProdMode = enableDiagramProdMode;
    exports.generateCurvePath = generateCurvePath;
    exports.generateLinePath = generateLinePath;
    exports.isArray = isArray;
    exports.isDev = isDev;
    exports.isFunction = isFunction;
    exports.isNil = isNil;
    exports.isString = isString;
    exports.log = log;
    exports.mapToArray = mapToArray;
    exports.setLogLevel = setLogLevel;
    exports.withLog = withLog;
    exports.ɵa = DefaultLinkComponent;
    exports.ɵb = DefaultLinkModel;
    exports.ɵc = LinkModel;
    exports.ɵd = BaseModel;
    exports.ɵe = BaseEntity;
    exports.ɵg = DefaultNodeComponent;
    exports.ɵh = DefaultNodeModel;
    exports.ɵi = NodeModel;
    exports.ɵj = DefaultPortComponent;
    exports.ɵk = DefaultPortModel;
    exports.ɵl = PortModel;
    exports.ɵm = DefaultLabelComponent;
    exports.ɵn = DefaultLabelModel;
    exports.ɵo = LabelModel;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=ngx-diagrams.umd.js.map