UNPKG

drawio-offline

Version:
1,278 lines (1,105 loc) 151 kB
/** * Copyright (c) 2006-2012, JGraph Ltd */ /** * Construcs a new sidebar for the given editor. */ function Sidebar(editorUi, container) { this.editorUi = editorUi; this.container = container; this.palettes = new Object(); this.taglist = new Object(); this.showTooltips = true; this.graph = editorUi.createTemporaryGraph(this.editorUi.editor.graph.getStylesheet()); this.graph.cellRenderer.minSvgStrokeWidth = this.minThumbStrokeWidth; this.graph.cellRenderer.antiAlias = this.thumbAntiAlias; this.graph.container.style.visibility = 'hidden'; this.graph.foldingEnabled = false; document.body.appendChild(this.graph.container); this.pointerUpHandler = mxUtils.bind(this, function() { this.showTooltips = true; }); mxEvent.addListener(document, (mxClient.IS_POINTER) ? 'pointerup' : 'mouseup', this.pointerUpHandler); this.pointerDownHandler = mxUtils.bind(this, function() { this.showTooltips = false; this.hideTooltip(); }); mxEvent.addListener(document, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', this.pointerDownHandler); this.pointerMoveHandler = mxUtils.bind(this, function(evt) { var src = mxEvent.getSource(evt); while (src != null) { if (src == this.currentElt) { return; } src = src.parentNode; } this.hideTooltip(); }); mxEvent.addListener(document, (mxClient.IS_POINTER) ? 'pointermove' : 'mousemove', this.pointerMoveHandler); // Handles mouse leaving the window this.pointerOutHandler = mxUtils.bind(this, function(evt) { if (evt.toElement == null && evt.relatedTarget == null) { this.hideTooltip(); } }); mxEvent.addListener(document, (mxClient.IS_POINTER) ? 'pointerout' : 'mouseout', this.pointerOutHandler); // Enables tooltips after scroll mxEvent.addListener(container, 'scroll', mxUtils.bind(this, function() { this.showTooltips = true; this.hideTooltip(); })); this.init(); }; /** * Adds all palettes to the sidebar. */ Sidebar.prototype.init = function() { var dir = STENCIL_PATH; this.addSearchPalette(true); this.addGeneralPalette(true); this.addMiscPalette(false); this.addAdvancedPalette(false); this.addBasicPalette(dir); this.setCurrentSearchEntryLibrary('arrows'); this.addStencilPalette('arrows', mxResources.get('arrows'), dir + '/arrows.xml', ';whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;strokeWidth=2'); this.setCurrentSearchEntryLibrary(); this.addUmlPalette(false); this.addBpmnPalette(dir, false); this.setCurrentSearchEntryLibrary('flowchart'); this.addStencilPalette('flowchart', 'Flowchart', dir + '/flowchart.xml', ';whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;strokeWidth=2'); this.setCurrentSearchEntryLibrary(); this.setCurrentSearchEntryLibrary('clipart'); this.addImagePalette('clipart', mxResources.get('clipart'), dir + '/clipart/', '_128x128.png', ['Earth_globe', 'Empty_Folder', 'Full_Folder', 'Gear', 'Lock', 'Software', 'Virus', 'Email', 'Database', 'Router_Icon', 'iPad', 'iMac', 'Laptop', 'MacBook', 'Monitor_Tower', 'Printer', 'Server_Tower', 'Workstation', 'Firewall_02', 'Wireless_Router_N', 'Credit_Card', 'Piggy_Bank', 'Graph', 'Safe', 'Shopping_Cart', 'Suit1', 'Suit2', 'Suit3', 'Pilot1', 'Worker1', 'Soldier1', 'Doctor1', 'Tech1', 'Security1', 'Telesales1'], null, {'Wireless_Router_N': 'wireless router switch wap wifi access point wlan', 'Router_Icon': 'router switch'}); this.setCurrentSearchEntryLibrary(); }; /** * Sets the default font size. */ Sidebar.prototype.collapsedImage = (!mxClient.IS_SVG) ? IMAGE_PATH + '/collapsed.gif' : 'data:image/gif;base64,R0lGODlhDQANAIABAJmZmf///yH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozNUQyRTJFNjZGNUYxMUU1QjZEOThCNDYxMDQ2MzNCQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozNUQyRTJFNzZGNUYxMUU1QjZEOThCNDYxMDQ2MzNCQiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjFERjc3MEUxNkY1RjExRTVCNkQ5OEI0NjEwNDYzM0JCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjFERjc3MEUyNkY1RjExRTVCNkQ5OEI0NjEwNDYzM0JCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAQAAAQAsAAAAAA0ADQAAAhSMj6lrwAjcC1GyahV+dcZJgeIIFgA7'; /** * Sets the default font size. */ Sidebar.prototype.expandedImage = (!mxClient.IS_SVG) ? IMAGE_PATH + '/expanded.gif' : 'data:image/gif;base64,R0lGODlhDQANAIABAJmZmf///yH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxREY3NzBERjZGNUYxMUU1QjZEOThCNDYxMDQ2MzNCQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxREY3NzBFMDZGNUYxMUU1QjZEOThCNDYxMDQ2MzNCQiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjFERjc3MERENkY1RjExRTVCNkQ5OEI0NjEwNDYzM0JCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjFERjc3MERFNkY1RjExRTVCNkQ5OEI0NjEwNDYzM0JCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAQAAAQAsAAAAAA0ADQAAAhGMj6nL3QAjVHIu6azbvPtWAAA7'; /** * */ Sidebar.prototype.searchImage = (!mxClient.IS_SVG) ? IMAGE_PATH + '/search.png' : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAEaSURBVHjabNGxS5VxFIfxz71XaWuQUJCG/gCHhgTD9VpEETg4aMOlQRp0EoezObgcd220KQiXmpretTAHQRBdojlQEJyukPdt+b1ywfvAGc7wnHP4nlZd1yKijQW8xzNc4Su+ZOYfQ3T6/f4YNvEJYzjELXp4VVXVz263+7cR2niBxAFeZ2YPi3iHR/gYERPDwhpOsd6sz8x/mfkNG3iOlWFhFj8y89J9KvzGXER0GuEaD42mgwHqUtoljbcRsTBCeINpfM/MgZLKPpaxFxGbOCqDXmILN7hoJrTKH+axhxmcYRxP0MIDnOBDZv5q1XUNIuJxifJp+UNV7t7BFM6xeic0RMQ4Bpl5W/ol7GISx/eEUUTECrbx+f8A8xhiZht9zsgAAAAASUVORK5CYII='; /** * Specifies if tooltips should be visible. Default is true. */ Sidebar.prototype.enableTooltips = true; /** * Specifies the delay for the tooltip. Default is 16 px. */ Sidebar.prototype.tooltipBorder = 16; /** * Specifies the delay for the tooltip. Default is 300 ms. */ Sidebar.prototype.tooltipDelay = 300; /** * Specifies the delay for the drop target icons. Default is 200 ms. */ Sidebar.prototype.dropTargetDelay = 200; /** * Specifies the URL of the gear image. */ Sidebar.prototype.gearImage = STENCIL_PATH + '/clipart/Gear_128x128.png'; /** * Specifies the width of the thumbnails. */ Sidebar.prototype.thumbWidth = 42; /** * Specifies the height of the thumbnails. */ Sidebar.prototype.thumbHeight = 42; /** * Specifies the width of the thumbnails. */ Sidebar.prototype.minThumbStrokeWidth = 1; /** * Specifies the width of the thumbnails. */ Sidebar.prototype.thumbAntiAlias = false; /** * Specifies the padding for the thumbnails. Default is 3. */ Sidebar.prototype.thumbPadding = (document.documentMode >= 5) ? 2 : 3; /** * Specifies the delay for the tooltip. Default is 2 px. */ Sidebar.prototype.thumbBorder = 2; /* * Experimental smaller sidebar entries */ if (urlParams['sidebar-entries'] != 'large') { Sidebar.prototype.thumbPadding = (document.documentMode >= 5) ? 0 : 1; Sidebar.prototype.thumbBorder = 1; Sidebar.prototype.thumbWidth = 32; Sidebar.prototype.thumbHeight = 30; Sidebar.prototype.minThumbStrokeWidth = 1.3; Sidebar.prototype.thumbAntiAlias = true; } /** * Specifies the size of the sidebar titles. */ Sidebar.prototype.sidebarTitleSize = 9; /** * Specifies if titles in the sidebar should be enabled. */ Sidebar.prototype.sidebarTitles = false; /** * Specifies if titles in the tooltips should be enabled. */ Sidebar.prototype.tooltipTitles = true; /** * Specifies if titles in the tooltips should be enabled. */ Sidebar.prototype.maxTooltipWidth = 400; /** * Specifies if titles in the tooltips should be enabled. */ Sidebar.prototype.maxTooltipHeight = 400; /** * Specifies if stencil files should be loaded and added to the search index * when stencil palettes are added. If this is false then the stencil files * are lazy-loaded when the palette is shown. */ Sidebar.prototype.addStencilsToIndex = true; /** * Specifies the width for clipart images. Default is 80. */ Sidebar.prototype.defaultImageWidth = 80; /** * Specifies the height for clipart images. Default is 80. */ Sidebar.prototype.defaultImageHeight = 80; /** * Adds all palettes to the sidebar. */ Sidebar.prototype.getTooltipOffset = function(elt, bounds) { var b = document.body; var d = document.documentElement; var bottom = Math.max(b.clientHeight || 0, d.clientHeight); var width = bounds.width + 2 * this.tooltipBorder + 4; var height = bounds.height + 2 * this.tooltipBorder; return new mxPoint(this.container.offsetWidth + this.editorUi.splitSize + 10 + this.editorUi.container.offsetLeft, Math.min(bottom - height - 20 /*status bar*/, Math.max(0, (this.editorUi.container.offsetTop + this.container.offsetTop + elt.offsetTop - this.container.scrollTop - height / 2 + 16)))); }; /** * Adds all palettes to the sidebar. */ Sidebar.prototype.showTooltip = function(elt, cells, w, h, title, showLabel) { if (this.enableTooltips && this.showTooltips) { if (this.currentElt != elt) { if (this.thread != null) { window.clearTimeout(this.thread); this.thread = null; } var show = mxUtils.bind(this, function() { // Lazy creation of the DOM nodes and graph instance if (this.tooltip == null) { this.tooltip = document.createElement('div'); this.tooltip.className = 'geSidebarTooltip'; this.tooltip.style.zIndex = mxPopupMenu.prototype.zIndex - 1; document.body.appendChild(this.tooltip); this.graph2 = new Graph(this.tooltip, null, null, this.editorUi.editor.graph.getStylesheet()); this.graph2.resetViewOnRootChange = false; this.graph2.foldingEnabled = false; this.graph2.gridEnabled = false; this.graph2.autoScroll = false; this.graph2.setTooltips(false); this.graph2.setConnectable(false); this.graph2.setEnabled(false); if (!mxClient.IS_SVG) { this.graph2.view.canvas.style.position = 'relative'; } } this.graph2.model.clear(); this.graph2.view.setTranslate(this.tooltipBorder, this.tooltipBorder); if (w > this.maxTooltipWidth || h > this.maxTooltipHeight) { this.graph2.view.scale = Math.round(Math.min(this.maxTooltipWidth / w, this.maxTooltipHeight / h) * 100) / 100; } else { this.graph2.view.scale = 1; } this.tooltip.style.display = 'block'; this.graph2.labelsVisible = (showLabel == null || showLabel); var fo = mxClient.NO_FO; mxClient.NO_FO = Editor.prototype.originalNoForeignObject; // Applies current style for preview var temp = this.graph2.cloneCells(cells); this.editorUi.insertHandler(temp, null, this.graph2.model); this.graph2.addCells(temp); mxClient.NO_FO = fo; var bounds = this.graph2.getGraphBounds(); var width = bounds.width + 2 * this.tooltipBorder + 4; var height = bounds.height + 2 * this.tooltipBorder; this.tooltip.style.overflow = 'visible'; this.tooltip.style.width = width + 'px'; var w2 = width; // Adds title for entry if (this.tooltipTitles && title != null && title.length > 0) { if (this.tooltipTitle == null) { this.tooltipTitle = document.createElement('div'); this.tooltipTitle.style.borderTop = '1px solid gray'; this.tooltipTitle.style.textAlign = 'center'; this.tooltipTitle.style.width = '100%'; this.tooltipTitle.style.overflow = 'hidden'; this.tooltipTitle.style.position = 'absolute'; this.tooltipTitle.style.paddingTop = '6px'; this.tooltipTitle.style.bottom = '6px'; this.tooltip.appendChild(this.tooltipTitle); } else { this.tooltipTitle.innerHTML = ''; } this.tooltipTitle.style.display = ''; mxUtils.write(this.tooltipTitle, title); // Allows for wider labels w2 = Math.min(this.maxTooltipWidth, Math.max(width, this.tooltipTitle.scrollWidth + 4)); var ddy = this.tooltipTitle.offsetHeight + 10; height += ddy; if (mxClient.IS_SVG) { this.tooltipTitle.style.marginTop = (2 - ddy) + 'px'; } else { height -= 6; this.tooltipTitle.style.top = (height - ddy) + 'px'; } } else if (this.tooltipTitle != null && this.tooltipTitle.parentNode != null) { this.tooltipTitle.style.display = 'none'; } // Updates width if label is wider if (w2 > width) { this.tooltip.style.width = w2 + 'px'; } this.tooltip.style.height = height + 'px'; var x0 = -Math.round(bounds.x - this.tooltipBorder) + ((w2 > width) ? (w2 - width) / 2 : 0); var y0 = -Math.round(bounds.y - this.tooltipBorder); var off = this.getTooltipOffset(elt, bounds); var left = off.x; var top = off.y; if (mxClient.IS_SVG) { if (x0 != 0 || y0 != 0) { this.graph2.view.canvas.setAttribute('transform', 'translate(' + x0 + ',' + y0 + ')'); } else { this.graph2.view.canvas.removeAttribute('transform'); } } else { this.graph2.view.drawPane.style.left = x0 + 'px'; this.graph2.view.drawPane.style.top = y0 + 'px'; } // Workaround for ignored position CSS style in IE9 // (changes to relative without the following line) this.tooltip.style.position = 'absolute'; this.tooltip.style.left = left + 'px'; this.tooltip.style.top = top + 'px'; mxUtils.fit(this.tooltip); }); if (this.tooltip != null && this.tooltip.style.display != 'none') { show(); } else { this.thread = window.setTimeout(show, this.tooltipDelay); } this.currentElt = elt; } } }; /** * Hides the current tooltip. */ Sidebar.prototype.hideTooltip = function() { if (this.thread != null) { window.clearTimeout(this.thread); this.thread = null; } if (this.tooltip != null) { this.tooltip.style.display = 'none'; this.currentElt = null; } }; /** * Hides the current tooltip. */ Sidebar.prototype.addDataEntry = function(tags, width, height, title, data) { return this.addEntry(tags, mxUtils.bind(this, function() { return this.createVertexTemplateFromData(data, width, height, title); })); }; /** * Adds the give entries to the search index. */ Sidebar.prototype.addEntries = function(images) { for (var i = 0; i < images.length; i++) { (mxUtils.bind(this, function(img) { var data = img.data; var tags = (img.title != null) ? img.title : ''; if (img.tags != null) { tags += ' ' + img.tags; } if (data != null && tags.length > 0) { this.addEntry(tags, mxUtils.bind(this, function() { data = this.editorUi.convertDataUri(data); var s = 'shape=image;verticalLabelPosition=bottom;verticalAlign=top;imageAspect=0;'; if (img.aspect == 'fixed') { s += 'aspect=fixed;' } return this.createVertexTemplate(s + 'image=' + data, img.w, img.h, '', img.title || '', false, false, true) })); } else if (img.xml != null && tags.length > 0) { this.addEntry(tags, mxUtils.bind(this, function() { var cells = this.editorUi.stringToCells(Graph.decompress(img.xml)); return this.createVertexTemplateFromCells( cells, img.w, img.h, img.title || '', true, false, true); })); } }))(images[i]); } }; /** * Hides the current tooltip. */ Sidebar.prototype.setCurrentSearchEntryLibrary = function(id, lib) { this.currentSearchEntryLibrary = (id != null) ? {id: id, lib: lib} : null; }; /** * Hides the current tooltip. */ Sidebar.prototype.addEntry = function(tags, fn) { if (this.taglist != null && tags != null && tags.length > 0) { if (this.currentSearchEntryLibrary != null) { fn.parentLibraries = [this.currentSearchEntryLibrary]; } // Replaces special characters var tmp = tags.toLowerCase().replace(/[\/\,\(\)]/g, ' ').split(' '); var tagList = []; var hash = {}; // Finds unique tags for (var i = 0; i < tmp.length; i++) { if (hash[tmp[i]] == null) { hash[tmp[i]] = true; tagList.push(tmp[i]); } // Adds additional entry with removed trailing numbers var normalized = tmp[i].replace(/\.*\d*$/, ''); if (normalized != tmp[i]) { if (hash[normalized] == null) { hash[normalized] = true; tagList.push(normalized); } } } for (var i = 0; i < tagList.length; i++) { this.addEntryForTag(tagList[i], fn); } } return fn; }; /** * Hides the current tooltip. */ Sidebar.prototype.addEntryForTag = function(tag, fn) { if (tag != null && tag.length > 1) { var entry = this.taglist[tag]; if (typeof entry !== 'object') { entry = {entries: []}; this.taglist[tag] = entry; } entry.entries.push(fn); } }; /** * Adds shape search UI. */ Sidebar.prototype.searchEntries = function(searchTerms, count, page, success, error) { if (this.taglist != null && searchTerms != null) { var tmp = searchTerms.toLowerCase().split(' '); var dict = new mxDictionary(); var max = (page + 1) * count; var results = []; var index = 0; for (var i = 0; i < tmp.length; i++) { if (tmp[i].length > 0) { var entry = this.taglist[tmp[i]]; var tmpDict = new mxDictionary(); if (entry != null) { var arr = entry.entries; results = []; for (var j = 0; j < arr.length; j++) { var entry = arr[j]; // NOTE Array does not contain duplicates if ((index == 0) == (dict.get(entry) == null)) { tmpDict.put(entry, entry); results.push(entry); if (i == tmp.length - 1 && results.length == max) { success(results.slice(page * count, max), max, true, tmp); return; } } } } else { results = []; } dict = tmpDict; index++; } } var len = results.length; success(results.slice(page * count, (page + 1) * count), len, false, tmp); } else { success([], null, null, tmp); } }; /** * Adds shape search UI. */ Sidebar.prototype.filterTags = function(tags) { if (tags != null) { var arr = tags.split(' '); var result = []; var hash = {}; // Ignores tags with leading numbers, strips trailing numbers for (var i = 0; i < arr.length; i++) { // Removes duplicates if (hash[arr[i]] == null) { hash[arr[i]] = '1'; result.push(arr[i]); } } return result.join(' '); } return null; }; /** * Adds the general palette to the sidebar. */ Sidebar.prototype.cloneCell = function(cell, value) { var clone = cell.clone(); if (value != null) { clone.value = value; } return clone; }; /** * Adds shape search UI. */ Sidebar.prototype.showPopupMenuForEntry = function(elt, libs, evt) { // Hook for subclassers }; /** * Adds shape search UI. */ Sidebar.prototype.addSearchPalette = function(expand) { var elt = document.createElement('div'); elt.style.visibility = 'hidden'; this.container.appendChild(elt); var div = document.createElement('div'); div.className = 'geSidebar'; div.style.boxSizing = 'border-box'; div.style.overflow = 'hidden'; div.style.width = '100%'; div.style.padding = '8px'; div.style.paddingTop = '14px'; div.style.paddingBottom = '0px'; if (!expand) { div.style.display = 'none'; } var inner = document.createElement('div'); inner.style.whiteSpace = 'nowrap'; inner.style.textOverflow = 'clip'; inner.style.paddingBottom = '8px'; inner.style.cursor = 'default'; var input = document.createElement('input'); input.setAttribute('placeholder', mxResources.get('searchShapes')); input.setAttribute('type', 'text'); input.style.fontSize = '12px'; input.style.overflow = 'hidden'; input.style.boxSizing = 'border-box'; input.style.border = 'solid 1px #d5d5d5'; input.style.borderRadius = '4px'; input.style.width = '100%'; input.style.outline = 'none'; input.style.padding = '6px'; input.style.paddingRight = '20px'; inner.appendChild(input); var cross = document.createElement('img'); cross.setAttribute('src', Sidebar.prototype.searchImage); cross.setAttribute('title', mxResources.get('search')); cross.style.position = 'relative'; cross.style.left = '-18px'; cross.style.top = '1px'; // Needed to block event transparency in IE cross.style.background = 'url(\'' + this.editorUi.editor.transparentImage + '\')'; var find; inner.appendChild(cross); div.appendChild(inner); var center = document.createElement('center'); var button = mxUtils.button(mxResources.get('moreResults'), function() { find(); }); button.style.display = 'none'; // Workaround for inherited line-height in quirks mode button.style.lineHeight = 'normal'; button.style.fontSize = '12px'; button.style.padding = '6px 12px 6px 12px'; button.style.marginTop = '4px'; button.style.marginBottom = '8px'; center.style.paddingTop = '4px'; center.style.paddingBottom = '4px'; center.appendChild(button); div.appendChild(center); var searchTerm = ''; var active = false; var complete = false; var page = 0; var hash = new Object(); // Count is dynamically updated below var count = 12; var clearDiv = mxUtils.bind(this, function() { active = false; this.currentSearch = null; var child = div.firstChild; while (child != null) { var next = child.nextSibling; if (child != inner && child != center) { child.parentNode.removeChild(child); } child = next; } }); mxEvent.addListener(cross, 'click', function() { if (cross.getAttribute('src') == Dialog.prototype.closeImage) { cross.setAttribute('src', Sidebar.prototype.searchImage); cross.setAttribute('title', mxResources.get('search')); button.style.display = 'none'; input.value = ''; searchTerm = ''; clearDiv(); } input.focus(); }); find = mxUtils.bind(this, function() { // Shows 4 rows (minimum 4 results) count = 4 * Math.max(1, Math.floor(this.container.clientWidth / (this.thumbWidth + 10))); this.hideTooltip(); if (input.value != '') { if (center.parentNode != null) { if (searchTerm != input.value) { clearDiv(); searchTerm = input.value; hash = new Object(); complete = false; page = 0; } if (!active && !complete) { button.setAttribute('disabled', 'true'); button.style.display = ''; button.style.cursor = 'wait'; button.innerHTML = mxResources.get('loading') + '...'; active = true; // Ignores old results var current = new Object(); this.currentSearch = current; this.searchEntries(searchTerm, count, page, mxUtils.bind(this, function(results, len, more, terms) { if (this.currentSearch == current) { results = (results != null) ? results : []; active = false; page++; this.insertSearchHint(div, searchTerm, count, page, results, len, more, terms); // Allows to repeat the search if (results.length == 0 && page == 1) { searchTerm = ''; } if (center.parentNode != null) { center.parentNode.removeChild(center); } for (var i = 0; i < results.length; i++) { (mxUtils.bind(this, function(result) { try { var elt = result(); // Avoids duplicates in results if (hash[elt.innerHTML] == null) { hash[elt.innerHTML] = (result.parentLibraries != null) ? result.parentLibraries.slice() : []; div.appendChild(elt); } else if (result.parentLibraries != null) { hash[elt.innerHTML] = hash[elt.innerHTML].concat(result.parentLibraries); } mxEvent.addGestureListeners(elt, null, null, mxUtils.bind(this, function(evt) { var libs = hash[elt.innerHTML]; if (mxEvent.isPopupTrigger(evt)) { this.showPopupMenuForEntry(elt, libs, evt); } })); // Disables the built-in context menu mxEvent.disableContextMenu(elt); } catch (e) { // ignore } }))(results[i]); } if (more) { button.removeAttribute('disabled'); button.innerHTML = mxResources.get('moreResults'); } else { button.innerHTML = mxResources.get('reset'); button.style.display = 'none'; complete = true; } button.style.cursor = ''; div.appendChild(center); } }), mxUtils.bind(this, function() { // TODO: Error handling button.style.cursor = ''; })); } } } else { clearDiv(); input.value = ''; searchTerm = ''; hash = new Object(); button.style.display = 'none'; complete = false; input.focus(); } }); this.searchShapes = function(value) { input.value = value; find(); }; mxEvent.addListener(input, 'keydown', mxUtils.bind(this, function(evt) { if (evt.keyCode == 13 /* Enter */) { find(); mxEvent.consume(evt); } })); mxEvent.addListener(input, 'keyup', mxUtils.bind(this, function(evt) { if (input.value == '') { cross.setAttribute('src', Sidebar.prototype.searchImage); cross.setAttribute('title', mxResources.get('search')); } else { cross.setAttribute('src', Dialog.prototype.closeImage); cross.setAttribute('title', mxResources.get('reset')); } if (input.value == '') { complete = true; button.style.display = 'none'; } else if (input.value != searchTerm) { button.style.display = 'none'; complete = false; } else if (!active) { if (complete) { button.style.display = 'none'; } else { button.style.display = ''; } } })); // Workaround for blocked text selection in Editor mxEvent.addListener(input, 'mousedown', function(evt) { if (evt.stopPropagation) { evt.stopPropagation(); } evt.cancelBubble = true; }); // Workaround for blocked text selection in Editor mxEvent.addListener(input, 'selectstart', function(evt) { if (evt.stopPropagation) { evt.stopPropagation(); } evt.cancelBubble = true; }); var outer = document.createElement('div'); outer.appendChild(div); this.container.appendChild(outer); // Keeps references to the DOM nodes this.palettes['search'] = [elt, outer]; }; /** * Adds the general palette to the sidebar. */ Sidebar.prototype.insertSearchHint = function(div, searchTerm, count, page, results, len, more, terms) { if (results.length == 0 && page == 1) { var err = document.createElement('div'); err.className = 'geTitle'; err.style.cssText = 'background-color:transparent;border-color:transparent;' + 'color:gray;padding:6px 0px 0px 0px !important;margin:4px 8px 4px 8px;' + 'text-align:center;cursor:default !important'; mxUtils.write(err, mxResources.get('noResultsFor', [searchTerm])); div.appendChild(err); } }; /** * Adds the general palette to the sidebar. */ Sidebar.prototype.addGeneralPalette = function(expand) { var lineTags = 'line lines connector connectors connection connections arrow arrows '; this.setCurrentSearchEntryLibrary('general', 'general'); var sb = this; // Reusable cells var field = new mxCell('List Item', new mxGeometry(0, 0, 60, 26), 'text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;'); field.vertex = true; var fns = [ this.createVertexTemplateEntry('rounded=0;whiteSpace=wrap;html=1;', 120, 60, '', 'Rectangle', null, null, 'rect rectangle box'), this.createVertexTemplateEntry('rounded=1;whiteSpace=wrap;html=1;', 120, 60, '', 'Rounded Rectangle', null, null, 'rounded rect rectangle box'), // Explicit strokecolor/fillcolor=none is a workaround to maintain transparent background regardless of current style this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;', 40, 20, 'Text', 'Text', null, null, 'text textbox textarea label'), this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;spacing=5;spacingTop=-20;whiteSpace=wrap;overflow=hidden;rounded=0;', 190, 120, '<h1>Heading</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>', 'Textbox', null, null, 'text textbox textarea'), this.createVertexTemplateEntry('ellipse;whiteSpace=wrap;html=1;', 120, 80, '', 'Ellipse', null, null, 'oval ellipse state'), this.createVertexTemplateEntry('whiteSpace=wrap;html=1;aspect=fixed;', 80, 80, '', 'Square', null, null, 'square'), this.createVertexTemplateEntry('ellipse;whiteSpace=wrap;html=1;aspect=fixed;', 80, 80, '', 'Circle', null, null, 'circle'), this.createVertexTemplateEntry('shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;', 120, 60, '', 'Process', null, null, 'process task'), this.createVertexTemplateEntry('rhombus;whiteSpace=wrap;html=1;', 80, 80, '', 'Diamond', null, null, 'diamond rhombus if condition decision conditional question test'), this.createVertexTemplateEntry('shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;', 120, 60, '', 'Parallelogram'), this.createVertexTemplateEntry('shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;', 120, 80, '', 'Hexagon', null, null, 'hexagon preparation'), this.createVertexTemplateEntry('triangle;whiteSpace=wrap;html=1;', 60, 80, '', 'Triangle', null, null, 'triangle logic inverter buffer'), this.createVertexTemplateEntry('shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;', 60, 80, '', 'Cylinder', null, null, 'cylinder data database'), this.createVertexTemplateEntry('ellipse;shape=cloud;whiteSpace=wrap;html=1;', 120, 80, '', 'Cloud', null, null, 'cloud network'), this.createVertexTemplateEntry('shape=document;whiteSpace=wrap;html=1;boundedLbl=1;', 120, 80, '', 'Document'), this.createVertexTemplateEntry('shape=internalStorage;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Internal Storage'), this.createVertexTemplateEntry('shape=cube;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;darkOpacity=0.05;darkOpacity2=0.1;', 120, 80, '', 'Cube'), this.createVertexTemplateEntry('shape=step;perimeter=stepPerimeter;whiteSpace=wrap;html=1;fixedSize=1;', 120, 80, '', 'Step'), this.createVertexTemplateEntry('shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;', 120, 60, '', 'Trapezoid'), this.createVertexTemplateEntry('shape=tape;whiteSpace=wrap;html=1;', 120, 100, '', 'Tape'), this.createVertexTemplateEntry('shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;', 80, 100, '', 'Note'), this.createVertexTemplateEntry('shape=card;whiteSpace=wrap;html=1;', 80, 100, '', 'Card'), this.createVertexTemplateEntry('shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;', 120, 80, '', 'Callout', null, null, 'bubble chat thought speech message'), this.createVertexTemplateEntry('shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;', 30, 60, 'Actor', 'Actor', false, null, 'user person human stickman'), this.createVertexTemplateEntry('shape=xor;whiteSpace=wrap;html=1;', 60, 80, '', 'Or', null, null, 'logic or'), this.createVertexTemplateEntry('shape=or;whiteSpace=wrap;html=1;', 60, 80, '', 'And', null, null, 'logic and'), this.createVertexTemplateEntry('shape=dataStorage;whiteSpace=wrap;html=1;fixedSize=1;', 100, 80, '', 'Data Storage'), this.createVertexTemplateEntry('swimlane;startSize=0;', 200, 200, '', 'Container', null, null, 'container swimlane lane pool group'), this.createVertexTemplateEntry('swimlane;', 200, 200, 'Vertical Container', 'Container', null, null, 'container swimlane lane pool group'), this.createVertexTemplateEntry('swimlane;horizontal=0;', 200, 200, 'Horizontal Container', 'Horizontal Container', null, null, 'container swimlane lane pool group'), this.addEntry('list group erd table', function() { var cell = new mxCell('List', new mxGeometry(0, 0, 140, 110), 'swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;' + 'resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;'); cell.vertex = true; cell.insert(sb.cloneCell(field, 'Item 1')); cell.insert(sb.cloneCell(field, 'Item 2')); cell.insert(sb.cloneCell(field, 'Item 3')); return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'List'); }), this.addEntry('list item entry value group erd table', function() { return sb.createVertexTemplateFromCells([sb.cloneCell(field, 'List Item')], field.geometry.width, field.geometry.height, 'List Item'); }), this.addEntry('curve', mxUtils.bind(this, function() { var cell = new mxCell('', new mxGeometry(0, 0, 50, 50), 'curved=1;endArrow=classic;html=1;'); cell.geometry.setTerminalPoint(new mxPoint(0, 50), true); cell.geometry.setTerminalPoint(new mxPoint(50, 0), false); cell.geometry.points = [new mxPoint(50, 50), new mxPoint(0, 0)]; cell.geometry.relative = true; cell.edge = true; return this.createEdgeTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Curve'); })), this.createEdgeTemplateEntry('shape=flexArrow;endArrow=classic;startArrow=classic;html=1;', 100, 100, '', 'Bidirectional Arrow', null, lineTags + 'bidirectional'), this.createEdgeTemplateEntry('shape=flexArrow;endArrow=classic;html=1;', 50, 50, '', 'Arrow', null, lineTags + 'directional directed'), this.createEdgeTemplateEntry('endArrow=none;dashed=1;html=1;', 50, 50, '', 'Dashed Line', null, lineTags + 'dashed undirected no'), this.createEdgeTemplateEntry('endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;', 50, 50, '', 'Dotted Line', null, lineTags + 'dotted undirected no'), this.createEdgeTemplateEntry('endArrow=none;html=1;', 50, 50, '', 'Line', null, lineTags + 'simple undirected plain blank no'), this.createEdgeTemplateEntry('endArrow=classic;startArrow=classic;html=1;', 50, 50, '', 'Bidirectional Connector', null, lineTags + 'bidirectional'), this.createEdgeTemplateEntry('endArrow=classic;html=1;', 50, 50, '', 'Directional Connector', null, lineTags + 'directional directed'), this.createEdgeTemplateEntry('shape=link;html=1;', 100, 0, '', 'Link', null, lineTags + 'link'), this.addEntry(lineTags + 'edge title', mxUtils.bind(this, function() { var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=classic;html=1;'); edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); edge.geometry.setTerminalPoint(new mxPoint(100, 0), false); edge.geometry.relative = true; edge.edge = true; var cell0 = new mxCell('Label', new mxGeometry(0, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;'); cell0.geometry.relative = true; cell0.setConnectable(false); cell0.vertex = true; edge.insert(cell0); return this.createEdgeTemplateFromCells([edge], 100, 0, 'Connector with Label'); })), this.addEntry(lineTags + 'edge title multiplicity', mxUtils.bind(this, function() { var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=classic;html=1;'); edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); edge.geometry.setTerminalPoint(new mxPoint(160, 0), false); edge.geometry.relative = true; edge.edge = true; var cell0 = new mxCell('Label', new mxGeometry(0, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;'); cell0.geometry.relative = true; cell0.setConnectable(false); cell0.vertex = true; edge.insert(cell0); var cell1 = new mxCell('Source', new mxGeometry(-1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;'); cell1.geometry.relative = true; cell1.setConnectable(false); cell1.vertex = true; edge.insert(cell1); return this.createEdgeTemplateFromCells([edge], 160, 0, 'Connector with 2 Labels'); })), this.addEntry(lineTags + 'edge title multiplicity', mxUtils.bind(this, function() { var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=classic;html=1;'); edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); edge.geometry.setTerminalPoint(new mxPoint(160, 0), false); edge.geometry.relative = true; edge.edge = true; var cell0 = new mxCell('Label', new mxGeometry(0, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;'); cell0.geometry.relative = true; cell0.setConnectable(false); cell0.vertex = true; edge.insert(cell0); var cell1 = new mxCell('Source', new mxGeometry(-1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;'); cell1.geometry.relative = true; cell1.setConnectable(false); cell1.vertex = true; edge.insert(cell1); var cell2 = new mxCell('Target', new mxGeometry(1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=right;verticalAlign=bottom;'); cell2.geometry.relative = true; cell2.setConnectable(false); cell2.vertex = true; edge.insert(cell2); return this.createEdgeTemplateFromCells([edge], 160, 0, 'Connector with 3 Labels'); })), this.addEntry(lineTags + 'edge shape symbol message mail email', mxUtils.bind(this, function() { var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=classic;html=1;'); edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); edge.geometry.setTerminalPoint(new mxPoint(100, 0), false); edge.geometry.relative = true; edge.edge = true; var cell = new mxCell('', new mxGeometry(0, 0, 20, 14), 'shape=message;html=1;outlineConnect=0;'); cell.geometry.relative = true; cell.vertex = true; cell.geometry.offset = new mxPoint(-10, -7); edge.insert(cell); return this.createEdgeTemplateFromCells([edge], 100, 0, 'Connector with Symbol'); })) ]; this.addPaletteFunctions('general', mxResources.get('general'), (expand != null) ? expand : true, fns); this.setCurrentSearchEntryLibrary(); }; /** * Adds the general palette to the sidebar. */ Sidebar.prototype.addMiscPalette = function(expand) { var sb = this; var lineTags = 'line lines connector connectors connection connections arrow arrows ' this.setCurrentSearchEntryLibrary('general', 'misc'); var fns = [ this.createVertexTemplateEntry('text;strokeColor=none;fillColor=none;html=1;fontSize=24;fontStyle=1;verticalAlign=middle;align=center;', 100, 40, 'Title', 'Title', null, null, 'text heading title'), this.createVertexTemplateEntry('text;strokeColor=none;fillColor=none;html=1;whiteSpace=wrap;verticalAlign=middle;overflow=hidden;', 100, 80, '<ul><li>Value 1</li><li>Value 2</li><li>Value 3</li></ul>', 'Unordered List'), this.createVertexTemplateEntry('text;strokeColor=none;fillColor=none;html=1;whiteSpace=wrap;verticalAlign=middle;overflow=hidden;', 100, 80, '<ol><li>Value 1</li><li>Value 2</li><li>Value 3</li></ol>', 'Ordered List'), this.addDataEntry('table', 180, 120, 'Table 1', '7ZjJTsMwEIafJleUhZZybVgucAFewDTT2pLjiewpaXl6xolLVQFqWBJArZRKns2xv5H7y4myvFxdW1HJWyxAR9lllOUWkdpRucpB6yiNVRFlF1GaxvyL0qsPokkTjSthwVCXgrQteBJ6Ca2ndTha6+BwUlR+SOLRu6aSSl7mRcLDWiqC+0rMfLzmTbDPkbB0r569K2Z7hoaEMmBDzQy1FpVTzWRthlS6uBFrXNLmNRtrGpYHlmD14RYbV9jfNWAJZNecUquCZMiYtBhiCWohN2WBTSxc61i81m6J8SBAex9g1h0gL5mU0HcwI2EWXVi+ZVVYrB6EXQAFR4XKENjLJ6bhgm+utM5Ro0du0PgXEVYhqGG+qX1EIiyDYQOY10kbKKMpP4wpj09G0Yh3k7OdbG1+fLqlHI0jy432c4BwVIPr3MD0aw08/YH+nfbbP2N89rZ/324NMsq5xppNqYoCTFfG2V7G454Qjw4c8WoX7wDEx0fiO3/wAyA/O+pAbzqw3m3TELIwOZQTdPZrsnB+4IiHl4UkPiIfWheS5CgMfQvDZEBhSD5xY/7fZyjZf63u7dD0fKv++5B/QRwO5ia8h3mP6sDm9tNeE9v58vcC'), this.addDataEntry('table', 180, 120, 'Table 2', '7ZjBbqMwEIafhmuFISTptbTbS/eyrfbuBie2ZDzITEqyT79jMMlGWVTUBlqVSkTyjGeM+SbDLxPEab67t7yQPyETOojvgji1ANiM8l0qtA6iUGVBfBtEUUi/IPrRMcvq2bDgVhjskxA1CS9cb0XjaRwl7rV3lJIXboj82bluJOa0zVtGw0oqFI8FX7n5ih6CfCVyi4/qj3OFZK/AIFdGWJ+zAq15Uap6sSZCKp098D1ssb1Na7nobW4eKL/00Raqf02/f2FR7DoZ1C4P4F5ALtDuKaRSGUofsWw4hVKojWzTPLyQl41jc8g9IqWBp/p/wnF/wrRlVFz/EivkZtMH9jnMzELxxO1GoHcUoAwKe/dCNFpoa6V1ChpcTQwYdyOEwk9qsW5znwER8ha8B3NYtIaS3NBFmNLwKgkSepqUbHa06XLhFlMwJVr6J7g1BC+xEiX2LWD0tgLOLlC/2Vn9ftfDKGQXLaQxLvpYyHfXCIjpWkNFplRZJkxf2PGrsOcDsU46WV+2aT49690p5xHQzzvRx5NEf3j3j8B+8S0Rg0nE/rRMYyjGsrOVZl+0lRYfphjXnayTabEeXzFY2Ml+Pkn2Y0oGY9+aMbRmLEfUDHZ+EG+bafFFm4m9fiofrHvOD+Ut7eXEaH+AbnSfqK+nCX9A4SDz+DGxnjv51vgX'), this.addDataEntry('table title', 180, 120, 'Table with Title 1', '7ZhRb6MwDMc/Da8nAmPdvZbu9nJ7WfcFMnAhUohR4o12n34OpKumrmqlDXa6VqJS/Lcdkp8bWSFK82Z9Z2Vb32MJOkpvozS3iDSMmnUOWkdJrMooXURJEvMvSv4c8IreG7fSgqFTEpIh4UXqZxiUR/mkYVAdbXRQXS1bP6Tem85ranitC8HDrlYEy1YW3t/xTlhzJC0t1auX0piFAg1JZcCGpAK1lq1T/WyLPqJWuvwrN/hM2/dsrfmKs5dhMT5balUZHhe8Sz/lPOwCLMH6IIleChjuABsgu+GQTpVUh4ibgVZcg6rqbVoWROkGoXrP3YHlQWD7Oed0j/NBxLxkUlI/QEHSVKfQ3odZWmwfpa2AgtCi8qhuX5iGC9pKaZ2jRl8Tg8a/iLANTg2rbe4TEmETDBvAvE/aQ8nm/DCmPP6VRRnvJmdb7Gx+fLilHI0jy/8EPwdIRx04OrWAyecF3ATEoUzH6nn1DeW8GrecxvjoXTm/XClksiuNHZu1KkswpyJPj56Z65EQZ2eOeP0R7wTEry/E+4RkOuSzS1sYuy3MJmwLN+dygmY/1hZ+nzni6duCiC/Ip+4LQlwaw9iNQYgJO4PYv2j/p4dIHL9mj3ZqRr5l//uQf6A7nM1V+AjzEdsDm7svgr3vwwfDNw=='), this.addDataEntry('table title', 180, 150, 'Table with Title 2', '7Zhdb5swFIZ/DbcTHyVrbiFdb7Kbptq9Cw5YMj7IPi1kv37HYJK1FDWbQoOmSUSyz4dt3id+L/CitGrvNavL75Bz6UV3XpRqAOxHVZtyKb3QF7kXbbww9Onnhd8mskGX9WumucJzGsK+4YXJZ95HHtmT5H3U4EG6qClZbYfYZaOkxIrOuglo2JQC+a5mmc039CYUM8g07sRPG4p8CmSgkAnFtWvKQEpWG9GttukqSiHzLTvAMw77DLNkL1qeP0BjXLeGZkuLGde6p8V37qw2zaQoFI0zEsHumLiX5Bp5OylUF3Iq3XOoOOoDlTQix9JV3PZi+iUXRTm0xS7ITB8ojr0n3WngpH8fQzTCMEmAjoyCyQeeIVPFOTDGWuca6kemC44uUIOwUt29kBpHVYWUKUiwyBQouxFC7ZKS74feJ0CEaiDjhDku2okSJ/SQTKn/JfZiepuU5sFpTo8t15iCMqjpj2LX4Mxgww2eCzB8H+DBSewwfcQzugDOmxHO4KI8lbLVJ55/jMp/gwpI2r2EhqalyHOuztU8+vDS3MykcTzS+Ec3DP2Faz24U1+bGNpQqGLbd65mgNG+BvH7BZgLzupf8LO34JblZ6tP9LOvI5yX5bkcP1tdzc9uJ/1s4VrP52cTMK7gZ+v/fja3n60/0c8Cf8QzWvYl++s7tL6aoQXBpKMtXOz5HG2CxvyORtPTR4Uu9+qbwy8='), this.addDataEntry('crossfunctional cross-functional cross functional flowchart swimlane table', 400, 400, 'Cross-Functional Flowchart', '7ZhRb5swEMc/DY+bMCRt97jQpi+tVC2fwINbbMnYyD4C6aefjaHpBrTRlNCoTALJPp9t+P25O5kgTvL6XtOCPaoMRBDfBXGilULfyusEhAiikGdBfBtEUWjvIFqPjJJmNCyoBonHTIj8hB0VJXiL3dyYL+tSpsiVpM55LVSVMqrROxvci9bZMFq4JtKfzrRKGRfZA92rEjtr11tpVT1wCcYOhM5ViTKXry0G7RYb/uwWXDgDw9wCuSW2WTGOsClo6gYri8uvIGhheLN1s4KGtNSG7+AHGL+Os0JdUJm1nUJxiaDvdhZQt/EvJXHTvpTbjAq+lbadgnO1hhYSaIR6FHRjainfg8oB9d66VDxD5j0WoRcjZMC3DP8yUuMN25e5B91so5VuWMa4J+P3FJW2JtLXrOK5oNLJxZTmz/blqXhNp3mO5cpe9smS8OsyWNp5ie2TQ99ezl1joqRBTXmDAajBCgxejprHKBcNK7fvBPIz3hOSRCcQctET8olRA+8JmSopIW2j8GOD6Sji8TDxepT4C9yTE1+OEo/mQ5xcTYn8ahR5PB/k0c2UyK9HC8SbX/mnLBAnqAlD8XK+onDTE+/fw+TiQF9fTin4Nl/O0xYAEs6X9LR5n5Ae6S7xv1lr/yf+4cQ/pN75Ej/pH88/UZyQkRPzR6R+0j9Bz4f0xMm/f8adD+qzZn/bPfw5bMb++LH4Gw=='), this.createVertexTemplateEntry('text;html=1;strokeColor=#c0c0c0;fillColor=#ffffff;overflow=fill;rounded=0;', 280, 160, '<table border="1" width="100%" height="100%" cellpadding="4" style="width:100%;height:100%;border-collapse:collapse;">' + '<tr style="background-color:#A7C942;color:#ffffff;border:1px solid #98bf21;"><th align="left">Title 1</th><th align="left">Title 2</th><th align="left">Title 3</th></tr>' + '<tr style="border:1px solid #98bf21;"><td>Value 1</td><td>Value 2</td><td>Value 3</td></tr>' + '<tr style="background-color:#EAF2D3;border:1px solid #98bf21;"><td>Value 4</td><td>Value 5</td><td>Value 6</td></tr>' + '<tr style="border:1px solid #98bf21;"><td>Value 7</td><td>Value 8</td><td>Value 9</td></tr>' + '<tr style="background-color:#EAF2D3;border:1px solid #98bf21;"><td>Value 10</td><td>Value 11</td><td>Value 12</td></tr></table>', 'HTML Table 1'), this.createVertexTemplateEntry('text;html=1;strokeColor=#c0c0c0;fillColor=none;overflow=fill;', 180, 140, '<table border="0" width="100%" height="100%" style="width:100%;height:100%;border-collapse:collapse;">' + '<tr><td align="center">Value 1</td><td align="center">Value 2</td><td align="center">Value 3</td></tr>' + '<tr><td align="center">Value 4</td><td align="center">Value 5</td><td align="center">Value 6</td></tr>' + '<tr><td align="center">Value 7</td><td align="center">Value 8</td><td align="center">Value 9</td></tr></table>', 'HTML Table 2'), this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;overflow=fill;', 180, 140, '<table border="1" width="100%" height="100%" style="width:100%;height:100%;border-collapse:collapse;">' + '<tr><td align="center">Value 1</td><td align="center">Value 2</td><td align="center">Value 3</td></tr>' + '<tr><td align="center">Value 4</td><td align="center">Value 5</td><td align="center">Value 6</td></tr>' + '<tr><td align="center">Value 7</td><td align="center">Value 8</td><td align="center">Value 9</td></tr></table>', 'HTML Table 3'), this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;overflow=fill;', 160, 140, '<table border="1" width="100%" height="100%" cellpadding="4" style="width:100%;height:100%;border-collapse:collapse;">' + '<tr><th align="center"><b>Title</b></th></tr>' + '<tr><td align="center">Section 1.1\nSection 1.2\nSection 1.3</td></tr>' + '<tr><td align="center">Section 2.1\nSection 2.2\nSection 2.3</td></tr></table>', 'HTML Table 4'), this.addEntry('link hyperlink', mxUtils.bind(this, function() { var cell = new mxCell('Link', new mxGeometry(0, 0, 60, 40), 'text;html=1;strokeColor=none;fillColor=none;whiteSpace=wrap;align=center;verticalAlign=middle;fontColor=#0000EE;fontStyle=4;'); cell.vertex = true; this.graph.setLinkForCell(cell, 'https://www.draw.io'); return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Link'); })), this.addEntry('timestamp date time text label', mxUtils.bind(this, function() { var cell = new mxCell('%date{ddd mmm dd yyyy HH:MM:ss}%', new mxGeometry(0, 0, 160, 20), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;'); cell.vertex = true; this.graph.setAttributeForCell(cell, 'placeholders', '1'); return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Timestamp'); })), this.addEntry('variable placeholder metadata hello world text label', mxUtils.bind(this, function() { var cell = new mxCell('%name% Text', new mxGeometry(0, 0, 80, 20), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;'); cell.vertex = true; this.graph.setAttributeForCell(cell, 'placeholders', '1'); this.graph.setAttributeForCell(cell, 'name', 'Variable'); return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Variable'); })), this.createVertexTemplateEntry('shape=ext;double=1;rounded=0;whiteSpace=wrap;html=1;', 120, 80, '', 'Double Rectangle', null, null, 'rect rectangle box double'), this.createVertexTemplateEntry('shape=ext;double=1;rounded=1;whiteSpace=wrap;html=1;', 120, 80, '', 'Double Rounded Rectangle', null, null, 'rounded rect rectangle box double'), this.createVertexTemplateEntry('ellipse;shape=doubleEllipse;whiteSpace=wrap;html=1;', 100, 60, '', 'Double Ellipse', null, null, 'oval ellipse start end state double'), this.createVertexTemplateEntry('shape=ext;double=1;whiteSpace=wrap;html=1;aspect=fixed;', 80, 80, '', 'Double Square', null, null, 'double square'), this.createVertexTemplateEntry('ellipse;shape=doubleEllipse;whiteSpace=wrap;html=1;aspect=fixed;', 80, 80, '', 'Double Circle', null, null, 'double circle'), t