summaryrefslogtreecommitdiffstats
path: root/cds-ui/designer-client/src/app/modules
diff options
context:
space:
mode:
Diffstat (limited to 'cds-ui/designer-client/src/app/modules')
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html33
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts328
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/palette.function.element.ts108
3 files changed, 376 insertions, 93 deletions
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
index 9021bf5e9..c0ea41dbc 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
@@ -73,7 +73,7 @@
<button type="button" class="btn">Insert Custom</button>
<button type="button" class="btn">Import Action</button>
</div>
- </div><!--
+ </div>
<div class="col-12 actionsList">
<b>Select from other packages:</b>
<div class="actions-scroll">
@@ -107,13 +107,32 @@
<button type="button" class="btn btn-secondary">Cancel</button>
</div>
</div>
--->
- <app-actions class="col-12 actionsList"></app-actions>
- <app-functions></app-functions>
+
+ <h1 class="col-12">Functions</h1>
+ <div id="palette-paper" class="col-12 componentsList">
+ <b>Drag and drop function to Action’s box</b>
+ <ul class="list-group actions-scroll">
+ <!-- <li class="list-group-item" *ngFor="let function of viewedFunctions">
+ <p class="compType-1">{{function.modelName}}</p>
+ </li> -->
+ <li class="list-group-item">
+ <p class="compType-2">component-netconf-executor</p>
+ </li>
+ <li class="list-group-item">
+ <p class="compType-3">component-remote-ansible-executor</p>
+ </li>
+ <li class="list-group-item">
+ <p class="compType-4">dg-generic</p>
+ </li>
+ <li class="list-group-item">
+ <p class="compType-1">component-resource-resolution</p>
+ </li>
+ </ul>
+ </div>
</div>
</ng-sidebar>
<!-- Page content -->
- <div ng-sidebar-content>
+ <div ng-sidebar-content id="board-paper">
<button class="rotate" (click)="_toggleSidebar1()">
<span>
Controller
@@ -144,7 +163,7 @@
<button type="button" class="btn btn-secondary topologyView">Source</button>
</div>
</div>
- <div class="card actionContainer">
+ <!-- <div class="card actionContainer">
<div class="card-header">
<span>Action 1</span>
</div>
@@ -170,7 +189,7 @@
<p>component-netconf-executor</p>
</a>
</div>
- </div>
+ </div> -->
<!-- <button (click)="_toggleSidebar2()" style="float:right;">Toggle sidebar right</button> -->
</div>
<!-- Attribute SideBar -->
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
index 6d36a961f..f3e592cdb 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
@@ -1,4 +1,7 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
+import * as _ from 'lodash';
+import * as joint from 'jointjs';
+import './palette.function.element';
@Component({
selector: 'app-designer',
@@ -10,6 +13,13 @@ export class DesignerComponent implements OnInit {
private controllerSideBar: boolean;
private attributesSideBar: boolean;
+
+ boardGraph: joint.dia.Graph;
+ boardPaper: joint.dia.Paper;
+
+ paletteGraph: joint.dia.Graph;
+ palettePaper: joint.dia.Paper;
+
constructor() {
this.controllerSideBar = true;
this.attributesSideBar = false;
@@ -22,101 +32,247 @@ export class DesignerComponent implements OnInit {
}
+ /**
+ * - There is a board (main paper) that will the action and function selected from the palette
+ * itmes in this board will be used to create tosca workflow and node templates
+ * - There is also palette , whis contains all the possible functions and actions
+ * that can be dragged into the board
+ * - There is also a fly paper , which is temporarliy paper created on the fly
+ * when items is dragged from the palette- and it's deleted when the item is dropped over
+ * the board.
+ * for more info about the drag and drop algorithem used please visit the following link:
+ * https://stackoverflow.com/a/36932973/1340034
+ */
+
ngOnInit() {
+ this.initializeBoard();
+ this.initializePalette();
+ // this.createEditBarOverThePaper();
+ const list = [
+ { modelName: 'component-netconf-executor'},
+ { modelName: 'component-remote-ansible-executor' },
+ { modelName: 'dg-generic' },
+ { modelName: 'component-resource-resolution' }];
+
+ const cells = this.buildPaletteGraphFromList(list);
+ this.paletteGraph.resetCells(cells);
+
+ let idx = 0;
+ cells.forEach(cell => {
+ console.log(cell);
+ cell.translate(5, (cell.attributes.size.height + 5) * idx++);
+
+ });
+ this.stencilPaperEventListeners();
+ }
+
+ initializePalette() {
+ if (!this.paletteGraph) {
+ this.paletteGraph = new joint.dia.Graph();
+ this.palettePaper = new joint.dia.Paper({
+ el: $('#palette-paper'),
+ model: this.paletteGraph,
+ height: 300,
+ width: 300,
+ gridSize: 1,
+ interactive: false
+ });
+ }
+ }
+
+ initializeBoard() {
+ if (!this.boardGraph) {
+ this.boardGraph = new joint.dia.Graph();
+ this.boardPaper = new joint.dia.Paper({
+ el: $('#board-paper'),
+ model: this.boardGraph,
+ height: 720,
+ width: 1200,
+ gridSize: 10,
+ drawGrid: true,
+ background: {
+ color: 'rgba(0, 255, 0, 0.3)'
+ },
+ cellViewNamespace: joint.shapes
+ });
+
+ this.boardPaper.on('all', element => {
+ // console.log(element);
+ });
+
+ this.boardPaper.on('link:pointerdown', link => {
+ console.log(link);
+ });
+
+ this.boardPaper.on('element:pointerdown', element => {
+ // this.modelSelected.emit(element.model.get('model'));
+ });
+
+ this.boardPaper.on('blank:pointerclick', () => {
+ // this.selectedModel = undefined;
+ });
+ }
+ }
+
+ buildPaletteGraphFromList(list: any) {
+ const elements = [];
+
+ console.log(list);
+ list.forEach(element => {
+ elements.push(this.createFuctionElementForPalette(element.modelName));
+ });
+
+ return elements;
+ }
- this.attachEditorBarToCanvas();
+
+ createFuctionElementForPalette(label: string) {
+ const element = new joint.shapes.app.FunctionElement({
+ id: label});
+ element.attr('#label/text', label);
+ return element;
}
- attachEditorBarToCanvas() {
- this.graph = new joint.dia.Graph,
- this.paper = new joint.dia.Paper({
- el: $('#paper'),
- model: this.graph,
- height: 720,
- width: 1200,
- gridSize: 2,
- drawGrid: true,
- cellViewNamespace: joint.shapes
+ stencilPaperEventListeners() {
+ this.palettePaper.on('cell:pointerdown', (draggedCell, pointerDownEvent, x, y) => {
+ console.log('pointerdown 2');
+
+ $('body').append(`
+ <div id="flyPaper"
+ style="position:fixed;z-index:100;opacity:.7;pointer-event:none;background-color: transparent !important;"></div>`
+ );
+ const flyGraph = new joint.dia.Graph();
+ const flyPaper = new joint.dia.Paper({
+ el: $('#flyPaper'),
+ model: flyGraph,
+ interactive: true
+ });
+ const flyShape = draggedCell.model.clone();
+ const pos = draggedCell.model.position();
+ const offset = {
+ x: x - pos.x,
+ y: y - pos.y
+ };
+
+ flyShape.position(0, 0);
+ flyGraph.addCell(flyShape);
+ $('#flyPaper').offset({
+ left: pointerDownEvent.pageX - offset.x,
+ top: pointerDownEvent.pageY - offset.y
+ });
+ $('body').on('mousemove.fly', mouseMoveEvent => {
+ $('#flyPaper').offset({
+ left: mouseMoveEvent.pageX - offset.x,
+ top: mouseMoveEvent.pageY - offset.y
+ });
});
- this.paper.setGrid({
- name: 'dot',
- args:
- { color: 'black', thickness: 2, scaleFactor: 8 }
+ $('body').on('mouseup.fly', mouseupEvent => {
+ const mouseupX = mouseupEvent.pageX;
+ const mouseupY = mouseupEvent.pageY;
+ const target = this.boardPaper.$el.offset();
+ // Dropped over paper ?
+ if (mouseupX > target.left &&
+ mouseupX < target.left + this.boardPaper.$el.width() &&
+ mouseupY > target.top && y < target.top + this.boardPaper.$el.height()) {
+ const clonedShape = flyShape.clone();
- }).drawGrid();
+ clonedShape.position(mouseupX - target.left - offset.x, mouseupY - target.top - offset.y);
+ this.boardGraph.addCell(clonedShape);
+ const cellViewsBelow =
+ this.boardPaper.findViewsFromPoint(clonedShape.getBBox().center());
+ if (cellViewsBelow.length) {
+ let cellViewBelow;
+ cellViewsBelow.forEach( cellItem => {
+ if (cellItem.model.id !== clonedShape.id) {
+ cellViewBelow = cellItem;
+ }
+ });
+ // Prevent recursive embedding.
+ if (cellViewBelow && cellViewBelow.model.get('parent') !== clonedShape.id) {
+ cellViewBelow.model.embed(clonedShape);
+ }
+ }
- joint.shapes["html"] = {};
- joint.shapes["html"].Element = joint.shapes.basic.Rect.extend({
- defaults: joint.util.deepSupplement({
- type: 'html.Element'
- }, joint.shapes.basic.Rect.prototype.defaults)
+ }
+ $('body').off('mousemove.fly').off('mouseup.fly');
+ // flyShape.remove();
+ $('#flyPaper').remove();
+ });
});
+ }
+
+ /**
+ * this is a way to add the button like zoom in , zoom out , and source over jointjs paper
+ * may be used if no other way is found
+ */
+ // createEditBarOverThePaper() {
+ // joint.shapes["html"] = {};
+ // joint.shapes["html"].Element = joint.shapes.basic.Rect.extend({
+ // defaults: joint.util.deepSupplement({
+ // type: 'html.Element'
+ // }, joint.shapes.basic.Rect.prototype.defaults)
+ // });
+ // joint.shapes["html"].ElementView = joint.dia.ElementView.extend({
+
+ // template: [
+ // '<div>',
+ // '<div id="editbar" class="editBar text-center">',
+ // '<div class="btn-group mr-2" role="group" aria-label="First group">',
+ // '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Undo">',
+ // '<img src="/assets/img/icon-undoActive.svg">',
+ // '</button>',
+ // '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Redo">',
+ // '<img src="/assets/img/icon-redo.svg">',
+ // '</button>',
+ // '</div>',
+ // '<div class="btn-group mr-2" role="group" aria-label="Second group">',
+ // '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Zoom Out">',
+ // '<img src="/assets/img/icon-zoomOut.svg">',
+ // '</button>',
+ // '<button type="button" class="btn btn-secondary pl-0 pr-0">100%</button>',
+ // '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Zoom In">',
+ // '<img src="/assets/img/icon-zoomIn.svg">',
+ // '</button>',
+ // '</div>',
+ // '<div class="btn-group viewBtns" role="group" aria-label="Third group">',
+ // '<button type="button" class="btn btn-secondary topologySource active">View</button>',
+ // '<button type="button" class="btn btn-secondary topologyView">Source</button>',
+ // '</div>',
+ // '</div>',
+ // '</div>'
+ // ].join(''),
+ // initialize: function () {
+ // _.bindAll(this, 'updateBox');
+ // joint.dia.ElementView.prototype.initialize.apply(this, arguments);
+
+ // this.$box = $(_.template(this.template)());
+ // // Prevent paper from handling pointerdown.
+ // this.$box.find('input,select').on('mousedown click', function (evt) {
+ // evt.stopPropagation();
+ // });
+ // this.model.on('change', this.updateBox, this);
+ // this.updateBox();
+ // },
+ // render: function () {
+ // joint.dia.ElementView.prototype.render.apply(this, arguments);
+ // this.paper.$el.prepend(this.$box);
+ // this.updateBox();
+ // return this;
+ // },
+ // updateBox: function () {
+ // // Set the position and dimension of the box so that it covers the JointJS element.
+ // var bbox = this.model.getBBox();
+ // this.$box.css({
+ // width: bbox.width,
+ // height: bbox.height,
+ // left: bbox.x,
+ // top: bbox.y,
+ // transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)'
+ // });
+ // }
+ // });
- joint.shapes["html"].ElementView = joint.dia.ElementView.extend({
-
- template: [
- '<div>',
- '<div id="editbar" class="editBar text-center">',
- '<div class="btn-group mr-2" role="group" aria-label="First group">',
- '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Undo">',
- '<img src="/assets/img/icon-undoActive.svg">',
- '</button>',
- '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Redo">',
- '<img src="/assets/img/icon-redo.svg">',
- '</button>',
- '</div>',
- '<div class="btn-group mr-2" role="group" aria-label="Second group">',
- '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Zoom Out">',
- '<img src="/assets/img/icon-zoomOut.svg">',
- '</button>',
- '<button type="button" class="btn btn-secondary pl-0 pr-0">100%</button>',
- '<button type="button" class="btn btn-secondary tooltip-bottom" data-tooltip="Zoom In">',
- '<img src="/assets/img/icon-zoomIn.svg">',
- '</button>',
- '</div>',
- '<div class="btn-group viewBtns" role="group" aria-label="Third group">',
- '<button type="button" class="btn btn-secondary topologySource active">View</button>',
- '<button type="button" class="btn btn-secondary topologyView">Source</button>',
- '</div>',
- '</div>',
- '</div>'
- ].join(''),
-
- initialize: function() {
- _.bindAll(this, 'updateBox');
- joint.dia.ElementView.prototype.initialize.apply(this, arguments);
-
- this.$box = $(_.template(this.template)());
- // Prevent paper from handling pointerdown.
- this.$box.find('input,select').on('mousedown click', function(evt) {
- evt.stopPropagation();
- });
- this.model.on('change', this.updateBox, this);
-
- this.updateBox();
- },
- render: function() {
- joint.dia.ElementView.prototype.render.apply(this, arguments);
- this.paper.$el.prepend(this.$box);
- this.updateBox();
- return this;
- },
- updateBox: function() {
- // Set the position and dimension of the box so that it covers the JointJS element.
- var bbox = this.model.getBBox();
- this.$box.css({
- width: bbox.width,
- height: bbox.height,
- left: bbox.x,
- top: bbox.y,
- transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)'
- });
- }
- });
-
- var el1 = new joint.shapes["html"].Element({});
- this.graph.addCells([el1]);
- }
+ // }
}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/palette.function.element.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/palette.function.element.ts
new file mode 100644
index 000000000..6f0ba8b5d
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/palette.function.element.ts
@@ -0,0 +1,108 @@
+import * as joint from 'jointjs';
+
+/**
+ * The function element in the palette should contain image and text with style- that is why
+ * it requires a custom element.
+ * The following code declares a type for typescript to accept "app.FunctionElement"
+ * and create an element implementation , then joins the app module inside shapes module for javascript to work.
+ * please refer to the official example :
+ * https://github.com/clientIO/joint/blob/master/demo/ts-demo/custom.ts
+ */
+
+declare module 'jointjs' {
+ namespace shapes {
+ // add new module called "app" under the already existing "shapes" modeule inside jointjs
+ export namespace app {
+ class FunctionElement extends joint.shapes.standard.Rectangle {
+ }
+ }
+ }
+}
+
+const rectWidth = 260;
+const rectHeight = 60;
+// custom element implementation
+// https://resources.jointjs.com/tutorials/joint/tutorials/custom-elements.html#markup
+const FunctionElement = joint.shapes.standard.Rectangle.define('app.FunctionElement', {
+ size: { width: rectWidth, height: rectHeight },
+ attrs: {
+ icon: {
+ 'xlink:href': 'http://placehold.it/16x16'
+ }
+ }
+}, {
+ markup:
+ `<defs>
+ <rect id="path-1" x="0" y="0" width="280" height="40" rx="2"></rect>
+ <filter x="-3.6%" y="-20.0%" width="107.1%" height="150.0%" filterUnits="objectBoundingBox" id="filter-2">
+ <feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+ <feGaussianBlur stdDeviation="3" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+ <feColorMatrix
+ values="0 0 0 0 0.185477813 0 0 0 0 0.324045386 0 0 0 0 0.59162415 0 0 0 0.15 0"
+ type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+ </filter>
+ </defs>
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="7.1-Designer" transform="translate(-14.000000, -618.000000)">
+ <g id="controller" transform="translate(0.000000, 60.000000)">
+ <g id="functions" transform="translate(0.000000, 479.000000)">
+ <g id="list" transform="translate(8.000000, 51.000000)">
+ <g id="1" transform="translate(12.000000, 32.000000)">
+ <g id="Card">
+ <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
+ <use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
+ </g>
+ <g id="drag-menu" transform="translate(20.000000, 15.000000)" fill="#C3CDDB" fill-rule="nonzero">
+ <g id="left">
+ <circle id="1" cx="0.8" cy="0.8" r="1"></circle>
+ <circle id="2" cx="0.8" cy="3.8" r="1"></circle>
+ <circle id="3" cx="0.8" cy="6.8" r="1"></circle>
+ <circle id="4" cx="0.8" cy="9.8" r="1"></circle>
+ </g>
+ <g id="right" transform="translate(2.400000, 0.000000)">
+ <circle id="1" cx="0.8" cy="0.8" r="1"></circle>
+ <circle id="2" cx="0.8" cy="3.8" r="1"></circle>
+ <circle id="3" cx="0.8" cy="6.8" r="1"></circle>
+ <circle id="4" cx="0.8" cy="9.8" r="1"></circle>
+ </g>
+ </g>
+ <g id="txt" transform="translate(35.000000, 10.000000)" fill="#1B3E6F">
+ <g id="browser" fill-rule="nonzero">
+ <path d="M21.0000051,0.39034364 C20.9994786,0.29701568 20.9615913,0.207858845 20.8946802,0.142685701 C20.8275953,0.0776863856 20.7373957,0.0424059852 20.6440678,0.044547851 L0.355932203,0.044547851 C0.262604288,0.0422321924 0.172230877,0.0776863856 0.105319805,0.142685701 C0.0384086886,0.207685061 0.000347590042,0.29701568 -5.13814986e-06,0.39034364 L-5.13814986e-06,17.159999 C-0.00104277013,17.3591681 0.156763131,17.5232306 0.355932203,17.5298348 L5.23487982,17.5298348 L5.40554656,17.912879 C5.46654862,18.0503509 5.60784396,18.1341201 5.75782903,18.1216069 L6.47264799,18.0673828 C6.73994471,18.3993313 7.04999502,18.6944353 7.39480435,18.9448739 L7.37377516,19.657781 C7.36943029,19.8086351 7.46067267,19.9459332 7.60144661,20.0001573 L9.11989375,20.5863678 C9.2601463,20.6404181 9.41934258,20.6006191 9.51753676,20.4866095 L9.98104809,19.9494091 C10.4045865,19.9888606 10.8310795,19.9779115 11.2520111,19.916388 L11.7481959,20.4339496 C11.8516039,20.5417025 12.0109739,20.573507 12.1477506,20.5137215 L13.639607,19.8609475 C13.7777741,19.8004667 13.8629337,19.6593452 13.8518108,19.5088387 L13.7993247,18.7940198 C14.1316208,18.526723 14.4270723,18.2164989 14.6776847,17.8715158 L15.3911133,17.892545 C15.5409246,17.9005396 15.6790916,17.8115566 15.7336632,17.6718253 L15.7911894,17.5298348 L20.6440678,17.5298348 C20.8432369,17.5230568 21.0010428,17.3591681 21.0000051,17.159999 L21.0000051,4.16360731 C21.0000051,4.16239078 21.0000051,4.16134799 21.0000051,4.16013141 C21.0000051,4.15891483 21.0000051,4.15787209 21.0000051,4.15665551 L21.0000051,0.39034364 Z M20.2881356,0.756529716 L20.2881356,3.82644497 L0.711864407,3.82644497 L0.711864407,0.756529716 L20.2881356,0.756529716 Z M14.5063228,17.1542638 C14.3836235,17.1502665 14.2675285,17.2102257 14.1997484,17.312591 C13.9348848,17.7102341 13.6029363,18.0588668 13.2186755,18.3428479 C13.1204814,18.4153204 13.0664311,18.5333273 13.0752946,18.6549838 L13.1234359,19.3094958 L12.0900506,19.7615367 L11.6362718,19.2882928 C11.5535454,19.2019167 11.4329317,19.1629866 11.3152725,19.1845372 C10.841681,19.2712609 10.3574881,19.2837742 9.88007315,19.2215556 C9.76137118,19.2060878 9.64284296,19.2514483 9.564809,19.3419955 L9.14248708,19.8314023 L8.09293898,19.4266337 L8.11223019,18.7724692 C8.11587988,18.6499437 8.05592061,18.5340225 7.95390296,18.4658948 C7.55625995,18.2010312 7.20762712,17.8690827 6.92364608,17.4848219 C6.85099974,17.3868015 6.73316673,17.3327513 6.61151017,17.3416148 L5.95682436,17.3895822 L5.81605037,17.0678877 C5.80683925,17.0333024 5.79241425,17.0001076 5.77312299,16.9696934 L5.50478348,16.356197 L5.97802733,15.9024182 C6.06440349,15.8196918 6.10333358,15.6990781 6.08178295,15.5815926 C5.99505927,15.1080012 5.98254603,14.6238083 6.04476462,14.1463933 C6.06005858,14.0276913 6.01487188,13.9091631 5.92432468,13.8309554 L5.4349179,13.4086335 L5.8396865,12.3590853 L6.49385096,12.3783766 C6.61655026,12.3823739 6.73264534,12.3224146 6.80042537,12.2200493 C7.06528899,11.8222325 7.3972375,11.4735997 7.7814983,11.1897924 C7.87969248,11.1171461 7.93374269,10.9993131 7.92487918,10.8774828 L7.87673793,10.2229708 L8.91012315,9.77092987 L9.36407574,10.2441737 C9.44680217,10.3305498 9.56741589,10.3694799 9.68490137,10.3479293 C10.1586666,10.2612056 10.6428595,10.2486924 11.1202744,10.310911 C11.2389764,10.326205 11.3575047,10.2810183 11.4357124,10.1904711 L11.8580343,9.7010643 L12.9075824,10.1058329 L12.8882912,10.7598236 C12.8846415,10.8825228 12.944427,10.9984441 13.0466184,11.0665718 C13.4442614,11.3312616 13.7928943,11.6633839 14.0767015,12.0476447 C14.1493479,12.145665 14.2671809,12.1997153 14.3888374,12.1908517 L15.0433495,12.1427105 L15.4955641,13.1760958 L15.0221465,13.6298745 C14.9359441,13.712601 14.897014,13.8332147 14.9183908,13.9507002 C15.0051145,14.4242916 15.0176278,14.9084845 14.9555829,15.3858994 C14.9401152,15.5046014 14.9853019,15.6231297 15.0760229,15.7013374 L15.5654297,16.1236593 L15.1603135,17.1732074 L14.5063228,17.1542638 Z M16.0659593,16.8179704 L16.3195263,16.1533782 C16.3735765,16.0120829 16.3339513,15.8520177 16.2199417,15.7522593 L15.6827413,15.2870101 C15.7223666,14.8632978 15.7114175,14.4362834 15.6498941,14.0151781 L16.1674556,13.5184719 C16.2750347,13.4150639 16.3068392,13.2555201 16.2470538,13.1187434 L15.5944534,11.6268869 C15.5339728,11.4885461 15.3928512,11.4033865 15.2423448,11.4145094 L14.527352,11.4669955 C14.2602291,11.1346994 13.9503525,10.8392479 13.6055432,10.5884617 L13.6265725,9.8750331 C13.6309173,9.72417903 13.5396749,9.58688094 13.398901,9.53248311 L11.8804539,8.94644629 C11.7402013,8.89239608 11.581005,8.93219513 11.4828109,9.04603083 L11.0191257,9.58357886 C10.5955873,9.5439536 10.1689205,9.55490265 9.74798893,9.61642611 L9.25180414,9.09869073 C9.14856992,8.99093782 8.98902606,8.95913336 8.85224942,9.01891885 L7.36039295,9.67151912 C7.2222259,9.73199979 7.13706632,9.87329513 7.1481892,10.0238016 L7.20067532,10.7386206 C6.86837924,11.0059173 6.57310149,11.3161414 6.32231526,11.6609507 L5.60888671,11.6400953 C5.45785885,11.6352291 5.32038697,11.7264715 5.26633675,11.867593 L4.68047373,13.3860401 C4.62642346,13.5262927 4.66622251,13.6854889 4.78005826,13.7836832 L5.31743247,14.2473682 C5.2778072,14.6707329 5.2887563,15.0973997 5.35027972,15.5181574 L4.83289195,16.014516 C4.72496525,16.120531 4.69333454,16.2819865 4.75312002,16.4210226 L4.92343914,16.8179704 L0.711864407,16.8179704 L0.711864407,4.53830938 L20.2881356,4.53830938 L20.2881356,16.8179704 L16.0659593,16.8179704 Z" id="Shape"></path>
+ <path d="M4.59635694,3.39804025 C5.19264767,3.39804025 5.67788336,2.8969892 5.67788336,2.28105964 C5.67788336,1.66513009 5.19282145,1.16425286 4.59635694,1.16425286 C3.99989242,1.16425286 3.51483051,1.66513009 3.51483051,2.28105964 C3.51483051,2.8969892 4.00006621,3.39804025 4.59635694,3.39804025 Z M4.59635694,1.87594344 C4.80021849,1.87594344 4.96601896,2.05773305 4.96601896,2.28088586 C4.96601896,2.50403867 4.80021849,2.68600206 4.59635694,2.68600206 C4.39266917,2.68600206 4.22669492,2.50438623 4.22669492,2.28105964 C4.22669492,2.05773305 4.39266917,1.87594344 4.59635694,1.87594344 Z" id="Shape"></path>
+ <path d="M6.95406017,3.39804025 C7.55017712,3.39804025 8.03541282,2.8969892 8.03541282,2.28105964 C8.03541282,1.66513009 7.55052468,1.16425286 6.95406017,1.16425286 C6.35759566,1.16425286 5.87288136,1.66513009 5.87288136,2.28105964 C5.87288136,2.8969892 6.35776949,3.39804025 6.95406017,3.39804025 Z M6.95406017,1.87594344 C7.15774794,1.87594344 7.32354841,2.05773305 7.32354841,2.28088586 C7.32354841,2.50403867 7.15774794,2.68600206 6.95406017,2.68600206 C6.75019862,2.68600206 6.58474576,2.50438623 6.58474576,2.28105964 C6.58474576,2.05773305 6.75037241,1.87594344 6.95406017,1.87594344 Z" id="Shape"></path>
+ <path d="M2.23865366,3.39804025 C2.83494439,3.39804025 3.32018008,2.8969892 3.32018008,2.28105964 C3.32018008,1.66513009 2.83511817,1.16425286 2.23865366,1.16425286 C1.64218914,1.16425286 1.15730106,1.66530392 1.15730106,2.28105964 C1.15730106,2.89681541 1.64236293,3.39804025 2.23865366,3.39804025 Z M2.23865366,1.87594344 C2.44234142,1.87594344 2.60831568,2.05773305 2.60831568,2.28088586 C2.60831568,2.50403867 2.44234142,2.68600206 2.23865366,2.68600206 C2.03496589,2.68600206 1.86916546,2.50421245 1.86916546,2.28088586 C1.86916546,2.05738548 2.03496589,1.87594344 2.23865366,1.87594344 Z" id="Shape"></path>
+ <path d="M10.5,11.3416893 C8.6087626,11.3416893 7.0755429,12.874909 7.0755429,14.7663202 C7.0755429,16.6575576 8.6087626,18.1907773 10.5,18.1907773 C12.3912374,18.1907773 13.9244571,16.6575576 13.9244571,14.7663202 C13.9223716,12.875778 12.3903684,11.3439486 10.5,11.3416893 Z M10.5,17.4789129 C9.00188692,17.4789129 7.78740731,16.2644333 7.78740731,14.7663202 C7.78740731,13.2680333 9.00188692,12.0535537 10.5,12.0535537 C11.9981131,12.0535537 13.2125927,13.2680333 13.2125927,14.7663202 C13.2110285,16.2637381 11.9974179,17.4771749 10.5,17.4789129 Z" id="Shape"></path>
+ <path d="M10.5,13.0556558 C9.55525026,13.0556558 8.7893356,13.8215704 8.7893356,14.7663202 C8.7893356,15.7108961 9.55525026,16.4768108 10.5,16.4768108 C11.4447497,16.4768108 12.2104906,15.7110699 12.2104906,14.7663202 C12.2094478,13.8220918 11.4442283,13.0568724 10.5,13.0556558 L10.5,13.0556558 Z M10.5,15.7649464 C9.94837458,15.7649464 9.5012,15.3177718 9.5012,14.7663202 C9.5012,14.2146948 9.94837458,13.7675202 10.5,13.7675202 C11.0516254,13.7675202 11.4986262,14.2146948 11.4986262,14.7663202 C11.4981048,15.317598 11.0512778,15.7642512 10.5,15.7649464 L10.5,15.7649464 Z" id="Shape"></path>
+ </g>
+ <text id="function-type" font-family="ArialMT, Arial" font-size="14" font-weight="normal" line-spacing="20">
+ <tspan id="label" x="32" y="13"></tspan>
+ </text>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>`
+ // [{
+ // tagName: 'rect',
+ // selector: 'body',
+ // }, {
+ // tagName: 'text',
+ // selector: 'label'
+ // }, {
+ // tagName: 'image',
+ // selector: 'icon'
+ // }, {
+ // tagName: 'image',
+ // selector: 'drag-handle'
+ // }
+ // ]
+});
+
+Object.assign(joint.shapes, {
+ app: {
+ FunctionElement
+ }
+});